Clean up some battle scr cmd data

This commit is contained in:
GriffinR 2020-07-16 20:12:12 -04:00
parent 0c4f3b269e
commit aba42513d3
25 changed files with 584 additions and 521 deletions

View File

@ -1263,8 +1263,8 @@
various \battler, VARIOUS_GET_MOVE_TARGET various \battler, VARIOUS_GET_MOVE_TARGET
.endm .endm
.macro various4 battler:req .macro getbattlerfainted battler:req
various \battler, 4 various \battler, VARIOUS_GET_BATTLER_FAINTED
.endm .endm
.macro resetintimidatetracebits battler:req .macro resetintimidatetracebits battler:req
@ -1279,8 +1279,8 @@
various \battler, 7 various \battler, 7
.endm .endm
.macro various8 battler:req .macro palaceflavortext battler:req
various \battler, 8 various \battler, VARIOUS_PALACE_FLAVOR_TEXT
.endm .endm
.macro arenajudgmentwindow .macro arenajudgmentwindow
@ -1365,11 +1365,11 @@
.endm .endm
.macro chosenstatus1animation battler:req, status:req .macro chosenstatus1animation battler:req, status:req
chosenstatusanimation \battler 0x0 \status chosenstatusanimation \battler, 0x0, \status
.endm .endm
.macro chosenstatus2animation battler:req, status:req .macro chosenstatus2animation battler:req, status:req
chosenstatusanimation \battler 0x1 \status chosenstatusanimation \battler, 0x1, \status
.endm .endm
.macro sethword dst:req, value:req .macro sethword dst:req, value:req

View File

@ -3153,8 +3153,8 @@ BattleScript_PursuitDmgOnSwitchOut::
waitmessage 0x40 waitmessage 0x40
tryfaintmon BS_TARGET, FALSE, NULL tryfaintmon BS_TARGET, FALSE, NULL
moveendfromto MOVEEND_ON_DAMAGE_ABILITIES, MOVEEND_CHOICE_MOVE moveendfromto MOVEEND_ON_DAMAGE_ABILITIES, MOVEEND_CHOICE_MOVE
various4 BS_TARGET getbattlerfainted BS_TARGET
jumpifbyte CMP_EQUAL, gBattleCommunication, 0x0, BattleScript_PursuitDmgOnSwitchOutRet jumpifbyte CMP_EQUAL, gBattleCommunication, FALSE, BattleScript_PursuitDmgOnSwitchOutRet
setbyte sGIVEEXP_STATE, 0x0 setbyte sGIVEEXP_STATE, 0x0
getexp BS_TARGET getexp BS_TARGET
BattleScript_PursuitDmgOnSwitchOutRet: BattleScript_PursuitDmgOnSwitchOutRet:
@ -4442,18 +4442,18 @@ BattleScript_FlushMessageBox::
printstring STRINGID_EMPTYSTRING3 printstring STRINGID_EMPTYSTRING3
return return
BattleScript_82DB881:: BattleScript_PalacePrintFlavorText::
setbyte gBattleCommunication + 1, 0x0 setbyte gBattleCommunication + 1, 0
BattleScript_82DB887:: BattleScript_PalaceTryBattlerFlavorText::
various8 BS_ATTACKER palaceflavortext BS_ATTACKER @ BS_ATTACKER here overwritten by gBattleCommunication + 1
jumpifbyte CMP_NOT_EQUAL, gBattleCommunication, 0x1, BattleScript_82DB89D jumpifbyte CMP_NOT_EQUAL, gBattleCommunication, TRUE, BattleScript_PalaceEndFlavorText
printfromtable gStringIds_85CCF0A printfromtable gBattlePalaceFlavorTextTable
waitmessage 0x40 waitmessage 0x40
BattleScript_82DB89D:: BattleScript_PalaceEndFlavorText::
addbyte gBattleCommunication + 1, 0x1 addbyte gBattleCommunication + 1, 1
jumpifbytenotequal gBattleCommunication + 1, gBattlersCount, BattleScript_82DB887 jumpifbytenotequal gBattleCommunication + 1, gBattlersCount, BattleScript_PalaceTryBattlerFlavorText
setbyte gBattleCommunication, 0x0 setbyte gBattleCommunication, 0
setbyte gBattleCommunication + 1, 0x0 setbyte gBattleCommunication + 1, 0
end2 end2
BattleScript_ArenaTurnBeginning:: BattleScript_ArenaTurnBeginning::

View File

@ -390,7 +390,7 @@ struct BattleStruct
u8 expGetterBattlerId; u8 expGetterBattlerId;
u8 unused_5; u8 unused_5;
u8 field_91; // related to gAbsentBattlerFlags, possibly absent flags turn ago? u8 field_91; // related to gAbsentBattlerFlags, possibly absent flags turn ago?
u8 field_92; // battle palace related u8 palaceFlags; // First 4 bits are "is < 50% HP and not asleep" for each battler, last 4 bits are selected moves to pass to AI
u8 field_93; // related to choosing pokemon? u8 field_93; // related to choosing pokemon?
u8 wallyBattleState; u8 wallyBattleState;
u8 wallyMovesState; u8 wallyMovesState;

View File

@ -1,6 +1,8 @@
#ifndef GUARD_BATTLE_SCRIPT_COMMANDS_H #ifndef GUARD_BATTLE_SCRIPT_COMMANDS_H
#define GUARD_BATTLE_SCRIPT_COMMANDS_H #define GUARD_BATTLE_SCRIPT_COMMANDS_H
#include "constants/pokemon.h"
#define WINDOW_CLEAR 0x1 #define WINDOW_CLEAR 0x1
#define WINDOW_x80 0x80 #define WINDOW_x80 0x80
@ -16,6 +18,6 @@ void HandleBattleWindow(u8 xStart, u8 yStart, u8 xEnd, u8 yEnd, u8 flags);
bool8 UproarWakeUpCheck(u8 battlerId); bool8 UproarWakeUpCheck(u8 battlerId);
extern void (* const gBattleScriptingCommandsTable[])(void); extern void (* const gBattleScriptingCommandsTable[])(void);
extern const u8 gUnknown_0831C494[][4]; extern const u8 gBattlePalaceNatureToMoveGroupLikelihood[NUM_NATURES][4];
#endif // GUARD_BATTLE_SCRIPT_COMMANDS_H #endif // GUARD_BATTLE_SCRIPT_COMMANDS_H

View File

@ -205,7 +205,7 @@ extern const u8 BattleScript_BerryStatRaiseEnd2[];
extern const u8 BattleScript_BerryFocusEnergyEnd2[]; extern const u8 BattleScript_BerryFocusEnergyEnd2[];
extern const u8 BattleScript_ActionSelectionItemsCantBeUsed[]; extern const u8 BattleScript_ActionSelectionItemsCantBeUsed[];
extern const u8 BattleScript_ArenaTurnBeginning[]; extern const u8 BattleScript_ArenaTurnBeginning[];
extern const u8 BattleScript_82DB881[]; extern const u8 BattleScript_PalacePrintFlavorText[];
extern const u8 BattleScript_ArenaDoJudgment[]; extern const u8 BattleScript_ArenaDoJudgment[];
extern const u8 BattleScript_82DAA0B[]; extern const u8 BattleScript_82DAA0B[];
extern const u8 BattleScript_AskIfWantsToForfeitMatch[]; extern const u8 BattleScript_AskIfWantsToForfeitMatch[];

View File

@ -37,146 +37,156 @@
#define B_SIDE_PLAYER 0 #define B_SIDE_PLAYER 0
#define B_SIDE_OPPONENT 1 #define B_SIDE_OPPONENT 1
#define B_FLANK_LEFT 0 #define B_FLANK_LEFT 0
#define B_FLANK_RIGHT 1 #define B_FLANK_RIGHT 1
#define BIT_SIDE 1 #define BIT_SIDE 1
#define BIT_FLANK 2 #define BIT_FLANK 2
// Battle Type Flags // Battle Type Flags
#define BATTLE_TYPE_DOUBLE 0x0001 #define BATTLE_TYPE_DOUBLE (1 << 0)
#define BATTLE_TYPE_LINK 0x0002 #define BATTLE_TYPE_LINK (1 << 1)
#define BATTLE_TYPE_IS_MASTER 0x0004 // In not-link battles, it's always set. #define BATTLE_TYPE_IS_MASTER (1 << 2) // In not-link battles, it's always set.
#define BATTLE_TYPE_TRAINER 0x0008 #define BATTLE_TYPE_TRAINER (1 << 3)
#define BATTLE_TYPE_FIRST_BATTLE 0x0010 #define BATTLE_TYPE_FIRST_BATTLE (1 << 4)
#define BATTLE_TYPE_20 0x0020 #define BATTLE_TYPE_20 (1 << 5)
#define BATTLE_TYPE_MULTI 0x0040 #define BATTLE_TYPE_MULTI (1 << 6)
#define BATTLE_TYPE_SAFARI 0x0080 #define BATTLE_TYPE_SAFARI (1 << 7)
#define BATTLE_TYPE_BATTLE_TOWER 0x0100 #define BATTLE_TYPE_BATTLE_TOWER (1 << 8)
#define BATTLE_TYPE_WALLY_TUTORIAL 0x0200 #define BATTLE_TYPE_WALLY_TUTORIAL (1 << 9)
#define BATTLE_TYPE_ROAMER 0x0400 #define BATTLE_TYPE_ROAMER (1 << 10)
#define BATTLE_TYPE_EREADER_TRAINER 0x0800 #define BATTLE_TYPE_EREADER_TRAINER (1 << 11)
#define BATTLE_TYPE_KYOGRE_GROUDON 0x1000 #define BATTLE_TYPE_KYOGRE_GROUDON (1 << 12)
#define BATTLE_TYPE_LEGENDARY 0x2000 #define BATTLE_TYPE_LEGENDARY (1 << 13)
#define BATTLE_TYPE_REGI 0x4000 #define BATTLE_TYPE_REGI (1 << 14)
#define BATTLE_TYPE_TWO_OPPONENTS 0x8000 #define BATTLE_TYPE_TWO_OPPONENTS (1 << 15)
#define BATTLE_TYPE_DOME 0x10000 #define BATTLE_TYPE_DOME (1 << 16)
#define BATTLE_TYPE_PALACE 0x20000 #define BATTLE_TYPE_PALACE (1 << 17)
#define BATTLE_TYPE_ARENA 0x40000 #define BATTLE_TYPE_ARENA (1 << 18)
#define BATTLE_TYPE_FACTORY 0x80000 #define BATTLE_TYPE_FACTORY (1 << 19)
#define BATTLE_TYPE_PIKE 0x100000 #define BATTLE_TYPE_PIKE (1 << 20)
#define BATTLE_TYPE_PYRAMID 0x200000 #define BATTLE_TYPE_PYRAMID (1 << 21)
#define BATTLE_TYPE_INGAME_PARTNER 0x400000 #define BATTLE_TYPE_INGAME_PARTNER (1 << 22)
#define BATTLE_TYPE_x800000 0x800000 #define BATTLE_TYPE_x800000 (1 << 23)
#define BATTLE_TYPE_RECORDED 0x1000000 #define BATTLE_TYPE_RECORDED (1 << 24)
#define BATTLE_TYPE_x2000000 0x2000000 #define BATTLE_TYPE_x2000000 (1 << 25)
#define BATTLE_TYPE_TRAINER_HILL 0x4000000 #define BATTLE_TYPE_TRAINER_HILL (1 << 26)
#define BATTLE_TYPE_SECRET_BASE 0x8000000 #define BATTLE_TYPE_SECRET_BASE (1 << 27)
#define BATTLE_TYPE_GROUDON 0x10000000 #define BATTLE_TYPE_GROUDON (1 << 28)
#define BATTLE_TYPE_KYOGRE 0x20000000 #define BATTLE_TYPE_KYOGRE (1 << 29)
#define BATTLE_TYPE_RAYQUAZA 0x40000000 #define BATTLE_TYPE_RAYQUAZA (1 << 30)
#define BATTLE_TYPE_x80000000 0x80000000 #define BATTLE_TYPE_x80000000 (1 << 31)
#define BATTLE_TYPE_FRONTIER (BATTLE_TYPE_BATTLE_TOWER | BATTLE_TYPE_DOME | BATTLE_TYPE_PALACE | BATTLE_TYPE_ARENA | BATTLE_TYPE_FACTORY | BATTLE_TYPE_PIKE | BATTLE_TYPE_PYRAMID) #define BATTLE_TYPE_FRONTIER (BATTLE_TYPE_BATTLE_TOWER | BATTLE_TYPE_DOME | BATTLE_TYPE_PALACE | BATTLE_TYPE_ARENA | BATTLE_TYPE_FACTORY | BATTLE_TYPE_PIKE | BATTLE_TYPE_PYRAMID)
#define BATTLE_TYPE_FRONTIER_NO_PYRAMID (BATTLE_TYPE_BATTLE_TOWER | BATTLE_TYPE_DOME | BATTLE_TYPE_PALACE | BATTLE_TYPE_ARENA | BATTLE_TYPE_FACTORY | BATTLE_TYPE_PIKE) #define BATTLE_TYPE_FRONTIER_NO_PYRAMID (BATTLE_TYPE_BATTLE_TOWER | BATTLE_TYPE_DOME | BATTLE_TYPE_PALACE | BATTLE_TYPE_ARENA | BATTLE_TYPE_FACTORY | BATTLE_TYPE_PIKE)
// Battle Outcome defines // Battle Outcome defines
#define B_OUTCOME_WON 0x1 #define B_OUTCOME_WON 1
#define B_OUTCOME_LOST 0x2 #define B_OUTCOME_LOST 2
#define B_OUTCOME_DREW 0x3 #define B_OUTCOME_DREW 3
#define B_OUTCOME_RAN 0x4 #define B_OUTCOME_RAN 4
#define B_OUTCOME_PLAYER_TELEPORTED 0x5 #define B_OUTCOME_PLAYER_TELEPORTED 5
#define B_OUTCOME_MON_FLED 0x6 #define B_OUTCOME_MON_FLED 6
#define B_OUTCOME_CAUGHT 0x7 #define B_OUTCOME_CAUGHT 7
#define B_OUTCOME_NO_SAFARI_BALLS 0x8 #define B_OUTCOME_NO_SAFARI_BALLS 8
#define B_OUTCOME_FORFEITED 0x9 #define B_OUTCOME_FORFEITED 9
#define B_OUTCOME_MON_TELEPORTED 0xA #define B_OUTCOME_MON_TELEPORTED 10
#define B_OUTCOME_LINK_BATTLE_RAN 0x80 #define B_OUTCOME_LINK_BATTLE_RAN 128
// Non-volatile status conditions // Non-volatile status conditions
// These persist remain outside of battle and after switching out // These persist remain outside of battle and after switching out
#define STATUS1_NONE 0x0 #define STATUS1_NONE 0
#define STATUS1_SLEEP 0x7 #define STATUS1_SLEEP (1 << 0 | 1 << 1 | 1 << 2) // First 3 bits (Number of turns to sleep)
#define STATUS1_POISON 0x8 #define STATUS1_SLEEP_TURN(num) ((num) << 0) // Just for readability (or if rearranging statuses)
#define STATUS1_BURN 0x10 #define STATUS1_POISON (1 << 3)
#define STATUS1_FREEZE 0x20 #define STATUS1_BURN (1 << 4)
#define STATUS1_PARALYSIS 0x40 #define STATUS1_FREEZE (1 << 5)
#define STATUS1_TOXIC_POISON 0x80 #define STATUS1_PARALYSIS (1 << 6)
#define STATUS1_TOXIC_COUNTER 0xF00 #define STATUS1_TOXIC_POISON (1 << 7)
#define STATUS1_TOXIC_COUNTER (1 << 8 | 1 << 9 | 1 << 10 | 1 << 11)
#define STATUS1_TOXIC_TURN(num) ((num) << 8)
#define STATUS1_PSN_ANY (STATUS1_POISON | STATUS1_TOXIC_POISON) #define STATUS1_PSN_ANY (STATUS1_POISON | STATUS1_TOXIC_POISON)
#define STATUS1_ANY (STATUS1_SLEEP | STATUS1_POISON | STATUS1_BURN | STATUS1_FREEZE | STATUS1_PARALYSIS | STATUS1_TOXIC_POISON) #define STATUS1_ANY (STATUS1_SLEEP | STATUS1_POISON | STATUS1_BURN | STATUS1_FREEZE | STATUS1_PARALYSIS | STATUS1_TOXIC_POISON)
// Volatile status ailments // Volatile status ailments
// These are removed after exiting the battle or switching out // These are removed after exiting the battle or switching out
#define STATUS2_CONFUSION 0x00000007 #define STATUS2_CONFUSION (1 << 0 | 1 << 1 | 1 << 2)
#define STATUS2_FLINCHED 0x00000008 #define STATUS2_CONFUSION_TURN(num) ((num) << 0)
#define STATUS2_UPROAR 0x00000070 #define STATUS2_FLINCHED (1 << 3)
#define STATUS2_BIDE 0x00000300 // two bits 0x100, 0x200 #define STATUS2_UPROAR (1 << 4 | 1 << 5 | 1 << 6)
#define STATUS2_LOCK_CONFUSE 0x00000C00 #define STATUS2_UPROAR_TURN(num) ((num) << 4)
#define STATUS2_MULTIPLETURNS 0x00001000 #define STATUS2_UNUSED (1 << 7)
#define STATUS2_WRAPPED 0x0000E000 #define STATUS2_BIDE (1 << 8 | 1 << 9)
#define STATUS2_INFATUATION 0x000F0000 // 4 bits, one for every battler #define STATUS2_BIDE_TURN(num) (((num) << 8) & STATUS2_BIDE)
#define STATUS2_LOCK_CONFUSE (1 << 10 | 1 << 11) // e.g. Thrash
#define STATUS2_LOCK_CONFUSE_TURN(num)((num) << 10)
#define STATUS2_MULTIPLETURNS (1 << 12)
#define STATUS2_WRAPPED (1 << 13 | 1 << 14 | 1 << 15)
#define STATUS2_WRAPPED_TURN(num) ((num) << 13)
#define STATUS2_INFATUATION (1 << 16 | 1 << 17 | 1 << 18 | 1 << 19) // 4 bits, one for every battler
#define STATUS2_INFATUATED_WITH(battler) (gBitTable[battler] << 16) #define STATUS2_INFATUATED_WITH(battler) (gBitTable[battler] << 16)
#define STATUS2_FOCUS_ENERGY 0x00100000 #define STATUS2_FOCUS_ENERGY (1 << 20)
#define STATUS2_TRANSFORMED 0x00200000 #define STATUS2_TRANSFORMED (1 << 21)
#define STATUS2_RECHARGE 0x00400000 #define STATUS2_RECHARGE (1 << 22)
#define STATUS2_RAGE 0x00800000 #define STATUS2_RAGE (1 << 23)
#define STATUS2_SUBSTITUTE 0x01000000 #define STATUS2_SUBSTITUTE (1 << 24)
#define STATUS2_DESTINY_BOND 0x02000000 #define STATUS2_DESTINY_BOND (1 << 25)
#define STATUS2_ESCAPE_PREVENTION 0x04000000 #define STATUS2_ESCAPE_PREVENTION (1 << 26)
#define STATUS2_NIGHTMARE 0x08000000 #define STATUS2_NIGHTMARE (1 << 27)
#define STATUS2_CURSED 0x10000000 #define STATUS2_CURSED (1 << 28)
#define STATUS2_FORESIGHT 0x20000000 #define STATUS2_FORESIGHT (1 << 29)
#define STATUS2_DEFENSE_CURL 0x40000000 #define STATUS2_DEFENSE_CURL (1 << 30)
#define STATUS2_TORMENT 0x80000000 #define STATUS2_TORMENT (1 << 31)
// Seems like per-battler statuses. Not quite sure how to categorize these // Seems like per-battler statuses. Not quite sure how to categorize these
#define STATUS3_LEECHSEED_BATTLER 0x3 #define STATUS3_LEECHSEED_BATTLER (1 << 0 | 1 << 1) // The battler to receive HP from Leech Seed
#define STATUS3_LEECHSEED 0x4 #define STATUS3_LEECHSEED (1 << 2)
#define STATUS3_ALWAYS_HITS 0x18 // two bits #define STATUS3_ALWAYS_HITS (1 << 3 | 1 << 4)
#define STATUS3_PERISH_SONG 0x20 #define STATUS3_ALWAYS_HITS_TURN(num) (((num) << 3) & STATUS3_ALWAYS_HITS) // "Always Hits" is set as a 2 turn timer, i.e. next turn is the last turn when it's active
#define STATUS3_ON_AIR 0x40 #define STATUS3_PERISH_SONG (1 << 5)
#define STATUS3_UNDERGROUND 0x80 #define STATUS3_ON_AIR (1 << 6)
#define STATUS3_MINIMIZED 0x100 #define STATUS3_UNDERGROUND (1 << 7)
#define STATUS3_ROOTED 0x400 #define STATUS3_MINIMIZED (1 << 8)
#define STATUS3_CHARGED_UP 0x200 #define STATUS3_CHARGED_UP (1 << 9)
#define STATUS3_YAWN 0x1800 // two bits #define STATUS3_ROOTED (1 << 10)
#define STATUS3_IMPRISONED_OTHERS 0x2000 #define STATUS3_YAWN (1 << 11 | 1 << 12) // Number of turns to sleep
#define STATUS3_GRUDGE 0x4000 #define STATUS3_YAWN_TURN(num) (((num) << 11) & STATUS3_YAWN)
#define STATUS3_CANT_SCORE_A_CRIT 0x8000 #define STATUS3_IMPRISONED_OTHERS (1 << 13)
#define STATUS3_MUDSPORT 0x10000 #define STATUS3_GRUDGE (1 << 14)
#define STATUS3_WATERSPORT 0x20000 #define STATUS3_CANT_SCORE_A_CRIT (1 << 15)
#define STATUS3_UNDERWATER 0x40000 #define STATUS3_MUDSPORT (1 << 16)
#define STATUS3_INTIMIDATE_POKES 0x80000 #define STATUS3_WATERSPORT (1 << 17)
#define STATUS3_TRACE 0x100000 #define STATUS3_UNDERWATER (1 << 18)
#define STATUS3_INTIMIDATE_POKES (1 << 19)
#define STATUS3_TRACE (1 << 20)
#define STATUS3_SEMI_INVULNERABLE (STATUS3_UNDERGROUND | STATUS3_ON_AIR | STATUS3_UNDERWATER) #define STATUS3_SEMI_INVULNERABLE (STATUS3_UNDERGROUND | STATUS3_ON_AIR | STATUS3_UNDERWATER)
// Not really sure what a "hitmarker" is. // Not really sure what a "hitmarker" is.
#define HITMARKER_x10 0x00000010 #define HITMARKER_x10 (1 << 4)
#define HITMARKER_x20 0x00000020 #define HITMARKER_x20 (1 << 5)
#define HITMARKER_DESTINYBOND 0x00000040 #define HITMARKER_DESTINYBOND (1 << 6)
#define HITMARKER_NO_ANIMATIONS 0x00000080 #define HITMARKER_NO_ANIMATIONS (1 << 7)
#define HITMARKER_IGNORE_SUBSTITUTE 0x00000100 #define HITMARKER_IGNORE_SUBSTITUTE (1 << 8)
#define HITMARKER_NO_ATTACKSTRING 0x00000200 #define HITMARKER_NO_ATTACKSTRING (1 << 9)
#define HITMARKER_ATTACKSTRING_PRINTED 0x00000400 #define HITMARKER_ATTACKSTRING_PRINTED (1 << 10)
#define HITMARKER_NO_PPDEDUCT 0x00000800 #define HITMARKER_NO_PPDEDUCT (1 << 11)
#define HITMARKER_SWAP_ATTACKER_TARGET 0x00001000 #define HITMARKER_SWAP_ATTACKER_TARGET (1 << 12)
#define HITMARKER_IGNORE_SAFEGUARD 0x00002000 #define HITMARKER_IGNORE_SAFEGUARD (1 << 13)
#define HITMARKER_SYNCHRONISE_EFFECT 0x00004000 #define HITMARKER_SYNCHRONISE_EFFECT (1 << 14)
#define HITMARKER_RUN 0x00008000 #define HITMARKER_RUN (1 << 15)
#define HITMARKER_IGNORE_ON_AIR 0x00010000 #define HITMARKER_IGNORE_ON_AIR (1 << 16)
#define HITMARKER_IGNORE_UNDERGROUND 0x00020000 #define HITMARKER_IGNORE_UNDERGROUND (1 << 17)
#define HITMARKER_IGNORE_UNDERWATER 0x00040000 #define HITMARKER_IGNORE_UNDERWATER (1 << 18)
#define HITMARKER_UNABLE_TO_USE_MOVE 0x00080000 #define HITMARKER_UNABLE_TO_USE_MOVE (1 << 19)
#define HITMARKER_x100000 0x00100000 #define HITMARKER_x100000 (1 << 20)
#define HITMARKER_x200000 0x00200000 #define HITMARKER_x200000 (1 << 21)
#define HITMARKER_x400000 0x00400000 #define HITMARKER_x400000 (1 << 22)
#define HITMARKER_x800000 0x00800000 #define HITMARKER_x800000 (1 << 23)
#define HITMARKER_GRUDGE 0x01000000 #define HITMARKER_GRUDGE (1 << 24)
#define HITMARKER_OBEYS 0x02000000 #define HITMARKER_OBEYS (1 << 25)
#define HITMARKER_x4000000 0x04000000 #define HITMARKER_x4000000 (1 << 26)
#define HITMARKER_CHARGING 0x08000000 #define HITMARKER_CHARGING (1 << 27)
#define HITMARKER_FAINTED(battler) (gBitTable[battler] << 0x1C) #define HITMARKER_FAINTED(battler) (gBitTable[battler] << 28)
#define HITMARKER_UNK(battler) (0x10000000 << battler) #define HITMARKER_FAINTED2(battler) (1 << (28 + battler))
// Per-side statuses that affect an entire party // Per-side statuses that affect an entire party
#define SIDE_STATUS_REFLECT (1 << 0) #define SIDE_STATUS_REFLECT (1 << 0)
@ -215,71 +225,70 @@
#define WEATHER_ANY (WEATHER_RAIN_ANY | WEATHER_SANDSTORM_ANY | WEATHER_SUN_ANY | WEATHER_HAIL_ANY) #define WEATHER_ANY (WEATHER_RAIN_ANY | WEATHER_SANDSTORM_ANY | WEATHER_SUN_ANY | WEATHER_HAIL_ANY)
// Move Effects // Move Effects
#define MOVE_EFFECT_SLEEP 0x1 #define MOVE_EFFECT_SLEEP 1
#define MOVE_EFFECT_POISON 0x2 #define MOVE_EFFECT_POISON 2
#define MOVE_EFFECT_BURN 0x3 #define MOVE_EFFECT_BURN 3
#define MOVE_EFFECT_FREEZE 0x4 #define MOVE_EFFECT_FREEZE 4
#define MOVE_EFFECT_PARALYSIS 0x5 #define MOVE_EFFECT_PARALYSIS 5
#define MOVE_EFFECT_TOXIC 0x6 #define MOVE_EFFECT_TOXIC 6
#define MOVE_EFFECT_CONFUSION 0x7 #define PRIMARY_STATUS_MOVE_EFFECT MOVE_EFFECT_TOXIC // All above move effects apply primary status
#define MOVE_EFFECT_FLINCH 0x8 #define MOVE_EFFECT_CONFUSION 7
#define MOVE_EFFECT_TRI_ATTACK 0x9 #define MOVE_EFFECT_FLINCH 8
#define MOVE_EFFECT_UPROAR 0xA #define MOVE_EFFECT_TRI_ATTACK 9
#define MOVE_EFFECT_PAYDAY 0xB #define MOVE_EFFECT_UPROAR 10
#define MOVE_EFFECT_CHARGING 0xC #define MOVE_EFFECT_PAYDAY 11
#define MOVE_EFFECT_WRAP 0xD #define MOVE_EFFECT_CHARGING 12
#define MOVE_EFFECT_RECOIL_25 0xE #define MOVE_EFFECT_WRAP 13
#define MOVE_EFFECT_ATK_PLUS_1 0xF #define MOVE_EFFECT_RECOIL_25 14
#define MOVE_EFFECT_DEF_PLUS_1 0x10 #define MOVE_EFFECT_ATK_PLUS_1 15
#define MOVE_EFFECT_SPD_PLUS_1 0x11 #define MOVE_EFFECT_DEF_PLUS_1 16
#define MOVE_EFFECT_SP_ATK_PLUS_1 0x12 #define MOVE_EFFECT_SPD_PLUS_1 17
#define MOVE_EFFECT_SP_DEF_PLUS_1 0x13 #define MOVE_EFFECT_SP_ATK_PLUS_1 18
#define MOVE_EFFECT_ACC_PLUS_1 0x14 #define MOVE_EFFECT_SP_DEF_PLUS_1 19
#define MOVE_EFFECT_EVS_PLUS_1 0x15 #define MOVE_EFFECT_ACC_PLUS_1 20
#define MOVE_EFFECT_ATK_MINUS_1 0x16 #define MOVE_EFFECT_EVS_PLUS_1 21
#define MOVE_EFFECT_DEF_MINUS_1 0x17 #define MOVE_EFFECT_ATK_MINUS_1 22
#define MOVE_EFFECT_SPD_MINUS_1 0x18 #define MOVE_EFFECT_DEF_MINUS_1 23
#define MOVE_EFFECT_SP_ATK_MINUS_1 0x19 #define MOVE_EFFECT_SPD_MINUS_1 24
#define MOVE_EFFECT_SP_DEF_MINUS_1 0x1A #define MOVE_EFFECT_SP_ATK_MINUS_1 25
#define MOVE_EFFECT_ACC_MINUS_1 0x1B #define MOVE_EFFECT_SP_DEF_MINUS_1 26
#define MOVE_EFFECT_EVS_MINUS_1 0x1C #define MOVE_EFFECT_ACC_MINUS_1 27
#define MOVE_EFFECT_RECHARGE 0x1D #define MOVE_EFFECT_EVS_MINUS_1 28
#define MOVE_EFFECT_RAGE 0x1E #define MOVE_EFFECT_RECHARGE 29
#define MOVE_EFFECT_STEAL_ITEM 0x1F #define MOVE_EFFECT_RAGE 30
#define MOVE_EFFECT_PREVENT_ESCAPE 0x20 #define MOVE_EFFECT_STEAL_ITEM 31
#define MOVE_EFFECT_NIGHTMARE 0x21 #define MOVE_EFFECT_PREVENT_ESCAPE 32
#define MOVE_EFFECT_ALL_STATS_UP 0x22 #define MOVE_EFFECT_NIGHTMARE 33
#define MOVE_EFFECT_RAPIDSPIN 0x23 #define MOVE_EFFECT_ALL_STATS_UP 34
#define MOVE_EFFECT_REMOVE_PARALYSIS 0x24 #define MOVE_EFFECT_RAPIDSPIN 35
#define MOVE_EFFECT_ATK_DEF_DOWN 0x25 #define MOVE_EFFECT_REMOVE_PARALYSIS 36
#define MOVE_EFFECT_RECOIL_33 0x26 #define MOVE_EFFECT_ATK_DEF_DOWN 37
#define MOVE_EFFECT_ATK_PLUS_2 0x27 #define MOVE_EFFECT_RECOIL_33 38
#define MOVE_EFFECT_DEF_PLUS_2 0x28 #define MOVE_EFFECT_ATK_PLUS_2 39
#define MOVE_EFFECT_SPD_PLUS_2 0x29 #define MOVE_EFFECT_DEF_PLUS_2 40
#define MOVE_EFFECT_SP_ATK_PLUS_2 0x2A #define MOVE_EFFECT_SPD_PLUS_2 41
#define MOVE_EFFECT_SP_DEF_PLUS_2 0x2B #define MOVE_EFFECT_SP_ATK_PLUS_2 42
#define MOVE_EFFECT_ACC_PLUS_2 0x2C #define MOVE_EFFECT_SP_DEF_PLUS_2 43
#define MOVE_EFFECT_EVS_PLUS_2 0x2D #define MOVE_EFFECT_ACC_PLUS_2 44
#define MOVE_EFFECT_ATK_MINUS_2 0x2E #define MOVE_EFFECT_EVS_PLUS_2 45
#define MOVE_EFFECT_DEF_MINUS_2 0x2F #define MOVE_EFFECT_ATK_MINUS_2 46
#define MOVE_EFFECT_SPD_MINUS_2 0x30 #define MOVE_EFFECT_DEF_MINUS_2 47
#define MOVE_EFFECT_SP_ATK_MINUS_2 0x31 #define MOVE_EFFECT_SPD_MINUS_2 48
#define MOVE_EFFECT_SP_DEF_MINUS_2 0x32 #define MOVE_EFFECT_SP_ATK_MINUS_2 49
#define MOVE_EFFECT_ACC_MINUS_2 0x33 #define MOVE_EFFECT_SP_DEF_MINUS_2 50
#define MOVE_EFFECT_EVS_MINUS_2 0x34 #define MOVE_EFFECT_ACC_MINUS_2 51
#define MOVE_EFFECT_THRASH 0x35 #define MOVE_EFFECT_EVS_MINUS_2 52
#define MOVE_EFFECT_KNOCK_OFF 0x36 #define MOVE_EFFECT_THRASH 53
#define MOVE_EFFECT_NOTHING_37 0x37 #define MOVE_EFFECT_KNOCK_OFF 54
#define MOVE_EFFECT_NOTHING_38 0x38 #define MOVE_EFFECT_NOTHING_37 55
#define MOVE_EFFECT_NOTHING_39 0x39 #define MOVE_EFFECT_NOTHING_38 56
#define MOVE_EFFECT_NOTHING_3A 0x3A #define MOVE_EFFECT_NOTHING_39 57
#define MOVE_EFFECT_SP_ATK_TWO_DOWN 0x3B #define MOVE_EFFECT_NOTHING_3A 58
#define MOVE_EFFECT_NOTHING_3C 0x3C #define MOVE_EFFECT_SP_ATK_TWO_DOWN 59
#define MOVE_EFFECT_NOTHING_3D 0x3D #define NUM_MOVE_EFFECTS 60
#define MOVE_EFFECT_NOTHING_3E 0x3E
#define MOVE_EFFECT_NOTHING_3F 0x3F #define MOVE_EFFECT_AFFECTS_USER 64
#define MOVE_EFFECT_AFFECTS_USER 0x40 #define MOVE_EFFECT_CERTAIN 128
#define MOVE_EFFECT_CERTAIN 0x80
// Battle terrain defines for gBattleTerrain. // Battle terrain defines for gBattleTerrain.
#define BATTLE_TERRAIN_GRASS 0 #define BATTLE_TERRAIN_GRASS 0

View File

@ -16,4 +16,14 @@
#define PALACE_DATA_WIN_STREAK 1 #define PALACE_DATA_WIN_STREAK 1
#define PALACE_DATA_WIN_STREAK_ACTIVE 2 #define PALACE_DATA_WIN_STREAK_ACTIVE 2
// Pokemon in Battle Palace have a move "group" type preference depending on nature
#define PALACE_MOVE_GROUP_ATTACK 0
#define PALACE_MOVE_GROUP_DEFENSE 1
#define PALACE_MOVE_GROUP_SUPPORT 2
// In palace doubles battles pokemon have a target preference depending on nature
#define PALACE_TARGET_STRONGER 0
#define PALACE_TARGET_WEAKER 1
#define PALACE_TARGET_RANDOM 2
#endif //GUARD_CONSTANTS_BATTLE_PALACE_H #endif //GUARD_CONSTANTS_BATTLE_PALACE_H

View File

@ -66,8 +66,10 @@
#define VARIOUS_SET_MAGIC_COAT_TARGET 1 #define VARIOUS_SET_MAGIC_COAT_TARGET 1
#define VARIOUS_IS_RUNNING_IMPOSSIBLE 2 #define VARIOUS_IS_RUNNING_IMPOSSIBLE 2
#define VARIOUS_GET_MOVE_TARGET 3 #define VARIOUS_GET_MOVE_TARGET 3
#define VARIOUS_GET_BATTLER_FAINTED 4
#define VARIOUS_RESET_INTIMIDATE_TRACE_BITS 5 #define VARIOUS_RESET_INTIMIDATE_TRACE_BITS 5
#define VARIOUS_UPDATE_CHOICE_MOVE_ON_LVL_UP 6 #define VARIOUS_UPDATE_CHOICE_MOVE_ON_LVL_UP 6
#define VARIOUS_PALACE_FLAVOR_TEXT 8
#define VARIOUS_ARENA_JUDGMENT_WINDOW 9 #define VARIOUS_ARENA_JUDGMENT_WINDOW 9
#define VARIOUS_ARENA_OPPONENT_MON_LOST 10 #define VARIOUS_ARENA_OPPONENT_MON_LOST 10
#define VARIOUS_ARENA_PLAYER_MON_LOST 11 #define VARIOUS_ARENA_PLAYER_MON_LOST 11

View File

@ -69,6 +69,7 @@
#define NATURE_SASSY 22 #define NATURE_SASSY 22
#define NATURE_CAREFUL 23 #define NATURE_CAREFUL 23
#define NATURE_QUIRKY 24 #define NATURE_QUIRKY 24
#define NUM_NATURES 25
// Pokemon Stats // Pokemon Stats
#define STAT_HP 0 #define STAT_HP 0
@ -80,7 +81,7 @@
#define STAT_ACC 6 // Only in battles. #define STAT_ACC 6 // Only in battles.
#define STAT_EVASION 7 // Only in battles. #define STAT_EVASION 7 // Only in battles.
#define NUM_EV_STATS NUM_STATS - 1 // excludes HP #define NUM_NATURE_STATS NUM_STATS - 1 // excludes HP
#define NUM_BATTLE_STATS NUM_STATS + 2 // includes Accuracy and Evasion #define NUM_BATTLE_STATS NUM_STATS + 2 // includes Accuracy and Evasion
// Shiny odds // Shiny odds

View File

@ -1,6 +1,9 @@
#ifndef GUARD_POKEBLOCK_H #ifndef GUARD_POKEBLOCK_H
#define GUARD_POKEBLOCK_H #define GUARD_POKEBLOCK_H
#include "constants/berry.h"
#include "constants/pokemon.h"
#define GFX_TAG_POKEBLOCK 14818 #define GFX_TAG_POKEBLOCK 14818
#define GFX_TAG_POKEBLOCK_CASE 14800 #define GFX_TAG_POKEBLOCK_CASE 14800
@ -43,7 +46,7 @@ void ChooseMonToGivePokeblock(struct Pokeblock *pokeblock, void (*callback)(void
void CB2_PreparePokeblockFeedScene(void); void CB2_PreparePokeblockFeedScene(void);
// pokeblock // pokeblock
extern const s8 gPokeblockFlavorCompatibilityTable[]; extern const s8 gPokeblockFlavorCompatibilityTable[NUM_NATURES * FLAVOR_COUNT];
extern const u8 *const gPokeblockNames[]; extern const u8 *const gPokeblockNames[];
extern const struct CompressedSpriteSheet gPokeblockCase_SpriteSheet; extern const struct CompressedSpriteSheet gPokeblockCase_SpriteSheet;
extern const struct CompressedSpritePalette gPokeblockCase_SpritePal; extern const struct CompressedSpritePalette gPokeblockCase_SpritePal;

View File

@ -471,9 +471,9 @@ static u8 ChooseMoveOrAction_Doubles(void)
else else
{ {
if (gBattleTypeFlags & BATTLE_TYPE_PALACE) if (gBattleTypeFlags & BATTLE_TYPE_PALACE)
BattleAI_SetupAIData(gBattleStruct->field_92 >> 4); BattleAI_SetupAIData(gBattleStruct->palaceFlags >> 4);
else else
BattleAI_SetupAIData(0xF); BattleAI_SetupAIData((1 << MAX_MON_MOVES) - 1);
gBattlerTarget = i; gBattlerTarget = i;

View File

@ -6,39 +6,40 @@
#include "sprite.h" #include "sprite.h"
#include "util.h" #include "util.h"
#include "constants/pokemon.h" #include "constants/pokemon.h"
#include "constants/battle_palace.h"
static void SmokescreenImpact_Callback(struct Sprite *); static void SmokescreenImpact_Callback(struct Sprite *);
static void SpriteCB_DestroySprite(struct Sprite *sprite); static void SpriteCB_DestroySprite(struct Sprite *sprite);
// The below data for smokescreen starts and ends with some data that belongs to battle_gfx_sfx_util.c // The below data for smokescreen starts and ends with some data that belongs to battle_gfx_sfx_util.c
const u8 gUnknown_0831C604[] = const u8 gBattlePalaceNatureToMoveTarget[NUM_NATURES] =
{ {
[NATURE_HARDY] = 0, [NATURE_HARDY] = PALACE_TARGET_STRONGER,
[NATURE_LONELY] = 0, [NATURE_LONELY] = PALACE_TARGET_STRONGER,
[NATURE_BRAVE] = 1, [NATURE_BRAVE] = PALACE_TARGET_WEAKER,
[NATURE_ADAMANT] = 0, [NATURE_ADAMANT] = PALACE_TARGET_STRONGER,
[NATURE_NAUGHTY] = 1, [NATURE_NAUGHTY] = PALACE_TARGET_WEAKER,
[NATURE_BOLD] = 1, [NATURE_BOLD] = PALACE_TARGET_WEAKER,
[NATURE_DOCILE] = 2, [NATURE_DOCILE] = PALACE_TARGET_RANDOM,
[NATURE_RELAXED] = 0, [NATURE_RELAXED] = PALACE_TARGET_STRONGER,
[NATURE_IMPISH] = 0, [NATURE_IMPISH] = PALACE_TARGET_STRONGER,
[NATURE_LAX] = 0, [NATURE_LAX] = PALACE_TARGET_STRONGER,
[NATURE_TIMID] = 1, [NATURE_TIMID] = PALACE_TARGET_WEAKER,
[NATURE_HASTY] = 1, [NATURE_HASTY] = PALACE_TARGET_WEAKER,
[NATURE_SERIOUS] = 1, [NATURE_SERIOUS] = PALACE_TARGET_WEAKER,
[NATURE_JOLLY] = 0, [NATURE_JOLLY] = PALACE_TARGET_STRONGER,
[NATURE_NAIVE] = 2, [NATURE_NAIVE] = PALACE_TARGET_RANDOM,
[NATURE_MODEST] = 1, [NATURE_MODEST] = PALACE_TARGET_WEAKER,
[NATURE_MILD] = 0, [NATURE_MILD] = PALACE_TARGET_STRONGER,
[NATURE_QUIET] = 1, [NATURE_QUIET] = PALACE_TARGET_WEAKER,
[NATURE_BASHFUL] = 1, [NATURE_BASHFUL] = PALACE_TARGET_WEAKER,
[NATURE_RASH] = 0, [NATURE_RASH] = PALACE_TARGET_STRONGER,
[NATURE_CALM] = 0, [NATURE_CALM] = PALACE_TARGET_STRONGER,
[NATURE_GENTLE] = 0, [NATURE_GENTLE] = PALACE_TARGET_STRONGER,
[NATURE_SASSY] = 1, [NATURE_SASSY] = PALACE_TARGET_WEAKER,
[NATURE_CAREFUL] = 1, [NATURE_CAREFUL] = PALACE_TARGET_WEAKER,
[NATURE_QUIRKY] = 0, [NATURE_QUIRKY] = PALACE_TARGET_STRONGER,
}; };
static const struct CompressedSpriteSheet sSmokescreenImpactSpriteSheet = static const struct CompressedSpriteSheet sSmokescreenImpactSpriteSheet =

View File

@ -4692,7 +4692,7 @@ static void DisplayTrainerInfoOnCard(u8 flags, u8 trainerTourneyId)
allocatedArray[NUM_STATS] += allocatedArray[STAT_HP]; allocatedArray[NUM_STATS] += allocatedArray[STAT_HP];
// Add the EVs with the nature modifier for this mon and and track number of negative natures // Add the EVs with the nature modifier for this mon and and track number of negative natures
for (j = 0; j < NUM_EV_STATS; j++) for (j = 0; j < NUM_NATURE_STATS; j++)
{ {
if (trainerId == TRAINER_FRONTIER_BRAIN) if (trainerId == TRAINER_FRONTIER_BRAIN)
nature = GetFrontierBrainMonNature(i); nature = GetFrontierBrainMonNature(i);
@ -4706,7 +4706,7 @@ static void DisplayTrainerInfoOnCard(u8 flags, u8 trainerTourneyId)
else if (gNatureStatTable[nature][j] < 0) else if (gNatureStatTable[nature][j] < 0)
{ {
allocatedArray[j + NUM_STATS + 1] += (allocatedArray[j + 1] * 90) / 100; allocatedArray[j + NUM_STATS + 1] += (allocatedArray[j + 1] * 90) / 100;
allocatedArray[j + NUM_STATS + NUM_EV_STATS + 2]++; allocatedArray[j + NUM_STATS + NUM_NATURE_STATS + 2]++;
} }
else else
{ {
@ -4742,7 +4742,7 @@ static void DisplayTrainerInfoOnCard(u8 flags, u8 trainerTourneyId)
} }
allocatedArray[NUM_STATS] += allocatedArray[STAT_HP]; allocatedArray[NUM_STATS] += allocatedArray[STAT_HP];
for (j = 0; j < NUM_EV_STATS; j++) for (j = 0; j < NUM_NATURE_STATS; j++)
{ {
nature = gFacilityTrainerMons[DOME_MONS[trainerTourneyId][i]].nature; nature = gFacilityTrainerMons[DOME_MONS[trainerTourneyId][i]].nature;
if (gNatureStatTable[nature][j] > 0) if (gNatureStatTable[nature][j] > 0)
@ -4752,7 +4752,7 @@ static void DisplayTrainerInfoOnCard(u8 flags, u8 trainerTourneyId)
else if (gNatureStatTable[nature][j] < 0) else if (gNatureStatTable[nature][j] < 0)
{ {
allocatedArray[j + NUM_STATS + 1] += (allocatedArray[j + 1] * 90) / 100; allocatedArray[j + NUM_STATS + 1] += (allocatedArray[j + 1] * 90) / 100;
allocatedArray[j + NUM_STATS + NUM_EV_STATS + 2]++; allocatedArray[j + NUM_STATS + NUM_NATURE_STATS + 2]++;
} }
else else
{ {

View File

@ -24,20 +24,21 @@
#include "contest.h" #include "contest.h"
#include "constants/songs.h" #include "constants/songs.h"
#include "constants/rgb.h" #include "constants/rgb.h"
#include "constants/battle_palace.h"
extern struct MusicPlayerInfo gMPlayInfo_SE1; extern struct MusicPlayerInfo gMPlayInfo_SE1;
extern struct MusicPlayerInfo gMPlayInfo_SE2; extern struct MusicPlayerInfo gMPlayInfo_SE2;
extern struct MusicPlayerInfo gMPlayInfo_BGM; extern struct MusicPlayerInfo gMPlayInfo_BGM;
extern const u8 gUnknown_0831C604[]; extern const u8 gBattlePalaceNatureToMoveTarget[];
extern const u8 * const gBattleAnims_General[]; extern const u8 * const gBattleAnims_General[];
extern const u8 * const gBattleAnims_Special[]; extern const u8 * const gBattleAnims_Special[];
extern const struct CompressedSpriteSheet gSpriteSheet_EnemyShadow; extern const struct CompressedSpriteSheet gSpriteSheet_EnemyShadow;
extern const struct SpriteTemplate gSpriteTemplate_EnemyShadow; extern const struct SpriteTemplate gSpriteTemplate_EnemyShadow;
// this file's functions // this file's functions
static u8 sub_805D4A8(u16 move); static u8 GetBattlePalaceMoveGroup(u16 move);
static u16 BattlePalaceGetTargetRetValue(void); static u16 GetBattlePalaceTarget(void);
static void sub_805D7EC(struct Sprite *sprite); static void sub_805D7EC(struct Sprite *sprite);
static bool8 ShouldAnimBeDoneRegardlessOfSubsitute(u8 animId); static bool8 ShouldAnimBeDoneRegardlessOfSubsitute(u8 animId);
static void Task_ClearBitWhenBattleTableAnimDone(u8 taskId); static void Task_ClearBitWhenBattleTableAnimDone(u8 taskId);
@ -108,6 +109,7 @@ void FreeBattleSpritesData(void)
FREE_AND_SET_NULL(gBattleSpritesDataPtr); FREE_AND_SET_NULL(gBattleSpritesDataPtr);
} }
// Pokemon chooses move to use in Battle Palace rather than player
u16 ChooseMoveAndTargetInBattlePalace(void) u16 ChooseMoveAndTargetInBattlePalace(void)
{ {
s32 i, var1, var2; s32 i, var1, var2;
@ -116,60 +118,88 @@ u16 ChooseMoveAndTargetInBattlePalace(void)
u8 unusableMovesBits = CheckMoveLimitations(gActiveBattler, 0, 0xFF); u8 unusableMovesBits = CheckMoveLimitations(gActiveBattler, 0, 0xFF);
s32 percent = Random() % 100; s32 percent = Random() % 100;
i = (gBattleStruct->field_92 & gBitTable[gActiveBattler]) ? 2 : 0; // Heavy variable re-use here makes this hard to read without defines
var2 = i; // Possibly just optimization? might still match with additional vars
var1 = i + 2; #define maxGroupNum var1
#define minGroupNum var2
#define selectedGroup percent
#define selectedMoves var2
#define moveTarget var1
#define validMoveFlags var1
#define numValidMoveGroups var2
#define validMoveGroup var2
for (; i < var1; i++) // If battler is < 50% HP and not asleep, use second set of move group likelihoods
// otherwise use first set
i = (gBattleStruct->palaceFlags & gBitTable[gActiveBattler]) ? 2 : 0;
minGroupNum = i;
maxGroupNum = i + 2; // + 2 because there are two percentages per set of likelihoods
// Each nature has a different percent chance to select a move from one of 3 move groups
// If percent is less than 1st check, use move from "Attack" group
// If percent is less than 2nd check, use move from "Defense" group
// Otherwise use move from "Support" group
for (; i < maxGroupNum; i++)
{ {
if (gUnknown_0831C494[GetNatureFromPersonality(gBattleMons[gActiveBattler].personality)][i] > percent) if (gBattlePalaceNatureToMoveGroupLikelihood[GetNatureFromPersonality(gBattleMons[gActiveBattler].personality)][i] > percent)
break; break;
} }
selectedGroup = i - minGroupNum;
if (i == maxGroupNum)
selectedGroup = PALACE_MOVE_GROUP_SUPPORT;
percent = i - var2; // Flag moves that match selected group, to be passed to AI
if (i == var1) for (selectedMoves = 0, i = 0; i < MAX_MON_MOVES; i++)
percent = 2;
for (var2 = 0, i = 0; i < MAX_MON_MOVES; i++)
{ {
if (moveInfo->moves[i] == MOVE_NONE) if (moveInfo->moves[i] == MOVE_NONE)
break; break;
if (percent == sub_805D4A8(moveInfo->moves[i]) && moveInfo->currentPp[i] != 0) if (selectedGroup == GetBattlePalaceMoveGroup(moveInfo->moves[i]) && moveInfo->currentPp[i] != 0)
var2 |= gBitTable[i]; selectedMoves |= gBitTable[i];
} }
if (var2 != 0) // Pass selected moves to AI, pick one
if (selectedMoves != 0)
{ {
gBattleStruct->field_92 &= 0xF; gBattleStruct->palaceFlags &= 0xF;
gBattleStruct->field_92 |= (var2 << 4); gBattleStruct->palaceFlags |= (selectedMoves << 4);
BattleAI_SetupAIData(var2); BattleAI_SetupAIData(selectedMoves);
chosenMoveId = BattleAI_ChooseMoveOrAction(); chosenMoveId = BattleAI_ChooseMoveOrAction();
} }
// If no moves matched the selected group, pick a new move from groups the pokemon has
// In this case the AI is not checked again, so the choice may be worse
// If a move is chosen this way, there's a 50% chance that it will be unable to use it anyway
if (chosenMoveId == -1) if (chosenMoveId == -1)
{ {
if (unusableMovesBits != 0xF) if (unusableMovesBits != 0xF)
{ {
var1 = 0, var2 = 0; validMoveFlags = 0, numValidMoveGroups = 0;
for (i = 0; i < MAX_MON_MOVES; i++) for (i = 0; i < MAX_MON_MOVES; i++)
{ {
if (sub_805D4A8(moveInfo->moves[i]) == 0 && !(gBitTable[i] & unusableMovesBits)) // validMoveFlags is used here as a bitfield for which moves can be used for each move group type
var1 += 0x1; // first 4 bits are for attack (1 for each move), then 4 bits for defense, and 4 for support
if (sub_805D4A8(moveInfo->moves[i]) == 1 && !(gBitTable[i] & unusableMovesBits)) if (GetBattlePalaceMoveGroup(moveInfo->moves[i]) == PALACE_MOVE_GROUP_ATTACK && !(gBitTable[i] & unusableMovesBits))
var1 += 0x10; validMoveFlags += (1 << 0);
if (sub_805D4A8(moveInfo->moves[i]) == 2 && !(gBitTable[i] & unusableMovesBits)) if (GetBattlePalaceMoveGroup(moveInfo->moves[i]) == PALACE_MOVE_GROUP_DEFENSE && !(gBitTable[i] & unusableMovesBits))
var1 += 0x100; validMoveFlags += (1 << 4);
if (GetBattlePalaceMoveGroup(moveInfo->moves[i]) == PALACE_MOVE_GROUP_SUPPORT && !(gBitTable[i] & unusableMovesBits))
validMoveFlags += (1 << 8);
} }
if ((var1 & 0xF) > 1) // Count the move groups the pokemon has
var2++; if ((validMoveFlags & 0xF) > 1)
if ((var1 & 0xF0) > 0x1F) numValidMoveGroups++;
var2++; if ((validMoveFlags & 0xF0) > 0x1F)
if ((var1 & 0xF0) > 0x1FF) numValidMoveGroups++;
var2++; if ((validMoveFlags & 0xF0) > 0x1FF)
numValidMoveGroups++;
if (var2 > 1 || var2 == 0)
// If more than 1 possible move group, or no possible move groups
// then choose move randomly
if (numValidMoveGroups > 1 || numValidMoveGroups == 0)
{ {
do do
{ {
@ -178,32 +208,35 @@ u16 ChooseMoveAndTargetInBattlePalace(void)
chosenMoveId = i; chosenMoveId = i;
} while (chosenMoveId == -1); } while (chosenMoveId == -1);
} }
// Otherwise randomly choose move of only available move group
else else
{ {
if ((var1 & 0xF) > 1) if ((validMoveFlags & 0xF) > 1)
var2 = 0; validMoveGroup = PALACE_MOVE_GROUP_ATTACK;
if ((var1 & 0xF0) > 0x1F) if ((validMoveFlags & 0xF0) > 0x1F)
var2 = 1; validMoveGroup = PALACE_MOVE_GROUP_DEFENSE;
if ((var1 & 0xF0) > 0x1FF) if ((validMoveFlags & 0xF0) > 0x1FF)
var2 = 2; validMoveGroup = PALACE_MOVE_GROUP_SUPPORT;
do do
{ {
i = Random() % MAX_MON_MOVES; i = Random() % MAX_MON_MOVES;
if (!(gBitTable[i] & unusableMovesBits) && var2 == sub_805D4A8(moveInfo->moves[i])) if (!(gBitTable[i] & unusableMovesBits) && validMoveGroup == GetBattlePalaceMoveGroup(moveInfo->moves[i]))
chosenMoveId = i; chosenMoveId = i;
} while (chosenMoveId == -1); } while (chosenMoveId == -1);
} }
// If a move was selected (and in this case was not from the Nature-chosen group)
// then there's a 50% chance it won't be used anyway
if (Random() % 100 > 49) if (Random() % 100 > 49)
{ {
gProtectStructs[gActiveBattler].palaceUnableToUseMove = 1; gProtectStructs[gActiveBattler].palaceUnableToUseMove = TRUE;
return 0; return 0;
} }
} }
else else
{ {
gProtectStructs[gActiveBattler].palaceUnableToUseMove = 1; gProtectStructs[gActiveBattler].palaceUnableToUseMove = TRUE;
return 0; return 0;
} }
} }
@ -211,26 +244,35 @@ u16 ChooseMoveAndTargetInBattlePalace(void)
if (moveInfo->moves[chosenMoveId] == MOVE_CURSE) if (moveInfo->moves[chosenMoveId] == MOVE_CURSE)
{ {
if (moveInfo->monType1 != TYPE_GHOST && moveInfo->monType2 != TYPE_GHOST) if (moveInfo->monType1 != TYPE_GHOST && moveInfo->monType2 != TYPE_GHOST)
var1 = MOVE_TARGET_USER; moveTarget = MOVE_TARGET_USER;
else else
var1 = MOVE_TARGET_SELECTED; moveTarget = MOVE_TARGET_SELECTED;
} }
else else
{ {
var1 = gBattleMoves[moveInfo->moves[chosenMoveId]].target; moveTarget = gBattleMoves[moveInfo->moves[chosenMoveId]].target;
} }
if (var1 & MOVE_TARGET_USER) if (moveTarget & MOVE_TARGET_USER)
chosenMoveId |= (gActiveBattler << 8); chosenMoveId |= (gActiveBattler << 8);
else if (var1 == MOVE_TARGET_SELECTED) else if (moveTarget == MOVE_TARGET_SELECTED)
chosenMoveId |= (BattlePalaceGetTargetRetValue()); chosenMoveId |= GetBattlePalaceTarget();
else else
chosenMoveId |= (GetBattlerAtPosition((GetBattlerPosition(gActiveBattler) & BIT_SIDE) ^ BIT_SIDE) << 8); chosenMoveId |= (GetBattlerAtPosition((GetBattlerPosition(gActiveBattler) & BIT_SIDE) ^ BIT_SIDE) << 8);
return chosenMoveId; return chosenMoveId;
} }
static u8 sub_805D4A8(u16 move) #undef maxGroupNum
#undef minGroupNum
#undef selectedGroup
#undef selectedMoves
#undef moveTarget
#undef validMoveFlags
#undef numValidMoveGroups
#undef validMoveGroup
static u8 GetBattlePalaceMoveGroup(u16 move)
{ {
switch (gBattleMoves[move].target) switch (gBattleMoves[move].target)
{ {
@ -240,21 +282,21 @@ static u8 sub_805D4A8(u16 move)
case MOVE_TARGET_BOTH: case MOVE_TARGET_BOTH:
case MOVE_TARGET_FOES_AND_ALLY: case MOVE_TARGET_FOES_AND_ALLY:
if (gBattleMoves[move].power == 0) if (gBattleMoves[move].power == 0)
return 2; return PALACE_MOVE_GROUP_SUPPORT;
else else
return 0; return PALACE_MOVE_GROUP_ATTACK;
break; break;
case MOVE_TARGET_DEPENDS: case MOVE_TARGET_DEPENDS:
case MOVE_TARGET_OPPONENTS_FIELD: case MOVE_TARGET_OPPONENTS_FIELD:
return 2; return PALACE_MOVE_GROUP_SUPPORT;
case MOVE_TARGET_USER: case MOVE_TARGET_USER:
return 1; return PALACE_MOVE_GROUP_DEFENSE;
default: default:
return 0; return PALACE_MOVE_GROUP_ATTACK;
} }
} }
static u16 BattlePalaceGetTargetRetValue(void) static u16 GetBattlePalaceTarget(void)
{ {
if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
{ {
@ -274,19 +316,19 @@ static u16 BattlePalaceGetTargetRetValue(void)
if (gBattleMons[opposing1].hp == gBattleMons[opposing2].hp) if (gBattleMons[opposing1].hp == gBattleMons[opposing2].hp)
return (((gActiveBattler & BIT_SIDE) ^ BIT_SIDE) + (Random() & 2)) << 8; return (((gActiveBattler & BIT_SIDE) ^ BIT_SIDE) + (Random() & 2)) << 8;
switch (gUnknown_0831C604[GetNatureFromPersonality(gBattleMons[gActiveBattler].personality)]) switch (gBattlePalaceNatureToMoveTarget[GetNatureFromPersonality(gBattleMons[gActiveBattler].personality)])
{ {
case 0: case PALACE_TARGET_STRONGER:
if (gBattleMons[opposing1].hp > gBattleMons[opposing2].hp) if (gBattleMons[opposing1].hp > gBattleMons[opposing2].hp)
return opposing1 << 8; return opposing1 << 8;
else else
return opposing2 << 8; return opposing2 << 8;
case 1: case PALACE_TARGET_WEAKER:
if (gBattleMons[opposing1].hp < gBattleMons[opposing2].hp) if (gBattleMons[opposing1].hp < gBattleMons[opposing2].hp)
return opposing1 << 8; return opposing1 << 8;
else else
return opposing2 << 8; return opposing2 << 8;
case 2: case PALACE_TARGET_RANDOM:
return (((gActiveBattler & BIT_SIDE) ^ BIT_SIDE) + (Random() & 2)) << 8; return (((gActiveBattler & BIT_SIDE) ^ BIT_SIDE) + (Random() & 2)) << 8;
} }
} }

View File

@ -3112,7 +3112,7 @@ static void BattleStartClearSetData(void)
} }
gBattleStruct->givenExpMons = 0; gBattleStruct->givenExpMons = 0;
gBattleStruct->field_92 = 0; gBattleStruct->palaceFlags = 0;
gRandomTurnNumber = Random(); gRandomTurnNumber = Random();
@ -3159,7 +3159,7 @@ void SwitchInClearSetData(void)
&& (gDisableStructs[i].battlerWithSureHit == gActiveBattler)) && (gDisableStructs[i].battlerWithSureHit == gActiveBattler))
{ {
gStatuses3[i] &= ~(STATUS3_ALWAYS_HITS); gStatuses3[i] &= ~(STATUS3_ALWAYS_HITS);
gStatuses3[i] |= 0x10; gStatuses3[i] |= STATUS3_ALWAYS_HITS_TURN(2);
} }
} }
} }
@ -3214,7 +3214,7 @@ void SwitchInClearSetData(void)
*(3 * 2 + gActiveBattler * 8 + (u8*)(gBattleStruct->lastTakenMoveFrom) + 0) = 0; *(3 * 2 + gActiveBattler * 8 + (u8*)(gBattleStruct->lastTakenMoveFrom) + 0) = 0;
*(3 * 2 + gActiveBattler * 8 + (u8*)(gBattleStruct->lastTakenMoveFrom) + 1) = 0; *(3 * 2 + gActiveBattler * 8 + (u8*)(gBattleStruct->lastTakenMoveFrom) + 1) = 0;
gBattleStruct->field_92 &= ~(gBitTable[gActiveBattler]); gBattleStruct->palaceFlags &= ~(gBitTable[gActiveBattler]);
for (i = 0; i < gBattlersCount; i++) for (i = 0; i < gBattlersCount; i++)
{ {
@ -3309,7 +3309,7 @@ void FaintClearSetData(void)
*(3 * 2 + gActiveBattler * 8 + (u8*)(gBattleStruct->lastTakenMoveFrom) + 0) = 0; *(3 * 2 + gActiveBattler * 8 + (u8*)(gBattleStruct->lastTakenMoveFrom) + 0) = 0;
*(3 * 2 + gActiveBattler * 8 + (u8*)(gBattleStruct->lastTakenMoveFrom) + 1) = 0; *(3 * 2 + gActiveBattler * 8 + (u8*)(gBattleStruct->lastTakenMoveFrom) + 1) = 0;
gBattleStruct->field_92 &= ~(gBitTable[gActiveBattler]); gBattleStruct->palaceFlags &= ~(gBitTable[gActiveBattler]);
for (i = 0; i < gBattlersCount; i++) for (i = 0; i < gBattlersCount; i++)
{ {
@ -4052,7 +4052,7 @@ void BattleTurnPassed(void)
gRandomTurnNumber = Random(); gRandomTurnNumber = Random();
if (gBattleTypeFlags & BATTLE_TYPE_PALACE) if (gBattleTypeFlags & BATTLE_TYPE_PALACE)
BattleScriptExecute(BattleScript_82DB881); BattleScriptExecute(BattleScript_PalacePrintFlavorText);
else if (gBattleTypeFlags & BATTLE_TYPE_ARENA && gBattleStruct->arenaTurnCounter == 0) else if (gBattleTypeFlags & BATTLE_TYPE_ARENA && gBattleStruct->arenaTurnCounter == 0)
BattleScriptExecute(BattleScript_ArenaTurnBeginning); BattleScriptExecute(BattleScript_ArenaTurnBeginning);
} }

View File

@ -1267,10 +1267,12 @@ static const u8 sText_PkmnGettingIntoPosition[] = _("{B_SCR_ACTIVE_NAME_WITH_PRE
static const u8 sText_PkmnBeganGrowlingDeeply[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX} began growling deeply!"); static const u8 sText_PkmnBeganGrowlingDeeply[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX} began growling deeply!");
static const u8 sText_PkmnEagerForMore[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX} is eager for more!"); static const u8 sText_PkmnEagerForMore[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX} is eager for more!");
const u16 gStringIds_85CCF0A[] = const u16 gBattlePalaceFlavorTextTable[] =
{ {
STRINGID_GLINTAPPEARSINEYE, STRINGID_PKMNGETTINGINTOPOSITION, STRINGID_GLINTAPPEARSINEYE,
STRINGID_PKMNBEGANGROWLINGDEEPLY, STRINGID_PKMNEAGERFORMORE STRINGID_PKMNGETTINGINTOPOSITION,
STRINGID_PKMNBEGANGROWLINGDEEPLY,
STRINGID_PKMNEAGERFORMORE
}; };
static const u8 sText_RefIfNothingIsDecided[] = _("REFEREE: If nothing is decided in\n3 turns, we will go to judging!"); static const u8 sText_RefIfNothingIsDecided[] = _("REFEREE: If nothing is decided in\n3 turns, we will go to judging!");

View File

@ -606,111 +606,66 @@ static const struct StatFractions sAccuracyStageRatios[] =
// The chance is 1/N for each stage. // The chance is 1/N for each stage.
static const u16 sCriticalHitChance[] = {16, 8, 4, 3, 2}; static const u16 sCriticalHitChance[] = {16, 8, 4, 3, 2};
static const u32 sStatusFlagsForMoveEffects[] = static const u32 sStatusFlagsForMoveEffects[NUM_MOVE_EFFECTS] =
{ {
0x00000000, [MOVE_EFFECT_SLEEP] = STATUS1_SLEEP,
STATUS1_SLEEP, [MOVE_EFFECT_POISON] = STATUS1_POISON,
STATUS1_POISON, [MOVE_EFFECT_BURN] = STATUS1_BURN,
STATUS1_BURN, [MOVE_EFFECT_FREEZE] = STATUS1_FREEZE,
STATUS1_FREEZE, [MOVE_EFFECT_PARALYSIS] = STATUS1_PARALYSIS,
STATUS1_PARALYSIS, [MOVE_EFFECT_TOXIC] = STATUS1_TOXIC_POISON,
STATUS1_TOXIC_POISON, [MOVE_EFFECT_CONFUSION] = STATUS2_CONFUSION,
STATUS2_CONFUSION, [MOVE_EFFECT_FLINCH] = STATUS2_FLINCHED,
STATUS2_FLINCHED, [MOVE_EFFECT_UPROAR] = STATUS2_UPROAR,
0x00000000, [MOVE_EFFECT_CHARGING] = STATUS2_MULTIPLETURNS,
STATUS2_UPROAR, [MOVE_EFFECT_WRAP] = STATUS2_WRAPPED,
0x00000000, [MOVE_EFFECT_RECHARGE] = STATUS2_RECHARGE,
STATUS2_MULTIPLETURNS, [MOVE_EFFECT_PREVENT_ESCAPE] = STATUS2_ESCAPE_PREVENTION,
STATUS2_WRAPPED, [MOVE_EFFECT_NIGHTMARE] = STATUS2_NIGHTMARE,
0x00000000, [MOVE_EFFECT_THRASH] = STATUS2_LOCK_CONFUSE,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
STATUS2_RECHARGE,
0x00000000,
0x00000000,
STATUS2_ESCAPE_PREVENTION,
STATUS2_NIGHTMARE,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
STATUS2_LOCK_CONFUSE,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x00000000
}; };
static const u8* const sMoveEffectBS_Ptrs[] = static const u8* const sMoveEffectBS_Ptrs[] =
{ {
[0] = BattleScript_MoveEffectSleep, [0] = BattleScript_MoveEffectSleep,
[MOVE_EFFECT_SLEEP] = BattleScript_MoveEffectSleep, [MOVE_EFFECT_SLEEP] = BattleScript_MoveEffectSleep,
[MOVE_EFFECT_POISON] = BattleScript_MoveEffectPoison, [MOVE_EFFECT_POISON] = BattleScript_MoveEffectPoison,
[MOVE_EFFECT_BURN] = BattleScript_MoveEffectBurn, [MOVE_EFFECT_BURN] = BattleScript_MoveEffectBurn,
[MOVE_EFFECT_FREEZE] = BattleScript_MoveEffectFreeze, [MOVE_EFFECT_FREEZE] = BattleScript_MoveEffectFreeze,
[MOVE_EFFECT_PARALYSIS] = BattleScript_MoveEffectParalysis, [MOVE_EFFECT_PARALYSIS] = BattleScript_MoveEffectParalysis,
[MOVE_EFFECT_TOXIC] = BattleScript_MoveEffectToxic, [MOVE_EFFECT_TOXIC] = BattleScript_MoveEffectToxic,
[MOVE_EFFECT_CONFUSION] = BattleScript_MoveEffectConfusion, [MOVE_EFFECT_CONFUSION] = BattleScript_MoveEffectConfusion,
[MOVE_EFFECT_FLINCH] = BattleScript_MoveEffectSleep, [MOVE_EFFECT_FLINCH] = BattleScript_MoveEffectSleep,
[MOVE_EFFECT_TRI_ATTACK] = BattleScript_MoveEffectSleep, [MOVE_EFFECT_TRI_ATTACK] = BattleScript_MoveEffectSleep,
[MOVE_EFFECT_UPROAR] = BattleScript_MoveEffectUproar, [MOVE_EFFECT_UPROAR] = BattleScript_MoveEffectUproar,
[MOVE_EFFECT_PAYDAY] = BattleScript_MoveEffectPayDay, [MOVE_EFFECT_PAYDAY] = BattleScript_MoveEffectPayDay,
[MOVE_EFFECT_CHARGING] = BattleScript_MoveEffectSleep, [MOVE_EFFECT_CHARGING] = BattleScript_MoveEffectSleep,
[MOVE_EFFECT_WRAP] = BattleScript_MoveEffectWrap, [MOVE_EFFECT_WRAP] = BattleScript_MoveEffectWrap,
[MOVE_EFFECT_RECOIL_25] = BattleScript_MoveEffectRecoil, [MOVE_EFFECT_RECOIL_25] = BattleScript_MoveEffectRecoil,
[MOVE_EFFECT_ATK_PLUS_1] = BattleScript_MoveEffectSleep, [MOVE_EFFECT_ATK_PLUS_1] = BattleScript_MoveEffectSleep,
[MOVE_EFFECT_DEF_PLUS_1] = BattleScript_MoveEffectSleep, [MOVE_EFFECT_DEF_PLUS_1] = BattleScript_MoveEffectSleep,
[MOVE_EFFECT_SPD_PLUS_1] = BattleScript_MoveEffectSleep, [MOVE_EFFECT_SPD_PLUS_1] = BattleScript_MoveEffectSleep,
[MOVE_EFFECT_SP_ATK_PLUS_1] = BattleScript_MoveEffectSleep, [MOVE_EFFECT_SP_ATK_PLUS_1] = BattleScript_MoveEffectSleep,
[MOVE_EFFECT_SP_DEF_PLUS_1] = BattleScript_MoveEffectSleep, [MOVE_EFFECT_SP_DEF_PLUS_1] = BattleScript_MoveEffectSleep,
[MOVE_EFFECT_ACC_PLUS_1] = BattleScript_MoveEffectSleep, [MOVE_EFFECT_ACC_PLUS_1] = BattleScript_MoveEffectSleep,
[MOVE_EFFECT_EVS_PLUS_1] = BattleScript_MoveEffectSleep, [MOVE_EFFECT_EVS_PLUS_1] = BattleScript_MoveEffectSleep,
[MOVE_EFFECT_ATK_MINUS_1] = BattleScript_MoveEffectSleep, [MOVE_EFFECT_ATK_MINUS_1] = BattleScript_MoveEffectSleep,
[MOVE_EFFECT_DEF_MINUS_1] = BattleScript_MoveEffectSleep, [MOVE_EFFECT_DEF_MINUS_1] = BattleScript_MoveEffectSleep,
[MOVE_EFFECT_SPD_MINUS_1] = BattleScript_MoveEffectSleep, [MOVE_EFFECT_SPD_MINUS_1] = BattleScript_MoveEffectSleep,
[MOVE_EFFECT_SP_ATK_MINUS_1] = BattleScript_MoveEffectSleep, [MOVE_EFFECT_SP_ATK_MINUS_1] = BattleScript_MoveEffectSleep,
[MOVE_EFFECT_SP_DEF_MINUS_1] = BattleScript_MoveEffectSleep, [MOVE_EFFECT_SP_DEF_MINUS_1] = BattleScript_MoveEffectSleep,
[MOVE_EFFECT_ACC_MINUS_1] = BattleScript_MoveEffectSleep, [MOVE_EFFECT_ACC_MINUS_1] = BattleScript_MoveEffectSleep,
[MOVE_EFFECT_EVS_MINUS_1] = BattleScript_MoveEffectSleep, [MOVE_EFFECT_EVS_MINUS_1] = BattleScript_MoveEffectSleep,
[MOVE_EFFECT_RECHARGE] = BattleScript_MoveEffectSleep, [MOVE_EFFECT_RECHARGE] = BattleScript_MoveEffectSleep,
[MOVE_EFFECT_RAGE] = BattleScript_MoveEffectSleep, [MOVE_EFFECT_RAGE] = BattleScript_MoveEffectSleep,
[MOVE_EFFECT_STEAL_ITEM] = BattleScript_MoveEffectSleep, [MOVE_EFFECT_STEAL_ITEM] = BattleScript_MoveEffectSleep,
[MOVE_EFFECT_PREVENT_ESCAPE] = BattleScript_MoveEffectSleep, [MOVE_EFFECT_PREVENT_ESCAPE] = BattleScript_MoveEffectSleep,
[MOVE_EFFECT_NIGHTMARE] = BattleScript_MoveEffectSleep, [MOVE_EFFECT_NIGHTMARE] = BattleScript_MoveEffectSleep,
[MOVE_EFFECT_ALL_STATS_UP] = BattleScript_MoveEffectSleep, [MOVE_EFFECT_ALL_STATS_UP] = BattleScript_MoveEffectSleep,
[MOVE_EFFECT_RAPIDSPIN] = BattleScript_MoveEffectSleep, [MOVE_EFFECT_RAPIDSPIN] = BattleScript_MoveEffectSleep,
[MOVE_EFFECT_REMOVE_PARALYSIS] = BattleScript_MoveEffectSleep, [MOVE_EFFECT_REMOVE_PARALYSIS] = BattleScript_MoveEffectSleep,
[MOVE_EFFECT_ATK_DEF_DOWN] = BattleScript_MoveEffectSleep, [MOVE_EFFECT_ATK_DEF_DOWN] = BattleScript_MoveEffectSleep,
[MOVE_EFFECT_RECOIL_33] = BattleScript_MoveEffectRecoil, [MOVE_EFFECT_RECOIL_33] = BattleScript_MoveEffectRecoil,
}; };
static const struct WindowTemplate sUnusedWinTemplate = {0, 1, 3, 7, 0xF, 0x1F, 0x3F}; static const struct WindowTemplate sUnusedWinTemplate = {0, 1, 3, 7, 0xF, 0x1F, 0x3F};
@ -797,16 +752,16 @@ static const u8 sFlailHpScaleToPowerTable[] =
static const u16 sNaturePowerMoves[] = static const u16 sNaturePowerMoves[] =
{ {
MOVE_STUN_SPORE, [BATTLE_TERRAIN_GRASS] = MOVE_STUN_SPORE,
MOVE_RAZOR_LEAF, [BATTLE_TERRAIN_LONG_GRASS] = MOVE_RAZOR_LEAF,
MOVE_EARTHQUAKE, [BATTLE_TERRAIN_SAND] = MOVE_EARTHQUAKE,
MOVE_HYDRO_PUMP, [BATTLE_TERRAIN_UNDERWATER] = MOVE_HYDRO_PUMP,
MOVE_SURF, [BATTLE_TERRAIN_WATER] = MOVE_SURF,
MOVE_BUBBLE_BEAM, [BATTLE_TERRAIN_POND] = MOVE_BUBBLE_BEAM,
MOVE_ROCK_SLIDE, [BATTLE_TERRAIN_MOUNTAIN] = MOVE_ROCK_SLIDE,
MOVE_SHADOW_BALL, [BATTLE_TERRAIN_CAVE] = MOVE_SHADOW_BALL,
MOVE_SWIFT, [BATTLE_TERRAIN_BUILDING] = MOVE_SWIFT,
MOVE_SWIFT [BATTLE_TERRAIN_PLAIN] = MOVE_SWIFT
}; };
// format: min. weight (hectograms), base power // format: min. weight (hectograms), base power
@ -864,58 +819,92 @@ static const u8 sPickupProbabilities[] =
static const u8 sTerrainToType[] = static const u8 sTerrainToType[] =
{ {
TYPE_GRASS, // tall grass [BATTLE_TERRAIN_GRASS] = TYPE_GRASS,
TYPE_GRASS, // long grass [BATTLE_TERRAIN_LONG_GRASS] = TYPE_GRASS,
TYPE_GROUND, // sand [BATTLE_TERRAIN_SAND] = TYPE_GROUND,
TYPE_WATER, // underwater [BATTLE_TERRAIN_UNDERWATER] = TYPE_WATER,
TYPE_WATER, // water [BATTLE_TERRAIN_WATER] = TYPE_WATER,
TYPE_WATER, // pond water [BATTLE_TERRAIN_POND] = TYPE_WATER,
TYPE_ROCK, // rock [BATTLE_TERRAIN_MOUNTAIN] = TYPE_ROCK,
TYPE_ROCK, // cave [BATTLE_TERRAIN_CAVE] = TYPE_ROCK,
TYPE_NORMAL, // building [BATTLE_TERRAIN_BUILDING] = TYPE_NORMAL,
TYPE_NORMAL, // plain [BATTLE_TERRAIN_PLAIN] = TYPE_NORMAL,
}; };
// - ITEM_ULTRA_BALL skips Master Ball and ITEM_NONE
static const u8 sBallCatchBonuses[] = static const u8 sBallCatchBonuses[] =
{ {
20, 15, 10, 15 // Ultra, Great, Poke, Safari [ITEM_ULTRA_BALL - ITEM_ULTRA_BALL] = 20,
[ITEM_GREAT_BALL - ITEM_ULTRA_BALL] = 15,
[ITEM_POKE_BALL - ITEM_ULTRA_BALL] = 10,
[ITEM_SAFARI_BALL - ITEM_ULTRA_BALL] = 15
}; };
const ALIGNED(4) u8 gUnknown_0831C494[][4] = // In Battle Palace, moves are chosen based on the pokemons nature rather than by the player
// Moves are grouped into "Attack", "Defense", or "Support" (see PALACE_MOVE_GROUP_*)
// Each nature has a certain percent chance of selecting a move from a particular group
// and a separate percent chance for each group when below 50% HP
// The table below doesn't list percentages for Support because you can subtract the other two
// Support percentages are listed in comments off to the side instead
#define PALACE_STYLE(atk, def, atkLow, defLow) {atk, atk + def, atkLow, atkLow + defLow}
const ALIGNED(4) u8 gBattlePalaceNatureToMoveGroupLikelihood[NUM_NATURES][4] =
{ {
{0x3d, 0x44, 0x3d, 0x44}, [NATURE_HARDY] = PALACE_STYLE(61, 7, 61, 7), // 32% support >= 50% HP, 32% support < 50% HP
{0x14, 0x2d, 0x54, 0x5c}, [NATURE_LONELY] = PALACE_STYLE(20, 25, 84, 8), // 55%, 8%
{0x46, 0x55, 0x20, 0x5c}, [NATURE_BRAVE] = PALACE_STYLE(70, 15, 32, 60), // 15%, 8%
{0x26, 0x45, 0x46, 0x55}, [NATURE_ADAMANT] = PALACE_STYLE(38, 31, 70, 15), // 31%, 15%
{0x14, 0x5a, 0x46, 0x5c}, [NATURE_NAUGHTY] = PALACE_STYLE(20, 70, 70, 22), // 10%, 8%
{0x1e, 0x32, 0x20, 0x5a}, [NATURE_BOLD] = PALACE_STYLE(30, 20, 32, 58), // 50%, 10%
{0x38, 0x4e, 0x38, 0x4e}, [NATURE_DOCILE] = PALACE_STYLE(56, 22, 56, 22), // 22%, 22%
{0x19, 0x28, 0x4b, 0x5a}, [NATURE_RELAXED] = PALACE_STYLE(25, 15, 75, 15), // 60%, 10%
{0x45, 0x4b, 0x1c, 0x53}, [NATURE_IMPISH] = PALACE_STYLE(69, 6, 28, 55), // 25%, 17%
{0x23, 0x2d, 0x1d, 0x23}, [NATURE_LAX] = PALACE_STYLE(35, 10, 29, 6), // 55%, 65%
{0x3e, 0x48, 0x1e, 0x32}, [NATURE_TIMID] = PALACE_STYLE(62, 10, 30, 20), // 28%, 50%
{0x3a, 0x5f, 0x58, 0x5e}, [NATURE_HASTY] = PALACE_STYLE(58, 37, 88, 6), // 5%, 6%
{0x22, 0x2d, 0x1d, 0x28}, [NATURE_SERIOUS] = PALACE_STYLE(34, 11, 29, 11), // 55%, 60%
{0x23, 0x28, 0x23, 0x5f}, [NATURE_JOLLY] = PALACE_STYLE(35, 5, 35, 60), // 60%, 5%
{0x38, 0x4e, 0x38, 0x4e}, [NATURE_NAIVE] = PALACE_STYLE(56, 22, 56, 22), // 22%, 22%
{0x23, 0x50, 0x22, 0x5e}, [NATURE_MODEST] = PALACE_STYLE(35, 45, 34, 60), // 20%, 6%
{0x2c, 0x5e, 0x22, 0x28}, [NATURE_MILD] = PALACE_STYLE(44, 50, 34, 6), // 6%, 60%
{0x38, 0x4e, 0x38, 0x4e}, [NATURE_QUIET] = PALACE_STYLE(56, 22, 56, 22), // 22%, 22%
{0x1e, 0x58, 0x1e, 0x58}, [NATURE_BASHFUL] = PALACE_STYLE(30, 58, 30, 58), // 12%, 12%
{0x1e, 0x2b, 0x1b, 0x21}, [NATURE_RASH] = PALACE_STYLE(30, 13, 27, 6), // 57%, 67%
{0x28, 0x5a, 0x19, 0x57}, [NATURE_CALM] = PALACE_STYLE(40, 50, 25, 62), // 10%, 13%
{0x12, 0x58, 0x5a, 0x5f}, [NATURE_GENTLE] = PALACE_STYLE(18, 70, 90, 5), // 12%, 5%
{0x58, 0x5e, 0x16, 0x2a}, [NATURE_SASSY] = PALACE_STYLE(88, 6, 22, 20), // 6%, 58%
{0x2a, 0x5c, 0x2a, 0x2f}, [NATURE_CAREFUL] = PALACE_STYLE(42, 50, 42, 5), // 8%, 53%
{0x38, 0x4e, 0x38, 0x4e} [NATURE_QUIRKY] = PALACE_STYLE(56, 22, 56, 22) // 22%, 22%
}; };
static const u8 sUnknown_0831C4F8[] = // Indices into gBattlePalaceFlavorTextTable
static const u8 sBattlePalaceNatureToFlavorTextId[NUM_NATURES] =
{ {
0x03, 0x00, 0x01, 0x00, 0x00, 0x01, 0x03, 0x00, [NATURE_HARDY] = 3,
0x01, 0x02, 0x02, 0x00, 0x03, 0x01, 0x03, 0x01, [NATURE_LONELY] = 0,
0x02, 0x03, 0x03, 0x02, 0x01, 0x00, 0x02, 0x02, [NATURE_BRAVE] = 1,
0x03, 0x00, 0x00, 0x00 [NATURE_ADAMANT] = 0,
[NATURE_NAUGHTY] = 0,
[NATURE_BOLD] = 1,
[NATURE_DOCILE] = 3,
[NATURE_RELAXED] = 0,
[NATURE_IMPISH] = 1,
[NATURE_LAX] = 2,
[NATURE_TIMID] = 2,
[NATURE_HASTY] = 0,
[NATURE_SERIOUS] = 3,
[NATURE_JOLLY] = 1,
[NATURE_NAIVE] = 3,
[NATURE_MODEST] = 1,
[NATURE_MILD] = 2,
[NATURE_QUIET] = 3,
[NATURE_BASHFUL] = 3,
[NATURE_RASH] = 2,
[NATURE_CALM] = 1,
[NATURE_GENTLE] = 0,
[NATURE_SASSY] = 2,
[NATURE_CAREFUL] = 2,
[NATURE_QUIRKY] = 3,
}; };
static void Cmd_attackcanceler(void) static void Cmd_attackcanceler(void)
@ -2245,7 +2234,7 @@ void SetMoveEffect(bool8 primary, u8 certain)
if (gBattleMons[gEffectBattler].status2 & STATUS2_SUBSTITUTE && affectsUser != MOVE_EFFECT_AFFECTS_USER) if (gBattleMons[gEffectBattler].status2 & STATUS2_SUBSTITUTE && affectsUser != MOVE_EFFECT_AFFECTS_USER)
INCREMENT_RESET_RETURN INCREMENT_RESET_RETURN
if (gBattleCommunication[MOVE_EFFECT_BYTE] <= 6) // status change if (gBattleCommunication[MOVE_EFFECT_BYTE] <= PRIMARY_STATUS_MOVE_EFFECT)
{ {
switch (sStatusFlagsForMoveEffects[gBattleCommunication[MOVE_EFFECT_BYTE]]) switch (sStatusFlagsForMoveEffects[gBattleCommunication[MOVE_EFFECT_BYTE]])
{ {
@ -2453,7 +2442,7 @@ void SetMoveEffect(bool8 primary, u8 certain)
BattleScriptPush(gBattlescriptCurrInstr + 1); BattleScriptPush(gBattlescriptCurrInstr + 1);
if (sStatusFlagsForMoveEffects[gBattleCommunication[MOVE_EFFECT_BYTE]] == STATUS1_SLEEP) if (sStatusFlagsForMoveEffects[gBattleCommunication[MOVE_EFFECT_BYTE]] == STATUS1_SLEEP)
gBattleMons[gEffectBattler].status1 |= ((Random() & 3) + 2); gBattleMons[gEffectBattler].status1 |= STATUS1_SLEEP_TURN((Random() & 3) + 2); // 2-5 turns
else else
gBattleMons[gEffectBattler].status1 |= sStatusFlagsForMoveEffects[gBattleCommunication[MOVE_EFFECT_BYTE]]; gBattleMons[gEffectBattler].status1 |= sStatusFlagsForMoveEffects[gBattleCommunication[MOVE_EFFECT_BYTE]];
@ -2513,7 +2502,7 @@ void SetMoveEffect(bool8 primary, u8 certain)
} }
else else
{ {
gBattleMons[gEffectBattler].status2 |= (((Random()) % 0x4)) + 2; gBattleMons[gEffectBattler].status2 |= STATUS2_CONFUSION_TURN(((Random()) % 4) + 2); // 2-5 turns
BattleScriptPush(gBattlescriptCurrInstr + 1); BattleScriptPush(gBattlescriptCurrInstr + 1);
gBattlescriptCurrInstr = sMoveEffectBS_Ptrs[gBattleCommunication[MOVE_EFFECT_BYTE]]; gBattlescriptCurrInstr = sMoveEffectBS_Ptrs[gBattleCommunication[MOVE_EFFECT_BYTE]];
@ -2546,7 +2535,7 @@ void SetMoveEffect(bool8 primary, u8 certain)
gBattleMons[gEffectBattler].status2 |= STATUS2_MULTIPLETURNS; gBattleMons[gEffectBattler].status2 |= STATUS2_MULTIPLETURNS;
gLockedMoves[gEffectBattler] = gCurrentMove; gLockedMoves[gEffectBattler] = gCurrentMove;
gBattleMons[gEffectBattler].status2 |= ((Random() & 3) + 2) << 4; gBattleMons[gEffectBattler].status2 |= STATUS2_UPROAR_TURN((Random() & 3) + 2); // 2-5 turns
BattleScriptPush(gBattlescriptCurrInstr + 1); BattleScriptPush(gBattlescriptCurrInstr + 1);
gBattlescriptCurrInstr = sMoveEffectBS_Ptrs[gBattleCommunication[MOVE_EFFECT_BYTE]]; gBattlescriptCurrInstr = sMoveEffectBS_Ptrs[gBattleCommunication[MOVE_EFFECT_BYTE]];
@ -2591,7 +2580,7 @@ void SetMoveEffect(bool8 primary, u8 certain)
} }
else else
{ {
gBattleMons[gEffectBattler].status2 |= ((Random() & 3) + 3) << 0xD; gBattleMons[gEffectBattler].status2 |= STATUS2_WRAPPED_TURN((Random() & 3) + 3); // 3-6 turns
*(gBattleStruct->wrappedMove + gEffectBattler * 2 + 0) = gCurrentMove; *(gBattleStruct->wrappedMove + gEffectBattler * 2 + 0) = gCurrentMove;
*(gBattleStruct->wrappedMove + gEffectBattler * 2 + 1) = gCurrentMove >> 8; *(gBattleStruct->wrappedMove + gEffectBattler * 2 + 1) = gCurrentMove >> 8;
@ -2834,7 +2823,7 @@ void SetMoveEffect(bool8 primary, u8 certain)
{ {
gBattleMons[gEffectBattler].status2 |= STATUS2_MULTIPLETURNS; gBattleMons[gEffectBattler].status2 |= STATUS2_MULTIPLETURNS;
gLockedMoves[gEffectBattler] = gCurrentMove; gLockedMoves[gEffectBattler] = gCurrentMove;
gBattleMons[gEffectBattler].status2 |= (((Random() & 1) + 2) << 0xA); gBattleMons[gEffectBattler].status2 |= STATUS2_LOCK_CONFUSE_TURN((Random() & 1) + 2); // thrash for 2-3 turns
} }
break; break;
case MOVE_EFFECT_KNOCK_OFF: case MOVE_EFFECT_KNOCK_OFF:
@ -2929,7 +2918,7 @@ static void Cmd_clearstatusfromeffect(void)
{ {
gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]); gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]);
if (gBattleCommunication[MOVE_EFFECT_BYTE] <= MOVE_EFFECT_TOXIC) if (gBattleCommunication[MOVE_EFFECT_BYTE] <= PRIMARY_STATUS_MOVE_EFFECT)
gBattleMons[gActiveBattler].status1 &= (~sStatusFlagsForMoveEffects[gBattleCommunication[MOVE_EFFECT_BYTE]]); gBattleMons[gActiveBattler].status1 &= (~sStatusFlagsForMoveEffects[gBattleCommunication[MOVE_EFFECT_BYTE]]);
else else
gBattleMons[gActiveBattler].status2 &= (~sStatusFlagsForMoveEffects[gBattleCommunication[MOVE_EFFECT_BYTE]]); gBattleMons[gActiveBattler].status2 &= (~sStatusFlagsForMoveEffects[gBattleCommunication[MOVE_EFFECT_BYTE]]);
@ -3482,7 +3471,7 @@ static void Cmd_getexp(void)
else else
{ {
gBattleStruct->expGetterMonId++; gBattleStruct->expGetterMonId++;
if (gBattleStruct->expGetterMonId <= 5) if (gBattleStruct->expGetterMonId < PARTY_SIZE)
gBattleScripting.getexpState = 2; // loop again gBattleScripting.getexpState = 2; // loop again
else else
gBattleScripting.getexpState = 6; // we're done gBattleScripting.getexpState = 6; // we're done
@ -3552,13 +3541,13 @@ static void Cmd_unknown_24(void)
// Impossible to decompile loops. // Impossible to decompile loops.
for (foundPlayer = 0, i = 0; i < gBattlersCount; i += 2) for (foundPlayer = 0, i = 0; i < gBattlersCount; i += 2)
{ {
if (HITMARKER_UNK(i) & gHitMarker && !gSpecialStatuses[i].flag40) if (HITMARKER_FAINTED2(i) & gHitMarker && !gSpecialStatuses[i].flag40)
foundPlayer++; foundPlayer++;
} }
for (foundOpponent = 0, i = 1; i < gBattlersCount; i += 2) for (foundOpponent = 0, i = 1; i < gBattlersCount; i += 2)
{ {
if (HITMARKER_UNK(i) & gHitMarker && !gSpecialStatuses[i].flag40) if (HITMARKER_FAINTED2(i) & gHitMarker && !gSpecialStatuses[i].flag40)
foundOpponent++; foundOpponent++;
} }
@ -4914,10 +4903,12 @@ static void Cmd_switchindataupdate(void)
SwitchInClearSetData(); SwitchInClearSetData();
if (gBattleTypeFlags & BATTLE_TYPE_PALACE && gBattleMons[gActiveBattler].maxHP / 2 >= gBattleMons[gActiveBattler].hp if (gBattleTypeFlags & BATTLE_TYPE_PALACE
&& gBattleMons[gActiveBattler].hp != 0 && !(gBattleMons[gActiveBattler].status1 & STATUS1_SLEEP)) && gBattleMons[gActiveBattler].maxHP / 2 >= gBattleMons[gActiveBattler].hp
&& gBattleMons[gActiveBattler].hp != 0
&& !(gBattleMons[gActiveBattler].status1 & STATUS1_SLEEP))
{ {
gBattleStruct->field_92 |= gBitTable[gActiveBattler]; gBattleStruct->palaceFlags |= gBitTable[gActiveBattler];
} }
gBattleScripting.battler = gActiveBattler; gBattleScripting.battler = gActiveBattler;
@ -5101,7 +5092,7 @@ static void Cmd_jumpifcantswitch(void)
break; break;
} }
if (i == 6) if (i == PARTY_SIZE)
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 2); gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 2);
else else
gBattlescriptCurrInstr += 6; gBattlescriptCurrInstr += 6;
@ -6588,11 +6579,11 @@ static void Cmd_various(void)
case VARIOUS_GET_MOVE_TARGET: case VARIOUS_GET_MOVE_TARGET:
gBattlerTarget = GetMoveTarget(gCurrentMove, 0); gBattlerTarget = GetMoveTarget(gCurrentMove, 0);
break; break;
case 4: case VARIOUS_GET_BATTLER_FAINTED:
if (gHitMarker & HITMARKER_FAINTED(gActiveBattler)) if (gHitMarker & HITMARKER_FAINTED(gActiveBattler))
gBattleCommunication[0] = 1; gBattleCommunication[0] = TRUE;
else else
gBattleCommunication[0] = 0; gBattleCommunication[0] = FALSE;
break; break;
case VARIOUS_RESET_INTIMIDATE_TRACE_BITS: case VARIOUS_RESET_INTIMIDATE_TRACE_BITS:
gSpecialStatuses[gActiveBattler].intimidatedMon = 0; gSpecialStatuses[gActiveBattler].intimidatedMon = 0;
@ -6628,17 +6619,19 @@ static void Cmd_various(void)
gHitMarker &= ~(HITMARKER_x400000); gHitMarker &= ~(HITMARKER_x400000);
} }
break; break;
case 8: case VARIOUS_PALACE_FLAVOR_TEXT:
gBattleCommunication[0] = 0; // Try and print end-of-turn Battle Palace flavor text (e.g. "A glint appears in mon's eyes")
gBattleCommunication[0] = FALSE; // whether or not msg should be printed
gBattleScripting.battler = gActiveBattler = gBattleCommunication[1]; gBattleScripting.battler = gActiveBattler = gBattleCommunication[1];
if (!(gBattleStruct->field_92 & gBitTable[gActiveBattler])
if (!(gBattleStruct->palaceFlags & gBitTable[gActiveBattler])
&& gBattleMons[gActiveBattler].maxHP / 2 >= gBattleMons[gActiveBattler].hp && gBattleMons[gActiveBattler].maxHP / 2 >= gBattleMons[gActiveBattler].hp
&& gBattleMons[gActiveBattler].hp != 0 && gBattleMons[gActiveBattler].hp != 0
&& !(gBattleMons[gActiveBattler].status1 & STATUS1_SLEEP)) && !(gBattleMons[gActiveBattler].status1 & STATUS1_SLEEP))
{ {
gBattleStruct->field_92 |= gBitTable[gActiveBattler]; gBattleStruct->palaceFlags |= gBitTable[gActiveBattler];
gBattleCommunication[0] = 1; gBattleCommunication[0] = TRUE;
gBattleCommunication[MULTISTRING_CHOOSER] = sUnknown_0831C4F8[GetNatureFromPersonality(gBattleMons[gActiveBattler].personality)]; gBattleCommunication[MULTISTRING_CHOOSER] = sBattlePalaceNatureToFlavorTextId[GetNatureFromPersonality(gBattleMons[gActiveBattler].personality)];
} }
break; break;
case VARIOUS_ARENA_JUDGMENT_WINDOW: case VARIOUS_ARENA_JUDGMENT_WINDOW:
@ -7368,7 +7361,7 @@ static void Cmd_setbide(void)
gBattleMons[gBattlerAttacker].status2 |= STATUS2_MULTIPLETURNS; gBattleMons[gBattlerAttacker].status2 |= STATUS2_MULTIPLETURNS;
gLockedMoves[gBattlerAttacker] = gCurrentMove; gLockedMoves[gBattlerAttacker] = gCurrentMove;
gTakenDmg[gBattlerAttacker] = 0; gTakenDmg[gBattlerAttacker] = 0;
gBattleMons[gBattlerAttacker].status2 |= (STATUS2_BIDE - 0x100); // 2 turns gBattleMons[gBattlerAttacker].status2 |= STATUS2_BIDE_TURN(2);
gBattlescriptCurrInstr++; gBattlescriptCurrInstr++;
} }
@ -8326,7 +8319,7 @@ static void Cmd_settypetorandomresistance(void) // conversion 2
static void Cmd_setalwayshitflag(void) static void Cmd_setalwayshitflag(void)
{ {
gStatuses3[gBattlerTarget] &= ~(STATUS3_ALWAYS_HITS); gStatuses3[gBattlerTarget] &= ~(STATUS3_ALWAYS_HITS);
gStatuses3[gBattlerTarget] |= 0x10; gStatuses3[gBattlerTarget] |= STATUS3_ALWAYS_HITS_TURN(2);
gDisableStructs[gBattlerTarget].battlerWithSureHit = gBattlerAttacker; gDisableStructs[gBattlerTarget].battlerWithSureHit = gBattlerAttacker;
gBattlescriptCurrInstr++; gBattlescriptCurrInstr++;
} }
@ -9145,7 +9138,7 @@ static void Cmd_trydobeatup(void)
else else
{ {
u8 beforeLoop = gBattleCommunication[0]; u8 beforeLoop = gBattleCommunication[0];
for (;gBattleCommunication[0] < 6; gBattleCommunication[0]++) for (;gBattleCommunication[0] < PARTY_SIZE; gBattleCommunication[0]++)
{ {
if (GetMonData(&party[gBattleCommunication[0]], MON_DATA_HP) if (GetMonData(&party[gBattleCommunication[0]], MON_DATA_HP)
&& GetMonData(&party[gBattleCommunication[0]], MON_DATA_SPECIES2) && GetMonData(&party[gBattleCommunication[0]], MON_DATA_SPECIES2)
@ -9153,7 +9146,7 @@ static void Cmd_trydobeatup(void)
&& !GetMonData(&party[gBattleCommunication[0]], MON_DATA_STATUS)) && !GetMonData(&party[gBattleCommunication[0]], MON_DATA_STATUS))
break; break;
} }
if (gBattleCommunication[0] < 6) if (gBattleCommunication[0] < PARTY_SIZE)
{ {
PREPARE_MON_NICK_WITH_PREFIX_BUFFER(gBattleTextBuff1, gBattlerAttacker, gBattleCommunication[0]) PREPARE_MON_NICK_WITH_PREFIX_BUFFER(gBattleTextBuff1, gBattlerAttacker, gBattleCommunication[0])
@ -9520,7 +9513,7 @@ static void Cmd_setyawn(void)
} }
else else
{ {
gStatuses3[gBattlerTarget] |= 0x1000; gStatuses3[gBattlerTarget] |= STATUS3_YAWN_TURN(2);
gBattlescriptCurrInstr += 5; gBattlescriptCurrInstr += 5;
} }
} }
@ -9654,7 +9647,7 @@ static void Cmd_assistattackselect(void)
else else
party = gPlayerParty; party = gPlayerParty;
for (monId = 0; monId < 6; monId++) for (monId = 0; monId < PARTY_SIZE; monId++)
{ {
if (monId == gBattlerPartyIndexes[gBattlerAttacker]) if (monId == gBattlerPartyIndexes[gBattlerAttacker])
continue; continue;
@ -9865,7 +9858,7 @@ static void Cmd_pickup(void)
if (lvlDivBy10 > 9) if (lvlDivBy10 > 9)
lvlDivBy10 = 9; lvlDivBy10 = 9;
for (j = 0; j < 9; j++) for (j = 0; j < (int)ARRAY_COUNT(sPickupProbabilities); j++)
{ {
if (sPickupProbabilities[j] > rand) if (sPickupProbabilities[j] > rand)
{ {
@ -10134,7 +10127,7 @@ static void Cmd_handleballthrow(void)
} }
} }
else else
ballMultiplier = sBallCatchBonuses[gLastUsedItem - 2]; ballMultiplier = sBallCatchBonuses[gLastUsedItem - ITEM_ULTRA_BALL];
odds = (catchRate * ballMultiplier / 10) odds = (catchRate * ballMultiplier / 10)
* (gBattleMons[gBattlerTarget].maxHP * 3 - gBattleMons[gBattlerTarget].hp * 2) * (gBattleMons[gBattlerTarget].maxHP * 3 - gBattleMons[gBattlerTarget].hp * 2)
@ -10436,7 +10429,7 @@ static void Cmd_trygivecaughtmonnick(void)
} }
break; break;
case 4: case 4:
if (CalculatePlayerPartyCount() == 6) if (CalculatePlayerPartyCount() == PARTY_SIZE)
gBattlescriptCurrInstr += 5; gBattlescriptCurrInstr += 5;
else else
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);

View File

@ -864,9 +864,9 @@ u8 DoBattlerEndTurnEffects(void)
gBattleMoveDamage = gBattleMons[gActiveBattler].maxHP / 16; gBattleMoveDamage = gBattleMons[gActiveBattler].maxHP / 16;
if (gBattleMoveDamage == 0) if (gBattleMoveDamage == 0)
gBattleMoveDamage = 1; gBattleMoveDamage = 1;
if ((gBattleMons[gActiveBattler].status1 & 0xF00) != 0xF00) // not 16 turns if ((gBattleMons[gActiveBattler].status1 & STATUS1_TOXIC_COUNTER) != STATUS1_TOXIC_TURN(15)) // not 16 turns
gBattleMons[gActiveBattler].status1 += 0x100; gBattleMons[gActiveBattler].status1 += STATUS1_TOXIC_TURN(1);
gBattleMoveDamage *= (gBattleMons[gActiveBattler].status1 & 0xF00) >> 8; gBattleMoveDamage *= (gBattleMons[gActiveBattler].status1 & STATUS1_TOXIC_COUNTER) >> 8;
BattleScriptExecute(BattleScript_PoisonTurnDmg); BattleScriptExecute(BattleScript_PoisonTurnDmg);
effect++; effect++;
} }
@ -917,7 +917,7 @@ u8 DoBattlerEndTurnEffects(void)
case ENDTURN_WRAP: // wrap case ENDTURN_WRAP: // wrap
if ((gBattleMons[gActiveBattler].status2 & STATUS2_WRAPPED) && gBattleMons[gActiveBattler].hp != 0) if ((gBattleMons[gActiveBattler].status2 & STATUS2_WRAPPED) && gBattleMons[gActiveBattler].hp != 0)
{ {
gBattleMons[gActiveBattler].status2 -= 0x2000; gBattleMons[gActiveBattler].status2 -= STATUS2_WRAPPED_TURN(1);
if (gBattleMons[gActiveBattler].status2 & STATUS2_WRAPPED) // damaged by wrap if (gBattleMons[gActiveBattler].status2 & STATUS2_WRAPPED) // damaged by wrap
{ {
// This is the only way I could get this array access to match. // This is the only way I could get this array access to match.
@ -973,7 +973,7 @@ u8 DoBattlerEndTurnEffects(void)
else else
{ {
gBattlerAttacker = gActiveBattler; gBattlerAttacker = gActiveBattler;
gBattleMons[gActiveBattler].status2 -= 0x10; // uproar timer goes down gBattleMons[gActiveBattler].status2 -= STATUS2_UPROAR_TURN(1);
if (WasUnableToUseMove(gActiveBattler)) if (WasUnableToUseMove(gActiveBattler))
{ {
CancelMultiTurnMoves(gActiveBattler); CancelMultiTurnMoves(gActiveBattler);
@ -999,7 +999,7 @@ u8 DoBattlerEndTurnEffects(void)
case ENDTURN_THRASH: // thrash case ENDTURN_THRASH: // thrash
if (gBattleMons[gActiveBattler].status2 & STATUS2_LOCK_CONFUSE) if (gBattleMons[gActiveBattler].status2 & STATUS2_LOCK_CONFUSE)
{ {
gBattleMons[gActiveBattler].status2 -= 0x400; gBattleMons[gActiveBattler].status2 -= STATUS2_LOCK_CONFUSE_TURN(1);
if (WasUnableToUseMove(gActiveBattler)) if (WasUnableToUseMove(gActiveBattler))
CancelMultiTurnMoves(gActiveBattler); CancelMultiTurnMoves(gActiveBattler);
else if (!(gBattleMons[gActiveBattler].status2 & STATUS2_LOCK_CONFUSE) else if (!(gBattleMons[gActiveBattler].status2 & STATUS2_LOCK_CONFUSE)
@ -1062,7 +1062,7 @@ u8 DoBattlerEndTurnEffects(void)
break; break;
case ENDTURN_LOCK_ON: // lock-on decrement case ENDTURN_LOCK_ON: // lock-on decrement
if (gStatuses3[gActiveBattler] & STATUS3_ALWAYS_HITS) if (gStatuses3[gActiveBattler] & STATUS3_ALWAYS_HITS)
gStatuses3[gActiveBattler] -= 0x8; gStatuses3[gActiveBattler] -= STATUS3_ALWAYS_HITS_TURN(1);
gBattleStruct->turnEffectsTracker++; gBattleStruct->turnEffectsTracker++;
break; break;
case ENDTURN_CHARGE: // charge case ENDTURN_CHARGE: // charge
@ -1078,13 +1078,13 @@ u8 DoBattlerEndTurnEffects(void)
case ENDTURN_YAWN: // yawn case ENDTURN_YAWN: // yawn
if (gStatuses3[gActiveBattler] & STATUS3_YAWN) if (gStatuses3[gActiveBattler] & STATUS3_YAWN)
{ {
gStatuses3[gActiveBattler] -= 0x800; gStatuses3[gActiveBattler] -= STATUS3_YAWN_TURN(1);
if (!(gStatuses3[gActiveBattler] & STATUS3_YAWN) && !(gBattleMons[gActiveBattler].status1 & STATUS1_ANY) if (!(gStatuses3[gActiveBattler] & STATUS3_YAWN) && !(gBattleMons[gActiveBattler].status1 & STATUS1_ANY)
&& gBattleMons[gActiveBattler].ability != ABILITY_VITAL_SPIRIT && gBattleMons[gActiveBattler].ability != ABILITY_VITAL_SPIRIT
&& gBattleMons[gActiveBattler].ability != ABILITY_INSOMNIA && !UproarWakeUpCheck(gActiveBattler)) && gBattleMons[gActiveBattler].ability != ABILITY_INSOMNIA && !UproarWakeUpCheck(gActiveBattler))
{ {
CancelMultiTurnMoves(gActiveBattler); CancelMultiTurnMoves(gActiveBattler);
gBattleMons[gActiveBattler].status1 |= (Random() & 3) + 2; gBattleMons[gActiveBattler].status1 |= STATUS1_SLEEP_TURN((Random() & 3) + 2); // 2-5 turns of sleep
BtlController_EmitSetMonData(0, REQUEST_STATUS_BATTLE, 0, 4, &gBattleMons[gActiveBattler].status1); BtlController_EmitSetMonData(0, REQUEST_STATUS_BATTLE, 0, 4, &gBattleMons[gActiveBattler].status1);
MarkBattlerForControllerExec(gActiveBattler); MarkBattlerForControllerExec(gActiveBattler);
gEffectBattler = gActiveBattler; gEffectBattler = gActiveBattler;
@ -1478,7 +1478,7 @@ u8 AtkCanceller_UnableToUseMove(void)
case CANCELLER_CONFUSED: // confusion case CANCELLER_CONFUSED: // confusion
if (gBattleMons[gBattlerAttacker].status2 & STATUS2_CONFUSION) if (gBattleMons[gBattlerAttacker].status2 & STATUS2_CONFUSION)
{ {
gBattleMons[gBattlerAttacker].status2--; gBattleMons[gBattlerAttacker].status2 -= STATUS2_CONFUSION_TURN(1);
if (gBattleMons[gBattlerAttacker].status2 & STATUS2_CONFUSION) if (gBattleMons[gBattlerAttacker].status2 & STATUS2_CONFUSION)
{ {
if (Random() & 1) if (Random() & 1)
@ -1540,7 +1540,7 @@ u8 AtkCanceller_UnableToUseMove(void)
case CANCELLER_BIDE: // bide case CANCELLER_BIDE: // bide
if (gBattleMons[gBattlerAttacker].status2 & STATUS2_BIDE) if (gBattleMons[gBattlerAttacker].status2 & STATUS2_BIDE)
{ {
gBattleMons[gBattlerAttacker].status2 -= 0x100; gBattleMons[gBattlerAttacker].status2 -= STATUS2_BIDE_TURN(1);
if (gBattleMons[gBattlerAttacker].status2 & STATUS2_BIDE) if (gBattleMons[gBattlerAttacker].status2 & STATUS2_BIDE)
{ {
gBattlescriptCurrInstr = BattleScript_BideStoringEnergy; gBattlescriptCurrInstr = BattleScript_BideStoringEnergy;

View File

@ -24,7 +24,7 @@ static const u8 sSassyNatureName[] = _("SASSY");
static const u8 sCarefulNatureName[] = _("CAREFUL"); static const u8 sCarefulNatureName[] = _("CAREFUL");
static const u8 sQuirkyNatureName[] = _("QUIRKY"); static const u8 sQuirkyNatureName[] = _("QUIRKY");
const u8 *const gNatureNamePointers[] = const u8 *const gNatureNamePointers[NUM_NATURES] =
{ {
[NATURE_HARDY] = sHardyNatureName, [NATURE_HARDY] = sHardyNatureName,
[NATURE_LONELY] = sLonelyNatureName, [NATURE_LONELY] = sLonelyNatureName,

View File

@ -2854,7 +2854,7 @@ void SetBattleTowerLinkPlayerGfx(void)
void ShowNatureGirlMessage(void) void ShowNatureGirlMessage(void)
{ {
static const u8 *const sNatureGirlMessages[] = { static const u8 *const sNatureGirlMessages[NUM_NATURES] = {
[NATURE_HARDY] = BattleFrontier_Lounge5_Text_NatureGirlHardy, [NATURE_HARDY] = BattleFrontier_Lounge5_Text_NatureGirlHardy,
[NATURE_LONELY] = BattleFrontier_Lounge5_Text_NatureGirlLonely, [NATURE_LONELY] = BattleFrontier_Lounge5_Text_NatureGirlLonely,
[NATURE_BRAVE] = BattleFrontier_Lounge5_Text_NatureGirlBrave, [NATURE_BRAVE] = BattleFrontier_Lounge5_Text_NatureGirlBrave,

View File

@ -117,7 +117,7 @@ EWRAM_DATA static struct PokeblockSavedData sSavedPokeblockData = {0};
EWRAM_DATA static struct PokeblockMenuStruct *sPokeblockMenu = NULL; EWRAM_DATA static struct PokeblockMenuStruct *sPokeblockMenu = NULL;
// const rom data // const rom data
const s8 gPokeblockFlavorCompatibilityTable[] = const s8 gPokeblockFlavorCompatibilityTable[NUM_NATURES * FLAVOR_COUNT] =
{ {
// Cool, Beauty, Cute, Smart, Tough // Cool, Beauty, Cute, Smart, Tough
0, 0, 0, 0, 0, // Hardy 0, 0, 0, 0, 0, // Hardy
@ -1386,7 +1386,7 @@ s16 PokeblockGetGain(u8 nature, const struct Pokeblock *pokeblock)
{ {
curGain = GetPokeblockData(pokeblock, flavor + PBLOCK_SPICY); curGain = GetPokeblockData(pokeblock, flavor + PBLOCK_SPICY);
if (curGain > 0) if (curGain > 0)
totalGain += curGain * gPokeblockFlavorCompatibilityTable[5 * nature + flavor]; totalGain += curGain * gPokeblockFlavorCompatibilityTable[FLAVOR_COUNT * nature + flavor];
} }
return totalGain; return totalGain;

View File

@ -84,7 +84,7 @@ EWRAM_DATA static struct PokeblockFeedStruct *sPokeblockFeed = NULL;
EWRAM_DATA static struct CompressedSpritePalette sPokeblockSpritePal = {0}; EWRAM_DATA static struct CompressedSpritePalette sPokeblockSpritePal = {0};
// const rom data // const rom data
static const u8 sNatureToMonPokeblockAnim[][2] = static const u8 sNatureToMonPokeblockAnim[NUM_NATURES][2] =
{ {
[NATURE_HARDY] = { 0, 0 }, [NATURE_HARDY] = { 0, 0 },
[NATURE_LONELY] = { 3, 0 }, [NATURE_LONELY] = { 3, 0 },

View File

@ -1349,7 +1349,7 @@ const struct SpindaSpot gSpindaSpotGraphics[] =
#include "data/pokemon/item_effects.h" #include "data/pokemon/item_effects.h"
const s8 gNatureStatTable[][NUM_EV_STATS] = const s8 gNatureStatTable[NUM_NATURES][NUM_NATURE_STATS] =
{ {
// Atk Def Spd Sp.Atk Sp.Def // Atk Def Spd Sp.Atk Sp.Def
{ 0, 0, 0, 0, 0}, // Hardy { 0, 0, 0, 0, 0}, // Hardy
@ -5372,12 +5372,12 @@ u8 *UseStatIncreaseItem(u16 itemId)
u8 GetNature(struct Pokemon *mon) u8 GetNature(struct Pokemon *mon)
{ {
return GetMonData(mon, MON_DATA_PERSONALITY, 0) % 25; return GetMonData(mon, MON_DATA_PERSONALITY, 0) % NUM_NATURES;
} }
u8 GetNatureFromPersonality(u32 personality) u8 GetNatureFromPersonality(u32 personality)
{ {
return personality % 25; return personality % NUM_NATURES;
} }
u16 GetEvolutionTargetSpecies(struct Pokemon *mon, u8 type, u16 evolutionItem) u16 GetEvolutionTargetSpecies(struct Pokemon *mon, u8 type, u16 evolutionItem)
@ -5747,7 +5747,7 @@ u8 GetTrainerEncounterMusicId(u16 trainerOpponentId)
u16 ModifyStatByNature(u8 nature, u16 n, u8 statIndex) u16 ModifyStatByNature(u8 nature, u16 n, u8 statIndex)
{ {
// Dont modify HP, Accuracy, or Evasion by nature // Dont modify HP, Accuracy, or Evasion by nature
if (statIndex <= STAT_HP || statIndex > NUM_EV_STATS) if (statIndex <= STAT_HP || statIndex > NUM_NATURE_STATS)
{ {
// Should just be "return n", but it wouldn't match without this. // Should just be "return n", but it wouldn't match without this.
u16 retVal = n; u16 retVal = n;
@ -6410,13 +6410,13 @@ bool8 IsMonSpriteNotFlipped(u16 species)
s8 GetMonFlavorRelation(struct Pokemon *mon, u8 flavor) s8 GetMonFlavorRelation(struct Pokemon *mon, u8 flavor)
{ {
u8 nature = GetNature(mon); u8 nature = GetNature(mon);
return gPokeblockFlavorCompatibilityTable[nature * 5 + flavor]; return gPokeblockFlavorCompatibilityTable[nature * FLAVOR_COUNT + flavor];
} }
s8 GetFlavorRelationByPersonality(u32 personality, u8 flavor) s8 GetFlavorRelationByPersonality(u32 personality, u8 flavor)
{ {
u8 nature = GetNatureFromPersonality(personality); u8 nature = GetNatureFromPersonality(personality);
return gPokeblockFlavorCompatibilityTable[nature * 5 + flavor]; return gPokeblockFlavorCompatibilityTable[nature * FLAVOR_COUNT + flavor];
} }
bool8 IsTradedMon(struct Pokemon *mon) bool8 IsTradedMon(struct Pokemon *mon)

View File

@ -783,7 +783,7 @@ static const u8 sBackAnimationIds[] =
0x94, 0x95, 0x96, // 0x19 0x94, 0x95, 0x96, // 0x19
}; };
static const u8 sBackAnimNatureModTable[] = static const u8 sBackAnimNatureModTable[NUM_NATURES] =
{ {
[NATURE_HARDY] = 0x00, [NATURE_HARDY] = 0x00,
[NATURE_LONELY] = 0x02, [NATURE_LONELY] = 0x02,

View File

@ -303,29 +303,27 @@ static u8 PickWildMonNature(void)
u8 i; u8 i;
u8 j; u8 j;
struct Pokeblock *safariPokeblock; struct Pokeblock *safariPokeblock;
u8 natures[25]; u8 natures[NUM_NATURES];
if (GetSafariZoneFlag() == TRUE && Random() % 100 < 80) if (GetSafariZoneFlag() == TRUE && Random() % 100 < 80)
{ {
safariPokeblock = SafariZoneGetActivePokeblock(); safariPokeblock = SafariZoneGetActivePokeblock();
if (safariPokeblock != NULL) if (safariPokeblock != NULL)
{ {
for (i = 0; i < 25; i++) for (i = 0; i < NUM_NATURES; i++)
natures[i] = i; natures[i] = i;
for (i = 0; i < 24; i++) for (i = 0; i < NUM_NATURES - 1; i++)
{ {
for (j = i + 1; j < 25; j++) for (j = i + 1; j < NUM_NATURES; j++)
{ {
if (Random() & 1) if (Random() & 1)
{ {
u8 temp = natures[i]; u8 temp;
SWAP(natures[i], natures[j], temp);
natures[i] = natures[j];
natures[j] = temp;
} }
} }
} }
for (i = 0; i < 25; i++) for (i = 0; i < NUM_NATURES; i++)
{ {
if (PokeblockGetGain(natures[i], safariPokeblock) > 0) if (PokeblockGetGain(natures[i], safariPokeblock) > 0)
return natures[i]; return natures[i];
@ -337,11 +335,11 @@ static u8 PickWildMonNature(void)
&& GetMonAbility(&gPlayerParty[0]) == ABILITY_SYNCHRONIZE && GetMonAbility(&gPlayerParty[0]) == ABILITY_SYNCHRONIZE
&& Random() % 2 == 0) && Random() % 2 == 0)
{ {
return GetMonData(&gPlayerParty[0], MON_DATA_PERSONALITY) % 25; return GetMonData(&gPlayerParty[0], MON_DATA_PERSONALITY) % NUM_NATURES;
} }
// random nature // random nature
return Random() % 25; return Random() % NUM_NATURES;
} }
static void CreateWildMon(u16 species, u8 level) static void CreateWildMon(u16 species, u8 level)