Update/battle engine c43dd0c3ca (#111)

This commit is contained in:
cawtds 2026-02-14 12:54:29 +01:00 committed by GitHub
parent 328838e0e6
commit 46e2a87e2e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
211 changed files with 12975 additions and 8809 deletions

View File

@ -30,10 +30,6 @@
.byte B_SCR_OP_TYPECALC
.endm
.macro adjustdamage
.byte B_SCR_OP_ADJUSTDAMAGE
.endm
.macro multihitresultmessage
.byte B_SCR_OP_MULTIHITRESULTMESSAGE
.endm
@ -363,8 +359,8 @@
.byte B_SCR_OP_WAITSTATE
.endm
.macro isdmgblockedbydisguise
.byte B_SCR_OP_ISDMGBLOCKEDBYDISGUISE
.macro tryselfconfusiondmgformchange
.byte B_SCR_OP_TRYSELFCONFUSIONDMGFORMCHANGE
.endm
.macro return
@ -687,10 +683,6 @@
.byte B_SCR_OP_USEITEMONOPPONENT
.endm
.macro unused_0x78
.byte B_SCR_OP_UNUSED_0X78
.endm
.macro setprotectlike
.byte B_SCR_OP_SETPROTECTLIKE
.endm
@ -714,10 +706,6 @@
.4byte \failInstr
.endm
.macro trymirrormove
.byte B_SCR_OP_UNUSED_0X7E
.endm
.macro setfieldweather
.byte B_SCR_OP_SETFIELDWEATHER
.endm
@ -739,14 +727,6 @@
.byte B_SCR_OP_TRYSETREST
.endm
.macro unused_0x82
.byte B_SCR_OP_UNUSED_0X82
.endm
.macro unused_0x83
.byte B_SCR_OP_UNUSED_0X83
.endm
.macro jumpifuproarwakes jumpInstr:req
.byte B_SCR_OP_JUMPIFUPROARWAKES
.4byte \jumpInstr
@ -765,14 +745,6 @@
.4byte \failInstr
.endm
.macro removestockpilecounters
callnative BS_RemoveStockpileCounters
.endm
.macro unused_0x88
.byte B_SCR_OP_UNUSED_0X88
.endm
.macro statbuffchange battler:req, flags:req, failInstr:req, stats=0
.byte B_SCR_OP_STATBUFFCHANGE
.byte \battler
@ -888,22 +860,6 @@
.byte B_SCR_OP_SETCALLEDMOVE
.endm
.macro unused_0x9f
.byte B_SCR_OP_UNUSED_0X9F
.endm
.macro unused_0xA0
.byte B_SCR_OP_UNUSED_0XA0
.endm
.macro unused_0xA1
.byte B_SCR_OP_UNUSED_0XA1
.endm
.macro unused_0xA2
.byte B_SCR_OP_UNUSED_0XA2
.endm
.macro disablelastusedattack failInstr:req
.byte B_SCR_OP_DISABLELASTUSEDATTACK
.4byte \failInstr
@ -933,20 +889,6 @@
.4byte \failInstr
.endm
.macro trychoosesleeptalkmove failInstr:req
.byte B_SCR_OP_UNUSED_0XA9
.4byte \failInstr
.endm
.macro trysetdestinybond failInstr:req
.byte B_SCR_OP_UNUSED_AA
.4byte \failInstr
.endm
.macro unused_0xab
.byte B_SCR_OP_UNUSED_0XAB
.endm
.macro settailwind failInstr:req
.byte B_SCR_OP_SETTAILWIND
.4byte \failInstr
@ -983,20 +925,12 @@
.4byte \failInstr
.endm
.macro unused_0xb3
.byte B_SCR_OP_UNUSED_0XB3
.endm
.macro jumpifconfusedandstatmaxed stat:req, jumpInstr:req
.byte B_SCR_OP_JUMPIFCONFUSEDANDSTATMAXED
.byte \stat
.4byte \jumpInstr
.endm
.macro unused_0xb5
.byte B_SCR_OP_UNUSED_0XB5
.endm
.macro setembargo failInstr:req
.byte B_SCR_OP_SETEMBARGO
.4byte \failInstr
@ -1010,10 +944,6 @@
.byte B_SCR_OP_SETSAFEGUARD
.endm
.macro magnitudedamagecalculation
.byte B_SCR_OP_MAGNITUDEDAMAGECALCULATION
.endm
.macro jumpifnopursuitswitchdmg jumpInstr:req
.byte B_SCR_OP_JUMPIFNOPURSUITSWITCHDMG
.4byte \jumpInstr
@ -1071,18 +1001,6 @@
setsemiinvulnerablebit TRUE
.endm
.macro unused_0xC6
.byte B_SCR_OP_UNUSED_0XC6
.endm
.macro unused_0xC7
.byte B_SCR_OP_UNUSED_0XC7
.endm
.macro unused_c8
.byte B_SCR_OP_UNUSED_C8
.endm
.macro trymemento failInstr:req
.byte B_SCR_OP_TRYMEMENTO
.4byte \failInstr
@ -1092,15 +1010,6 @@
.byte B_SCR_OP_SETFORCEDTARGET
.endm
.macro unused_0xcb battler:req
.byte B_SCR_OP_UNUSED_0XCB
.byte \battler
.endm
.macro unused_0xCC
.byte B_SCR_OP_UNUSED_0XCC
.endm
.macro curestatuswithmove failInstr:req
.byte B_SCR_OP_CURESTATUSWITHMOVE
.4byte \failInstr
@ -1111,10 +1020,6 @@
.4byte \failInstr
.endm
.macro unused_0xcf
.byte B_SCR_OP_UNUSED_0XCF
.endm
.macro settaunt failInstr:req
.byte B_SCR_OP_SETTAUNT
.4byte \failInstr
@ -1156,10 +1061,6 @@
.4byte \failInstr
.endm
.macro Cmd_unused0xd8
.byte B_SCR_OP_UNUSED0XD8
.endm
.macro setroom
.byte B_SCR_OP_SETROOM
.endm
@ -1186,11 +1087,6 @@
.4byte \failInstr
.endm
.macro assistattackselect failInstr:req
.byte B_SCR_OP_UNUSED_0XDE
.4byte \failInstr
.endm
.macro trysetmagiccoat failInstr:req
.byte B_SCR_OP_TRYSETMAGICCOAT
.4byte \failInstr
@ -1201,11 +1097,6 @@
.4byte \failInstr
.endm
.macro unused2 ptr:req
.byte B_SCR_OP_UNUSED2
.4byte \ptr
.endm
.macro switchoutabilities battler:req
.byte B_SCR_OP_SWITCHOUTABILITIES
.byte \battler
@ -1217,22 +1108,10 @@
.4byte \jumpInstr
.endm
.macro unused_0xE4
.byte B_SCR_OP_UNUSED_0XE4
.endm
.macro pickup
.byte B_SCR_OP_PICKUP
.endm
.macro unused_0xE6
.byte B_SCR_OP_UNUSED_0XE6
.endm
.macro unused_0xE7
.byte B_SCR_OP_UNUSED_0XE7
.endm
.macro settypebasedhalvers failInstr:req
.byte B_SCR_OP_SETTYPEBASEDHALVERS
.4byte \failInstr
@ -1262,10 +1141,6 @@
.byte B_SCR_OP_SNATCHSETBATTLERS
.endm
.macro unused_0xee
.byte B_SCR_OP_UNUSED_0XEE
.endm
.macro handleballthrow
.byte B_SCR_OP_HANDLEBALLTHROW
.endm
@ -1452,24 +1327,6 @@
.4byte \ptr
.endm
.macro handlemegaevo battler:req, case:req
callnative BS_HandleMegaEvolution
.byte \battler
.byte \case
.endm
.macro handleprimalreversion battler:req, case:req
callnative BS_HandlePrimalReversion
.byte \battler
.byte \case
.endm
.macro handleultraburst battler:req, case:req
callnative BS_HandleUltraBurst
.byte \battler
.byte \case
.endm
.macro jumpifshelltrap battler:req, jumpInstr:req
callnative BS_JumpIfShellTrap
.byte \battler
@ -1605,12 +1462,8 @@
.4byte \jumpInstr
.endm
.macro trygulpmissile
callnative BS_TryGulpMissile
.endm
.macro tryactivategulpmissile
callnative BS_TryActivateGulpMissile
.macro trytwoturnmovespowerherbformchange
callnative BS_TryTwoTurnMovesPowerHerbFormChange
.endm
.macro tryquash failInstr:req
@ -1637,10 +1490,6 @@
.4byte \jumpInstr
.endm
.macro ficklebeamdamagecalculation
callnative BS_FickleBeamDamageCalculation
.endm
.macro trytarshot failInstr:req
callnative BS_TryTarShot
.4byte \failInstr
@ -2130,10 +1979,11 @@
.4byte \failInstr
.endm
.macro handleformchange battler:req, case_:req
.macro handleformchange battler:req, caseId:req, bufferSpeciesName=TRUE
callnative BS_HandleFormChange
.byte \battler
.byte \case_
.byte \caseId
.byte \bufferSpeciesName
.endm
.macro tryautotomize failInstr:req
@ -2319,9 +2169,8 @@
.4byte \failInstr
.endm
.macro setpoltergeistmessage failInstr:req
.macro setpoltergeistmessage
callnative BS_SetPoltergeistMessage
.4byte \failInstr
.endm
.macro tryresetnegativestatstages
@ -2340,11 +2189,6 @@
callnative BS_BattlerItemToLastUsedItem
.endm
@ various remaining from pokefirered
.macro getbattlersforrecall
callnative BS_GetBattlersForRecall
.endm
.macro setallytonexttarget jumpInstr:req
jumpifbyte CMP_GREATER_THAN, gBattlerTarget, 0x1, 1f
addbyte gBattlerTarget, 0x2
@ -2426,3 +2270,8 @@
.byte \battler
.byte \switchedItems
.endm
@ various remaining from pokefirered
.macro getbattlersforrecall
callnative BS_GetBattlersForRecall
.endm

View File

@ -61,7 +61,7 @@ gBattleAnimGeneral_SilphScoped::
monbg ANIM_ATTACKER
playsewithpan SE_M_TELEPORT, SOUND_PAN_ATTACKER
waitplaysewithpan SE_M_MINIMIZE, SOUND_PAN_ATTACKER, 48
createvisualtask AnimTask_TransformMon, 3, FALSE, FALSE, TRUE
createvisualtask AnimTask_TransformMon, 3, SPECIES_GFX_CHANGE_GHOST_UNVEIL
waitsound
waitforvisualfinish
clearmonbg ANIM_ATTACKER
@ -26246,7 +26246,7 @@ gBattleAnimMove_Transform::
monbg ANIM_ATTACKER
playsewithpan SE_M_TELEPORT, SOUND_PAN_ATTACKER
waitplaysewithpan SE_M_MINIMIZE, SOUND_PAN_ATTACKER, 48
createvisualtask AnimTask_TransformMon, 2, 0, 1
createvisualtask AnimTask_TransformMon, 2, SPECIES_GFX_CHANGE_TRANSFORM
waitforvisualfinish
clearmonbg ANIM_ATTACKER
end
@ -28768,14 +28768,28 @@ gBattleAnimGeneral_SimpleHeal::
gBattleAnimGeneral_IllusionOff::
monbg ANIM_TARGET
createvisualtask AnimTask_TransformMon, 2, 1, 0
createvisualtask AnimTask_TransformMon, 2, SPECIES_GFX_CHANGE_ILLUSION_OFF
waitforvisualfinish
clearmonbg ANIM_TARGET
end
gBattleAnimGeneral_FormChange::
monbg ANIM_ATTACKER
createvisualtask AnimTask_TransformMon, 2, 1, 0
createvisualtask AnimTask_TransformMon, 2, SPECIES_GFX_CHANGE_FORM_CHANGE
waitforvisualfinish
clearmonbg ANIM_ATTACKER
end
gBattleAnimGeneral_FormChangeDisguise::
playsewithpan SE_CONTEST_CONDITION_LOSE, SOUND_PAN_TARGET
createvisualtask AnimTask_ShakeMon2, 2, ANIM_TARGET, 2, 0, 10, 1
waitforvisualfinish
playsewithpan SE_CONTEST_CURTAIN_FALL, SOUND_PAN_TARGET
goto gBattleAnimGeneral_FormChangeInstant
gBattleAnimGeneral_FormChangeInstant::
monbg ANIM_ATTACKER
createvisualtask AnimTask_TransformMon, 2, SPECIES_GFX_CHANGE_FORM_CHANGE_INSTANT
waitforvisualfinish
clearmonbg ANIM_ATTACKER
end
@ -28851,6 +28865,7 @@ MegaEvolutionSpinEffect:
return
gBattleAnimGeneral_TeraCharge::
createvisualtask AnimTask_HideOpponentShadows, 2 @ Hide opponent shadows so they don't flicker between battle anims
loadspritegfx ANIM_TAG_TERA_CRYSTAL
loadspritegfx ANIM_TAG_TERA_SHATTER
loadspritegfx ANIM_TAG_FOCUS_ENERGY
@ -28872,7 +28887,6 @@ gBattleAnimGeneral_TeraCharge::
delay 20
createvisualtask AnimTask_BlendBattleAnimPalExclude, 5, 5, 2, 0, 16, RGB_WHITEALPHA
waitforvisualfinish
createvisualtask AnimTask_TransformMon, 2, 1, 0
call TeraChargeParticles
playsewithpan SE_M_BRICK_BREAK, SOUND_PAN_ATTACKER
clearmonbg ANIM_ATK_PARTNER

File diff suppressed because it is too large Load Diff

View File

@ -16,6 +16,7 @@
#include "constants/event_objects.h"
#include "constants/event_object_movement.h"
#include "constants/field_move.h"
#include "constants/field_poison.h"
#include "constants/frontier_util.h"
#include "constants/decorations.h"
#include "constants/item.h"

View File

@ -1,30 +1,21 @@
Test_EventScript_NPC::
msgbox Test_Text_WelcomeToWorldOfPokemon, MSGBOX_NPC
end
EventScript_TestSignpostMsg::
msgbox Test_Text_ThisIsASignpost, MSGBOX_SIGN
end
Test_EventScript_CoordEvent::
msgbox Test_Text_ThisIsACoordEvent, MSGBOX_SIGN
end
Test_Text_WelcomeToWorldOfPokemon::
.string "テストよう メッセージです!\n"
.string "ポケモンの せかいへ ようこそ!$"
Test_Text_ThisIsASignpost::
.string "テストよう メッセージです!\n"
.string "かんばん です$"
Test_Text_ThisIsACoordEvent::
.string "テストよう メッセージです!\n"
.string "ざひょう チェックの イベントです$"
EventScript_TryGetTrainerScript::
special ShouldTryGetTrainerScript
goto_if_eq VAR_RESULT, TRUE, EventScript_GotoTrainerScript
releaseall
end
.align 2
Test_Text_Empty::
.string "$"
EventScript_GotoTrainerScript::
gotobeatenscript
releaseall
end
EventScript_ObjectApproachPlayer::
lock

View File

@ -14,10 +14,10 @@ EventScript_TryDoNormalTrainerBattle::
applymovement VAR_LAST_TALKED, Movement_RevealTrainer
waitmovement 0
clearflag FLAG_SAFE_FOLLOWER_MOVEMENT
specialvar VAR_RESULT, Script_HasTrainerBeenFought
specialvar VAR_RESULT, GetTrainerFlag
goto_if_ne VAR_RESULT, FALSE, EventScript_NoTrainerBattle
special PlayTrainerEncounterMusic
special SetUpTrainerMovement
special SetTrainerFacingDirection
goto EventScript_ShowTrainerIntroMsg
EventScript_NoTrainerBattle::
@ -27,12 +27,12 @@ EventScript_TryDoDoubleTrainerBattle::
lock
faceplayer
call EventScript_RevealTrainer
specialvar VAR_RESULT, Script_HasTrainerBeenFought
specialvar VAR_RESULT, GetTrainerFlag
goto_if_ne VAR_RESULT, FALSE, EventScript_NoDoubleTrainerBattle
special HasEnoughMonsForDoubleBattle
goto_if_ne VAR_RESULT, PLAYER_HAS_TWO_USABLE_MONS, EventScript_NotEnoughMonsForDoubleBattle
special PlayTrainerEncounterMusic
special SetUpTrainerMovement
special SetTrainerFacingDirection
goto EventScript_ShowTrainerIntroMsg
EventScript_NotEnoughMonsForDoubleBattle::
@ -60,7 +60,7 @@ EventScript_TryDoRematchBattle::
specialvar VAR_RESULT, IsTrainerReadyForRematch
goto_if_eq VAR_RESULT, FALSE, EventScript_NoRematchBattle
special PlayTrainerEncounterMusic
special SetUpTrainerMovement
special SetTrainerFacingDirection
special ShowTrainerIntroSpeech
waitmessage
waitbuttonpress
@ -79,7 +79,7 @@ EventScript_TryDoDoubleRematchBattle::
special HasEnoughMonsForDoubleBattle
goto_if_ne VAR_RESULT, PLAYER_HAS_TWO_USABLE_MONS, EventScript_NotEnoughMonsForDoubleRematchBattle
special PlayTrainerEncounterMusic
special SetUpTrainerMovement
special SetTrainerFacingDirection
special ShowTrainerIntroSpeech
waitmessage
waitbuttonpress

View File

@ -36,7 +36,8 @@ EventScript_FieldPoison::
textcolor NPC_TEXT_COLOR_NEUTRAL
special TryFieldPoisonWhiteOut
waitstate
goto_if_eq VAR_RESULT, TRUE, EventScript_FieldWhiteOut
goto_if_eq VAR_RESULT, FLDPSN_WHITEOUT, EventScript_FieldWhiteOut
goto_if_eq VAR_RESULT, FLDPSN_FRONTIER_WHITEOUT, EventScript_FrontierFieldWhiteOut
releaseall
end

View File

@ -69,7 +69,7 @@ gSpecials::
def_special GetTrainerBattleMode
def_special ShowTrainerIntroSpeech
def_special ShowTrainerCantBattleSpeech
def_special Script_HasTrainerBeenFought
def_special GetTrainerFlag
def_special DoTrainerApproach
def_special PlayTrainerEncounterMusic
def_special ShouldTryRematchBattle
@ -315,8 +315,8 @@ gSpecials::
def_special StartGroudonKyogreBattle
def_special BattleSetup_StartLegendaryBattle
def_special StartRegiBattle
def_special SetUpTrainerMovement
def_special NullFieldSpecial
def_special SetTrainerFacingDirection
def_special ShouldTryGetTrainerScript
def_special NullFieldSpecial
def_special StartDroughtWeatherBlend
def_special DoDiveWarp

View File

@ -6,6 +6,7 @@
#include "constants/battle_switch_in.h"
#include "constants/abilities.h"
#include "constants/battle.h"
#include "constants/battle_move_resolution.h"
#include "constants/form_change_types.h"
#include "constants/hold_effects.h"
#include "constants/moves.h"
@ -28,26 +29,6 @@
#include "random.h" // for rng_value_t
#include "trainer_slide.h"
// Helper for accessing command arguments and advancing gBattlescriptCurrInstr.
//
// For example accuracycheck is defined as:
//
// .macro accuracycheck failInstr:req, move:req
// .byte 0x1
// .4byte \failInstr
// .2byte \move
// .endm
//
// Which corresponds to:
//
// CMD_ARGS(const u8 *failInstr, u16 move);
//
// The arguments can be accessed as cmd->failInstr and cmd->move.
// gBattlescriptCurrInstr = cmd->nextInstr; advances to the next instruction.
#define CMD_ARGS(...) const struct __attribute__((packed)) { u8 opcode; RECURSIVELY(R_FOR_EACH(APPEND_SEMICOLON, __VA_ARGS__)) const u8 nextInstr[0]; } *const cmd UNUSED = (const void *)gBattlescriptCurrInstr
#define VARIOUS_ARGS(...) CMD_ARGS(u8 battler, u8 id, ##__VA_ARGS__)
#define NATIVE_ARGS(...) CMD_ARGS(void (*func)(void), ##__VA_ARGS__)
// Used to exclude moves learned temporarily by Transform or Mimic
#define MOVE_IS_PERMANENT(battler, moveSlot) \
(!(gBattleMons[battler].volatiles.transformed) \
@ -555,7 +536,7 @@ struct EventStates
enum FirstTurnEventsStates beforeFirstTurn:8;
enum FaintedActions faintedAction:8;
enum BattlerId faintedActionBattler:4;
enum MoveSuccessOrder atkCanceler:8;
enum CancelerState atkCanceler:8;
enum BattlerId atkCancelerBattler:4;
enum BattleIntroStates battleIntro:8;
enum SwitchInEvents switchIn:8;
@ -584,7 +565,7 @@ struct BattleStruct
u8 expSentInMons; // As bits for player party mons - not including exp share mons.
u8 wildVictorySong;
enum Type dynamicMoveType;
u8 battlerPreventingSwitchout;
enum BattlerId battlerPreventingSwitchout;
u8 moneyMultiplier:6;
u8 moneyMultiplierItem:1;
u8 moneyMultiplierMove:1;
@ -621,7 +602,6 @@ struct BattleStruct
void (*savedCallback)(void);
u16 chosenItem[MAX_BATTLERS_COUNT];
u16 choicedMove[MAX_BATTLERS_COUNT];
u16 changedItems[MAX_BATTLERS_COUNT];
u8 switchInBattlerCounter;
u16 lastTakenMoveFrom[MAX_BATTLERS_COUNT][MAX_BATTLERS_COUNT]; // a 2-D array [target][attacker]
union {
@ -657,9 +637,9 @@ struct BattleStruct
u8 stolenStats[NUM_BATTLE_STATS]; // hp byte is used for which stats to raise, other inform about by how many stages
enum Ability tracedAbility[MAX_BATTLERS_COUNT];
struct Illusion illusion[MAX_BATTLERS_COUNT];
u8 soulheartBattlerId;
u8 friskedBattler; // Frisk needs to identify 2 battlers in double battles.
u8 quickClawBattlerId;
enum BattlerId soulheartBattlerId;
enum BattlerId friskedBattler; // Frisk needs to identify 2 battlers in double battles.
enum BattlerId quickClawBattlerId;
struct LostItem itemLost[NUM_BATTLE_SIDES][PARTY_SIZE]; // Pokemon that had items consumed or stolen (two bytes per party member per side)
u8 blunderPolicy:1; // should blunder policy activate
u8 swapDamageCategory:1; // Photon Geyser, Shell Side Arm, Light That Burns the Sky
@ -825,7 +805,7 @@ struct BattleScripting
u8 moveendState;
u8 savedStatChanger; // For further use, if attempting to change stat two times(ex. Moody)
u8 shiftSwitched; // When the game tells you the next enemy's pokemon and you switch. Option for noobs but oh well.
u8 battler;
enum BattlerId battler;
u8 animTurn;
u8 animTargetsHit;
u8 statChanger;
@ -989,8 +969,8 @@ extern u8 gBattlersCount;
extern u16 gBattlerPartyIndexes[MAX_BATTLERS_COUNT];
extern u8 gBattlerPositions[MAX_BATTLERS_COUNT];
extern u8 gActionsByTurnOrder[MAX_BATTLERS_COUNT];
extern u8 gBattlerByTurnOrder[MAX_BATTLERS_COUNT];
extern u8 gBattlersBySpeed[MAX_BATTLERS_COUNT];
extern enum BattlerId gBattlerByTurnOrder[MAX_BATTLERS_COUNT];
extern enum BattlerId gBattlersBySpeed[MAX_BATTLERS_COUNT];
extern u8 gCurrentTurnActionNumber;
extern u8 gCurrentActionFuncId;
extern struct BattlePokemon gBattleMons[MAX_BATTLERS_COUNT];
@ -1003,11 +983,11 @@ extern u16 gCalledMove;
extern s32 gBideDmg[MAX_BATTLERS_COUNT];
extern u16 gLastUsedItem;
extern enum Ability gLastUsedAbility;
extern u8 gBattlerAttacker;
extern u8 gBattlerTarget;
extern u8 gBattlerFainted;
extern u8 gEffectBattler;
extern u8 gPotentialItemEffectBattler;
extern enum BattlerId gBattlerAttacker;
extern enum BattlerId gBattlerTarget;
extern enum BattlerId gBattlerFainted;
extern enum BattlerId gEffectBattler;
extern enum BattlerId gPotentialItemEffectBattler;
extern u8 gAbsentBattlerFlags;
extern u8 gMultiHitCounter;
extern const u8 *gBattlescriptCurrInstr;
@ -1064,7 +1044,7 @@ extern u16 gMoveToLearn;
extern u32 gFieldStatuses;
extern struct FieldTimer gFieldTimers;
extern u16 gBattleTurnCounter;
extern u8 gBattlerAbility;
extern enum BattlerId gBattlerAbility;
extern struct QueuedStatBoost gQueuedStatBoosts[MAX_BATTLERS_COUNT];
extern MainCallback gPreBattleCallback1;
@ -1083,7 +1063,7 @@ extern u8 gPartyCriticalHits[PARTY_SIZE];
extern u8 gCategoryIconSpriteId;
extern struct PokedudeBattlerState *gPokedudeBattlerStates[MAX_BATTLERS_COUNT];
static inline bool32 IsBattlerAlive(u32 battler)
static inline bool32 IsBattlerAlive(enum BattlerId battler)
{
if (battler >= gBattlersCount)
return FALSE;
@ -1095,24 +1075,24 @@ static inline bool32 IsBattlerAlive(u32 battler)
return TRUE;
}
static inline bool32 IsBattlerTurnDamaged(u32 battler)
static inline bool32 IsBattlerTurnDamaged(enum BattlerId battler)
{
return gSpecialStatuses[battler].damagedByAttack;
}
static inline bool32 IsBattlerAtMaxHp(u32 battler)
static inline bool32 IsBattlerAtMaxHp(enum BattlerId battler)
{
return gBattleMons[battler].hp == gBattleMons[battler].maxHP;
}
static inline enum BattlerPosition GetBattlerPosition(u32 battler)
static inline enum BattlerPosition GetBattlerPosition(enum BattlerId battler)
{
return gBattlerPositions[battler];
}
static inline u32 GetBattlerAtPosition(enum BattlerPosition position)
static inline enum BattlerId GetBattlerAtPosition(enum BattlerPosition position)
{
u32 battler;
enum BattlerId battler;
for (battler = 0; battler < gBattlersCount; battler++)
{
if (GetBattlerPosition(battler) == position)
@ -1121,37 +1101,37 @@ static inline u32 GetBattlerAtPosition(enum BattlerPosition position)
return battler;
}
static inline u32 GetPartnerBattler(u32 battler)
static inline u32 GetPartnerBattler(enum BattlerId battler)
{
return GetBattlerAtPosition(BATTLE_PARTNER(GetBattlerPosition(battler)));
}
static inline u32 GetOppositeBattler(u32 battler)
static inline u32 GetOppositeBattler(enum BattlerId battler)
{
return GetBattlerAtPosition(BATTLE_OPPOSITE(GetBattlerPosition(battler)));
}
static inline u32 GetBattlerSide(u32 battler)
static inline u32 GetBattlerSide(enum BattlerId battler)
{
return GetBattlerPosition(battler) & BIT_SIDE;
}
static inline bool32 IsOnPlayerSide(u32 battler)
static inline bool32 IsOnPlayerSide(enum BattlerId battler)
{
return GetBattlerSide(battler) == B_SIDE_PLAYER;
}
static inline bool32 IsBattlerAlly(u32 battlerAtk, u32 battlerDef)
static inline bool32 IsBattlerAlly(enum BattlerId battlerAtk, enum BattlerId battlerDef)
{
return GetBattlerSide(battlerAtk) == GetBattlerSide(battlerDef);
}
static inline u32 GetOpposingSideBattler(u32 battler)
static inline u32 GetOpposingSideBattler(enum BattlerId battler)
{
return GetBattlerAtPosition(BATTLE_OPPOSITE(GetBattlerSide(battler)));
}
static inline struct Pokemon* GetBattlerMon(u32 battler)
static inline struct Pokemon* GetBattlerMon(enum BattlerId battler)
{
u32 index = gBattlerPartyIndexes[battler];
return !IsOnPlayerSide(battler) ? &gEnemyParty[index] : &gPlayerParty[index];
@ -1162,12 +1142,12 @@ static inline struct Pokemon *GetSideParty(enum BattleSide side)
return side == B_SIDE_PLAYER ? gPlayerParty : gEnemyParty;
}
static inline struct Pokemon *GetBattlerParty(u32 battler)
static inline struct Pokemon *GetBattlerParty(enum BattlerId battler)
{
return GetSideParty(GetBattlerSide(battler));
}
static inline struct PartyState *GetBattlerPartyState(u32 battler)
static inline struct PartyState *GetBattlerPartyState(enum BattlerId battler)
{
return &gBattleStruct->partyState[GetBattlerSide(battler)][gBattlerPartyIndexes[battler]];
}
@ -1184,26 +1164,26 @@ static inline bool32 IsSpreadMove(enum MoveTarget moveTarget)
return moveTarget == TARGET_BOTH || moveTarget == TARGET_FOES_AND_ALLY;
}
static inline u32 GetChosenMoveFromPosition(u32 battler)
static inline u32 GetBattlerChosenMove(enum BattlerId battler)
{
return gBattleMons[battler].moves[gBattleStruct->chosenMovePositions[battler]];
}
static inline void SetPassiveDamageAmount(u32 battler, s32 value)
static inline void SetPassiveDamageAmount(enum BattlerId battler, s32 value)
{
if (value == 0)
value = 1;
gBattleStruct->passiveHpUpdate[battler] = value;
}
static inline void SetHealAmount(u32 battler, s32 value)
static inline void SetHealAmount(enum BattlerId battler, s32 value)
{
if (value == 0)
value = 1;
gBattleStruct->passiveHpUpdate[battler] = -1 * value;
}
static inline bool32 IsGhostBattleWithoutScope()
static inline bool32 IsGhostBattleWithoutScope(void)
{
return (gBattleTypeFlags & BATTLE_TYPE_GHOST) && !CheckBagHasItem(ITEM_SILPH_SCOPE, 1);
}

View File

@ -126,16 +126,16 @@ enum MoveComparisonResult
void BattleAI_SetupItems(void);
void BattleAI_SetupFlags(void);
void BattleAI_SetupAIData(u8 defaultScoreMoves, u32 battler);
void ComputeBattlerDecisions(u32 battler);
u32 BattleAI_ChooseMoveIndex(u32 battler);
void BattleAI_SetupAIData(u8 defaultScoreMoves, enum BattlerId battler);
void ComputeBattlerDecisions(enum BattlerId battler);
u32 BattleAI_ChooseMoveIndex(enum BattlerId battler);
void Ai_InitPartyStruct(void);
void Ai_UpdateSwitchInData(u32 battler);
void Ai_UpdateFaintData(u32 battler);
void Ai_UpdateSwitchInData(enum BattlerId battler);
void Ai_UpdateFaintData(enum BattlerId battler);
void SetAiLogicDataForTurn(struct AiLogicData *aiData);
void ResetDynamicAiFunctions(void);
void AI_TrySwitchOrUseItem(u32 battler);
void CalcBattlerAiMovesData(struct AiLogicData *aiData, u32 battlerAtk, u32 battlerDef, u32 weather, u32 fieldStatus);
void AI_TrySwitchOrUseItem(enum BattlerId battler);
void CalcBattlerAiMovesData(struct AiLogicData *aiData, enum BattlerId battlerAtk, enum BattlerId battlerDef, u32 weather, u32 fieldStatus);
extern AiSwitchFunc gDynamicAiSwitchFunc;

View File

@ -43,11 +43,11 @@ enum SwitchType
SWITCH_MID_BATTLE_OPTIONAL,
};
u32 GetMostSuitableMonToSwitchInto(u32 battler, enum SwitchType switchType);
bool32 ShouldSwitch(u32 battler);
void ModifySwitchAfterMoveScoring(u32 battler);
u32 AI_SelectRevivalBlessingMon(u32 battler);
bool32 IsSwitchinValid(u32 battler);
bool32 IsAceMon(u32 battler, u32 monPartyId);
u32 GetMostSuitableMonToSwitchInto(enum BattlerId battler, enum SwitchType switchType);
bool32 ShouldSwitch(enum BattlerId battler);
void ModifySwitchAfterMoveScoring(enum BattlerId battler);
u32 AI_SelectRevivalBlessingMon(enum BattlerId battler);
bool32 IsSwitchinValid(enum BattlerId battler);
bool32 IsAceMon(enum BattlerId battler, u32 monPartyId);
#endif // GUARD_BATTLE_AI_SWITCH_H

View File

@ -77,154 +77,154 @@ static inline bool32 IsMoveUnusable(u32 moveIndex, enum Move move, u32 moveLimit
typedef bool32 (*MoveFlag)(enum Move move);
bool32 AI_IsFaster(u32 battlerAi, u32 battlerDef, enum Move aiMove, enum Move playerMove, enum ConsiderPriority considerPriority);
bool32 AI_IsSlower(u32 battlerAi, u32 battlerDef, enum Move aiMove, enum Move playerMove, enum ConsiderPriority considerPriority);
bool32 AI_IsFaster(enum BattlerId battlerAi, enum BattlerId battlerDef, enum Move aiMove, enum Move playerMove, enum ConsiderPriority considerPriority);
bool32 AI_IsSlower(enum BattlerId battlerAi, enum BattlerId battlerDef, enum Move aiMove, enum Move playerMove, enum ConsiderPriority considerPriority);
bool32 AI_RandLessThan(u32 val);
bool32 AI_IsBattlerGrounded(u32 battler);
enum MoveTarget AI_GetBattlerMoveTargetType(u32 battler, enum Move move);
enum Ability AI_GetMoldBreakerSanitizedAbility(u32 battlerAtk, enum Ability abilityAtk, enum Ability abilityDef, enum HoldEffect holdEffectDef, enum Move move);
u32 AI_GetDamage(u32 battlerAtk, u32 battlerDef, u32 moveIndex, enum DamageCalcContext calcContext, struct AiLogicData *aiData);
bool32 AI_IsBattlerGrounded(enum BattlerId battler);
enum MoveTarget AI_GetBattlerMoveTargetType(enum BattlerId battler, enum Move move);
enum Ability AI_GetMoldBreakerSanitizedAbility(enum BattlerId battlerAtk, enum Ability abilityAtk, enum Ability abilityDef, enum HoldEffect holdEffectDef, enum Move move);
u32 AI_GetDamage(enum BattlerId battlerAtk, enum BattlerId battlerDef, u32 moveIndex, enum DamageCalcContext calcContext, struct AiLogicData *aiData);
bool32 IsAiFlagPresent(u64 flag);
bool32 IsAiBattlerAware(u32 battlerId);
bool32 CanAiPredictMove(u32 battlerId);
bool32 IsAiBattlerAssumingStab(u32 battlerId);
bool32 IsAiBattlerAssumingStatusMoves(u32 battlerId);
bool32 IsAiBattlerPredictingAbility(u32 battlerId);
bool32 IsAiBattlerAware(enum BattlerId battlerId);
bool32 CanAiPredictMove(enum BattlerId battlerId);
bool32 IsAiBattlerAssumingStab(enum BattlerId battlerId);
bool32 IsAiBattlerAssumingStatusMoves(enum BattlerId battlerId);
bool32 IsAiBattlerPredictingAbility(enum BattlerId battlerId);
bool32 ShouldRecordStatusMove(enum Move move);
void ClearBattlerMoveHistory(u32 battlerId);
void RecordLastUsedMoveBy(u32 battlerId, enum Move move);
void RecordAllMoves(u32 battler);
void RecordKnownMove(u32 battlerId, enum Move move);
void RecordAbilityBattle(u32 battlerId, enum Ability abilityId);
void ClearBattlerAbilityHistory(u32 battlerId);
void RecordItemEffectBattle(u32 battlerId, enum HoldEffect itemEffect);
void ClearBattlerItemEffectHistory(u32 battlerId);
void SaveBattlerData(u32 battlerId);
void SetBattlerData(u32 battlerId);
void SetBattlerAiData(u32 battlerId, struct AiLogicData *aiData);
void RestoreBattlerData(u32 battlerId);
enum Move GetAIChosenMove(u32 battlerId);
void ClearBattlerMoveHistory(enum BattlerId battlerId);
void RecordLastUsedMoveBy(enum BattlerId battlerId, enum Move move);
void RecordAllMoves(enum BattlerId battler);
void RecordKnownMove(enum BattlerId battlerId, enum Move move);
void RecordAbilityBattle(enum BattlerId battlerId, enum Ability abilityId);
void ClearBattlerAbilityHistory(enum BattlerId battlerId);
void RecordItemEffectBattle(enum BattlerId battlerId, enum HoldEffect itemEffect);
void ClearBattlerItemEffectHistory(enum BattlerId battlerId);
void SaveBattlerData(enum BattlerId battlerId);
void SetBattlerData(enum BattlerId battlerId);
void SetBattlerAiData(enum BattlerId battler, struct AiLogicData *aiData);
void RestoreBattlerData(enum BattlerId battlerId);
enum Move GetAIChosenMove(enum BattlerId battlerId);
u32 GetTotalBaseStat(u32 species);
bool32 IsTruantMonVulnerable(u32 battlerAI, u32 opposingBattler);
bool32 AI_BattlerAtMaxHp(u32 battler);
u32 GetHealthPercentage(u32 battler);
bool32 AI_CanBattlerEscape(u32 battler);
bool32 IsBattlerTrapped(u32 battlerAtk, u32 battlerDef);
s32 AI_WhoStrikesFirst(u32 battlerAI, u32 battler2, enum Move aiMoveConsidered, enum Move playerMoveConsidered, enum ConsiderPriority considerPriority);
bool32 CanTargetFaintAi(u32 battlerDef, u32 battlerAtk);
u32 NoOfHitsForTargetToFaintBattler(u32 battlerDef, u32 battlerAtk, enum AiConsiderEndure considerEndure);
void GetBestDmgMovesFromBattler(u32 battlerAtk, u32 battlerDef, enum DamageCalcContext calcContext, enum Move *bestMoves);
u32 GetMoveIndex(u32 battler, enum Move move);
bool32 IsBestDmgMove(u32 battlerAtk, u32 battlerDef, enum DamageCalcContext calcContext, enum Move move);
bool32 BestDmgMoveHasEffect(u32 battlerAtk, u32 battlerDef, enum DamageCalcContext calcContext, enum BattleMoveEffects moveEffect);
u32 GetBestDmgFromBattler(u32 battler, u32 battlerTarget, enum DamageCalcContext calcContext);
bool32 CanTargetMoveFaintAi(enum Move move, u32 battlerDef, u32 battlerAtk, u32 nHits);
bool32 CanTargetFaintAiWithMod(u32 battlerDef, u32 battlerAtk, s32 hpMod, s32 dmgMod);
enum Ability AI_DecideKnownAbilityForTurn(u32 battlerId);
enum HoldEffect AI_DecideHoldEffectForTurn(u32 battlerId);
bool32 DoesBattlerIgnoreAbilityChecks(u32 battlerAtk, enum Ability atkAbility, enum Move move);
bool32 IsTruantMonVulnerable(enum BattlerId battlerAI, enum BattlerId opposingBattler);
bool32 AI_BattlerAtMaxHp(enum BattlerId battler);
u32 GetHealthPercentage(enum BattlerId battler);
bool32 AI_CanBattlerEscape(enum BattlerId battler);
bool32 IsBattlerTrapped(enum BattlerId battlerAtk, enum BattlerId battlerDef);
s32 AI_WhoStrikesFirst(enum BattlerId battlerAI, enum BattlerId battler, enum Move aiMoveConsidered, enum Move playerMoveConsidered, enum ConsiderPriority considerPriority);
bool32 CanTargetFaintAi(enum BattlerId battlerDef, enum BattlerId battlerAtk);
u32 NoOfHitsForTargetToFaintBattler(enum BattlerId battlerDef, enum BattlerId battlerAtk, enum AiConsiderEndure considerEndure);
void GetBestDmgMovesFromBattler(enum BattlerId battlerAtk, enum BattlerId battlerDef, enum DamageCalcContext calcContext, enum Move *bestMoves);
u32 GetMoveIndex(enum BattlerId battler, enum Move move);
bool32 IsBestDmgMove(enum BattlerId battlerAtk, enum BattlerId battlerDef, enum DamageCalcContext calcContext, enum Move move);
bool32 BestDmgMoveHasEffect(enum BattlerId battlerAtk, enum BattlerId battlerDef, enum DamageCalcContext calcContext, enum BattleMoveEffects moveEffect);
u32 GetBestDmgFromBattler(enum BattlerId battler, enum BattlerId battlerTarget, enum DamageCalcContext calcContext);
bool32 CanTargetMoveFaintAi(enum Move move, enum BattlerId battlerDef, enum BattlerId battlerAtk, u32 nHits);
bool32 CanTargetFaintAiWithMod(enum BattlerId battlerDef, enum BattlerId battlerAtk, s32 hpMod, s32 dmgMod);
enum Ability AI_DecideKnownAbilityForTurn(enum BattlerId battlerId);
enum HoldEffect AI_DecideHoldEffectForTurn(enum BattlerId battlerId);
bool32 DoesBattlerIgnoreAbilityChecks(enum BattlerId battlerAtk, enum Ability atkAbility, enum Move move);
u32 AI_GetWeather(void);
u32 AI_GetSwitchinWeather(u32 battler);
u32 AI_GetSwitchinFieldStatus(u32 battler);
u32 AI_GetSwitchinWeather(enum BattlerId battler);
u32 AI_GetSwitchinFieldStatus(enum BattlerId battler);
enum WeatherState IsWeatherActive(u32 flags);
bool32 CanAIFaintTarget(u32 battlerAtk, u32 battlerDef, u32 numHits);
bool32 CanIndexMoveFaintTarget(u32 battlerAtk, u32 battlerDef, u32 index, enum DamageCalcContext calcContext);
bool32 HasDamagingMove(u32 battler);
bool32 HasDamagingMoveOfType(u32 battler, enum Type type);
u32 GetBattlerSecondaryDamage(u32 battlerId);
bool32 BattlerWillFaintFromWeather(u32 battler, enum Ability ability);
bool32 BattlerWillFaintFromSecondaryDamage(u32 battler, enum Ability ability);
bool32 ShouldTryOHKO(u32 battlerAtk, u32 battlerDef, enum Ability atkAbility, enum Ability defAbility, enum Move move);
bool32 ShouldUseRecoilMove(u32 battlerAtk, u32 battlerDef, u32 recoilDmg, u32 moveIndex);
bool32 ShouldAbsorb(u32 battlerAtk, u32 battlerDef, enum Move move);
bool32 ShouldRecover(u32 battlerAtk, u32 battlerDef, enum Move move, u32 healPercent);
bool32 ShouldSetScreen(u32 battlerAtk, u32 battlerDef, enum BattleMoveEffects moveEffect);
bool32 ShouldCureStatus(u32 battlerAtk, u32 battlerDef, struct AiLogicData *aiData);
bool32 ShouldCureStatusWithItem(u32 battlerAtk, u32 battlerDef, struct AiLogicData *aiData);
enum AIPivot ShouldPivot(u32 battlerAtk, u32 battlerDef, enum Move move);
bool32 CanAIFaintTarget(enum BattlerId battlerAtk, enum BattlerId battlerDef, u32 numHits);
bool32 CanIndexMoveFaintTarget(enum BattlerId battlerAtk, enum BattlerId battlerDef, u32 index, enum DamageCalcContext calcContext);
bool32 HasDamagingMove(enum BattlerId battler);
bool32 HasDamagingMoveOfType(enum BattlerId battler, enum Type type);
u32 GetBattlerSecondaryDamage(enum BattlerId battlerId);
bool32 BattlerWillFaintFromWeather(enum BattlerId battler, enum Ability ability);
bool32 BattlerWillFaintFromSecondaryDamage(enum BattlerId battler, enum Ability ability);
bool32 ShouldTryOHKO(enum BattlerId battlerAtk, enum BattlerId battlerDef, enum Ability atkAbility, enum Ability defAbility, enum Move move);
bool32 ShouldUseRecoilMove(enum BattlerId battlerAtk, enum BattlerId battlerDef, u32 recoilDmg, u32 moveIndex);
bool32 ShouldAbsorb(enum BattlerId battlerAtk, enum BattlerId battlerDef, enum Move move);
bool32 ShouldRecover(enum BattlerId battlerAtk, enum BattlerId battlerDef, enum Move move, u32 healPercent);
bool32 ShouldSetScreen(enum BattlerId battlerAtk, enum BattlerId battlerDef, enum BattleMoveEffects moveEffect);
bool32 ShouldCureStatus(enum BattlerId battlerAtk, enum BattlerId battlerDef, struct AiLogicData *aiData);
bool32 ShouldCureStatusWithItem(enum BattlerId battlerAtk, enum BattlerId battlerDef, struct AiLogicData *aiData);
enum AIPivot ShouldPivot(enum BattlerId battlerAtk, enum BattlerId battlerDef, enum Move move);
bool32 IsRecycleEncouragedItem(enum Item item);
bool32 ShouldRestoreHpBerry(u32 battlerAtk, enum Item item);
bool32 ShouldRestoreHpBerry(enum BattlerId battlerAtk, enum Item item);
bool32 IsStatBoostingBerry(enum Item item);
bool32 CanKnockOffItem(u32 fromBattler, u32 battler, enum Item item);
bool32 CanKnockOffItem(enum BattlerId fromBattler, enum BattlerId battler, enum Item item);
bool32 IsAbilityOfRating(enum Ability ability, s32 rating);
bool32 AI_IsAbilityOnSide(u32 battlerId, enum Ability ability);
bool32 AI_MoveMakesContact(u32 battlerAtk, u32 battlerDef, enum Ability ability, enum HoldEffect holdEffect, enum Move move);
bool32 IsUnseenFistContactMove(u32 battlerAtk, u32 battlerDef, enum Move move);
bool32 IsConsideringZMove(u32 battlerAtk, u32 battlerDef, enum Move move);
bool32 ShouldUseZMove(u32 battlerAtk, u32 battlerDef, enum Move chosenMove);
void SetAIUsingGimmick(u32 battler, enum AIConsiderGimmick use);
bool32 IsAIUsingGimmick(u32 battler);
void DecideTerastal(u32 battler);
bool32 CanEndureHit(u32 battler, u32 battlerTarget, enum Move move);
bool32 ShouldFinalGambit(u32 battlerAtk, u32 battlerDef, bool32 aiIsFaster);
bool32 ShouldConsiderSelfSacrificeDamageEffect(u32 battlerAtk, u32 battlerDef, enum Move move, bool32 aiIsFaster);
bool32 AI_IsAbilityOnSide(enum BattlerId battlerId, enum Ability ability);
bool32 AI_MoveMakesContact(enum BattlerId battlerAtk, enum BattlerId battlerDef, enum Ability ability, enum HoldEffect holdEffect, enum Move move);
bool32 IsUnseenFistContactMove(enum BattlerId battlerAtk, enum BattlerId battlerDef, enum Move move);
bool32 IsConsideringZMove(enum BattlerId battlerAtk, enum BattlerId battlerDef, enum Move move);
bool32 ShouldUseZMove(enum BattlerId battlerAtk, enum BattlerId battlerDef, enum Move chosenMove);
void SetAIUsingGimmick(enum BattlerId battler, enum AIConsiderGimmick use);
bool32 IsAIUsingGimmick(enum BattlerId battler);
void DecideTerastal(enum BattlerId battler);
bool32 CanEndureHit(enum BattlerId battler, enum BattlerId battlerTarget, enum Move move);
bool32 ShouldFinalGambit(enum BattlerId battlerAtk, enum BattlerId battlerDef, bool32 aiIsFaster);
bool32 ShouldConsiderSelfSacrificeDamageEffect(enum BattlerId battlerAtk, enum BattlerId battlerDef, enum Move move, bool32 aiIsFaster);
// stat stage checks
bool32 AnyStatIsRaised(u32 battlerId);
bool32 AnyUsefulStatIsRaised(u32 battlerId);
bool32 CanLowerStat(u32 battlerAtk, u32 battlerDef, struct AiLogicData *aiData, enum Stat stat);
bool32 BattlerStatCanRise(u32 battler, enum Ability battlerAbility, enum Stat stat);
bool32 AreBattlersStatsMaxed(u32 battler);
u32 CountPositiveStatStages(u32 battlerId);
u32 CountNegativeStatStages(u32 battlerId);
bool32 AnyStatIsRaised(enum BattlerId battlerId);
bool32 AnyUsefulStatIsRaised(enum BattlerId battlerId);
bool32 CanLowerStat(enum BattlerId battlerAtk, enum BattlerId battlerDef, struct AiLogicData *aiData, enum Stat stat);
bool32 BattlerStatCanRise(enum BattlerId battler, enum Ability battlerAbility, enum Stat stat);
bool32 AreBattlersStatsMaxed(enum BattlerId battler);
u32 CountPositiveStatStages(enum BattlerId battlerId);
u32 CountNegativeStatStages(enum BattlerId battlerId);
// move checks
bool32 Ai_IsPriorityBlocked(u32 battlerAtk, u32 battlerDef, enum Move move, struct AiLogicData *aiData);
bool32 Ai_IsPriorityBlocked(enum BattlerId battlerAtk, enum BattlerId battlerDef, enum Move move, struct AiLogicData *aiData);
bool32 AI_CanMoveBeBlockedByTarget(struct BattleContext *ctx);
bool32 MovesWithCategoryUnusable(u32 attacker, u32 target, enum DamageCategory category);
enum MoveComparisonResult CompareMoveEffects(enum Move move1, enum Move move2, u32 battlerAtk, u32 battlerDef, s32 noOfHitsToKo);
struct SimulatedDamage AI_CalcDamageSaveBattlers(enum Move move, u32 battlerAtk, u32 battlerDef, uq4_12_t *typeEffectiveness, enum AIConsiderGimmick considerGimmickAtk, enum AIConsiderGimmick considerGimmickDef);
bool32 IsAdditionalEffectBlocked(u32 battlerAtk, u32 abilityAtk, u32 battlerDef, enum Ability abilityDef);
struct SimulatedDamage AI_CalcDamage(enum Move move, u32 battlerAtk, u32 battlerDef, uq4_12_t *typeEffectiveness, enum AIConsiderGimmick considerGimmickAtk, enum AIConsiderGimmick considerGimmickDef, u32 weather, u32 fieldStatuses);
bool32 AI_IsDamagedByRecoil(u32 battler);
enum MoveComparisonResult CompareMoveEffects(enum Move move1, enum Move move2, enum BattlerId battlerAtk, enum BattlerId battlerDef, s32 noOfHitsToKo);
struct SimulatedDamage AI_CalcDamageSaveBattlers(enum Move move, enum BattlerId battlerAtk, enum BattlerId battlerDef, uq4_12_t *typeEffectiveness, enum AIConsiderGimmick considerGimmickAtk, enum AIConsiderGimmick considerGimmickDef);
bool32 IsAdditionalEffectBlocked(enum BattlerId battlerAtk, u32 abilityAtk, enum BattlerId battlerDef, enum Ability abilityDef);
struct SimulatedDamage AI_CalcDamage(enum Move move, enum BattlerId battlerAtk, enum BattlerId battlerDef, uq4_12_t *typeEffectiveness, enum AIConsiderGimmick considerGimmickAtk, enum AIConsiderGimmick considerGimmickDef, u32 weather, u32 fieldStatuses);
bool32 AI_IsDamagedByRecoil(enum BattlerId battler);
u32 GetNoOfHitsToKO(u32 dmg, s32 hp);
u32 GetNoOfHitsToKOBattlerDmg(u32 dmg, u32 battlerDef);
u32 GetNoOfHitsToKOBattler(u32 battlerAtk, u32 battlerDef, u32 moveIndex, enum DamageCalcContext calcContext, enum AiConsiderEndure considerEndure);
u32 GetBestNoOfHitsToKO(u32 battlerAtk, u32 battlerDef, enum DamageCalcContext calcContext);
u32 GetCurrDamageHpPercent(u32 battlerAtk, u32 battlerDef, enum DamageCalcContext calcContext);
uq4_12_t AI_GetMoveEffectiveness(enum Move move, u32 battlerAtk, u32 battlerDef);
enum Move *GetMovesArray(u32 battler);
u32 GetNoOfHitsToKOBattlerDmg(u32 dmg, enum BattlerId battlerDef);
u32 GetNoOfHitsToKOBattler(enum BattlerId battlerAtk, enum BattlerId battlerDef, u32 moveIndex, enum DamageCalcContext calcContext, enum AiConsiderEndure considerEndure);
u32 GetBestNoOfHitsToKO(enum BattlerId battlerAtk, enum BattlerId battlerDef, enum DamageCalcContext calcContext);
u32 GetCurrDamageHpPercent(enum BattlerId battlerAtk, enum BattlerId battlerDef, enum DamageCalcContext calcContext);
uq4_12_t AI_GetMoveEffectiveness(enum Move move, enum BattlerId battlerAtk, enum BattlerId battlerDef);
enum Move *GetMovesArray(enum BattlerId battler);
bool32 IsConfusionMoveEffect(enum BattleMoveEffects moveEffect);
bool32 HasMove(u32 battlerId, enum Move move);
u32 GetBattlerMoveIndexWithEffect(u32 battler, enum BattleMoveEffects effect);
bool32 HasPhysicalBestMove(u32 battlerAtk, u32 battlerDef, enum DamageCalcContext calcContext);
bool32 HasOnlyMovesWithCategory(u32 battlerId, enum DamageCategory category, bool32 onlyOffensive);
bool32 HasMoveWithCategory(u32 battler, enum DamageCategory category);
bool32 HasMoveWithType(u32 battler, enum Type type);
bool32 HasMoveWithEffect(u32 battler, enum BattleMoveEffects moveEffect);
bool32 HasMoveWithAIEffect(u32 battler, u32 aiEffect);
bool32 HasBattlerSideMoveWithEffect(u32 battler, enum BattleMoveEffects effect);
bool32 HasBattlerSideMoveWithAIEffect(u32 battler, u32 effect);
bool32 HasBattlerSideUsedMoveWithEffect(u32 battler, enum BattleMoveEffects effect);
bool32 HasNonVolatileMoveEffect(u32 battlerId, enum MoveEffect effect);
bool32 IsPowerBasedOnStatus(u32 battlerId, enum BattleMoveEffects effect, u32 argument);
bool32 HasMoveWithAdditionalEffect(u32 battlerId, enum MoveEffect moveEffect);
bool32 HasBattlerSideMoveWithAdditionalEffect(u32 battler, enum MoveEffect moveEffect);
bool32 HasMoveWithCriticalHitChance(u32 battlerId);
bool32 HasMoveWithMoveEffectExcept(u32 battlerId, enum MoveEffect moveEffect, enum BattleMoveEffects exception);
bool32 HasMoveThatLowersOwnStats(u32 battlerId);
bool32 HasMoveWithLowAccuracy(u32 battlerAtk, u32 battlerDef, u32 accCheck, bool32 ignoreStatus);
bool32 HasAnyKnownMove(u32 battlerId);
bool32 HasMove(enum BattlerId battlerId, enum Move move);
u32 GetBattlerMoveIndexWithEffect(enum BattlerId battler, enum BattleMoveEffects effect);
bool32 HasPhysicalBestMove(enum BattlerId battlerAtk, enum BattlerId battlerDef, enum DamageCalcContext calcContext);
bool32 HasOnlyMovesWithCategory(enum BattlerId battlerId, enum DamageCategory category, bool32 onlyOffensive);
bool32 HasMoveWithCategory(enum BattlerId battler, enum DamageCategory category);
bool32 HasMoveWithType(enum BattlerId battler, enum Type type);
bool32 HasMoveWithEffect(enum BattlerId battler, enum BattleMoveEffects moveEffect);
bool32 HasMoveWithAIEffect(enum BattlerId battler, u32 aiEffect);
bool32 HasBattlerSideMoveWithEffect(enum BattlerId battler, enum BattleMoveEffects effect);
bool32 HasBattlerSideMoveWithAIEffect(enum BattlerId battler, u32 effect);
bool32 HasBattlerSideUsedMoveWithEffect(enum BattlerId battler, enum BattleMoveEffects effect);
bool32 HasNonVolatileMoveEffect(enum BattlerId battlerId, enum MoveEffect effect);
bool32 IsPowerBasedOnStatus(enum BattlerId battlerId, enum BattleMoveEffects effect, u32 argument);
bool32 HasMoveWithAdditionalEffect(enum BattlerId battlerId, enum MoveEffect moveEffect);
bool32 HasBattlerSideMoveWithAdditionalEffect(enum BattlerId battler, enum MoveEffect moveEffect);
bool32 HasMoveWithCriticalHitChance(enum BattlerId battlerId);
bool32 HasMoveWithMoveEffectExcept(enum BattlerId battlerId, enum MoveEffect moveEffect, enum BattleMoveEffects exception);
bool32 HasMoveThatLowersOwnStats(enum BattlerId battlerId);
bool32 HasMoveWithLowAccuracy(enum BattlerId battlerAtk, enum BattlerId battlerDef, u32 accCheck, bool32 ignoreStatus);
bool32 HasAnyKnownMove(enum BattlerId battlerId);
bool32 IsAromaVeilProtectedEffect(enum BattleMoveEffects moveEffect);
bool32 IsNonVolatileStatusMove(enum Move move);
bool32 IsMoveRedirectionPrevented(u32 battlerAtk, enum Move move, enum Ability atkAbility);
bool32 IsMoveRedirectionPrevented(enum BattlerId battlerAtk, enum Move move, enum Ability atkAbility);
bool32 IsHazardMove(enum Move move);
bool32 IsTwoTurnNotSemiInvulnerableMove(u32 battlerAtk, enum Move move);
bool32 IsBattlerDamagedByStatus(u32 battler);
s32 ProtectChecks(u32 battlerAtk, u32 battlerDef, enum Move move, enum Move predictedMove);
bool32 ShouldRaiseAnyStat(u32 battlerAtk, u32 battlerDef);
bool32 ShouldSetWeather(u32 battler, u32 weather);
bool32 ShouldClearWeather(u32 battler, u32 weather);
bool32 ShouldSetFieldStatus(u32 battler, u32 fieldStatus);
bool32 ShouldClearFieldStatus(u32 battler, u32 fieldStatus);
bool32 HasSleepMoveWithLowAccuracy(u32 battlerAtk, u32 battlerDef);
bool32 HasHealingEffect(u32 battler);
bool32 IsTwoTurnNotSemiInvulnerableMove(enum BattlerId battlerAtk, enum Move move);
bool32 IsBattlerDamagedByStatus(enum BattlerId battler);
s32 ProtectChecks(enum BattlerId battlerAtk, enum BattlerId battlerDef, enum Move move, enum Move predictedMove);
bool32 ShouldRaiseAnyStat(enum BattlerId battlerAtk, enum BattlerId battlerDef);
bool32 ShouldSetWeather(enum BattlerId battler, u32 weather);
bool32 ShouldClearWeather(enum BattlerId battler, u32 weather);
bool32 ShouldSetFieldStatus(enum BattlerId battler, u32 fieldStatus);
bool32 ShouldClearFieldStatus(enum BattlerId battler, u32 fieldStatus);
bool32 HasSleepMoveWithLowAccuracy(enum BattlerId battlerAtk, enum BattlerId battlerDef);
bool32 HasHealingEffect(enum BattlerId battler);
bool32 IsTrappingMove(enum Move move);
bool32 HasTrappingMoveEffect(u32 battler);
bool32 IsFlinchGuaranteed(u32 battlerAtk, u32 battlerDef, enum Move move);
bool32 HasChoiceEffect(u32 battler);
bool32 HasThawingMove(u32 battler);
bool32 HasUsableWhileAsleepMove(u32 battler);
bool32 HasTrappingMoveEffect(enum BattlerId battler);
bool32 IsFlinchGuaranteed(enum BattlerId battlerAtk, enum BattlerId battlerDef, enum Move move);
bool32 HasChoiceEffect(enum BattlerId battler);
bool32 HasThawingMove(enum BattlerId battler);
bool32 HasUsableWhileAsleepMove(enum BattlerId battler);
bool32 IsStatRaisingEffect(enum BattleMoveEffects effect);
bool32 IsStatLoweringEffect(enum BattleMoveEffects effect);
bool32 IsSelfStatLoweringEffect(enum MoveEffect effect);
@ -233,107 +233,107 @@ bool32 IsSwitchOutEffect(enum BattleMoveEffects effect);
bool32 IsChaseEffect(enum BattleMoveEffects effect);
bool32 IsAttackBoostMoveEffect(enum BattleMoveEffects effect);
bool32 IsUngroundingEffect(enum BattleMoveEffects effect);
bool32 HasMoveWithFlag(u32 battler, MoveFlag getFlag);
bool32 HasMoveWithFlag(enum BattlerId battler, MoveFlag getFlag);
bool32 IsHazardClearingMove(enum Move move);
bool32 IsSubstituteEffect(enum BattleMoveEffects effect);
bool32 IsSelfSacrificeEffect(enum Move move);
u32 GetAIExplosionChanceFromHP(u32 hpPercent);
// status checks
bool32 AI_CanBeConfused(u32 battlerAtk, u32 battlerDef, enum Move move, enum Ability ability);
bool32 IsBattlerIncapacitated(u32 battler, enum Ability ability);
bool32 AI_CanPutToSleep(u32 battlerAtk, u32 battlerDef, enum Ability defAbility, enum Move move, enum Move partnerMove);
bool32 ShouldPoison(u32 battlerAtk, u32 battlerDef);
bool32 AI_CanPoison(u32 battlerAtk, u32 battlerDef, enum Ability defAbility, enum Move move, enum Move partnerMove);
bool32 AI_CanParalyze(u32 battlerAtk, u32 battlerDef, enum Ability defAbility, enum Move move, enum Move partnerMove);
bool32 AI_CanConfuse(u32 battlerAtk, u32 battlerDef, enum Ability defAbility, u32 battlerAtkPartner, enum Move move, enum Move partnerMove);
bool32 ShouldBurn(u32 battlerAtk, u32 battlerDef, enum Ability abilityDef);
bool32 ShouldFreezeOrFrostbite(u32 battlerAtk, u32 battlerDef, enum Ability abilityDef);
bool32 ShouldParalyze(u32 battlerAtk, u32 battlerDef, enum Ability abilityDef);
bool32 AI_CanBurn(u32 battlerAtk, u32 battlerDef, enum Ability defAbility, u32 battlerAtkPartner, enum Move move, enum Move partnerMove);
bool32 AI_CanGiveFrostbite(u32 battlerAtk, u32 battlerDef, enum Ability defAbility, u32 battlerAtkPartner, enum Move move, enum Move partnerMove);
bool32 AI_CanBeInfatuated(u32 battlerAtk, u32 battlerDef, enum Ability defAbility);
bool32 AnyPartyMemberStatused(u32 battlerId, bool32 checkSoundproof);
bool32 ShouldTryToFlinch(u32 battlerAtk, u32 battlerDef, enum Ability atkAbility, enum Ability defAbility, enum Move move);
bool32 ShouldTrap(u32 battlerAtk, u32 battlerDef, enum Move move);
bool32 IsWakeupTurn(u32 battler);
bool32 AI_IsBattlerAsleepOrComatose(u32 battlerId);
bool32 AI_CanBeConfused(enum BattlerId battlerAtk, enum BattlerId battlerDef, enum Move move, enum Ability ability);
bool32 IsBattlerIncapacitated(enum BattlerId battler, enum Ability ability);
bool32 AI_CanPutToSleep(enum BattlerId battlerAtk, enum BattlerId battlerDef, enum Ability defAbility, enum Move move, enum Move partnerMove);
bool32 ShouldPoison(enum BattlerId battlerAtk, enum BattlerId battlerDef);
bool32 AI_CanPoison(enum BattlerId battlerAtk, enum BattlerId battlerDef, enum Ability defAbility, enum Move move, enum Move partnerMove);
bool32 AI_CanParalyze(enum BattlerId battlerAtk, enum BattlerId battlerDef, enum Ability defAbility, enum Move move, enum Move partnerMove);
bool32 AI_CanConfuse(enum BattlerId battlerAtk, enum BattlerId battlerDef, enum Ability defAbility, enum BattlerId battlerAtkPartner, enum Move move, enum Move partnerMove);
bool32 ShouldBurn(enum BattlerId battlerAtk, enum BattlerId battlerDef, enum Ability abilityDef);
bool32 ShouldFreezeOrFrostbite(enum BattlerId battlerAtk, enum BattlerId battlerDef, enum Ability abilityDef);
bool32 ShouldParalyze(enum BattlerId battlerAtk, enum BattlerId battlerDef, enum Ability abilityDef);
bool32 AI_CanBurn(enum BattlerId battlerAtk, enum BattlerId battlerDef, enum Ability defAbility, enum BattlerId battlerAtkPartner, enum Move move, enum Move partnerMove);
bool32 AI_CanGiveFrostbite(enum BattlerId battlerAtk, enum BattlerId battlerDef, enum Ability defAbility, enum BattlerId battlerAtkPartner, enum Move move, enum Move partnerMove);
bool32 AI_CanBeInfatuated(enum BattlerId battlerAtk, enum BattlerId battlerDef, enum Ability defAbility);
bool32 AnyPartyMemberStatused(enum BattlerId battlerId, bool32 checkSoundproof);
bool32 ShouldTryToFlinch(enum BattlerId battlerAtk, enum BattlerId battlerDef, enum Ability atkAbility, enum Ability defAbility, enum Move move);
bool32 ShouldTrap(enum BattlerId battlerAtk, enum BattlerId battlerDef, enum Move move);
bool32 IsWakeupTurn(enum BattlerId battler);
bool32 AI_IsBattlerAsleepOrComatose(enum BattlerId battlerId);
// ability logic
bool32 IsMoxieTypeAbility(enum Ability ability);
bool32 DoesAbilityRaiseStatsWhenLowered(enum Ability ability);
bool32 ShouldTriggerAbility(u32 battlerAtk, u32 battlerDef, enum Ability ability);
bool32 CanEffectChangeAbility(u32 battlerAtk, u32 battlerDef, enum Move move, struct AiLogicData *aiData);
void AbilityChangeScore(u32 battlerAtk, u32 battlerDef, enum Move move, s32 *score, struct AiLogicData *aiData);
s32 BattlerBenefitsFromAbilityScore(u32 battler, enum Ability ability, struct AiLogicData *aiData);
bool32 ShouldTriggerAbility(enum BattlerId battlerAtk, enum BattlerId battlerDef, enum Ability ability);
bool32 CanEffectChangeAbility(enum BattlerId battlerAtk, enum BattlerId battlerDef, enum Move move, struct AiLogicData *aiData);
void AbilityChangeScore(enum BattlerId battlerAtk, enum BattlerId battlerDef, enum Move move, s32 *score, struct AiLogicData *aiData);
enum AIScore BattlerBenefitsFromAbilityScore(enum BattlerId battler, enum Ability ability, struct AiLogicData *aiData);
// partner logic
bool32 IsTargetingPartner(u32 battlerAtk, u32 battlerDef);
bool32 IsTargetingPartner(enum BattlerId battlerAtk, enum BattlerId battlerDef);
// IsTargetingPartner includes a check to make sure the adjacent pokemon is truly a partner.
enum Move GetAllyChosenMove(u32 battlerId);
enum Move GetAllyChosenMove(enum BattlerId battlerId);
bool32 IsBattle1v1(void);
// IsBattle1v1 is distinct from !IsDoubleBattle. If the player is fighting Maxie and Tabitha, with Steven as their partner, and both Tabitha and Steven have run out of Pokemon, the battle is 1v1, even though mechanically it is a Double Battle for how battlers and flags are set.
// Most AI checks should be using IsBattle1v1; most engine checks should be using !IsDoubleBattle
bool32 HasTwoOpponents(u32 battler);
bool32 HasTwoOpponents(enum BattlerId battler);
// HasTwoOpponents checks if the opposing side has two pokemon. Partner state is irrelevant. e.g., Dragon Darts hits one time with two opponents and twice with one opponent.
bool32 HasPartner(u32 battler);
bool32 HasPartnerIgnoreFlags(u32 battler);
bool32 HasPartner(enum BattlerId battler);
bool32 HasPartnerIgnoreFlags(enum BattlerId battler);
// HasPartner respects the Attacks Partner AI flag; HasPartnerIgnoreFlags checks only if a live pokemon is adjacent.
bool32 AreMovesEquivalent(u32 battlerAtk, u32 battlerAtkPartner, enum Move move, enum Move partnerMove);
bool32 DoesPartnerHaveSameMoveEffect(u32 battlerAtkPartner, u32 battlerDef, enum Move move, enum Move partnerMove);
bool32 PartnerMoveEffectIsStatusSameTarget(u32 battlerAtkPartner, u32 battlerDef, enum Move partnerMove);
bool32 PartnerMoveEffectIs(u32 battlerAtkPartner, enum Move partnerMove, enum BattleMoveEffects effectCheck);
bool32 PartnerMoveIs(u32 battlerAtkPartner, enum Move partnerMove, enum Move moveCheck);
bool32 PartnerMoveIsSameAsAttacker(u32 battlerAtkPartner, u32 battlerDef, enum Move move, enum Move partnerMove);
bool32 PartnerMoveIsSameNoTarget(u32 battlerAtkPartner, enum Move move, enum Move partnerMove);
bool32 AreMovesEquivalent(enum BattlerId battlerAtk, enum BattlerId battlerAtkPartner, enum Move move, enum Move partnerMove);
bool32 DoesPartnerHaveSameMoveEffect(enum BattlerId battlerAtkPartner, enum BattlerId battlerDef, enum Move move, enum Move partnerMove);
bool32 PartnerMoveEffectIsStatusSameTarget(enum BattlerId battlerAtkPartner, enum BattlerId battlerDef, enum Move partnerMove);
bool32 PartnerMoveEffectIs(enum BattlerId battlerAtkPartner, enum Move partnerMove, enum BattleMoveEffects effectCheck);
bool32 PartnerMoveIs(enum BattlerId battlerAtkPartner, enum Move partnerMove, enum Move moveCheck);
bool32 PartnerMoveIsSameAsAttacker(enum BattlerId battlerAtkPartner, enum BattlerId battlerDef, enum Move move, enum Move partnerMove);
bool32 PartnerMoveIsSameNoTarget(enum BattlerId battlerAtkPartner, enum Move move, enum Move partnerMove);
bool32 PartnerMoveActivatesSleepClause(enum Move partnerMove);
bool32 ShouldUseWishAromatherapy(u32 battlerAtk, u32 battlerDef, enum Move move);
u32 GetFriendlyFireKOThreshold(u32 battler);
bool32 IsAllyProtectingFromMove(u32 battlerAtk, enum Move attackerMove, enum Move allyMove);
bool32 ShouldUseWishAromatherapy(enum BattlerId battlerAtk, enum BattlerId battlerDef, enum Move move);
u32 GetFriendlyFireKOThreshold(enum BattlerId battler);
bool32 IsAllyProtectingFromMove(enum BattlerId battlerAtk, enum Move attackerMove, enum Move allyMove);
// party logic
struct BattlePokemon *AllocSaveBattleMons(void);
void FreeRestoreBattleMons(struct BattlePokemon *savedBattleMons);
struct AiLogicData *AllocSaveAiLogicData(void);
void FreeRestoreAiLogicData(struct AiLogicData *savedAiLogicData);
s32 CountUsablePartyMons(u32 battlerId);
bool32 IsPartyFullyHealedExceptBattler(u32 battler);
bool32 PartyHasMoveCategory(u32 battlerId, enum DamageCategory category);
bool32 SideHasMoveCategory(u32 battlerId, enum DamageCategory category);
void GetAIPartyIndexes(u32 battlerId, s32 *firstId, s32 *lastId);
u32 GetActiveBattlerIds(u32 battler, u32 *battlerIn1, u32 *battlerIn2);
bool32 IsPartyMonOnFieldOrChosenToSwitch(u32 partyIndex, u32 battlerIn1, u32 battlerIn2);
s32 CountUsablePartyMons(enum BattlerId battlerId);
bool32 IsPartyFullyHealedExceptBattler(enum BattlerId battler);
bool32 PartyHasMoveCategory(enum BattlerId battlerId, enum DamageCategory category);
bool32 SideHasMoveCategory(enum BattlerId battlerId, enum DamageCategory category);
void GetAIPartyIndexes(enum BattlerId battlerId, s32 *firstId, s32 *lastId);
u32 GetActiveBattlerIds(enum BattlerId battler, enum BattlerId *battlerIn1, enum BattlerId *battlerIn2);
bool32 IsPartyMonOnFieldOrChosenToSwitch(u32 partyIndex, enum BattlerId battlerIn1, enum BattlerId battlerIn2);
// score increases
enum AIScore IncreaseStatUpScore(u32 battlerAtk, u32 battlerDef, enum StatChange statId);
enum AIScore IncreaseStatUpScoreContrary(u32 battlerAtk, u32 battlerDef, enum StatChange statId);
enum AIScore IncreaseStatDownScore(u32 battlerAtk, u32 battlerDef, enum Stat stat);
void IncreasePoisonScore(u32 battlerAtk, u32 battlerDef, enum Move move, s32 *score);
void IncreaseBurnScore(u32 battlerAtk, u32 battlerDef, enum Move move, s32 *score);
void IncreaseParalyzeScore(u32 battlerAtk, u32 battlerDef, enum Move move, s32 *score);
void IncreaseSleepScore(u32 battlerAtk, u32 battlerDef, enum Move move, s32 *score);
void IncreaseConfusionScore(u32 battlerAtk, u32 battlerDef, enum Move move, s32 *score);
void IncreaseFrostbiteScore(u32 battlerAtk, u32 battlerDef, enum Move move, s32 *score);
bool32 HasHPForDamagingSetup(u32 battlerAtk, u32 battlerDef, u32 hpThreshold);
enum AIScore IncreaseStatUpScore(enum BattlerId battlerAtk, enum BattlerId battlerDef, enum StatChange statId);
enum AIScore IncreaseStatUpScoreContrary(enum BattlerId battlerAtk, enum BattlerId battlerDef, enum StatChange statId);
enum AIScore IncreaseStatDownScore(enum BattlerId battlerAtk, enum BattlerId battlerDef, enum Stat stat);
void IncreasePoisonScore(enum BattlerId battlerAtk, enum BattlerId battlerDef, enum Move move, s32 *score);
void IncreaseBurnScore(enum BattlerId battlerAtk, enum BattlerId battlerDef, enum Move move, s32 *score);
void IncreaseParalyzeScore(enum BattlerId battlerAtk, enum BattlerId battlerDef, enum Move move, s32 *score);
void IncreaseSleepScore(enum BattlerId battlerAtk, enum BattlerId battlerDef, enum Move move, s32 *score);
void IncreaseConfusionScore(enum BattlerId battlerAtk, enum BattlerId battlerDef, enum Move move, s32 *score);
void IncreaseFrostbiteScore(enum BattlerId battlerAtk, enum BattlerId battlerDef, enum Move move, s32 *score);
bool32 HasHPForDamagingSetup(enum BattlerId battlerAtk, enum BattlerId battlerDef, u32 hpThreshold);
s32 AI_TryToClearStats(u32 battlerAtk, u32 battlerDef, bool32 isDoubleBattle);
bool32 AI_ShouldCopyStatChanges(u32 battlerAtk, u32 battlerDef);
bool32 AI_ShouldSetUpHazards(u32 battlerAtk, u32 battlerDef, enum Move move, struct AiLogicData *aiData);
void IncreaseTidyUpScore(u32 battlerAtk, u32 battlerDef, enum Move move, s32 *score);
bool32 AI_ShouldSpicyExtract(u32 battlerAtk, u32 battlerAtkPartner, enum Move move, struct AiLogicData *aiData);
u32 IncreaseSubstituteMoveScore(u32 battlerAtk, u32 battlerDef, enum Move move);
bool32 IsBattlerItemEnabled(u32 battler);
bool32 IsBattlerPredictedToSwitch(u32 battler);
enum Move GetIncomingMove(u32 battler, u32 opposingBattler, struct AiLogicData *aiData);
enum Move GetIncomingMoveSpeedCheck(u32 battler, u32 opposingBattler, struct AiLogicData *aiData);
s32 AI_TryToClearStats(enum BattlerId battlerAtk, enum BattlerId battlerDef, bool32 isDoubleBattle);
bool32 AI_ShouldCopyStatChanges(enum BattlerId battlerAtk, enum BattlerId battlerDef);
bool32 AI_ShouldSetUpHazards(enum BattlerId battlerAtk, enum BattlerId battlerDef, enum Move move, struct AiLogicData *aiData);
void IncreaseTidyUpScore(enum BattlerId battlerAtk, enum BattlerId battlerDef, enum Move move, s32 *score);
bool32 AI_ShouldSpicyExtract(enum BattlerId battlerAtk, enum BattlerId battlerAtkPartner, enum Move move, struct AiLogicData *aiData);
u32 IncreaseSubstituteMoveScore(enum BattlerId battlerAtk, enum BattlerId battlerDef, enum Move move);
bool32 IsBattlerItemEnabled(enum BattlerId battler);
bool32 IsBattlerPredictedToSwitch(enum BattlerId battler);
enum Move GetIncomingMove(enum BattlerId battler, enum BattlerId opposingBattler, struct AiLogicData *aiData);
enum Move GetIncomingMoveSpeedCheck(enum BattlerId battler, enum BattlerId opposingBattler, struct AiLogicData *aiData);
bool32 IsNaturalEnemy(u32 speciesAttacker, u32 speciesTarget);
bool32 AI_OpponentCanFaintAiWithMod(u32 battler, u32 healAmount);
void SetBattlerFieldStatusForSwitchin(u32 battler);
bool32 ShouldInstructPartner(u32 battlerDef, enum Move move);
bool32 CanMoveBeBouncedBack(u32 battler, enum Move move);
bool32 AI_OpponentCanFaintAiWithMod(enum BattlerId battler, u32 healAmount);
void SetBattlerFieldStatusForSwitchin(enum BattlerId battler);
bool32 ShouldInstructPartner(enum BattlerId partner, enum Move move);
bool32 CanMoveBeBouncedBack(enum BattlerId battler, enum Move move);
// Switching and item helpers
bool32 AiExpectsToFaintPlayer(u32 battler);
bool32 AiExpectsToFaintPlayer(enum BattlerId battler);
// These are for the purpose of not doubling up on moves during double battles.
// Used in GetAIEffectGroup for move effects and GetAIEffectGroupFromMove for additional effects

View File

@ -98,7 +98,7 @@ struct LinkBattleAnim
u8 furyCutterCounter;
u8 syrupBombIsShiny:1;
u8 isTransformedMonShiny:1;
u8 padding:4;
u8 stockpileCounter:4;
};
#define ANIM_ARGS_COUNT 8

View File

@ -1013,6 +1013,8 @@ extern const u8 gBattleAnimGeneral_GhostGetOut[];
extern const u8 gBattleAnimGeneral_SilphScoped[];
extern const u8 gBattleAnimGeneral_SafariRockThrow[];
extern const u8 gBattleAnimGeneral_SafariReaction[];
extern const u8 gBattleAnimGeneral_FormChangeInstant[];
extern const u8 gBattleAnimGeneral_FormChangeDisguise[];
// special animations
extern const u8 gBattleAnimSpecial_LevelUp[];

View File

@ -19,6 +19,7 @@ void LoadBattleMenuWindowGfx(void);
void LoadBattleTextboxAndBackground(void);
void BattleInitBgsAndWindows(void);
void DrawMainBattleBackground(void);
bool8 LoadChosenBattleElement(u8 caseId);
void DrawTerrainTypeBattleBackground(void);
const void* GetBattleBackgroundPalette(u16 terrain);

View File

@ -1,7 +1,7 @@
#ifndef GUARD_BATTLE_CONTROLLERS_H
#define GUARD_BATTLE_CONTROLLERS_H
typedef void (*BattleControllerFunc)(u32 battler);
typedef void (*BattleControllerFunc)(enum BattlerId battler);
enum {
REQUEST_ALL_BATTLE,
@ -75,10 +75,11 @@ enum BattleController
BATTLE_CONTROLLER_LINK_PARTNER,
BATTLE_CONTROLLER_LINK_OPPONENT,
BATTLE_CONTROLLER_SAFARI,
BATTLE_CONTROLLER_WALLY,
BATTLE_CONTROLLER_RECORDED_PLAYER,
BATTLE_CONTROLLER_RECORDED_PARTNER,
BATTLE_CONTROLLER_RECORDED_OPPONENT,
BATTLE_CONTROLLER_OAK_OLD_MAN,
BATTLE_CONTROLLER_POKEDUDE,
BATTLE_CONTROLLERS_COUNT,
};
@ -90,47 +91,47 @@ enum BattleController
// (e.g. MarkBattlerForControllerExec) instead of using these macros
// directly.
static inline void MarkBattleControllerActiveOnLocal(u32 battler)
static inline void MarkBattleControllerActiveOnLocal(enum BattlerId battler)
{
gBattleControllerExecFlags |= (1u << battler);
}
static inline void MarkBattleControllerIdleOnLocal(u32 battler)
static inline void MarkBattleControllerIdleOnLocal(enum BattlerId battler)
{
gBattleControllerExecFlags &= ~(1u << battler);
}
static inline bool32 IsBattleControllerActiveOnLocal(u32 battler)
static inline bool32 IsBattleControllerActiveOnLocal(enum BattlerId battler)
{
return gBattleControllerExecFlags & (1u << battler);
}
static inline void MarkBattleControllerMessageOutboundOverLink(u32 battler)
static inline void MarkBattleControllerMessageOutboundOverLink(enum BattlerId battler)
{
gBattleControllerExecFlags |= ((1u << battler) << (32 - MAX_BATTLERS_COUNT));
}
static inline void MarkBattleControllerMessageSynchronizedOverLink(u32 battler)
static inline void MarkBattleControllerMessageSynchronizedOverLink(enum BattlerId battler)
{
gBattleControllerExecFlags &= ~((1 << 28) << (battler));
}
static inline bool32 IsBattleControllerMessageSynchronizedOverLink(u32 battler)
static inline bool32 IsBattleControllerMessageSynchronizedOverLink(enum BattlerId battler)
{
return gBattleControllerExecFlags & (1u << (battler + 28));
}
static inline void MarkBattleControllerActiveForPlayer(u32 battler, u32 playerId)
static inline void MarkBattleControllerActiveForPlayer(enum BattlerId battler, u32 playerId)
{
gBattleControllerExecFlags |= ((1u << battler) << ((playerId) << 2));
}
static inline void MarkBattleControllerIdleForPlayer(u32 battler, u32 playerId)
static inline void MarkBattleControllerIdleForPlayer(enum BattlerId battler, u32 playerId)
{
gBattleControllerExecFlags &= ~((1u << battler) << ((playerId) * 4));
}
static inline bool32 IsBattleControllerActiveForPlayer(u32 battler, u32 playerId)
static inline bool32 IsBattleControllerActiveForPlayer(enum BattlerId battler, u32 playerId)
{
return gBattleControllerExecFlags & ((1u << battler) << ((playerId) * 4));
}
@ -138,7 +139,7 @@ static inline bool32 IsBattleControllerActiveForPlayer(u32 battler, u32 playerId
// This actually checks if a specific controller is active on any player or if
// *any* controller is pending sync over link communications, but the macro name
// can only be so specific before it just gets ridiculous.
static inline bool32 IsBattleControllerActiveOrPendingSyncAnywhere(u32 battler)
static inline bool32 IsBattleControllerActiveOrPendingSyncAnywhere(enum BattlerId battler)
{
return gBattleControllerExecFlags & (
(1u << battler)
@ -284,8 +285,8 @@ enum
};
extern struct UnusedControllerStruct gUnusedControllerStruct;
extern void (*gBattlerControllerFuncs[MAX_BATTLERS_COUNT])(u32 battler);
extern void (*gBattlerControllerEndFuncs[MAX_BATTLERS_COUNT])(u32 battler);
extern void (*gBattlerControllerFuncs[MAX_BATTLERS_COUNT])(enum BattlerId battler);
extern void (*gBattlerControllerEndFuncs[MAX_BATTLERS_COUNT])(enum BattlerId battler);
extern u8 gBattleControllerData[MAX_BATTLERS_COUNT];
extern u8 gBattlerBattleController[MAX_BATTLERS_COUNT];
@ -295,178 +296,178 @@ void SetUpBattleVars(void);
void InitBattleControllers(void);
bool32 IsValidForBattle(struct Pokemon *mon);
void TryReceiveLinkBattleData(void);
void PrepareBufferDataTransferLink(u32 battler, u32 bufferId, u16 size, u8 *data);
void UpdateFriendshipFromXItem(u32 battler);
void PrepareBufferDataTransferLink(enum BattlerId battler, u32 bufferId, u16 size, u8 *data);
void UpdateFriendshipFromXItem(enum BattlerId battler);
bool32 IsAiVsAiBattle(void);
bool32 BattlerIsPlayer(u32 battlerId);
bool32 BattlerIsPartner(u32 battlerId);
bool32 BattlerIsOpponent(u32 battlerId);
bool32 BattlerIsRecorded(u32 battlerId);
bool32 BattlerIsLink(u32 battlerId);
bool32 BattlerIsWally(u32 battlerId);
bool32 BattlerHasAi(u32 battlerId);
bool32 BattlerIsPlayer(enum BattlerId battlerId);
bool32 BattlerIsPartner(enum BattlerId battlerId);
bool32 BattlerIsOpponent(enum BattlerId battlerId);
bool32 BattlerIsRecorded(enum BattlerId battlerId);
bool32 BattlerIsLink(enum BattlerId battlerId);
bool32 BattlerIsOldMan(enum BattlerId battlerId);
bool32 BattlerHasAi(enum BattlerId battlerId);
// emitters
void BtlController_EmitGetMonData(u32 battler, u32 bufferId, u8 requestId, u8 monToCheck);
void BtlController_EmitSetMonData(u32 battler, u32 bufferId, u8 requestId, u8 monToCheck, u8 bytes, void *data);
void BtlController_EmitLoadMonSprite(u32 battler, u32 bufferId);
void BtlController_EmitSwitchInAnim(u32 battler, u32 bufferId, u8 partyId, bool8 dontClearTransform, bool8 dontClearSubstituteBit);
void BtlController_EmitReturnMonToBall(u32 battler, u32 bufferId, bool8 skipAnim);
void BtlController_EmitDrawTrainerPic(u32 battler, u32 bufferId);
void BtlController_EmitTrainerSlide(u32 battler, u32 bufferId);
void BtlController_EmitTrainerSlideBack(u32 battler, u32 bufferId);
void BtlController_EmitFaintAnimation(u32 battler, u32 bufferId);
void BtlController_EmitBallThrowAnim(u32 battler, u32 bufferId, u8 caseId);
void BtlController_EmitMoveAnimation(u32 battler, u32 bufferId, enum Move move, u8 turnOfMove, u16 movePower, s32 dmg, u8 friendship, u8 multihit);
void BtlController_EmitPrintString(u32 battler, u32 bufferId, enum StringID stringId);
void BtlController_EmitPrintSelectionString(u32 battler, u32 bufferId, enum StringID stringId);
void BtlController_EmitChooseAction(u32 battler, u32 bufferId, u8 action, enum Item itemId);
void BtlController_EmitYesNoBox(u32 battler, u32 bufferId);
void BtlController_EmitChooseMove(u32 battler, u32 bufferId, bool8 isDoubleBattle, bool8 NoPpNumber, struct ChooseMoveStruct *movePpData);
void BtlController_EmitChooseItem(u32 battler, u32 bufferId, u8 *battlePartyOrder);
void BtlController_EmitChoosePokemon(u32 battler, u32 bufferId, u8 caseId, u8 slotId, u16 abilityId, u8 battlerPreventingSwitchout, u8 *data);
void BtlController_EmitHealthBarUpdate(u32 battler, u32 bufferId, u16 hpValue);
void BtlController_EmitExpUpdate(u32 battler, u32 bufferId, u8 partyId, s32 expPoints);
void BtlController_EmitStatusIconUpdate(u32 battler, u32 bufferId, u32 status);
void BtlController_EmitStatusAnimation(u32 battler, u32 bufferId, bool8 isVolatile, u32 status);
void BtlController_EmitDataTransfer(u32 battler, u32 bufferId, u16 size, void *data);
void BtlController_EmitTwoReturnValues(u32 battler, u32 bufferId, u8 ret8, u32 ret32);
void BtlController_EmitChosenMonReturnValue(u32 battler, u32 bufferId, u8 partyId, u8 *battlePartyOrder);
void BtlController_EmitOneReturnValue(u32 battler, u32 bufferId, u16 ret);
void BtlController_EmitOneReturnValue_Duplicate(u32 battler, u32 bufferId, u16 ret);
void BtlController_EmitHitAnimation(u32 battler, u32 bufferId);
void BtlController_EmitCantSwitch(u32 battler, u32 bufferId);
void BtlController_EmitPlaySE(u32 battler, u32 bufferId, u16 songId);
void BtlController_EmitPlayFanfareOrBGM(u32 battler, u32 bufferId, u16 songId, bool8 playBGM);
void BtlController_EmitFaintingCry(u32 battler, u32 bufferId);
void BtlController_EmitIntroSlide(u32 battler, u32 bufferId, u8 terrainId);
void BtlController_EmitIntroTrainerBallThrow(u32 battler, u32 bufferId);
void BtlController_EmitDrawPartyStatusSummary(u32 battler, u32 bufferId, struct HpAndStatus *hpAndStatus, u8 flags);
void BtlController_EmitHidePartyStatusSummary(u32 battler, u32 bufferId);
void BtlController_EmitEndBounceEffect(u32 battler, u32 bufferId);
void BtlController_EmitSpriteInvisibility(u32 battler, u32 bufferId, bool8 isInvisible);
void BtlController_EmitBattleAnimation(u32 battler, u32 bufferId, u8 animationId, u16 argument);
void BtlController_EmitLinkStandbyMsg(u32 battler, u32 bufferId, u8 mode, bool32 record);
void BtlController_EmitResetActionMoveSelection(u32 battler, u32 bufferId, u8 caseId);
void BtlController_EmitEndLinkBattle(u32 battler, u32 bufferId, u8 battleOutcome);
void BtlController_EmitDebugMenu(u32 battler, u32 bufferId);
void BtlController_EmitGetMonData(enum BattlerId battler, u32 bufferId, u8 requestId, u8 monToCheck);
void BtlController_EmitSetMonData(enum BattlerId battler, u32 bufferId, u8 requestId, u8 monToCheck, u8 bytes, void *data);
void BtlController_EmitLoadMonSprite(enum BattlerId battler, u32 bufferId);
void BtlController_EmitSwitchInAnim(enum BattlerId battler, u32 bufferId, u8 partyId, bool8 dontClearTransform, bool8 dontClearSubstituteBit);
void BtlController_EmitReturnMonToBall(enum BattlerId battler, u32 bufferId, bool8 skipAnim);
void BtlController_EmitDrawTrainerPic(enum BattlerId battler, u32 bufferId);
void BtlController_EmitTrainerSlide(enum BattlerId battler, u32 bufferId);
void BtlController_EmitTrainerSlideBack(enum BattlerId battler, u32 bufferId);
void BtlController_EmitFaintAnimation(enum BattlerId battler, u32 bufferId);
void BtlController_EmitBallThrowAnim(enum BattlerId battler, u32 bufferId, u8 caseId);
void BtlController_EmitMoveAnimation(enum BattlerId battler, u32 bufferId, enum Move move, u8 turnOfMove, u16 movePower, s32 dmg, u8 friendship, u8 multihit);
void BtlController_EmitPrintString(enum BattlerId battler, u32 bufferId, enum StringID stringId);
void BtlController_EmitPrintSelectionString(enum BattlerId battler, u32 bufferId, enum StringID stringId);
void BtlController_EmitChooseAction(enum BattlerId battler, u32 bufferId, u8 action, enum Item itemId);
void BtlController_EmitYesNoBox(enum BattlerId battler, u32 bufferId);
void BtlController_EmitChooseMove(enum BattlerId battler, u32 bufferId, bool8 isDoubleBattle, bool8 NoPpNumber, struct ChooseMoveStruct *movePpData);
void BtlController_EmitChooseItem(enum BattlerId battler, u32 bufferId, u8 *battlePartyOrder);
void BtlController_EmitChoosePokemon(enum BattlerId battler, u32 bufferId, u8 caseId, u8 slotId, u16 abilityId, enum BattlerId battlerPreventingSwitchout, u8 *data);
void BtlController_EmitHealthBarUpdate(enum BattlerId battler, u32 bufferId, u16 hpValue);
void BtlController_EmitExpUpdate(enum BattlerId battler, u32 bufferId, u8 partyId, s32 expPoints);
void BtlController_EmitStatusIconUpdate(enum BattlerId battler, u32 bufferId, u32 status);
void BtlController_EmitStatusAnimation(enum BattlerId battler, u32 bufferId, bool8 isVolatile, u32 status);
void BtlController_EmitDataTransfer(enum BattlerId battler, u32 bufferId, u16 size, void *data);
void BtlController_EmitTwoReturnValues(enum BattlerId battler, u32 bufferId, u8 ret8, u32 ret32);
void BtlController_EmitChosenMonReturnValue(enum BattlerId battler, u32 bufferId, u8 partyId, u8 *battlePartyOrder);
void BtlController_EmitOneReturnValue(enum BattlerId battler, u32 bufferId, u16 ret);
void BtlController_EmitOneReturnValue_Duplicate(enum BattlerId battler, u32 bufferId, u16 ret);
void BtlController_EmitHitAnimation(enum BattlerId battler, u32 bufferId);
void BtlController_EmitCantSwitch(enum BattlerId battler, u32 bufferId);
void BtlController_EmitPlaySE(enum BattlerId battler, u32 bufferId, u16 songId);
void BtlController_EmitPlayFanfareOrBGM(enum BattlerId battler, u32 bufferId, u16 songId, bool8 playBGM);
void BtlController_EmitFaintingCry(enum BattlerId battler, u32 bufferId);
void BtlController_EmitIntroSlide(enum BattlerId battler, u32 bufferId, u8 terrainId);
void BtlController_EmitIntroTrainerBallThrow(enum BattlerId battler, u32 bufferId);
void BtlController_EmitDrawPartyStatusSummary(enum BattlerId battler, u32 bufferId, struct HpAndStatus *hpAndStatus, u8 flags);
void BtlController_EmitHidePartyStatusSummary(enum BattlerId battler, u32 bufferId);
void BtlController_EmitEndBounceEffect(enum BattlerId battler, u32 bufferId);
void BtlController_EmitSpriteInvisibility(enum BattlerId battler, u32 bufferId, bool8 isInvisible);
void BtlController_EmitBattleAnimation(enum BattlerId battler, u32 bufferId, u8 animationId, u16 argument);
void BtlController_EmitLinkStandbyMsg(enum BattlerId battler, u32 bufferId, u8 mode, bool32 record);
void BtlController_EmitResetActionMoveSelection(enum BattlerId battler, u32 bufferId, u8 caseId);
void BtlController_EmitEndLinkBattle(enum BattlerId battler, u32 bufferId, u8 battleOutcome);
void BtlController_EmitDebugMenu(enum BattlerId battler, u32 bufferId);
void BtlController_Complete(u32 battler); // Can be used for all the controllers.
void BtlController_Empty(u32 battler); // Empty command, does nothing, only completes the execution.
void BtlController_TerminatorNop(u32 battler); // Dummy function at the end of the table.
void BattleControllerDummy(u32 battler);
void StartSendOutAnim(u32 battler, bool32 dontClearTransform, bool32 dontClearSubstituteBit, bool32 doSlideIn);
void Controller_WaitForString(u32 battler);
void Controller_WaitForHealthBar(u32 battler);
void BtlController_Complete(enum BattlerId battler); // Can be used for all the controllers.
void BtlController_Empty(enum BattlerId battler); // Empty command, does nothing, only completes the execution.
void BtlController_TerminatorNop(enum BattlerId battler); // Dummy function at the end of the table.
void BattleControllerDummy(enum BattlerId battler);
void StartSendOutAnim(enum BattlerId battler, bool32 dontClearTransform, bool32 dontClearSubstituteBit, bool32 doSlideIn);
void Controller_WaitForString(enum BattlerId battler);
void Controller_WaitForHealthBar(enum BattlerId battler);
// handlers
void BtlController_HandleGetMonData(u32 battler);
void BtlController_HandleGetRawMonData(u32 battler);
void BtlController_HandleSetMonData(u32 battler);
void BtlController_HandleSetRawMonData(u32 battler);
void BtlController_HandleLoadMonSprite(u32 battler);
void BtlController_HandleSwitchInAnim(u32 battler);
void BtlController_HandleReturnMonToBall(u32 battler);
void BtlController_HandleDrawTrainerPic(u32 battlerId, enum TrainerPicID trainerPicId, bool32 isFrontPic, s16 xPos, s16 yPos, s32 subpriority);
void BtlController_HandleTrainerSlide(u32 battler, enum TrainerPicID trainerPicId);
void BtlController_HandleTrainerSlideBack(u32 battlerId, s16 data0, bool32 startAnim);
void BtlController_HandleFaintAnimation(u32 battler);
void BtlController_HandleBallThrowAnim(u32 battler);
void BtlController_HandleMoveAnimation(u32 battler);
void BtlController_HandlePrintString(u32 battler);
void BtlController_HandlePrintStringPlayerOnly(u32 battler);
void BtlController_HandleHealthBarUpdate(u32 battler);
void BtlController_HandleStatusIconUpdate(u32 battler);
void BtlController_HandleStatusAnimation(u32 battler);
void BtlController_HandleHitAnimation(u32 battler);
void BtlController_HandlePlaySE(u32 battler);
void BtlController_HandlePlayFanfareOrBGM(u32 battler);
void BtlController_HandleFaintingCry(u32 battler);
void BtlController_HandleIntroSlide(u32 battler);
void BtlController_HandleSpriteInvisibility(u32 battler);
bool32 TwoPlayerIntroMons(u32 battlerId); // Double battle with both player pokemon active.
bool32 TwoOpponentIntroMons(u32 battlerId); // Double battle with both opponent pokemon active.
void BtlController_HandleIntroTrainerBallThrow(u32 battler, u16 tagTrainerPal, const u16 *trainerPal, s16 framesToWait, void (*controllerCallback)(u32 battler));
void BtlController_HandleDrawPartyStatusSummary(u32 battler, enum BattleSide side, bool32 considerDelay);
void BtlController_HandleHidePartyStatusSummary(u32 battler);
void BtlController_HandleBattleAnimation(u32 battler);
void BtlController_HandleGetMonData(enum BattlerId battler);
void BtlController_HandleGetRawMonData(enum BattlerId battler);
void BtlController_HandleSetMonData(enum BattlerId battler);
void BtlController_HandleSetRawMonData(enum BattlerId battler);
void BtlController_HandleLoadMonSprite(enum BattlerId battler);
void BtlController_HandleSwitchInAnim(enum BattlerId battler);
void BtlController_HandleReturnMonToBall(enum BattlerId battler);
void BtlController_HandleDrawTrainerPic(enum BattlerId battlerId, enum TrainerPicID trainerPicId, bool32 isFrontPic, s16 xPos, s16 yPos, s32 subpriority);
void BtlController_HandleTrainerSlide(enum BattlerId battler, enum TrainerPicID trainerPicId);
void BtlController_HandleTrainerSlideBack(enum BattlerId battlerId, s16 data0, bool32 startAnim);
void BtlController_HandleFaintAnimation(enum BattlerId battler);
void BtlController_HandleBallThrowAnim(enum BattlerId battler);
void BtlController_HandleMoveAnimation(enum BattlerId battler);
void BtlController_HandlePrintString(enum BattlerId battler);
void BtlController_HandlePrintStringPlayerOnly(enum BattlerId battler);
void BtlController_HandleHealthBarUpdate(enum BattlerId battler);
void BtlController_HandleStatusIconUpdate(enum BattlerId battler);
void BtlController_HandleStatusAnimation(enum BattlerId battler);
void BtlController_HandleHitAnimation(enum BattlerId battler);
void BtlController_HandlePlaySE(enum BattlerId battler);
void BtlController_HandlePlayFanfareOrBGM(enum BattlerId battler);
void BtlController_HandleFaintingCry(enum BattlerId battler);
void BtlController_HandleIntroSlide(enum BattlerId battler);
void BtlController_HandleSpriteInvisibility(enum BattlerId battler);
bool32 TwoPlayerIntroMons(enum BattlerId battlerId); // Double battle with both player pokemon active.
bool32 TwoOpponentIntroMons(enum BattlerId battlerId); // Double battle with both opponent pokemon active.
void BtlController_HandleIntroTrainerBallThrow(enum BattlerId battler, u16 tagTrainerPal, const u16 *trainerPal, s16 framesToWait, void (*controllerCallback)(enum BattlerId battler));
void BtlController_HandleDrawPartyStatusSummary(enum BattlerId battler, enum BattleSide side, bool32 considerDelay);
void BtlController_HandleHidePartyStatusSummary(enum BattlerId battler);
void BtlController_HandleBattleAnimation(enum BattlerId battler);
// player controller
void SetControllerToPlayer(u32 battler);
void PlayerBufferExecCompleted(u32 battler);
void SetBattleEndCallbacks(u32 battler);
void PlayerHandleExpUpdate(u32 battler);
void SetControllerToPlayer(enum BattlerId battler);
void PlayerBufferExecCompleted(enum BattlerId battler);
void SetBattleEndCallbacks(enum BattlerId battler);
void PlayerHandleExpUpdate(enum BattlerId battler);
enum TrainerPicID LinkPlayerGetTrainerPicId(u32 multiplayerId);
void CB2_SetUpReshowBattleScreenAfterMenu(void);
void CB2_SetUpReshowBattleScreenAfterMenu2(void);
void Task_PlayerController_RestoreBgmAfterCry(u8 taskId);
void ActionSelectionCreateCursorAt(u8 cursorPosition, u8 baseTileNum);
void ActionSelectionDestroyCursorAt(u8 cursorPosition);
void InitMoveSelectionsVarsAndStrings(u32 battler);
void InitMoveSelectionsVarsAndStrings(enum BattlerId battler);
void MoveSelectionCreateCursorAt(u8 cursorPos, u8 arg1);
void MoveSelectionDestroyCursorAt(u8 cursorPosition);
void PlayerHandleChooseMove(u32 battler);
void HandleInputChooseMove(u32 battler);
void HandleInputChooseTarget(u32 battler);
void HandleInputShowEntireFieldTargets(u32 battler);
void HandleInputShowTargets(u32 battler);
void HandleMoveSwitching(u32 battler);
void HandleChooseMoveAfterDma3(u32 battler);
void PlayerHandleChooseMove(enum BattlerId battler);
void HandleInputChooseMove(enum BattlerId battler);
void HandleInputChooseTarget(enum BattlerId battler);
void HandleInputShowEntireFieldTargets(enum BattlerId battler);
void HandleInputShowTargets(enum BattlerId battler);
void HandleMoveSwitching(enum BattlerId battler);
void HandleChooseMoveAfterDma3(enum BattlerId battler);
// recorded player controller
void SetControllerToRecordedPlayer(u32 battler);
void RecordedPlayerBufferExecCompleted(u32 battler);
void SetControllerToRecordedPlayer(enum BattlerId battler);
void RecordedPlayerBufferExecCompleted(enum BattlerId battler);
// recorded partner controller
void SetControllerToRecordedPartner(u32 battler);
void RecordedPartnerBufferExecCompleted(u32 battler);
void SetControllerToRecordedPartner(enum BattlerId battler);
void RecordedPartnerBufferExecCompleted(enum BattlerId battler);
// opponent controller
void SetControllerToOpponent(u32 battler);
void OpponentBufferExecCompleted(u32 battler);
void OpponentHandleTrainerSlide(u32 battler);
void SetControllerToOpponent(enum BattlerId battler);
void OpponentBufferExecCompleted(enum BattlerId battler);
void OpponentHandleTrainerSlide(enum BattlerId battler);
// player partner controller
void Controller_PlayerPartnerShowIntroHealthbox(u32 battler); // Also used by the link partner.
void SetControllerToPlayerPartner(u32 battler);
void PlayerPartnerBufferExecCompleted(u32 battler);
void Controller_PlayerPartnerShowIntroHealthbox(enum BattlerId battler); // Also used by the link partner.
void SetControllerToPlayerPartner(enum BattlerId battler);
void PlayerPartnerBufferExecCompleted(enum BattlerId battler);
// safari controller
void SetControllerToSafari(u32 battler);
void SafariBufferExecCompleted(u32 battler);
void SetControllerToSafari(enum BattlerId battler);
void SafariBufferExecCompleted(enum BattlerId battler);
// recorded opponent controller
void SetControllerToRecordedOpponent(u32 battler);
void RecordedOpponentBufferExecCompleted(u32 battler);
void SetControllerToRecordedOpponent(enum BattlerId battler);
void RecordedOpponentBufferExecCompleted(enum BattlerId battler);
// link opponent
void SetControllerToLinkOpponent(u32 battler);
void LinkOpponentBufferExecCompleted(u32 battler);
void SetControllerToLinkOpponent(enum BattlerId battler);
void LinkOpponentBufferExecCompleted(enum BattlerId battler);
// link partner
void SetControllerToLinkPartner(u32 battler);
void LinkPartnerBufferExecCompleted(u32 battler);
void SetControllerToLinkPartner(enum BattlerId battler);
void LinkPartnerBufferExecCompleted(enum BattlerId battler);
void TrySetBattlerShadowSpriteCallback(u32 battler);
void TrySetBattlerShadowSpriteCallback(enum BattlerId battler);
void AnimateMonAfterPokeBallFail(u32 battler);
void TryShinyAnimAfterMonAnim(u32 battler);
void WaitForMonAnimAfterLoad(u32 battler);
void BtlController_HandleSwitchInWaitAndEnd(u32 battler);
void BtlController_Intro_DelayAndEnd(u32 battler);
void BtlController_HandleSwitchInShowHealthbox(u32 battler);
void BtlController_HandleSwitchInTryShinyAnim(u32 battler);
void BtlController_HandleSwitchInSoundAndEnd(u32 battler);
void BtlController_HandleSwitchInShowSubstitute(u32 battler);
void AnimateMonAfterPokeBallFail(enum BattlerId battler);
void TryShinyAnimAfterMonAnim(enum BattlerId battler);
void WaitForMonAnimAfterLoad(enum BattlerId battler);
void BtlController_HandleSwitchInWaitAndEnd(enum BattlerId battler);
void BtlController_Intro_DelayAndEnd(enum BattlerId battler);
void BtlController_HandleSwitchInShowHealthbox(enum BattlerId battler);
void BtlController_HandleSwitchInTryShinyAnim(enum BattlerId battler);
void BtlController_HandleSwitchInSoundAndEnd(enum BattlerId battler);
void BtlController_HandleSwitchInShowSubstitute(enum BattlerId battler);
// oak and old man controller
void SetControllerToOakOrOldMan(u32 battler);
void OakOldManBufferExecCompleted(u32 battler);
void SetControllerToOakOrOldMan(enum BattlerId battler);
void OakOldManBufferExecCompleted(enum BattlerId battler);
// pokedude controller
void SetControllerToPokedude(u32 battler);
void SetControllerToPokedude(enum BattlerId battler);
void InitPokedudePartyAndOpponent(void);
void PokedudeBufferExecCompleted(u32 battler);
void PokedudeBufferExecCompleted(enum BattlerId battler);
// These flags are set to signal that the indicated message
// was already emitted
@ -482,41 +483,15 @@ void PokedudeBufferExecCompleted(u32 battler);
bool8 BtlCtrl_OakOldMan_TestState2Flag(u8 mask);
void BtlCtrl_OakOldMan_SetState2Flag(u8 mask);
void PrintOakText_InflictingDamageIsKey(u32 battler);
void PrintOakText_HowDisappointing(u32 battler);
void PrintOakText_OakNoRunningFromATrainer(u32 battler);
void OakOldManHandleInputChooseMove(u32 battler);
void PrintOakText_InflictingDamageIsKey(enum BattlerId battler);
void PrintOakText_HowDisappointing(enum BattlerId battler);
void PrintOakText_OakNoRunningFromATrainer(enum BattlerId battler);
void OakOldManHandleInputChooseMove(enum BattlerId battler);
void BtlCtrl_DrawVoiceoverMessageFrame(void);
void BtlCtrl_RemoveVoiceoverMessageFrame(void);
bool32 ShouldBattleRestrictionsApply(u32 battler);
bool32 ShouldBattleRestrictionsApply(enum BattlerId battler);
void FreeShinyStars(void);
enum BattleTrainer GetBattlerTrainer(enum BattlerId battler);
// oak and old man controller
void SetControllerToOakOrOldMan(u32 battler);
void OakOldManBufferExecCompleted(u32 battler);
// These flags are set to signal that the indicated message
// was already emitted
// Inflicting damage is key
#define FIRST_BATTLE_MSG_FLAG_INFLICT_DMG 0x1
// Lowering stats is advantageous
#define FIRST_BATTLE_MSG_FLAG_STAT_CHG 0x2
// Keep an eye on your HP
#define FIRST_BATTLE_MSG_FLAG_HP_RESTORE 0x4
//
#define FIRST_BATTLE_MSG_FLAG_PARTY_MENU 0x8
bool8 BtlCtrl_OakOldMan_TestState2Flag(u8 mask);
void BtlCtrl_OakOldMan_SetState2Flag(u8 mask);
void PrintOakText_InflictingDamageIsKey(u32 battler);
void PrintOakText_HowDisappointing(u32 battler);
void PrintOakText_OakNoRunningFromATrainer(u32 battler);
void OakOldManHandleInputChooseMove(u32 battler);
void BtlCtrl_DrawVoiceoverMessageFrame(void);
void BtlCtrl_RemoveVoiceoverMessageFrame(void);
#endif // GUARD_BATTLE_CONTROLLERS_H

View File

@ -3,16 +3,16 @@
#define DYNAMAX_TURNS_COUNT 3
bool32 CanDynamax(u32 battler);
bool32 IsGigantamaxed(u32 battler);
bool32 CanDynamax(enum BattlerId battler);
bool32 IsGigantamaxed(enum BattlerId battler);
void ApplyDynamaxHPMultiplier(struct Pokemon *mon);
void ActivateDynamax(u32 battler);
u32 GetNonDynamaxHP(u32 battler);
u32 GetNonDynamaxMaxHP(u32 battler);
void UndoDynamax(u32 battler);
void ActivateDynamax(enum BattlerId battler);
u32 GetNonDynamaxHP(enum BattlerId battler);
u32 GetNonDynamaxMaxHP(enum BattlerId battler);
void UndoDynamax(enum BattlerId battler);
bool32 IsMoveBlockedByMaxGuard(enum Move move);
enum Move GetMaxMove(u32 battler, enum Move baseMove);
enum Move GetMaxMove(enum BattlerId battler, enum Move baseMove);
u32 GetMaxMovePower(enum Move move);
bool32 IsMaxMove(enum Move move);
void ChooseDamageNonTypesString(enum Type type);

View File

@ -1,7 +1,6 @@
#ifndef GUARD_BATTLE_END_TURN
#define GUARD_BATTLE_END_TURN
u32 DoEndTurnEffects(void);
bool32 DoEndTurnEffects(void);
#endif // GUARD_BATTLE_END_TURN

View File

@ -3,6 +3,7 @@
void AllocateBattleSpritesData(void);
void FreeBattleSpritesData(void);
u16 ChooseMoveAndTargetInBattlePalace(enum BattlerId battler);
void SpriteCB_WaitForBattlerBallReleaseAnim(struct Sprite *sprite);
void SpriteCB_TrainerSlideIn(struct Sprite *sprite);
void SpriteCB_TrainerSpawn(struct Sprite *sprite);
@ -22,7 +23,7 @@ bool8 BattleInitAllSprites(u8 *state, u8 *battlerId);
void ClearSpritesHealthboxAnimData(void);
void CopyAllBattleSpritesInvisibilities(void);
void CopyBattleSpriteInvisibility(u8 battlerId);
void HandleSpeciesGfxDataChange(u8 battlerAtk, u8 battlerDef, bool32 megaEvo, bool32 trackEnemyPersonality, bool32 ghostUnveil);
void HandleSpeciesGfxDataChange(enum BattlerId battlerAtk, enum BattlerId battlerDef, u8 changeType);
void BattleLoadSubstituteOrMonSpriteGfx(u8 battlerId, bool8 loadMonSprite);
void LoadBattleMonGfxAndAnimate(u8 battlerId, bool8 loadMonSprite, u8 spriteId);
void TrySetBehindSubstituteSpriteBit(u8 battlerId, u16 move);

View File

@ -19,32 +19,32 @@ struct GimmickInfo
const struct SpriteTemplate *triggerTemplate;
const u32 indicatorPalTag;
const u8 *indicatorData;
bool32 (*CanActivate)(u32 battler);
void (*ActivateGimmick)(u32 battler);
bool32 (*CanActivate)(enum BattlerId battler);
void (*ActivateGimmick)(enum BattlerId battler);
};
void AssignUsableGimmicks(void);
bool32 CanActivateGimmick(u32 battler, enum Gimmick gimmick);
bool32 IsGimmickSelected(u32 battler, enum Gimmick gimmick);
void SetActiveGimmick(u32 battler, enum Gimmick gimmick);
enum Gimmick GetActiveGimmick(u32 battler);
bool32 ShouldTrainerBattlerUseGimmick(u32 battler, enum Gimmick gimmick);
bool32 HasTrainerUsedGimmick(u32 battler, enum Gimmick gimmick);
void SetGimmickAsActivated(u32 battler, enum Gimmick gimmick);
bool32 CanActivateGimmick(enum BattlerId battler, enum Gimmick gimmick);
bool32 IsGimmickSelected(enum BattlerId battler, enum Gimmick gimmick);
void SetActiveGimmick(enum BattlerId battler, enum Gimmick gimmick);
enum Gimmick GetActiveGimmick(enum BattlerId battler);
bool32 ShouldTrainerBattlerUseGimmick(enum BattlerId battler, enum Gimmick gimmick);
bool32 HasTrainerUsedGimmick(enum BattlerId battler, enum Gimmick gimmick);
void SetGimmickAsActivated(enum BattlerId battler, enum Gimmick gimmick);
void ChangeGimmickTriggerSprite(u32 spriteId, u32 animId);
void CreateGimmickTriggerSprite(u32 battler);
void CreateGimmickTriggerSprite(enum BattlerId battler);
bool32 IsGimmickTriggerSpriteActive(void);
bool32 IsGimmickTriggerSpriteMatchingBattler(u32 battler);
bool32 IsGimmickTriggerSpriteMatchingBattler(enum BattlerId battler);
void HideGimmickTriggerSprite(void);
void DestroyGimmickTriggerSprite(void);
void LoadIndicatorSpritesGfx(void);
u32 GetIndicatorPalTag(u32 battler);
u32 GetIndicatorPalTag(enum BattlerId battler);
void UpdateIndicatorVisibilityAndType(u32 healthboxId, bool32 invisible);
void UpdateIndicatorOamPriority(u32 healthboxId, u32 oamPriority);
void UpdateIndicatorLevelData(u32 healthboxId, u32 level);
void CreateIndicatorSprite(u32 battler);
void CreateIndicatorSprite(enum BattlerId battler);
extern const struct GimmickInfo gGimmicksInfo[];

View File

@ -119,7 +119,7 @@ void InitBattlerHealthboxCoords(u8 battler);
void GetBattlerHealthboxCoords(u8 battler, s16 *x, s16 *y);
void UpdateHpTextInHealthbox(u32 healthboxSpriteId, u32 maxOrCurrent, s16 currHp, s16 maxHp);
void SwapHpBarsWithHpText(void);
u8 CreatePartyStatusSummarySprites(u8 battler, struct HpAndStatus *partyInfo, bool8 skipPlayer, bool8 isBattleStart);
u8 CreatePartyStatusSummarySprites(enum BattlerId battler, struct HpAndStatus *partyInfo, bool8 skipPlayer, bool8 isBattleStart);
void Task_HidePartyStatusSummary(u8 taskId);
void UpdateHealthboxAttribute(u8 healthboxSpriteId, struct Pokemon *mon, u8 elementId);
s32 MoveBattleBar(u8 battler, u8 healthboxSpriteId, u8 whichBar, u8 unused);

View File

@ -82,31 +82,31 @@ void SpriteCB_HideAsMoveTarget(struct Sprite *sprite);
void SpriteCB_OpponentMonFromBall(struct Sprite *sprite);
void SpriteCB_BattleSpriteStartSlideLeft(struct Sprite *sprite);
void SpriteCB_FaintSlideAnim(struct Sprite *sprite);
void DoBounceEffect(u8 battler, u8 which, s8 delta, s8 amplitude);
void EndBounceEffect(u8 battler, u8 which);
void DoBounceEffect(enum BattlerId battler, u8 which, s8 delta, s8 amplitude);
void EndBounceEffect(enum BattlerId battler, u8 which);
void SpriteCB_PlayerMonFromBall(struct Sprite *sprite);
void SpriteCB_PlayerMonSlideIn(struct Sprite *sprite);
void SpriteCB_TrainerThrowObject(struct Sprite *sprite);
void AnimSetCenterToCornerVecX(struct Sprite *sprite);
void BeginBattleIntroDummy(void);
void BeginBattleIntro(void);
void SwitchInClearSetData(u32 battler, struct Volatiles *volatilesCopy);
const u8 *FaintClearSetData(u32 battler);
void SwitchInClearSetData(enum BattlerId battler, struct Volatiles *volatilesCopy);
const u8 *FaintClearSetData(enum BattlerId battler);
void BattleTurnPassed(void);
u8 IsRunningFromBattleImpossible(u32 battler);
void SwitchTwoBattlersInParty(u32 battler, u32 battler2);
void SwitchPartyOrder(u32 battler);
u8 IsRunningFromBattleImpossible(enum BattlerId battler);
void SwitchTwoBattlersInParty(enum BattlerId battler, enum BattlerId battler2);
void SwitchPartyOrder(enum BattlerId battler);
void SwapTurnOrder(u8 id1, u8 id2);
u32 GetBattlerTotalSpeedStat(u32 battler, enum Ability ability, enum HoldEffect holdEffect);
s32 GetChosenMovePriority(u32 battler, enum Ability ability);
s32 GetBattleMovePriority(u32 battler, enum Ability ability, enum Move move);
u32 GetBattlerTotalSpeedStat(enum BattlerId battler, enum Ability ability, enum HoldEffect holdEffect);
s32 GetChosenMovePriority(enum BattlerId battler, enum Ability ability);
s32 GetBattleMovePriority(enum BattlerId battler, enum Ability ability, enum Move move);
s32 GetWhichBattlerFasterArgs(struct BattleCalcValues *calcValues, bool32 ignoreChosenMoves, u32 speedBattler1, u32 speedBattler2, s32 priority1, s32 priority2);
s32 GetWhichBattlerFasterOrTies(struct BattleCalcValues *calcValues, bool32 ignoreChosenMoves);
s32 GetWhichBattlerFaster(struct BattleCalcValues *calcValues, bool32 ignoreChosenMoves);
void RunBattleScriptCommands_PopCallbacksStack(void);
void RunBattleScriptCommands(void);
enum Type GetDynamicMoveType(struct Pokemon *mon, enum Move move, u32 battler, enum MonState monInBattle);
void SetTypeBeforeUsingMove(enum Move move, u32 battlerAtk);
enum Type GetDynamicMoveType(struct Pokemon *mon, enum Move move, enum BattlerId battler, enum MonState monInBattle);
void SetTypeBeforeUsingMove(enum Move move, enum BattlerId battler);
bool32 IsWildMonSmart(void);
u8 CreateNPCTrainerPartyFromTrainer(struct Pokemon *party, const struct Trainer *trainer, bool32 firstTrainer, u32 battleTypeFlags);
void ModifyPersonalityForNature(u32 *personality, u32 newNature);

View File

@ -271,6 +271,9 @@ extern const u8 *const gStatNamesTable2[];
extern const u16 gMissStringIds[];
// battle main
extern const u8 gText_LinkStandby3[];
extern const u8 BattleFrontier_BattleTowerBattleRoom_Text_RecordCouldntBeSaved[];
extern const u8 gText_Sleep[];
extern const u8 gText_Poison[];
extern const u8 gText_Burn[];

View File

@ -3,7 +3,8 @@
#include "constants/battle_move_resolution.h"
bool32 DoMoveEnd(enum MoveEndState endMode, enum MoveEndState endState);
enum CancelerResult DoAttackCanceler(void);
enum MoveEndResult DoMoveEnd(enum MoveEndState endMode, enum MoveEndState endState);
void MoveValuesCleanUp(void);
#endif // GUARD_BATTLE_MOVE_RESOLUTION_H

View File

@ -40,33 +40,34 @@ union TRANSPARENT StatChangeFlags
};
};
bool32 HasBattlerActedThisTurn(u32 battler);
u32 GetBattlerTurnOrderNum(u32 battler);
bool32 NoAliveMonsForBattlerSide(u32 battler);
bool32 HasBattlerActedThisTurn(enum BattlerId battler);
u32 GetBattlerTurnOrderNum(enum BattlerId battler);
bool32 NoAliveMonsForBattlerSide(enum BattlerId battler);
bool32 NoAliveMonsForPlayer(void);
bool32 NoAliveMonsForEitherParty(void);
void SetMoveEffect(u32 battler, u32 effectBattler, enum MoveEffect moveEffect, const u8 *battleScript, enum SetMoveEffectFlags effectFlags);
bool32 CanBattlerSwitch(u32 battlerId);
void SetMoveEffect(enum BattlerId battlerAtk, enum BattlerId effectBattler, enum MoveEffect moveEffect, const u8 *battleScript, enum SetMoveEffectFlags effectFlags);
bool32 CanBattlerSwitch(enum BattlerId battlerId);
void BattleDestroyYesNoCursorAt(u8 cursorPosition);
void BattleCreateYesNoCursorAt(u8 cursorPosition);
void BufferMoveToLearnIntoBattleTextBuff2(void);
void HandleBattleWindow(u8 xStart, u8 yStart, u8 xEnd, u8 yEnd, u8 flags);
bool8 UproarWakeUpCheck(u8 battler);
bool32 DoesSubstituteBlockMove(u32 battlerAtk, u32 battlerDef, enum Move move);
bool32 DoesDisguiseBlockMove(u32 battler, enum Move move);
bool32 CanUseLastResort(u8 battlerId);
u32 IsFlowerVeilProtected(u32 battler);
u32 IsLeafGuardProtected(u32 battler, enum Ability ability);
bool32 IsShieldsDownProtected(u32 battler, enum Ability ability);
u32 IsAbilityStatusProtected(u32 battler, enum Ability ability);
bool32 TryResetBattlerStatChanges(u8 battler);
bool32 CanCamouflage(u8 battlerId);
void StealTargetItem(u8 battlerStealer, u8 battlerItem);
bool8 UproarWakeUpCheck(enum BattlerId battler);
bool32 DoesSubstituteBlockMove(enum BattlerId battlerAtk, enum BattlerId battlerDef, enum Move move);
bool32 DoesDisguiseBlockMove(enum BattlerId battler, enum Move move);
bool32 DoesIceFaceBlockMove(enum BattlerId battler, enum Move move);
bool32 CanUseLastResort(enum BattlerId battlerId);
u32 IsFlowerVeilProtected(enum BattlerId battler);
u32 IsLeafGuardProtected(enum BattlerId battler, enum Ability ability);
bool32 IsShieldsDownProtected(enum BattlerId battler, enum Ability ability);
u32 IsAbilityStatusProtected(enum BattlerId battler, enum Ability ability);
bool32 TryResetBattlerStatChanges(enum BattlerId battler);
bool32 CanCamouflage(enum BattlerId battler);
void StealTargetItem(enum BattlerId battlerStealer, enum BattlerId battlerItem);
u8 GetCatchingBattler(void);
bool32 ProteanTryChangeType(u32 battler, enum Ability ability, enum Move move, enum Type moveType);
u8 GetFirstFaintedPartyIndex(u8 battlerId);
void SaveBattlerTarget(u32 battler);
void SaveBattlerAttacker(u32 battler);
bool32 ProteanTryChangeType(enum BattlerId battler, enum Ability ability, enum Move move, enum Type moveType);
u8 GetFirstFaintedPartyIndex(enum BattlerId battler);
void SaveBattlerTarget(enum BattlerId battler);
void SaveBattlerAttacker(enum BattlerId battler);
bool32 CanBurnHitThaw(enum Move move);
bool32 IsMonGettingExpSentOut(void);

View File

@ -345,6 +345,8 @@ extern const u8 BattleScript_DancerActivates[];
extern const u8 BattleScript_AftermathDmg[];
extern const u8 BattleScript_BattlerFormChange[];
extern const u8 BattleScript_BattlerFormChangeEnd2[];
extern const u8 BattleScript_BattlerFormChangeNoPopup[];
extern const u8 BattleScript_BattlerFormChangeDisguise[];
extern const u8 BattleScript_AttackerFormChangeWithString[];
extern const u8 BattleScript_TargetFormChange[];
extern const u8 BattleScript_AnticipationActivates[];
@ -397,7 +399,7 @@ extern const u8 BattleScript_DoesntAffectTargetAtkString[];
extern const u8 BattleScript_DoesntAffectScripting[];
extern const u8 BattleScript_GulpMissileGorging[];
extern const u8 BattleScript_GulpMissileGulping[];
extern const u8 BattleScript_GulpMissileFormChange[];
extern const u8 BattleScript_TwoTurnMovesSecondTurnFormChange[];
extern const u8 BattleScript_BattleBondActivatesOnMoveEndAttacker[];
extern const u8 BattleScript_EffectBattleBondStatIncrease[];
extern const u8 BattleScript_PrimalWeatherBlocksMove[];
@ -514,6 +516,10 @@ extern const u8 BattleScript_Explosion[];
extern const u8 BattleScript_ActivateSwitchInAbility[];
extern const u8 BattleScript_BreakScreens[];
extern const u8 BattleScript_StealStats[];
extern const u8 BattleScript_BeatUpAttackMessage[];
extern const u8 BattleScript_MagnitudeMessage[];
extern const u8 BattleScript_FickleBeamMessage[];
extern const u8 BattleScript_BeforeSnoreMessage[];
// zmoves
extern const u8 BattleScript_ZMoveActivateDamaging[];
@ -587,7 +593,6 @@ extern const u8 BattleScript_EffectLightScreen[];
extern const u8 BattleScript_EffectRest[];
extern const u8 BattleScript_RestIsAlreadyAsleep[];
extern const u8 BattleScript_InsomniaProtects[];
extern const u8 BattleScript_EffectOHKO[];
extern const u8 BattleScript_EffectHealBlock[];
extern const u8 BattleScript_RecoilIfMiss[];
extern const u8 BattleScript_EffectMist[];
@ -619,7 +624,6 @@ extern const u8 BattleScript_EffectHappyHour[];
extern const u8 BattleScript_EffectDisable[];
extern const u8 BattleScript_EffectEncore[];
extern const u8 BattleScript_EffectPainSplit[];
extern const u8 BattleScript_EffectSnore[];
extern const u8 BattleScript_EffectConversion2[];
extern const u8 BattleScript_EffectLockOn[];
extern const u8 BattleScript_EffectSketch[];
@ -641,7 +645,6 @@ extern const u8 BattleScript_EffectSwagger[];
extern const u8 BattleScript_EffectAttract[];
extern const u8 BattleScript_EffectPresent[];
extern const u8 BattleScript_EffectSafeguard[];
extern const u8 BattleScript_EffectMagnitude[];
extern const u8 BattleScript_EffectBatonPass[];
extern const u8 BattleScript_EffectCaptivate[];
extern const u8 BattleScript_EffectMorningSun[];
@ -660,7 +663,6 @@ extern const u8 BattleScript_EffectSemiInvulnerable[];
extern const u8 BattleScript_EffectDefenseCurl[];
extern const u8 BattleScript_EffectSoftboiled[];
extern const u8 BattleScript_EffectStockpile[];
extern const u8 BattleScript_EffectSpitUp[];
extern const u8 BattleScript_EffectSwallow[];
extern const u8 BattleScript_EffectOverwriteAbility[];
extern const u8 BattleScript_EffectTorment[];
@ -696,7 +698,6 @@ extern const u8 BattleScript_EffectDragonDance[];
extern const u8 BattleScript_EffectCamouflage[];
extern const u8 BattleScript_EffectPledge[];
extern const u8 BattleScript_EffectFling[];
extern const u8 BattleScript_EffectNaturalGift[];
extern const u8 BattleScript_EffectRoost[];
extern const u8 BattleScript_EffectGravity[];
extern const u8 BattleScript_EffectMiracleEye[];
@ -809,7 +810,6 @@ extern const u8 BattleScript_EffectFilletAway[];
extern const u8 BattleScript_EffectShedTail[];
extern const u8 BattleScript_EffectTidyUp[];
extern const u8 BattleScript_EffectSpicyExtract[];
extern const u8 BattleScript_EffectFickleBeam[];
extern const u8 BattleScript_GhostBallDodge[];
extern const u8 BattleScript_GhostGetOutGetOut[];
extern const u8 BattleScript_TooScaredToMove[];
@ -818,7 +818,7 @@ extern const u8 BattleScript_SilphScopeUnveiled[];
// pokefirered
extern const u8 BattleScript_BattleTowerTrainerBattleWon[];
extern const u8 BattleScript_TrainerTowerTrainerBattleWon[];
extern const u8 BattleScript_MoveUsedLoafingAroundMsg[];
extern const u8 BattleScript_OldMan_Pokedude_CaughtMessage[];

View File

@ -1,6 +1,7 @@
#ifndef GUARD_BATTLE_SETUP_H
#define GUARD_BATTLE_SETUP_H
#include "battle_transition.h"
#include "vs_seeker.h"
/*
the layout of the first byte can be confusing here
@ -48,11 +49,11 @@ void BattleSetup_StartLatiBattle(void);
void BattleSetup_StartLegendaryBattle(void);
void StartGroudonKyogreBattle(void);
void StartRegiBattle(void);
u8 BattleSetup_GetEnvironmentId(void);
u8 BattleSetup_GetBattleTowerBattleTransition(void);
u8 GetWildBattleTransition(void);
u8 GetTrainerBattleTransition(void);
u8 GetSpecialBattleTransition(s32 id);
enum BattleEnvironments BattleSetup_GetEnvironmentId(void);
enum BattleTransition GetWildBattleTransition(void);
enum BattleTransition GetTrainerBattleTransition(void);
enum BattleTransition GetSpecialBattleTransition(enum BattleTransitionGroup id);
void ChooseStarter(void);
void ChooseStarter(void);
void ResetTrainerOpponentIds(void);
void SetMapVarsToTrainerA(void);

View File

@ -1,12 +1,12 @@
#ifndef GUARD_BATTLE_TERASTAL_H
#define GUARD_BATTLE_TERASTAL_H
void ActivateTera(u32 battler);
void ApplyBattlerVisualsForTeraAnim(u32 battler);
bool32 CanTerastallize(u32 battler);
enum Type GetBattlerTeraType(u32 battler);
void ExpendTypeStellarBoost(u32 battler, enum Type type);
bool32 IsTypeStellarBoosted(u32 battler, enum Type type);
void ActivateTera(enum BattlerId battler);
void ApplyBattlerVisualsForTeraAnim(enum BattlerId battler);
bool32 CanTerastallize(enum BattlerId battler);
enum Type GetBattlerTeraType(enum BattlerId battler);
void ExpendTypeStellarBoost(enum BattlerId battler, enum Type type);
bool32 IsTypeStellarBoosted(enum BattlerId battler, enum Type type);
uq4_12_t GetTeraMultiplier(struct BattleContext *ctx);
u16 GetTeraTypeRGB(enum Type type);

View File

@ -1,7 +1,8 @@
#ifndef GUARD_BATTLE_TRANSITION_H
#define GUARD_BATTLE_TRANSITION_H
enum {
enum MugshotColor
{
MUGSHOT_COLOR_PURPLE,
MUGSHOT_COLOR_GREEN,
MUGSHOT_COLOR_PINK,
@ -10,7 +11,8 @@ enum {
MUGSHOT_COLOR_COUNT
};
enum {
enum BattleTransition
{
B_TRANSITION_BLUR,
B_TRANSITION_SWIRL,
B_TRANSITION_SHUFFLE,
@ -28,10 +30,48 @@ enum {
B_TRANSITION_COUNT
};
#define B_TRANSITION_FRONTIER_LOGO_WIGGLE B_TRANSITION_BLUR
#define B_TRANSITION_FRONTIER_LOGO_WAVE B_TRANSITION_BLUR
#define B_TRANSITION_FRONTIER_SQUARES B_TRANSITION_BLUR
#define B_TRANSITION_FRONTIER_SQUARES_SCROLL B_TRANSITION_BLUR
#define B_TRANSITION_FRONTIER_SQUARES_SPIRAL B_TRANSITION_BLUR
#define B_TRANSITION_FRONTIER_CIRCLES_MEET B_TRANSITION_BLUR
#define B_TRANSITION_FRONTIER_CIRCLES_CROSS B_TRANSITION_BLUR
#define B_TRANSITION_FRONTIER_CIRCLES_ASYMMETRIC_SPIRAL B_TRANSITION_BLUR
#define B_TRANSITION_FRONTIER_CIRCLES_SYMMETRIC_SPIRAL B_TRANSITION_BLUR
#define B_TRANSITION_FRONTIER_CIRCLES_MEET_IN_SEQ B_TRANSITION_BLUR
#define B_TRANSITION_FRONTIER_CIRCLES_CROSS_IN_SEQ B_TRANSITION_BLUR
#define B_TRANSITION_FRONTIER_CIRCLES_ASYMMETRIC_SPIRAL_IN_SEQ B_TRANSITION_BLUR
#define B_TRANSITION_FRONTIER_CIRCLES_SYMMETRIC_SPIRAL_IN_SEQ B_TRANSITION_BLUR
#define B_TRANSITION_REGICE B_TRANSITION_BLUR
#define B_TRANSITION_REGISTEEL B_TRANSITION_BLUR
#define B_TRANSITION_REGIROCK B_TRANSITION_BLUR
#define B_TRANSITION_KYOGRE B_TRANSITION_BLUR
#define B_TRANSITION_GROUDON B_TRANSITION_BLUR
#define B_TRANSITION_RAYQUAZA B_TRANSITION_BLUR
#define B_TRANSITION_AQUA B_TRANSITION_BLUR
#define B_TRANSITION_MAGMA B_TRANSITION_BLUR
// IDs for GetSpecialBattleTransition
enum BattleTransitionGroup
{
B_TRANSITION_GROUP_B_TOWER,
B_TRANSITION_GROUP_B_DOME = 3,
B_TRANSITION_GROUP_B_PALACE,
B_TRANSITION_GROUP_B_ARENA,
B_TRANSITION_GROUP_B_FACTORY,
B_TRANSITION_GROUP_B_PIKE,
B_TRANSITION_GROUP_B_PYRAMID = 10,
B_TRANSITION_GROUP_TRAINER_TOWER,
B_TRANSITION_GROUP_SECRET_BASE,
B_TRANSITION_GROUP_E_READER,
};
extern const struct SpritePalette gSpritePalette_Pokeball;
bool8 IsBattleTransitionDone(void);
void BattleTransition_StartOnField(u8 transitionId);
void BattleTransition_StartOnField(enum BattleTransition transitionId);
void Task_BattleTransition_Intro(u8 taskId);
#endif // GUARD_BATTLE_TRANSITION_H

View File

@ -41,7 +41,6 @@ enum FieldEffectCases
enum AbilityEffect
{
ABILITYEFFECT_ON_SWITCHIN,
ABILITYEFFECT_ENDTURN,
ABILITYEFFECT_MOVE_END_ATTACKER,
ABILITYEFFECT_COLOR_CHANGE, // Color Change / Berserk / Anger Shell
@ -49,6 +48,7 @@ enum AbilityEffect
ABILITYEFFECT_IMMUNITY,
ABILITYEFFECT_SYNCHRONIZE,
ABILITYEFFECT_ATK_SYNCHRONIZE,
ABILITYEFFECT_FORM_CHANGE_ON_HIT,
ABILITYEFFECT_MOVE_END_OTHER,
ABILITYEFFECT_MOVE_END_FOES_FAINTED, // Moxie-like abilities / Battle Bond / Magician
@ -56,6 +56,8 @@ enum AbilityEffect
ABILITYEFFECT_TERA_SHIFT,
ABILITYEFFECT_NEUTRALIZINGGAS,
ABILITYEFFECT_UNNERVE,
ABILITYEFFECT_ON_SWITCHIN,
ABILITYEFFECT_SWITCH_IN_FORM_CHANGE,
ABILITYEFFECT_COMMANDER, // Commander / Hospitality / Costar
ABILITYEFFECT_ON_WEATHER,
ABILITYEFFECT_ON_TERRAIN,
@ -86,76 +88,11 @@ enum ItemEffect
// for Natural Gift and Fling
struct TypePower
{
enum Type type;
enum Type type:8;
u8 power;
u16 effect;
};
enum MoveSuccessOrder
{
CANCELER_STANCE_CHANGE_1,
CANCELER_CLEAR_FLAGS,
CANCELER_SKY_DROP,
CANCELER_RECHARGE,
CANCELER_CHILLY_RECEPTION,
CANCELER_ASLEEP_OR_FROZEN,
CANCELER_POWER_POINTS,
CANCELER_OBEDIENCE,
CANCELER_TRUANT,
CANCELER_FOCUS_GEN5,
CANCELER_FLINCH,
CANCELER_DISABLED,
CANCELER_VOLATILE_BLOCKED, // Gravity / Heal Block / Throat Chop
CANCELER_TAUNTED,
CANCELER_IMPRISONED,
CANCELER_CONFUSED,
CANCELER_GHOST,
CANCELER_PARALYZED,
CANCELER_INFATUATION,
CANCELER_BIDE,
CANCELER_Z_MOVES,
CANCELER_CHOICE_LOCK,
CANCELER_CALLSUBMOVE,
CANCELER_THAW,
CANCELER_STANCE_CHANGE_2,
CANCELER_ATTACKSTRING,
CANCELER_PPDEDUCTION,
CANCELER_SKY_BATTLE,
CANCELER_WEATHER_PRIMAL,
CANCELER_FOCUS_PRE_GEN5,
CANCELER_MOVE_FAILURE,
CANCELER_POWDER_STATUS,
CANCELER_PRIORITY_BLOCK,
CANCELER_PROTEAN,
CANCELER_EXPLODING_DAMP,
CANCELER_EXPLOSION,
CANCELER_CHARGING,
CANCELER_NO_TARGET,
CANCELER_TOOK_ATTACK,
CANCELER_TARGET_FAILURE,
CANCELER_NOT_FULLY_PROTECTED,
CANCELER_MULTIHIT_MOVES,
CANCELER_END,
};
enum Obedience
{
OBEYS,
DISOBEYS_LOAFS,
DISOBEYS_HITS_SELF,
DISOBEYS_FALL_ASLEEP,
DISOBEYS_WHILE_ASLEEP,
DISOBEYS_RANDOM_MOVE,
};
enum MoveCanceler
{
MOVE_STEP_SUCCESS,
MOVE_STEP_BREAK, // Runs script. Increments state
MOVE_STEP_PAUSE, // Runs script. Does not increment state
MOVE_STEP_FAILURE, // Move failed, jump to script that handles the failure
};
enum ImmunityHealStatusOutcome
{
IMMUNITY_NO_EFFECT,
@ -169,8 +106,8 @@ extern const struct TypePower gNaturalGiftTable[];
struct BattleContext
{
u32 battlerAtk:3;
u32 battlerDef:3;
enum BattlerId battlerAtk:3;
enum BattlerId battlerDef:3;
u32 fixedBasePower:8;
u32 weather:16;
u32 unused:2;
@ -203,8 +140,8 @@ struct BattleContext
// Helper struct to keep the arg list small and prevent constant recalculations of abilities/hold effects.
struct BattleCalcValues
{
u32 battlerAtk:3;
u32 battlerDef:3;
enum BattlerId battlerAtk:3;
enum BattlerId battlerDef:3;
enum Move move:16;
u32 padding:10;
enum Ability abilities[MAX_BATTLERS_COUNT];
@ -238,16 +175,17 @@ enum EjectPackTiming
};
void HandleAction_ThrowBall(void);
uq4_12_t CalcTypeEffectivenessMultiplierHelper(enum Move move, enum Type moveType, u32 battlerAtk, u32 battlerDef, enum Ability abilityAtk, enum Ability abilityDef, bool32 recordAbilities);
uq4_12_t CalcTypeEffectivenessMultiplierHelper(enum Move move, enum Type moveType, enum BattlerId battlerAtk, enum BattlerId battlerDef, enum Ability abilityAtk, enum Ability abilityDef, bool32 recordAbilities);
u32 GetCurrentBattleWeather(void);
bool32 EndOrContinueWeather(void);
bool32 IsUnnerveBlocked(u32 battler, enum Item itemId);
bool32 IsAffectedByFollowMe(u32 battlerAtk, enum BattleSide defSide, enum Move move);
enum DamageCategory GetReflectDamageMoveDamageCategory(enum BattlerId battler, enum Move move);
bool32 IsUnnerveBlocked(enum BattlerId battler, enum Item itemId);
bool32 IsAffectedByFollowMe(enum BattlerId battlerAtk, enum BattleSide defSide, enum Move move);
void DetermineTarget(enum MoveTarget moveTarget, bool32 overwriteTarget);
void HandleAction_UseMove(void);
void HandleAction_Switch(void);
void HandleAction_UseItem(void);
bool32 TryRunFromBattle(u32 battler);
bool32 TryRunFromBattle(enum BattlerId battler);
void HandleAction_Run(void);
void HandleAction_WatchesCarefully(void);
void HandleAction_SafariZoneBallThrow(void);
@ -258,72 +196,71 @@ void HandleAction_OldManBallThrow(void);
void HandleAction_TryFinish(void);
void HandleAction_NothingIsFainted(void);
void HandleAction_ActionFinished(void);
u8 GetBattlerForBattleScript(u8 caseId);
bool32 IsBattlerMarkedForControllerExec(u32 battler);
void MarkBattlerForControllerExec(u32 battler);
void MarkBattlerReceivedLinkData(u32 battler);
const u8 *CancelMultiTurnMoves(u32 battler, enum SkyDropState skyDropState);
bool32 IsLastMonToMove(u32 battler);
bool32 ShouldDefiantCompetitiveActivate(u32 battler, enum Ability ability);
void PrepareStringBattle(enum StringID stringId, u32 battler);
enum BattlerId GetBattlerForBattleScript(u8 caseId);
bool32 IsBattlerMarkedForControllerExec(enum BattlerId battler);
void MarkBattlerForControllerExec(enum BattlerId battler);
void MarkBattlerReceivedLinkData(enum BattlerId battler);
const u8 *CancelMultiTurnMoves(enum BattlerId battler, enum SkyDropState skyDropState);
bool32 IsLastMonToMove(enum BattlerId battler);
bool32 ShouldDefiantCompetitiveActivate(enum BattlerId battler, enum Ability ability);
void PrepareStringBattle(enum StringID stringId, enum BattlerId battler);
void ResetSentPokesToOpponentValue(void);
void OpponentSwitchInResetSentPokesToOpponentValue(u32 battler);
void UpdateSentPokesToOpponentValue(u32 battler);
void OpponentSwitchInResetSentPokesToOpponentValue(enum BattlerId battler);
void UpdateSentPokesToOpponentValue(enum BattlerId battler);
void BattleScriptPush(const u8 *bsPtr);
void BattleScriptPushCursor(void);
void BattleScriptCall(const u8 *bsPtr);
void BattleScriptPop(void);
u32 TrySetCantSelectMoveBattleScript(u32 battler);
u32 CheckMoveLimitations(u32 battler, u8 unusableMoves, u16 check);
bool32 AreAllMovesUnusable(u32 battler);
u8 GetImprisonedMovesCount(u32 battler, enum Move move);
s32 GetDrainedBigRootHp(u32 battler, s32 hp);
bool32 IsAbilityAndRecord(u32 battler, enum Ability battlerAbility, enum Ability abilityToCheck);
u32 TrySetCantSelectMoveBattleScript(enum BattlerId battler);
u32 CheckMoveLimitations(enum BattlerId battler, u8 unusableMoves, u16 check);
bool32 AreAllMovesUnusable(enum BattlerId battler);
u8 GetImprisonedMovesCount(enum BattlerId battler, enum Move move);
s32 GetDrainedBigRootHp(enum BattlerId battler, s32 hp);
bool32 IsAbilityAndRecord(enum BattlerId battler, enum Ability battlerAbility, enum Ability abilityToCheck);
bool32 HandleFaintedMonActions(void);
void TryClearRageAndFuryCutter(void);
enum MoveCanceler AtkCanceler_MoveSuccessOrder(void);
bool32 HasNoMonsToSwitch(u32 battler, u8 partyIdBattlerOn1, u8 partyIdBattlerOn2);
bool32 TryChangeBattleWeather(u32 battler, u32 battleWeatherId, enum Ability ability);
bool32 TryChangeBattleTerrain(u32 battler, u32 statusFlag);
bool32 CanAbilityBlockMove(u32 battlerAtk, u32 battlerDef, enum Ability abilityAtk, enum Ability abilityDef, u32 move, enum ResultOption option);
bool32 HasNoMonsToSwitch(enum BattlerId battler, u8 partyIdBattlerOn1, u8 partyIdBattlerOn2);
bool32 TryChangeBattleWeather(enum BattlerId battler, u32 battleWeatherId, enum Ability ability);
bool32 TryChangeBattleTerrain(enum BattlerId battler, u32 statusFlag);
bool32 CanAbilityBlockMove(enum BattlerId battlerAtk, enum BattlerId battlerDef, enum Ability abilityAtk, enum Ability abilityDef, u32 move, enum ResultOption option);
bool32 CanTargetBlockPranksterMove(struct BattleContext *ctx, s32 movePriority);
bool32 CanPsychicTerrainProtectTarget(struct BattleContext *ctx, s32 movePriority);
bool32 CanMoveBeBlockedByTarget(struct BattleContext *ctx, s32 movePriority);
bool32 CanAbilityAbsorbMove(struct BattleContext *ctx);
bool32 TryFieldEffects(enum FieldEffectCases caseId);
u32 AbilityBattleEffects(enum AbilityEffect caseID, u32 battler, enum Ability ability, enum Move move, bool32 shouldAbilityTrigger);
bool32 TryPrimalReversion(u32 battler);
u32 AbilityBattleEffects(enum AbilityEffect caseID, enum BattlerId battler, enum Ability ability, enum Move move, bool32 shouldAbilityTrigger);
bool32 TryPrimalReversion(enum BattlerId battler);
bool32 IsNeutralizingGasOnField(void);
bool32 IsMoldBreakerTypeAbility(u32 battler, enum Ability ability);
enum Ability GetBattlerAbilityIgnoreMoldBreaker(u32 battler);
enum Ability GetBattlerAbilityNoAbilityShield(u32 battler);
enum Ability GetBattlerAbilityInternal(u32 battler, bool32 ignoreMoldBreaker, bool32 noAbilityShield);
enum Ability GetBattlerAbility(u32 battler);
u32 IsAbilityOnSide(u32 battler, enum Ability ability);
u32 IsAbilityOnOpposingSide(u32 battler, enum Ability ability);
bool32 IsMoldBreakerTypeAbility(enum BattlerId battler, enum Ability ability);
enum Ability GetBattlerAbilityIgnoreMoldBreaker(enum BattlerId battler);
enum Ability GetBattlerAbilityNoAbilityShield(enum BattlerId battler);
enum Ability GetBattlerAbilityInternal(enum BattlerId battler, bool32 ignoreMoldBreaker, bool32 noAbilityShield);
enum Ability GetBattlerAbility(enum BattlerId battler);
u32 IsAbilityOnSide(enum BattlerId battler, enum Ability ability);
u32 IsAbilityOnOpposingSide(enum BattlerId battler, enum Ability ability);
u32 IsAbilityOnField(enum Ability ability);
u32 IsAbilityOnFieldExcept(u32 battler, enum Ability ability);
u32 IsAbilityPreventingEscape(u32 battler);
u32 IsAbilityOnFieldExcept(enum BattlerId battler, enum Ability ability);
u32 IsAbilityPreventingEscape(enum BattlerId battler);
bool32 IsBattlerProtected(struct BattleContext *ctx);
enum ProtectType GetProtectType(enum ProtectMethod method);
bool32 CanBattlerEscape(u32 battler); // no ability check
bool32 CanBattlerEscape(enum BattlerId battler); // no ability check
void BattleScriptExecute(const u8 *BS_ptr);
void BattleScriptPushCursorAndCallback(const u8 *BS_ptr);
void ClearVariousBattlerFlags(u32 battler);
void ClearVariousBattlerFlags(enum BattlerId battler);
void HandleAction_RunBattleScript(void);
u32 SetRandomTarget(u32 battler);
u32 SetRandomTarget(enum BattlerId battlerAtk);
u32 GetBattleMoveTarget(enum Move move, enum MoveTarget moveTarget);
enum Obedience GetAttackerObedienceForAction(void);
enum HoldEffect GetBattlerHoldEffect(u32 battler);
enum HoldEffect GetBattlerHoldEffectIgnoreAbility(u32 battler);
enum HoldEffect GetBattlerHoldEffectIgnoreNegation(u32 battler);
enum HoldEffect GetBattlerHoldEffectInternal(u32 battler, enum Ability ability);
u32 GetBattlerHoldEffectParam(u32 battler);
bool32 CanBattlerAvoidContactEffects(u32 battlerAtk, u32 battlerDef, enum Ability abilityAtk, enum HoldEffect holdEffectAtk, enum Move move);
bool32 IsMoveMakingContact(u32 battlerAtk, u32 battlerDef, enum Ability abilityAtk, enum HoldEffect holdEffectAtk, enum Move move);
bool32 IsBattlerGrounded(u32 battler, enum Ability ability, enum HoldEffect holdEffect);
enum HoldEffect GetBattlerHoldEffect(enum BattlerId battler);
enum HoldEffect GetBattlerHoldEffectIgnoreAbility(enum BattlerId battler);
enum HoldEffect GetBattlerHoldEffectIgnoreNegation(enum BattlerId battler);
enum HoldEffect GetBattlerHoldEffectInternal(enum BattlerId battler, enum Ability ability);
u32 GetBattlerHoldEffectParam(enum BattlerId battler);
bool32 CanBattlerAvoidContactEffects(enum BattlerId battlerAtk, enum BattlerId battlerDef, enum Ability abilityAtk, enum HoldEffect holdEffectAtk, enum Move move);
bool32 IsMoveMakingContact(enum BattlerId battlerAtk, enum BattlerId battlerDef, enum Ability abilityAtk, enum HoldEffect holdEffectAtk, enum Move move);
bool32 IsBattlerGrounded(enum BattlerId battler, enum Ability ability, enum HoldEffect holdEffect);
u32 GetMoveSlot(u16 *moves, enum Move move);
u32 GetBattlerWeight(u32 battler);
u32 GetBattlerWeight(enum BattlerId battler);
s32 CalcCritChanceStage(struct BattleContext *ctx);
s32 CalcCritChanceStageGen1(struct BattleContext *ctx);
s32 CalculateMoveDamage(struct BattleContext *ctx);
@ -335,157 +272,160 @@ uq4_12_t CalcPartyMonTypeEffectivenessMultiplier(enum Move move, u16 speciesDef,
uq4_12_t GetTypeModifier(enum Type atkType, enum Type defType);
uq4_12_t GetOverworldTypeEffectiveness(struct Pokemon *mon, enum Type moveType);
void UpdateMoveResultFlags(uq4_12_t modifier, u16 *resultFlags);
s32 GetStealthHazardDamage(enum TypeSideHazard hazardType, u32 battler);
s32 GetStealthHazardDamage(enum TypeSideHazard hazardType, enum BattlerId battler);
s32 GetStealthHazardDamageByTypesAndHP(enum TypeSideHazard hazardType, enum Type type1, enum Type type2, u32 maxHp);
bool32 CanMegaEvolve(u32 battler);
bool32 CanUltraBurst(u32 battler);
void ActivateMegaEvolution(u32 battler);
void ActivateUltraBurst(u32 battler);
bool32 IsBattlerMegaEvolved(u32 battler);
bool32 IsBattlerPrimalReverted(u32 battler);
bool32 IsBattlerUltraBursted(u32 battler);
u32 GetBattleFormChangeTargetSpecies(u32 battler, enum FormChanges method);
bool32 CanMegaEvolve(enum BattlerId battler);
bool32 CanUltraBurst(enum BattlerId battler);
void ActivateMegaEvolution(enum BattlerId battler);
void ActivateUltraBurst(enum BattlerId battler);
bool32 IsBattlerMegaEvolved(enum BattlerId battler);
bool32 IsBattlerPrimalReverted(enum BattlerId battler);
bool32 IsBattlerUltraBursted(enum BattlerId battler);
u32 GetBattleFormChangeTargetSpecies(enum BattlerId battler, enum FormChanges method, enum Ability ability);
bool32 TryRevertPartyMonFormChange(u32 partyIndex);
bool32 TryBattleFormChange(u32 battler, enum FormChanges method);
bool32 DoBattlersShareType(u32 battler1, u32 battler2);
bool32 CanBattlerGetOrLoseItem(u32 fromBattler, u32 battler, enum Item itemId);
u32 GetBattlerVisualSpecies(u32 battler);
bool32 TryClearIllusion(u32 battler, enum Ability ability);
u32 GetIllusionMonSpecies(u32 battler);
struct Pokemon *GetIllusionMonPtr(u32 battler);
void ClearIllusionMon(u32 battler);
u32 GetIllusionMonPartyId(struct Pokemon *party, struct Pokemon *mon, struct Pokemon *partnerMon, u32 battler);
void SetIllusionMon(struct Pokemon *mon, u32 battler);
enum ImmunityHealStatusOutcome TryImmunityAbilityHealStatus(u32 battler);
bool32 ShouldGetStatBadgeBoost(u16 flagId, u32 battler);
bool32 TryBattleFormChange(enum BattlerId battler, enum FormChanges method, enum Ability ability);
bool32 DoBattlersShareType(enum BattlerId battler1, enum BattlerId battler2);
bool32 CanBattlerGetOrLoseItem(enum BattlerId fromBattler, enum BattlerId battler, enum Item itemId);
u32 GetBattlerVisualSpecies(enum BattlerId battler);
bool32 TryClearIllusion(enum BattlerId battler, enum Ability ability);
u32 GetIllusionMonSpecies(enum BattlerId battler);
struct Pokemon *GetIllusionMonPtr(enum BattlerId battler);
void ClearIllusionMon(enum BattlerId battler);
u32 GetIllusionMonPartyId(struct Pokemon *party, struct Pokemon *mon, struct Pokemon *partnerMon, enum BattlerId battler);
void SetIllusionMon(struct Pokemon *mon, enum BattlerId battler);
enum ImmunityHealStatusOutcome TryImmunityAbilityHealStatus(enum BattlerId battler);
bool32 ShouldGetStatBadgeBoost(u16 flagId, enum BattlerId battler);
uq4_12_t GetBadgeBoostModifier(void);
enum DamageCategory GetBattleMoveCategory(enum Move move);
void SetDynamicMoveCategory(u32 battlerAtk, u32 battlerDef, enum Move move);
bool32 CanFling(u32 battlerAtk, u32 battlerDef);
void SetDynamicMoveCategory(enum BattlerId battlerAtk, enum BattlerId battlerDef, enum Move move);
bool32 CanFling(enum BattlerId battlerAtk);
bool32 IsTelekinesisBannedSpecies(u16 species);
bool32 IsHealBlockPreventingMove(u32 battler, enum Move move);
bool32 IsBelchPreventingMove(u32 battler, enum Move move);
bool32 HasEnoughHpToEatBerry(u32 battler, enum Ability ability, u32 hpFraction, enum Item itemId);
bool32 IsPartnerMonFromSameTrainer(u32 battler);
enum DamageCategory GetCategoryBasedOnStats(u32 battler);
bool32 IsHealBlockPreventingMove(enum BattlerId battler, enum Move move);
bool32 IsGravityPreventingMove(enum Move move);
bool32 IsBelchPreventingMove(enum BattlerId battler, enum Move move);
bool32 HasEnoughHpToEatBerry(enum BattlerId battler, enum Ability ability, u32 hpFraction, enum Item itemId);
bool32 IsPartnerMonFromSameTrainer(enum BattlerId battler);
enum DamageCategory GetCategoryBasedOnStats(enum BattlerId battler);
void SetShellSideArmCategory(void);
bool32 MoveIsAffectedBySheerForce(enum Move move);
bool32 IsSheerForceAffected(enum Move move, enum Ability ability);
void TryRestoreHeldItems(void);
bool32 CanStealItem(u32 battlerStealing, u32 battlerItem, enum Item item);
void TrySaveExchangedItem(u32 battler, enum Item stolenItem);
bool32 IsBattlerAffectedByHazards(u32 battler, enum HoldEffect holdEffect, bool32 toxicSpikes);
void SortBattlersBySpeed(u8 *battlers, bool32 slowToFast);
bool32 CompareStat(u32 battler, enum Stat statId, u32 cmpTo, u32 cmpKind, enum Ability ability);
bool32 BlocksPrankster(enum Move move, u32 battlerPrankster, u32 battlerDef, bool32 checkTarget);
bool32 PickupHasValidTarget(u32 battler);
bool32 CanStealItem(enum BattlerId battlerStealing, enum BattlerId battlerItem, enum Item item);
void TrySaveExchangedItem(enum BattlerId battler, enum Item stolenItem);
bool32 IsBattlerAffectedByHazards(enum BattlerId battler, enum HoldEffect holdEffect, bool32 toxicSpikes);
void SortBattlersBySpeed(enum BattlerId *battlers, bool32 slowToFast);
bool32 CompareStat(enum BattlerId battler, enum Stat statId, u32 cmpTo, u32 cmpKind, enum Ability ability);
bool32 BlocksPrankster(enum Move move, enum BattlerId battlerPrankster, enum BattlerId battlerDef, bool32 checkTarget);
bool32 PickupHasValidTarget(enum BattlerId battler);
bool32 CantPickupItem(u32 battler);
bool32 IsBattlerWeatherAffected(u32 battler, u32 weatherFlags);
enum MoveTarget GetBattlerMoveTargetType(u32 battler, enum Move move);
bool32 CanTargetBattler(u32 battlerAtk, u32 battlerDef, enum Move move);
bool32 IsBattlerWeatherAffected(enum BattlerId battler, u32 weatherFlags);
enum MoveTarget GetBattlerMoveTargetType(enum BattlerId battler, enum Move move);
bool32 CanTargetBattler(enum BattlerId battlerAtk, enum BattlerId battlerDef, enum Move move);
u32 GetNextTarget(u32 moveTarget, bool32 excludeCurrent);
void CopyMonLevelAndBaseStatsToBattleMon(u32 battler, struct Pokemon *mon);
void CopyMonAbilityAndTypesToBattleMon(u32 battler, struct Pokemon *mon);
void RecalcBattlerStats(u32 battler, struct Pokemon *mon, bool32 isDynamaxing);
void CopyMonLevelAndBaseStatsToBattleMon(enum BattlerId battler, struct Pokemon *mon);
void CopyMonAbilityAndTypesToBattleMon(enum BattlerId battler, struct Pokemon *mon);
void RecalcBattlerStats(enum BattlerId battler, struct Pokemon *mon, bool32 isDynamaxing);
bool32 IsGen6ExpShareEnabled(void);
bool32 MoveHasAdditionalEffect(enum Move move, enum MoveEffect moveEffect);
bool32 MoveHasAdditionalEffectWithChance(enum Move move, enum MoveEffect moveEffect, u32 chance);
bool32 MoveHasAdditionalEffectSelf(enum Move move, enum MoveEffect moveEffect);
bool32 IsMoveEffectRemoveSpeciesType(enum Move move, enum MoveEffect moveEffect, u32 argument);
bool32 MoveHasChargeTurnAdditionalEffect(enum Move move);
bool32 CanTargetPartner(u32 battlerAtk, u32 battlerDef);
bool32 IsBattlerUnaffectedByMove(u32 battler);
bool32 CanTargetPartner(enum BattlerId battlerAtk, enum BattlerId battlerDef);
bool32 IsBattlerUnaffectedByMove(enum BattlerId battler);
bool32 MoodyCantRaiseStat(u32 stat);
bool32 MoodyCantLowerStat(u32 stat);
bool32 IsPsychicTerrainAffected(u32 battler, enum Ability ability, enum HoldEffect holdEffect, u32 fieldStatuses);
bool32 IsMistyTerrainAffected(u32 battler, enum Ability ability, enum HoldEffect holdEffect, u32 fieldStatuses);
bool32 IsGrassyTerrainAffected(u32 battler, enum Ability ability, enum HoldEffect holdEffect, u32 fieldStatuses);
bool32 IsElectricTerrainAffected(u32 battler, enum Ability ability, enum HoldEffect holdEffect, u32 fieldStatuses);
bool32 IsAnyTerrainAffected(u32 battler, enum Ability ability, enum HoldEffect holdEffect, u32 fieldStatuses);
bool32 IsBattlerTerrainAffected(u32 battler, enum Ability ability, enum HoldEffect holdEffect, u32 fieldStatuses, u32 terrainFlag);
enum Stat GetHighestStatId(u32 battler);
enum Stat GetParadoxHighestStatId(u32 battler);
enum Stat GetParadoxBoostedStatId(u32 battler);
bool32 IsPsychicTerrainAffected(enum BattlerId battler, enum Ability ability, enum HoldEffect holdEffect, u32 fieldStatuses);
bool32 IsMistyTerrainAffected(enum BattlerId battler, enum Ability ability, enum HoldEffect holdEffect, u32 fieldStatuses);
bool32 IsGrassyTerrainAffected(enum BattlerId battler, enum Ability ability, enum HoldEffect holdEffect, u32 fieldStatuses);
bool32 IsElectricTerrainAffected(enum BattlerId battler, enum Ability ability, enum HoldEffect holdEffect, u32 fieldStatuses);
bool32 IsAnyTerrainAffected(enum BattlerId battler, enum Ability ability, enum HoldEffect holdEffect, u32 fieldStatuses);
bool32 IsBattlerTerrainAffected(enum BattlerId battler, enum Ability ability, enum HoldEffect holdEffect, u32 fieldStatuses, u32 terrainFlag);
enum Stat GetHighestStatId(enum BattlerId battler);
enum Stat GetParadoxHighestStatId(enum BattlerId battler);
enum Stat GetParadoxBoostedStatId(enum BattlerId battler);
bool32 CanBeSlept(u32 battlerAtk, u32 battlerDef, enum Ability abilityDef, enum SleepClauseBlock isBlockedBySleepClause);
bool32 CanBePoisoned(u32 battlerAtk, u32 battlerDef, enum Ability abilityAtk, enum Ability abilityDef);
bool32 CanBeBurned(u32 battlerAtk, u32 battlerDef, enum Ability ability);
bool32 CanBeParalyzed(u32 battlerAtk, u32 battlerDef, enum Ability abilityDef);
bool32 CanBeFrozen(u32 battlerAtk, u32 battlerDef, enum Ability abilityDef);
bool32 CanGetFrostbite(u32 battlerAtk, u32 battlerDef, enum Ability abilityDef);
bool32 CanSetNonVolatileStatus(u32 battlerAtk, u32 battlerDef, enum Ability abilityAtk, enum Ability abilityDef, enum MoveEffect secondaryMoveEffect, enum ResultOption option);
bool32 CanBeConfused(u32 battler);
u32 GetBattlerAffectionHearts(u32 battler);
bool32 CanBeSlept(enum BattlerId battlerAtk, enum BattlerId battlerDef, enum Ability abilityDef, enum SleepClauseBlock isBlockedBySleepClause);
bool32 CanBePoisoned(enum BattlerId battlerAtk, enum BattlerId battlerDef, enum Ability abilityAtk, enum Ability abilityDef);
bool32 CanBeBurned(enum BattlerId battlerAtk, enum BattlerId battlerDef, enum Ability ability);
bool32 CanBeParalyzed(enum BattlerId battlerAtk, enum BattlerId battlerDef, enum Ability abilityDef);
bool32 CanBeFrozen(enum BattlerId battlerAtk, enum BattlerId battlerDef, enum Ability abilityDef);
bool32 CanGetFrostbite(enum BattlerId battlerAtk, enum BattlerId battlerDef, enum Ability abilityDef);
bool32 CanSetNonVolatileStatus(enum BattlerId battlerAtk, enum BattlerId battlerDef, enum Ability abilityAtk, enum Ability abilityDef, enum MoveEffect secondaryMoveEffect, enum ResultOption option);
bool32 CanBeConfused(enum BattlerId battler);
u32 GetBattlerAffectionHearts(enum BattlerId battler);
void TryToRevertMimicryAndFlags(void);
bool32 BattleArenaTurnEnd(void);
u32 CountBattlerStatIncreases(u32 battler, bool32 countEvasionAcc);
bool32 BattlerHasCopyableChanges(u32 battler);
bool32 ChangeTypeBasedOnTerrain(u32 battler);
void RemoveConfusionStatus(u32 battler);
u32 GetBattlerGender(u32 battler);
bool32 AreBattlersOfOppositeGender(u32 battler1, u32 battler2);
bool32 AreBattlersOfSameGender(u32 battler1, u32 battler2);
u32 CalcSecondaryEffectChance(u32 battler, enum Ability battlerAbility, const struct AdditionalEffect *additionalEffect);
bool32 MoveEffectIsGuaranteed(u32 battler, enum Ability battlerAbility, const struct AdditionalEffect *additionalEffect);
void GetBattlerTypes(u32 battler, bool32 ignoreTera, enum Type types[static 3]);
enum Type GetBattlerType(u32 battler, u32 typeIndex, bool32 ignoreTera);
u32 CountBattlerStatIncreases(enum BattlerId battler, bool32 countEvasionAcc);
bool32 BattlerHasCopyableChanges(enum BattlerId battler);
bool32 ChangeTypeBasedOnTerrain(enum BattlerId battler);
void RemoveConfusionStatus(enum BattlerId battler);
u32 GetBattlerGender(enum BattlerId battler);
bool32 AreBattlersOfOppositeGender(enum BattlerId battler1, enum BattlerId battler2);
bool32 AreBattlersOfSameGender(enum BattlerId battler1, enum BattlerId battler2);
u32 CalcSecondaryEffectChance(enum BattlerId battler, enum Ability battlerAbility, const struct AdditionalEffect *additionalEffect);
bool32 MoveEffectIsGuaranteed(enum BattlerId battler, enum Ability battlerAbility, const struct AdditionalEffect *additionalEffect);
void GetBattlerTypes(enum BattlerId battler, bool32 ignoreTera, enum Type types[static 3]);
enum Type GetBattlerType(enum BattlerId battler, u32 typeIndex, bool32 ignoreTera);
bool32 CanMonParticipateInSkyBattle(struct Pokemon *mon);
void RemoveBattlerType(u32 battler, enum Type type);
void RemoveBattlerType(enum BattlerId battler, enum Type type);
enum Type GetBattleMoveType(enum Move move);
void TryActivateSleepClause(u32 battler, u32 indexInParty);
void TryActivateSleepClause(enum BattlerId battler, u32 indexInParty);
void TryDeactivateSleepClause(enum BattleSide battlerSide, u32 indexInParty);
bool32 IsSleepClauseActiveForSide(enum BattleSide battlerSide);
bool32 IsSleepClauseEnabled(void);
void ClearDamageCalcResults(void);
u32 DoesDestinyBondFail(u32 battler);
u32 DoesDestinyBondFail(enum BattlerId battler);
bool32 IsMoveEffectBlockedByTarget(enum Ability ability);
bool32 SetTargetToNextPursuiter(u32 battlerDef);
bool32 SetTargetToNextPursuiter(enum BattlerId battlerDef);
bool32 IsPursuitTargetSet(void);
void ClearPursuitValuesIfSet(u32 battler);
void ClearPursuitValuesIfSet(enum BattlerId battler);
void ClearPursuitValues(void);
bool32 HasWeatherEffect(void);
bool32 IsFutureSightAttackerInParty(u32 battlerAtk, u32 battlerDef, enum Move move);
bool32 HadMoreThanHalfHpNowDoesnt(u32 battler);
void ChooseStatBoostAnimation(u32 battler);
bool32 IsFutureSightAttackerInParty(enum BattlerId battlerAtk, enum BattlerId battlerDef, enum Move move);
bool32 HadMoreThanHalfHpNowDoesnt(enum BattlerId battler);
void ChooseStatBoostAnimation(enum BattlerId battler);
void UpdateStallMons(void);
bool32 TrySwitchInEjectPack(enum EjectPackTiming timing);
bool32 EmergencyExitCanBeTriggered(u32 battler);
bool32 TryTriggerSymbiosis(u32 battler, u32 ally);
bool32 TrySymbiosis(u32 battler, enum Item itemId, bool32 moveEnd);
void BestowItem(u32 battlerAtk, u32 battlerDef);
ARM_FUNC u32 GetBattlerVolatile(u32 battler, enum Volatile _volatile);
void SetMonVolatile(u32 battler, enum Volatile _volatile, u32 newValue);
bool32 ItemHealMonVolatile(u32 battler, enum Item itemId);
bool32 EmergencyExitCanBeTriggered(enum BattlerId battler);
bool32 TryTriggerSymbiosis(enum BattlerId battler, u32 ally);
bool32 TrySymbiosis(enum BattlerId battler, enum Item itemId, bool32 moveEnd);
void BestowItem(enum BattlerId battlerAtk, enum BattlerId battlerDef);
ARM_FUNC u32 GetBattlerVolatile(enum BattlerId battler, enum Volatile _volatile);
void SetMonVolatile(enum BattlerId battler, enum Volatile _volatile, u32 newValue);
bool32 ItemHealMonVolatile(enum BattlerId battler, enum Item itemId);
void PushHazardTypeToQueue(enum BattleSide side, enum Hazards hazardType);
bool32 IsHazardOnSide(enum BattleSide side, enum Hazards hazardType);
bool32 AreAnyHazardsOnSide(enum BattleSide side);
void RemoveAllHazardsFromField(enum BattleSide side);
bool32 IsHazardOnSideAndClear(enum BattleSide side, enum Hazards hazardType);
void RemoveHazardFromField(enum BattleSide side, enum Hazards hazardType);
bool32 CanMoveSkipAccuracyCalc(u32 battlerAtk, u32 battlerDef, enum Ability abilityAtk, enum Ability abilityDef, enum Move move, enum ResultOption option);
u32 GetTotalAccuracy(u32 battlerAtk, u32 battlerDef, enum Move move, enum Ability atkAbility, enum Ability defAbility, enum HoldEffect atkHoldEffect, enum HoldEffect defHoldEffect);
bool32 IsSemiInvulnerable(u32 battler, enum SemiInvulnerableExclusion excludeCommander);
bool32 BreaksThroughSemiInvulnerablity(u32 battlerAtk, u32 battlerDef, enum Ability abilityAtk, enum Ability abilityDef, enum Move move);
bool32 HasPartnerTrainer(u32 battler);
bool32 IsAffectedByPowderMove(u32 battler, enum Ability ability, enum HoldEffect holdEffect);
enum Move GetNaturePowerMove(u32 battler);
void RemoveAbilityFlags(u32 battler);
void CheckSetUnburden(u32 battler);
bool32 CanMoveSkipAccuracyCalc(enum BattlerId battlerAtk, enum BattlerId battlerDef, enum Ability abilityAtk, enum Ability abilityDef, enum Move move, enum ResultOption option);
u32 GetTotalAccuracy(enum BattlerId battlerAtk, enum BattlerId battlerDef, enum Move move, enum Ability atkAbility, enum Ability defAbility, enum HoldEffect atkHoldEffect, enum HoldEffect defHoldEffect);
bool32 DoesOHKOMoveMissTarget(struct BattleCalcValues *cv);
bool32 DoesMoveMissTarget(struct BattleCalcValues *cv);
bool32 IsSemiInvulnerable(enum BattlerId battler, enum SemiInvulnerableExclusion excludeCommander);
bool32 BreaksThroughSemiInvulnerablity(enum BattlerId battlerAtk, enum BattlerId battlerDef, enum Ability abilityAtk, enum Ability abilityDef, enum Move move);
bool32 HasPartnerTrainer(enum BattlerId battler);
bool32 IsAffectedByPowderMove(enum BattlerId battler, enum Ability ability, enum HoldEffect holdEffect);
enum Move GetNaturePowerMove(void);
void RemoveAbilityFlags(enum BattlerId battler);
void CheckSetUnburden(enum BattlerId battler);
bool32 IsDazzlingAbility(enum Ability ability);
bool32 IsAllowedToUseBag(void);
bool32 IsAnyTargetTurnDamaged(u32 battlerAtk);
bool32 IsAnyTargetTurnDamaged(enum BattlerId battlerAtk);
bool32 IsAnyTargetAffected(void);
bool32 IsMimikyuDisguised(u32 battler);
bool32 IsMimikyuDisguised(enum BattlerId battler);
bool32 IsDoubleSpreadMove(void);
bool32 IsBattlerInvalidForSpreadMove(u32 battlerAtk, u32 battlerDef);
bool32 IsBattlerInvalidForSpreadMove(enum BattlerId battlerAtk, enum BattlerId battlerDef);
void SetStartingStatus(enum StartingStatus status);
void ResetStartingStatuses(void);
bool32 IsUsableWhileAsleepEffect(enum BattleMoveEffects effect);
void SetWrapTurns(u32 battler, enum HoldEffect holdEffect);
void SetWrapTurns(enum BattlerId battler, enum HoldEffect holdEffect);
bool32 ChangeOrderTargetAfterAttacker(void);
void TryUpdateEvolutionTracker(enum EvolutionConditions evolutionCondition, u32 upAmount, enum Move usedMove);
bool32 CanUseMoveConsecutively(u32 battler);
void TryResetConsecutiveUseCounter(u32 battler);
bool32 CanUseMoveConsecutively(enum BattlerId battler);
void TryResetConsecutiveUseCounter(enum BattlerId battler);
void SetOrClearRageVolatile(void);
#endif // GUARD_BATTLE_UTIL_H

View File

@ -3,8 +3,8 @@
void AllocateBattleResources(void);
void FreeBattleResources(void);
void AdjustFriendshipOnBattleFaint(u8 battler);
void SwitchPartyOrderInGameMulti(u8 battler, u8 arg1);
u32 BattlePalace_TryEscapeStatus(u8 battler);
void AdjustFriendshipOnBattleFaint(enum BattlerId battler);
void SwitchPartyOrderInGameMulti(enum BattlerId battler, u8 arg1);
u32 BattlePalace_TryEscapeStatus(enum BattlerId battler);
#endif // GUARD_BATTLE_UTIL_H

View File

@ -1,29 +1,27 @@
#ifndef GUARD_BATTLE_Z_MOVE_H
#define GUARD_BATTLE_Z_MOVE_H
#include "constants/battle_z_move_effects.h"
#define MOVE_Z_STATUS 0xFFFF
struct SignatureZMove
{
u16 species;
u16 item;
u16 move;
u16 zmove;
enum Item item;
enum Move move;
enum Move zmove;
};
bool32 IsZMove(u32 move);
bool32 CanUseZMove(u32 battler);
u32 GetUsableZMove(u32 battler, u32 move);
void ActivateZMove(u32 battler);
bool32 IsViableZMove(u32 battler, u32 move);
bool32 TryChangeZTrigger(u32 battler, u32 moveIndex);
u32 GetTypeBasedZMove(u32 move);
u32 GetSignatureZMove(u32 move, u32 species, u32 item);
bool32 MoveSelectionDisplayZMove(u16 zmove, u32 battler);
bool32 IsZMove(enum Move move);
bool32 CanUseZMove(enum BattlerId battler);
enum Move GetUsableZMove(enum BattlerId battler, enum Move move);
void ActivateZMove(enum BattlerId battler);
bool32 IsViableZMove(enum BattlerId battler, enum Move move);
bool32 TryChangeZTrigger(enum BattlerId battler, u32 moveIndex);
enum Move GetTypeBasedZMove(enum Move move);
enum Move GetSignatureZMove(enum Move move, u32 species, enum Item item);
bool32 MoveSelectionDisplayZMove(enum Move zmove, enum BattlerId battler);
void SetZEffect(void);
void AssignUsableZMoves(u32 battler, u16 *moves);
u32 GetZMovePower(u32 move);
void AssignUsableZMoves(enum BattlerId battler, enum Move *moves);
u32 GetZMovePower(enum Move move);
#endif // GUARD_BATTLE_Z_MOVE_H

View File

@ -93,12 +93,14 @@
#define B_MINIMIZE_EVASION GEN_LATEST // In Gen5+, Minimize raises evasion by 2 stages instead of 1.
#define B_GROWTH_STAT_RAISE GEN_LATEST // In Gen5+, Growth raises Attack in addition to Special Attack by 1 stage each. Under the effects of the sun, it raises them by 2 stages each instead.
#define B_FOCUS_ENERGY_CRIT_RATIO GEN_LATEST // In Gen3+, Focus Energy increases critical hit ratio by 2 instead of 1.
#define B_PSYCH_UP_CRIT_RATIO GEN_LATEST // In Gen6+, Psych Up also copies the target's critical hit ratio.
// Other move settings
#define B_INCINERATE_GEMS GEN_LATEST // In Gen6+, Incinerate can destroy Gems.
#define B_CAN_SPITE_FAIL GEN_LATEST // In Gen4+, Spite can no longer fail if the foe's last move only has 1 remaining PP.
#define B_CRASH_IF_TARGET_IMMUNE GEN_LATEST // In Gen4+, moves with crash damage will crash if the user attacks a target that is immune due to their typing.
#define B_MEMENTO_FAIL GEN_LATEST // In Gen4+, Memento no longer fails if the target already has -6 Attack and Special Attack. Additionally, in Gen5+, it fails if there is no target, or if the target is protected or behind a Substitute.
#define B_PARTING_SHOT_SWITCH GEN_LATEST // In Gen7+, the user won't switch out if Parting Shot fails to lower the target's stats.
#define B_GLARE_GHOST GEN_LATEST // In Gen4+, Glare can hit Ghost-type Pokémon normally.
#define B_SKILL_SWAP GEN_LATEST // In Gen4+, Skill Swap triggers switch-in abilities after use.
#define B_BRICK_BREAK GEN_LATEST // In Gen4+, you can destroy your own side's screens. In Gen 5+, screens are not removed if the target is immune.
@ -130,6 +132,8 @@
#define B_AFTER_YOU_TURN_ORDER GEN_LATEST // In Gen8+, After You doesn't fail if the turn order wouldn't change after use.
#define B_QUASH_TURN_ORDER GEN_LATEST // In Gen8+, Quash-affected battlers move according to speed order. Before Gen8, Quash-affected battlers move in the order they were affected by Quash.
#define B_DESTINY_BOND_FAIL GEN_LATEST // In Gen7+, Destiny Bond fails if used repeatedly.
#define B_FORESIGHT_FAIL GEN_LATEST // In Gen2 and Gen5+, Foresight fails if used against a target already under its effect.
#define B_MIRACLE_EYE_FAIL GEN_LATEST // In Gen5+, Miracle Eye fails if used against a target already under its effect.
#define B_PURSUIT_TARGET GEN_LATEST // In Gen4+, Pursuit attacks a switching opponent even if they weren't targeting them. Before Gen4, Pursuit only attacks a switching opponent that it originally targeted.
#define B_SKIP_RECHARGE GEN_LATEST // In Gen1, recharging moves such as Hyper Beam skip the recharge if the target gets KO'd
#define B_ENCORE_TARGET GEN_LATEST // In Gen5+, encored moves are allowed to choose a target

View File

@ -35,7 +35,7 @@ enum BattlerPosition
B_POSITION_ABSENT = 0xFF,
};
enum BattlerId
enum __attribute__((packed)) BattlerId
{
B_BATTLER_0,
B_BATTLER_1,
@ -284,7 +284,6 @@ enum VolatileFlags
F(VOLATILE_ROOST_ACTIVE, roostActive, (u32, 1)) \
F(VOLATILE_UNBURDEN_ACTIVE, unburdenActive, (u32, 1)) \
F(VOLATILE_NEUTRALIZING_GAS, neutralizingGas, (u32, 1)) \
F(VOLATILE_TRIGGER_ICE_FACE, triggerIceFace, (u32, 1)) \
F(VOLATILE_UNNERVE_ACTIVATED, unnerveActivated, (u32, 1)) \
F(VOLATILE_ENDURED, endured, (u32, 1)) \
F(VOLATILE_TRY_EJECT_PACK, tryEjectPack, (u32, 1)) \
@ -410,11 +409,13 @@ enum TypeSideHazard
#define MOVE_RESULT_NOT_VERY_EFFECTIVE (1 << 2)
#define MOVE_RESULT_DOESNT_AFFECT_FOE (1 << 3)
#define MOVE_RESULT_ONE_HIT_KO (1 << 4)
#define MOVE_RESULT_FAILED (1 << 5)
#define MOVE_RESULT_FOE_ENDURED (1 << 6)
#define MOVE_RESULT_FOE_HUNG_ON (1 << 7)
#define MOVE_RESULT_STURDIED (1 << 8)
#define MOVE_RESULT_FOE_ENDURED_AFFECTION (1 << 9)
#define MOVE_RESULT_ONE_HIT_KO_NO_AFFECT (1 << 5)
#define MOVE_RESULT_ONE_HIT_KO_STURDY (1 << 6)
#define MOVE_RESULT_FAILED (1 << 7)
#define MOVE_RESULT_FOE_ENDURED (1 << 8)
#define MOVE_RESULT_FOE_HUNG_ON (1 << 9)
#define MOVE_RESULT_STURDIED (1 << 10)
#define MOVE_RESULT_FOE_ENDURED_AFFECTION (1 << 11)
#define MOVE_RESULT_AVOIDED_ATTACK (MOVE_RESULT_MISSED | MOVE_RESULT_FAILED)
#define MOVE_RESULT_NO_EFFECT (MOVE_RESULT_MISSED | MOVE_RESULT_FAILED | MOVE_RESULT_DOESNT_AFFECT_FOE)
@ -594,6 +595,7 @@ enum __attribute__((packed)) MoveEffect
// Move effects that happen before the move hits. Set in SetPreAttackMoveEffect
MOVE_EFFECT_BREAK_SCREEN,
MOVE_EFFECT_STEAL_STATS,
MOVE_EFFECT_BEAT_UP_MESSAGE, // Handles the message printing for gen2,3 and 4
NUM_MOVE_EFFECTS
};
@ -731,11 +733,6 @@ enum MoveTarget
#define PARENTAL_BOND_2ND_HIT 1
#define PARENTAL_BOND_OFF 0
// Constants for if HandleScriptMegaPrimalBurst should handle Mega Evolution, Primal Reversion, or Ultra Burst.
#define HANDLE_TYPE_MEGA_EVOLUTION 0
#define HANDLE_TYPE_PRIMAL_REVERSION 1
#define HANDLE_TYPE_ULTRA_BURST 2
// Constants for Torment
#define PERMANENT_TORMENT 0xF

View File

@ -597,10 +597,11 @@
#define B_ANIM_MON_SCARED 56
#define B_ANIM_GHOST_GET_OUT 57
#define B_ANIM_SILPH_SCOPED 58
#define B_ANIM_ROCK_THROW (B_ANIM_SILPH_SCOPED + 1)
#define B_ANIM_SAFARI_REACTION (B_ANIM_ROCK_THROW + 1)
#define NUM_B_ANIMS_GENERAL (B_ANIM_SAFARI_REACTION + 1)
#define B_ANIM_ROCK_THROW 59
#define B_ANIM_SAFARI_REACTION 60
#define B_ANIM_FORM_CHANGE_INSTANT 61
#define B_ANIM_FORM_CHANGE_DISGUISE 62
#define NUM_B_ANIMS_GENERAL 63
// special animations table (sBattleAnims_Special)
#define B_ANIM_LVL_UP 0
@ -676,6 +677,16 @@
#define ANIM_ORDER_UP_DROOPY 2
#define ANIM_ORDER_UP_STRETCHY 3
// AnimTask_TransformMon variations
enum SpeciesGfxChange
{
SPECIES_GFX_CHANGE_TRANSFORM,
SPECIES_GFX_CHANGE_FORM_CHANGE,
SPECIES_GFX_CHANGE_FORM_CHANGE_INSTANT,
SPECIES_GFX_CHANGE_ILLUSION_OFF,
SPECIES_GFX_CHANGE_GHOST_UNVEIL,
};
// Flags given to various functions to indicate which palettes to consider.
// Handled by UnpackSelectedBattlePalettes
#define F_PAL_BG (1 << 0)

View File

@ -49,7 +49,7 @@ enum EndTurnResolutionOrder
ENDTURN_TERRAIN,
ENDTURN_THIRD_EVENT_BLOCK,
ENDTURN_EMERGENCY_EXIT_4,
ENDTURN_FORM_CHANGE_ABILITIES,
ENDTURN_FORM_CHANGE,
ENDTURN_EJECT_PACK,
ENDTURN_DYNAMAX,
ENDTURN_TRAINER_A_SLIDES,

View File

@ -33,7 +33,6 @@ enum __attribute__((packed)) BattleMoveEffects
EFFECT_LIGHT_SCREEN,
EFFECT_REST,
EFFECT_OHKO,
EFFECT_SHEER_COLD, // Same as EFFECT_OHKO but Ice-types are immune to it and has decreased accuracy for non Ice-type users.
EFFECT_FUSION_COMBO,
EFFECT_FIXED_PERCENT_DAMAGE,
EFFECT_FIXED_HP_DAMAGE,

View File

@ -1,11 +1,77 @@
#ifndef GUARD_CONSTANTS_BATTLE_MOVE_RESOLUTION_H
#define GUARD_CONSTANTS_BATTLE_MOVE_RESOLUTION_H
enum Obedience
{
OBEYS,
DISOBEYS_LOAFS,
DISOBEYS_HITS_SELF,
DISOBEYS_FALL_ASLEEP,
DISOBEYS_WHILE_ASLEEP,
DISOBEYS_RANDOM_MOVE,
};
enum CancelerResult
{
CANCELER_RESULT_SUCCESS,
CANCELER_RESULT_BREAK, // Runs script. Increments state
CANCELER_RESULT_PAUSE, // Runs script. Does not increment state
CANCELER_RESULT_FAILURE, // Move failed, jump to script that handles the failure
};
enum CancelerState
{
CANCELER_STANCE_CHANGE_1,
CANCELER_CLEAR_FLAGS,
CANCELER_SKY_DROP,
CANCELER_RECHARGE,
CANCELER_CHILLY_RECEPTION,
CANCELER_ASLEEP_OR_FROZEN,
CANCELER_POWER_POINTS,
CANCELER_OBEDIENCE,
CANCELER_TRUANT,
CANCELER_FOCUS_GEN5,
CANCELER_FLINCH,
CANCELER_DISABLED,
CANCELER_VOLATILE_BLOCKED, // Gravity / Heal Block / Throat Chop
CANCELER_TAUNTED,
CANCELER_IMPRISONED,
CANCELER_CONFUSED,
CANCELER_GHOST,
CANCELER_PARALYZED,
CANCELER_INFATUATION,
CANCELER_BIDE,
CANCELER_Z_MOVES,
CANCELER_CHOICE_LOCK,
CANCELER_CALLSUBMOVE,
CANCELER_THAW,
CANCELER_STANCE_CHANGE_2,
CANCELER_ATTACKSTRING,
CANCELER_PPDEDUCTION,
CANCELER_MOVE_SPECIFIC_MESSAGE,
CANCELER_SKY_BATTLE,
CANCELER_WEATHER_PRIMAL,
CANCELER_FOCUS_PRE_GEN5,
CANCELER_MOVE_FAILURE,
CANCELER_POWDER_STATUS,
CANCELER_PRIORITY_BLOCK,
CANCELER_PROTEAN,
CANCELER_EXPLODING_DAMP,
CANCELER_EXPLOSION,
CANCELER_CHARGING,
CANCELER_NO_TARGET,
CANCELER_TOOK_ATTACK,
CANCELER_TARGET_FAILURE,
CANCELER_NOT_FULLY_PROTECTED,
CANCELER_MULTIHIT_MOVES,
CANCELER_END,
};
enum MoveEndResult
{
MOVEEND_STEP_CONTINUE,
MOVEEND_STEP_RUN_SCRIPT,
MOVEEND_STEP_BREAK,
MOVEEND_RESULT_CONTINUE,
MOVEEND_RESULT_RUN_SCRIPT,
MOVEEND_RESULT_BREAK,
};
// cases for Cmd_moveend - Order matters!
@ -17,6 +83,7 @@ enum MoveEndState
MOVEEND_RAGE,
MOVEEND_SYNCHRONIZE_TARGET,
MOVEEND_ABILITIES,
MOVEEND_FORM_CHANGE_ON_HIT, // Disguise / Gulp Missile
MOVEEND_ABILITIES_ATTACKER,
MOVEEND_STATUS_IMMUNITY_ABILITIES, // TODO: Do berries come before????
MOVEEND_SYNCHRONIZE_ATTACKER,
@ -54,7 +121,6 @@ enum MoveEndState
MOVEEND_MIRROR_HERB,
MOVEEND_PICKPOCKET,
MOVEEND_THIRD_MOVE_BLOCK,
MOVEEND_CHANGED_ITEMS,
MOVEEND_CLEAR_BITS,
MOVEEND_DANCER,
MOVEEND_PURSUIT_NEXT_ACTION,

View File

@ -10,7 +10,6 @@ enum BattleScriptOpcode
B_SCR_OP_CRITCALC,
B_SCR_OP_DAMAGECALC,
B_SCR_OP_TYPECALC,
B_SCR_OP_ADJUSTDAMAGE,
B_SCR_OP_MULTIHITRESULTMESSAGE,
B_SCR_OP_ATTACKANIMATION,
B_SCR_OP_WAITANIMATION,
@ -62,7 +61,7 @@ enum BattleScriptOpcode
B_SCR_OP_BICWORD,
B_SCR_OP_PAUSE,
B_SCR_OP_WAITSTATE,
B_SCR_OP_ISDMGBLOCKEDBYDISGUISE,
B_SCR_OP_TRYSELFCONFUSIONDMGFORMCHANGE,
B_SCR_OP_RETURN,
B_SCR_OP_END,
B_SCR_OP_END2,
@ -121,25 +120,20 @@ enum BattleScriptOpcode
B_SCR_OP_HPTHRESHOLDS,
B_SCR_OP_HPTHRESHOLDS2,
B_SCR_OP_USEITEMONOPPONENT,
B_SCR_OP_UNUSED_0X78,
B_SCR_OP_SETPROTECTLIKE,
B_SCR_OP_TRYEXPLOSION,
B_SCR_OP_SETATKHPTOZERO,
B_SCR_OP_JUMPIFNEXTTARGETVALID,
B_SCR_OP_TRYHEALHALFHEALTH,
B_SCR_OP_UNUSED_0X7E,
B_SCR_OP_SETFIELDWEATHER,
B_SCR_OP_SETREFLECT,
B_SCR_OP_SETSEEDED,
B_SCR_OP_MANIPULATEDAMAGE,
B_SCR_OP_TRYSETREST,
B_SCR_OP_UNUSED_0X82,
B_SCR_OP_UNUSED_0X83,
B_SCR_OP_JUMPIFUPROARWAKES,
B_SCR_OP_STOCKPILE,
B_SCR_OP_STOCKPILETOBASEDAMAGE,
B_SCR_OP_STOCKPILETOHPHEAL,
B_SCR_OP_UNUSED_0X88,
B_SCR_OP_STATBUFFCHANGE,
B_SCR_OP_NORMALISEBUFFS,
B_SCR_OP_SETBIDE,
@ -162,19 +156,12 @@ enum BattleScriptOpcode
B_SCR_OP_SETSUBSTITUTE,
B_SCR_OP_MIMICATTACKCOPY,
B_SCR_OP_SETCALLEDMOVE,
B_SCR_OP_UNUSED_0X9F,
B_SCR_OP_UNUSED_0XA0,
B_SCR_OP_UNUSED_0XA1,
B_SCR_OP_UNUSED_0XA2,
B_SCR_OP_DISABLELASTUSEDATTACK,
B_SCR_OP_TRYSETENCORE,
B_SCR_OP_PAINSPLITDMGCALC,
B_SCR_OP_SETTYPETORANDOMRESISTANCE,
B_SCR_OP_SETALWAYSHITFLAG,
B_SCR_OP_COPYMOVEPERMANENTLY,
B_SCR_OP_UNUSED_0XA9,
B_SCR_OP_UNUSED_AA,
B_SCR_OP_UNUSED_0XAB,
B_SCR_OP_SETTAILWIND,
B_SCR_OP_TRYSPITEPPREDUCE,
B_SCR_OP_HEALPARTYSTATUS,
@ -182,35 +169,25 @@ enum BattleScriptOpcode
B_SCR_OP_TRYSETSPIKES,
B_SCR_OP_SETVOLATILE,
B_SCR_OP_TRYSETPERISHSONG,
B_SCR_OP_UNUSED_0XB3,
B_SCR_OP_JUMPIFCONFUSEDANDSTATMAXED,
B_SCR_OP_UNUSED_0XB5,
B_SCR_OP_SETEMBARGO,
B_SCR_OP_PRESENTDAMAGECALCULATION,
B_SCR_OP_SETSAFEGUARD,
B_SCR_OP_MAGNITUDEDAMAGECALCULATION,
B_SCR_OP_JUMPIFNOPURSUITSWITCHDMG,
B_SCR_OP_TRYACTIVATEITEM,
B_SCR_OP_HALVEHP,
B_SCR_OP_COPYFOESTATS,
B_SCR_OP_RAPIDSPINFREE,
B_SCR_OP_UNUSED_0XBF,
B_SCR_OP_RECOVERBASEDONSUNLIGHT,
B_SCR_OP_SETSTICKYWEB,
B_SCR_OP_SELECTFIRSTVALIDTARGET,
B_SCR_OP_SETFUTUREATTACK,
B_SCR_OP_TRYDOBEATUP,
B_SCR_OP_SETSEMIINVULNERABLEBIT,
B_SCR_OP_UNUSED_0XC6,
B_SCR_OP_UNUSED_0XC7,
B_SCR_OP_UNUSED_C8,
B_SCR_OP_TRYMEMENTO,
B_SCR_OP_SETFORCEDTARGET,
B_SCR_OP_UNUSED_0XCB,
B_SCR_OP_UNUSED_0XCC,
B_SCR_OP_CURESTATUSWITHMOVE,
B_SCR_OP_SETTORMENT,
B_SCR_OP_UNUSED_0XCF,
B_SCR_OP_SETTAUNT,
B_SCR_OP_TRYSETHELPINGHAND,
B_SCR_OP_TRYSWAPITEMS,
@ -219,29 +196,22 @@ enum BattleScriptOpcode
B_SCR_OP_SETTOXICSPIKES,
B_SCR_OP_SETGASTROACID,
B_SCR_OP_SETYAWN,
B_SCR_OP_UNUSED0XD8,
B_SCR_OP_SETROOM,
B_SCR_OP_TRYSWAPABILITIES,
B_SCR_OP_TRYIMPRISON,
B_SCR_OP_SETSTEALTHROCK,
B_SCR_OP_TRYSETVOLATILE,
B_SCR_OP_UNUSED_0XDE,
B_SCR_OP_TRYSETMAGICCOAT,
B_SCR_OP_TRYSETSNATCH,
B_SCR_OP_UNUSED2,
B_SCR_OP_SWITCHOUTABILITIES,
B_SCR_OP_JUMPIFHASNOHP,
B_SCR_OP_UNUSED_0XE4,
B_SCR_OP_PICKUP,
B_SCR_OP_UNUSED_0XE6,
B_SCR_OP_UNUSED_0XE7,
B_SCR_OP_SETTYPEBASEDHALVERS,
B_SCR_OP_JUMPIFSUBSTITUTEBLOCKS,
B_SCR_OP_TRYRECYCLEITEM,
B_SCR_OP_SETTYPETOENVIRONMENT,
B_SCR_OP_PURSUITDOUBLES,
B_SCR_OP_SNATCHSETBATTLERS,
B_SCR_OP_UNUSED_0XEE,
B_SCR_OP_HANDLEBALLTHROW,
B_SCR_OP_GIVECAUGHTMON,
B_SCR_OP_TRYSETCAUGHTMONDEXFLAGS,
@ -258,6 +228,40 @@ enum BattleScriptOpcode
B_SCR_OP_JUMPIFCAPTIVATEAFFECTED,
B_SCR_OP_SETNONVOLATILESTATUS,
B_SCR_OP_TRYOVERWRITEABILITY,
// Expansion users, please don't use any of the unused commands.
// They are reserved for expansion usage.
// Use callnatives instead.
B_SCR_OP_UNUSED_1,
B_SCR_OP_UNUSED_2,
B_SCR_OP_UNUSED_3,
B_SCR_OP_UNUSED_4,
B_SCR_OP_UNUSED_5,
B_SCR_OP_UNUSED_6,
B_SCR_OP_UNUSED_7,
B_SCR_OP_UNUSED_8,
B_SCR_OP_UNUSED_9,
B_SCR_OP_UNUSED_10,
B_SCR_OP_UNUSED_11,
B_SCR_OP_UNUSED_12,
B_SCR_OP_UNUSED_13,
B_SCR_OP_UNUSED_14,
B_SCR_OP_UNUSED_15,
B_SCR_OP_UNUSED_16,
B_SCR_OP_UNUSED_17,
B_SCR_OP_UNUSED_18,
B_SCR_OP_UNUSED_19,
B_SCR_OP_UNUSED_20,
B_SCR_OP_UNUSED_21,
B_SCR_OP_UNUSED_22,
B_SCR_OP_UNUSED_23,
B_SCR_OP_UNUSED_24,
B_SCR_OP_UNUSED_25,
B_SCR_OP_UNUSED_26,
B_SCR_OP_UNUSED_27,
B_SCR_OP_UNUSED_28,
B_SCR_OP_UNUSED_29,
B_SCR_OP_UNUSED_30,
B_SCR_OP_CALLNATIVE,
};

View File

@ -11,6 +11,6 @@
#define TRAINER_BATTLE_REMATCH_DOUBLE 7
#define TRAINER_BATTLE_CONTINUE_SCRIPT_DOUBLE_NO_MUSIC 8
#define TRAINER_BATTLE_EARLY_RIVAL 9
#define TRAINER_BATTLE_SET_TRAINERS_FOR_MULTI_BATTLE 10
#define TRAINER_BATTLE_TWO_TRAINERS_NO_INTRO 10
#endif // GUARD_CONSTANTS_BATTLE_SETUP_H

View File

@ -26,7 +26,6 @@ enum StringID
STRINGID_ATTACKMISSED,
STRINGID_PKMNPROTECTEDITSELF,
STRINGID_STATSWONTINCREASE2,
STRINGID_AVOIDEDDAMAGE,
STRINGID_ITDOESNTAFFECT,
STRINGID_SCR_ITDOESNTAFFECT,
STRINGID_BATTLERFAINTED,
@ -295,7 +294,6 @@ enum StringID
STRINGID_ITEMALLOWSONLYYMOVE,
STRINGID_PKMNHUNGONWITHX,
STRINGID_EMPTYSTRING3,
STRINGID_PKMNSXBLOCKSY,
STRINGID_PKMNSXRESTOREDHPALITTLE2,
STRINGID_PKMNSXWHIPPEDUPSANDSTORM,
STRINGID_PKMNSXPREVENTSYLOSS,
@ -321,7 +319,6 @@ enum StringID
STRINGID_EMPTYSTRING4,
STRINGID_ABOOSTED,
STRINGID_PKMNSXINTENSIFIEDSUN,
STRINGID_PKMNMAKESGROUNDMISS,
STRINGID_YOUTHROWABALLNOWRIGHT,
STRINGID_PKMNSXTOOKATTACK,
STRINGID_PKMNCHOSEXASDESTINY,
@ -338,6 +335,7 @@ enum StringID
STRINGID_PKMNSXPREVENTSFLINCHING,
STRINGID_PKMNALREADYHASBURN,
STRINGID_STATSWONTDECREASE2,
STRINGID_PKMNSXBLOCKSY,
STRINGID_PKMNSXWOREOFF,
STRINGID_THEWALLSHATTERED,
STRINGID_PKMNSXCUREDITSYPROBLEM,
@ -455,6 +453,7 @@ enum StringID
STRINGID_STEALTHROCKDMG,
STRINGID_TOXICSPIKESABSORBED,
STRINGID_TOXICSPIKESPOISONED,
STRINGID_TOXICSPIKESBADLYPOISONED,
STRINGID_STICKYWEBSWITCHIN,
STRINGID_HEALINGWISHCAMETRUE,
STRINGID_HEALINGWISHHEALED,
@ -710,7 +709,6 @@ enum StringID
STRINGID_TIMETODYNAMAX,
STRINGID_TIMETOGIGANTAMAX,
STRINGID_QUESTIONFORFEITBATTLE,
STRINGID_TOXICSPIKESBADLYPOISONED,
STRINGID_POWERCONSTRUCTPRESENCEOFMANY,
STRINGID_POWERCONSTRUCTTRANSFORM,
STRINGID_ABILITYSHIELDPROTECTS,
@ -719,14 +717,15 @@ enum StringID
STRINGID_SILPHSCOPEUNVEILED,
STRINGID_GHOSTWASMAROWAK,
STRINGID_TRAINER1MON1COMEBACK,
// pokefirered specific
STRINGID_OLDMANUSEDITEM,
STRINGID_GOTCHAPKMNCAUGHTOLDMAN,
STRINGID_THREWROCK,
STRINGID_THREWBAIT,
STRINGID_PKMNANGRY,
STRINGID_PKMNEATING,
STRINGID_PKMNDISGUISEWASBUSTED,
// pokefirered specific
STRINGID_OLDMANUSEDITEM,
STRINGID_GOTCHAPKMNCAUGHTOLDMAN,
STRINGID_PKMNTRANSFERREDBILLSPC,
STRINGID_PKMNBOXBILLSPCFULL,
STRINGID_POKEDUDEUSED,

View File

@ -8,6 +8,7 @@ enum SwitchInEvents
SWITCH_IN_EVENTS_NEUTRALIZING_GAS,
SWITCH_IN_EVENTS_UNNERVE,
SWITCH_IN_EVENTS_FIRST_BLOCK,
SWITCH_IN_EVENTS_FORM_CHANGE,
SWITCH_IN_EVENTS_SECOND_BLOCK,
SWITCH_IN_EVENTS_WHITE_HERB,
SWITCH_IN_EVENTS_OPPORTUNIST,

View File

@ -1,38 +1,40 @@
#ifndef GUARD_Z_MOVE_EFFECTS_H
#define GUARD_Z_MOVE_EFFECTS_H
#define Z_EFFECT_NONE 0
#define Z_EFFECT_RESET_STATS 1
#define Z_EFFECT_ALL_STATS_UP_1 2
#define Z_EFFECT_BOOST_CRITS 3
#define Z_EFFECT_FOLLOW_ME 4
#define Z_EFFECT_CURSE 5
#define Z_EFFECT_RECOVER_HP 6
#define Z_EFFECT_RESTORE_REPLACEMENT_HP 7
enum ZEffect
{
Z_EFFECT_NONE,
Z_EFFECT_RESET_STATS,
Z_EFFECT_ALL_STATS_UP_1,
Z_EFFECT_BOOST_CRITS,
Z_EFFECT_FOLLOW_ME,
Z_EFFECT_CURSE,
Z_EFFECT_RECOVER_HP,
Z_EFFECT_RESTORE_REPLACEMENT_HP,
#define Z_EFFECT_ATK_UP_1 8
#define Z_EFFECT_DEF_UP_1 9
#define Z_EFFECT_SPD_UP_1 10
#define Z_EFFECT_SPATK_UP_1 11
#define Z_EFFECT_SPDEF_UP_1 12
#define Z_EFFECT_ACC_UP_1 13
#define Z_EFFECT_EVSN_UP_1 14
Z_EFFECT_ATK_UP_1,
Z_EFFECT_DEF_UP_1,
Z_EFFECT_SPD_UP_1,
Z_EFFECT_SPATK_UP_1,
Z_EFFECT_SPDEF_UP_1,
Z_EFFECT_ACC_UP_1,
Z_EFFECT_EVSN_UP_1,
#define Z_EFFECT_ATK_UP_2 15
#define Z_EFFECT_DEF_UP_2 16
#define Z_EFFECT_SPD_UP_2 17
#define Z_EFFECT_SPATK_UP_2 18
#define Z_EFFECT_SPDEF_UP_2 19
#define Z_EFFECT_ACC_UP_2 20
#define Z_EFFECT_EVSN_UP_2 21
#define Z_EFFECT_ATK_UP_3 22
#define Z_EFFECT_DEF_UP_3 23
#define Z_EFFECT_SPD_UP_3 24
#define Z_EFFECT_SPATK_UP_3 25
#define Z_EFFECT_SPDEF_UP_3 26
#define Z_EFFECT_ACC_UP_3 27
#define Z_EFFECT_EVSN_UP_3 28
Z_EFFECT_ATK_UP_2,
Z_EFFECT_DEF_UP_2,
Z_EFFECT_SPD_UP_2,
Z_EFFECT_SPATK_UP_2,
Z_EFFECT_SPDEF_UP_2,
Z_EFFECT_ACC_UP_2,
Z_EFFECT_EVSN_UP_2,
Z_EFFECT_ATK_UP_3,
Z_EFFECT_DEF_UP_3,
Z_EFFECT_SPD_UP_3,
Z_EFFECT_SPATK_UP_3,
Z_EFFECT_SPDEF_UP_3,
Z_EFFECT_ACC_UP_3,
Z_EFFECT_EVSN_UP_3,
};
#endif // GUARD_Z_MOVE_EFFECTS_H

View File

@ -17,12 +17,15 @@
#define BERRY_COLOR_YELLOW 4
#define BERRY_COLOR_PINK 5
#define FLAVOR_SPICY 0
#define FLAVOR_DRY 1
#define FLAVOR_SWEET 2
#define FLAVOR_BITTER 3
#define FLAVOR_SOUR 4
#define FLAVOR_COUNT 5
enum __attribute__((__packed__)) Flavor
{
FLAVOR_SPICY,
FLAVOR_DRY,
FLAVOR_SWEET,
FLAVOR_BITTER,
FLAVOR_SOUR,
FLAVOR_COUNT,
};
#define BERRY_STAGE_NO_BERRY 0 // there is no tree planted and the soil is completely flat.
#define BERRY_STAGE_PLANTED 1

View File

@ -0,0 +1,14 @@
#ifndef GUARD_CONSTANTS_FIELD_POISON_H
#define GUARD_CONSTANTS_FIELD_POISON_H
enum {
FLDPSN_NONE,
FLDPSN_PSN,
FLDPSN_FNT
};
#define FLDPSN_NO_WHITEOUT 0
#define FLDPSN_WHITEOUT 1
#define FLDPSN_FRONTIER_WHITEOUT 2
#endif //GUARD_CONSTANTS_FIELD_POISON_H

View File

@ -1,7 +1,7 @@
#ifndef GUARD_CONSTANTS_FORM_CHANGE_TYPES_H
#define GUARD_CONSTANTS_FORM_CHANGE_TYPES_H
// FORM_CHANGE_BATTLE_HP_PERCENT param2 arguments
// FORM_CHANGE_BATTLE_HP_PERCENT_TURN_END / FORM_CHANGE_BATTLE_HP_PERCENT_SEND_OUT param2 arguments
enum FormChangeBattleHPPercentArguments
{
HP_HIGHER_THAN = 1,
@ -47,8 +47,6 @@ enum FormChanges
// - No parameters.
FORM_CHANGE_WITHDRAW,
// Form change that activates when the Pokémon faints, either in battle or in the overworld by poison.
// If species is not specified and it's on the player's side, it will try to use the value
// saved in gBattleStruct->partyState[x][y].changedSpecies from a previous form change.
// - No parameters.
FORM_CHANGE_FAINT,
// Form change that activates when the Pokémon is sent out at the beginning of a battle
@ -65,15 +63,36 @@ enum FormChanges
// param1: battle environment to check.
FORM_CHANGE_END_BATTLE_ENVIRONMENT,
// Form change that activates when the Pokémon is switched out in battle.
// param1: ability to check, optional
FORM_CHANGE_BATTLE_SWITCH,
// param1: (optional) ability to check
FORM_CHANGE_BATTLE_SWITCH_OUT,
// Form change that activates when the Pokémon is switched-in in battle.
// This form change happens before other abilities like Neutralizing Gas.
// param1: ability to check
FORM_CHANGE_BATTLE_SWITCH_IN,
// Form change that activates when the Pokémon's HP % passes a certain threshold.
// param1: Ability to check.
// param2: HP comparer
// - HP_HIGHER_THAN if the form triggers when the current HP is higher than the specified threshold.
// - HP_LOWER_EQ_THAN if the form triggers when the current HP is lower or equal than the specified threshold.
// param3: HP percentage threshold.
FORM_CHANGE_BATTLE_HP_PERCENT,
// param4: (optional) Minimum level to do form change
FORM_CHANGE_BATTLE_HP_PERCENT_TURN_END,
// Form change that activates when the Pokémon's HP % passes a certain threshold when sent out into battle.
// param1: Ability to check.
// param2: HP comparer
// - HP_HIGHER_THAN if the form triggers when the current HP is higher than the specified threshold.
// - HP_LOWER_EQ_THAN if the form triggers when the current HP is lower or equal than the specified threshold.
// param3: HP percentage threshold.
// param4: (optional) Minimum level to do form change
FORM_CHANGE_BATTLE_HP_PERCENT_SEND_OUT,
// Form change that activates when the Pokémon's HP % passes a certain threshold when using a move.
// param1: Ability to check.
// param2: HP comparer
// - HP_HIGHER_THAN if the form triggers when the current HP is higher than the specified threshold.
// - HP_LOWER_EQ_THAN if the form triggers when the current HP is lower or equal than the specified threshold.
// param3: HP percentage threshold.
// param4: Move used.
FORM_CHANGE_BATTLE_HP_PERCENT_DURING_MOVE,
// Form change that activates when the mon has the defined item.
// If it's on the player's side, it also requires ITEM_MEGA_RING in the user's bag and for the player to trigger it by pressing START before selecting a move.
// param1: item to hold.
@ -112,8 +131,13 @@ enum FormChanges
// Form change that activates when inflicted with a specific status
// param1: status
FORM_CHANGE_STATUS,
// Form change that activates after move is used. Currently only used for activating Gulp Missile.
FORM_CHANGE_HIT_BY_MOVE,
// Form change that activates after receiving an attack.
// param1: ability
// param2: move category to check
FORM_CHANGE_BATTLE_HIT_BY_MOVE_CATEGORY,
// Form change that activates after hitting itself in confusion.
// param1: ability
FORM_CHANGE_BATTLE_HIT_BY_CONFUSION_SELF_DMG,
// Form change that activates when terastallized as as a specific type
// param1: tera type
FORM_CHANGE_BATTLE_TERASTALLIZATION,

View File

@ -86,11 +86,13 @@
F(MINIMIZE_EVASION, minimizeEvasion, (u32, GEN_COUNT - 1)) \
F(GROWTH_STAT_RAISE, growthStatRaise, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(FOCUS_ENERGY_CRIT_RATIO, focusEnergyCritRatio, (u32, GEN_COUNT - 1)) \
F(PSYCH_UP_CRIT_RATIO, psychUpCritRatio, (u32, GEN_COUNT - 1)) \
/* Other move settings */ \
F(INCINERATE_GEMS, incinerateGems, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(CAN_SPITE_FAIL, canSpiteFail, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(CRASH_IF_TARGET_IMMUNE, crashIfTargetImmune, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(MEMENTO_FAIL, mementoFail, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(PARTING_SHOT_SWITCH, partingShotSwitch, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(GLARE_GHOST, glareGhost, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(SKILL_SWAP, skillSwap, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(BRICK_BREAK, brickBreak, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
@ -120,6 +122,8 @@
F(AFTER_YOU_TURN_ORDER, afterYouTurnOrder, (u32, GEN_COUNT - 1)) \
F(QUASH_TURN_ORDER, quashTurnOrder, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(DESTINY_BOND_FAIL, destinyBondFail, (u32, GEN_COUNT - 1)) \
F(FORESIGHT_FAIL, foresightFail, (u32, GEN_COUNT - 1)) \
F(MIRACLE_EYE_FAIL, miracleEyeFail, (u32, GEN_COUNT - 1)) \
F(PURSUIT_TARGET, pursuitTarget, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(SKIP_RECHARGE, skipRecharge, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \
F(ENCORE_TARGET, encoreTarget, (u32, GEN_COUNT - 1)) \

View File

@ -33,14 +33,17 @@
#define NUM_VERSIONS 15
#define LANGUAGE_JAPANESE 1
#define LANGUAGE_ENGLISH 2
#define LANGUAGE_FRENCH 3
#define LANGUAGE_ITALIAN 4
#define LANGUAGE_GERMAN 5
#define LANGUAGE_KOREAN 6 // 6 goes unused but the theory is it was meant to be Korean
#define LANGUAGE_SPANISH 7
#define NUM_LANGUAGES 7
enum Language
{
LANGUAGE_JAPANESE = 1,
LANGUAGE_ENGLISH = 2,
LANGUAGE_FRENCH = 3,
LANGUAGE_ITALIAN = 4,
LANGUAGE_GERMAN = 5,
LANGUAGE_KOREAN = 6, // 6 goes unused but the theory is it was meant to be Korean
LANGUAGE_SPANISH = 7,
NUM_LANGUAGES
};
#define GAME_LANGUAGE (LANGUAGE_ENGLISH)
@ -134,9 +137,12 @@ enum FrontierLevelMode
#define NUM_TOWER_CHALLENGE_TYPES 4
#define MALE 0
#define FEMALE 1
#define GENDER_COUNT 2
enum Gender
{
MALE,
FEMALE,
GENDER_COUNT,
};
#define BARD_SONG_LENGTH 6
#define NUM_STORYTELLER_TALES 4

View File

@ -360,8 +360,6 @@
#define MUS_NONE 0xFFFF
// placeholders
#define SE_SUDOWOODO_SHAKE SE_USE_ITEM
#define SE_POKENAV_CALL SE_USE_ITEM
#define MUS_B_TOWER MUS_ROUTE1
#define MUS_B_FRONTIER MUS_ROUTE1
#define MUS_B_ARENA MUS_ROUTE1
@ -375,12 +373,20 @@
#define MUS_B_DOME MUS_ROUTE1
#define MUS_B_FACTORY MUS_ROUTE1
#define MUS_B_PYRAMID_TOP MUS_ROUTE1
#define MUS_VS_FRONTIER_BRAIN MUS_VS_CHAMPION
#define MUS_VS_KYOGRE_GROUDON MUS_VS_LEGEND
#define MUS_VS_RAYQUAZA MUS_VS_LEGEND
#define MUS_VS_MEW MUS_VS_LEGEND
#define MUS_VS_REGI MUS_VS_LEGEND
#define MUS_OBTAIN_SYMBOL SE_USE_ITEM
#define MUS_OBTAIN_B_POINTS SE_USE_ITEM
#define SE_ARENA_TIMEUP1 SE_USE_ITEM
#define SE_ARENA_TIMEUP2 SE_USE_ITEM
#define SE_PIKE_CURTAIN_CLOSE SE_USE_ITEM
#define SE_PIKE_CURTAIN_OPEN SE_USE_ITEM
#define SE_SUDOWOODO_SHAKE SE_USE_ITEM
#define SE_POKENAV_CALL SE_USE_ITEM
#endif // GUARD_CONSTANTS_SONGS_H

View File

@ -19,7 +19,7 @@
#define TRAINER_ENCOUNTER_MUSIC_INTERVIEWER 12
#define TRAINER_ENCOUNTER_MUSIC_RICH 13 // Rich Boys and Gentlemen
// TODO: replace with actual trainer classes
// placeholders
#define FACILITY_CLASS_TUBER_M FACILITY_CLASS_RUIN_MANIAC
#define FACILITY_CLASS_PKMN_BREEDER_M FACILITY_CLASS_RUIN_MANIAC
@ -27,9 +27,16 @@
#define FACILITY_CLASS_TUBER_F FACILITY_CLASS_AROMA_LADY
#define FACILITY_CLASS_PKMN_BREEDER_F FACILITY_CLASS_AROMA_LADY
#define TRAINER_CLASS_RIVAL TRAINER_CLASS_RIVAL_LATE
#define TRAINER_CLASS_TUBER_M TRAINER_CLASS_RS_TUBER_M
#define TRAINER_CLASS_TUBER_F TRAINER_CLASS_RS_TUBER_F
#define TRAINER_CLASS_RIVAL TRAINER_CLASS_RIVAL_LATE
#define TRAINER_CLASS_TUBER_M TRAINER_CLASS_RS_TUBER_M
#define TRAINER_CLASS_TUBER_F TRAINER_CLASS_RS_TUBER_F
#define TRAINER_CLASS_SALON_MAIDEN TRAINER_CLASS_TUBER
#define TRAINER_CLASS_DOME_ACE TRAINER_CLASS_PKMN_BREEDER
#define TRAINER_CLASS_PALACE_MAVEN TRAINER_CLASS_PKMN_RANGER
#define TRAINER_CLASS_ARENA_TYCOON TRAINER_CLASS_AROMA_LADY
#define TRAINER_CLASS_FACTORY_HEAD TRAINER_CLASS_RUIN_MANIAC
#define TRAINER_CLASS_PIKE_QUEEN TRAINER_CLASS_LADY
#define TRAINER_CLASS_PYRAMID_KING TRAINER_CLASS_PAINTER

View File

@ -232,7 +232,7 @@ static inline u16 SanitizeTrainerId(u16 trainerId)
{
switch (trainerId)
{
case TRAINER_RECORD_MIXING_FRIEND:
// case TRAINER_RECORD_MIXING_FRIEND:
case TRAINER_RECORD_MIXING_APPRENTICE:
case TRAINER_EREADER:
case TRAINER_FRONTIER_BRAIN:

View File

@ -844,6 +844,7 @@ extern const u8 EventScript_TryDoDoubleRematchBattle[];
extern const u8 EventScript_TryDoRematchBattle[];
extern const u8 EventScript_StartTrainerApproach[];
extern const u8 EventScript_TestSignpostMsg[];
extern const u8 EventScript_TryGetTrainerScript[];
extern const u8 EventScript_ObjectApproachPlayer[];
extern const u8 BerryTreeScript[];

View File

@ -11,6 +11,7 @@ enum {
};
bool8 ShowFieldMessage(const u8 *message);
bool8 ShowFieldMessageFromBuffer(void);
bool8 ShowFieldAutoScrollMessage(const u8 *message);
void HideFieldMessageBox(void);
bool8 IsFieldMessageBoxHidden(void);

View File

@ -3,12 +3,6 @@
#include "global.h"
enum {
FLDPSN_NONE,
FLDPSN_PSN,
FLDPSN_FNT
};
s32 DoPoisonFieldEffect(void);
#endif //GUARD_FIELD_POISON_H

View File

@ -33,5 +33,6 @@ bool8 InPokemonCenter(void);
void UpdateFrontierManiac(u16 daysSince);
void UpdateFrontierGambler(u16 daysSince);
void FrontierGamblerSetWonOrLost(bool8 won);
bool8 InMultiPartnerRoom(void);
#endif // GUARD_FIELD_SPECIALS_H

View File

@ -37,7 +37,7 @@ struct Main
/*0x439*/ u8 oamLoadDisabled:1;
/*0x439*/ u8 inBattle:1;
/*0x439*/ u8 field_439_x4:1;
/*0x439*/ u8 anyLinkBattlerHasFrontierPass:1;
};
#define GAME_CODE_LENGTH 4

View File

@ -1,11 +1,13 @@
#ifndef GUARD_MOVES_H
#define GUARD_MOVES_H
#include "generational_changes.h"
#include "contest_effect.h"
#include "constants/battle.h"
#include "constants/battle_factory.h"
#include "constants/battle_move_effects.h"
#include "constants/battle_string_ids.h"
#include "constants/battle_z_move_effects.h"
#include "constants/moves.h"
// For defining EFFECT_HIT etc. with battle TV scores and flags etc.
@ -94,6 +96,7 @@ struct MoveInfo
u32 criticalHitStage:2;
bool32 alwaysCriticalHit:1;
u32 numAdditionalEffects:3; // limited to 7
// Flags
bool32 makesContact:1;
bool32 ignoresProtect:1;
@ -126,6 +129,12 @@ struct MoveInfo
bool32 alwaysHitsInRain:1;
bool32 accuracy50InSun:1;
bool32 alwaysHitsInHailSnow:1;
bool32 alwaysHitsOnSameType:1; // Always hits if user is of same type as move
bool32 noAffectOnSameTypeTarget:1; // Fails if target is of same type as move
bool32 accIncreaseByTenOnSameType:1; // Accuracy is increased by 10% if user is of same type as move
bool32 padding1:15;
// end of word
// Ban flags
bool32 gravityBanned:1;
bool32 mirrorMoveBanned:1;
@ -143,7 +152,7 @@ struct MoveInfo
bool32 dampBanned:1;
//Other
bool32 validApprenticeMove:1;
u32 padding:3;
u32 padding2:17;
// end of word
union {
@ -165,7 +174,7 @@ struct MoveInfo
} reflectDamage;
struct {
u16 terrain;
u16 percent:14;
u16 percent:13;
enum TerrainGroundCheck groundCheck:2;
u16 hitsBothFoes:1;
} terrainBoost;
@ -259,7 +268,7 @@ static inline u32 GetMovePP(enum Move moveId)
return gMovesInfo[SanitizeMoveId(moveId)].pp;
}
static inline u32 GetMoveZEffect(enum Move moveId)
static inline enum ZEffect GetMoveZEffect(enum Move moveId)
{
moveId = SanitizeMoveId(moveId);
assertf(GetMoveCategory(moveId) == DAMAGE_CATEGORY_STATUS, "not a status move: %S", gMovesInfo[moveId].name);
@ -458,6 +467,29 @@ static inline bool32 MoveAlwaysHitsInHailSnow(enum Move moveId)
return gMovesInfo[SanitizeMoveId(moveId)].alwaysHitsInHailSnow;
}
static inline bool32 MoveAlwaysHitsOnSameType(enum Move moveId)
{
#if TESTING
if (moveId == MOVE_TOXIC && GetConfig(CONFIG_TOXIC_NEVER_MISS) < GEN_6)
return FALSE;
#endif
return gMovesInfo[SanitizeMoveId(moveId)].alwaysHitsOnSameType;
}
static inline bool32 MoveHasNoEffectOnSameType(enum Move moveId)
{
#if TESTING
if (moveId == MOVE_SHEER_COLD && GetConfig(CONFIG_SHEER_COLD_IMMUNITY) < GEN_7)
return FALSE;
#endif
return gMovesInfo[SanitizeMoveId(moveId)].noAffectOnSameTypeTarget;
}
static inline bool32 MoveHasIncreasedAccByTenOnSameType(enum Move moveId)
{
return gMovesInfo[SanitizeMoveId(moveId)].accIncreaseByTenOnSameType;
}
static inline bool32 IsMoveGravityBanned(enum Move moveId)
{
return gMovesInfo[SanitizeMoveId(moveId)].gravityBanned;
@ -613,7 +645,7 @@ static inline u32 GetMoveTerrainBoost_GroundCheck(enum Move moveId)
return gMovesInfo[moveId].argument.terrainBoost.groundCheck;
}
static inline u32 GetMoveTerrainBoost_HitsBothFoes(enum Move moveId)
static inline bool32 GetMoveTerrainBoost_HitsBothFoes(enum Move moveId)
{
moveId = SanitizeMoveId(moveId);
assertf(gMovesInfo[moveId].effect == EFFECT_TERRAIN_BOOST, "not a terrain boosted move: %S", GetMoveName(moveId));
@ -688,7 +720,7 @@ static inline u32 GetMoveRecoil(enum Move moveId)
return gMovesInfo[moveId].argument.recoilPercentage;
}
static inline u32 GetMoveNonVolatileStatus(enum Move move)
static inline enum MoveEffect GetMoveNonVolatileStatus(enum Move move)
{
move = SanitizeMoveId(move);
switch (GetMoveEffect(move))

View File

@ -84,7 +84,7 @@ void ChooseMonForWirelessMinigame(void);
void OpenPartyMenuInBattle(u8 partyAction);
void Pokedude_OpenPartyMenuInBattle(void);
void Pokedude_ChooseMonForInBattleItem(void);
void EnterPartyFromItemMenuInBattle(void);
void ChooseMonForInBattleItem(void);
void BufferBattlePartyCurrentOrder(void);
void BufferBattlePartyCurrentOrderBySide(u8 battlerId, u8 flankId);
void SwitchPartyOrderLinkMulti(u8 battlerId, u8 slot, u8 slot2);

View File

@ -653,6 +653,26 @@ struct FormChange
u16 param1;
u16 param2;
u16 param3;
u16 param4;
};
struct FormChangeContext
{
enum FormChanges method:16;
u16 currentSpecies;
u16 partyItemUsed;
u16 multichoiceSelection;
u16 heldItem;
u16 ability;
u16 learnedMove;
u32 status;
u16 moves[MAX_MON_MOVES];
u16 hp;
u16 maxHP;
u32 gmaxFactor:1;
enum Type teraType;
u32 level:7;
u32 padding:8;
};
enum FusionExtraMoveHandling
@ -760,6 +780,7 @@ u16 GiveMoveToMon(struct Pokemon *mon, enum Move move);
u16 GiveMoveToBoxMon(struct BoxPokemon *boxMon, enum Move move);
u16 GiveMoveToBattleMon(struct BattlePokemon *mon, enum Move move);
void SetMonMoveSlot(struct Pokemon *mon, enum Move move, u8 slot);
void SetBoxMonMoveSlot(struct BoxPokemon *mon, enum Move move, u8 slot);
void SetBattleMonMoveSlot(struct BattlePokemon *mon, enum Move move, u8 slot);
void GiveMonInitialMoveset(struct Pokemon *mon);
void GiveBoxMonInitialMoveset(struct BoxPokemon *boxMon);
@ -769,8 +790,8 @@ enum Move MonTryLearningNewMoveAtLevel(struct Pokemon *mon, bool32 firstMove, u3
enum Move MonTryLearningNewMove(struct Pokemon *mon, bool8 firstMove);
void DeleteFirstMoveAndGiveMoveToMon(struct Pokemon *mon, enum Move move);
void DeleteFirstMoveAndGiveMoveToBoxMon(struct BoxPokemon *boxMon, enum Move move);
u8 CountAliveMonsInBattle(u8 caseId, u32 battler);
u8 GetDefaultMoveTarget(u8 battler);
u8 CountAliveMonsInBattle(u8 caseId, enum BattlerId battler);
u8 GetDefaultMoveTarget(enum BattlerId battler);
u8 GetMonGender(struct Pokemon *mon);
u8 GetBoxMonGender(struct BoxPokemon *boxMon);
u8 GetGenderFromSpeciesAndPersonality(u16 species, u32 personality);
@ -799,7 +820,7 @@ u8 GiveCapturedMonToPlayer(struct Pokemon *mon);
u8 CopyMonToPC(struct Pokemon *mon);
u8 CalculatePlayerPartyCount(void);
u8 CalculateEnemyPartyCount(void);
u8 CalculateEnemyPartyCountInSide(u32 battler);
u8 CalculateEnemyPartyCountInSide(enum BattlerId battler);
u8 GetMonsStateToDoubles(void);
u8 GetMonsStateToDoubles_2(void);
enum Ability GetAbilityBySpecies(u16 species, u8 abilityNum);
@ -834,11 +855,11 @@ void RemoveMonPPBonus(struct Pokemon *mon, u8 moveIndex);
void RemoveBoxMonPPBonus(struct BoxPokemon *mon, u8 moveIndex);
void RemoveBattleMonPPBonus(struct BattlePokemon *mon, u8 moveIndex);
void PokemonToBattleMon(struct Pokemon *src, struct BattlePokemon *dst);
void CopyPartyMonToBattleData(u32 battler, u32 partyIndex);
void CopyPartyMonToBattleData(enum BattlerId battler, u32 partyIndex);
bool8 ExecuteTableBasedItemEffect(struct Pokemon *mon, enum Item item, u8 partyIndex, u8 moveIndex);
bool8 PokemonUseItemEffects(struct Pokemon *mon, enum Item item, u8 partyIndex, u8 moveIndex, u8 usedByAI);
bool8 HealStatusConditions(struct Pokemon *mon, u32 healMask, u8 battler);
u8 GetItemEffectParamOffset(u32 battler, enum Item itemId, u8 effectByte, u8 effectBit);
bool8 HealStatusConditions(struct Pokemon *mon, u32 healMask, enum BattlerId battler);
u8 GetItemEffectParamOffset(enum BattlerId battler, enum Item itemId, u8 effectByte, u8 effectBit);
u8 *UseStatIncreaseItem(enum Item itemId);
u8 GetNature(struct Pokemon *mon);
u8 GetNatureFromPersonality(u32 personality);
@ -910,8 +931,8 @@ const u16 *GetMonSpritePalFromSpeciesIsEgg(u16 species, bool32 isShiny, bool32 i
bool32 IsMoveHM(enum Move move);
bool32 CannotForgetMove(enum Move move);
bool8 IsMonSpriteNotFlipped(u16 species);
s8 GetMonFlavorRelation(struct Pokemon *mon, u8 flavor);
s8 GetFlavorRelationByPersonality(u32 personality, u8 flavor);
s8 GetMonFlavorRelation(struct Pokemon *mon, enum Flavor flavor);
s8 GetFlavorRelationByPersonality(u32 personality, enum Flavor flavor);
bool8 IsTradedMon(struct Pokemon *mon);
bool8 IsOtherTrainer(u32 otId, u8 *otName);
void MonRestorePP(struct Pokemon *mon);
@ -927,7 +948,7 @@ void StopPokemonAnimationDelayTask(void);
void BattleAnimateBackSprite(struct Sprite *sprite, u16 species);
u8 GetOpposingLinkMultiBattlerId(bool8 rightSide, u8 multiplayerId);
enum TrainerPicID FacilityClassToPicIndex(u16 facilityClass);
enum TrainerPicID PlayerGenderToFrontTrainerPicId(u8 playerGender);
enum TrainerPicID PlayerGenderToFrontTrainerPicId(enum Gender playerGender);
void HandleSetPokedexFlag(enum NationalDexOrder nationalNum, u8 caseId, u32 personality);
void HandleSetPokedexFlagFromMon(struct Pokemon *mon, u32 caseId);
bool8 HasTwoFramesAnimation(u16 species);
@ -936,14 +957,14 @@ void DestroyMonSpritesGfxManager(u8 managerId);
u8 *MonSpritesGfxManager_GetSpritePtr(u8 managerId, u8 spriteNum);
u16 GetFormSpeciesId(u16 speciesId, u8 formId);
u8 GetFormIdFromFormSpeciesId(u16 formSpeciesId);
u32 GetFormChangeTargetSpecies(struct Pokemon *mon, enum FormChanges method, u32 arg);
u32 GetFormChangeTargetSpeciesBoxMon(struct BoxPokemon *boxMon, enum FormChanges method, u32 arg);
u32 GetFormChangeTargetSpecies_Internal(struct FormChangeContext ctx);
bool32 DoesSpeciesHaveFormChangeMethod(u16 species, enum FormChanges method);
u16 MonTryLearningNewMoveEvolution(struct Pokemon *mon, bool8 firstMove);
void RemoveIVIndexFromList(u8 *ivs, u8 selectedIv);
void TrySpecialOverworldEvo(void);
bool32 SpeciesHasGenderDifferences(u16 species);
bool32 TryFormChange(u32 monId, enum BattleSide side, enum FormChanges method);
bool32 TryFormChange(struct Pokemon *mon, enum FormChanges method);
bool32 TryBoxMonFormChange(struct BoxPokemon *boxMon, enum FormChanges method);
void TryToSetBattleFormChangeMoves(struct Pokemon *mon, enum FormChanges method);
u32 GetMonFriendshipScore(struct Pokemon *pokemon);
u32 GetMonAffectionHearts(struct Pokemon *pokemon);
@ -957,7 +978,7 @@ void HealPokemon(struct Pokemon *mon);
void HealBoxPokemon(struct BoxPokemon *boxMon);
void UpdateDaysPassedSinceFormChange(u16 days);
void TrySetDayLimitToFormChange(struct Pokemon *mon);
enum Type CheckDynamicMoveType(struct Pokemon *mon, enum Move move, u32 battler, enum MonState state);
enum Type CheckDynamicMoveType(struct Pokemon *mon, enum Move move, enum BattlerId battler, enum MonState state);
uq4_12_t GetDynamaxLevelHPMultiplier(u32 dynamaxLevel, bool32 inverseMultiplier);
u32 GetRegionalFormByRegion(u32 species, u32 region);
bool32 IsSpeciesForeignRegionalForm(u32 species, u32 currentRegion);
@ -969,6 +990,7 @@ void SavePlayerPartyMon(u32 index, struct Pokemon *mon);
bool32 IsSpeciesOfType(u32 species, enum Type type);
struct BoxPokemon *GetSelectedBoxMonFromPcOrParty(void);
u32 GiveScriptedMonToPlayer(struct Pokemon *mon, u8 slot);
void ChangePokemonNicknameWithCallback(void (*callback)(void));
// pokefirered
u16 GetFirstPartnerMove(u16 species);

View File

@ -9,7 +9,9 @@ extern const u16 gMonIconPalettes[][16];
// extern const u8 gMonIconPaletteIndices[];
const u8 *GetMonIconPtr(u16 speciesId, u32 personality);
const u8 *GetMonIconPtrIsEgg(u16 species, u32 personality, bool32 isEgg);
const u8 *GetMonIconTiles(u16 iconSpecies, bool32 extra);
const u8 *GetMonIconTilesIsEgg(u16 species, u32 personality, bool32 isEgg);
const u16 *GetValidMonIconPalettePtr(u16 speciesId);
void LoadMonIconPalettes(void);
void FreeMonIconPalettes(void);
@ -19,6 +21,7 @@ void FreeAndDestroyMonIconSprite(struct Sprite *);
u16 GetUnownLetterByPersonality(u32 personality);
void SpriteCB_MonIcon(struct Sprite *);
u8 CreateMonIcon(u16 species, SpriteCallback callback, s16 x, s16 y, u8 subpriority, u32 personality);
u8 CreateMonIconIsEgg(u16 species, void (*callback)(struct Sprite *), s16 x, s16 y, u8 subpriority, u32 personality, bool32 isEgg);
u8 UpdateMonIconFrame(struct Sprite *sprite);
void LoadMonIconPalette(u16 iconId);
void LoadMonIconPalettePersonality(u16 species, u32 personality);

View File

@ -11,7 +11,7 @@ extern const struct CompressedSpriteSheet gSpriteSheet_CategoryIcons;
extern const struct SpritePalette gSpritePal_CategoryIcons;
extern const struct SpriteTemplate gSpriteTemplate_CategoryIcons;
void ShowSelectMovePokemonSummaryScreen(struct Pokemon *, u8, u8, MainCallback, u16);
void ShowSelectMovePokemonSummaryScreen(struct Pokemon *mons, u8 monIndex, void (*callback)(void), u16 newMove);
u8 GetMoveSlotToReplace(void);
void SummaryScreen_SetUnknownTaskId(u8 a0);
void SummaryScreen_DestroyUnknownTask(void);

View File

@ -169,6 +169,7 @@ enum RandomTag
RNG_QUICK_DRAW,
RNG_QUICK_CLAW,
RNG_TRACE,
RNG_FOREWARN,
RNG_FICKLE_BEAM,
RNG_AI_ABILITY,
RNG_AI_SCORE_TIE_DOUBLES_MOVE,
@ -240,6 +241,7 @@ enum RandomTag
RNG_MAGNITUDE,
RNG_FISHING_BITE,
RNG_FISHING_GEN3_STICKY,
RNG_WILD_MON_TARGET,
RNG_TAUNT,
};

View File

@ -2400,7 +2400,6 @@ extern const u8 gText_BattleArenaGutsSymbol[];
extern const u8 gText_BattleFactoryKnowledgeSymbol[];
extern const u8 gText_BattlePikeLuckSymbol[];
extern const u8 gText_BattlePyramidBraveSymbol[];
extern const u8 gText_EmptyString7[];
extern const u8 gText_BattleTower3[];
extern const u8 gText_BattleDome2[];
extern const u8 gText_BattlePalace2[];

View File

@ -621,7 +621,7 @@ enum
struct QueuedAbilityEvent
{
u8 battlerId;
enum BattlerId battlerId;
enum Ability ability;
};
@ -638,14 +638,14 @@ enum { EXP_EVENT_NEW_EXP, EXP_EVENT_DELTA_EXP };
struct QueuedHPEvent
{
u32 battlerId:3;
enum BattlerId battlerId:3;
u32 type:1;
u32 address:28;
};
struct QueuedSubHitEvent
{
u32 battlerId:3;
enum BattlerId battlerId:3;
u32 checkBreak:1;
u32 breakSub:1;
u32 address:27;
@ -653,7 +653,7 @@ struct QueuedSubHitEvent
struct QueuedExpEvent
{
u32 battlerId:3;
enum BattlerId battlerId:3;
u32 type:1;
u32 address:28;
};
@ -665,7 +665,7 @@ struct QueuedMessageEvent
struct QueuedStatusEvent
{
u32 battlerId:3;
enum BattlerId battlerId:3;
u32 mask:29;
};
@ -1064,7 +1064,7 @@ void ClosePokemon(u32 sourceLine);
void RNGSeed_(u32 sourceLine, rng_value_t seed);
void AIFlags_(u32 sourceLine, u64 flags);
void BattlerAIFlags_(u32 sourceLine, u32 battler, u64 flags);
void BattlerAIFlags_(u32 sourceLine, enum BattlerId battler, u64 flags);
void AILogScores(u32 sourceLine);
void Gender_(u32 sourceLine, u32 gender);
void Nature_(u32 sourceLine, u32 nature);
@ -1098,18 +1098,14 @@ void Environment_(u32 sourceLine, u32 environment);
static inline bool8 IsMultibattleTest(void)
{
if (TESTING)
#if TESTING
{
if (((gBattleTypeFlags & BATTLE_MULTI_TEST) == BATTLE_MULTI_TEST)
|| ((gBattleTypeFlags & BATTLE_TWO_VS_ONE_TEST) == BATTLE_TWO_VS_ONE_TEST))
|| ((gBattleTypeFlags & BATTLE_TWO_VS_ONE_TEST) == BATTLE_TWO_VS_ONE_TEST))
return TRUE;
else
return FALSE;
}
else
{
return FALSE;
}
#endif
return FALSE;
}
// Created for easy use of EXPECT_MOVES, so the user can provide 1, 2, 3 or 4 moves for AI which can pass the test.

View File

@ -13,23 +13,23 @@ extern const bool8 gTestRunnerSkipIsFail;
enum Gimmick;
void TestRunner_Battle_RecordAbilityPopUp(u32 battlerId, enum Ability ability);
void TestRunner_Battle_RecordAbilityPopUp(enum BattlerId battlerId, enum Ability ability);
void TestRunner_Battle_RecordAnimation(u32 animType, u32 animId);
void TestRunner_Battle_RecordHP(u32 battlerId, u32 oldHP, u32 newHP);
void TestRunner_Battle_RecordSubHit(u32 battlerId, u32 damage, bool32 broke);
void TestRunner_Battle_RecordExp(u32 battlerId, u32 oldExp, u32 newExp);
void TestRunner_Battle_RecordHP(enum BattlerId battlerId, u32 oldHP, u32 newHP);
void TestRunner_Battle_RecordSubHit(enum BattlerId battlerId, u32 damage, bool32 broke);
void TestRunner_Battle_RecordExp(enum BattlerId battlerId, u32 oldExp, u32 newExp);
void TestRunner_Battle_RecordMessage(const u8 *message);
void TestRunner_Battle_RecordStatus1(u32 battlerId, u32 status1);
void TestRunner_Battle_RecordStatus1(enum BattlerId battlerId, u32 status1);
void TestRunner_Battle_RecordCatchChance(u32 catchChance);
void TestRunner_Battle_AfterLastTurn(void);
void TestRunner_Battle_CheckChosenMove(u32 battlerId, enum Move moveId, u32 target, enum Gimmick gimmick);
void TestRunner_Battle_CheckSwitch(u32 battlerId, u32 partyIndex);
void TestRunner_Battle_CheckAiMoveScores(u32 battlerId);
void TestRunner_Battle_AISetScore(const char *file, u32 line, u32 battlerId, u32 moveIndex, s32 score);
void TestRunner_Battle_AIAdjustScore(const char *file, u32 line, u32 battlerId, u32 moveIndex, s32 score);
void TestRunner_Battle_CheckChosenMove(enum BattlerId battlerId, enum Move moveId, u32 target, enum Gimmick gimmick);
void TestRunner_Battle_CheckSwitch(enum BattlerId battlerId, u32 partyIndex);
void TestRunner_Battle_CheckAiMoveScores(enum BattlerId battlerId);
void TestRunner_Battle_AISetScore(const char *file, u32 line, enum BattlerId battlerId, u32 moveIndex, s32 score);
void TestRunner_Battle_AIAdjustScore(const char *file, u32 line, enum BattlerId battlerId, u32 moveIndex, s32 score);
void TestRunner_CheckMemory(void);
void TestRunner_Battle_CheckBattleRecordActionType(u32 battlerId, u32 recordIndex, u32 actionType);
void TestRunner_Battle_CheckBattleRecordActionType(enum BattlerId battlerId, u32 recordIndex, u32 actionType);
u32 TestRunner_Battle_GetForcedAbility(enum BattleTrainer trainer, u32 partyIndex);
u32 TestRunner_Battle_GetChosenGimmick(enum BattleTrainer trainer, u32 partyIndex);

View File

@ -11,16 +11,16 @@ struct MessageStatus
};
void SetTrainerSlideMessage(enum DifficultyLevel difficulty, u32 trainerId, u32 slideId);
enum TrainerSlideTargets ShouldDoTrainerSlide(u32 battler, enum TrainerSlideType slideId);
void TryInitializeFirstSTABMoveTrainerSlide(u32 battlerDef, u32 battlerAtk, enum Type moveType);
enum TrainerSlideTargets ShouldDoTrainerSlide(enum BattlerId battler, enum TrainerSlideType slideId);
void TryInitializeFirstSTABMoveTrainerSlide(enum BattlerId battlerDef, enum BattlerId battlerAtk, enum Type moveType);
void TryInitializeTrainerSlidePlayerLandsFirstCriticalHit(u32 target);
void TryInitializeTrainerSlideEnemyLandsFirstCriticalHit(u32 target);
void TryInitializeTrainerSlidePlayerLandsFirstSuperEffectiveHit(u32 target);
void TryInitializeTrainerSlideEnemyMonUnaffected(u32 target);
bool32 IsTrainerSlideInitialized(u32 battler, enum TrainerSlideType slideId);
bool32 IsTrainerSlidePlayed(u32 battler, enum TrainerSlideType slideId);
void InitalizeTrainerSlide(u32 battler, enum TrainerSlideType slideId);
void MarkTrainerSlideAsPlayed(u32 battler, enum TrainerSlideType slideId);
void MarkInitializedTrainerSlidesAsPlayed(u32 battler, enum TrainerSlideType slideId);
bool32 IsTrainerSlideInitialized(enum BattlerId battler, enum TrainerSlideType slideId);
bool32 IsTrainerSlidePlayed(enum BattlerId battler, enum TrainerSlideType slideId);
void InitalizeTrainerSlide(enum BattlerId battler, enum TrainerSlideType slideId);
void MarkTrainerSlideAsPlayed(enum BattlerId battler, enum TrainerSlideType slideId);
void MarkInitializedTrainerSlidesAsPlayed(enum BattlerId battler, enum TrainerSlideType slideId);
#endif // GUARD_TRAINER_SLIDE_H

View File

@ -1,7 +1,7 @@
#ifndef GUARD_TYPE_ICONS_H
#define GUARD_TYPE_ICONS_H
void LoadTypeIcons(u32);
void LoadTypeIcons(enum BattlerId battler);
#define TYPE_ICON_TAG 0x2720
#define TYPE_ICON_TAG_2 0x2721

View File

@ -38,14 +38,15 @@
#define AI_ACTION_WATCH (1 << 2)
#define AI_ACTION_DO_NOT_ATTACK (1 << 3)
static u32 ChooseMoveOrAction(u32 battler);
static u32 ChooseMoveOrAction_Singles(u32 battler);
static u32 ChooseMoveOrAction_Doubles(u32 battler);
static inline void BattleAI_DoAIProcessing(struct AiThinkingStruct *aiThink, u32 battlerAtk, u32 battlerDef);
static inline void BattleAI_DoAIProcessing_PredictedSwitchin(struct AiThinkingStruct *aiThink, struct AiLogicData *aiData, u32 battlerAtk, u32 battlerDef);
static u32 ChooseMoveOrAction(enum BattlerId battler);
static u32 ChooseMoveOrAction_Singles(enum BattlerId battler);
static u32 ChooseMoveOrAction_Doubles(enum BattlerId battler);
static inline void BattleAI_DoAIProcessing(struct AiThinkingStruct *aiThink, enum BattlerId battlerAtk, enum BattlerId battlerDef);
static inline void BattleAI_DoAIProcessing_PredictedSwitchin(struct AiThinkingStruct *aiThink, struct AiLogicData *aiData, enum BattlerId battlerAtk, enum BattlerId battlerDef);
static bool32 IsPinchBerryItemEffect(enum HoldEffect holdEffect);
static bool32 DoesAbilityBenefitFromSunOrRain(u32 battler, enum Ability ability, u32 weather);
static void AI_CompareDamagingMoves(u32 battlerAtk, u32 battlerDef);
static bool32 DoesAbilityBenefitFromSunOrRain(enum BattlerId battler, enum Ability ability, u32 weather);
static void AI_CompareDamagingMoves(enum BattlerId battlerAtk, enum BattlerId battlerDef);
static u32 GetWindAbilityScore(enum BattlerId battlerAtk, enum BattlerId battlerDef, struct AiLogicData *aiData);
// ewram
EWRAM_DATA const u8 *gAIScriptPtr = NULL; // Still used in contests
@ -53,25 +54,25 @@ EWRAM_DATA AiScoreFunc sDynamicAiFunc = NULL;
EWRAM_DATA AiSwitchFunc gDynamicAiSwitchFunc = NULL;
// const rom data
static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, enum Move move, s32 score);
static s32 AI_TryToFaint(u32 battlerAtk, u32 battlerDef, enum Move move, s32 score);
static s32 AI_CheckViability(u32 battlerAtk, u32 battlerDef, enum Move move, s32 score);
static s32 AI_ForceSetupFirstTurn(u32 battlerAtk, u32 battlerDef, enum Move move, s32 score);
static s32 AI_Risky(u32 battlerAtk, u32 battlerDef, enum Move move, s32 score);
static s32 AI_TryTo2HKO(u32 battlerAtk, u32 battlerDef, enum Move move, s32 score);
static s32 AI_AttacksPartner(u32 battlerAtk, u32 battlerDef, enum Move move, s32 score);
static s32 AI_PreferBatonPass(u32 battlerAtk, u32 battlerDef, enum Move move, s32 score);
static s32 AI_HPAware(u32 battlerAtk, u32 battlerDef, enum Move move, s32 score);
static s32 AI_Roaming(u32 battlerAtk, u32 battlerDef, enum Move move, s32 score);
static s32 AI_Safari(u32 battlerAtk, u32 battlerDef, enum Move move, s32 score);
static s32 AI_FirstBattle(u32 battlerAtk, u32 battlerDef, enum Move move, s32 score);
static s32 AI_DoubleBattle(u32 battlerAtk, u32 battlerDef, enum Move move, s32 score);
static s32 AI_PowerfulStatus(u32 battlerAtk, u32 battlerDef, enum Move move, s32 score);
static s32 AI_DynamicFunc(u32 battlerAtk, u32 battlerDef, enum Move move, s32 score);
static s32 AI_PredictSwitch(u32 battlerAtk, u32 battlerDef, enum Move move, s32 score);
static s32 AI_CheckPpStall(u32 battlerAtk, u32 battlerDef, enum Move move, s32 score);
static s32 AI_CheckBadMove(enum BattlerId battlerAtk, enum BattlerId battlerDef, enum Move move, s32 score);
static s32 AI_TryToFaint(enum BattlerId battlerAtk, enum BattlerId battlerDef, enum Move move, s32 score);
static s32 AI_CheckViability(enum BattlerId battlerAtk, enum BattlerId battlerDef, enum Move move, s32 score);
static s32 AI_ForceSetupFirstTurn(enum BattlerId battlerAtk, enum BattlerId battlerDef, enum Move move, s32 score);
static s32 AI_Risky(enum BattlerId battlerAtk, enum BattlerId battlerDef, enum Move move, s32 score);
static s32 AI_TryTo2HKO(enum BattlerId battlerAtk, enum BattlerId battlerDef, enum Move move, s32 score);
static s32 AI_AttacksPartner(enum BattlerId battlerAtk, enum BattlerId battlerDef, enum Move move, s32 score);
static s32 AI_PreferBatonPass(enum BattlerId battlerAtk, enum BattlerId battlerDef, enum Move move, s32 score);
static s32 AI_HPAware(enum BattlerId battlerAtk, enum BattlerId battlerDef, enum Move move, s32 score);
static s32 AI_Roaming(enum BattlerId battlerAtk, enum BattlerId battlerDef, enum Move move, s32 score);
static s32 AI_Safari(enum BattlerId battlerAtk, enum BattlerId battlerDef, enum Move move, s32 score);
static s32 AI_FirstBattle(enum BattlerId battlerAtk, enum BattlerId battlerDef, enum Move move, s32 score);
static s32 AI_DoubleBattle(enum BattlerId battlerAtk, enum BattlerId battlerDef, enum Move move, s32 score);
static s32 AI_PowerfulStatus(enum BattlerId battlerAtk, enum BattlerId battlerDef, enum Move move, s32 score);
static s32 AI_DynamicFunc(enum BattlerId battlerAtk, enum BattlerId battlerDef, enum Move move, s32 score);
static s32 AI_PredictSwitch(enum BattlerId battlerAtk, enum BattlerId battlerDef, enum Move move, s32 score);
static s32 AI_CheckPpStall(enum BattlerId battlerAtk, enum BattlerId battlerDef, enum Move move, s32 score);
static s32 (*const sBattleAiFuncTable[])(u32, u32, enum Move, s32) =
static s32 (*const sBattleAiFuncTable[])(enum BattlerId, enum BattlerId, enum Move, s32) =
{
[0] = AI_CheckBadMove, // AI_FLAG_CHECK_BAD_MOVE
[1] = AI_TryToFaint, // AI_FLAG_TRY_TO_FAINT
@ -143,7 +144,7 @@ static s32 (*const sBattleAiFuncTable[])(u32, u32, enum Move, s32) =
void BattleAI_SetupItems(void)
{
u8 *data = (u8 *)gBattleHistory;
const u16 *items = GetTrainerItemsFromId(TRAINER_BATTLE_PARAM.opponentA);
const enum Item *items = GetTrainerItemsFromId(TRAINER_BATTLE_PARAM.opponentA);
for (u32 i = 0; i < sizeof(struct BattleHistory); i++)
data[i] = 0;
@ -189,7 +190,7 @@ static u64 GetWildAiFlags(void)
return flags;
}
static u64 GetAiFlags(u16 trainerId, u32 battler)
static u64 GetAiFlags(u16 trainerId, enum BattlerId battler)
{
u64 flags = 0;
@ -207,10 +208,8 @@ static u64 GetAiFlags(u16 trainerId, u32 battler)
flags = AI_FLAG_SAFARI;
else if (gBattleTypeFlags & BATTLE_TYPE_ROAMER)
flags = AI_FLAG_ROAMING;
else if (gBattleTypeFlags & BATTLE_TYPE_WILD_SCRIPTED)
flags = AI_FLAG_CHECK_BAD_MOVE;
// else if (gBattleTypeFlags & BATTLE_TYPE_FIRST_BATTLE)
// flags = AI_FLAG_FIRST_BATTLE;
else if (gBattleTypeFlags & BATTLE_TYPE_FIRST_BATTLE)
flags = AI_FLAG_FIRST_BATTLE;
else if (gBattleTypeFlags & BATTLE_TYPE_FACTORY)
flags = GetAiScriptsInBattleFactory();
else if (gBattleTypeFlags & (BATTLE_TYPE_FRONTIER | BATTLE_TYPE_EREADER_TRAINER | BATTLE_TYPE_TRAINER_HILL | BATTLE_TYPE_SECRET_BASE))
@ -241,22 +240,22 @@ static u64 GetAiFlags(u16 trainerId, u32 battler)
void BattleAI_SetupFlags(void)
{
if (IsAiVsAiBattle())
gAiThinkingStruct->aiFlags[B_POSITION_PLAYER_LEFT] = GetAiFlags(gPartnerTrainerId, B_POSITION_PLAYER_LEFT);
gAiThinkingStruct->aiFlags[B_BATTLER_0] = GetAiFlags(gPartnerTrainerId, B_BATTLER_0);
else
gAiThinkingStruct->aiFlags[B_POSITION_PLAYER_LEFT] = 0; // player has no AI
gAiThinkingStruct->aiFlags[B_BATTLER_0] = 0; // player has no AI
if (DEBUG_OVERWORLD_MENU && gIsDebugBattle)
{
gAiThinkingStruct->aiFlags[B_POSITION_OPPONENT_LEFT] = gDebugAIFlags;
gAiThinkingStruct->aiFlags[B_POSITION_OPPONENT_RIGHT] = gDebugAIFlags;
gAiThinkingStruct->aiFlags[B_BATTLER_1] = gDebugAIFlags;
gAiThinkingStruct->aiFlags[B_BATTLER_3] = gDebugAIFlags;
return;
}
if (IsWildMonSmart() && !(gBattleTypeFlags & (BATTLE_TYPE_LINK | BATTLE_TYPE_TRAINER)))
{
// smart wild AI
gAiThinkingStruct->aiFlags[B_POSITION_OPPONENT_LEFT] = GetAiFlags(0xFFFF, B_POSITION_OPPONENT_LEFT);
gAiThinkingStruct->aiFlags[B_POSITION_OPPONENT_RIGHT] = GetAiFlags(0xFFFF, B_POSITION_OPPONENT_RIGHT);
gAiThinkingStruct->aiFlags[B_BATTLER_1] = GetAiFlags(0xFFFF, B_BATTLER_1);
gAiThinkingStruct->aiFlags[B_BATTLER_3] = GetAiFlags(0xFFFF, B_BATTLER_3);
// The check is here because wild natural enemies are not symmetrical.
if (B_WILD_NATURAL_ENEMIES && IsDoubleBattle())
@ -264,38 +263,38 @@ void BattleAI_SetupFlags(void)
u32 speciesLeft = GetMonData(&gEnemyParty[0], MON_DATA_SPECIES);
u32 speciesRight = GetMonData(&gEnemyParty[1], MON_DATA_SPECIES);
if (IsNaturalEnemy(speciesLeft, speciesRight))
gAiThinkingStruct->aiFlags[B_POSITION_OPPONENT_LEFT] |= AI_FLAG_ATTACKS_PARTNER;
gAiThinkingStruct->aiFlags[B_BATTLER_1] |= AI_FLAG_ATTACKS_PARTNER;
if (IsNaturalEnemy(speciesRight, speciesLeft))
gAiThinkingStruct->aiFlags[B_POSITION_OPPONENT_RIGHT] |= AI_FLAG_ATTACKS_PARTNER;
gAiThinkingStruct->aiFlags[B_BATTLER_3] |= AI_FLAG_ATTACKS_PARTNER;
}
}
else
{
gAiThinkingStruct->aiFlags[B_POSITION_OPPONENT_LEFT] = GetAiFlags(TRAINER_BATTLE_PARAM.opponentA, B_POSITION_OPPONENT_LEFT);
gAiThinkingStruct->aiFlags[B_BATTLER_1] = GetAiFlags(TRAINER_BATTLE_PARAM.opponentA, B_BATTLER_1);
if ((TRAINER_BATTLE_PARAM.opponentB != 0) && (TRAINER_BATTLE_PARAM.opponentB != 0xFFFF))
gAiThinkingStruct->aiFlags[B_POSITION_OPPONENT_RIGHT] = GetAiFlags(TRAINER_BATTLE_PARAM.opponentB, B_POSITION_OPPONENT_RIGHT);
gAiThinkingStruct->aiFlags[B_BATTLER_3] = GetAiFlags(TRAINER_BATTLE_PARAM.opponentB, B_BATTLER_3);
else
gAiThinkingStruct->aiFlags[B_POSITION_OPPONENT_RIGHT] = gAiThinkingStruct->aiFlags[B_POSITION_OPPONENT_LEFT];
gAiThinkingStruct->aiFlags[B_BATTLER_3] = gAiThinkingStruct->aiFlags[B_BATTLER_1];
}
if (gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER)
{
gAiThinkingStruct->aiFlags[B_POSITION_PLAYER_RIGHT] = GetAiFlags(gPartnerTrainerId, B_POSITION_PLAYER_RIGHT);
gAiThinkingStruct->aiFlags[B_BATTLER_2] = GetAiFlags(gPartnerTrainerId, B_BATTLER_1);
}
else if (IsDoubleBattle() && IsAiVsAiBattle())
{
gAiThinkingStruct->aiFlags[B_POSITION_PLAYER_RIGHT] = gAiThinkingStruct->aiFlags[B_POSITION_PLAYER_LEFT];
gAiThinkingStruct->aiFlags[B_BATTLER_2] = gAiThinkingStruct->aiFlags[B_BATTLER_0];
}
else // Assign ai flags for player for prediction
{
u64 aiFlags = GetAiFlags(TRAINER_BATTLE_PARAM.opponentA, B_POSITION_OPPONENT_LEFT)
| GetAiFlags(TRAINER_BATTLE_PARAM.opponentB, B_POSITION_OPPONENT_RIGHT);
gAiThinkingStruct->aiFlags[B_POSITION_PLAYER_RIGHT] = aiFlags;
gAiThinkingStruct->aiFlags[B_POSITION_PLAYER_LEFT] = aiFlags;
u64 aiFlags = GetAiFlags(TRAINER_BATTLE_PARAM.opponentA, B_BATTLER_1)
| GetAiFlags(TRAINER_BATTLE_PARAM.opponentB, B_BATTLER_3);
gAiThinkingStruct->aiFlags[B_BATTLER_2] = aiFlags;
gAiThinkingStruct->aiFlags[B_BATTLER_0] = aiFlags;
}
}
void BattleAI_SetupAIData(u8 defaultScoreMoves, u32 battler)
void BattleAI_SetupAIData(u8 defaultScoreMoves, enum BattlerId battler)
{
u32 moveLimitations;
u64 flags[MAX_BATTLERS_COUNT];
@ -341,7 +340,7 @@ bool32 BattlerChooseNonMoveAction(void)
return FALSE;
}
void SetupAIPredictionData(u32 battler, enum SwitchType switchType)
void SetupAIPredictionData(enum BattlerId battler, enum SwitchType switchType)
{
s32 opposingBattler = GetOppositeBattler(battler);
gAiLogicData->aiPredictionInProgress = TRUE;
@ -361,7 +360,7 @@ void SetupAIPredictionData(u32 battler, enum SwitchType switchType)
gAiLogicData->aiPredictionInProgress = FALSE;
}
void ComputeBattlerDecisions(u32 battler)
void ComputeBattlerDecisions(enum BattlerId battler)
{
bool32 isAiBattler = (gBattleTypeFlags & BATTLE_TYPE_HAS_AI || IsWildMonSmart()) && (BattlerHasAi(battler) && !(gBattleTypeFlags & BATTLE_TYPE_PALACE));
if (isAiBattler || CanAiPredictMove(battler))
@ -394,7 +393,7 @@ void ComputeBattlerDecisions(u32 battler)
}
}
void ReconsiderGimmick(u32 battlerAtk, u32 battlerDef, enum Move move)
void ReconsiderGimmick(enum BattlerId battlerAtk, enum BattlerId battlerDef, enum Move move)
{
// After choosing a move for battlerAtk assuming that a gimmick will be used, reconsider whether the gimmick is necessary.
@ -405,23 +404,23 @@ void ReconsiderGimmick(u32 battlerAtk, u32 battlerDef, enum Move move)
SetAIUsingGimmick(battlerAtk, NO_GIMMICK);
}
static u32 ChooseMoveOrAction(u32 battler)
static u32 ChooseMoveOrAction(enum BattlerId battler)
{
if (IsDoubleBattle())
return ChooseMoveOrAction_Doubles(battler);
return ChooseMoveOrAction_Singles(battler);
}
static void SetupRandomRollsForAIMoveSelection(u32 battler)
static void SetupRandomRollsForAIMoveSelection(enum BattlerId battler)
{
gAiLogicData->shouldConsiderExplosion = RandomPercentage(RNG_AI_CONSIDER_EXPLOSION, GetAIExplosionChanceFromHP(gAiLogicData->hpPercents[battler]));
gAiLogicData->shouldConsiderFinalGambit = RandomPercentage(RNG_AI_FINAL_GAMBIT, FINAL_GAMBIT_CHANCE);
}
void AI_TrySwitchOrUseItem(u32 battler)
void AI_TrySwitchOrUseItem(enum BattlerId battler)
{
struct Pokemon *party;
u32 battlerIn1, battlerIn2;
enum BattlerId battlerIn1, battlerIn2;
s32 firstId;
s32 lastId; // + 1
party = GetBattlerParty(battler);
@ -470,7 +469,7 @@ void AI_TrySwitchOrUseItem(u32 battler)
BtlController_EmitTwoReturnValues(battler, B_COMM_TO_ENGINE, B_ACTION_USE_MOVE, BATTLE_OPPOSITE(battler) << 8);
}
u32 BattleAI_ChooseMoveIndex(u32 battler)
u32 BattleAI_ChooseMoveIndex(enum BattlerId battler)
{
u32 chosenMoveIndex;
@ -497,7 +496,7 @@ u32 BattleAI_ChooseMoveIndex(u32 battler)
static void CopyBattlerDataToAIParty(u32 bPosition, enum BattleSide side)
{
u32 battler = GetBattlerAtPosition(bPosition);
enum BattlerId battler = GetBattlerAtPosition(bPosition);
struct AiPartyMon *aiMon = &gAiPartyData->mons[side][gBattlerPartyIndexes[battler]];
struct BattlePokemon *bMon = &gBattleMons[battler];
@ -555,7 +554,7 @@ void Ai_InitPartyStruct(void)
}
}
void Ai_UpdateSwitchInData(u32 battler)
void Ai_UpdateSwitchInData(enum BattlerId battler)
{
enum BattleSide side = GetBattlerSide(battler);
struct AiPartyMon *aiMon = &gAiPartyData->mons[side][gBattlerPartyIndexes[battler]];
@ -584,7 +583,7 @@ void Ai_UpdateSwitchInData(u32 battler)
}
}
void Ai_UpdateFaintData(u32 battler)
void Ai_UpdateFaintData(enum BattlerId battler)
{
struct AiPartyMon *aiMon = &gAiPartyData->mons[GetBattlerSide(battler)][gBattlerPartyIndexes[battler]];
ClearBattlerMoveHistory(battler);
@ -593,7 +592,7 @@ void Ai_UpdateFaintData(u32 battler)
aiMon->isFainted = TRUE;
}
void RecordMovesBasedOnStab(u32 battler)
void RecordMovesBasedOnStab(enum BattlerId battler)
{
for (u32 moveIndex = 0; moveIndex < MAX_MON_MOVES; moveIndex++)
{
@ -603,7 +602,7 @@ void RecordMovesBasedOnStab(u32 battler)
}
}
void RecordStatusMoves(u32 battler)
void RecordStatusMoves(enum BattlerId battler)
{
for (u32 moveIndex = 0; moveIndex < MAX_MON_MOVES; moveIndex++)
{
@ -613,10 +612,10 @@ void RecordStatusMoves(u32 battler)
}
}
void SetBattlerAiData(u32 battler, struct AiLogicData *aiData)
void SetBattlerAiData(enum BattlerId battler, struct AiLogicData *aiData)
{
enum Ability ability;
u32 holdEffect;
enum HoldEffect holdEffect;
ability = aiData->abilities[battler] = AI_DecideKnownAbilityForTurn(battler);
aiData->items[battler] = gBattleMons[battler].item;
@ -635,7 +634,7 @@ void SetBattlerAiData(u32 battler, struct AiLogicData *aiData)
}
#define BYPASSES_ACCURACY_CALC 101 // 101 indicates for ai that the move will always hit
static u32 Ai_SetMoveAccuracy(struct AiLogicData *aiData, u32 battlerAtk, u32 battlerDef, enum Move move)
static u32 Ai_SetMoveAccuracy(struct AiLogicData *aiData, enum BattlerId battlerAtk, enum BattlerId battlerDef, enum Move move)
{
u32 accuracy;
enum Ability abilityAtk = aiData->abilities[battlerAtk];
@ -656,7 +655,7 @@ static u32 Ai_SetMoveAccuracy(struct AiLogicData *aiData, u32 battlerAtk, u32 ba
}
#undef BYPASSES_ACCURACY_CALC
void CalcBattlerAiMovesData(struct AiLogicData *aiData, u32 battlerAtk, u32 battlerDef, u32 weather, u32 fieldStatus)
void CalcBattlerAiMovesData(struct AiLogicData *aiData, enum BattlerId battlerAtk, enum BattlerId battlerDef, u32 weather, u32 fieldStatus)
{
enum Move move;
enum Move *moves = GetMovesArray(battlerAtk);
@ -680,13 +679,13 @@ void CalcBattlerAiMovesData(struct AiLogicData *aiData, u32 battlerAtk, u32 batt
}
}
static void SetBattlerAiMovesData(struct AiLogicData *aiData, u32 battlerAtk, u32 battlersCount, u32 weather)
static void SetBattlerAiMovesData(struct AiLogicData *aiData, enum BattlerId battlerAtk, u32 battlersCount, u32 weather)
{
SaveBattlerData(battlerAtk);
SetBattlerData(battlerAtk);
// Simulate dmg for both ai controlled mons and for player controlled mons.
for (u32 battlerDef = 0; battlerDef < battlersCount; battlerDef++)
for (enum BattlerId battlerDef = 0; battlerDef < battlersCount; battlerDef++)
{
if (battlerAtk == battlerDef || !IsBattlerAlive(battlerDef))
continue;
@ -720,7 +719,7 @@ void SetAiLogicDataForTurn(struct AiLogicData *aiData)
gAiLogicData->aiCalcInProgress = TRUE;
if (DEBUG_AI_DELAY_TIMER)
CycleCountStart();
for (u32 battlerAtk = 0; battlerAtk < battlersCount; battlerAtk++)
for (enum BattlerId battlerAtk = 0; battlerAtk < battlersCount; battlerAtk++)
{
if (!IsBattlerAlive(battlerAtk))
continue;
@ -728,7 +727,7 @@ void SetAiLogicDataForTurn(struct AiLogicData *aiData)
SetBattlerAiData(battlerAtk, aiData);
}
for (u32 battlerAtk = 0; battlerAtk < battlersCount; battlerAtk++)
for (enum BattlerId battlerAtk = 0; battlerAtk < battlersCount; battlerAtk++)
{
if (!IsBattlerAlive(battlerAtk))
continue;
@ -736,7 +735,7 @@ void SetAiLogicDataForTurn(struct AiLogicData *aiData)
SetBattlerAiMovesData(aiData, battlerAtk, battlersCount, weather);
}
for (u32 battlerAtk = 0; battlerAtk < battlersCount; battlerAtk++)
for (enum BattlerId battlerAtk = 0; battlerAtk < battlersCount; battlerAtk++)
{
// Prediction limited to player side but can be expanded to read partners move in the future
if (!IsOnPlayerSide(battlerAtk) || !CanAiPredictMove(battlerAtk))
@ -755,15 +754,15 @@ void SetAiLogicDataForTurn(struct AiLogicData *aiData)
gAiLogicData->aiCalcInProgress = FALSE;
}
u32 GetPartyMonAbility(struct Pokemon *mon)
enum Ability GetPartyMonAbility(struct Pokemon *mon)
{
// Doesn't have any special handling yet
// Doesn't have any special handling yet
u32 species = GetMonData(mon, MON_DATA_SPECIES);
enum Ability ability = GetSpeciesAbility(species, GetMonData(mon, MON_DATA_ABILITY_NUM));
return ability;
}
static u32 PpStallReduction(enum Move move, u32 battlerAtk)
static u32 PpStallReduction(enum Move move, enum BattlerId battlerAtk)
{
if (move == MOVE_NONE)
return 0;
@ -802,13 +801,13 @@ static u32 PpStallReduction(enum Move move, u32 battlerAtk)
return returnValue;
}
static u32 ChooseMoveOrAction_Singles(u32 battler)
static u32 ChooseMoveOrAction_Singles(enum BattlerId battler)
{
u8 currentMoveArray[MAX_MON_MOVES];
u8 consideredMoveArray[MAX_MON_MOVES];
u32 numOfBestMoves;
u64 flags = gAiThinkingStruct->aiFlags[battler];
u32 opposingBattler = GetOppositeBattler(battler);
enum BattlerId opposingBattler = GetOppositeBattler(battler);
gAiThinkingStruct->aiLogicId = 0;
gAiThinkingStruct->movesetIndex = 0;
@ -864,7 +863,7 @@ static u32 ChooseMoveOrAction_Singles(u32 battler)
return consideredMoveArray[RandomUniform(RNG_AI_SCORE_TIE_SINGLES, 0, numOfBestMoves - 1)];
}
static u32 ChooseMoveOrAction_Doubles(u32 battler)
static u32 ChooseMoveOrAction_Doubles(enum BattlerId battler)
{
u64 flags;
s32 bestMovePointsForTarget[MAX_BATTLERS_COUNT];
@ -876,7 +875,7 @@ static u32 ChooseMoveOrAction_Doubles(u32 battler)
u32 mostViableMovesNo;
s32 mostMovePoints;
for (u32 battlerIndex = 0; battlerIndex < MAX_BATTLERS_COUNT; battlerIndex++)
for (enum BattlerId battlerIndex = 0; battlerIndex < MAX_BATTLERS_COUNT; battlerIndex++)
{
if (battlerIndex == battler || gBattleMons[battlerIndex].hp == 0)
{
@ -961,7 +960,7 @@ static u32 ChooseMoveOrAction_Doubles(u32 battler)
mostViableTargetsArray[0] = 0;
mostViableTargetsNo = 1;
for (u32 battlerIndex = 1; battlerIndex < MAX_BATTLERS_COUNT; battlerIndex++)
for (enum BattlerId battlerIndex = 1; battlerIndex < MAX_BATTLERS_COUNT; battlerIndex++)
{
if (mostMovePoints == bestMovePointsForTarget[battlerIndex])
{
@ -986,7 +985,7 @@ static u32 ChooseMoveOrAction_Doubles(u32 battler)
return actionOrMoveIndex[gBattlerTarget];
}
static inline bool32 ShouldConsiderMoveForBattler(u32 battlerAi, u32 battlerDef, enum Move move)
static inline bool32 ShouldConsiderMoveForBattler(enum BattlerId battlerAi, enum BattlerId battlerDef, enum Move move)
{
if (battlerAi == BATTLE_PARTNER(battlerDef))
{
@ -997,7 +996,7 @@ static inline bool32 ShouldConsiderMoveForBattler(u32 battlerAi, u32 battlerDef,
return TRUE;
}
static inline void BattleAI_DoAIProcessing(struct AiThinkingStruct *aiThink, u32 battlerAtk, u32 battlerDef)
static inline void BattleAI_DoAIProcessing(struct AiThinkingStruct *aiThink, enum BattlerId battlerAtk, enum BattlerId battlerDef)
{
do
{
@ -1032,7 +1031,7 @@ static inline void BattleAI_DoAIProcessing(struct AiThinkingStruct *aiThink, u32
aiThink->movesetIndex = 0;
}
void BattleAI_DoAIProcessing_PredictedSwitchin(struct AiThinkingStruct *aiThink, struct AiLogicData *aiData, u32 battlerAtk, u32 battlerDef)
void BattleAI_DoAIProcessing_PredictedSwitchin(struct AiThinkingStruct *aiThink, struct AiLogicData *aiData, enum BattlerId battlerAtk, enum BattlerId battlerDef)
{
struct BattlePokemon switchoutCandidate = gBattleMons[battlerDef];
struct SimulatedDamage simulatedDamageSwitchout[MAX_MON_MOVES];
@ -1145,14 +1144,14 @@ void BattleAI_DoAIProcessing_PredictedSwitchin(struct AiThinkingStruct *aiThink,
// AI Score Functions
// AI_FLAG_CHECK_BAD_MOVE - decreases move scores
static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, enum Move move, s32 score)
static s32 AI_CheckBadMove(enum BattlerId battlerAtk, enum BattlerId battlerDef, enum Move move, s32 score)
{
if (IsTargetingPartner(battlerAtk, battlerDef))
return score;
// move data
enum BattleMoveEffects moveEffect = GetMoveEffect(move);
u32 nonVolatileStatus = GetMoveNonVolatileStatus(move);
enum MoveEffect nonVolatileStatus = GetMoveNonVolatileStatus(move);
enum Type moveType;
enum MoveTarget moveTarget = AI_GetBattlerMoveTargetType(battlerAtk, move);
struct AiLogicData *aiData = gAiLogicData;
@ -1170,18 +1169,28 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, enum Move move, s32 s
SetTypeBeforeUsingMove(move, battlerAtk);
moveType = GetBattleMoveType(move);
if (gBattleStruct->battlerState[battlerDef].commandingDondozo)
RETURN_SCORE_MINUS(20);
if (IsPowderMove(move) && !IsAffectedByPowderMove(battlerDef, aiData->abilities[battlerDef], aiData->holdEffects[battlerDef]))
RETURN_SCORE_MINUS(10);
if (!BreaksThroughSemiInvulnerablity(battlerAtk, battlerDef, aiData->abilities[battlerAtk], aiData->abilities[battlerDef], move)
&& moveEffect != EFFECT_SEMI_INVULNERABLE && AI_IsFaster(battlerAtk, battlerDef, move, predictedMoveSpeedCheck, CONSIDER_PRIORITY))
&& moveEffect != EFFECT_SEMI_INVULNERABLE && AI_IsFaster(battlerAtk, battlerDef, move, predictedMoveSpeedCheck, CONSIDER_PRIORITY)
&& abilityAtk != ABILITY_NO_GUARD && abilityDef != ABILITY_NO_GUARD)
RETURN_SCORE_MINUS(10);
if (IsTwoTurnNotSemiInvulnerableMove(battlerAtk, move) && CanTargetFaintAi(battlerDef, battlerAtk))
RETURN_SCORE_MINUS(10);
if (CanTargetFaintAi(battlerDef, battlerAtk))
{
if (IsTwoTurnNotSemiInvulnerableMove(battlerAtk, move))
RETURN_SCORE_MINUS(10);
if (gBattleStruct->battlerState[battlerDef].commandingDondozo)
RETURN_SCORE_MINUS(20);
if (moveEffect == EFFECT_SEMI_INVULNERABLE && aiData->holdEffects[battlerAtk] != HOLD_EFFECT_POWER_HERB)
{
if (abilityAtk == ABILITY_NO_GUARD || abilityDef == ABILITY_NO_GUARD)
RETURN_SCORE_MINUS(10);
}
}
// Don't setup into expected Focus Punch.
if (GetMoveCategory(move) == DAMAGE_CATEGORY_STATUS
@ -1196,7 +1205,7 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, enum Move move, s32 s
// Don't use anything but super effective thawing moves if target is frozen if any other attack available
if (((GetMoveType(move) == TYPE_FIRE && GetMovePower(move) != 0) || CanBurnHitThaw(move)) && effectiveness < UQ_4_12(2.0) && (gBattleMons[battlerDef].status1 & STATUS1_ICY_ANY))
{
u32 aiMove;
enum Move aiMove;
for (u32 moveIndex = 0; moveIndex < MAX_MON_MOVES; moveIndex++)
{
aiMove = gBattleMons[battlerAtk].moves[moveIndex];
@ -1797,10 +1806,6 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, enum Move move, s32 s
|| !(weather & (B_WEATHER_ICY_ANY)))
ADJUST_SCORE(-10);
break;
case EFFECT_SHEER_COLD:
if (GetConfig(CONFIG_SHEER_COLD_IMMUNITY) >= GEN_7 && IS_BATTLER_OF_TYPE(battlerDef, TYPE_ICE))
RETURN_SCORE_MINUS(20);
// fallthrough
case EFFECT_OHKO:
if (!ShouldTryOHKO(battlerAtk, battlerDef, aiData->abilities[battlerAtk], aiData->abilities[battlerDef], move))
ADJUST_SCORE(-10);
@ -2535,9 +2540,9 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, enum Move move, s32 s
ADJUST_SCORE(-10);
break;
case EFFECT_NATURE_POWER:
predictedMove = GetNaturePowerMove(battlerAtk);
predictedMove = GetNaturePowerMove();
if (GetMoveEffect(predictedMove) != GetMoveEffect(move))
return AI_CheckBadMove(battlerAtk, battlerDef, GetNaturePowerMove(battlerAtk), score);
return AI_CheckBadMove(battlerAtk, battlerDef, GetNaturePowerMove(), score);
break;
case EFFECT_TAUNT:
if (gBattleMons[battlerDef].volatiles.tauntTimer > 0
@ -2759,7 +2764,7 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, enum Move move, s32 s
ADJUST_SCORE(-10);
break;
case EFFECT_FLING:
if (!CanFling(battlerAtk, battlerDef))
if (!CanFling(battlerAtk))
{
ADJUST_SCORE(-10);
}
@ -3082,6 +3087,8 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, enum Move move, s32 s
if (!ShouldBurn(battlerAtk, battlerDef, aiData->abilities[battlerDef]))
ADJUST_SCORE(-5);
break;
default:
break;
}
// Choice items
@ -3106,7 +3113,7 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, enum Move move, s32 s
return score;
}
static s32 AI_GetWhichBattlerFasterOrTies(u32 battlerAtk, u32 battlerDef, bool32 ignoreChosenMoves)
static s32 AI_GetWhichBattlerFasterOrTies(enum BattlerId battlerAtk, enum BattlerId battlerDef, bool32 ignoreChosenMoves)
{
struct BattleCalcValues calcValues = {0};
calcValues.battlerAtk = battlerAtk;
@ -3119,7 +3126,7 @@ static s32 AI_GetWhichBattlerFasterOrTies(u32 battlerAtk, u32 battlerDef, bool32
return GetWhichBattlerFasterOrTies(&calcValues, ignoreChosenMoves);
}
static s32 AI_TryToFaint(u32 battlerAtk, u32 battlerDef, enum Move move, s32 score)
static s32 AI_TryToFaint(enum BattlerId battlerAtk, enum BattlerId battlerDef, enum Move move, s32 score)
{
u32 movesetIndex = gAiThinkingStruct->movesetIndex;
enum Move predictedMoveSpeedCheck = GetIncomingMoveSpeedCheck(battlerAtk, battlerDef, gAiLogicData);
@ -3153,17 +3160,17 @@ static s32 AI_TryToFaint(u32 battlerAtk, u32 battlerDef, enum Move move, s32 sco
}
// double battle logic
static s32 AI_DoubleBattle(u32 battlerAtk, u32 battlerDef, enum Move move, s32 score)
static s32 AI_DoubleBattle(enum BattlerId battlerAtk, enum BattlerId battlerDef, enum Move move, s32 score)
{
// move data
enum Type moveType = GetMoveType(move);
enum BattleMoveEffects effect = GetMoveEffect(move);
enum MoveTarget moveTarget = AI_GetBattlerMoveTargetType(battlerAtk, move);
// ally data
u32 battlerAtkPartner = BATTLE_PARTNER(battlerAtk);
enum BattlerId battlerAtkPartner = BATTLE_PARTNER(battlerAtk);
struct AiLogicData *aiData = gAiLogicData;
enum Ability atkPartnerAbility = aiData->abilities[BATTLE_PARTNER(battlerAtk)];
u32 atkPartnerHoldEffect = aiData->holdEffects[BATTLE_PARTNER(battlerAtk)];
enum HoldEffect atkPartnerHoldEffect = aiData->holdEffects[BATTLE_PARTNER(battlerAtk)];
enum BattleMoveEffects partnerEffect = GetMoveEffect(aiData->partnerMove);
bool32 partnerProtecting = IsAllyProtectingFromMove(battlerAtk, move, aiData->partnerMove) && !MoveIgnoresProtect(move);
bool32 partnerHasBadAbility = (gAbilitiesInfo[atkPartnerAbility].aiRating < 0);
@ -3177,12 +3184,11 @@ static s32 AI_DoubleBattle(u32 battlerAtk, u32 battlerDef, enum Move move, s32 s
bool32 hasPartner = HasPartner(battlerAtk);
u32 friendlyFireThreshold = GetFriendlyFireKOThreshold(battlerAtk);
u32 noOfHitsToKOPartner = GetNoOfHitsToKOBattler(battlerAtk, battlerAtkPartner, gAiThinkingStruct->movesetIndex, AI_ATTACKING, CONSIDER_ENDURE);
bool32 wouldPartnerFaint = hasPartner && CanIndexMoveFaintTarget(battlerAtk, battlerAtkPartner, gAiThinkingStruct->movesetIndex, AI_ATTACKING)
&& !partnerProtecting;
bool32 wouldPartnerFaint = hasPartner && CanIndexMoveFaintTarget(battlerAtk, battlerAtkPartner, gAiThinkingStruct->movesetIndex, AI_ATTACKING) && !partnerProtecting;
bool32 isFriendlyFireOK = !wouldPartnerFaint && (noOfHitsToKOPartner == 0 || noOfHitsToKOPartner > friendlyFireThreshold);
// check what effect partner is using
if (aiData->partnerMove != 0 && hasPartner)
if (aiData->partnerMove != MOVE_NONE && hasPartner)
{
// This catches weather, terrain, screens, etc
if (AreMovesEquivalent(battlerAtk, battlerAtkPartner, move, aiData->partnerMove))
@ -3912,7 +3918,7 @@ static bool32 IsPinchBerryItemEffect(enum HoldEffect holdEffect)
}
}
static bool32 DoesAbilityBenefitFromSunOrRain(u32 battler, enum Ability ability, u32 weather)
static bool32 DoesAbilityBenefitFromSunOrRain(enum BattlerId battler, enum Ability ability, u32 weather)
{
switch (ability)
{
@ -3923,7 +3929,6 @@ static bool32 DoesAbilityBenefitFromSunOrRain(u32 battler, enum Ability ability,
return (weather & B_WEATHER_RAIN);
case ABILITY_HARVEST:
if (GetItemPocket(gAiLogicData->items[battler]) != POCKET_BERRIES
&& GetItemPocket(gBattleStruct->changedItems[battler]) != POCKET_BERRIES
&& GetItemPocket(GetBattlerPartyState(battler)->usedHeldItem) != POCKET_BERRIES)
{
return FALSE;
@ -3940,7 +3945,27 @@ static bool32 DoesAbilityBenefitFromSunOrRain(u32 battler, enum Ability ability,
return FALSE;
}
static enum MoveComparisonResult CompareMoveAccuracies(u32 battlerAtk, u32 battlerDef, u32 moveSlot1, u32 moveSlot2)
static u32 GetWindAbilityScore(enum BattlerId battlerAtk, enum BattlerId battlerDef, struct AiLogicData *aiData)
{
u32 score = 0;
if (aiData->abilities[battlerAtk] == ABILITY_WIND_RIDER)
{
score = IncreaseStatUpScore(battlerAtk, battlerDef, STAT_CHANGE_ATK);
}
else if (aiData->abilities[battlerAtk] == ABILITY_WIND_POWER)
{
if (gBattleMons[battlerAtk].volatiles.chargeTimer == 0
&& HasDamagingMoveOfType(battlerAtk, TYPE_ELECTRIC))
{
score = DECENT_EFFECT;
}
}
return score;
}
static enum MoveComparisonResult CompareMoveAccuracies(enum BattlerId battlerAtk, enum BattlerId battlerDef, u32 moveSlot1, u32 moveSlot2)
{
u32 acc1 = gAiLogicData->moveAccuracy[battlerAtk][battlerDef][moveSlot1];
u32 acc2 = gAiLogicData->moveAccuracy[battlerAtk][battlerDef][moveSlot2];
@ -3952,7 +3977,7 @@ static enum MoveComparisonResult CompareMoveAccuracies(u32 battlerAtk, u32 battl
return MOVE_NEUTRAL_COMPARISON;
}
static enum MoveComparisonResult CompareMoveSpeeds(u32 battlerAtk, u32 battlerDef, bool32 move1Faster, bool32 move2Faster)
static enum MoveComparisonResult CompareMoveSpeeds(enum BattlerId battlerAtk, enum BattlerId battlerDef, bool32 move1Faster, bool32 move2Faster)
{
if (move1Faster && !move2Faster)
return MOVE_WON_COMPARISON;
@ -3961,7 +3986,7 @@ static enum MoveComparisonResult CompareMoveSpeeds(u32 battlerAtk, u32 battlerDe
return MOVE_NEUTRAL_COMPARISON;
}
static enum MoveComparisonResult CompareGuaranteeFaintTarget(u32 battlerAtk, u32 battlerDef, u16 moveSlot1, u16 moveSlot2, u16 *moves)
static enum MoveComparisonResult CompareGuaranteeFaintTarget(enum BattlerId battlerAtk, enum BattlerId battlerDef, u16 moveSlot1, u16 moveSlot2, u16 *moves)
{
s32 dmg1, dmg2;
bool32 guarantee1, guarantee2;
@ -3982,7 +4007,7 @@ static enum MoveComparisonResult CompareGuaranteeFaintTarget(u32 battlerAtk, u32
return MOVE_NEUTRAL_COMPARISON;
}
static enum MoveComparisonResult CompareResistBerryEffects(u32 battlerAtk, u32 battlerDef, u32 moveSlot1, u32 moveSlot2)
static enum MoveComparisonResult CompareResistBerryEffects(enum BattlerId battlerAtk, enum BattlerId battlerDef, u32 moveSlot1, u32 moveSlot2)
{
// Check for resist berries in OHKOs
if (gAiLogicData->holdEffects[battlerDef] == HOLD_EFFECT_RESIST_BERRY)
@ -3997,7 +4022,7 @@ static enum MoveComparisonResult CompareResistBerryEffects(u32 battlerAtk, u32 b
return MOVE_NEUTRAL_COMPARISON;
}
static enum MoveComparisonResult CompareMoveSelfSacrifice(u32 battlerAtk, u32 battlerDef, enum Move move1, enum Move move2)
static enum MoveComparisonResult CompareMoveSelfSacrifice(enum BattlerId battlerAtk, enum BattlerId battlerDef, enum Move move1, enum Move move2)
{
bool32 selfSacrifice1 = IsSelfSacrificeEffect(move1);
bool32 selfSacrifice2 = IsSelfSacrificeEffect(move2);
@ -4009,7 +4034,7 @@ static enum MoveComparisonResult CompareMoveSelfSacrifice(u32 battlerAtk, u32 ba
return MOVE_NEUTRAL_COMPARISON;
}
static enum MoveComparisonResult CompareMoveTwoTurnEffect(u32 battlerAtk, enum Move move1, enum Move move2)
static enum MoveComparisonResult CompareMoveTwoTurnEffect(enum BattlerId battlerAtk, enum Move move1, enum Move move2)
{
bool32 twoTurn1 = IsTwoTurnNotSemiInvulnerableMove(battlerAtk, move1);
bool32 twoTurn2 = IsTwoTurnNotSemiInvulnerableMove(battlerAtk, move2);
@ -4021,9 +4046,9 @@ static enum MoveComparisonResult CompareMoveTwoTurnEffect(u32 battlerAtk, enum M
return MOVE_NEUTRAL_COMPARISON;
}
static inline bool32 ShouldUseSpreadDamageMove(u32 battlerAtk, enum Move move, u32 moveIndex, u32 hitsToFaintOpposingBattler)
static inline bool32 ShouldUseSpreadDamageMove(enum BattlerId battlerAtk, enum Move move, u32 moveIndex, u32 hitsToFaintOpposingBattler)
{
u32 partnerBattler = BATTLE_PARTNER(battlerAtk);
enum BattlerId partnerBattler = BATTLE_PARTNER(battlerAtk);
u32 noOfHitsToFaintPartner = GetNoOfHitsToKOBattler(battlerAtk, partnerBattler, moveIndex, AI_ATTACKING, CONSIDER_ENDURE);
u32 friendlyFireThreshold = GetFriendlyFireKOThreshold(battlerAtk);
return (HasPartnerIgnoreFlags(battlerAtk)
@ -4033,7 +4058,7 @@ static inline bool32 ShouldUseSpreadDamageMove(u32 battlerAtk, enum Move move, u
&& noOfHitsToFaintPartner < (friendlyFireThreshold * 2));
}
static bool32 ShouldCompareMove(u32 battlerAtk, u32 battlerDef, u32 moveIndex, enum Move move)
static bool32 ShouldCompareMove(enum BattlerId battlerAtk, enum BattlerId battlerDef, u32 moveIndex, enum Move move)
{
if (IsTargetingPartner(battlerAtk, battlerDef))
return FALSE;
@ -4046,7 +4071,7 @@ static bool32 ShouldCompareMove(u32 battlerAtk, u32 battlerDef, u32 moveIndex, e
return TRUE;
}
static void AI_CompareDamagingMoves(u32 battlerAtk, u32 battlerDef)
static void AI_CompareDamagingMoves(enum BattlerId battlerAtk, enum BattlerId battlerDef)
{
u32 tempMoveScores[MAX_MON_MOVES];
u32 moveComparisonScores[MAX_MON_MOVES];
@ -4220,7 +4245,7 @@ static void AI_CompareDamagingMoves(u32 battlerAtk, u32 battlerDef)
}
}
static s32 AI_CalcHoldEffectMoveScore(u32 battlerAtk, u32 battlerDef, enum Move move, struct AiLogicData *aiData)
static s32 AI_CalcHoldEffectMoveScore(enum BattlerId battlerAtk, enum BattlerId battlerDef, enum Move move, struct AiLogicData *aiData)
{
enum HoldEffect holdEffect = aiData->holdEffects[battlerAtk];
@ -4249,7 +4274,7 @@ static s32 AI_CalcHoldEffectMoveScore(u32 battlerAtk, u32 battlerDef, enum Move
return score;
}
static s32 AI_CalcMoveEffectScore(u32 battlerAtk, u32 battlerDef, enum Move move, struct AiLogicData *aiData)
static s32 AI_CalcMoveEffectScore(enum BattlerId battlerAtk, enum BattlerId battlerDef, enum Move move, struct AiLogicData *aiData)
{
// move data
enum BattleMoveEffects moveEffect = GetMoveEffect(move);
@ -4326,6 +4351,8 @@ static s32 AI_CalcMoveEffectScore(u32 battlerAtk, u32 battlerDef, enum Move move
case MOVE_EFFECT_BURN:
IncreaseBurnScore(battlerAtk, battlerDef, move, &score);
break;
default:
break;
}
// move effect checks
switch (moveEffect)
@ -4630,7 +4657,6 @@ static s32 AI_CalcMoveEffectScore(u32 battlerAtk, u32 battlerDef, enum Move move
}
break;
case EFFECT_OHKO:
case EFFECT_SHEER_COLD:
if (GetActiveGimmick(battlerDef) == GIMMICK_DYNAMAX)
break;
else if (gBattleMons[battlerAtk].volatiles.lockOn)
@ -4737,10 +4763,12 @@ static s32 AI_CalcMoveEffectScore(u32 battlerAtk, u32 battlerDef, enum Move move
case MOVE_EFFECT_PARALYSIS:
encourage = TRUE;
break;
default:
break;
}
if (gBattleMons[battlerDef].volatiles.encoreTimer == 0
&& (B_MENTAL_HERB < GEN_5 || aiData->holdEffects[battlerDef] != HOLD_EFFECT_MENTAL_HERB)
&& (encourage))
&& (B_MENTAL_HERB < GEN_5 || aiData->holdEffects[battlerDef] != HOLD_EFFECT_MENTAL_HERB)
&& (encourage))
ADJUST_SCORE(BEST_EFFECT);
break;
}
@ -4750,7 +4778,7 @@ static s32 AI_CalcMoveEffectScore(u32 battlerAtk, u32 battlerDef, enum Move move
ADJUST_SCORE(BEST_EFFECT);
break;
case EFFECT_LOCK_ON:
if (HasMoveWithEffect(battlerAtk, EFFECT_OHKO) || HasMoveWithEffect(battlerAtk, EFFECT_SHEER_COLD))
if (HasMoveWithEffect(battlerAtk, EFFECT_OHKO))
ADJUST_SCORE(GOOD_EFFECT);
else if (HasMoveWithLowAccuracy(battlerAtk, battlerDef, 85, TRUE))
ADJUST_SCORE(GOOD_EFFECT);
@ -4919,6 +4947,9 @@ static s32 AI_CalcMoveEffectScore(u32 battlerAtk, u32 battlerDef, enum Move move
case EFFECT_SEMI_INVULNERABLE:
if (predictedMove != MOVE_NONE && isBattle1v1)
{
if (aiData->abilities[battlerAtk] == ABILITY_NO_GUARD || aiData->abilities[battlerDef] == ABILITY_NO_GUARD)
break;
enum BattleMoveEffects predictedEffect = GetMoveEffect(predictedMove);
if ((AI_IsFaster(battlerAtk, battlerDef, move, predictedMoveSpeedCheck, CONSIDER_PRIORITY))
&& (IsExplosionMove(predictedMove) || predictedEffect == EFFECT_PROTECT))
@ -5593,6 +5624,14 @@ static s32 AI_CalcMoveEffectScore(u32 battlerAtk, u32 battlerDef, enum Move move
if (CountUsablePartyMons(battlerAtk) != 0)
ADJUST_SCORE(WEAK_EFFECT);
if (!(gSideStatuses[GetBattlerSide(battlerAtk)] & SIDE_STATUS_TAILWIND))
{
u32 windAbilityScore = GetWindAbilityScore(battlerAtk, battlerDef, aiData);
if (windAbilityScore > 0)
ADJUST_SCORE(windAbilityScore);
}
}
else
{
@ -5606,15 +5645,26 @@ static s32 AI_CalcMoveEffectScore(u32 battlerAtk, u32 battlerDef, enum Move move
tailwindScore += 1;
if (speed <= foe2Speed && (speed * 2) > foe2Speed)
tailwindScore += 1;
if (partnerSpeed <= foe1Speed && (speed * 2) > foe1Speed)
if (partnerSpeed <= foe1Speed && (partnerSpeed * 2) > foe1Speed)
tailwindScore += 1;
if (partnerSpeed <= foe1Speed && (speed * 2) > foe1Speed)
if (partnerSpeed <= foe2Speed && (partnerSpeed * 2) > foe2Speed)
tailwindScore += 1;
if (tailwindScore > 0)
tailwindScore += 1;
ADJUST_SCORE(tailwindScore);
if (!(gSideStatuses[GetBattlerSide(battlerAtk)] & SIDE_STATUS_TAILWIND))
{
u32 windAbilityScore = GetWindAbilityScore(battlerAtk, battlerDef, aiData);
if (IsBattlerAlive(BATTLE_PARTNER(battlerAtk)))
windAbilityScore += GetWindAbilityScore(BATTLE_PARTNER(battlerAtk), battlerDef, aiData);
if (windAbilityScore > 0)
ADJUST_SCORE(windAbilityScore);
}
}
break;
}
@ -5796,7 +5846,7 @@ static s32 AI_CalcMoveEffectScore(u32 battlerAtk, u32 battlerDef, enum Move move
return score;
}
static s32 AI_CalcAdditionalEffectScore(u32 battlerAtk, u32 battlerDef, enum Move move, struct AiLogicData *aiData)
static s32 AI_CalcAdditionalEffectScore(enum BattlerId battlerAtk, enum BattlerId battlerDef, enum Move move, struct AiLogicData *aiData)
{
// move data
s32 score = 0;
@ -5936,7 +5986,7 @@ static s32 AI_CalcAdditionalEffectScore(u32 battlerAtk, u32 battlerDef, enum Mov
case MOVE_EFFECT_SP_DEF_MINUS_1:
case MOVE_EFFECT_EVS_MINUS_1:
{
u32 statId = STAT_ATK + additionalEffect->moveEffect - MOVE_EFFECT_ATK_MINUS_1;
enum Stat statId = STAT_ATK + additionalEffect->moveEffect - MOVE_EFFECT_ATK_MINUS_1;
if (CanLowerStat(battlerAtk, battlerDef, aiData, statId))
ADJUST_SCORE(IncreaseStatDownScore(battlerAtk, battlerDef, statId));
break;
@ -5947,7 +5997,7 @@ static s32 AI_CalcAdditionalEffectScore(u32 battlerAtk, u32 battlerDef, enum Mov
case MOVE_EFFECT_SP_DEF_MINUS_2:
case MOVE_EFFECT_EVS_MINUS_2:
{
u32 statId = STAT_ATK + additionalEffect->moveEffect - MOVE_EFFECT_ATK_MINUS_2;
enum Stat statId = STAT_ATK + additionalEffect->moveEffect - MOVE_EFFECT_ATK_MINUS_2;
if (CanLowerStat(battlerAtk, battlerDef, aiData, statId))
ADJUST_SCORE(IncreaseStatDownScore(battlerAtk, battlerDef, statId));
break;
@ -5970,7 +6020,7 @@ static s32 AI_CalcAdditionalEffectScore(u32 battlerAtk, u32 battlerDef, enum Mov
case MOVE_EFFECT_LOWER_SP_ATK_SIDE:
case MOVE_EFFECT_LOWER_SP_DEF_SIDE:
{
u32 statId = STAT_ATK + additionalEffect->moveEffect - MOVE_EFFECT_LOWER_ATTACK_SIDE;
enum Stat statId = STAT_ATK + additionalEffect->moveEffect - MOVE_EFFECT_LOWER_ATTACK_SIDE;
if (CanLowerStat(battlerAtk, battlerDef, aiData, statId))
ADJUST_SCORE(IncreaseStatDownScore(battlerAtk, battlerDef, statId));
break;
@ -6150,7 +6200,7 @@ static s32 AI_CalcAdditionalEffectScore(u32 battlerAtk, u32 battlerDef, enum Mov
}
// AI_FLAG_CHECK_VIABILITY - Chooses best possible move to hit player
static s32 AI_CheckViability(u32 battlerAtk, u32 battlerDef, enum Move move, s32 score)
static s32 AI_CheckViability(enum BattlerId battlerAtk, enum BattlerId battlerDef, enum Move move, s32 score)
{
struct AiLogicData *aiData = gAiLogicData;
@ -6178,7 +6228,7 @@ static s32 AI_CheckViability(u32 battlerAtk, u32 battlerDef, enum Move move, s32
}
// Effects that are encouraged on the first turn of battle
static s32 AI_ForceSetupFirstTurn(u32 battlerAtk, u32 battlerDef, enum Move move, s32 score)
static s32 AI_ForceSetupFirstTurn(enum BattlerId battlerAtk, enum BattlerId battlerDef, enum Move move, s32 score)
{
if (IsTargetingPartner(battlerAtk, battlerDef)
|| gBattleResults.battleTurnCounter != 0)
@ -6286,7 +6336,7 @@ static s32 AI_ForceSetupFirstTurn(u32 battlerAtk, u32 battlerDef, enum Move move
}
// Adds score bonus to 'riskier' move effects and high crit moves
static s32 AI_Risky(u32 battlerAtk, u32 battlerDef, enum Move move, s32 score)
static s32 AI_Risky(enum BattlerId battlerAtk, enum BattlerId battlerDef, enum Move move, s32 score)
{
struct AiLogicData *aiData = gAiLogicData;
@ -6333,7 +6383,6 @@ static s32 AI_Risky(u32 battlerAtk, u32 battlerDef, enum Move move, s32 score)
case EFFECT_FLATTER:
case EFFECT_ATTRACT:
case EFFECT_OHKO:
case EFFECT_SHEER_COLD:
ADJUST_SCORE(AVERAGE_RISKY_EFFECT);
break;
case EFFECT_HIT:
@ -6363,7 +6412,7 @@ static s32 AI_Risky(u32 battlerAtk, u32 battlerDef, enum Move move, s32 score)
}
// Adds score bonus to OHKOs and 2HKOs
static s32 AI_TryTo2HKO(u32 battlerAtk, u32 battlerDef, enum Move move, s32 score)
static s32 AI_TryTo2HKO(enum BattlerId battlerAtk, enum BattlerId battlerDef, enum Move move, s32 score)
{
if (IsTargetingPartner(battlerAtk, battlerDef))
return score;
@ -6377,7 +6426,7 @@ static s32 AI_TryTo2HKO(u32 battlerAtk, u32 battlerDef, enum Move move, s32 scor
}
// Adds score bonus to targeting "partner"
static s32 AI_AttacksPartner(u32 battlerAtk, u32 battlerDef, enum Move move, s32 score)
static s32 AI_AttacksPartner(enum BattlerId battlerAtk, enum BattlerId battlerDef, enum Move move, s32 score)
{
if (battlerDef == BATTLE_PARTNER(battlerAtk)
// natural enemies in wild battles try to kill each other
@ -6402,7 +6451,7 @@ static s32 AI_AttacksPartner(u32 battlerAtk, u32 battlerDef, enum Move move, s32
}
// Prefers moves that are good for baton pass
static s32 AI_PreferBatonPass(u32 battlerAtk, u32 battlerDef, enum Move move, s32 score)
static s32 AI_PreferBatonPass(enum BattlerId battlerAtk, enum BattlerId battlerDef, enum Move move, s32 score)
{
if (IsTargetingPartner(battlerAtk, battlerDef)
|| CountUsablePartyMons(battlerAtk) == 0
@ -6454,7 +6503,7 @@ static s32 AI_PreferBatonPass(u32 battlerAtk, u32 battlerDef, enum Move move, s3
return score;
}
static s32 AI_HPAware(u32 battlerAtk, u32 battlerDef, enum Move move, s32 score)
static s32 AI_HPAware(enum BattlerId battlerAtk, enum BattlerId battlerDef, enum Move move, s32 score)
{
enum BattleMoveEffects effect = GetMoveEffect(move);
enum Type moveType = 0;
@ -6637,6 +6686,8 @@ static s32 AI_HPAware(u32 battlerAtk, u32 battlerDef, enum Move move, s32 score)
case MOVE_EFFECT_POISON:
ADJUST_SCORE(-2);
break;
default:
break;
}
}
else
@ -6650,7 +6701,7 @@ static s32 AI_HPAware(u32 battlerAtk, u32 battlerDef, enum Move move, s32 score)
return score;
}
static s32 AI_PowerfulStatus(u32 battlerAtk, u32 battlerDef, enum Move move, s32 score)
static s32 AI_PowerfulStatus(enum BattlerId battlerAtk, enum BattlerId battlerDef, enum Move move, s32 score)
{
enum BattleMoveEffects moveEffect = GetMoveEffect(move);
@ -6762,7 +6813,7 @@ bool32 DoesSideHaveDamagingHazards(enum BattleSide side)
return FALSE;
}
static s32 AI_PredictSwitch(u32 battlerAtk, u32 battlerDef, enum Move move, s32 score)
static s32 AI_PredictSwitch(enum BattlerId battlerAtk, enum BattlerId battlerDef, enum Move move, s32 score)
{
u32 unmodifiedScore = score;
enum Ability ability = gBattleMons[battlerAtk].ability;
@ -6771,7 +6822,7 @@ static s32 AI_PredictSwitch(u32 battlerAtk, u32 battlerDef, enum Move move, s32
enum BattleMoveEffects moveEffect = GetMoveEffect(move);
struct AiLogicData *aiData = gAiLogicData;
uq4_12_t effectiveness = aiData->effectiveness[battlerAtk][battlerDef][gAiThinkingStruct->movesetIndex];
u32 predictedMove = GetIncomingMove(battlerAtk, battlerDef, gAiLogicData);
enum Move predictedMove = GetIncomingMove(battlerAtk, battlerDef, gAiLogicData);
enum Move predictedMoveSpeedCheck = GetIncomingMoveSpeedCheck(battlerAtk, battlerDef, gAiLogicData);
// Switch benefit
@ -6916,7 +6967,7 @@ static s32 AI_PredictSwitch(u32 battlerAtk, u32 battlerDef, enum Move move, s32
return score;
}
static s32 AI_CheckPpStall(u32 battlerAtk, u32 battlerDef, enum Move move, s32 score)
static s32 AI_CheckPpStall(enum BattlerId battlerAtk, enum BattlerId battlerDef, enum Move move, s32 score)
{
if (!IsOnPlayerSide(battlerAtk))
score -= PpStallReduction(move, battlerAtk);
@ -6934,7 +6985,7 @@ static void AI_Watch(void)
}
// Roaming pokemon logic
static s32 AI_Roaming(u32 battlerAtk, u32 battlerDef, enum Move move, s32 score)
static s32 AI_Roaming(enum BattlerId battlerAtk, enum BattlerId battlerDef, enum Move move, s32 score)
{
bool32 roamerCanFlee = FALSE;
@ -6953,7 +7004,7 @@ static s32 AI_Roaming(u32 battlerAtk, u32 battlerDef, enum Move move, s32 score)
}
// Safari pokemon logic
static s32 AI_Safari(u32 battlerAtk, u32 battlerDef, enum Move move, s32 score)
static s32 AI_Safari(enum BattlerId battlerAtk, enum BattlerId battlerDef, enum Move move, s32 score)
{
u32 safariFleeRate = gBattleStruct->safariEscapeFactor * 5; // Safari flee rate, from 0-20.
@ -6966,7 +7017,7 @@ static s32 AI_Safari(u32 battlerAtk, u32 battlerDef, enum Move move, s32 score)
}
// First battle logic
static s32 AI_FirstBattle(u32 battlerAtk, u32 battlerDef, enum Move move, s32 score)
static s32 AI_FirstBattle(enum BattlerId battlerAtk, enum BattlerId battlerDef, enum Move move, s32 score)
{
if (!IS_FRLG && gAiLogicData->hpPercents[battlerDef] <= 20)
AI_Flee();
@ -6974,12 +7025,11 @@ static s32 AI_FirstBattle(u32 battlerAtk, u32 battlerDef, enum Move move, s32 sc
return score;
}
// Dynamic AI Functions
// For specific battle scenarios
// Example - prefer attacking opposite foe in a tag battle
s32 AI_TagBattlePreferFoe(u32 battlerAtk, u32 battlerDef, enum Move move, s32 score)
s32 AI_TagBattlePreferFoe(enum BattlerId battlerAtk, enum BattlerId battlerDef, enum Move move, s32 score)
{
if (!(gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER))
{
@ -7000,7 +7050,7 @@ s32 AI_TagBattlePreferFoe(u32 battlerAtk, u32 battlerDef, enum Move move, s32 sc
return score;
}
static s32 AI_DynamicFunc(u32 battlerAtk, u32 battlerDef, enum Move move, s32 score)
static s32 AI_DynamicFunc(enum BattlerId battlerAtk, enum BattlerId battlerDef, enum Move move, s32 score)
{
if (sDynamicAiFunc != NULL)
score = sDynamicAiFunc(battlerAtk, battlerDef, move, score);

View File

@ -32,23 +32,23 @@ struct IncomingHealInfo
u16 healEndOfTurn:1;
u16 curesStatus:1;
};
static bool32 CanUseSuperEffectiveMoveAgainstOpponents(u32 battler);
static bool32 FindMonWithFlagsAndSuperEffective(u32 battler, u16 flags, u32 moduloPercent);
static u32 GetSwitchinHazardsDamage(u32 battler);
static bool32 AI_CanSwitchinAbilityTrapOpponent(enum Ability ability, u32 opponent);
static u32 GetBattlerTypeMatchup(u32 opposingBattler, u32 battler);
static u32 GetSwitchinHitsToKO(s32 damageTaken, u32 battler, const struct IncomingHealInfo *healInfo, u32 originalHp);
static void GetIncomingHealInfo(u32 battler, struct IncomingHealInfo *healInfo);
static u32 GetWishHealAmountForBattler(u32 battler);
static bool32 CanUseSuperEffectiveMoveAgainstOpponents(enum BattlerId battler);
static bool32 FindMonWithFlagsAndSuperEffective(enum BattlerId battler, u16 flags, u32 moduloPercent);
static u32 GetSwitchinHazardsDamage(enum BattlerId battler);
static bool32 AI_CanSwitchinAbilityTrapOpponent(enum Ability ability, enum BattlerId opposingBattler);
static u32 GetBattlerTypeMatchup(enum BattlerId opposingBattler, enum BattlerId battler);
static u32 GetSwitchinHitsToKO(s32 damageTaken, enum BattlerId battler, const struct IncomingHealInfo *healInfo, u32 originalHp);
static void GetIncomingHealInfo(enum BattlerId battler, struct IncomingHealInfo *healInfo);
static u32 GetWishHealAmountForBattler(enum BattlerId battler);
static void InitializeSwitchinCandidate(u32 switchinBattler, struct Pokemon *mon)
static void InitializeSwitchinCandidate(enum BattlerId switchinBattler, struct Pokemon *mon)
{
PokemonToBattleMon(mon, &gBattleMons[switchinBattler]);
// Setup switchin battler data
gAiThinkingStruct->saved[switchinBattler].saved = TRUE;
SetBattlerAiData(switchinBattler, gAiLogicData);
SetBattlerFieldStatusForSwitchin(switchinBattler);
for (u32 battlerIndex = 0; battlerIndex < gBattlersCount; battlerIndex++)
for (enum BattlerId battlerIndex = 0; battlerIndex < gBattlersCount; battlerIndex++)
{
if (switchinBattler == battlerIndex || !IsBattlerAlive(battlerIndex))
continue;
@ -60,7 +60,7 @@ static void InitializeSwitchinCandidate(u32 switchinBattler, struct Pokemon *mon
gAiThinkingStruct->saved[switchinBattler].saved = FALSE;
}
static u32 GetWishHealAmountForBattler(u32 battler)
static u32 GetWishHealAmountForBattler(enum BattlerId battler)
{
u32 wishHeal = 0;
@ -82,7 +82,7 @@ static u32 GetWishHealAmountForBattler(u32 battler)
return wishHeal;
}
static void GetIncomingHealInfo(u32 battler, struct IncomingHealInfo *healInfo)
static void GetIncomingHealInfo(enum BattlerId battler, struct IncomingHealInfo *healInfo)
{
memset(healInfo, 0, sizeof(*healInfo));
@ -189,7 +189,7 @@ u32 GetSwitchChance(enum ShouldSwitchScenario shouldSwitchScenario)
}
}
bool32 IsAceMon(u32 battler, u32 monPartyId)
bool32 IsAceMon(enum BattlerId battler, u32 monPartyId)
{
if (gAiThinkingStruct->aiFlags[battler] & AI_FLAG_ACE_POKEMON
&& !gProtectStructs[battler].forcedSwitch
@ -202,7 +202,7 @@ bool32 IsAceMon(u32 battler, u32 monPartyId)
return FALSE;
}
static bool32 AreStatsRaised(u32 battler)
static bool32 AreStatsRaised(enum BattlerId battler)
{
u8 buffedStatsValue = 0;
@ -215,13 +215,13 @@ static bool32 AreStatsRaised(u32 battler)
return (buffedStatsValue > STAY_IN_STATS_RAISED);
}
static inline bool32 SetSwitchinAndSwitch(u32 battler, u32 switchinId)
static inline bool32 SetSwitchinAndSwitch(enum BattlerId battler, u32 switchinId)
{
gBattleStruct->AI_monToSwitchIntoId[battler] = switchinId;
return TRUE;
}
static bool32 AI_DoesChoiceEffectBlockMove(u32 battler, enum Move move)
static bool32 AI_DoesChoiceEffectBlockMove(enum BattlerId battler, enum Move move)
{
// Choice locked into something else
if (gAiLogicData->lastUsedMove[battler] != MOVE_NONE && gAiLogicData->lastUsedMove[battler] != move
@ -262,11 +262,11 @@ static inline bool32 CanBattlerWin1v1(u32 hitsToKOAI, u32 hitsToKOPlayer, bool32
// Note that as many return statements as possible are INTENTIONALLY put after all of the loops;
// the function can take a max of about 0.06s to run, and this prevents the player from identifying
// whether the mon will switch or not by seeing how long the delay is before they select a move
static bool32 ShouldSwitchIfHasBadOdds(u32 battler)
static bool32 ShouldSwitchIfHasBadOdds(enum BattlerId battler)
{
//Variable initialization
enum BattlerPosition opposingPosition = BATTLE_OPPOSITE(GetBattlerPosition(battler));
u32 opposingBattler = GetBattlerAtPosition(opposingPosition);
enum BattlerId opposingBattler = GetBattlerAtPosition(opposingPosition);
enum Move *playerMoves = GetMovesArray(opposingBattler);
enum Move aiMove, playerMove, bestPlayerPriorityMove = MOVE_NONE, bestPlayerMove = MOVE_NONE, expectedMove = MOVE_NONE;
enum Ability aiAbility = gAiLogicData->abilities[battler];
@ -312,7 +312,7 @@ static bool32 ShouldSwitchIfHasBadOdds(u32 battler)
aiMoveEffect = GetMoveEffect(aiMove);
if (aiMove != MOVE_NONE && gBattleMons[battler].pp[moveIndex] > 0)
{
u32 nonVolatileStatus = GetMoveNonVolatileStatus(aiMove);
enum MoveEffect nonVolatileStatus = GetMoveNonVolatileStatus(aiMove);
// Check if mon has an "important" status move
if (aiMoveEffect == EFFECT_REFLECT || aiMoveEffect == EFFECT_LIGHT_SCREEN
|| aiMoveEffect == EFFECT_SPIKES || aiMoveEffect == EFFECT_TOXIC_SPIKES || aiMoveEffect == EFFECT_STEALTH_ROCK || aiMoveEffect == EFFECT_STICKY_WEB || aiMoveEffect == EFFECT_LEECH_SEED
@ -394,7 +394,7 @@ static bool32 ShouldSwitchIfHasBadOdds(u32 battler)
return FALSE;
}
static bool32 ShouldSwitchIfTruant(u32 battler)
static bool32 ShouldSwitchIfTruant(enum BattlerId battler)
{
// Switch if mon with truant is bodied by Protect or invulnerability spam
if (gAiLogicData->abilities[battler] == ABILITY_TRUANT
@ -409,7 +409,7 @@ static bool32 ShouldSwitchIfTruant(u32 battler)
return FALSE;
}
static u32 FindMonWithMoveOfEffectiveness(u32 battler, u32 opposingBattler, uq4_12_t effectiveness)
static u32 FindMonWithMoveOfEffectiveness(enum BattlerId battler, enum BattlerId opposingBattler, uq4_12_t effectiveness)
{
enum Move move;
s32 firstId;
@ -441,43 +441,66 @@ static u32 FindMonWithMoveOfEffectiveness(u32 battler, u32 opposingBattler, uq4_
return FALSE; // There is not a single Pokémon in the party that has a move with this effectiveness threshold
}
static bool32 ShouldSwitchIfAllMovesBad(u32 battler)
static bool32 CanMoveAffectTarget(struct BattleContext *ctx, u32 moveIndex)
{
u32 moveIndex;
u32 opposingBattler = GetOppositeBattler(battler);
enum Move aiMove;
if (ctx->move != MOVE_NONE
&& gAiLogicData->effectiveness[ctx->battlerAtk][ctx->battlerDef][moveIndex] > UQ_4_12(0.0)
&& !AI_CanMoveBeBlockedByTarget(ctx))
return TRUE;
return FALSE;
}
static bool32 IsMoveBad(struct BattleContext *ctx, u32 moveIndex)
{
if (CanMoveAffectTarget(ctx, moveIndex))
return FALSE;
if (!ALL_MOVES_BAD_STATUS_MOVES_BAD || GetMovePower(ctx->move) != 0) // If using ALL_MOVES_BAD_STATUS_MOVES_BAD, then need power to be non-zero
return TRUE;
return FALSE;
}
static bool32 ShouldSwitchIfAllMovesBad(enum BattlerId battler)
{
enum BattlerId opposingBattler = GetOppositeBattler(battler);
struct BattleContext ctx = {0};
ctx.battlerAtk = battler;
ctx.battlerDef = opposingBattler;
ctx.abilityAtk = gAiLogicData->abilities[ctx.battlerAtk];
ctx.abilityDef = gAiLogicData->abilities[ctx.battlerDef];
ctx.holdEffectAtk = gAiLogicData->holdEffects[ctx.battlerAtk];
ctx.holdEffectDef = gAiLogicData->holdEffects[ctx.battlerDef];
// Switch if no moves affect opponents
if (IsDoubleBattle())
if (HasTwoOpponents(battler))
{
u32 opposingPartner = BATTLE_PARTNER(opposingBattler);
for (moveIndex = 0; moveIndex < MAX_MON_MOVES; moveIndex++)
enum BattlerId opposingPartner = BATTLE_PARTNER(opposingBattler);
for (u32 moveIndex = 0; moveIndex < MAX_MON_MOVES; moveIndex++)
{
aiMove = gBattleMons[battler].moves[moveIndex];
if (aiMove == MOVE_NONE)
continue;
if (gAiLogicData->effectiveness[battler][opposingBattler][moveIndex] > UQ_4_12(0.0)
|| gAiLogicData->effectiveness[battler][opposingPartner][moveIndex] > UQ_4_12(0.0))
ctx.move = ctx.chosenMove = gBattleMons[battler].moves[moveIndex];
ctx.moveType = GetBattleMoveType(ctx.move);
// Check if move is bad in the context of both opposing battlers
if (!IsMoveBad(&ctx, moveIndex))
{
return FALSE;
}
else
{
// Set partner data in ctx
ctx.battlerDef = opposingPartner;
ctx.abilityDef = gAiLogicData->abilities[ctx.battlerDef];
ctx.holdEffectDef = gAiLogicData->holdEffects[ctx.battlerDef];
if (!IsMoveBad(&ctx, moveIndex))
return FALSE;
}
}
}
else
{
struct BattleContext ctx = {0};
ctx.battlerAtk = battler;
ctx.battlerDef = opposingBattler;
ctx.abilityAtk = gAiLogicData->abilities[ctx.battlerAtk];
ctx.abilityDef = gAiLogicData->abilities[ctx.battlerDef];
ctx.holdEffectAtk = gAiLogicData->holdEffects[ctx.battlerAtk];
ctx.holdEffectDef = gAiLogicData->holdEffects[ctx.battlerDef];
for (moveIndex = 0; moveIndex < MAX_MON_MOVES; moveIndex++)
for (u32 moveIndex = 0; moveIndex < MAX_MON_MOVES; moveIndex++)
{
aiMove = gBattleMons[battler].moves[moveIndex];
if (aiMove != MOVE_NONE
&& gAiLogicData->effectiveness[battler][opposingBattler][moveIndex] > UQ_4_12(0.0)
&& !AI_CanMoveBeBlockedByTarget(&ctx)
&& (!ALL_MOVES_BAD_STATUS_MOVES_BAD || GetMovePower(aiMove) != 0)) // If using ALL_MOVES_BAD_STATUS_MOVES_BAD, then need power to be non-zero
ctx.move = ctx.chosenMove = gBattleMons[battler].moves[moveIndex];
ctx.moveType = GetBattleMoveType(ctx.move);
if (!IsMoveBad(&ctx, moveIndex))
return FALSE;
}
}
@ -494,9 +517,9 @@ static bool32 ShouldSwitchIfAllMovesBad(u32 battler)
return FALSE;
}
static bool32 ShouldSwitchIfWonderGuard(u32 battler)
static bool32 ShouldSwitchIfWonderGuard(enum BattlerId battler)
{
u32 opposingBattler = GetOppositeBattler(battler);
enum BattlerId opposingBattler = GetOppositeBattler(battler);
if (IsDoubleBattle())
return FALSE;
@ -522,17 +545,17 @@ static bool32 ShouldSwitchIfWonderGuard(u32 battler)
return FALSE;
}
static bool32 FindMonThatAbsorbsOpponentsMove(u32 battler)
static bool32 FindMonThatAbsorbsOpponentsMove(enum BattlerId battler)
{
u32 battlerIn1, battlerIn2;
enum BattlerId battlerIn1, battlerIn2;
u8 numAbsorbingAbilities = 0;
enum Ability absorbingTypeAbilities[3]; // Array size is maximum number of absorbing abilities for a single type
enum Ability absorbingTypeAbilities[8]; // Max needed for type + move property absorbers
s32 firstId;
s32 lastId;
struct Pokemon *party;
enum Ability monAbility;
enum Move aiMove;
u32 opposingBattler = GetOppositeBattler(battler);
enum BattlerId opposingBattler = GetOppositeBattler(battler);
enum Move incomingMove = GetIncomingMove(battler, opposingBattler, gAiLogicData);
enum Type incomingType = CheckDynamicMoveType(GetBattlerMon(opposingBattler), incomingMove, opposingBattler, MON_IN_BATTLE);
bool32 isOpposingBattlerChargingOrInvulnerable = !BreaksThroughSemiInvulnerablity(battler, opposingBattler, gAiLogicData->abilities[battler], gAiLogicData->abilities[opposingBattler], incomingMove) || IsTwoTurnNotSemiInvulnerableMove(opposingBattler, incomingMove);
@ -570,42 +593,47 @@ static bool32 FindMonThatAbsorbsOpponentsMove(u32 battler)
{
absorbingTypeAbilities[numAbsorbingAbilities++] = ABILITY_FLASH_FIRE;
}
else if (incomingType == TYPE_WATER || (isOpposingBattlerChargingOrInvulnerable && incomingType == TYPE_WATER))
if (incomingType == TYPE_WATER || (isOpposingBattlerChargingOrInvulnerable && incomingType == TYPE_WATER))
{
absorbingTypeAbilities[numAbsorbingAbilities++] = ABILITY_WATER_ABSORB;
absorbingTypeAbilities[numAbsorbingAbilities++] = ABILITY_DRY_SKIN;
if (GetConfig(CONFIG_REDIRECT_ABILITY_IMMUNITY) >= GEN_5)
absorbingTypeAbilities[numAbsorbingAbilities++] = ABILITY_STORM_DRAIN;
}
else if (incomingType == TYPE_ELECTRIC || (isOpposingBattlerChargingOrInvulnerable && incomingType == TYPE_ELECTRIC))
if (incomingType == TYPE_ELECTRIC || (isOpposingBattlerChargingOrInvulnerable && incomingType == TYPE_ELECTRIC))
{
absorbingTypeAbilities[numAbsorbingAbilities++] = ABILITY_VOLT_ABSORB;
absorbingTypeAbilities[numAbsorbingAbilities++] = ABILITY_MOTOR_DRIVE;
if (GetConfig(CONFIG_REDIRECT_ABILITY_IMMUNITY) >= GEN_5)
absorbingTypeAbilities[numAbsorbingAbilities++] = ABILITY_LIGHTNING_ROD;
}
else if (incomingType == TYPE_GRASS || (isOpposingBattlerChargingOrInvulnerable && incomingType == TYPE_GRASS))
if (incomingType == TYPE_GRASS || (isOpposingBattlerChargingOrInvulnerable && incomingType == TYPE_GRASS))
{
absorbingTypeAbilities[numAbsorbingAbilities++] = ABILITY_SAP_SIPPER;
}
else if (incomingType == TYPE_GROUND || (isOpposingBattlerChargingOrInvulnerable && incomingType == TYPE_GROUND))
if (incomingType == TYPE_GROUND || (isOpposingBattlerChargingOrInvulnerable && incomingType == TYPE_GROUND))
{
absorbingTypeAbilities[numAbsorbingAbilities++] = ABILITY_EARTH_EATER;
absorbingTypeAbilities[numAbsorbingAbilities++] = ABILITY_LEVITATE;
}
else if (IsSoundMove(incomingMove) || (isOpposingBattlerChargingOrInvulnerable && IsSoundMove(incomingMove)))
if (IsSoundMove(incomingMove) || (isOpposingBattlerChargingOrInvulnerable && IsSoundMove(incomingMove)))
{
absorbingTypeAbilities[numAbsorbingAbilities++] = ABILITY_SOUNDPROOF;
}
else if (IsBallisticMove(incomingMove) || (isOpposingBattlerChargingOrInvulnerable && IsBallisticMove(incomingMove)))
if (IsBallisticMove(incomingMove) || (isOpposingBattlerChargingOrInvulnerable && IsBallisticMove(incomingMove)))
{
absorbingTypeAbilities[numAbsorbingAbilities++] = ABILITY_BULLETPROOF;
}
else if (IsWindMove(incomingMove) || (isOpposingBattlerChargingOrInvulnerable && IsWindMove(incomingMove)))
if (IsWindMove(incomingMove) || (isOpposingBattlerChargingOrInvulnerable && IsWindMove(incomingMove)))
{
absorbingTypeAbilities[numAbsorbingAbilities++] = ABILITY_WIND_RIDER;
}
else
if (IsPowderMove(incomingMove) || (isOpposingBattlerChargingOrInvulnerable && IsPowderMove(incomingMove)))
{
if (GetConfig(CONFIG_POWDER_OVERCOAT) >= GEN_6)
absorbingTypeAbilities[numAbsorbingAbilities++] = ABILITY_OVERCOAT;
}
if (numAbsorbingAbilities == 0)
{
return FALSE;
}
@ -649,10 +677,10 @@ static bool32 FindMonThatAbsorbsOpponentsMove(u32 battler)
return FALSE;
}
static bool32 ShouldSwitchIfOpponentChargingOrInvulnerable(u32 battler)
static bool32 ShouldSwitchIfOpponentChargingOrInvulnerable(enum BattlerId battler)
{
u32 opposingBattler = GetOppositeBattler(battler);
u32 incomingMove = GetIncomingMove(battler, opposingBattler, gAiLogicData);
enum BattlerId opposingBattler = GetOppositeBattler(battler);
enum Move incomingMove = GetIncomingMove(battler, opposingBattler, gAiLogicData);
bool32 isOpposingBattlerChargingOrInvulnerable = !BreaksThroughSemiInvulnerablity(battler, opposingBattler, gAiLogicData->abilities[battler], gAiLogicData->abilities[opposingBattler], incomingMove) || IsTwoTurnNotSemiInvulnerableMove(opposingBattler, incomingMove);
@ -666,7 +694,7 @@ static bool32 ShouldSwitchIfOpponentChargingOrInvulnerable(u32 battler)
return FALSE;
}
static bool32 ShouldSwitchIfTrapperInParty(u32 battler)
static bool32 ShouldSwitchIfTrapperInParty(enum BattlerId battler)
{
s32 firstId;
s32 lastId;
@ -703,13 +731,13 @@ static bool32 ShouldSwitchIfTrapperInParty(u32 battler)
return FALSE;
}
static bool32 ShouldSwitchIfBadlyStatused(u32 battler)
static bool32 ShouldSwitchIfBadlyStatused(enum BattlerId battler)
{
bool32 switchMon = FALSE;
enum Ability monAbility = gAiLogicData->abilities[battler];
enum HoldEffect holdEffect = gAiLogicData->holdEffects[battler];
enum BattlerPosition opposingPosition = BATTLE_OPPOSITE(GetBattlerPosition(battler));
u8 opposingBattler = GetBattlerAtPosition(opposingPosition);
enum BattlerId opposingBattler = GetBattlerAtPosition(opposingPosition);
bool32 hasStatRaised = AnyUsefulStatIsRaised(battler);
//Perish Song
@ -803,7 +831,7 @@ static bool32 ShouldSwitchIfBadlyStatused(u32 battler)
return FALSE;
}
static bool32 GetHitEscapeTransformState(u32 battlerAtk, enum Move move)
static bool32 GetHitEscapeTransformState(enum BattlerId battlerAtk, enum Move move)
{
u32 moveIndex;
bool32 hasValidTarget = FALSE;
@ -836,7 +864,7 @@ static bool32 GetHitEscapeTransformState(u32 battlerAtk, enum Move move)
ctx.abilityAtk = gAiLogicData->abilities[battlerAtk];
for (u32 battlerDef = 0; battlerDef < gBattlersCount; battlerDef++)
for (enum BattlerId battlerDef = 0; battlerDef < gBattlersCount; battlerDef++)
{
if (!IsBattlerAlive(battlerDef) || IsBattlerAlly(battlerDef, battlerAtk))
continue;
@ -878,7 +906,7 @@ static bool32 GetHitEscapeTransformState(u32 battlerAtk, enum Move move)
return isFasterThanAll;
}
static bool32 ShouldSwitchIfAbilityBenefit(u32 battler)
static bool32 ShouldSwitchIfAbilityBenefit(enum BattlerId battler)
{
bool32 hasStatRaised = AnyUsefulStatIsRaised(battler);
@ -943,7 +971,7 @@ static bool32 ShouldSwitchIfAbilityBenefit(u32 battler)
return SetSwitchinAndSwitch(battler, PARTY_SIZE);
}
static bool32 CanUseSuperEffectiveMoveAgainstOpponent(u32 battler, u32 opposingBattler)
static bool32 CanUseSuperEffectiveMoveAgainstOpponent(enum BattlerId battler, enum BattlerId opposingBattler)
{
enum Move move;
@ -962,23 +990,23 @@ static bool32 CanUseSuperEffectiveMoveAgainstOpponent(u32 battler, u32 opposingB
return FALSE;
}
static bool32 CanUseSuperEffectiveMoveAgainstOpponents(u32 battler)
static bool32 CanUseSuperEffectiveMoveAgainstOpponents(enum BattlerId battler)
{
u32 opposingPosition = BATTLE_OPPOSITE(GetBattlerPosition(battler));
u32 opposingBattler = GetBattlerAtPosition(opposingPosition);
enum BattlerPosition opposingPosition = GetBattlerPosition(BATTLE_OPPOSITE(battler));
enum BattlerId opposingBattler = GetBattlerAtPosition(opposingPosition);
if (CanUseSuperEffectiveMoveAgainstOpponent(battler, opposingBattler))
return TRUE;
if (IsDoubleBattle() && CanUseSuperEffectiveMoveAgainstOpponent(battler, BATTLE_PARTNER(opposingPosition)))
if (HasTwoOpponents(battler) && CanUseSuperEffectiveMoveAgainstOpponent(battler, BATTLE_PARTNER(BATTLE_OPPOSITE(battler))))
return TRUE;
return FALSE;
}
static bool32 FindMonWithFlagsAndSuperEffective(u32 battler, u16 flags, u32 percentChance)
static bool32 FindMonWithFlagsAndSuperEffective(enum BattlerId battler, u16 flags, u32 percentChance)
{
u32 battlerIn1, battlerIn2;
enum BattlerId battlerIn1, battlerIn2;
s32 firstId;
s32 lastId; // + 1
struct Pokemon *party;
@ -1039,9 +1067,9 @@ static bool32 FindMonWithFlagsAndSuperEffective(u32 battler, u16 flags, u32 perc
return FALSE;
}
static bool32 CanMonSurviveHazardSwitchin(u32 battler)
static bool32 CanMonSurviveHazardSwitchin(enum BattlerId battler)
{
u32 battlerIn1, battlerIn2;
enum BattlerId battlerIn1, battlerIn2;
u32 hazardDamage = 0, battlerHp = gBattleMons[battler].hp;
enum Ability ability = gAiLogicData->abilities[battler];
enum Move aiMove;
@ -1082,10 +1110,10 @@ static bool32 CanMonSurviveHazardSwitchin(u32 battler)
return TRUE;
}
static bool32 ShouldSwitchIfEncored(u32 battler)
static bool32 ShouldSwitchIfEncored(enum BattlerId battler)
{
enum Move encoredMove = gBattleMons[battler].volatiles.encoredMove;
u32 opposingBattler = GetOppositeBattler(battler);
enum BattlerId opposingBattler = GetOppositeBattler(battler);
// Only use this if AI_FLAG_SMART_SWITCHING is set for the trainer
if (!(gAiThinkingStruct->aiFlags[battler] & AI_FLAG_SMART_SWITCHING))
@ -1110,29 +1138,46 @@ static bool32 ShouldSwitchIfEncored(u32 battler)
return FALSE;
}
static bool32 ShouldSwitchIfBadChoiceLock(u32 battler)
static bool32 ShouldSwitchIfBadChoiceLock(enum BattlerId battler)
{
enum Move lastUsedMove = gAiLogicData->lastUsedMove[battler];
u32 opposingBattler = GetOppositeBattler(battler);
bool32 moveAffectsTarget = TRUE;
enum Move choicedMove = gBattleStruct->choicedMove[battler];
enum BattlerId opposingBattler = GetOppositeBattler(battler);
struct BattleContext ctx = {0};
ctx.battlerAtk = battler;
ctx.battlerDef = opposingBattler;
ctx.move = ctx.chosenMove = lastUsedMove;
ctx.moveType = GetBattleMoveType(lastUsedMove);
ctx.move = ctx.chosenMove = choicedMove;
ctx.moveType = GetBattleMoveType(choicedMove);
ctx.abilityAtk = gAiLogicData->abilities[ctx.battlerAtk];
ctx.abilityDef = gAiLogicData->abilities[ctx.battlerDef];
ctx.holdEffectAtk = gAiLogicData->holdEffects[ctx.battlerAtk];
ctx.holdEffectDef = gAiLogicData->holdEffects[ctx.battlerDef];
if (lastUsedMove != MOVE_NONE
&& (AI_GetMoveEffectiveness(lastUsedMove, battler, opposingBattler) == UQ_4_12(0.0) || AI_CanMoveBeBlockedByTarget(&ctx)))
moveAffectsTarget = FALSE;
// Not locked in to anything yet, or not choiced
if (choicedMove == MOVE_NONE)
return FALSE;
if (IsHoldEffectChoice(ctx.holdEffectAtk) && IsBattlerItemEnabled(battler))
u32 moveIndex = GetMoveIndex(battler, choicedMove);
if (HasTwoOpponents(battler))
{
if ((GetMoveCategory(lastUsedMove) == DAMAGE_CATEGORY_STATUS || !moveAffectsTarget) && RandomPercentage(RNG_AI_SWITCH_CHOICE_LOCKED, GetSwitchChance(SHOULD_SWITCH_CHOICE_LOCKED)))
enum BattlerId opposingPartner = BATTLE_PARTNER(opposingBattler);
if (IsHoldEffectChoice(ctx.holdEffectAtk) && IsBattlerItemEnabled(battler))
{
if (GetMoveCategory(choicedMove) == DAMAGE_CATEGORY_STATUS || !CanMoveAffectTarget(&ctx, moveIndex))
{
// Set partner data in ctx
ctx.battlerDef = opposingPartner;
ctx.abilityDef = gAiLogicData->abilities[ctx.battlerDef];
ctx.holdEffectDef = gAiLogicData->holdEffects[ctx.battlerDef];
if (!CanMoveAffectTarget(&ctx, moveIndex) && RandomPercentage(RNG_AI_SWITCH_CHOICE_LOCKED, GetSwitchChance(SHOULD_SWITCH_CHOICE_LOCKED)))
return SetSwitchinAndSwitch(battler, PARTY_SIZE);
}
}
}
else if (IsHoldEffectChoice(ctx.holdEffectAtk) && IsBattlerItemEnabled(battler))
{
if ((GetMoveCategory(choicedMove) == DAMAGE_CATEGORY_STATUS || !CanMoveAffectTarget(&ctx, moveIndex)) && RandomPercentage(RNG_AI_SWITCH_CHOICE_LOCKED, GetSwitchChance(SHOULD_SWITCH_CHOICE_LOCKED)))
return SetSwitchinAndSwitch(battler, PARTY_SIZE);
}
@ -1140,7 +1185,7 @@ static bool32 ShouldSwitchIfBadChoiceLock(u32 battler)
}
// AI should switch if it's become setup fodder and has something better to switch to
static bool32 ShouldSwitchIfAttackingStatsLowered(u32 battler)
static bool32 ShouldSwitchIfAttackingStatsLowered(enum BattlerId battler)
{
s8 attackingStage = gBattleMons[battler].statStages[STAT_ATK];
s8 spAttackingStage = gBattleMons[battler].statStages[STAT_SPATK];
@ -1185,7 +1230,7 @@ static bool32 ShouldSwitchIfAttackingStatsLowered(u32 battler)
return FALSE;
}
bool32 ShouldSwitchDynFuncExample(u32 battler)
bool32 ShouldSwitchDynFuncExample(enum BattlerId battler)
{
// Chance to switch if trainer class is Guitarist, perhaps thematic for Jugglers
if (GetTrainerClassFromId(TRAINER_BATTLE_PARAM.opponentA) == TRAINER_CLASS_GUITARIST
@ -1196,7 +1241,7 @@ bool32 ShouldSwitchDynFuncExample(u32 battler)
return FALSE;
}
static bool32 CanBattlerConsiderSwitch(u32 battler)
static bool32 CanBattlerConsiderSwitch(enum BattlerId battler)
{
if (gBattleMons[battler].volatiles.wrapped)
return FALSE;
@ -1213,9 +1258,9 @@ static bool32 CanBattlerConsiderSwitch(u32 battler)
return TRUE;
}
bool32 ShouldSwitch(u32 battler)
bool32 ShouldSwitch(enum BattlerId battler)
{
u32 battlerIn1, battlerIn2;
enum BattlerId battlerIn1, battlerIn2;
s32 firstId;
s32 lastId; // + 1
struct Pokemon *party;
@ -1306,7 +1351,7 @@ bool32 ShouldSwitch(u32 battler)
return FALSE;
}
bool32 ShouldSwitchIfAllScoresBad(u32 battler)
bool32 ShouldSwitchIfAllScoresBad(enum BattlerId battler)
{
u32 score, opposingBattler = GetOppositeBattler(battler);
if (!(gAiThinkingStruct->aiFlags[battler] & AI_FLAG_SMART_SWITCHING))
@ -1314,9 +1359,19 @@ bool32 ShouldSwitchIfAllScoresBad(u32 battler)
for (u32 moveIndex = 0; moveIndex < MAX_MON_MOVES; moveIndex++)
{
score = gAiBattleData->finalScore[battler][opposingBattler][moveIndex];
if (score > AI_BAD_SCORE_THRESHOLD)
return FALSE;
if (HasTwoOpponents(battler))
{
u32 score1 = gAiBattleData->finalScore[battler][opposingBattler][moveIndex];
u32 score2 = gAiBattleData->finalScore[battler][BATTLE_PARTNER(opposingBattler)][moveIndex];
if (score1 > AI_BAD_SCORE_THRESHOLD || score2 > AI_BAD_SCORE_THRESHOLD)
return FALSE;
}
else
{
score = gAiBattleData->finalScore[battler][opposingBattler][moveIndex];
if (score > AI_BAD_SCORE_THRESHOLD)
return FALSE;
}
}
if (RandomPercentage(RNG_AI_SWITCH_ALL_SCORES_BAD, GetSwitchChance(SHOULD_SWITCH_ALL_SCORES_BAD))
&& (gAiLogicData->mostSuitableMonId[battler] != PARTY_SIZE || !ALL_SCORES_BAD_NEEDS_GOOD_SWITCHIN))
@ -1324,9 +1379,10 @@ bool32 ShouldSwitchIfAllScoresBad(u32 battler)
return FALSE;
}
bool32 ShouldStayInToUseMove(u32 battler)
bool32 ShouldStayInToUseMove(enum BattlerId battler)
{
u32 aiMove, opposingBattler = GetOppositeBattler(battler);
enum Move aiMove;
u32 opposingBattler = GetOppositeBattler(battler);
enum BattleMoveEffects aiMoveEffect;
for (u32 moveIndex = 0; moveIndex < MAX_MON_MOVES; moveIndex++)
{
@ -1341,16 +1397,17 @@ bool32 ShouldStayInToUseMove(u32 battler)
&& !GetHitEscapeTransformState(battler, aiMove))
continue;
if (gAiBattleData->finalScore[battler][opposingBattler][moveIndex] > AI_GOOD_SCORE_THRESHOLD)
if (gAiBattleData->finalScore[battler][opposingBattler][moveIndex] > AI_GOOD_SCORE_THRESHOLD
|| (HasTwoOpponents(battler) && gAiBattleData->finalScore[battler][BATTLE_PARTNER(opposingBattler)][moveIndex] > AI_GOOD_SCORE_THRESHOLD))
return TRUE;
}
}
return FALSE;
}
void ModifySwitchAfterMoveScoring(u32 battler)
void ModifySwitchAfterMoveScoring(enum BattlerId battler)
{
u32 battlerIn1, battlerIn2;
enum BattlerId battlerIn1, battlerIn2;
s32 firstId;
s32 lastId; // + 1
struct Pokemon *party;
@ -1396,12 +1453,12 @@ void ModifySwitchAfterMoveScoring(u32 battler)
gAiLogicData->shouldSwitch &= ~(1u << battler);
}
bool32 IsSwitchinValid(u32 battler)
bool32 IsSwitchinValid(enum BattlerId battler)
{
// Edge case: See if partner already chose to switch into the same mon
if (IsDoubleBattle())
{
u32 partner = BATTLE_PARTNER(battler);
enum BattlerId partner = BATTLE_PARTNER(battler);
if (gBattleStruct->AI_monToSwitchIntoId[battler] == PARTY_SIZE) // Generic switch
{
if ((gAiLogicData->shouldSwitch & (1u << partner)) && gAiLogicData->monToSwitchInId[partner] == gAiLogicData->mostSuitableMonId[battler])
@ -1421,12 +1478,13 @@ bool32 IsSwitchinValid(u32 battler)
}
// Gets hazard damage
static u32 GetSwitchinHazardsDamage(u32 battler)
static u32 GetSwitchinHazardsDamage(enum BattlerId battler)
{
u8 tSpikesLayers;
u16 heldItemEffect = gAiLogicData->holdEffects[battler];
enum HoldEffect heldItemEffect = gAiLogicData->holdEffects[battler];
u32 maxHP = gBattleMons[battler].maxHP;
enum Ability ability = gAiLogicData->abilities[battler], status = gBattleMons[battler].status1;
enum Ability ability = gAiLogicData->abilities[battler];
u32 status = gBattleMons[battler].status1;
u32 spikesDamage = 0, tSpikesDamage = 0, hazardDamage = 0;
enum BattleSide side = GetBattlerSide(battler);
@ -1479,7 +1537,7 @@ static u32 GetSwitchinHazardsDamage(u32 battler)
}
// Gets damage / healing from weather
static s32 GetSwitchinWeatherImpact(u32 battler)
static s32 GetSwitchinWeatherImpact(enum BattlerId battler)
{
s32 weatherImpact = 0, maxHP = gBattleMons[battler].maxHP;
enum Ability ability = gAiLogicData->abilities[battler];
@ -1542,7 +1600,7 @@ static s32 GetSwitchinWeatherImpact(u32 battler)
}
// Gets one turn of recurring healing
static u32 GetSwitchinRecurringHealing(u32 battler)
static u32 GetSwitchinRecurringHealing(enum BattlerId battler)
{
u32 recurringHealing = 0, maxHP = gBattleMons[battler].maxHP;
enum Ability ability = gAiLogicData->abilities[battler];
@ -1577,7 +1635,7 @@ static u32 GetSwitchinRecurringHealing(u32 battler)
}
// Gets one turn of recurring damage
static u32 GetSwitchinRecurringDamage(u32 battler)
static u32 GetSwitchinRecurringDamage(enum BattlerId battler)
{
u32 passiveDamage = 0, maxHP = gBattleMons[battler].maxHP;
enum Ability ability = gAiLogicData->abilities[battler];
@ -1609,7 +1667,7 @@ static u32 GetSwitchinRecurringDamage(u32 battler)
}
// Gets one turn of status damage
static u32 GetSwitchinStatusDamage(u32 battler)
static u32 GetSwitchinStatusDamage(enum BattlerId battler)
{
u8 tSpikesLayers = gSideTimers[GetBattlerSide(battler)].toxicSpikesAmount;
enum HoldEffect heldItemEffect = gAiLogicData->holdEffects[battler];
@ -1682,7 +1740,7 @@ static u32 GetSwitchinStatusDamage(u32 battler)
}
// Gets number of hits to KO factoring in hazards, healing held items, status, weather, and incoming heals
static u32 GetSwitchinHitsToKO(s32 damageTaken, u32 battler, const struct IncomingHealInfo *healInfo, u32 originalHp)
static u32 GetSwitchinHitsToKO(s32 damageTaken, enum BattlerId battler, const struct IncomingHealInfo *healInfo, u32 originalHp)
{
u32 hazardDamage = GetSwitchinHazardsDamage(battler);
u32 hazardCheckHp = healInfo->healBeforeHazards ? gBattleMons[battler].maxHP : gBattleMons[battler].hp;
@ -1709,7 +1767,7 @@ static u32 GetSwitchinHitsToKO(s32 damageTaken, u32 battler, const struct Incomi
u32 hitsToKO = 0;
u16 maxHP = gBattleMons[battler].maxHP, item = gAiLogicData->items[battler], heldItemEffect = GetItemHoldEffect(item);
u8 weatherDuration = gBattleStruct->weatherDuration, holdEffectParam = GetItemHoldEffectParam(item);
u32 opposingBattler = GetOppositeBattler(battler);
enum BattlerId opposingBattler = GetOppositeBattler(battler);
enum Ability opposingAbility = gAiLogicData->abilities[opposingBattler], ability = gAiLogicData->abilities[battler];
bool32 usedSingleUseHealingItem = FALSE, opponentCanBreakMold = IsMoldBreakerTypeAbility(opposingBattler, opposingAbility);
s32 currentHP = startingHP, singleUseItemHeal = 0;
@ -1809,16 +1867,16 @@ static u32 GetSwitchinHitsToKO(s32 damageTaken, u32 battler, const struct Incomi
}
// Disguise will always add an extra hit to KO
if (!opponentCanBreakMold && gBattleMons[battler].species == SPECIES_MIMIKYU_DISGUISED)
if (!opponentCanBreakMold && IsMimikyuDisguised(battler))
hitsToKO++;
return hitsToKO;
}
static u32 GetBattlerTypeMatchup(u32 opposingBattler, u32 battler)
static u32 GetBattlerTypeMatchup(enum BattlerId opposingBattler, enum BattlerId battler)
{
// Check type matchup
u32 typeEffectiveness1 = UQ_4_12(1.0), typeEffectiveness2 = UQ_4_12(1.0);
uq4_12_t typeEffectiveness1 = UQ_4_12(1.0), typeEffectiveness2 = UQ_4_12(1.0);
enum Type atkType1 = gBattleMons[opposingBattler].types[0], atkType2 = gBattleMons[opposingBattler].types[1];
enum Type defType1 = gBattleMons[battler].types[0], defType2 = gBattleMons[battler].types[1];
@ -1845,7 +1903,7 @@ static u32 GetBattlerTypeMatchup(u32 opposingBattler, u32 battler)
return typeEffectiveness1 + typeEffectiveness2;
}
static u32 GetSwitchinCandidate(u32 switchinCategory, u32 battler, int firstId, int lastId, enum SwitchType switchType)
static u32 GetSwitchinCandidate(u32 switchinCategory, enum BattlerId battler, int firstId, int lastId, enum SwitchType switchType)
{
if (switchinCategory == 0)
return PARTY_SIZE;
@ -1870,7 +1928,7 @@ static u32 GetSwitchinCandidate(u32 switchinCategory, u32 battler, int firstId,
return PARTY_SIZE;
}
static u32 GetValidSwitchinCandidate(u32 validMonIds, u32 battler, u32 firstId, u32 lastId, enum SwitchType switchType)
static u32 GetValidSwitchinCandidate(u32 validMonIds, enum BattlerId battler, u32 firstId, u32 lastId, enum SwitchType switchType)
{
if (validMonIds == 0)
return PARTY_SIZE;
@ -1895,7 +1953,7 @@ static u32 GetValidSwitchinCandidate(u32 validMonIds, u32 battler, u32 firstId,
return PARTY_SIZE;
}
static s32 GetMaxDamagePlayerCouldDealToSwitchin(u32 battler, u32 opposingBattler, enum Move *bestPlayerMove)
static s32 GetMaxDamagePlayerCouldDealToSwitchin(enum BattlerId battler, enum BattlerId opposingBattler, enum Move *bestPlayerMove)
{
enum Move playerMove;
enum Move *playerMoves = GetMovesArray(opposingBattler);
@ -1922,7 +1980,7 @@ static s32 GetMaxDamagePlayerCouldDealToSwitchin(u32 battler, u32 opposingBattle
return maxDamageTaken;
}
static s32 GetMaxPriorityDamagePlayerCouldDealToSwitchin(u32 battler, u32 opposingBattler, enum Move *bestPlayerPriorityMove)
static s32 GetMaxPriorityDamagePlayerCouldDealToSwitchin(enum BattlerId battler, enum BattlerId opposingBattler, enum Move *bestPlayerPriorityMove)
{
enum Move playerMove;
enum Move *playerMoves = GetMovesArray(opposingBattler);
@ -1953,7 +2011,7 @@ static s32 GetMaxPriorityDamagePlayerCouldDealToSwitchin(u32 battler, u32 opposi
return maxDamageTaken;
}
static bool32 AI_CanSwitchinAbilityTrapOpponent(enum Ability ability, u32 opposingBattler)
static bool32 AI_CanSwitchinAbilityTrapOpponent(enum Ability ability, enum BattlerId opposingBattler)
{
if (AI_CanBattlerEscape(opposingBattler))
return FALSE;
@ -1974,7 +2032,7 @@ static bool32 AI_CanSwitchinAbilityTrapOpponent(enum Ability ability, u32 opposi
return FALSE;
}
static inline bool32 IsFreeSwitch(enum SwitchType switchType, u32 battlerSwitchingOut, u32 opposingBattler)
static inline bool32 IsFreeSwitch(enum SwitchType switchType, enum BattlerId battlerSwitchingOut, enum BattlerId opposingBattler)
{
bool32 movedSecond = GetBattlerTurnOrderNum(battlerSwitchingOut) > GetBattlerTurnOrderNum(opposingBattler) ? TRUE : FALSE;
@ -2031,7 +2089,7 @@ static inline bool32 CanSwitchinWin1v1(u32 hitsToKOAI, u32 hitsToKOPlayer, bool3
// This function splits switching behaviour depending on whether the switch is free.
// Everything runs in the same loop to minimize computation time. This makes it harder to read, but hopefully the comments can guide you!
static u32 GetBestMonIntegrated(struct Pokemon *party, int firstId, int lastId, u32 battler, u32 opposingBattler, u32 battlerIn1, u32 battlerIn2, enum SwitchType switchType)
static u32 GetBestMonIntegrated(struct Pokemon *party, int firstId, int lastId, enum BattlerId battler, enum BattlerId opposingBattler, enum BattlerId battlerIn1, enum BattlerId battlerIn2, enum SwitchType switchType)
{
struct IncomingHealInfo healInfoData;
const struct IncomingHealInfo *healInfo = &healInfoData;
@ -2272,7 +2330,7 @@ static u32 GetBestMonIntegrated(struct Pokemon *party, int firstId, int lastId,
return PARTY_SIZE;
}
static u32 GetBestMonVanilla(struct Pokemon *party, int firstId, int lastId, u32 battler, u32 opposingBattler, u32 battlerIn1, u32 battlerIn2, enum SwitchType switchType)
static u32 GetBestMonVanilla(struct Pokemon *party, int firstId, int lastId, enum BattlerId battler, enum BattlerId opposingBattler, enum BattlerId battlerIn1, enum BattlerId battlerIn2, enum SwitchType switchType)
{
s32 aceMonCount = 0;
u32 validMonIds = 0, batonPassIds = 0, typeMatchupIds = 0, bestDamageId = PARTY_SIZE, aceMonId = PARTY_SIZE;
@ -2315,7 +2373,7 @@ static u32 GetBestMonVanilla(struct Pokemon *party, int firstId, int lastId, u32
if (gBattleMons[battler].pp[moveIndex] < 1)
continue;
u32 aiMove = gBattleMons[battler].moves[moveIndex];
enum Move aiMove = gBattleMons[battler].moves[moveIndex];
// Baton Pass
if (GetMoveEffect(aiMove) == EFFECT_BATON_PASS)
@ -2367,7 +2425,7 @@ static u32 GetBestMonVanilla(struct Pokemon *party, int firstId, int lastId, u32
return PARTY_SIZE;
}
static u32 GetNextMonInParty(struct Pokemon *party, int firstId, int lastId, u32 battlerIn1, u32 battlerIn2)
static u32 GetNextMonInParty(struct Pokemon *party, int firstId, int lastId, enum BattlerId battlerIn1, enum BattlerId battlerIn2)
{
// Iterate through mons
for (u32 monIndex = firstId; monIndex < lastId; monIndex++)
@ -2382,11 +2440,11 @@ static u32 GetNextMonInParty(struct Pokemon *party, int firstId, int lastId, u32
return PARTY_SIZE;
}
u32 GetMostSuitableMonToSwitchInto(u32 battler, enum SwitchType switchType)
u32 GetMostSuitableMonToSwitchInto(enum BattlerId battler, enum SwitchType switchType)
{
u32 opposingBattler = 0;
enum BattlerId opposingBattler = 0;
u32 bestMonId = PARTY_SIZE;
u32 battlerIn1 = 0, battlerIn2 = 0;
enum BattlerId battlerIn1 = 0, battlerIn2 = 0;
s32 firstId = 0;
s32 lastId = 0; // + 1
struct Pokemon *party;
@ -2421,10 +2479,10 @@ u32 GetMostSuitableMonToSwitchInto(u32 battler, enum SwitchType switchType)
}
}
u32 AI_SelectRevivalBlessingMon(u32 battler)
u32 AI_SelectRevivalBlessingMon(enum BattlerId battler)
{
s32 firstId = 0, lastId = 0;
u32 opposingBattler = 0;
enum BattlerId opposingBattler = 0;
struct Pokemon *party = GetBattlerParty(battler);
u32 bestMonId = PARTY_SIZE;
s32 bestScore = -1;

File diff suppressed because it is too large Load Diff

View File

@ -261,6 +261,8 @@ static const u8* const sBattleAnims_General[NUM_B_ANIMS_GENERAL] =
[B_ANIM_SILPH_SCOPED] = gBattleAnimGeneral_SilphScoped,
[B_ANIM_ROCK_THROW] = gBattleAnimGeneral_SafariRockThrow,
[B_ANIM_SAFARI_REACTION] = gBattleAnimGeneral_SafariReaction,
[B_ANIM_FORM_CHANGE_INSTANT] = gBattleAnimGeneral_FormChangeInstant,
[B_ANIM_FORM_CHANGE_DISGUISE] = gBattleAnimGeneral_FormChangeDisguise,
};
static const u8* const sBattleAnims_Special[NUM_B_ANIMS_SPECIAL] =

View File

@ -2488,7 +2488,7 @@ void AnimTask_HideSwapSprite(u8 taskId)
gTasks[taskId].data[0]++;
break;
case 1:
HandleSpeciesGfxDataChange(gBattleAnimAttacker, gBattleAnimTarget, gTasks[taskId].data[10], gBattleAnimArgs[1], FALSE);
HandleSpeciesGfxDataChange(gBattleAnimAttacker, gBattleAnimTarget, SPECIES_GFX_CHANGE_FORM_CHANGE);
GetBgDataForTransform(&animBg, gBattleAnimAttacker);
if (IsContest())
@ -2576,14 +2576,10 @@ void AnimTask_SetOpponentShadowCallbacks(u8 taskId)
DestroyAnimVisualTask(taskId);
}
#define megaEvo data[10]
#define trackEnemyPersonality data[11]
#define ghostUnveil data[12]
void AnimTask_TransformMon(u8 taskId)
{
// int i, j;
u8 position;
enum BattlerPosition position;
struct BattleAnimBgData animBg;
u8 *dest;
u8 *src;
@ -2593,15 +2589,19 @@ void AnimTask_TransformMon(u8 taskId)
switch (gTasks[taskId].data[0])
{
case 0:
gTasks[taskId].data[10] = gBattleAnimArgs[0];
if (gTasks[taskId].data[10] == SPECIES_GFX_CHANGE_FORM_CHANGE_INSTANT)
{
// Skip mosaic animation
gTasks[taskId].data[0] = 2;
break;
}
SetGpuReg(REG_OFFSET_MOSAIC, 0);
if (GetBattlerSpriteBGPriorityRank(gBattleAnimAttacker) == 1)
SetAnimBgAttribute(1, BG_ANIM_MOSAIC, 1);
else
SetAnimBgAttribute(2, BG_ANIM_MOSAIC, 1);
gTasks[taskId].megaEvo = gBattleAnimArgs[0];
gTasks[taskId].trackEnemyPersonality = gBattleAnimArgs[1];
gTasks[taskId].ghostUnveil = gBattleAnimArgs[2];
gTasks[taskId].data[0]++;
break;
case 1:
@ -2616,7 +2616,7 @@ void AnimTask_TransformMon(u8 taskId)
}
break;
case 2:
HandleSpeciesGfxDataChange(gBattleAnimAttacker, gBattleAnimTarget, gTasks[taskId].megaEvo, gTasks[taskId].trackEnemyPersonality, gTasks[taskId].ghostUnveil);
HandleSpeciesGfxDataChange(gBattleAnimAttacker, gBattleAnimTarget, gTasks[taskId].data[10]);
GetBgDataForTransform(&animBg, gBattleAnimAttacker);
if (IsContest())
@ -2660,6 +2660,12 @@ void AnimTask_TransformMon(u8 taskId)
// StartSpriteAffineAnim(&gSprites[gBattlerSpriteIds[gBattleAnimAttacker]], BATTLER_AFFINE_NORMAL);
}
if (gTasks[taskId].data[10] == SPECIES_GFX_CHANGE_FORM_CHANGE_INSTANT)
{
// Skip mosaic animation
DestroyAnimVisualTask(taskId);
break;
}
gTasks[taskId].data[0]++;
break;
case 3:
@ -2685,7 +2691,7 @@ void AnimTask_TransformMon(u8 taskId)
{
if (!IsOnPlayerSide(gBattleAnimAttacker))
{
if (gTasks[taskId].data[10] == 0)
if (gTasks[taskId].data[10] == SPECIES_GFX_CHANGE_TRANSFORM)
SetBattlerShadowSpriteCallback(gBattleAnimAttacker, gBattleSpritesDataPtr->battlerData[gBattleAnimAttacker].transformSpecies);
}
}
@ -2695,10 +2701,6 @@ void AnimTask_TransformMon(u8 taskId)
}
}
#undef megaEvo
#undef trackEnemyPersonality
#undef ghostUnveil
void AnimTask_IsMonInvisible(u8 taskId)
{
gBattleAnimArgs[ARG_RET_ID] = gSprites[gBattlerSpriteIds[gBattleAnimAttacker]].invisible;

View File

@ -562,48 +562,56 @@ static void BufferArenaOpponentName(void)
void DrawArenaRefereeTextBox(void)
{
u8 width = 27;
u8 palNum = 7;
u32 width = 0x1A;
u32 pal = 7;
FillBgTilemapBufferRect(0, 0, 254, 14, 1, 6, palNum);
FillBgTilemapBufferRect(0, 0, 32, 14, 1, 6, palNum);
FillBgTilemapBufferRect(0, 0x31, 0, 14, 1, 1, palNum);
FillBgTilemapBufferRect(0, 0x33, 1, 14, 1, 1, palNum);
FillBgTilemapBufferRect(0, 0x34, 2, 14, width, 1, palNum);
width++;
FillBgTilemapBufferRect(0, 0x35, 28, 14, 1, 1, palNum);
FillBgTilemapBufferRect(0, 0x36, 29, 14, 1, 1, palNum);
FillBgTilemapBufferRect(0, 0x37, 0, 15, 1, 5, palNum);
FillBgTilemapBufferRect(0, 0x39, 1, 15, width, 5, palNum);
FillBgTilemapBufferRect(0, 0x3A, 29, 15, 1, 5, palNum);
FillBgTilemapBufferRect(0, 0x831, 0, 19, 1, 1, palNum);
FillBgTilemapBufferRect(0, 0x833, 1, 19, 1, 1, palNum);
FillBgTilemapBufferRect(0, 0x834, 2, 19, width - 2, 1, palNum);
FillBgTilemapBufferRect(0, 0x835, 28, 19, 1, 1, palNum);
FillBgTilemapBufferRect(0, 0x836, 29, 19, 1, 1, palNum);
FillBgTilemapBufferRect(0, 0x30, 0, 0xE, 1, 1, pal);
FillBgTilemapBufferRect(0, 0x31, 1, 0xE, 1, 1, pal);
FillBgTilemapBufferRect(0, 0x32, 2, 0xE, width, 1, pal);
FillBgTilemapBufferRect(0, 0x33, 0x1C, 0xE, 1, 1, pal);
FillBgTilemapBufferRect(0, 0x34, 0x1D, 0xE, 1, 1, pal);
FillBgTilemapBufferRect(0, 0x35, 0, 0xF, 1, 1, pal);
FillBgTilemapBufferRect(0, 0x36, 1, 0xF, 1, 1, pal);
FillBgTilemapBufferRect(0, 0x38, 0x1C, 0xF, 1, 1, pal);
FillBgTilemapBufferRect(0, 0x39, 0x1D, 0xF, 1, 1, pal);
FillBgTilemapBufferRect(0, 0x3A, 0, 0x10, 1, 1, pal);
FillBgTilemapBufferRect(0, 0x3B, 1, 0x10, 1, 1, pal);
FillBgTilemapBufferRect(0, 0x3C, 0x1C, 0x10, 1, 1, pal);
FillBgTilemapBufferRect(0, 0x3D, 0x1D, 0x10, 1, 1, pal);
FillBgTilemapBufferRect(0, BG_TILE_V_FLIP(0x3A), 0, 0x11, 1, 1, pal);
FillBgTilemapBufferRect(0, BG_TILE_V_FLIP(0x3B), 1, 0x11, 1, 1, pal);
FillBgTilemapBufferRect(0, BG_TILE_V_FLIP(0x3C), 0x1C, 0x11, 1, 1, pal);
FillBgTilemapBufferRect(0, BG_TILE_V_FLIP(0x3D), 0x1D, 0x11, 1, 1, pal);
FillBgTilemapBufferRect(0, BG_TILE_V_FLIP(0x35), 0, 0x12, 1, 1, pal);
FillBgTilemapBufferRect(0, BG_TILE_V_FLIP(0x36), 1, 0x12, 1, 1, pal);
FillBgTilemapBufferRect(0, BG_TILE_V_FLIP(0x38), 0x1C, 0x12, 1, 1, pal);
FillBgTilemapBufferRect(0, BG_TILE_V_FLIP(0x39), 0x1D, 0x12, 1, 1, pal);
FillBgTilemapBufferRect(0, BG_TILE_V_FLIP(0x30), 0, 0x13, 1, 1, pal);
FillBgTilemapBufferRect(0, BG_TILE_V_FLIP(0x31), 1, 0x13, 1, 1, pal);
FillBgTilemapBufferRect(0, BG_TILE_V_FLIP(0x32), 2, 0x13, width, 1, pal);
FillBgTilemapBufferRect(0, BG_TILE_V_FLIP(0x33), 0x1C, 0x13, 1, 1, pal);
FillBgTilemapBufferRect(0, BG_TILE_V_FLIP(0x34), 0x1D, 0x13, 1, 1, pal);
}
void EraseArenaRefereeTextBox(void)
{
u8 width;
u8 height;
u8 palNum = 0;
u32 pal = 0;
u32 width = 0x1A;
u32 height = 4;
FillBgTilemapBufferRect(0, 3, 0, 14, 1, 1, palNum);
height = 4;
FillBgTilemapBufferRect(0, 4, 1, 14, 1, 1, palNum);
width = 27;
FillBgTilemapBufferRect(0, 5, 2, 14, width, 1, palNum);
FillBgTilemapBufferRect(0, 6, 28, 14, 1, 1, palNum);
FillBgTilemapBufferRect(0, 7, 29, 14, 1, 1, palNum);
FillBgTilemapBufferRect(0, 8, 0, 15, 1, height, palNum);
FillBgTilemapBufferRect(0, 9, 1, 15, 1, height, palNum);
FillBgTilemapBufferRect(0, 0xA, 2, 15, width, height, palNum);
FillBgTilemapBufferRect(0, 0xB, 28, 15, 1, height, palNum);
FillBgTilemapBufferRect(0, 0xC, 29, 15, 1, height, palNum);
FillBgTilemapBufferRect(0, 0xD, 0, 19, 1, 1, palNum);
FillBgTilemapBufferRect(0, 0xE, 1, 19, 1, 1, palNum);
FillBgTilemapBufferRect(0, 0xF, 2, 19, width, 1, palNum);
FillBgTilemapBufferRect(0, 0x10, 28, 19, 1, 1, palNum);
FillBgTilemapBufferRect(0, 0x11, 29, 19, 1, 1, palNum);
FillBgTilemapBufferRect(0, 3, 0, 0xE, 1, 1, pal);
FillBgTilemapBufferRect(0, 4, 1, 0xE, 1, 1, pal);
FillBgTilemapBufferRect(0, 5, 2, 0xE, width, 1, pal);
FillBgTilemapBufferRect(0, 6, 0x1C, 0xE, 1, 1, pal);
FillBgTilemapBufferRect(0, 7, 0x1D, 0xE, 1, 1, pal);
FillBgTilemapBufferRect(0, 8, 0, 0xF, 1, height, pal);
FillBgTilemapBufferRect(0, 9, 1, 0xF, 1, height, pal);
FillBgTilemapBufferRect(0, 0xA, 2, 0xF, width, height, pal);
FillBgTilemapBufferRect(0, 0xB, 0x1C, 0xF, 1, height, pal);
FillBgTilemapBufferRect(0, 0xC, 0x1D, 0xF, 1, height, pal);
FillBgTilemapBufferRect(0, 0xD, 0, 0x13, 1, 1, pal);
FillBgTilemapBufferRect(0, 0xE, 1, 0x13, 1, 1, pal);
FillBgTilemapBufferRect(0, 0xF, 2, 0x13, width, 1, pal);
FillBgTilemapBufferRect(0, 0x10, 0x1C, 0x13, 1, 1, pal);
FillBgTilemapBufferRect(0, 0x11, 0x1D, 0x13, 1, 1, pal);
}

View File

@ -732,7 +732,7 @@ void LoadBattleMenuWindowGfx(void)
gPlttBufferUnfaded[BG_PLTT_ID(5) + 15] = RGB( 26, 26, 25);
CpuCopy16(&gPlttBufferUnfaded[BG_PLTT_ID(5) + 12], &gPlttBufferFaded[BG_PLTT_ID(5) + 12], PLTT_SIZEOF(4));
if (gBattleTypeFlags & (BATTLE_TYPE_FIRST_BATTLE | BATTLE_TYPE_POKEDUDE))
if (gBattleTypeFlags & (BATTLE_TYPE_ARENA | BATTLE_TYPE_FIRST_BATTLE | BATTLE_TYPE_POKEDUDE))
{
// Load graphics for the Battle Arena referee's mid-battle messages.
Menu_LoadStdPalAt(BG_PLTT_ID(7));

View File

@ -6,9 +6,11 @@
#include "battle_interface.h"
#include "battle_message.h"
#include "battle_setup.h"
#include "battle_tower.h"
// #include "battle_tv.h"
#include "bg.h"
#include "data.h"
#include "frontier_util.h"
#include "link.h"
#include "main.h"
#include "m4a.h"
@ -29,17 +31,17 @@
#include "recorded_battle.h"
#include "random.h"
static void LinkOpponentHandleDrawTrainerPic(u32 battler);
static void LinkOpponentHandleTrainerSlide(u32 battler);
static void LinkOpponentHandleTrainerSlideBack(u32 battler);
static void LinkOpponentHandleIntroTrainerBallThrow(u32 battler);
static void LinkOpponentHandleDrawPartyStatusSummary(u32 battler);
static void LinkOpponentHandleLinkStandbyMsg(u32 battler);
static void LinkOpponentHandleEndLinkBattle(u32 battler);
static void LinkOpponentHandleDrawTrainerPic(enum BattlerId battler);
static void LinkOpponentHandleTrainerSlide(enum BattlerId battler);
static void LinkOpponentHandleTrainerSlideBack(enum BattlerId battler);
static void LinkOpponentHandleIntroTrainerBallThrow(enum BattlerId battler);
static void LinkOpponentHandleDrawPartyStatusSummary(enum BattlerId battler);
static void LinkOpponentHandleLinkStandbyMsg(enum BattlerId battler);
static void LinkOpponentHandleEndLinkBattle(enum BattlerId battler);
static void LinkOpponentBufferRunCommand(u32 battler);
static void LinkOpponentBufferRunCommand(enum BattlerId battler);
static void (*const sLinkOpponentBufferCommands[CONTROLLER_CMDS_COUNT])(u32 battler) =
static void (*const sLinkOpponentBufferCommands[CONTROLLER_CMDS_COUNT])(enum BattlerId battler) =
{
[CONTROLLER_GETMONDATA] = BtlController_HandleGetMonData,
[CONTROLLER_GETRAWMONDATA] = BtlController_Empty,
@ -96,13 +98,14 @@ static void (*const sLinkOpponentBufferCommands[CONTROLLER_CMDS_COUNT])(u32 batt
[CONTROLLER_TERMINATOR_NOP] = BtlController_TerminatorNop
};
void SetControllerToLinkOpponent(u32 battler)
void SetControllerToLinkOpponent(enum BattlerId battler)
{
gBattlerBattleController[battler] = BATTLE_CONTROLLER_LINK_OPPONENT;
gBattlerControllerEndFuncs[battler] = LinkOpponentBufferExecCompleted;
gBattlerControllerFuncs[battler] = LinkOpponentBufferRunCommand;
}
static void LinkOpponentBufferRunCommand(u32 battler)
static void LinkOpponentBufferRunCommand(enum BattlerId battler)
{
if (IsBattleControllerActiveOnLocal(battler))
{
@ -113,7 +116,7 @@ static void LinkOpponentBufferRunCommand(u32 battler)
}
}
static void Intro_WaitForShinyAnimAndHealthbox(u32 battler)
static void Intro_WaitForShinyAnimAndHealthbox(enum BattlerId battler)
{
bool32 healthboxAnimDone = FALSE;
bool32 twoMons = FALSE;
@ -148,8 +151,7 @@ static void Intro_WaitForShinyAnimAndHealthbox(u32 battler)
gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(battler)].triedShinyMonAnim = FALSE;
gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(battler)].finishedShinyMonAnim = FALSE;
FreeSpriteTilesByTag(ANIM_TAG_GOLD_STARS);
FreeSpritePaletteByTag(ANIM_TAG_GOLD_STARS);
FreeShinyStars();
}
else
{
@ -160,10 +162,7 @@ static void Intro_WaitForShinyAnimAndHealthbox(u32 battler)
gBattleSpritesDataPtr->healthBoxesData[battler].finishedShinyMonAnim = FALSE;
if (GetBattlerPosition(battler) == B_POSITION_OPPONENT_RIGHT)
{
FreeSpriteTilesByTag(ANIM_TAG_GOLD_STARS);
FreeSpritePaletteByTag(ANIM_TAG_GOLD_STARS);
}
FreeShinyStars();
}
gBattleSpritesDataPtr->healthBoxesData[battler].introEndDelay = 3;
@ -171,7 +170,7 @@ static void Intro_WaitForShinyAnimAndHealthbox(u32 battler)
}
}
static void Intro_TryShinyAnimShowHealthbox(u32 battler)
static void Intro_TryShinyAnimShowHealthbox(enum BattlerId battler)
{
bool32 bgmRestored = FALSE;
@ -248,7 +247,7 @@ static void Intro_TryShinyAnimShowHealthbox(u32 battler)
DestroySprite(&gSprites[gBattleControllerData[battler]]);
SetBattlerShadowSpriteCallback(battler, GetMonData(GetBattlerMon(battler), MON_DATA_SPECIES));
SetBattlerShadowSpriteCallback(battler, GetBattlerVisualSpecies(battler));
gBattleSpritesDataPtr->animationData->introAnimActive = FALSE;
gBattleSpritesDataPtr->healthBoxesData[battler].bgmRestored = FALSE;
@ -259,7 +258,7 @@ static void Intro_TryShinyAnimShowHealthbox(u32 battler)
}
}
void LinkOpponentBufferExecCompleted(u32 battler)
void LinkOpponentBufferExecCompleted(enum BattlerId battler)
{
gBattlerControllerFuncs[battler] = LinkOpponentBufferRunCommand;
if (gBattleTypeFlags & BATTLE_TYPE_LINK)
@ -275,34 +274,41 @@ void LinkOpponentBufferExecCompleted(u32 battler)
}
}
static void LinkOpponentHandleDrawTrainerPic(u32 battler)
static void LinkOpponentHandleDrawTrainerPic(enum BattlerId battler)
{
s16 xPos;
u32 trainerPicId;
enum TrainerPicID trainerPicId;
enum BattlerPosition position = GetBattlerPosition(battler);
if (gBattleTypeFlags & BATTLE_TYPE_MULTI)
{
if ((GetBattlerPosition(battler) & BIT_FLANK) != 0) // second mon
if ((position & BIT_FLANK) != 0) // second mon
xPos = 152;
else // first mon
xPos = 200;
if ((gLinkPlayers[GetBattlerMultiplayerId(battler)].version & 0xFF) == VERSION_RUBY
|| (gLinkPlayers[GetBattlerMultiplayerId(battler)].version & 0xFF) == VERSION_SAPPHIRE
|| (gLinkPlayers[GetBattlerMultiplayerId(battler)].version & 0xFF) == VERSION_EMERALD)
if (gBattleTypeFlags & BATTLE_TYPE_BATTLE_TOWER)
{
if (gLinkPlayers[GetBattlerMultiplayerId(battler)].gender != MALE)
trainerPicId = gFacilityClassToPicIndex[FACILITY_CLASS_PKMN_TRAINER_MAY];
if (position == B_POSITION_OPPONENT_LEFT)
trainerPicId = GetFrontierTrainerFrontSpriteId(TRAINER_BATTLE_PARAM.opponentA);
else
trainerPicId = gFacilityClassToPicIndex[FACILITY_CLASS_PKMN_TRAINER_BRENDAN];
}
else if (gLinkPlayers[GetBattlerMultiplayerId(battler)].gender != MALE)
{
trainerPicId = gFacilityClassToPicIndex[FACILITY_CLASS_LEAF];
trainerPicId = GetFrontierTrainerFrontSpriteId(TRAINER_BATTLE_PARAM.opponentB);
}
else
{
trainerPicId = gFacilityClassToPicIndex[FACILITY_CLASS_RED];
if ((gLinkPlayers[GetBattlerMultiplayerId(battler)].version & 0xFF) == VERSION_RUBY
|| (gLinkPlayers[GetBattlerMultiplayerId(battler)].version & 0xFF) == VERSION_SAPPHIRE
|| (gLinkPlayers[GetBattlerMultiplayerId(battler)].version & 0xFF) == VERSION_EMERALD)
{
if (gLinkPlayers[GetBattlerMultiplayerId(battler)].gender != MALE)
trainerPicId = gFacilityClassToPicIndex[FACILITY_CLASS_PKMN_TRAINER_MAY];
else
trainerPicId = gFacilityClassToPicIndex[FACILITY_CLASS_PKMN_TRAINER_BRENDAN];
}
else
{
trainerPicId = PlayerGenderToFrontTrainerPicId(gLinkPlayers[GetBattlerMultiplayerId(battler)].gender);
}
}
}
else
@ -321,57 +327,59 @@ static void LinkOpponentHandleDrawTrainerPic(u32 battler)
else
trainerPicId = gFacilityClassToPicIndex[FACILITY_CLASS_PKMN_TRAINER_BRENDAN];
}
else if (gLinkPlayers[GetMultiplayerId() ^ BIT_SIDE].gender != MALE)
{
trainerPicId = gFacilityClassToPicIndex[FACILITY_CLASS_LEAF];
}
else
{
trainerPicId = gFacilityClassToPicIndex[FACILITY_CLASS_RED];
trainerPicId = PlayerGenderToFrontTrainerPicId(gLinkPlayers[GetMultiplayerId() ^ BIT_SIDE].gender);
}
}
BtlController_HandleDrawTrainerPic(battler, trainerPicId, TRUE, xPos, 40, -1);
}
static void LinkOpponentHandleTrainerSlide(u32 battler)
static void LinkOpponentHandleTrainerSlide(enum BattlerId battler)
{
u32 trainerPicId = TRAINER_PIC_RED;
enum TrainerPicID trainerPicId;
if (GetBattlerPosition(battler) == B_POSITION_OPPONENT_LEFT)
trainerPicId = GetFrontierTrainerFrontSpriteId(TRAINER_BATTLE_PARAM.opponentA);
else
trainerPicId = GetFrontierTrainerFrontSpriteId(TRAINER_BATTLE_PARAM.opponentB);
BtlController_HandleTrainerSlide(battler, trainerPicId);
BtlController_Complete(battler); // Possibly a bug, because execution should be completed after the slide in finishes. See Controller_WaitForTrainerPic.
}
static void LinkOpponentHandleTrainerSlideBack(u32 battler)
static void LinkOpponentHandleTrainerSlideBack(enum BattlerId battler)
{
BtlController_HandleTrainerSlideBack(battler, 35, FALSE);
}
static void LinkOpponentHandleIntroTrainerBallThrow(u32 battler)
static void LinkOpponentHandleIntroTrainerBallThrow(enum BattlerId battler)
{
BtlController_HandleIntroTrainerBallThrow(battler, 0, NULL, 0, Intro_TryShinyAnimShowHealthbox);
}
static void LinkOpponentHandleDrawPartyStatusSummary(u32 battler)
static void LinkOpponentHandleDrawPartyStatusSummary(enum BattlerId battler)
{
BtlController_HandleDrawPartyStatusSummary(battler, B_SIDE_OPPONENT, TRUE);
}
static void LinkOpponentHandleLinkStandbyMsg(u32 battler)
static void LinkOpponentHandleLinkStandbyMsg(enum BattlerId battler)
{
// RecordedBattle_RecordAllBattlerData(&gBattleResources->bufferA[battler][2]);
RecordedBattle_RecordAllBattlerData(&gBattleResources->bufferA[battler][2]);
BtlController_Complete(battler);
}
static void LinkOpponentHandleEndLinkBattle(u32 battler)
static void LinkOpponentHandleEndLinkBattle(enum BattlerId battler)
{
// RecordedBattle_RecordAllBattlerData(&gBattleResources->bufferA[battler][4]);
RecordedBattle_RecordAllBattlerData(&gBattleResources->bufferA[battler][4]);
if (gBattleResources->bufferA[battler][1] == B_OUTCOME_DREW)
gBattleOutcome = gBattleResources->bufferA[battler][1];
else
gBattleOutcome = gBattleResources->bufferA[battler][1] ^ B_OUTCOME_DREW;
// gSaveBlock2Ptr->frontier.disableRecordBattle = gBattleResources->bufferA[battler][2];
gSaveBlock2Ptr->frontier.disableRecordBattle = gBattleResources->bufferA[battler][2];
FadeOutMapMusic(5);
BeginFastPaletteFade(3);
BtlController_Complete(battler);

View File

@ -6,9 +6,11 @@
#include "battle_interface.h"
#include "battle_message.h"
#include "battle_setup.h"
#include "battle_tower.h"
// #include "battle_tv.h"
#include "bg.h"
#include "data.h"
#include "frontier_util.h"
#include "link.h"
#include "main.h"
#include "m4a.h"
@ -29,16 +31,16 @@
#include "recorded_battle.h"
#include "random.h"
static void LinkPartnerHandleDrawTrainerPic(u32 battler);
static void LinkPartnerHandleTrainerSlideBack(u32 battler);
static void LinkPartnerHandleIntroTrainerBallThrow(u32 battler);
static void LinkPartnerHandleDrawPartyStatusSummary(u32 battler);
static void LinkPartnerHandleLinkStandbyMsg(u32 battler);
static void LinkPartnerHandleEndLinkBattle(u32 battler);
static void LinkPartnerHandleDrawTrainerPic(enum BattlerId battler);
static void LinkPartnerHandleTrainerSlideBack(enum BattlerId battler);
static void LinkPartnerHandleIntroTrainerBallThrow(enum BattlerId battler);
static void LinkPartnerHandleDrawPartyStatusSummary(enum BattlerId battler);
static void LinkPartnerHandleLinkStandbyMsg(enum BattlerId battler);
static void LinkPartnerHandleEndLinkBattle(enum BattlerId battler);
static void LinkPartnerBufferRunCommand(u32 battler);
static void LinkPartnerBufferRunCommand(enum BattlerId battler);
static void (*const sLinkPartnerBufferCommands[CONTROLLER_CMDS_COUNT])(u32 battler) =
static void (*const sLinkPartnerBufferCommands[CONTROLLER_CMDS_COUNT])(enum BattlerId battler) =
{
[CONTROLLER_GETMONDATA] = BtlController_HandleGetMonData,
[CONTROLLER_GETRAWMONDATA] = BtlController_Empty,
@ -95,13 +97,14 @@ static void (*const sLinkPartnerBufferCommands[CONTROLLER_CMDS_COUNT])(u32 battl
[CONTROLLER_TERMINATOR_NOP] = BtlController_TerminatorNop
};
void SetControllerToLinkPartner(u32 battler)
void SetControllerToLinkPartner(enum BattlerId battler)
{
gBattlerBattleController[battler] = BATTLE_CONTROLLER_LINK_PARTNER;
gBattlerControllerEndFuncs[battler] = LinkPartnerBufferExecCompleted;
gBattlerControllerFuncs[battler] = LinkPartnerBufferRunCommand;
}
static void LinkPartnerBufferRunCommand(u32 battler)
static void LinkPartnerBufferRunCommand(enum BattlerId battler)
{
if (IsBattleControllerActiveOnLocal(battler))
{
@ -112,7 +115,7 @@ static void LinkPartnerBufferRunCommand(u32 battler)
}
}
void LinkPartnerBufferExecCompleted(u32 battler)
void LinkPartnerBufferExecCompleted(enum BattlerId battler)
{
gBattlerControllerFuncs[battler] = LinkPartnerBufferRunCommand;
if (gBattleTypeFlags & BATTLE_TYPE_LINK)
@ -128,10 +131,10 @@ void LinkPartnerBufferExecCompleted(u32 battler)
}
}
static void LinkPartnerHandleDrawTrainerPic(u32 battler)
static void LinkPartnerHandleDrawTrainerPic(enum BattlerId battler)
{
s16 xPos;
u32 trainerPicId;
enum TrainerPicID trainerPicId;
if (gBattleTypeFlags & BATTLE_TYPE_MULTI)
{
@ -151,35 +154,35 @@ static void LinkPartnerHandleDrawTrainerPic(u32 battler)
-1);
}
static void LinkPartnerHandleTrainerSlideBack(u32 battler)
static void LinkPartnerHandleTrainerSlideBack(enum BattlerId battler)
{
BtlController_HandleTrainerSlideBack(battler, 35, FALSE);
}
static void LinkPartnerHandleIntroTrainerBallThrow(u32 battler)
static void LinkPartnerHandleIntroTrainerBallThrow(enum BattlerId battler)
{
u32 trainerPicId = LinkPlayerGetTrainerPicId(GetBattlerMultiplayerId(battler));
enum TrainerPicID trainerPicId = LinkPlayerGetTrainerPicId(GetBattlerMultiplayerId(battler));
const u16 *trainerPal = gTrainerBacksprites[trainerPicId].palette.data;
// Link partner uses the same intro sequence as the player partner.
BtlController_HandleIntroTrainerBallThrow(battler, 0xD6F9, trainerPal, 24, Controller_PlayerPartnerShowIntroHealthbox);
}
static void LinkPartnerHandleDrawPartyStatusSummary(u32 battler)
static void LinkPartnerHandleDrawPartyStatusSummary(enum BattlerId battler)
{
BtlController_HandleDrawPartyStatusSummary(battler, B_SIDE_PLAYER, TRUE);
}
static void LinkPartnerHandleLinkStandbyMsg(u32 battler)
static void LinkPartnerHandleLinkStandbyMsg(enum BattlerId battler)
{
// RecordedBattle_RecordAllBattlerData(&gBattleResources->bufferA[battler][2]);
RecordedBattle_RecordAllBattlerData(&gBattleResources->bufferA[battler][2]);
BtlController_Complete(battler);
}
static void LinkPartnerHandleEndLinkBattle(u32 battler)
static void LinkPartnerHandleEndLinkBattle(enum BattlerId battler)
{
// RecordedBattle_RecordAllBattlerData(&gBattleResources->bufferA[battler][4]);
RecordedBattle_RecordAllBattlerData(&gBattleResources->bufferA[battler][4]);
gBattleOutcome = gBattleResources->bufferA[battler][1];
// gSaveBlock2Ptr->frontier.disableRecordBattle = gBattleResources->bufferA[battler][2];
gSaveBlock2Ptr->frontier.disableRecordBattle = gBattleResources->bufferA[battler][2];
FadeOutMapMusic(5);
BeginFastPaletteFade(3);
BtlController_Complete(battler);

View File

@ -1,48 +1,52 @@
#include "global.h"
#include "gflib.h"
#include "task.h"
#include "pokeball.h"
#include "party_menu.h"
#include "util.h"
#include "m4a.h"
#include "link.h"
#include "item.h"
#include "item_menu.h"
#include "strings.h"
#include "battle.h"
#include "battle_anim.h"
#include "battle_controllers.h"
#include "battle_interface.h"
#include "battle_message.h"
#include "bg.h"
#include "item.h"
#include "item_menu.h"
#include "link.h"
#include "m4a.h"
#include "palette.h"
#include "party_menu.h"
#include "pokeball.h"
#include "reshow_battle_screen.h"
#include "sound.h"
#include "strings.h"
#include "task.h"
#include "text.h"
#include "util.h"
#include "constants/battle_string_ids.h"
#include "constants/songs.h"
#include "constants/items.h"
#include "constants/rgb.h"
#include "constants/songs.h"
static void OakOldManHandleDrawTrainerPic(u32 battler);
static void OakOldManHandleTrainerSlide(u32 battler);
static void OakOldManHandlePrintString(u32 battler);
static void OakOldManHandlePrintSelectionString(u32 battler);
static void OakOldManHandleChooseAction(u32 battler);
static void OakOldManHandleChooseMove(u32 battler);
static void OakOldManHandleChooseItem(u32 battler);
static void OakOldManHandleChoosePokemon(u32 battler);
static void OakOldManHandlePlaySE(u32 battler);
static void OakOldManHandleFaintingCry(u32 battler);
static void OakOldManHandleIntroTrainerBallThrow(u32 battler);
static void OakOldManHandleDrawPartyStatusSummary(u32 battler);
static void OakOldManHandleEndBounceEffect(u32 battler);
static void OakOldManHandleLinkStandbyMsg(u32 battler);
static void OakOldManHandleEndLinkBattle(u32 battler);
static void OakOldManHandleDrawTrainerPic(enum BattlerId battler);
static void OakOldManHandleTrainerSlide(enum BattlerId battler);
static void OakOldManHandlePrintString(enum BattlerId battler);
static void OakOldManHandlePrintSelectionString(enum BattlerId battler);
static void OakOldManHandleChooseAction(enum BattlerId battler);
static void OakOldManHandleChooseMove(enum BattlerId battler);
static void OakOldManHandleChooseItem(enum BattlerId battler);
static void OakOldManHandleChoosePokemon(enum BattlerId battler);
static void OakOldManHandlePlaySE(enum BattlerId battler);
static void OakOldManHandleFaintingCry(enum BattlerId battler);
static void OakOldManHandleIntroTrainerBallThrow(enum BattlerId battler);
static void OakOldManHandleDrawPartyStatusSummary(enum BattlerId battler);
static void OakOldManHandleEndBounceEffect(enum BattlerId battler);
static void OakOldManHandleLinkStandbyMsg(enum BattlerId battler);
static void OakOldManHandleEndLinkBattle(enum BattlerId battler);
static void OakOldManBufferRunCommand(u32 battler);
static void WaitForMonSelection(u32 battler);
static void CompleteWhenChoseItem(u32 battler);
static void PrintOakText_KeepAnEyeOnHP(u32 battler);
static void Intro_WaitForShinyAnimAndHealthbox(u32 battler);
static void PrintOakText_ForPetesSake(u32 battler);
static void PrintOakTextWithMainBgDarkened(u32 battler, const u8 *text, u8 delay);
static void HandleInputChooseAction(u32 battler);
static void OakOldManBufferRunCommand(enum BattlerId battler);
static void WaitForMonSelection(enum BattlerId battler);
static void CompleteWhenChoseItem(enum BattlerId battler);
static void PrintOakText_KeepAnEyeOnHP(enum BattlerId battler);
static void Intro_WaitForShinyAnimAndHealthbox(enum BattlerId battler);
static void PrintOakText_ForPetesSake(enum BattlerId battler);
static void PrintOakTextWithMainBgDarkened(enum BattlerId battler, const u8 *text, u8 delay);
static void HandleInputChooseAction(enum BattlerId battler);
static const u8 sText_ForPetesSake[] = _("OAK: Oh, for Pete's sake…\nSo pushy, as always.\p{B_PLAYER_NAME}.\pYou've never had a POKéMON battle\nbefore, have you?\pA POKéMON battle is when TRAINERS\npit their POKéMON against each\lother.\p");
static const u8 sText_HowDissapointing[] = _("OAK: Hm…\nHow disappointing…\pIf you win, you earn prize money,\nand your POKéMON grow.\pBut if you lose, {B_PLAYER_NAME}, you end\nup paying prize money…\pHowever, since you had no warning\nthis time, I'll pay for you.\pBut things won't be this way once\nyou step outside these doors.\pThat's why you must strengthen your\nPOKéMON by battling wild POKéMON.\p");
@ -55,7 +59,7 @@ static const u8 sText_TryBattling[] = _("But rather than talking about it,\nyou'
static const u8 sText_WinEarnsPrizeMoney[] = _("OAK: Hm! Excellent!\pIf you win, you earn prize money,\nand your POKéMON will grow!\pBattle other TRAINERS and make\nyour POKéMON strong!\p");
static const u8 gText_WhatWillOldManDo[] = _("What will the\nold man do?");
static void (*const sOakOldManBufferCommands[CONTROLLER_CMDS_COUNT])(u32 battler) =
static void (*const sOakOldManBufferCommands[CONTROLLER_CMDS_COUNT])(enum BattlerId battler) =
{
[CONTROLLER_GETMONDATA] = BtlController_HandleGetMonData,
[CONTROLLER_GETRAWMONDATA] = BtlController_Empty,
@ -112,8 +116,9 @@ static void (*const sOakOldManBufferCommands[CONTROLLER_CMDS_COUNT])(u32 battler
[CONTROLLER_TERMINATOR_NOP] = BtlController_TerminatorNop,
};
void SetControllerToOakOrOldMan(u32 battler)
void SetControllerToOakOrOldMan(enum BattlerId battler)
{
gBattlerBattleController[battler] = BATTLE_CONTROLLER_OAK_OLD_MAN;
gBattlerControllerEndFuncs[battler] = OakOldManBufferExecCompleted;
gBattlerControllerFuncs[battler] = OakOldManBufferRunCommand;
gBattleStruct->simulatedInputState[0] = 0;
@ -122,7 +127,7 @@ void SetControllerToOakOrOldMan(u32 battler)
gBattleStruct->simulatedInputState[3] = 0;
}
static void OakOldManBufferRunCommand(u32 battler)
static void OakOldManBufferRunCommand(enum BattlerId battler)
{
if (gBattleControllerExecFlags & (1u << battler))
{
@ -133,7 +138,7 @@ static void OakOldManBufferRunCommand(u32 battler)
}
}
static void HandleInputChooseAction(u32 battler)
static void HandleInputChooseAction(enum BattlerId battler)
{
// Like player, but specifically for Rival in Oak's Lab
u16 itemId = gBattleResources->bufferA[battler][2] | (gBattleResources->bufferA[battler][3] << 8);
@ -205,13 +210,13 @@ static void HandleInputChooseAction(u32 battler)
{
if ((gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
&& GetBattlerPosition(battler) == B_POSITION_PLAYER_RIGHT
&& !(gAbsentBattlerFlags & gBitTable[GetBattlerAtPosition(B_POSITION_PLAYER_LEFT)])
&& !(gAbsentBattlerFlags & (1 << GetBattlerAtPosition(B_POSITION_PLAYER_LEFT)))
&& !(gBattleTypeFlags & BATTLE_TYPE_MULTI))
{
if (gBattleResources->bufferA[battler][1] == B_ACTION_USE_ITEM)
{
// Add item to bag if it is a ball
if (IsItemBall(itemId))
if (GetItemPocket(itemId) == POCKET_POKE_BALLS)
AddBagItem(itemId, 1);
else
return;
@ -227,7 +232,7 @@ static void HandleInputChooseAction(u32 battler)
}
}
static void SimulateInputChooseAction(u32 battler)
static void SimulateInputChooseAction(enum BattlerId battler)
{
// Old Man
switch (gBattleStruct->simulatedInputState[0])
@ -259,13 +264,13 @@ static void SimulateInputChooseAction(u32 battler)
}
}
static void CompleteOnInactiveTextPrinter(u32 battler)
static void CompleteOnInactiveTextPrinter(enum BattlerId battler)
{
if (!IsTextPrinterActiveOnWindow(0))
OakOldManBufferExecCompleted(battler);
}
static void OakOldManSetBattleEndCallbacks(u32 battler)
static void OakOldManSetBattleEndCallbacks(enum BattlerId battler)
{
if (!gPaletteFade.active)
{
@ -275,14 +280,14 @@ static void OakOldManSetBattleEndCallbacks(u32 battler)
}
}
void OakOldManHandleInputChooseMove(u32 battler)
void OakOldManHandleInputChooseMove(enum BattlerId battler)
{
HandleInputChooseMove(battler);
if (!(gBattleControllerExecFlags & (1u << battler)))
OakOldManBufferExecCompleted(battler);
}
static void OpenPartyMenuToChooseMon(u32 battler)
static void OpenPartyMenuToChooseMon(enum BattlerId battler)
{
if (!gPaletteFade.active)
{
@ -296,7 +301,7 @@ static void OpenPartyMenuToChooseMon(u32 battler)
}
}
static void WaitForMonSelection(u32 battler)
static void WaitForMonSelection(enum BattlerId battler)
{
if (gMain.callback2 == BattleMainCB2 && !gPaletteFade.active)
{
@ -308,7 +313,7 @@ static void WaitForMonSelection(u32 battler)
}
}
static void OpenBagAndChooseItem(u32 battler)
static void OpenBagAndChooseItem(enum BattlerId battler)
{
if (!gPaletteFade.active)
{
@ -322,7 +327,7 @@ static void OpenBagAndChooseItem(u32 battler)
}
}
static void CompleteWhenChoseItem(u32 battler)
static void CompleteWhenChoseItem(enum BattlerId battler)
{
if (gMain.callback2 == BattleMainCB2 && !gPaletteFade.active)
{
@ -341,7 +346,7 @@ static void CompleteWhenChoseItem(u32 battler)
}
}
static void Intro_TryShinyAnimShowHealthbox(u32 battler)
static void Intro_TryShinyAnimShowHealthbox(enum BattlerId battler)
{
if (!gBattleSpritesDataPtr->healthBoxesData[battler].triedShinyMonAnim
&& !gBattleSpritesDataPtr->healthBoxesData[battler].ballAnimActive)
@ -371,7 +376,7 @@ static void Intro_TryShinyAnimShowHealthbox(u32 battler)
}
}
static void Intro_WaitForShinyAnimAndHealthbox(u32 battler)
static void Intro_WaitForShinyAnimAndHealthbox(enum BattlerId battler)
{
bool32 r4 = FALSE;
@ -393,7 +398,7 @@ static void Intro_WaitForShinyAnimAndHealthbox(u32 battler)
}
}
static void PrintOakText_ForPetesSake(u32 battler)
static void PrintOakText_ForPetesSake(enum BattlerId battler)
{
u32 mask;
@ -446,7 +451,7 @@ static void PrintOakText_ForPetesSake(u32 battler)
case 5:
if (!IsTextPrinterActiveOnWindow(B_WIN_OAK_OLD_MAN))
{
mask = (gBitTable[gBattleStruct->simulatedInputState[1]] | gBitTable[gBattleStruct->simulatedInputState[3]]) << 16;
mask = ((1 << gBattleStruct->simulatedInputState[1]) | (1 << gBattleStruct->simulatedInputState[3])) << 16;
BeginNormalPaletteFade(mask,
4,
0,
@ -486,32 +491,32 @@ static void PrintOakText_ForPetesSake(u32 battler)
}
}
void PrintOakText_InflictingDamageIsKey(u32 battler)
void PrintOakText_InflictingDamageIsKey(enum BattlerId battler)
{
PrintOakTextWithMainBgDarkened(battler, sText_InflictingDamageIsKey, 1);
}
static void PrintOakText_LoweringStats(u32 battler)
static void PrintOakText_LoweringStats(enum BattlerId battler)
{
PrintOakTextWithMainBgDarkened(battler, sText_LoweringStats, 64);
}
void PrintOakText_OakNoRunningFromATrainer(u32 battler)
void PrintOakText_OakNoRunningFromATrainer(enum BattlerId battler)
{
PrintOakTextWithMainBgDarkened(battler, sText_OakNoRunningFromATrainer, 1);
}
static void PrintOakText_WinEarnsPrizeMoney(u32 battler)
static void PrintOakText_WinEarnsPrizeMoney(enum BattlerId battler)
{
PrintOakTextWithMainBgDarkened(battler, sText_WinEarnsPrizeMoney, 64);
}
void PrintOakText_HowDisappointing(u32 battler)
void PrintOakText_HowDisappointing(enum BattlerId battler)
{
PrintOakTextWithMainBgDarkened(battler, sText_HowDissapointing, 64);
}
static void PrintOakTextWithMainBgDarkened(u32 battler, const u8 *text, u8 delay)
static void PrintOakTextWithMainBgDarkened(enum BattlerId battler, const u8 *text, u8 delay)
{
// If delay is 0, it's treated as 256.
switch (gBattleStruct->simulatedInputState[0])
@ -572,7 +577,7 @@ static void PrintOakTextWithMainBgDarkened(u32 battler, const u8 *text, u8 delay
}
}
static void PrintOakText_KeepAnEyeOnHP(u32 battler)
static void PrintOakText_KeepAnEyeOnHP(enum BattlerId battler)
{
u32 mask;
@ -593,7 +598,7 @@ static void PrintOakText_KeepAnEyeOnHP(u32 battler)
case 1:
if (!gPaletteFade.active)
{
mask = (gBitTable[gBattleStruct->simulatedInputState[1]] | gBitTable[gBattleStruct->simulatedInputState[3]]) << 16;
mask = ((1 << gBattleStruct->simulatedInputState[1]) | (1 << gBattleStruct->simulatedInputState[3])) << 16;
BeginNormalPaletteFade(mask,
4,
8,
@ -617,7 +622,7 @@ static void PrintOakText_KeepAnEyeOnHP(u32 battler)
case 4:
if (!IsTextPrinterActiveOnWindow(B_WIN_OAK_OLD_MAN))
{
mask = (gBitTable[gBattleStruct->simulatedInputState[1]] | gBitTable[gBattleStruct->simulatedInputState[3]]) << 16;
mask = ((1 << gBattleStruct->simulatedInputState[1]) | (1 << gBattleStruct->simulatedInputState[3])) << 16;
BeginNormalPaletteFade(mask,
4,
0,
@ -649,7 +654,7 @@ static void PrintOakText_KeepAnEyeOnHP(u32 battler)
}
}
void OakOldManBufferExecCompleted(u32 battler)
void OakOldManBufferExecCompleted(enum BattlerId battler)
{
gBattlerControllerFuncs[battler] = OakOldManBufferRunCommand;
if (gBattleTypeFlags & BATTLE_TYPE_LINK)
@ -665,26 +670,26 @@ void OakOldManBufferExecCompleted(u32 battler)
}
}
static void OakOldManHandleDrawTrainerPic(u32 battler)
static void OakOldManHandleDrawTrainerPic(enum BattlerId battler)
{
u32 trainerPicId = (gBattleTypeFlags & BATTLE_TYPE_FIRST_BATTLE) ? gSaveBlock2Ptr->playerGender + TRAINER_BACK_PIC_RED : TRAINER_BACK_PIC_OLD_MAN;
BtlController_HandleDrawTrainerPic(battler, trainerPicId, FALSE, 80, (8 - gTrainerBacksprites[trainerPicId].coordinates.size) * 4 + 80, 30);
}
static void OakOldManHandleTrainerSlide(u32 battler)
static void OakOldManHandleTrainerSlide(enum BattlerId battler)
{
u32 trainerPicId = (gBattleTypeFlags & BATTLE_TYPE_FIRST_BATTLE) ? gSaveBlock2Ptr->playerGender + TRAINER_BACK_PIC_RED : TRAINER_BACK_PIC_OLD_MAN;
BtlController_HandleTrainerSlide(battler, trainerPicId);
}
static void OakOldManHandlePrintString(u32 battler)
static void OakOldManHandlePrintString(enum BattlerId battler)
{
u16 *stringId;
gBattle_BG0_X = 0;
gBattle_BG0_Y = 0;
stringId = (u16 *)(&gBattleResources->bufferA[battler][2]);
if (gBattleTypeFlags & BATTLE_TYPE_CATCH_TUTORIAL&& *stringId == STRINGID_INTROSENDOUT)
if (gBattleTypeFlags & BATTLE_TYPE_CATCH_TUTORIAL && *stringId == STRINGID_INTROSENDOUT)
{
OakOldManBufferExecCompleted(battler);
}
@ -722,7 +727,7 @@ static void OakOldManHandlePrintString(u32 battler)
}
}
static void OakOldManHandlePrintSelectionString(u32 battler)
static void OakOldManHandlePrintSelectionString(enum BattlerId battler)
{
if (GetBattlerSide(battler) == B_SIDE_PLAYER)
OakOldManHandlePrintString(battler);
@ -730,7 +735,7 @@ static void OakOldManHandlePrintSelectionString(u32 battler)
OakOldManBufferExecCompleted(battler);
}
static void HandleChooseActionAfterDma3(u32 battler)
static void HandleChooseActionAfterDma3(enum BattlerId battler)
{
if (!IsDma3ManagerBusyWithBgCopy())
{
@ -743,7 +748,7 @@ static void HandleChooseActionAfterDma3(u32 battler)
}
}
static void OakOldManHandleChooseAction(u32 battler)
static void OakOldManHandleChooseAction(enum BattlerId battler)
{
s32 i;
@ -763,7 +768,7 @@ static void OakOldManHandleChooseAction(u32 battler)
BattlePutTextOnWindow(gDisplayedStringBattle, B_WIN_ACTION_PROMPT);
}
static void OakHandleChooseMove_WaitDma3(u32 battler)
static void OakHandleChooseMove_WaitDma3(enum BattlerId battler)
{
if (!IsDma3ManagerBusyWithBgCopy())
{
@ -773,7 +778,7 @@ static void OakHandleChooseMove_WaitDma3(u32 battler)
}
}
static void OakOldManHandleChooseMove(u32 battler)
static void OakOldManHandleChooseMove(enum BattlerId battler)
{
if (gBattleTypeFlags & BATTLE_TYPE_FIRST_BATTLE)
{
@ -801,7 +806,7 @@ static void OakOldManHandleChooseMove(u32 battler)
}
}
static void OakOldManHandleChooseItem(u32 battler)
static void OakOldManHandleChooseItem(enum BattlerId battler)
{
s32 i;
@ -812,7 +817,7 @@ static void OakOldManHandleChooseItem(u32 battler)
gBattlePartyCurrentOrder[i] = gBattleResources->bufferA[battler][i + 1];
}
static void OakOldManHandleChoosePokemon(u32 battler)
static void OakOldManHandleChoosePokemon(enum BattlerId battler)
{
s32 i;
@ -828,13 +833,13 @@ static void OakOldManHandleChoosePokemon(u32 battler)
gBattlerInMenuId = battler;
}
static void OakOldManHandlePlaySE(u32 battler)
static void OakOldManHandlePlaySE(enum BattlerId battler)
{
PlaySE(gBattleResources->bufferA[battler][1] | (gBattleResources->bufferA[battler][2] << 8));
OakOldManBufferExecCompleted(battler);
}
static void OakOldManHandleFaintingCry(u32 battler)
static void OakOldManHandleFaintingCry(enum BattlerId battler)
{
u16 species = GetMonData(&gPlayerParty[gBattlerPartyIndexes[battler]], MON_DATA_SPECIES);
@ -842,7 +847,7 @@ static void OakOldManHandleFaintingCry(u32 battler)
OakOldManBufferExecCompleted(battler);
}
static void OakOldManHandleIntroTrainerBallThrow(u32 battler)
static void OakOldManHandleIntroTrainerBallThrow(enum BattlerId battler)
{
if (gBattleTypeFlags & BATTLE_TYPE_FIRST_BATTLE)
{
@ -857,7 +862,7 @@ static void OakOldManHandleIntroTrainerBallThrow(u32 battler)
}
}
static void OakOldManHandleDrawPartyStatusSummary(u32 battler)
static void OakOldManHandleDrawPartyStatusSummary(enum BattlerId battler)
{
if (gBattleResources->bufferA[battler][1] != 0
&& GetBattlerSide(battler) == B_SIDE_PLAYER)
@ -875,14 +880,14 @@ static void OakOldManHandleDrawPartyStatusSummary(u32 battler)
}
}
static void OakOldManHandleEndBounceEffect(u32 battler)
static void OakOldManHandleEndBounceEffect(enum BattlerId battler)
{
EndBounceEffect(battler, BOUNCE_HEALTHBOX);
EndBounceEffect(battler, BOUNCE_MON);
OakOldManBufferExecCompleted(battler);
}
static void OakOldManHandleLinkStandbyMsg(u32 battler)
static void OakOldManHandleLinkStandbyMsg(enum BattlerId battler)
{
switch (gBattleResources->bufferA[battler][1])
{
@ -897,7 +902,7 @@ static void OakOldManHandleLinkStandbyMsg(u32 battler)
OakOldManBufferExecCompleted(battler);
}
static void OakOldManHandleEndLinkBattle(u32 battler)
static void OakOldManHandleEndLinkBattle(enum BattlerId battler)
{
gBattleOutcome = gBattleResources->bufferA[battler][1];
FadeOutMapMusic(5);

View File

@ -3,20 +3,20 @@
#include "battle_ai_main.h"
#include "battle_ai_switch.h"
#include "battle_ai_util.h"
#include "constants/battle.h"
#include "constants/battle_ai.h"
#include "battle_anim.h"
// #include "battle_arena.h"
#include "battle_arena.h"
#include "battle_controllers.h"
#include "battle_message.h"
#include "battle_interface.h"
#include "battle_setup.h"
#include "battle_special.h"
// #include "battle_special.h"
// #include "battle_tv.h"
#include "battle_z_move.h"
#include "bg.h"
#include "data.h"
// #include "frontier_util.h"
#include "frontier_util.h"
#include "item.h"
#include "link.h"
#include "main.h"
@ -46,18 +46,18 @@
#include "test/battle.h"
#include "test/test_runner_battle.h"
static void OpponentHandleDrawTrainerPic(u32 battler);
static void OpponentHandleTrainerSlideBack(u32 battler);
static void OpponentHandleChooseAction(u32 battler);
static void OpponentHandleChooseMove(u32 battler);
static void OpponentHandleChooseItem(u32 battler);
static void OpponentHandleChoosePokemon(u32 battler);
static void OpponentHandleIntroTrainerBallThrow(u32 battler);
static void OpponentHandleDrawPartyStatusSummary(u32 battler);
static void OpponentHandleEndLinkBattle(u32 battler);
static void OpponentBufferRunCommand(u32 battler);
static void OpponentHandleDrawTrainerPic(enum BattlerId battler);
static void OpponentHandleTrainerSlideBack(enum BattlerId battler);
static void OpponentHandleChooseAction(enum BattlerId battler);
static void OpponentHandleChooseMove(enum BattlerId battler);
static void OpponentHandleChooseItem(enum BattlerId battler);
static void OpponentHandleChoosePokemon(enum BattlerId battler);
static void OpponentHandleIntroTrainerBallThrow(enum BattlerId battler);
static void OpponentHandleDrawPartyStatusSummary(enum BattlerId battler);
static void OpponentHandleEndLinkBattle(enum BattlerId battler);
static void OpponentBufferRunCommand(enum BattlerId battler);
static void (*const sOpponentBufferCommands[CONTROLLER_CMDS_COUNT])(u32 battler) =
static void (*const sOpponentBufferCommands[CONTROLLER_CMDS_COUNT])(enum BattlerId battler) =
{
[CONTROLLER_GETMONDATA] = BtlController_HandleGetMonData,
[CONTROLLER_GETRAWMONDATA] = BtlController_HandleGetRawMonData,
@ -114,14 +114,14 @@ static void (*const sOpponentBufferCommands[CONTROLLER_CMDS_COUNT])(u32 battler)
[CONTROLLER_TERMINATOR_NOP] = BtlController_TerminatorNop
};
void SetControllerToOpponent(u32 battler)
void SetControllerToOpponent(enum BattlerId battler)
{
gBattlerBattleController[battler] = BATTLE_CONTROLLER_OPPONENT;
gBattlerControllerEndFuncs[battler] = OpponentBufferExecCompleted;
gBattlerControllerFuncs[battler] = OpponentBufferRunCommand;
}
static void OpponentBufferRunCommand(u32 battler)
static void OpponentBufferRunCommand(enum BattlerId battler)
{
if (IsBattleControllerActiveOnLocal(battler))
{
@ -132,7 +132,7 @@ static void OpponentBufferRunCommand(u32 battler)
}
}
static void Intro_WaitForShinyAnimAndHealthbox(u32 battler)
static void Intro_WaitForShinyAnimAndHealthbox(enum BattlerId battler)
{
bool8 healthboxAnimDone = FALSE;
bool8 twoMons;
@ -197,7 +197,7 @@ static void Intro_WaitForShinyAnimAndHealthbox(u32 battler)
}
}
static void Intro_TryShinyAnimShowHealthbox(u32 battler)
static void Intro_TryShinyAnimShowHealthbox(enum BattlerId battler)
{
bool32 bgmRestored = FALSE;
bool32 battlerAnimsDone = FALSE;
@ -295,7 +295,7 @@ static void Intro_TryShinyAnimShowHealthbox(u32 battler)
}
}
void OpponentBufferExecCompleted(u32 battler)
void OpponentBufferExecCompleted(enum BattlerId battler)
{
gBattlerControllerFuncs[battler] = OpponentBufferRunCommand;
if (gBattleTypeFlags & BATTLE_TYPE_LINK)
@ -311,18 +311,36 @@ void OpponentBufferExecCompleted(u32 battler)
}
}
static u32 OpponentGetTrainerPicId(u32 battlerId)
static u32 OpponentGetTrainerPicId(enum BattlerId battlerId)
{
enum TrainerPicID trainerPicId;
if (gBattleTypeFlags & BATTLE_TYPE_FRONTIER)
if (gBattleTypeFlags & BATTLE_TYPE_SECRET_BASE)
{
trainerPicId = TRAINER_PIC_RED; // placeholder
trainerPicId = GetSecretBaseTrainerPicIndex();
}
else if (TRAINER_BATTLE_PARAM.opponentA == TRAINER_FRONTIER_BRAIN)
{
trainerPicId = GetFrontierBrainTrainerPicIndex();
}
else if (gBattleTypeFlags & BATTLE_TYPE_TRAINER_TOWER)
{
trainerPicId = GetTrainerTowerTrainerFrontSpriteId();
}
else if (gBattleTypeFlags & BATTLE_TYPE_FRONTIER)
{
if (gBattleTypeFlags & (BATTLE_TYPE_TWO_OPPONENTS | BATTLE_TYPE_TOWER_LINK_MULTI))
{
if (battlerId == 1)
trainerPicId = GetFrontierTrainerFrontSpriteId(TRAINER_BATTLE_PARAM.opponentA);
else
trainerPicId = GetFrontierTrainerFrontSpriteId(TRAINER_BATTLE_PARAM.opponentB);
}
else
{
trainerPicId = GetFrontierTrainerFrontSpriteId(TRAINER_BATTLE_PARAM.opponentA);
}
}
else if (gBattleTypeFlags & BATTLE_TYPE_EREADER_TRAINER)
{
trainerPicId = GetEreaderTrainerFrontSpriteId();
@ -342,7 +360,7 @@ static u32 OpponentGetTrainerPicId(u32 battlerId)
return trainerPicId;
}
static void OpponentHandleDrawTrainerPic(u32 battler)
static void OpponentHandleDrawTrainerPic(enum BattlerId battler)
{
s16 xPos;
enum TrainerPicID trainerPicId;
@ -384,24 +402,24 @@ static void OpponentHandleDrawTrainerPic(u32 battler)
BtlController_HandleDrawTrainerPic(battler, trainerPicId, TRUE, xPos, 40, -1);
}
void OpponentHandleTrainerSlide(u32 battler)
void OpponentHandleTrainerSlide(enum BattlerId battler)
{
enum TrainerPicID trainerPicId = OpponentGetTrainerPicId(battler);
BtlController_HandleTrainerSlide(battler, trainerPicId);
}
static void OpponentHandleTrainerSlideBack(u32 battler)
static void OpponentHandleTrainerSlideBack(enum BattlerId battler)
{
BtlController_HandleTrainerSlideBack(battler, 35, FALSE);
}
static void OpponentHandleChooseAction(u32 battler)
static void OpponentHandleChooseAction(enum BattlerId battler)
{
AI_TrySwitchOrUseItem(battler);
BtlController_Complete(battler);
}
static void OpponentHandleChooseMove(u32 battler)
static void OpponentHandleChooseMove(enum BattlerId battler)
{
u32 chosenMoveIndex;
struct ChooseMoveStruct *moveInfo = (struct ChooseMoveStruct *)(&gBattleResources->bufferA[battler][4]);
@ -411,7 +429,7 @@ static void OpponentHandleChooseMove(u32 battler)
{
if (gBattleTypeFlags & BATTLE_TYPE_PALACE)
{
// BtlController_EmitTwoReturnValues(battler, B_COMM_TO_ENGINE, B_ACTION_EXEC_SCRIPT, ChooseMoveAndTargetInBattlePalace(battler));
BtlController_EmitTwoReturnValues(battler, B_COMM_TO_ENGINE, B_ACTION_EXEC_SCRIPT, ChooseMoveAndTargetInBattlePalace(battler));
}
else if (gAiBattleData->actionFlee)
{
@ -464,16 +482,18 @@ static void OpponentHandleChooseMove(u32 battler)
move = moveInfo->moves[chosenMoveIndex];
} while (move == MOVE_NONE);
enum MoveTarget target = GetBattlerMoveTargetType(battler, move);
if (target == TARGET_USER || target == TARGET_USER_OR_ALLY)
enum MoveTarget moveTarget = GetBattlerMoveTargetType(battler, move);
if (moveTarget == TARGET_USER || moveTarget == TARGET_USER_OR_ALLY)
{
BtlController_EmitTwoReturnValues(battler, B_COMM_TO_ENGINE, B_ACTION_EXEC_SCRIPT, (chosenMoveIndex) | (battler << 8));
}
else if (IsDoubleBattle())
{
enum BattlerId targetBattler;
do {
target = GetBattlerAtPosition(Random() & 2);
} while (!CanTargetBattler(battler, target, move));
enum BattlerPosition pos = RandomPercentage(RNG_WILD_MON_TARGET, 50) ? B_POSITION_PLAYER_LEFT : B_POSITION_PLAYER_RIGHT;
targetBattler = GetBattlerAtPosition(pos);
} while (!CanTargetBattler(battler, targetBattler, move));
// Don't bother to check if they're enemies if the move can't attack ally
if (B_WILD_NATURAL_ENEMIES == TRUE && GetBattlerMoveTargetType(battler, move) != TARGET_BOTH)
@ -484,14 +504,14 @@ static void OpponentHandleChooseMove(u32 battler)
bool32 isPartnerEnemy = IsNaturalEnemy(speciesAttacker, speciesTarget);
if (isPartnerEnemy && CanTargetBattler(battler, target, move))
if (isPartnerEnemy && CanTargetBattler(battler, GetBattlerAtPosition(BATTLE_PARTNER(battler)), move))
BtlController_EmitTwoReturnValues(battler, B_COMM_TO_ENGINE, B_ACTION_EXEC_SCRIPT, (chosenMoveIndex) | (GetBattlerAtPosition(BATTLE_PARTNER(battler)) << 8));
else
BtlController_EmitTwoReturnValues(battler, B_COMM_TO_ENGINE, B_ACTION_EXEC_SCRIPT, (chosenMoveIndex) | (target << 8));
BtlController_EmitTwoReturnValues(battler, B_COMM_TO_ENGINE, B_ACTION_EXEC_SCRIPT, (chosenMoveIndex) | (targetBattler << 8));
}
else
{
BtlController_EmitTwoReturnValues(battler, B_COMM_TO_ENGINE, B_ACTION_EXEC_SCRIPT, (chosenMoveIndex) | (target << 8));
BtlController_EmitTwoReturnValues(battler, B_COMM_TO_ENGINE, B_ACTION_EXEC_SCRIPT, (chosenMoveIndex) | (targetBattler << 8));
}
}
else
@ -501,13 +521,13 @@ static void OpponentHandleChooseMove(u32 battler)
}
}
static void OpponentHandleChooseItem(u32 battler)
static void OpponentHandleChooseItem(enum BattlerId battler)
{
BtlController_EmitOneReturnValue(battler, B_COMM_TO_ENGINE, gBattleStruct->chosenItem[battler]);
BtlController_Complete(battler);
}
static void OpponentHandleChoosePokemon(u32 battler)
static void OpponentHandleChoosePokemon(enum BattlerId battler)
{
s32 chosenMonId;
enum SwitchType switchType = SWITCH_AFTER_KO;
@ -534,7 +554,8 @@ static void OpponentHandleChoosePokemon(u32 battler)
chosenMonId = GetMostSuitableMonToSwitchInto(battler, switchType);
if (chosenMonId == PARTY_SIZE) // Advanced logic failed so we pick the next available battler
{
s32 battler1, battler2, firstId, lastId;
enum BattlerId battler1, battler2;
s32 firstId, lastId;
if (!IsDoubleBattle())
{
@ -570,17 +591,17 @@ static void OpponentHandleChoosePokemon(u32 battler)
BtlController_Complete(battler);
}
static void OpponentHandleIntroTrainerBallThrow(u32 battler)
static void OpponentHandleIntroTrainerBallThrow(enum BattlerId battler)
{
BtlController_HandleIntroTrainerBallThrow(battler, 0, NULL, 0, Intro_TryShinyAnimShowHealthbox);
}
static void OpponentHandleDrawPartyStatusSummary(u32 battler)
static void OpponentHandleDrawPartyStatusSummary(enum BattlerId battler)
{
BtlController_HandleDrawPartyStatusSummary(battler, B_SIDE_OPPONENT, TRUE);
}
static void OpponentHandleEndLinkBattle(u32 battler)
static void OpponentHandleEndLinkBattle(enum BattlerId battler)
{
if (gBattleTypeFlags & BATTLE_TYPE_LINK && !(gBattleTypeFlags & BATTLE_TYPE_IS_MASTER))
{

View File

@ -1,9 +1,9 @@
#include "global.h"
#include "battle.h"
#include "battle_anim.h"
// #include "battle_arena.h"
#include "battle_arena.h"
#include "battle_controllers.h"
// #include "battle_dome.h"
#include "battle_dome.h"
#include "battle_interface.h"
#include "battle_message.h"
#include "battle_setup.h"
@ -51,41 +51,41 @@
#include "test/battle.h"
#include "test/test_runner_battle.h"
static void PlayerHandleLoadMonSprite(u32 battler);
static void PlayerHandleDrawTrainerPic(u32 battler);
static void PlayerHandleTrainerSlide(u32 battler);
static void PlayerHandleTrainerSlideBack(u32 battler);
static void PlayerHandlePaletteFade(u32 battler);
static void PlayerHandlePause(u32 battler);
static void PlayerHandleChooseAction(u32 battler);
static void PlayerHandleYesNoBox(u32 battler);
static void PlayerHandleChooseItem(u32 battler);
static void PlayerHandleChoosePokemon(u32 battler);
static void PlayerHandleCmd23(u32 battler);
static void PlayerHandleStatusXor(u32 battler);
static void PlayerHandleDMA3Transfer(u32 battler);
static void PlayerHandlePlayBGM(u32 battler);
static void PlayerHandleTwoReturnValues(u32 battler);
static void PlayerHandleChosenMonReturnValue(u32 battler);
static void PlayerHandleOneReturnValue(u32 battler);
static void PlayerHandleOneReturnValue_Duplicate(u32 battler);
static void PlayerHandleIntroTrainerBallThrow(u32 battler);
static void PlayerHandleDrawPartyStatusSummary(u32 battler);
static void PlayerHandleEndBounceEffect(u32 battler);
static void PlayerHandleLinkStandbyMsg(u32 battler);
static void PlayerHandleResetActionMoveSelection(u32 battler);
static void PlayerHandleEndLinkBattle(u32 battler);
static void PlayerHandleBattleDebug(u32 battler);
static void PlayerHandleLoadMonSprite(enum BattlerId battler);
static void PlayerHandleDrawTrainerPic(enum BattlerId battler);
static void PlayerHandleTrainerSlide(enum BattlerId battler);
static void PlayerHandleTrainerSlideBack(enum BattlerId battler);
static void PlayerHandlePaletteFade(enum BattlerId battler);
static void PlayerHandlePause(enum BattlerId battler);
static void PlayerHandleChooseAction(enum BattlerId battler);
static void PlayerHandleYesNoBox(enum BattlerId battler);
static void PlayerHandleChooseItem(enum BattlerId battler);
static void PlayerHandleChoosePokemon(enum BattlerId battler);
static void PlayerHandleCmd23(enum BattlerId battler);
static void PlayerHandleStatusXor(enum BattlerId battler);
static void PlayerHandleDMA3Transfer(enum BattlerId battler);
static void PlayerHandlePlayBGM(enum BattlerId battler);
static void PlayerHandleTwoReturnValues(enum BattlerId battler);
static void PlayerHandleChosenMonReturnValue(enum BattlerId battler);
static void PlayerHandleOneReturnValue(enum BattlerId battler);
static void PlayerHandleOneReturnValue_Duplicate(enum BattlerId battler);
static void PlayerHandleIntroTrainerBallThrow(enum BattlerId battler);
static void PlayerHandleDrawPartyStatusSummary(enum BattlerId battler);
static void PlayerHandleEndBounceEffect(enum BattlerId battler);
static void PlayerHandleLinkStandbyMsg(enum BattlerId battler);
static void PlayerHandleResetActionMoveSelection(enum BattlerId battler);
static void PlayerHandleEndLinkBattle(enum BattlerId battler);
static void PlayerHandleBattleDebug(enum BattlerId battler);
static void PlayerBufferRunCommand(u32 battler);
static void MoveSelectionDisplayPpNumber(u32 battler);
static void MoveSelectionDisplayPpString(u32 battler);
static void MoveSelectionDisplayMoveType(u32 battler);
static void MoveSelectionDisplayMoveNames(u32 battler);
static void TryMoveSelectionDisplayMoveDescription(u32 battler);
static void MoveSelectionDisplayMoveDescription(u32 battler);
static void WaitForMonSelection(u32 battler);
static void CompleteWhenChoseItem(u32 battler);
static void PlayerBufferRunCommand(enum BattlerId battler);
static void MoveSelectionDisplayPpNumber(enum BattlerId battler);
static void MoveSelectionDisplayPpString(enum BattlerId battler);
static void MoveSelectionDisplayMoveType(enum BattlerId battler);
static void MoveSelectionDisplayMoveNames(enum BattlerId battler);
static void TryMoveSelectionDisplayMoveDescription(enum BattlerId battler);
static void MoveSelectionDisplayMoveDescription(enum BattlerId battler);
static void WaitForMonSelection(enum BattlerId battler);
static void CompleteWhenChoseItem(enum BattlerId battler);
static void Task_LaunchLvlUpAnim(u8);
static void Task_PrepareToGiveExpWithExpBar(u8);
static void Task_SetControllerToWaitForString(u8);
@ -94,12 +94,12 @@ static void Task_UpdateLvlInHealthbox(u8);
static void PrintLinkStandbyMsg(void);
static void Task_CreateLevelUpVerticalStripes(u8 taskId);
static void ReloadMoveNames(u32 battler);
static u32 CheckTypeEffectiveness(u32 battlerAtk, u32 battlerDef);
static u32 CheckTargetTypeEffectiveness(u32 battler);
static void MoveSelectionDisplayMoveEffectiveness(u32 foeEffectiveness, u32 battler);
static void ReloadMoveNames(enum BattlerId battler);
static u32 CheckTypeEffectiveness(enum BattlerId battlerAtk, enum BattlerId battlerDef);
static u32 CheckTargetTypeEffectiveness(enum BattlerId battler);
static void MoveSelectionDisplayMoveEffectiveness(u32 foeEffectiveness, enum BattlerId battler);
static void (*const sPlayerBufferCommands[CONTROLLER_CMDS_COUNT])(u32 battler) =
static void (*const sPlayerBufferCommands[CONTROLLER_CMDS_COUNT])(enum BattlerId battler) =
{
[CONTROLLER_GETMONDATA] = BtlController_HandleGetMonData,
[CONTROLLER_GETRAWMONDATA] = BtlController_HandleGetRawMonData,
@ -156,7 +156,7 @@ static void (*const sPlayerBufferCommands[CONTROLLER_CMDS_COUNT])(u32 battler) =
[CONTROLLER_TERMINATOR_NOP] = BtlController_TerminatorNop
};
void SetControllerToPlayer(u32 battler)
void SetControllerToPlayer(enum BattlerId battler)
{
gBattlerBattleController[battler] = BATTLE_CONTROLLER_PLAYER;
gBattlerControllerEndFuncs[battler] = PlayerBufferExecCompleted;
@ -165,7 +165,7 @@ void SetControllerToPlayer(u32 battler)
gPlayerDpadHoldFrames = 0;
}
void PlayerBufferExecCompleted(u32 battler)
void PlayerBufferExecCompleted(enum BattlerId battler)
{
gBattlerControllerFuncs[battler] = PlayerBufferRunCommand;
if (gBattleTypeFlags & BATTLE_TYPE_LINK)
@ -181,7 +181,7 @@ void PlayerBufferExecCompleted(u32 battler)
}
}
static void PlayerBufferRunCommand(u32 battler)
static void PlayerBufferRunCommand(enum BattlerId battler)
{
if (IsBattleControllerActiveOnLocal(battler))
{
@ -192,7 +192,7 @@ static void PlayerBufferRunCommand(u32 battler)
}
}
static void CompleteOnBattlerSpritePosX_0(u32 battler)
static void CompleteOnBattlerSpritePosX_0(enum BattlerId battler)
{
if (gSprites[gBattlerSpriteIds[battler]].x2 == 0)
BtlController_Complete(battler);
@ -232,7 +232,7 @@ static u32 GetNextBall(u32 ballId)
return ballId;
}
static void HandleInputChooseAction(u32 battler)
static void HandleInputChooseAction(enum BattlerId battler)
{
enum Item itemId = gBattleResources->bufferA[battler][2] | (gBattleResources->bufferA[battler][3] << 8);
@ -411,12 +411,18 @@ static void HandleInputChooseAction(u32 battler)
}
}
void HandleInputChooseTarget(u32 battler)
void HandleInputChooseTarget(enum BattlerId battler)
{
s32 i;
static const u8 identities[MAX_BATTLERS_COUNT] = {B_POSITION_PLAYER_LEFT, B_POSITION_PLAYER_RIGHT, B_POSITION_OPPONENT_RIGHT, B_POSITION_OPPONENT_LEFT};
enum BattlerId i;
static const enum BattlerPosition identities[MAX_BATTLERS_COUNT] =
{
B_POSITION_PLAYER_LEFT,
B_POSITION_PLAYER_RIGHT,
B_POSITION_OPPONENT_RIGHT,
B_POSITION_OPPONENT_LEFT,
};
enum Move move = GetMonData(GetBattlerMon(battler), MON_DATA_MOVE1 + gMoveSelectionCursor[battler]);
u16 moveTarget = GetBattlerMoveTargetType(battler, move);
enum MoveTarget moveTarget = GetBattlerMoveTargetType(battler, move);
DoBounceEffect(gMultiUsePlayerCursor, BOUNCE_HEALTHBOX, 15, 1);
for (i = 0; i < gBattlersCount; i++)
@ -502,7 +508,7 @@ void HandleInputChooseTarget(u32 battler)
break;
}
if (B_SHOW_EFFECTIVENESS)
MoveSelectionDisplayMoveEffectiveness(CheckTypeEffectiveness(battler, GetBattlerPosition(gMultiUsePlayerCursor)), battler);
MoveSelectionDisplayMoveEffectiveness(CheckTypeEffectiveness(battler, gMultiUsePlayerCursor), battler);
if (gAbsentBattlerFlags & (1u << gMultiUsePlayerCursor)
|| !CanTargetBattler(battler, gMultiUsePlayerCursor, move)
@ -555,7 +561,7 @@ void HandleInputChooseTarget(u32 battler)
break;
}
if (B_SHOW_EFFECTIVENESS)
MoveSelectionDisplayMoveEffectiveness(CheckTypeEffectiveness(battler, GetBattlerPosition(gMultiUsePlayerCursor)), battler);
MoveSelectionDisplayMoveEffectiveness(CheckTypeEffectiveness(battler, gMultiUsePlayerCursor), battler);
if (gAbsentBattlerFlags & (1u << gMultiUsePlayerCursor)
|| !CanTargetBattler(battler, gMultiUsePlayerCursor, move)
@ -570,8 +576,7 @@ void HandleInputChooseTarget(u32 battler)
static void HideAllTargets(void)
{
s32 i;
for (i = 0; i < MAX_BATTLERS_COUNT; i++)
for (enum BattlerId i = 0; i < MAX_BATTLERS_COUNT; i++)
{
if (IsBattlerAlive(i) && gBattleSpritesDataPtr->healthBoxesData[i].healthboxIsBouncing)
{
@ -581,7 +586,7 @@ static void HideAllTargets(void)
}
}
static void HideShownTargets(u32 battler)
static void HideShownTargets(enum BattlerId battler)
{
s32 i;
for (i = 0; i < MAX_BATTLERS_COUNT; i++)
@ -594,7 +599,7 @@ static void HideShownTargets(u32 battler)
}
}
void HandleInputShowEntireFieldTargets(u32 battler)
void HandleInputShowEntireFieldTargets(enum BattlerId battler)
{
if (JOY_HELD(DPAD_ANY) && gSaveBlock2Ptr->optionsButtonMode == OPTIONS_BUTTON_MODE_L_EQUALS_A)
gPlayerDpadHoldFrames++;
@ -622,7 +627,7 @@ void HandleInputShowEntireFieldTargets(u32 battler)
}
}
void HandleInputShowTargets(u32 battler)
void HandleInputShowTargets(enum BattlerId battler)
{
if (JOY_HELD(DPAD_ANY) && gSaveBlock2Ptr->optionsButtonMode == OPTIONS_BUTTON_MODE_L_EQUALS_A)
gPlayerDpadHoldFrames++;
@ -651,7 +656,7 @@ void HandleInputShowTargets(u32 battler)
}
}
static void TryShowAsTarget(u32 battler)
static void TryShowAsTarget(enum BattlerId battler)
{
if (IsBattlerAlive(battler))
{
@ -681,7 +686,7 @@ static bool32 CanSelectBattler(enum MoveTarget target)
return FALSE;
}
void HandleInputChooseMove(u32 battler)
void HandleInputChooseMove(enum BattlerId battler)
{
u32 canSelectTarget = 0;
struct ChooseMoveStruct *moveInfo = (struct ChooseMoveStruct *)(&gBattleResources->bufferA[battler][4]);
@ -737,8 +742,7 @@ void HandleInputChooseMove(u32 battler)
// Show all available targets for multi-target moves
if (moveTarget == TARGET_ALL_BATTLERS || moveTarget == TARGET_FIELD)
{
u32 i = 0;
for (i = 0; i < gBattlersCount; i++)
for (enum BattlerId i = 0; i < gBattlersCount; i++)
TryShowAsTarget(i);
canSelectTarget = 3;
@ -776,7 +780,7 @@ void HandleInputChooseMove(u32 battler)
else
gMultiUsePlayerCursor = GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT);
if (B_SHOW_EFFECTIVENESS)
MoveSelectionDisplayMoveEffectiveness(CheckTypeEffectiveness(battler, GetBattlerPosition(gMultiUsePlayerCursor)), battler);
MoveSelectionDisplayMoveEffectiveness(CheckTypeEffectiveness(battler, gMultiUsePlayerCursor), battler);
gSprites[gBattlerSpriteIds[gMultiUsePlayerCursor]].callback = SpriteCB_ShowAsMoveTarget;
break;
@ -929,7 +933,7 @@ void HandleInputChooseMove(u32 battler)
}
}
static void ReloadMoveNames(u32 battler)
static void ReloadMoveNames(enum BattlerId battler)
{
if (gBattleStruct->zmove.viable && !gBattleStruct->zmove.viewing)
{
@ -949,7 +953,7 @@ static void ReloadMoveNames(u32 battler)
}
}
static u32 UNUSED HandleMoveInputUnused(u32 battler)
static u32 UNUSED HandleMoveInputUnused(enum BattlerId battler)
{
u32 var = 0;
@ -999,7 +1003,7 @@ static u32 UNUSED HandleMoveInputUnused(u32 battler)
return var;
}
void HandleMoveSwitching(u32 battler)
void HandleMoveSwitching(enum BattlerId battler)
{
u8 perMovePPBonuses[MAX_MON_MOVES];
struct ChooseMoveStruct moveStruct;
@ -1199,7 +1203,7 @@ void HandleMoveSwitching(u32 battler)
}
}
static void SetLinkBattleEndCallbacks(u32 battler)
static void SetLinkBattleEndCallbacks(enum BattlerId battler)
{
if (gWirelessCommType == 0)
{
@ -1230,7 +1234,7 @@ static void SetLinkBattleEndCallbacks(u32 battler)
}
// Despite handling link battles separately, this is only ever used by link battles
void SetBattleEndCallbacks(u32 battler)
void SetBattleEndCallbacks(enum BattlerId battler)
{
if (!gPaletteFade.active)
{
@ -1256,7 +1260,7 @@ void SetBattleEndCallbacks(u32 battler)
}
}
static void Intro_WaitForShinyAnimAndHealthbox(u32 battler)
static void Intro_WaitForShinyAnimAndHealthbox(enum BattlerId battler)
{
bool8 healthboxAnimDone = FALSE;
@ -1294,7 +1298,7 @@ static void Intro_WaitForShinyAnimAndHealthbox(u32 battler)
}
}
static void Intro_TryShinyAnimShowHealthbox(u32 battler)
static void Intro_TryShinyAnimShowHealthbox(enum BattlerId battler)
{
bool32 bgmRestored = FALSE;
bool32 battlerAnimsDone = FALSE;
@ -1395,7 +1399,7 @@ void Task_PlayerController_RestoreBgmAfterCry(u8 taskId)
#define tExpTask_gainedExp_2 data[4] // Stored as two half-words containing a word.
#define tExpTask_frames data[10]
static void DynamaxModifyHPLevelUp(struct Pokemon *mon, u32 battler, u32 oldMaxHP)
static void DynamaxModifyHPLevelUp(struct Pokemon *mon, enum BattlerId battler, u32 oldMaxHP)
{
ApplyDynamaxHPMultiplier(mon);
gBattleScripting.levelUpHP = GetMonData(mon, MON_DATA_MAX_HP) - oldMaxHP; // overwrite levelUpHP since it overflows
@ -1411,7 +1415,7 @@ static s32 GetTaskExpValue(u8 taskId)
static void Task_GiveExpToMon(u8 taskId)
{
u32 monId = (u8)(gTasks[taskId].tExpTask_monId);
u8 battler = gTasks[taskId].tExpTask_battler;
enum BattlerId battler = gTasks[taskId].tExpTask_battler;
s32 gainedExp = GetTaskExpValue(taskId);
if (GetBattlerCoordsIndex(battler) == BATTLE_COORDS_DOUBLES || monId != gBattlerPartyIndexes[battler]) // Give exp without moving the expbar.
@ -1461,7 +1465,7 @@ static void Task_PrepareToGiveExpWithExpBar(u8 taskId)
{
u8 monIndex = gTasks[taskId].tExpTask_monId;
s32 gainedExp = GetTaskExpValue(taskId);
u8 battler = gTasks[taskId].tExpTask_battler;
enum BattlerId battler = gTasks[taskId].tExpTask_battler;
struct Pokemon *mon = &gPlayerParty[monIndex];
u8 level = GetMonData(mon, MON_DATA_LEVEL);
u16 species = GetMonData(mon, MON_DATA_SPECIES);
@ -1492,7 +1496,7 @@ static void Task_GiveExpWithExpBar(u8 taskId)
{
u8 monId = gTasks[taskId].tExpTask_monId;
s32 gainedExp = GetTaskExpValue(taskId);
u8 battler = gTasks[taskId].tExpTask_battler;
enum BattlerId battler = gTasks[taskId].tExpTask_battler;
struct Pokemon *mon = &gPlayerParty[monId];
newExpPoints = MoveBattleBar(battler, gHealthboxSpriteIds[battler], EXP_BAR, 0);
@ -1537,7 +1541,7 @@ static void Task_GiveExpWithExpBar(u8 taskId)
static void Task_LaunchLvlUpAnim(u8 taskId)
{
u8 battler = gTasks[taskId].tExpTask_battler;
enum BattlerId battler = gTasks[taskId].tExpTask_battler;
u8 monIndex = gTasks[taskId].tExpTask_monId;
if (IsDoubleBattle() == TRUE && monIndex == gBattlerPartyIndexes[BATTLE_PARTNER(battler)])
@ -1549,7 +1553,7 @@ static void Task_LaunchLvlUpAnim(u8 taskId)
static void Task_UpdateLvlInHealthbox(u8 taskId)
{
u8 battler = gTasks[taskId].tExpTask_battler;
enum BattlerId battler = gTasks[taskId].tExpTask_battler;
if (!gBattleSpritesDataPtr->healthBoxesData[battler].specialAnimActive)
{
@ -1566,16 +1570,16 @@ static void Task_UpdateLvlInHealthbox(u8 taskId)
static void Task_SetControllerToWaitForString(u8 taskId)
{
u8 battlerId = gTasks[taskId].tExpTask_battler;
enum BattlerId battler = gTasks[taskId].tExpTask_battler;
if (IsBattlerSpriteVisible(battlerId) == TRUE && !gTestRunnerEnabled)
if (IsBattlerSpriteVisible(battler) == TRUE && !gTestRunnerEnabled)
{
gTasks[taskId].func = Task_CreateLevelUpVerticalStripes;
gTasks[taskId].data[15] = 0;
}
else
{
gBattlerControllerFuncs[battlerId] = Controller_WaitForString;
gBattlerControllerFuncs[battler] = Controller_WaitForString;
DestroyTask(taskId);
}
}
@ -1583,10 +1587,10 @@ static void Task_SetControllerToWaitForString(u8 taskId)
static void Task_CreateLevelUpVerticalStripes(u8 taskId)
{
s16 *data = gTasks[taskId].data;
u8 battlerId = tExpTask_battler;
u16 bgPriorityRank = GetBattlerSpriteBGPriorityRank(battlerId);
enum BattlerId battler = tExpTask_battler;
u16 bgPriorityRank = GetBattlerSpriteBGPriorityRank(battler);
bool32 isOnBg2 = ((bgPriorityRank ^ 1)) != 0;
struct Sprite *sprite = &gSprites[gBattlerSpriteIds[battlerId]];
struct Sprite *sprite = &gSprites[gBattlerSpriteIds[battler]];
switch (data[15])
{
@ -1611,12 +1615,7 @@ static void Task_CreateLevelUpVerticalStripes(u8 taskId)
}
break;
case 1:
{
u32 battlerIdAlt = battlerId;
bool32 v6Alt = isOnBg2;
MoveBattlerSpriteToBG(battlerIdAlt, v6Alt, FALSE);
}
MoveBattlerSpriteToBG(battler, isOnBg2, FALSE);
++data[15];
break;
case 2:
@ -1655,13 +1654,13 @@ static void Task_CreateLevelUpVerticalStripes(u8 taskId)
gBattle_BG2_X = data[14];
gBattle_BG2_Y = data[13];
}
gBattlerControllerFuncs[battlerId] = Controller_WaitForString;
gBattlerControllerFuncs[battler] = Controller_WaitForString;
DestroyTask(taskId);
break;
}
}
static void OpenPartyMenuToChooseMon(u32 battler)
static void OpenPartyMenuToChooseMon(enum BattlerId battler)
{
if (!gPaletteFade.active)
{
@ -1675,7 +1674,7 @@ static void OpenPartyMenuToChooseMon(u32 battler)
}
}
static void WaitForMonSelection(u32 battler)
static void WaitForMonSelection(enum BattlerId battler)
{
if (gMain.callback2 == BattleMainCB2 && !gPaletteFade.active)
{
@ -1691,7 +1690,7 @@ static void WaitForMonSelection(u32 battler)
}
}
static void OpenBagAndChooseItem(u32 battler)
static void OpenBagAndChooseItem(enum BattlerId battler)
{
if (!gPaletteFade.active)
{
@ -1702,7 +1701,7 @@ static void OpenBagAndChooseItem(u32 battler)
}
}
static void CompleteWhenChoseItem(u32 battler)
static void CompleteWhenChoseItem(enum BattlerId battler)
{
if (gMain.callback2 == BattleMainCB2 && !gPaletteFade.active)
{
@ -1711,7 +1710,7 @@ static void CompleteWhenChoseItem(u32 battler)
}
}
static void PlayerHandleYesNoInput(u32 battler)
static void PlayerHandleYesNoInput(enum BattlerId battler)
{
if (JOY_NEW(DPAD_UP) && gMultiUsePlayerCursor != 0)
{
@ -1747,7 +1746,7 @@ static void PlayerHandleYesNoInput(u32 battler)
}
}
static void MoveSelectionDisplayMoveNames(u32 battler)
static void MoveSelectionDisplayMoveNames(enum BattlerId battler)
{
s32 i;
struct ChooseMoveStruct *moveInfo = (struct ChooseMoveStruct *)(&gBattleResources->bufferA[battler][4]);
@ -1767,13 +1766,13 @@ static void MoveSelectionDisplayMoveNames(u32 battler)
}
}
static void MoveSelectionDisplayPpString(u32 battler)
static void MoveSelectionDisplayPpString(enum BattlerId battler)
{
StringCopy(gDisplayedStringBattle, gText_MoveInterfacePP);
BattlePutTextOnWindow(gDisplayedStringBattle, B_WIN_PP);
}
static void MoveSelectionDisplayPpNumber(u32 battler)
static void MoveSelectionDisplayPpNumber(enum BattlerId battler)
{
u8 *txtPtr;
struct ChooseMoveStruct *moveInfo;
@ -1790,7 +1789,7 @@ static void MoveSelectionDisplayPpNumber(u32 battler)
BattlePutTextOnWindow(gDisplayedStringBattle, B_WIN_PP_REMAINING);
}
static void MoveSelectionDisplayMoveType(u32 battler)
static void MoveSelectionDisplayMoveType(enum BattlerId battler)
{
u8 *txtPtr, *end;
u32 speciesId = gBattleMons[battler].species;
@ -1834,7 +1833,7 @@ static void MoveSelectionDisplayMoveType(u32 battler)
BattlePutTextOnWindow(gDisplayedStringBattle, B_WIN_MOVE_TYPE);
}
static void TryMoveSelectionDisplayMoveDescription(u32 battler)
static void TryMoveSelectionDisplayMoveDescription(enum BattlerId battler)
{
if (!B_SHOW_MOVE_DESCRIPTION)
return;
@ -1843,7 +1842,7 @@ static void TryMoveSelectionDisplayMoveDescription(u32 battler)
MoveSelectionDisplayMoveDescription(battler);
}
static void MoveSelectionDisplayMoveDescription(u32 battler)
static void MoveSelectionDisplayMoveDescription(enum BattlerId battler)
{
struct ChooseMoveStruct *moveInfo = (struct ChooseMoveStruct*)(&gBattleResources->bufferA[battler][4]);
enum Move move = moveInfo->moves[gMoveSelectionCursor[battler]];
@ -1955,7 +1954,7 @@ static void PrintLinkStandbyMsg(void)
}
}
static void PlayerHandleLoadMonSprite(u32 battler)
static void PlayerHandleLoadMonSprite(enum BattlerId battler)
{
BattleLoadMonSpriteGfx(GetBattlerMon(battler), battler);
gSprites[gBattlerSpriteIds[battler]].oam.paletteNum = battler;
@ -1992,7 +1991,7 @@ static enum TrainerPicID PlayerGetTrainerBackPicId(void)
// In emerald it's possible to have a tag battle in the battle frontier facilities with AI
// which use the front sprite for both the player and the partner as opposed to any other battles (including the one with Steven)
// that use an animated back pic.
static void PlayerHandleDrawTrainerPic(u32 battler)
static void PlayerHandleDrawTrainerPic(enum BattlerId battler)
{
bool32 isFrontPic;
s16 xPos, yPos;
@ -2049,24 +2048,24 @@ static void PlayerHandleDrawTrainerPic(u32 battler)
BtlController_HandleDrawTrainerPic(battler, trainerPicId, isFrontPic, xPos, yPos, -1);
}
static void PlayerHandleTrainerSlide(u32 battler)
static void PlayerHandleTrainerSlide(enum BattlerId battler)
{
enum TrainerPicID trainerPicId = PlayerGetTrainerBackPicId();
BtlController_HandleTrainerSlide(battler, trainerPicId);
}
static void PlayerHandleTrainerSlideBack(u32 battler)
static void PlayerHandleTrainerSlideBack(enum BattlerId battler)
{
BtlController_HandleTrainerSlideBack(battler, 50, TRUE);
}
static void PlayerHandlePaletteFade(u32 battler)
static void PlayerHandlePaletteFade(enum BattlerId battler)
{
BeginNormalPaletteFade(PALETTES_ALL, 2, 0, 16, RGB_BLACK);
BtlController_Complete(battler);
}
static void PlayerHandlePause(u32 battler)
static void PlayerHandlePause(enum BattlerId battler)
{
u8 timer = gBattleResources->bufferA[battler][1];
@ -2076,7 +2075,7 @@ static void PlayerHandlePause(u32 battler)
BtlController_Complete(battler);
}
static void HandleChooseActionAfterDma3(u32 battler)
static void HandleChooseActionAfterDma3(enum BattlerId battler)
{
if (!IsDma3ManagerBusyWithBgCopy())
{
@ -2103,7 +2102,7 @@ static void HandleChooseActionAfterDma3(u32 battler)
}
}
static void PlayerHandleChooseAction(u32 battler)
static void PlayerHandleChooseAction(enum BattlerId battler)
{
s32 i;
@ -2119,21 +2118,22 @@ static void PlayerHandleChooseAction(u32 battler)
PREPARE_MON_NICK_BUFFER(gBattleTextBuff1, battler, gBattlerPartyIndexes[battler]);
BattleStringExpandPlaceholdersToDisplayedString(gText_WhatWillPkmnDo);
if (B_SHOW_PARTNER_TARGET && gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER && IsBattlerAlive(B_POSITION_PLAYER_RIGHT))
enum BattlerId partner = GetBattlerAtPosition(B_POSITION_PLAYER_RIGHT);
if (B_SHOW_PARTNER_TARGET && gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER && IsBattlerAlive(partner))
{
StringCopy(gStringVar1, COMPOUND_STRING("Partner will use:\n"));
enum Move move = GetChosenMoveFromPosition(B_POSITION_PLAYER_RIGHT);
enum Move move = GetBattlerChosenMove(partner);
StringAppend(gStringVar1, GetMoveName(move));
enum MoveTarget moveTarget = GetBattlerMoveTargetType(B_POSITION_PLAYER_RIGHT, move);
enum MoveTarget moveTarget = GetBattlerMoveTargetType(partner, move);
if (moveTarget == TARGET_SELECTED || moveTarget == TARGET_SMART)
{
if (gAiBattleData->chosenTarget[B_POSITION_PLAYER_RIGHT] == B_POSITION_OPPONENT_LEFT)
if (gAiBattleData->chosenTarget[partner] == B_POSITION_OPPONENT_LEFT)
StringAppend(gStringVar1, COMPOUND_STRING(" -{UP_ARROW}"));
else if (gAiBattleData->chosenTarget[B_POSITION_PLAYER_RIGHT] == B_POSITION_OPPONENT_RIGHT)
else if (gAiBattleData->chosenTarget[partner] == B_POSITION_OPPONENT_RIGHT)
StringAppend(gStringVar1, COMPOUND_STRING(" {UP_ARROW}-"));
else if (gAiBattleData->chosenTarget[B_POSITION_PLAYER_RIGHT] == B_POSITION_PLAYER_LEFT)
else if (gAiBattleData->chosenTarget[partner] == B_POSITION_PLAYER_LEFT)
StringAppend(gStringVar1, COMPOUND_STRING(" {DOWN_ARROW}-"));
else if (gAiBattleData->chosenTarget[B_POSITION_PLAYER_RIGHT] == B_POSITION_PLAYER_RIGHT)
else if (gAiBattleData->chosenTarget[partner] == B_POSITION_PLAYER_RIGHT)
StringAppend(gStringVar1, COMPOUND_STRING(" -{DOWN_ARROW}"));
}
else if (moveTarget == TARGET_USER_AND_ALLY)
@ -2160,7 +2160,7 @@ static void PlayerHandleChooseAction(u32 battler)
}
}
static void PlayerHandleYesNoBox(u32 battler)
static void PlayerHandleYesNoBox(enum BattlerId battler)
{
if (IsOnPlayerSide(battler))
{
@ -2176,7 +2176,7 @@ static void PlayerHandleYesNoBox(u32 battler)
}
}
void HandleChooseMoveAfterDma3(u32 battler)
void HandleChooseMoveAfterDma3(enum BattlerId battler)
{
if (!IsDma3ManagerBusyWithBgCopy())
{
@ -2188,22 +2188,22 @@ void HandleChooseMoveAfterDma3(u32 battler)
// arenaMindPoints is used here as a placeholder for a timer.
// static void PlayerChooseMoveInBattlePalace(u32 battler)
// {
// if (--gBattleStruct->arenaMindPoints[battler] == 0)
// {
// gBattlePalaceMoveSelectionRngValue = gRngValue;
// BtlController_EmitTwoReturnValues(battler, B_COMM_TO_ENGINE, B_ACTION_EXEC_SCRIPT, ChooseMoveAndTargetInBattlePalace(battler));
// BtlController_Complete(battler);
// }
// }
static void PlayerChooseMoveInBattlePalace(enum BattlerId battler)
{
if (--gBattleStruct->arenaMindPoints[battler] == 0)
{
gBattlePalaceMoveSelectionRngValue = gRngValue;
BtlController_EmitTwoReturnValues(battler, B_COMM_TO_ENGINE, B_ACTION_EXEC_SCRIPT, ChooseMoveAndTargetInBattlePalace(battler));
BtlController_Complete(battler);
}
}
void PlayerHandleChooseMove(u32 battler)
void PlayerHandleChooseMove(enum BattlerId battler)
{
if (gBattleTypeFlags & BATTLE_TYPE_PALACE)
{
// gBattleStruct->arenaMindPoints[battler] = 8;
// gBattlerControllerFuncs[battler] = PlayerChooseMoveInBattlePalace;
gBattleStruct->arenaMindPoints[battler] = 8;
gBattlerControllerFuncs[battler] = PlayerChooseMoveInBattlePalace;
}
else
{
@ -2227,7 +2227,7 @@ void PlayerHandleChooseMove(u32 battler)
}
}
void InitMoveSelectionsVarsAndStrings(u32 battler)
void InitMoveSelectionsVarsAndStrings(enum BattlerId battler)
{
LoadTypeIcons(battler);
MoveSelectionDisplayMoveNames(battler);
@ -2241,7 +2241,7 @@ void InitMoveSelectionsVarsAndStrings(u32 battler)
MoveSelectionDisplayMoveType(battler);
}
static void PlayerHandleChooseItem(u32 battler)
static void PlayerHandleChooseItem(enum BattlerId battler)
{
s32 i;
@ -2253,7 +2253,7 @@ static void PlayerHandleChooseItem(u32 battler)
gBattlePartyCurrentOrder[i] = gBattleResources->bufferA[battler][1 + i];
}
static void PlayerHandleChoosePokemon(u32 battler)
static void PlayerHandleChoosePokemon(enum BattlerId battler)
{
s32 i;
@ -2280,14 +2280,14 @@ static void PlayerHandleChoosePokemon(u32 battler)
}
}
static void PlayerHandleCmd23(u32 battler)
static void PlayerHandleCmd23(enum BattlerId battler)
{
BattleStopLowHpSound();
BeginNormalPaletteFade(PALETTES_ALL, 2, 0, 16, RGB_BLACK);
BtlController_Complete(battler);
}
void PlayerHandleExpUpdate(u32 battler)
void PlayerHandleExpUpdate(enum BattlerId battler)
{
u8 monId = gBattleResources->bufferA[battler][1];
s32 taskId, expPointsToGive;
@ -2315,7 +2315,7 @@ void PlayerHandleExpUpdate(u32 battler)
#undef tExpTask_gainedExp_2
#undef tExpTask_frames
static void PlayerHandleStatusXor(u32 battler)
static void PlayerHandleStatusXor(enum BattlerId battler)
{
u32 val = GetMonData(GetBattlerMon(battler), MON_DATA_STATUS) ^ gBattleResources->bufferA[battler][1];
@ -2323,7 +2323,7 @@ static void PlayerHandleStatusXor(u32 battler)
BtlController_Complete(battler);
}
static void PlayerHandleDMA3Transfer(u32 battler)
static void PlayerHandleDMA3Transfer(enum BattlerId battler)
{
u32 dstArg = gBattleResources->bufferA[battler][1]
| (gBattleResources->bufferA[battler][2] << 8)
@ -2350,56 +2350,56 @@ static void PlayerHandleDMA3Transfer(u32 battler)
BtlController_Complete(battler);
}
static void PlayerHandlePlayBGM(u32 battler)
static void PlayerHandlePlayBGM(enum BattlerId battler)
{
PlayBGM(gBattleResources->bufferA[battler][1] | (gBattleResources->bufferA[battler][2] << 8));
BtlController_Complete(battler);
}
static void PlayerHandleTwoReturnValues(u32 battler)
static void PlayerHandleTwoReturnValues(enum BattlerId battler)
{
BtlController_EmitTwoReturnValues(battler, B_COMM_TO_ENGINE, B_ACTION_USE_MOVE, 0);
BtlController_Complete(battler);
}
static void PlayerHandleChosenMonReturnValue(u32 battler)
static void PlayerHandleChosenMonReturnValue(enum BattlerId battler)
{
BtlController_EmitChosenMonReturnValue(battler, B_COMM_TO_ENGINE, 0, NULL);
BtlController_Complete(battler);
}
static void PlayerHandleOneReturnValue(u32 battler)
static void PlayerHandleOneReturnValue(enum BattlerId battler)
{
BtlController_EmitOneReturnValue(battler, B_COMM_TO_ENGINE, 0);
BtlController_Complete(battler);
}
static void PlayerHandleOneReturnValue_Duplicate(u32 battler)
static void PlayerHandleOneReturnValue_Duplicate(enum BattlerId battler)
{
BtlController_EmitOneReturnValue_Duplicate(battler, B_COMM_TO_ENGINE, 0);
BtlController_Complete(battler);
}
static void PlayerHandleIntroTrainerBallThrow(u32 battler)
static void PlayerHandleIntroTrainerBallThrow(enum BattlerId battler)
{
const u32 paletteIndex = PlayerGetTrainerBackPicId(); // - TRAINER_PIC_FRONT_COUNT;
const u16 *trainerPal = gTrainerBacksprites[paletteIndex].palette.data;
BtlController_HandleIntroTrainerBallThrow(battler, 0xD6F8, trainerPal, 31, Intro_TryShinyAnimShowHealthbox);
}
static void PlayerHandleDrawPartyStatusSummary(u32 battler)
static void PlayerHandleDrawPartyStatusSummary(enum BattlerId battler)
{
BtlController_HandleDrawPartyStatusSummary(battler, B_SIDE_PLAYER, TRUE);
}
static void PlayerHandleEndBounceEffect(u32 battler)
static void PlayerHandleEndBounceEffect(enum BattlerId battler)
{
EndBounceEffect(battler, BOUNCE_HEALTHBOX);
EndBounceEffect(battler, BOUNCE_MON);
BtlController_Complete(battler);
}
static void PlayerHandleLinkStandbyMsg(u32 battler)
static void PlayerHandleLinkStandbyMsg(enum BattlerId battler)
{
RecordedBattle_RecordAllBattlerData(&gBattleResources->bufferA[battler][2]);
switch (gBattleResources->bufferA[battler][1])
@ -2418,7 +2418,7 @@ static void PlayerHandleLinkStandbyMsg(u32 battler)
BtlController_Complete(battler);
}
static void PlayerHandleResetActionMoveSelection(u32 battler)
static void PlayerHandleResetActionMoveSelection(enum BattlerId battler)
{
switch (gBattleResources->bufferA[battler][1])
{
@ -2436,18 +2436,18 @@ static void PlayerHandleResetActionMoveSelection(u32 battler)
BtlController_Complete(battler);
}
static void PlayerHandleEndLinkBattle(u32 battler)
static void PlayerHandleEndLinkBattle(enum BattlerId battler)
{
// RecordedBattle_RecordAllBattlerData(&gBattleResources->bufferA[battler][4]);
RecordedBattle_RecordAllBattlerData(&gBattleResources->bufferA[battler][4]);
gBattleOutcome = gBattleResources->bufferA[battler][1];
// gSaveBlock2Ptr->frontier.disableRecordBattle = gBattleResources->bufferA[battler][2];
gSaveBlock2Ptr->frontier.disableRecordBattle = gBattleResources->bufferA[battler][2];
FadeOutMapMusic(5);
BeginFastPaletteFade(3);
BtlController_Complete(battler);
gBattlerControllerFuncs[battler] = SetBattleEndCallbacks;
}
static void Controller_WaitForDebug(u32 battler)
static void Controller_WaitForDebug(enum BattlerId battler)
{
if (gMain.callback2 == BattleMainCB2 && !gPaletteFade.active)
{
@ -2455,7 +2455,7 @@ static void Controller_WaitForDebug(u32 battler)
}
}
static void PlayerHandleBattleDebug(u32 battler)
static void PlayerHandleBattleDebug(enum BattlerId battler)
{
BeginNormalPaletteFade(-1, 0, 0, 0x10, 0);
SetMainCallback2(CB2_BattleDebugMenu);
@ -2486,7 +2486,7 @@ static bool32 ShouldShowTypeEffectiveness(u32 targetId)
return TRUE;
}
static u32 CheckTypeEffectiveness(u32 battlerAtk, u32 battlerDef)
static u32 CheckTypeEffectiveness(enum BattlerId battlerAtk, enum BattlerId battlerDef)
{
struct ChooseMoveStruct *moveInfo = (struct ChooseMoveStruct *)(&gBattleResources->bufferA[battlerAtk][4]);
struct BattleContext ctx = {0};
@ -2514,14 +2514,14 @@ static u32 CheckTypeEffectiveness(u32 battlerAtk, u32 battlerDef)
return EFFECTIVENESS_NORMAL; // Normal effectiveness
}
static u32 CheckTargetTypeEffectiveness(u32 battler)
static u32 CheckTargetTypeEffectiveness(enum BattlerId battler)
{
u32 battlerFoe = BATTLE_OPPOSITE(battler);
enum BattlerId battlerFoe = BATTLE_OPPOSITE(battler);
u32 foeEffectiveness = CheckTypeEffectiveness(battler, battlerFoe);
if (IsDoubleBattle())
{
u32 partnerFoe = BATTLE_PARTNER(battlerFoe);
enum BattlerId partnerFoe = BATTLE_PARTNER(battlerFoe);
u32 partnerFoeEffectiveness = CheckTypeEffectiveness(battler, partnerFoe);
if (!IsBattlerAlive(battlerFoe))
return partnerFoeEffectiveness;
@ -2532,7 +2532,7 @@ static u32 CheckTargetTypeEffectiveness(u32 battler)
return foeEffectiveness; // fallthrough for any other circumstance
}
static void MoveSelectionDisplayMoveEffectiveness(u32 foeEffectiveness, u32 battler)
static void MoveSelectionDisplayMoveEffectiveness(u32 foeEffectiveness, enum BattlerId battler)
{
static const u8 noIcon[] = _("");
static const u8 effectiveIcon[] = _("{CIRCLE_HOLLOW}");

View File

@ -8,10 +8,11 @@
#include "battle_message.h"
#include "battle_interface.h"
#include "battle_setup.h"
#include "battle_tower.h"
#include "battle_z_move.h"
#include "bg.h"
#include "data.h"
// #include "frontier_util.h"
#include "frontier_util.h"
#include "item_use.h"
#include "link.h"
#include "main.h"
@ -35,19 +36,19 @@
#include "test/battle.h"
#include "test/test_runner_battle.h"
static void PlayerPartnerHandleDrawTrainerPic(u32 battler);
static void PlayerPartnerHandleTrainerSlide(u32 battler);
static void PlayerPartnerHandleTrainerSlideBack(u32 battler);
static void PlayerPartnerHandleChooseAction(u32 battler);
static void PlayerPartnerHandleChooseMove(u32 battler);
static void PlayerPartnerHandleChoosePokemon(u32 battler);
static void PlayerPartnerHandleIntroTrainerBallThrow(u32 battler);
static void PlayerPartnerHandleDrawPartyStatusSummary(u32 battler);
static void PlayerPartnerHandleEndLinkBattle(u32 battler);
static void PlayerPartnerHandleDrawTrainerPic(enum BattlerId battler);
static void PlayerPartnerHandleTrainerSlide(enum BattlerId battler);
static void PlayerPartnerHandleTrainerSlideBack(enum BattlerId battler);
static void PlayerPartnerHandleChooseAction(enum BattlerId battler);
static void PlayerPartnerHandleChooseMove(enum BattlerId battler);
static void PlayerPartnerHandleChoosePokemon(enum BattlerId battler);
static void PlayerPartnerHandleIntroTrainerBallThrow(enum BattlerId battler);
static void PlayerPartnerHandleDrawPartyStatusSummary(enum BattlerId battler);
static void PlayerPartnerHandleEndLinkBattle(enum BattlerId battler);
static void PlayerPartnerBufferRunCommand(u32 battler);
static void PlayerPartnerBufferRunCommand(enum BattlerId battler);
static void (*const sPlayerPartnerBufferCommands[CONTROLLER_CMDS_COUNT])(u32 battler) =
static void (*const sPlayerPartnerBufferCommands[CONTROLLER_CMDS_COUNT])(enum BattlerId battler) =
{
[CONTROLLER_GETMONDATA] = BtlController_HandleGetMonData,
[CONTROLLER_GETRAWMONDATA] = BtlController_Empty,
@ -104,14 +105,14 @@ static void (*const sPlayerPartnerBufferCommands[CONTROLLER_CMDS_COUNT])(u32 bat
[CONTROLLER_TERMINATOR_NOP] = BtlController_TerminatorNop
};
void SetControllerToPlayerPartner(u32 battler)
void SetControllerToPlayerPartner(enum BattlerId battler)
{
gBattlerBattleController[battler] = BATTLE_CONTROLLER_PLAYER_PARTNER;
gBattlerControllerEndFuncs[battler] = PlayerPartnerBufferExecCompleted;
gBattlerControllerFuncs[battler] = PlayerPartnerBufferRunCommand;
}
static void PlayerPartnerBufferRunCommand(u32 battler)
static void PlayerPartnerBufferRunCommand(enum BattlerId battler)
{
if (IsBattleControllerActiveOnLocal(battler))
{
@ -122,7 +123,7 @@ static void PlayerPartnerBufferRunCommand(u32 battler)
}
}
static void Intro_WaitForHealthbox(u32 battler)
static void Intro_WaitForHealthbox(enum BattlerId battler)
{
bool32 finished = FALSE;
@ -151,7 +152,7 @@ static void Intro_WaitForHealthbox(u32 battler)
}
// Also used by the link partner.
void Controller_PlayerPartnerShowIntroHealthbox(u32 battler)
void Controller_PlayerPartnerShowIntroHealthbox(enum BattlerId battler)
{
if (!gBattleSpritesDataPtr->healthBoxesData[battler].ballAnimActive
&& !gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(battler)].ballAnimActive
@ -181,7 +182,7 @@ void Controller_PlayerPartnerShowIntroHealthbox(u32 battler)
}
}
void PlayerPartnerBufferExecCompleted(u32 battler)
void PlayerPartnerBufferExecCompleted(enum BattlerId battler)
{
gBattlerControllerFuncs[battler] = PlayerPartnerBufferRunCommand;
if (gBattleTypeFlags & BATTLE_TYPE_LINK)
@ -212,7 +213,7 @@ static enum TrainerPicID PlayerPartnerGetTrainerBackPicId(enum DifficultyLevel d
// some explanation here
// in emerald it's possible to have a tag battle in the battle frontier facilities with AI
// which use the front sprite for both the player and the partner as opposed to any other battles (including the one with Steven) that use the back pic as well as animate it
static void PlayerPartnerHandleDrawTrainerPic(u32 battler)
static void PlayerPartnerHandleDrawTrainerPic(enum BattlerId battler)
{
bool32 isFrontPic;
s16 xPos, yPos;
@ -228,7 +229,7 @@ static void PlayerPartnerHandleDrawTrainerPic(u32 battler)
}
else if (gPartnerTrainerId > TRAINER_PARTNER(PARTNER_NONE))
{
trainerPicId = gBattlePartners[difficulty][gPartnerTrainerId - TRAINER_PARTNER(PARTNER_NONE)].trainerBackPic;
trainerPicId = PlayerPartnerGetTrainerBackPicId(difficulty);
xPos = 90;
yPos = (8 - gTrainerBacksprites[trainerPicId].coordinates.size) * 4 + 80;
}
@ -240,7 +241,7 @@ static void PlayerPartnerHandleDrawTrainerPic(u32 battler)
}
else
{
trainerPicId = TRAINER_PIC_RED;
trainerPicId = GetFrontierTrainerFrontSpriteId(gPartnerTrainerId);
xPos = 32;
yPos = 80;
}
@ -254,32 +255,32 @@ static void PlayerPartnerHandleDrawTrainerPic(u32 battler)
BtlController_HandleDrawTrainerPic(battler, trainerPicId, isFrontPic, xPos, yPos, -1);
}
static void PlayerPartnerHandleTrainerSlide(u32 battler)
static void PlayerPartnerHandleTrainerSlide(enum BattlerId battler)
{
enum DifficultyLevel difficulty = GetBattlePartnerDifficultyLevel(gPartnerTrainerId);
enum TrainerPicID trainerPicId = PlayerPartnerGetTrainerBackPicId(difficulty);
BtlController_HandleTrainerSlide(battler, trainerPicId);
}
static void PlayerPartnerHandleTrainerSlideBack(u32 battler)
static void PlayerPartnerHandleTrainerSlideBack(enum BattlerId battler)
{
BtlController_HandleTrainerSlideBack(battler, 35, FALSE);
}
static void PlayerPartnerHandleChooseAction(u32 battler)
static void PlayerPartnerHandleChooseAction(enum BattlerId battler)
{
AI_TrySwitchOrUseItem(battler);
BtlController_Complete(battler);
}
static void PlayerPartnerHandleChooseMove(u32 battler)
static void PlayerPartnerHandleChooseMove(enum BattlerId battler)
{
u32 chosenMoveIndex;
struct ChooseMoveStruct *moveInfo = (struct ChooseMoveStruct *)(&gBattleResources->bufferA[battler][4]);
chosenMoveIndex = gAiBattleData->chosenMoveIndex[battler];
gBattlerTarget = gAiBattleData->chosenTarget[battler];
u32 moveTarget = GetBattlerMoveTargetType(battler, moveInfo->moves[chosenMoveIndex]);
enum MoveTarget moveTarget = GetBattlerMoveTargetType(battler, moveInfo->moves[chosenMoveIndex]);
if (moveTarget == TARGET_USER || moveTarget == TARGET_USER_OR_ALLY)
{
@ -307,7 +308,7 @@ static void PlayerPartnerHandleChooseMove(u32 battler)
BtlController_Complete(battler);
}
static void PlayerPartnerHandleChoosePokemon(u32 battler)
static void PlayerPartnerHandleChoosePokemon(enum BattlerId battler)
{
s32 chosenMonId;
// Choosing Revival Blessing target
@ -322,8 +323,8 @@ static void PlayerPartnerHandleChoosePokemon(u32 battler)
if (chosenMonId == PARTY_SIZE || !IsValidForBattle(&gPlayerParty[chosenMonId])) // just switch to the next mon
{
s32 firstId = (IsAiVsAiBattle()) ? 0 : (PARTY_SIZE / 2);
u32 battler1 = GetBattlerAtPosition(B_POSITION_PLAYER_LEFT);
u32 battler2 = IsDoubleBattle() ? GetBattlerAtPosition(B_POSITION_PLAYER_RIGHT) : battler1;
enum BattlerId battler1 = GetBattlerAtPosition(B_POSITION_PLAYER_LEFT);
enum BattlerId battler2 = IsDoubleBattle() ? GetBattlerAtPosition(B_POSITION_PLAYER_RIGHT) : battler1;
for (chosenMonId = firstId; chosenMonId < PARTY_SIZE; chosenMonId++)
{
@ -343,13 +344,14 @@ static void PlayerPartnerHandleChoosePokemon(u32 battler)
gBattleStruct->AI_monToSwitchIntoId[battler] = PARTY_SIZE;
gBattleStruct->monToSwitchIntoId[battler] = chosenMonId;
}
if (TESTING)
TestRunner_Battle_CheckSwitch(battler, chosenMonId);
#if TESTING
TestRunner_Battle_CheckSwitch(battler, chosenMonId);
#endif
BtlController_EmitChosenMonReturnValue(battler, B_COMM_TO_ENGINE, chosenMonId, NULL);
BtlController_Complete(battler);
}
static void PlayerPartnerHandleIntroTrainerBallThrow(u32 battler)
static void PlayerPartnerHandleIntroTrainerBallThrow(enum BattlerId battler)
{
const u16 *trainerPal;
enum DifficultyLevel difficulty = GetBattlePartnerDifficultyLevel(gPartnerTrainerId);
@ -359,17 +361,17 @@ static void PlayerPartnerHandleIntroTrainerBallThrow(u32 battler)
else if (IsAiVsAiBattle())
trainerPal = gTrainerSprites[GetTrainerBackPicFromId(gPartnerTrainerId)].palette.data;
else
trainerPal = gTrainerSprites[TRAINER_PIC_RED].palette.data; // 2 vs 2 multi battle in Battle Frontier, load front sprite and pal.
trainerPal = gTrainerSprites[GetFrontierTrainerFrontSpriteId(gPartnerTrainerId)].palette.data; // 2 vs 2 multi battle in Battle Frontier, load front sprite and pal.
BtlController_HandleIntroTrainerBallThrow(battler, 0xD6F9, trainerPal, 24, Controller_PlayerPartnerShowIntroHealthbox);
}
static void PlayerPartnerHandleDrawPartyStatusSummary(u32 battler)
static void PlayerPartnerHandleDrawPartyStatusSummary(enum BattlerId battler)
{
BtlController_HandleDrawPartyStatusSummary(battler, B_SIDE_PLAYER, TRUE);
}
static void PlayerPartnerHandleEndLinkBattle(u32 battler)
static void PlayerPartnerHandleEndLinkBattle(enum BattlerId battler)
{
gBattleOutcome = gBattleResources->bufferA[battler][1];
FadeOutMapMusic(5);

View File

@ -27,7 +27,7 @@ struct PokedudeTextScriptHeader
u8 btlcmd;
u8 side;
u16 stringid;
void (*callback)(u32 battler);
void (*callback)(enum BattlerId battler);
};
struct PokedudeBattlePartyInfo
@ -40,33 +40,33 @@ struct PokedudeBattlePartyInfo
u8 gender;
};
static void PokedudeHandleDrawTrainerPic(u32 battler);
static void PokedudeHandleTrainerSlide(u32 battler);
static void PokedudeHandlePrintSelectionString(u32 battler);
static void PokedudeHandleChooseAction(u32 battler);
static void PokedudeHandleChooseMove(u32 battler);
static void PokedudeHandleChooseItem(u32 battler);
static void PokedudeHandleChoosePokemon(u32 battler);
static void PokedudeHandleStatusXor(u32 battler);
static void PokedudeHandlePlaySE(u32 battler);
static void PokedudeHandleIntroTrainerBallThrow(u32 battler);
static void PokedudeHandleDrawPartyStatusSummary(u32 battler);
static void PokedudeHandleEndBounceEffect(u32 battler);
static void PokedudeHandleLinkStandbyMsg(u32 battler);
static void PokedudeHandleEndLinkBattle(u32 battler);
static void PokedudeHandleDrawTrainerPic(enum BattlerId battler);
static void PokedudeHandleTrainerSlide(enum BattlerId battler);
static void PokedudeHandlePrintSelectionString(enum BattlerId battler);
static void PokedudeHandleChooseAction(enum BattlerId battler);
static void PokedudeHandleChooseMove(enum BattlerId battler);
static void PokedudeHandleChooseItem(enum BattlerId battler);
static void PokedudeHandleChoosePokemon(enum BattlerId battler);
static void PokedudeHandleStatusXor(enum BattlerId battler);
static void PokedudeHandlePlaySE(enum BattlerId battler);
static void PokedudeHandleIntroTrainerBallThrow(enum BattlerId battler);
static void PokedudeHandleDrawPartyStatusSummary(enum BattlerId battler);
static void PokedudeHandleEndBounceEffect(enum BattlerId battler);
static void PokedudeHandleLinkStandbyMsg(enum BattlerId battler);
static void PokedudeHandleEndLinkBattle(enum BattlerId battler);
static void PokedudeAction_PrintVoiceoverMessage(u32 battler);
static void PokedudeAction_PrintMessageWithHealthboxPals(u32 battler);
static void PokedudeSimulateInputChooseAction(u32 battler);
static void PokedudeBufferRunCommand(u32 battler);
static bool8 HandlePokedudeVoiceoverEtc(u32 battler);
static void PokedudeSimulateInputChooseMove(u32 battler);
static void WaitForMonSelection(u32 battler);
static void CompleteWhenChoseItem(u32 battler);
static void Intro_WaitForShinyAnimAndHealthbox(u32 battler);
static void PokedudeAction_PrintVoiceoverMessage(enum BattlerId battler);
static void PokedudeAction_PrintMessageWithHealthboxPals(enum BattlerId battler);
static void PokedudeSimulateInputChooseAction(enum BattlerId battler);
static void PokedudeBufferRunCommand(enum BattlerId battler);
static bool8 HandlePokedudeVoiceoverEtc(enum BattlerId battler);
static void PokedudeSimulateInputChooseMove(enum BattlerId battler);
static void WaitForMonSelection(enum BattlerId battler);
static void CompleteWhenChoseItem(enum BattlerId battler);
static void Intro_WaitForShinyAnimAndHealthbox(enum BattlerId battler);
static const u8 *GetPokedudeText(void);
static void (*const sPokedudeBufferCommands[CONTROLLER_CMDS_COUNT])(u32 battler) =
static void (*const sPokedudeBufferCommands[CONTROLLER_CMDS_COUNT])(enum BattlerId battler) =
{
[CONTROLLER_GETMONDATA] = BtlController_HandleGetMonData,
[CONTROLLER_GETRAWMONDATA] = BtlController_Empty,
@ -128,7 +128,7 @@ static void (*const sPokedudeBufferCommands[CONTROLLER_CMDS_COUNT])(u32 battler)
#define pdScriptNum simulatedInputState[2]
#define pdMessageNo simulatedInputState[3]
void SetControllerToPokedude(u32 battler)
void SetControllerToPokedude(enum BattlerId battler)
{
gBattlerControllerEndFuncs[battler] = PokedudeBufferExecCompleted;
gBattlerControllerFuncs[battler] = PokedudeBufferRunCommand;
@ -136,7 +136,7 @@ void SetControllerToPokedude(u32 battler)
gBattleStruct->pdMessageNo = 0;
}
static void PokedudeBufferRunCommand(u32 battler)
static void PokedudeBufferRunCommand(enum BattlerId battler)
{
if (gBattleControllerExecFlags & (1u << battler))
{
@ -152,12 +152,12 @@ static void PokedudeBufferRunCommand(u32 battler)
}
}
static void HandleInputChooseAction(u32 battler)
static void HandleInputChooseAction(enum BattlerId battler)
{
PokedudeSimulateInputChooseAction(battler);
}
static void Pokedude_SetBattleEndCallbacks(u32 battler)
static void Pokedude_SetBattleEndCallbacks(enum BattlerId battler)
{
if (!gPaletteFade.active)
{
@ -167,7 +167,7 @@ static void Pokedude_SetBattleEndCallbacks(u32 battler)
}
}
static void Intro_DelayAndEnd(u32 battler)
static void Intro_DelayAndEnd(enum BattlerId battler)
{
if (--gBattleSpritesDataPtr->healthBoxesData[battler].introEndDelay == 255)
{
@ -176,12 +176,12 @@ static void Intro_DelayAndEnd(u32 battler)
}
}
static void PokedudeHandleInputChooseMove(u32 battler)
static void PokedudeHandleInputChooseMove(enum BattlerId battler)
{
PokedudeSimulateInputChooseMove(battler);
}
static void OpenPartyMenuToChooseMon(u32 battler)
static void OpenPartyMenuToChooseMon(enum BattlerId battler)
{
if (!gPaletteFade.active)
{
@ -192,7 +192,7 @@ static void OpenPartyMenuToChooseMon(u32 battler)
}
}
static void WaitForMonSelection(u32 battler)
static void WaitForMonSelection(enum BattlerId battler)
{
if (gMain.callback2 == BattleMainCB2 && !gPaletteFade.active)
{
@ -204,7 +204,7 @@ static void WaitForMonSelection(u32 battler)
}
}
static void OpenBagAndChooseItem(u32 battler)
static void OpenBagAndChooseItem(enum BattlerId battler)
{
u8 callbackId;
@ -227,7 +227,7 @@ static void OpenBagAndChooseItem(u32 battler)
}
}
static void CompleteWhenChoseItem(u32 battler)
static void CompleteWhenChoseItem(enum BattlerId battler)
{
if (gMain.callback2 == BattleMainCB2 && !gPaletteFade.active)
{
@ -236,7 +236,7 @@ static void CompleteWhenChoseItem(u32 battler)
}
}
static void Intro_TryShinyAnimShowHealthbox(u32 battler)
static void Intro_TryShinyAnimShowHealthbox(enum BattlerId battler)
{
if (!gBattleSpritesDataPtr->healthBoxesData[battler].triedShinyMonAnim
&& !gBattleSpritesDataPtr->healthBoxesData[battler].ballAnimActive)
@ -266,7 +266,7 @@ static void Intro_TryShinyAnimShowHealthbox(u32 battler)
}
}
static void Intro_WaitForShinyAnimAndHealthbox(u32 battler)
static void Intro_WaitForShinyAnimAndHealthbox(enum BattlerId battler)
{
bool32 r4 = FALSE;
@ -288,7 +288,7 @@ static void Intro_WaitForShinyAnimAndHealthbox(u32 battler)
}
}
void PokedudeBufferExecCompleted(u32 battler)
void PokedudeBufferExecCompleted(enum BattlerId battler)
{
gBattlerControllerFuncs[battler] = PokedudeBufferRunCommand;
if (gBattleTypeFlags & BATTLE_TYPE_LINK)
@ -304,7 +304,7 @@ void PokedudeBufferExecCompleted(u32 battler)
}
}
static void PokedudeHandleDrawTrainerPic(u32 battler)
static void PokedudeHandleDrawTrainerPic(enum BattlerId battler)
{
u32 trainerPicId;
bool32 isFrontPic;
@ -329,12 +329,12 @@ static void PokedudeHandleDrawTrainerPic(u32 battler)
BtlController_HandleDrawTrainerPic(battler, trainerPicId, isFrontPic, xPos, yPos, subpriority);
}
static void PokedudeHandleTrainerSlide(u32 battler)
static void PokedudeHandleTrainerSlide(enum BattlerId battler)
{
BtlController_HandleTrainerSlide(battler, TRAINER_BACK_PIC_POKEDUDE);
}
static void PokedudeHandlePrintSelectionString(u32 battler)
static void PokedudeHandlePrintSelectionString(enum BattlerId battler)
{
if (GetBattlerSide(battler) == B_SIDE_PLAYER)
BtlController_HandlePrintString(battler);
@ -342,7 +342,7 @@ static void PokedudeHandlePrintSelectionString(u32 battler)
PokedudeBufferExecCompleted(battler);
}
static void HandleChooseActionAfterDma3(u32 battler)
static void HandleChooseActionAfterDma3(enum BattlerId battler)
{
if (!IsDma3ManagerBusyWithBgCopy())
{
@ -352,7 +352,7 @@ static void HandleChooseActionAfterDma3(u32 battler)
}
}
static void PokedudeHandleChooseAction(u32 battler)
static void PokedudeHandleChooseAction(enum BattlerId battler)
{
s32 i;
@ -374,7 +374,7 @@ static void PokedudeHandleChooseAction(u32 battler)
}
}
static void PokedudeHandleChooseMoveAfterDma3(u32 battler)
static void PokedudeHandleChooseMoveAfterDma3(enum BattlerId battler)
{
if (!IsDma3ManagerBusyWithBgCopy())
{
@ -384,7 +384,7 @@ static void PokedudeHandleChooseMoveAfterDma3(u32 battler)
}
}
static void PokedudeHandleChooseMove(u32 battler)
static void PokedudeHandleChooseMove(enum BattlerId battler)
{
if (GetBattlerSide(battler) == B_SIDE_PLAYER)
{
@ -397,7 +397,7 @@ static void PokedudeHandleChooseMove(u32 battler)
}
}
static void PokedudeHandleChooseItem(u32 battler)
static void PokedudeHandleChooseItem(enum BattlerId battler)
{
s32 i;
@ -408,7 +408,7 @@ static void PokedudeHandleChooseItem(u32 battler)
gBattlePartyCurrentOrder[i] = gBattleResources->bufferA[battler][i + 1];
}
static void PokedudeHandleChoosePokemon(u32 battler)
static void PokedudeHandleChoosePokemon(enum BattlerId battler)
{
s32 i;
@ -425,7 +425,7 @@ static void PokedudeHandleChoosePokemon(u32 battler)
}
// shared with battle_controller_player
static void PokedudeHandleStatusXor(u32 battler)
static void PokedudeHandleStatusXor(enum BattlerId battler)
{
struct Pokemon *mon;
u8 val;
@ -439,18 +439,18 @@ static void PokedudeHandleStatusXor(u32 battler)
PokedudeBufferExecCompleted(battler);
}
static void PokedudeHandlePlaySE(u32 battler)
static void PokedudeHandlePlaySE(enum BattlerId battler)
{
PlaySE(gBattleResources->bufferA[battler][1] | (gBattleResources->bufferA[battler][2] << 8));
PokedudeBufferExecCompleted(battler);
}
static void PokedudeHandleIntroTrainerBallThrow(u32 battler)
static void PokedudeHandleIntroTrainerBallThrow(enum BattlerId battler)
{
BtlController_HandleIntroTrainerBallThrow(battler, 0xD6F8, gTrainerBacksprites[TRAINER_BACK_PIC_POKEDUDE].palette.data, 31, Intro_TryShinyAnimShowHealthbox);
}
static void PokedudeHandleDrawPartyStatusSummary(u32 battler)
static void PokedudeHandleDrawPartyStatusSummary(enum BattlerId battler)
{
if (gBattleResources->bufferA[battler][1] != 0
&& GetBattlerSide(battler) == B_SIDE_PLAYER)
@ -468,14 +468,14 @@ static void PokedudeHandleDrawPartyStatusSummary(u32 battler)
}
}
static void PokedudeHandleEndBounceEffect(u32 battler)
static void PokedudeHandleEndBounceEffect(enum BattlerId battler)
{
EndBounceEffect(battler, BOUNCE_HEALTHBOX);
EndBounceEffect(battler, BOUNCE_MON);
PokedudeBufferExecCompleted(battler);
}
static void PokedudeHandleLinkStandbyMsg(u32 battler)
static void PokedudeHandleLinkStandbyMsg(enum BattlerId battler)
{
switch (gBattleResources->bufferA[battler][1])
{
@ -490,7 +490,7 @@ static void PokedudeHandleLinkStandbyMsg(u32 battler)
PokedudeBufferExecCompleted(battler);
}
static void PokedudeHandleEndLinkBattle(u32 battler)
static void PokedudeHandleEndLinkBattle(enum BattlerId battler)
{
gBattleOutcome = gBattleResources->bufferA[battler][1];
FadeOutMapMusic(5);
@ -936,7 +936,7 @@ static const struct PokedudeBattlePartyInfo *const sPokedudeBattlePartyPointers[
COMMON_DATA struct PokedudeBattlerState *gPokedudeBattlerStates[MAX_BATTLERS_COUNT] = {0};
static void PokedudeSimulateInputChooseAction(u32 battler)
static void PokedudeSimulateInputChooseAction(enum BattlerId battler)
{
const struct PokedudeInputScript *script_p = sInputScripts_ChooseAction[gBattleStruct->pdScriptNum];
@ -984,7 +984,7 @@ static void PokedudeSimulateInputChooseAction(u32 battler)
}
}
static void PokedudeSimulateInputChooseMove(u32 battler)
static void PokedudeSimulateInputChooseMove(enum BattlerId battler)
{
const struct PokedudeInputScript *script_p = sInputScripts_ChooseMove[gBattleStruct->pdScriptNum];
@ -1015,7 +1015,7 @@ static void PokedudeSimulateInputChooseMove(u32 battler)
}
}
static bool8 HandlePokedudeVoiceoverEtc(u32 battler)
static bool8 HandlePokedudeVoiceoverEtc(enum BattlerId battler)
{
const struct PokedudeTextScriptHeader *header_p = sPokedudeTextScripts[gBattleStruct->pdScriptNum];
const u16 * bstringid_p = (const u16 *)&gBattleResources->bufferA[battler][2];
@ -1038,13 +1038,13 @@ static bool8 HandlePokedudeVoiceoverEtc(u32 battler)
return TRUE;
}
static void ReturnFromPokedudeAction(u32 battler)
static void ReturnFromPokedudeAction(enum BattlerId battler)
{
gPokedudeBattlerStates[battler]->timer = 0;
gBattlerControllerFuncs[battler] = PokedudeBufferRunCommand;
}
static void PokedudeAction_PrintVoiceoverMessage(u32 battler)
static void PokedudeAction_PrintVoiceoverMessage(enum BattlerId battler)
{
switch (gPokedudeBattlerStates[battler]->timer)
{
@ -1093,7 +1093,7 @@ static void PokedudeAction_PrintVoiceoverMessage(u32 battler)
}
}
static void PokedudeAction_PrintMessageWithHealthboxPals(u32 battler)
static void PokedudeAction_PrintMessageWithHealthboxPals(enum BattlerId battler)
{
switch (gPokedudeBattlerStates[battler]->timer)
{

View File

@ -6,10 +6,11 @@
#include "battle_interface.h"
#include "battle_message.h"
#include "battle_setup.h"
#include "battle_tower.h"
// #include "battle_tv.h"
#include "bg.h"
#include "data.h"
// #include "frontier_util.h"
#include "frontier_util.h"
#include "item_menu.h"
#include "item_use.h"
#include "link.h"
@ -34,20 +35,20 @@
#include "test/battle.h"
#include "test/test_runner_battle.h"
static void RecordedOpponentHandleDrawTrainerPic(u32 battler);
static void RecordedOpponentHandleTrainerSlideBack(u32 battler);
static void RecordedOpponentHandleChooseAction(u32 battler);
static void RecordedOpponentHandleChooseMove(u32 battler);
static void RecordedOpponentHandleChooseItem(u32 battler);
static void RecordedOpponentHandleChoosePokemon(u32 battler);
static void RecordedOpponentHandleStatusAnimation(u32 battler);
static void RecordedOpponentHandleIntroTrainerBallThrow(u32 battler);
static void RecordedOpponentHandleDrawPartyStatusSummary(u32 battler);
static void RecordedOpponentHandleEndLinkBattle(u32 battler);
static void RecordedOpponentHandleDrawTrainerPic(enum BattlerId battler);
static void RecordedOpponentHandleTrainerSlideBack(enum BattlerId battler);
static void RecordedOpponentHandleChooseAction(enum BattlerId battler);
static void RecordedOpponentHandleChooseMove(enum BattlerId battler);
static void RecordedOpponentHandleChooseItem(enum BattlerId battler);
static void RecordedOpponentHandleChoosePokemon(enum BattlerId battler);
static void RecordedOpponentHandleStatusAnimation(enum BattlerId battler);
static void RecordedOpponentHandleIntroTrainerBallThrow(enum BattlerId battler);
static void RecordedOpponentHandleDrawPartyStatusSummary(enum BattlerId battler);
static void RecordedOpponentHandleEndLinkBattle(enum BattlerId battler);
static void RecordedOpponentBufferRunCommand(u32 battler);
static void RecordedOpponentBufferRunCommand(enum BattlerId battler);
static void (*const sRecordedOpponentBufferCommands[CONTROLLER_CMDS_COUNT])(u32 battler) =
static void (*const sRecordedOpponentBufferCommands[CONTROLLER_CMDS_COUNT])(enum BattlerId battler) =
{
[CONTROLLER_GETMONDATA] = BtlController_HandleGetMonData,
[CONTROLLER_GETRAWMONDATA] = BtlController_Empty,
@ -104,14 +105,14 @@ static void (*const sRecordedOpponentBufferCommands[CONTROLLER_CMDS_COUNT])(u32
[CONTROLLER_TERMINATOR_NOP] = BtlController_TerminatorNop
};
void SetControllerToRecordedOpponent(u32 battler)
void SetControllerToRecordedOpponent(enum BattlerId battler)
{
gBattlerBattleController[battler] = BATTLE_CONTROLLER_RECORDED_OPPONENT;
gBattlerControllerEndFuncs[battler] = RecordedOpponentBufferExecCompleted;
gBattlerControllerFuncs[battler] = RecordedOpponentBufferRunCommand;
}
static void RecordedOpponentBufferRunCommand(u32 battler)
static void RecordedOpponentBufferRunCommand(enum BattlerId battler)
{
if (IsBattleControllerActiveOnLocal(battler))
{
@ -122,7 +123,7 @@ static void RecordedOpponentBufferRunCommand(u32 battler)
}
}
void RecordedOpponentBufferExecCompleted(u32 battler)
void RecordedOpponentBufferExecCompleted(enum BattlerId battler)
{
gBattlerControllerFuncs[battler] = RecordedOpponentBufferRunCommand;
if (gBattleTypeFlags & BATTLE_TYPE_LINK)
@ -138,7 +139,7 @@ void RecordedOpponentBufferExecCompleted(u32 battler)
}
}
static void Intro_WaitForShinyAnimAndHealthbox(u32 battler)
static void Intro_WaitForShinyAnimAndHealthbox(enum BattlerId battler)
{
bool8 healthboxAnimDone = FALSE;
@ -179,7 +180,7 @@ static void Intro_WaitForShinyAnimAndHealthbox(u32 battler)
}
}
static void Intro_TryShinyAnimShowHealthbox(u32 battler)
static void Intro_TryShinyAnimShowHealthbox(enum BattlerId battler)
{
bool32 bgmRestored = FALSE;
bool32 battlerAnimsDone = FALSE;
@ -269,15 +270,16 @@ static void Intro_TryShinyAnimShowHealthbox(u32 battler)
}
}
static void RecordedOpponentHandleDrawTrainerPic(u32 battler)
static void RecordedOpponentHandleDrawTrainerPic(enum BattlerId battler)
{
s16 xPos;
enum TrainerPicID trainerPicId;
enum BattlerPosition position = GetBattlerPosition(battler);
// Sets Multibattle test opponent sprites to not be Hiker
if (IsMultibattleTest())
{
if (GetBattlerPosition(battler) == B_POSITION_OPPONENT_LEFT)
if (position == B_POSITION_OPPONENT_LEFT)
{
trainerPicId = TRAINER_PIC_LEAF;
if (!(gBattleTypeFlags & BATTLE_TYPE_TWO_OPPONENTS))
@ -293,44 +295,55 @@ static void RecordedOpponentHandleDrawTrainerPic(u32 battler)
}
else if (gBattleTypeFlags & BATTLE_TYPE_MULTI)
{
if ((GetBattlerPosition(battler) & BIT_FLANK) != 0) // second mon
if ((position & BIT_FLANK) != 0) // second mon
xPos = 152;
else // first mon
xPos = 200;
if (gBattleTypeFlags & BATTLE_TYPE_BATTLE_TOWER)
trainerPicId = TRAINER_PIC_RED;
{
if (position == B_POSITION_OPPONENT_LEFT)
trainerPicId = GetFrontierTrainerFrontSpriteId(TRAINER_BATTLE_PARAM.opponentA);
else
trainerPicId = GetFrontierTrainerFrontSpriteId(TRAINER_BATTLE_PARAM.opponentB);
}
else
{
trainerPicId = PlayerGenderToFrontTrainerPicId(GetBattlerLinkPlayerGender(battler));
}
}
else
{
xPos = 176;
if (TRAINER_BATTLE_PARAM.opponentA == TRAINER_UNION_ROOM)
{
trainerPicId = GetUnionRoomTrainerPic();
}
else
{
trainerPicId = PlayerGenderToFrontTrainerPicId(gLinkPlayers[gRecordedBattleMultiplayerId ^ BIT_SIDE].gender);
}
}
BtlController_HandleDrawTrainerPic(battler, trainerPicId, TRUE, xPos, 40, -1);
}
static void RecordedOpponentHandleTrainerSlideBack(u32 battler)
static void RecordedOpponentHandleTrainerSlideBack(enum BattlerId battler)
{
BtlController_HandleTrainerSlideBack(battler, 35, FALSE);
}
static void RecordedOpponentHandleChooseAction(u32 battler)
static void RecordedOpponentHandleChooseAction(enum BattlerId battler)
{
BtlController_EmitTwoReturnValues(battler, B_COMM_TO_ENGINE, RecordedBattle_GetBattlerAction(RECORDED_ACTION_TYPE, battler), 0);
BtlController_Complete(battler);
}
static void RecordedOpponentHandleChooseMove(u32 battler)
static void RecordedOpponentHandleChooseMove(enum BattlerId battler)
{
if (gBattleTypeFlags & BATTLE_TYPE_PALACE)
{
// BtlController_EmitTwoReturnValues(battler, B_COMM_TO_ENGINE, B_ACTION_EXEC_SCRIPT, ChooseMoveAndTargetInBattlePalace(battler));
BtlController_EmitTwoReturnValues(battler, B_COMM_TO_ENGINE, B_ACTION_EXEC_SCRIPT, ChooseMoveAndTargetInBattlePalace(battler));
}
else
{
@ -342,7 +355,7 @@ static void RecordedOpponentHandleChooseMove(u32 battler)
BtlController_Complete(battler);
}
static void RecordedOpponentHandleChooseItem(u32 battler)
static void RecordedOpponentHandleChooseItem(enum BattlerId battler)
{
u8 byte1 = RecordedBattle_GetBattlerAction(RECORDED_ITEM_ID, battler);
u8 byte2 = RecordedBattle_GetBattlerAction(RECORDED_ITEM_ID, battler);
@ -353,7 +366,7 @@ static void RecordedOpponentHandleChooseItem(u32 battler)
BtlController_Complete(battler);
}
static void RecordedOpponentHandleChoosePokemon(u32 battler)
static void RecordedOpponentHandleChoosePokemon(enum BattlerId battler)
{
gBattleStruct->monToSwitchIntoId[battler] = RecordedBattle_GetBattlerAction(RECORDED_PARTY_INDEX, battler);
gSelectedMonPartyId = gBattleStruct->monToSwitchIntoId[battler]; // Revival Blessing
@ -361,22 +374,22 @@ static void RecordedOpponentHandleChoosePokemon(u32 battler)
BtlController_Complete(battler);
}
static void RecordedOpponentHandleStatusAnimation(u32 battler)
static void RecordedOpponentHandleStatusAnimation(enum BattlerId battler)
{
BtlController_HandleStatusAnimation(battler);
}
static void RecordedOpponentHandleIntroTrainerBallThrow(u32 battler)
static void RecordedOpponentHandleIntroTrainerBallThrow(enum BattlerId battler)
{
BtlController_HandleIntroTrainerBallThrow(battler, 0, NULL, 0, Intro_TryShinyAnimShowHealthbox);
}
static void RecordedOpponentHandleDrawPartyStatusSummary(u32 battler)
static void RecordedOpponentHandleDrawPartyStatusSummary(enum BattlerId battler)
{
BtlController_HandleDrawPartyStatusSummary(battler, B_SIDE_OPPONENT, TRUE);
}
static void RecordedOpponentHandleEndLinkBattle(u32 battler)
static void RecordedOpponentHandleEndLinkBattle(enum BattlerId battler)
{
if (gBattleResources->bufferA[battler][1] == B_OUTCOME_DREW)
gBattleOutcome = gBattleResources->bufferA[battler][1];

View File

@ -7,10 +7,11 @@
#include "battle_message.h"
#include "battle_interface.h"
#include "battle_setup.h"
#include "battle_tower.h"
#include "battle_z_move.h"
#include "bg.h"
#include "data.h"
// #include "frontier_util.h"
#include "frontier_util.h"
#include "item_use.h"
#include "link.h"
#include "main.h"
@ -34,18 +35,18 @@
#include "constants/party_menu.h"
#include "constants/trainers.h"
static void RecordedPartnerHandleDrawTrainerPic(u32 battler);
static void RecordedPartnerHandleTrainerSlide(u32 battler);
static void RecordedPartnerHandleTrainerSlideBack(u32 battler);
static void RecordedPartnerHandleChooseAction(u32 battler);
static void RecordedPartnerHandleChooseMove(u32 battler);
static void RecordedPartnerHandleChoosePokemon(u32 battler);
static void RecordedPartnerHandleIntroTrainerBallThrow(u32 battler);
static void RecordedPartnerHandleDrawPartyStatusSummary(u32 battler);
static void RecordedPartnerHandleEndLinkBattle(u32 battler);
static void RecordedPartnerBufferRunCommand(u32 battler);
static void RecordedPartnerHandleDrawTrainerPic(enum BattlerId battler);
static void RecordedPartnerHandleTrainerSlide(enum BattlerId battler);
static void RecordedPartnerHandleTrainerSlideBack(enum BattlerId battler);
static void RecordedPartnerHandleChooseAction(enum BattlerId battler);
static void RecordedPartnerHandleChooseMove(enum BattlerId battler);
static void RecordedPartnerHandleChoosePokemon(enum BattlerId battler);
static void RecordedPartnerHandleIntroTrainerBallThrow(enum BattlerId battler);
static void RecordedPartnerHandleDrawPartyStatusSummary(enum BattlerId battler);
static void RecordedPartnerHandleEndLinkBattle(enum BattlerId battler);
static void RecordedPartnerBufferRunCommand(enum BattlerId battler);
static void (*const sRecordedPartnerBufferCommands[CONTROLLER_CMDS_COUNT])(u32 battler) =
static void (*const sRecordedPartnerBufferCommands[CONTROLLER_CMDS_COUNT])(enum BattlerId battler) =
{
[CONTROLLER_GETMONDATA] = BtlController_HandleGetMonData,
[CONTROLLER_GETRAWMONDATA] = BtlController_Empty,
@ -102,14 +103,14 @@ static void (*const sRecordedPartnerBufferCommands[CONTROLLER_CMDS_COUNT])(u32 b
[CONTROLLER_TERMINATOR_NOP] = BtlController_TerminatorNop
};
void SetControllerToRecordedPartner(u32 battler)
void SetControllerToRecordedPartner(enum BattlerId battler)
{
gBattlerBattleController[battler] = BATTLE_CONTROLLER_RECORDED_PARTNER;
gBattlerControllerEndFuncs[battler] = RecordedPartnerBufferExecCompleted;
gBattlerControllerFuncs[battler] = RecordedPartnerBufferRunCommand;
}
static void RecordedPartnerBufferRunCommand(u32 battler)
static void RecordedPartnerBufferRunCommand(enum BattlerId battler)
{
if (IsBattleControllerActiveOnLocal(battler))
{
@ -120,7 +121,7 @@ static void RecordedPartnerBufferRunCommand(u32 battler)
}
}
static void Intro_WaitForHealthbox(u32 battler)
static void Intro_WaitForHealthbox(enum BattlerId battler)
{
bool32 finished = FALSE;
@ -148,7 +149,7 @@ static void Intro_WaitForHealthbox(u32 battler)
}
}
void Controller_RecordedPartnerShowIntroHealthbox(u32 battler)
void Controller_RecordedPartnerShowIntroHealthbox(enum BattlerId battler)
{
if (!gBattleSpritesDataPtr->healthBoxesData[battler].ballAnimActive
&& !gBattleSpritesDataPtr->healthBoxesData[BATTLE_PARTNER(battler)].ballAnimActive
@ -178,7 +179,7 @@ void Controller_RecordedPartnerShowIntroHealthbox(u32 battler)
}
}
void RecordedPartnerBufferExecCompleted(u32 battler)
void RecordedPartnerBufferExecCompleted(enum BattlerId battler)
{
gBattlerControllerFuncs[battler] = RecordedPartnerBufferRunCommand;
if (gBattleTypeFlags & BATTLE_TYPE_LINK)
@ -209,7 +210,7 @@ static enum TrainerPicID RecordedPartnerGetTrainerBackPicId(enum DifficultyLevel
// some explanation here
// in emerald it's possible to have a tag battle in the battle frontier facilities with AI
// which use the front sprite for both the player and the partner as opposed to any other battles (including the one with Steven) that use the back pic as well as animate it
static void RecordedPartnerHandleDrawTrainerPic(u32 battler)
static void RecordedPartnerHandleDrawTrainerPic(enum BattlerId battler)
{
bool32 isFrontPic;
s16 xPos, yPos;
@ -224,25 +225,25 @@ static void RecordedPartnerHandleDrawTrainerPic(u32 battler)
BtlController_HandleDrawTrainerPic(battler, trainerPicId, isFrontPic, xPos, yPos, -1);
}
static void RecordedPartnerHandleTrainerSlide(u32 battler)
static void RecordedPartnerHandleTrainerSlide(enum BattlerId battler)
{
enum DifficultyLevel difficulty = GetBattlePartnerDifficultyLevel(gPartnerTrainerId);
enum TrainerPicID trainerPicId = RecordedPartnerGetTrainerBackPicId(difficulty);
BtlController_HandleTrainerSlide(battler, trainerPicId);
}
static void RecordedPartnerHandleTrainerSlideBack(u32 battler)
static void RecordedPartnerHandleTrainerSlideBack(enum BattlerId battler)
{
BtlController_HandleTrainerSlideBack(battler, 35, FALSE);
}
static void RecordedPartnerHandleChooseAction(u32 battler)
static void RecordedPartnerHandleChooseAction(enum BattlerId battler)
{
BtlController_EmitTwoReturnValues(battler, B_COMM_TO_ENGINE, RecordedBattle_GetBattlerAction(RECORDED_ACTION_TYPE, battler), 0);
BtlController_Complete(battler);
}
static void RecordedPartnerHandleChooseMove(u32 battler)
static void RecordedPartnerHandleChooseMove(enum BattlerId battler)
{
u8 moveIndex = RecordedBattle_GetBattlerAction(RECORDED_MOVE_SLOT, battler);
u8 target = RecordedBattle_GetBattlerAction(RECORDED_MOVE_TARGET, battler);
@ -251,7 +252,7 @@ static void RecordedPartnerHandleChooseMove(u32 battler)
BtlController_Complete(battler);
}
static void RecordedPartnerHandleChoosePokemon(u32 battler)
static void RecordedPartnerHandleChoosePokemon(enum BattlerId battler)
{
gBattleStruct->monToSwitchIntoId[battler] = RecordedBattle_GetBattlerAction(RECORDED_PARTY_INDEX, battler);
gSelectedMonPartyId = gBattleStruct->monToSwitchIntoId[battler]; // Revival Blessing
@ -259,7 +260,7 @@ static void RecordedPartnerHandleChoosePokemon(u32 battler)
BtlController_Complete(battler);
}
static void RecordedPartnerHandleIntroTrainerBallThrow(u32 battler)
static void RecordedPartnerHandleIntroTrainerBallThrow(enum BattlerId battler)
{
const u16 *trainerPal;
enum DifficultyLevel difficulty = GetBattlePartnerDifficultyLevel(gPartnerTrainerId);
@ -269,17 +270,17 @@ static void RecordedPartnerHandleIntroTrainerBallThrow(u32 battler)
else if (IsAiVsAiBattle())
trainerPal = gTrainerSprites[GetTrainerPicFromId(gPartnerTrainerId)].palette.data;
else
trainerPal = gTrainerSprites[TRAINER_PIC_RED].palette.data; // 2 vs 2 multi battle in Battle Frontier, load front sprite and pal.
trainerPal = gTrainerSprites[GetFrontierTrainerFrontSpriteId(gPartnerTrainerId)].palette.data; // 2 vs 2 multi battle in Battle Frontier, load front sprite and pal.
BtlController_HandleIntroTrainerBallThrow(battler, 0xD6F9, trainerPal, 24, Controller_RecordedPartnerShowIntroHealthbox);
}
static void RecordedPartnerHandleDrawPartyStatusSummary(u32 battler)
static void RecordedPartnerHandleDrawPartyStatusSummary(enum BattlerId battler)
{
BtlController_HandleDrawPartyStatusSummary(battler, B_SIDE_PLAYER, TRUE);
}
static void RecordedPartnerHandleEndLinkBattle(u32 battler)
static void RecordedPartnerHandleEndLinkBattle(enum BattlerId battler)
{
gBattleOutcome = gBattleResources->bufferA[battler][1];
FadeOutMapMusic(5);

View File

@ -31,19 +31,19 @@
#include "test/battle.h"
#include "test/test_runner_battle.h"
static void RecordedPlayerHandleDrawTrainerPic(u32 battler);
static void RecordedPlayerHandleTrainerSlideBack(u32 battler);
static void RecordedPlayerHandleChooseAction(u32 battler);
static void RecordedPlayerHandleChooseMove(u32 battler);
static void RecordedPlayerHandleChooseItem(u32 battler);
static void RecordedPlayerHandleChoosePokemon(u32 battler);
static void RecordedPlayerHandleStatusAnimation(u32 battler);
static void RecordedPlayerHandleIntroTrainerBallThrow(u32 battler);
static void RecordedPlayerHandleDrawPartyStatusSummary(u32 battler);
static void RecordedPlayerHandleEndLinkBattle(u32 battler);
static void RecordedPlayerBufferRunCommand(u32 battler);
static void RecordedPlayerHandleDrawTrainerPic(enum BattlerId battler);
static void RecordedPlayerHandleTrainerSlideBack(enum BattlerId battler);
static void RecordedPlayerHandleChooseAction(enum BattlerId battler);
static void RecordedPlayerHandleChooseMove(enum BattlerId battler);
static void RecordedPlayerHandleChooseItem(enum BattlerId battler);
static void RecordedPlayerHandleChoosePokemon(enum BattlerId battler);
static void RecordedPlayerHandleStatusAnimation(enum BattlerId battler);
static void RecordedPlayerHandleIntroTrainerBallThrow(enum BattlerId battler);
static void RecordedPlayerHandleDrawPartyStatusSummary(enum BattlerId battler);
static void RecordedPlayerHandleEndLinkBattle(enum BattlerId battler);
static void RecordedPlayerBufferRunCommand(enum BattlerId battler);
static void (*const sRecordedPlayerBufferCommands[CONTROLLER_CMDS_COUNT])(u32 battler) =
static void (*const sRecordedPlayerBufferCommands[CONTROLLER_CMDS_COUNT])(enum BattlerId battler) =
{
[CONTROLLER_GETMONDATA] = BtlController_HandleGetMonData,
[CONTROLLER_GETRAWMONDATA] = BtlController_Empty,
@ -100,14 +100,14 @@ static void (*const sRecordedPlayerBufferCommands[CONTROLLER_CMDS_COUNT])(u32 ba
[CONTROLLER_TERMINATOR_NOP] = BtlController_TerminatorNop
};
void SetControllerToRecordedPlayer(u32 battler)
void SetControllerToRecordedPlayer(enum BattlerId battler)
{
gBattlerBattleController[battler] = BATTLE_CONTROLLER_RECORDED_PLAYER;
gBattlerControllerEndFuncs[battler] = RecordedPlayerBufferExecCompleted;
gBattlerControllerFuncs[battler] = RecordedPlayerBufferRunCommand;
}
static void RecordedPlayerBufferRunCommand(u32 battler)
static void RecordedPlayerBufferRunCommand(enum BattlerId battler)
{
if (IsBattleControllerActiveOnLocal(battler))
{
@ -118,7 +118,7 @@ static void RecordedPlayerBufferRunCommand(u32 battler)
}
}
static void Intro_WaitForShinyAnimAndHealthbox(u32 battler)
static void Intro_WaitForShinyAnimAndHealthbox(enum BattlerId battler)
{
bool32 healthboxAnimDone = FALSE;
@ -184,7 +184,7 @@ static void Intro_WaitForShinyAnimAndHealthbox(u32 battler)
}
}
static void Intro_TryShinyAnimShowHealthbox(u32 battler)
static void Intro_TryShinyAnimShowHealthbox(enum BattlerId battler)
{
bool32 bgmRestored = FALSE;
@ -253,7 +253,7 @@ static void Intro_TryShinyAnimShowHealthbox(u32 battler)
}
}
void RecordedPlayerBufferExecCompleted(u32 battler)
void RecordedPlayerBufferExecCompleted(enum BattlerId battler)
{
gBattlerControllerFuncs[battler] = RecordedPlayerBufferRunCommand;
if (gBattleTypeFlags & BATTLE_TYPE_LINK)
@ -269,7 +269,7 @@ void RecordedPlayerBufferExecCompleted(u32 battler)
}
}
static void RecordedPlayerHandleDrawTrainerPic(u32 battler)
static void RecordedPlayerHandleDrawTrainerPic(enum BattlerId battler)
{
bool32 isFrontPic;
s16 xPos, yPos;
@ -290,12 +290,12 @@ static void RecordedPlayerHandleDrawTrainerPic(u32 battler)
if (gBattleTypeFlags & BATTLE_TYPE_RECORDED_LINK)
{
if (gBattleTypeFlags & BATTLE_TYPE_MULTI)
trainerPicId = GetBattlerLinkPlayerGender(battler);
trainerPicId = GetBattlerLinkPlayerGender(battler) + TRAINER_BACK_PIC_RED;
else
trainerPicId = gLinkPlayers[gRecordedBattleMultiplayerId].gender;
trainerPicId = gLinkPlayers[gRecordedBattleMultiplayerId].gender + TRAINER_BACK_PIC_RED;
}
else
trainerPicId = gLinkPlayers[0].gender;
trainerPicId = gLinkPlayers[0].gender + TRAINER_BACK_PIC_RED;
if (gBattleTypeFlags & BATTLE_TYPE_MULTI)
{
@ -330,25 +330,25 @@ static void RecordedPlayerHandleDrawTrainerPic(u32 battler)
BtlController_HandleDrawTrainerPic(battler, trainerPicId, isFrontPic, xPos, yPos, -1);
}
static void RecordedPlayerHandleTrainerSlideBack(u32 battler)
static void RecordedPlayerHandleTrainerSlideBack(enum BattlerId battler)
{
BtlController_HandleTrainerSlideBack(battler, 35, FALSE);
}
// static void ChooseActionInBattlePalace(u32 battler)
// {
// if (gBattleCommunication[4] >= gBattlersCount / 2)
// {
// BtlController_EmitTwoReturnValues(battler, B_COMM_TO_ENGINE, RecordedBattle_GetBattlerAction(RECORDED_BATTLE_PALACE_ACTION, battler), 0);
// BtlController_Complete(battler);
// }
// }
static void ChooseActionInBattlePalace(enum BattlerId battler)
{
if (gBattleCommunication[4] >= gBattlersCount / 2)
{
BtlController_EmitTwoReturnValues(battler, B_COMM_TO_ENGINE, RecordedBattle_GetBattlerAction(RECORDED_BATTLE_PALACE_ACTION, battler), 0);
BtlController_Complete(battler);
}
}
static void RecordedPlayerHandleChooseAction(u32 battler)
static void RecordedPlayerHandleChooseAction(enum BattlerId battler)
{
if (gBattleTypeFlags & BATTLE_TYPE_PALACE)
{
// gBattlerControllerFuncs[battler] = ChooseActionInBattlePalace;
gBattlerControllerFuncs[battler] = ChooseActionInBattlePalace;
}
else
{
@ -357,11 +357,11 @@ static void RecordedPlayerHandleChooseAction(u32 battler)
}
}
static void RecordedPlayerHandleChooseMove(u32 battler)
static void RecordedPlayerHandleChooseMove(enum BattlerId battler)
{
if (gBattleTypeFlags & BATTLE_TYPE_PALACE)
{
// BtlController_EmitTwoReturnValues(battler, B_COMM_TO_ENGINE, B_ACTION_EXEC_SCRIPT, ChooseMoveAndTargetInBattlePalace(battler));
BtlController_EmitTwoReturnValues(battler, B_COMM_TO_ENGINE, B_ACTION_EXEC_SCRIPT, ChooseMoveAndTargetInBattlePalace(battler));
}
else
{
@ -373,7 +373,7 @@ static void RecordedPlayerHandleChooseMove(u32 battler)
BtlController_Complete(battler);
}
static void RecordedPlayerHandleChooseItem(u32 battler)
static void RecordedPlayerHandleChooseItem(enum BattlerId battler)
{
u8 byte1 = RecordedBattle_GetBattlerAction(RECORDED_ITEM_ID, battler);
u8 byte2 = RecordedBattle_GetBattlerAction(RECORDED_ITEM_ID, battler);
@ -384,7 +384,7 @@ static void RecordedPlayerHandleChooseItem(u32 battler)
BtlController_Complete(battler);
}
static void RecordedPlayerHandleChoosePokemon(u32 battler)
static void RecordedPlayerHandleChoosePokemon(enum BattlerId battler)
{
gBattleStruct->monToSwitchIntoId[battler] = RecordedBattle_GetBattlerAction(RECORDED_PARTY_INDEX, battler);
gSelectedMonPartyId = gBattleStruct->monToSwitchIntoId[battler]; // Revival Blessing
@ -392,12 +392,12 @@ static void RecordedPlayerHandleChoosePokemon(u32 battler)
BtlController_Complete(battler);
}
static void RecordedPlayerHandleStatusAnimation(u32 battler)
static void RecordedPlayerHandleStatusAnimation(enum BattlerId battler)
{
BtlController_HandleStatusAnimation(battler);
}
static void RecordedPlayerHandleIntroTrainerBallThrow(u32 battler)
static void RecordedPlayerHandleIntroTrainerBallThrow(enum BattlerId battler)
{
enum TrainerPicID trainerPicId;
const u16 *trainerPal;
@ -411,12 +411,12 @@ static void RecordedPlayerHandleIntroTrainerBallThrow(u32 battler)
BtlController_HandleIntroTrainerBallThrow(battler, 0xD6F9, trainerPal, 24, Intro_TryShinyAnimShowHealthbox);
}
static void RecordedPlayerHandleDrawPartyStatusSummary(u32 battler)
static void RecordedPlayerHandleDrawPartyStatusSummary(enum BattlerId battler)
{
BtlController_HandleDrawPartyStatusSummary(battler, B_SIDE_PLAYER, TRUE);
}
static void RecordedPlayerHandleEndLinkBattle(u32 battler)
static void RecordedPlayerHandleEndLinkBattle(enum BattlerId battler)
{
gBattleOutcome = gBattleResources->bufferA[battler][1];
FadeOutMapMusic(5);

View File

@ -29,18 +29,18 @@
#include "constants/trainers.h"
#include "constants/rgb.h"
static void SafariHandleDrawTrainerPic(u32 battler);
static void SafariHandleChooseAction(u32 battler);
static void SafariHandleChooseItem(u32 battler);
static void SafariHandleStatusIconUpdate(u32 battler);
static void SafariHandleFaintingCry(u32 battler);
static void SafariHandleIntroTrainerBallThrow(u32 battler);
static void SafariHandleEndLinkBattle(u32 battler);
static void SafariHandleDrawTrainerPic(enum BattlerId battler);
static void SafariHandleChooseAction(enum BattlerId battler);
static void SafariHandleChooseItem(enum BattlerId battler);
static void SafariHandleStatusIconUpdate(enum BattlerId battler);
static void SafariHandleFaintingCry(enum BattlerId battler);
static void SafariHandleIntroTrainerBallThrow(enum BattlerId battler);
static void SafariHandleEndLinkBattle(enum BattlerId battler);
static void SafariBufferRunCommand(u32 battler);
static void CompleteWhenChosePokeblock(u32 battler);
static void SafariBufferRunCommand(enum BattlerId battler);
static void CompleteWhenChosePokeblock(enum BattlerId battler);
static void (*const sSafariBufferCommands[CONTROLLER_CMDS_COUNT])(u32 battler) =
static void (*const sSafariBufferCommands[CONTROLLER_CMDS_COUNT])(enum BattlerId battler) =
{
[CONTROLLER_GETMONDATA] = BtlController_Empty,
[CONTROLLER_GETRAWMONDATA] = BtlController_Empty,
@ -100,14 +100,14 @@ static void (*const sSafariBufferCommands[CONTROLLER_CMDS_COUNT])(u32 battler) =
static const u8 sText_WhatWillPlayerThrow[] = _("What will {B_PLAYER_NAME}\nthrow?");
static const u8 sText_SafariZoneMenu[] = _("{PALETTE 5}{COLOR_HIGHLIGHT_SHADOW 13 14 15}BALL{CLEAR_TO 56}BAIT\nROCK{CLEAR_TO 56}RUN");
void SetControllerToSafari(u32 battler)
void SetControllerToSafari(enum BattlerId battler)
{
gBattlerBattleController[battler] = BATTLE_CONTROLLER_SAFARI;
gBattlerControllerEndFuncs[battler] = SafariBufferExecCompleted;
gBattlerControllerFuncs[battler] = SafariBufferRunCommand;
}
static void SafariBufferRunCommand(u32 battler)
static void SafariBufferRunCommand(enum BattlerId battler)
{
if (IsBattleControllerActiveOnLocal(battler))
{
@ -118,7 +118,7 @@ static void SafariBufferRunCommand(u32 battler)
}
}
static void HandleInputChooseAction(u32 battler)
static void HandleInputChooseAction(enum BattlerId battler)
{
if (JOY_NEW(A_BUTTON))
{
@ -190,13 +190,13 @@ static void HandleInputChooseAction(u32 battler)
}
}
static void Controller_WaitForHealthbox(u32 battler)
static void Controller_WaitForHealthbox(enum BattlerId battler)
{
if (gSprites[gHealthboxSpriteIds[battler]].callback == SpriteCallbackDummy)
BtlController_Complete(battler);
}
static void SafariSetBattleEndCallbacks(u32 battler)
static void SafariSetBattleEndCallbacks(enum BattlerId battler)
{
if (!gPaletteFade.active)
{
@ -206,7 +206,7 @@ static void SafariSetBattleEndCallbacks(u32 battler)
}
}
static void SafariOpenPokeblockCase(u32 battler)
static void SafariOpenPokeblockCase(enum BattlerId battler)
{
if (!gPaletteFade.active)
{
@ -214,7 +214,7 @@ static void SafariOpenPokeblockCase(u32 battler)
}
}
static void CompleteWhenChosePokeblock(u32 battler)
static void CompleteWhenChosePokeblock(enum BattlerId battler)
{
if (gMain.callback2 == BattleMainCB2 && !gPaletteFade.active)
{
@ -223,7 +223,7 @@ static void CompleteWhenChosePokeblock(u32 battler)
}
}
void SafariBufferExecCompleted(u32 battler)
void SafariBufferExecCompleted(enum BattlerId battler)
{
gBattlerControllerFuncs[battler] = SafariBufferRunCommand;
if (gBattleTypeFlags & BATTLE_TYPE_LINK)
@ -239,7 +239,7 @@ void SafariBufferExecCompleted(u32 battler)
}
}
static void SafariHandleDrawTrainerPic(u32 battler)
static void SafariHandleDrawTrainerPic(enum BattlerId battler)
{
enum TrainerPicID trainerPicId = gSaveBlock2Ptr->playerGender + TRAINER_BACK_PIC_RED;
@ -248,7 +248,7 @@ static void SafariHandleDrawTrainerPic(u32 battler)
30);
}
static void HandleChooseActionAfterDma3(u32 battler)
static void HandleChooseActionAfterDma3(enum BattlerId battler)
{
if (!IsDma3ManagerBusyWithBgCopy())
{
@ -258,7 +258,7 @@ static void HandleChooseActionAfterDma3(u32 battler)
}
}
static void SafariHandleChooseAction(u32 battler)
static void SafariHandleChooseAction(enum BattlerId battler)
{
s32 i;
@ -274,14 +274,14 @@ static void SafariHandleChooseAction(u32 battler)
BattlePutTextOnWindow(gDisplayedStringBattle, B_WIN_ACTION_PROMPT);
}
static void SafariHandleChooseItem(u32 battler)
static void SafariHandleChooseItem(enum BattlerId battler)
{
BeginNormalPaletteFade(PALETTES_ALL, 0, 0, 0x10, RGB_BLACK);
gBattlerControllerFuncs[battler] = SafariOpenPokeblockCase;
gBattlerInMenuId = battler;
}
static void SafariHandleStatusIconUpdate(u32 battler)
static void SafariHandleStatusIconUpdate(enum BattlerId battler)
{
UpdateHealthboxAttribute(gHealthboxSpriteIds[battler], GetBattlerMon(battler), HEALTHBOX_SAFARI_BALLS_TEXT);
BtlController_Complete(battler);
@ -289,7 +289,7 @@ static void SafariHandleStatusIconUpdate(u32 battler)
// All of the other controllers(except Wally's) use CRY_MODE_FAINT.
// Player is not a pokemon, so it can't really faint in the Safari anyway.
static void SafariHandleFaintingCry(u32 battler)
static void SafariHandleFaintingCry(enum BattlerId battler)
{
u16 species = GetMonData(GetBattlerMon(battler), MON_DATA_SPECIES);
@ -297,7 +297,7 @@ static void SafariHandleFaintingCry(u32 battler)
BtlController_Complete(battler);
}
static void SafariHandleIntroTrainerBallThrow(u32 battler)
static void SafariHandleIntroTrainerBallThrow(enum BattlerId battler)
{
UpdateHealthboxAttribute(gHealthboxSpriteIds[battler], GetBattlerMon(battler), HEALTHBOX_SAFARI_ALL_TEXT);
StartHealthboxSlideIn(battler);
@ -305,7 +305,7 @@ static void SafariHandleIntroTrainerBallThrow(u32 battler)
gBattlerControllerFuncs[battler] = Controller_WaitForHealthbox;
}
static void SafariHandleEndLinkBattle(u32 battler)
static void SafariHandleEndLinkBattle(enum BattlerId battler)
{
gBattleOutcome = gBattleResources->bufferA[battler][1];
FadeOutMapMusic(5);

File diff suppressed because it is too large Load Diff

View File

@ -70,7 +70,7 @@ static const struct GMaxMove sGMaxMoveTable[] =
};
// Returns whether a battler can Dynamax.
bool32 CanDynamax(u32 battler)
bool32 CanDynamax(enum BattlerId battler)
{
u16 species = GetBattlerVisualSpecies(battler);
enum HoldEffect holdEffect = GetBattlerHoldEffectIgnoreNegation(battler);
@ -120,7 +120,7 @@ bool32 CanDynamax(u32 battler)
}
// Returns whether a battler is transformed into a Gigantamax form.
bool32 IsGigantamaxed(u32 battler)
bool32 IsGigantamaxed(enum BattlerId battler)
{
struct Pokemon *mon = GetBattlerMon(battler);
if ((gSpeciesInfo[gBattleMons[battler].species].isGigantamax) && GetMonData(mon, MON_DATA_GIGANTAMAX_FACTOR))
@ -144,7 +144,7 @@ void ApplyDynamaxHPMultiplier(struct Pokemon* mon)
}
// Returns the non-Dynamax HP of a Pokemon.
u32 GetNonDynamaxHP(u32 battler)
u32 GetNonDynamaxHP(enum BattlerId battler)
{
if (GetActiveGimmick(battler) != GIMMICK_DYNAMAX || gBattleMons[battler].species == SPECIES_SHEDINJA)
return gBattleMons[battler].hp;
@ -158,7 +158,7 @@ u32 GetNonDynamaxHP(u32 battler)
}
// Returns the non-Dynamax Max HP of a Pokemon.
u32 GetNonDynamaxMaxHP(u32 battler)
u32 GetNonDynamaxMaxHP(enum BattlerId battler)
{
if (GetActiveGimmick(battler) != GIMMICK_DYNAMAX || gBattleMons[battler].species == SPECIES_SHEDINJA)
return gBattleMons[battler].maxHP;
@ -172,7 +172,7 @@ u32 GetNonDynamaxMaxHP(u32 battler)
}
// Sets flags used for Dynamaxing and checks Gigantamax forms.
void ActivateDynamax(u32 battler)
void ActivateDynamax(enum BattlerId battler)
{
// Set appropriate use flags.
SetActiveGimmick(battler, GIMMICK_DYNAMAX);
@ -188,13 +188,13 @@ void ActivateDynamax(u32 battler)
// Try Gigantamax form change.
if (!gBattleMons[battler].volatiles.transformed) // Ditto cannot Gigantamax.
TryBattleFormChange(battler, FORM_CHANGE_BATTLE_GIGANTAMAX);
TryBattleFormChange(battler, FORM_CHANGE_BATTLE_GIGANTAMAX, GetBattlerAbility(battler));
BattleScriptPushCursorAndCallback(BattleScript_DynamaxBegins);
}
// Unsets the flags used for Dynamaxing and reverts max HP if needed.
void UndoDynamax(u32 battler)
void UndoDynamax(enum BattlerId battler)
{
// Revert HP if battler is still Dynamaxed.
if (GetActiveGimmick(battler) == GIMMICK_DYNAMAX)
@ -211,7 +211,7 @@ void UndoDynamax(u32 battler)
// Undo form change if needed.
if (IsGigantamaxed(battler))
TryBattleFormChange(battler, FORM_CHANGE_END_BATTLE);
TryBattleFormChange(battler, FORM_CHANGE_END_BATTLE, GetBattlerAbility(battler));
}
// Certain moves are blocked by Max Guard that normally ignore protection.
@ -234,15 +234,16 @@ bool32 IsMoveBlockedByMaxGuard(enum Move move)
}
}
static enum Move GetTypeBasedMaxMove(u32 battler, enum Type type)
static enum Move GetTypeBasedMaxMove(enum BattlerId battler, enum Type type)
{
// Gigantamax check
u32 i;
u32 species = gBattleMons[battler].species;
u32 targetSpecies = species;
enum Ability ability = GetBattlerAbility(battler);
if (!gSpeciesInfo[species].isGigantamax)
targetSpecies = GetBattleFormChangeTargetSpecies(battler, FORM_CHANGE_BATTLE_GIGANTAMAX);
targetSpecies = GetBattleFormChangeTargetSpecies(battler, FORM_CHANGE_BATTLE_GIGANTAMAX, ability);
if (targetSpecies != species)
species = targetSpecies;
@ -263,7 +264,7 @@ static enum Move GetTypeBasedMaxMove(u32 battler, enum Type type)
}
// Returns the appropriate Max Move or G-Max Move for a battler to use.
enum Move GetMaxMove(u32 battler, enum Move baseMove)
enum Move GetMaxMove(enum BattlerId battler, enum Move baseMove)
{
enum Type moveType;
SetTypeBeforeUsingMove(baseMove, battler);
@ -402,7 +403,6 @@ static enum MaxPowerTier GetMaxPowerTier(enum Move move)
case EFFECT_FINAL_GAMBIT:
return MAX_POWER_TIER_2;
case EFFECT_OHKO:
case EFFECT_SHEER_COLD:
case EFFECT_RETURN:
case EFFECT_FRUSTRATION:
case EFFECT_HEAT_CRASH:
@ -459,43 +459,3 @@ void ChooseDamageNonTypesString(enum Type type)
break;
}
}
// Updates Dynamax HP multipliers and healthboxes.
void BS_UpdateDynamax(void)
{
NATIVE_ARGS();
u32 battler = gBattleScripting.battler;
struct Pokemon *mon = GetBattlerMon(battler);
if (!IsGigantamaxed(battler)) // RecalcBattlerStats will get called on form change.
RecalcBattlerStats(battler, mon, GetActiveGimmick(battler) == GIMMICK_DYNAMAX);
UpdateHealthboxAttribute(gHealthboxSpriteIds[battler], mon, HEALTHBOX_ALL);
gBattlescriptCurrInstr = cmd->nextInstr;
}
// Goes to the jump instruction if the target is Dynamaxed.
void BS_JumpIfDynamaxed(void)
{
NATIVE_ARGS(const u8 *jumpInstr);
if ((GetActiveGimmick(gBattlerTarget) == GIMMICK_DYNAMAX))
gBattlescriptCurrInstr = cmd->jumpInstr;
else
gBattlescriptCurrInstr = cmd->nextInstr;
}
void BS_UndoDynamax(void)
{
NATIVE_ARGS(u8 battler);
u32 battler = GetBattlerForBattleScript(cmd->battler);
if (GetActiveGimmick(battler) == GIMMICK_DYNAMAX)
{
UndoDynamax(battler);
gBattleScripting.battler = battler;
BattleScriptCall(BattleScript_DynamaxEnds_Ret);
return;
}
gBattlescriptCurrInstr = cmd->nextInstr;
}

View File

@ -15,7 +15,7 @@
static u32 GetBattlerSideForMessage(enum BattleSide side)
{
u32 battler = 0;
enum BattlerId battler = 0;
for (battler = 0; battler < gBattlersCount; battler++)
{
@ -26,23 +26,22 @@ static u32 GetBattlerSideForMessage(enum BattleSide side)
return battler;
}
static bool32 HandleEndTurnOrder(u32 battler)
static bool32 HandleEndTurnOrder(enum BattlerId battler)
{
bool32 effect = FALSE;
gBattleTurnCounter++;
gBattleStruct->eventState.endTurn++;
for (u32 i = 0; i < gBattlersCount; i++)
for (enum BattlerId i = 0; i < gBattlersCount; i++)
gBattlerByTurnOrder[i] = i;
SortBattlersBySpeed(gBattlerByTurnOrder, FALSE);
return effect;
}
static bool32 HandleEndTurnVarious(u32 battler)
static bool32 HandleEndTurnVarious(enum BattlerId battler)
{
u32 i;
bool32 effect = FALSE;
gBattleStruct->eventState.endTurn++;
@ -50,13 +49,13 @@ static bool32 HandleEndTurnVarious(u32 battler)
if (gFieldTimers.fairyLockTimer > 0 && --gFieldTimers.fairyLockTimer == 0)
gFieldStatuses &= ~STATUS_FIELD_FAIRY_LOCK;
for (i = 0; i < NUM_BATTLE_SIDES; i++)
for (enum BattleSide i = 0; i < NUM_BATTLE_SIDES; i++)
{
if (gSideTimers[i].damageNonTypesTimer > 0 && --gSideTimers[i].damageNonTypesTimer == 0)
gSideStatuses[i] &= ~SIDE_STATUS_DAMAGE_NON_TYPES;
}
for (i = 0; i < gBattlersCount; i++)
for (enum BattlerId i = 0; i < gBattlersCount; i++)
{
if (gBattleMons[i].volatiles.throatChopTimer > 0)
gBattleMons[i].volatiles.throatChopTimer--;
@ -87,13 +86,13 @@ static bool32 HandleEndTurnVarious(u32 battler)
return effect;
}
static bool32 HandleEndTurnWeather(u32 battler)
static bool32 HandleEndTurnWeather(enum BattlerId battler)
{
gBattleStruct->eventState.endTurn++;
return EndOrContinueWeather();
}
static bool32 HandleEndTurnWeatherDamage(u32 battler)
static bool32 HandleEndTurnWeatherDamage(enum BattlerId battler)
{
bool32 effect = FALSE;
@ -182,7 +181,7 @@ static bool32 HandleEndTurnWeatherDamage(u32 battler)
return effect;
}
static bool32 HandleEndTurnEmergencyExit(u32 battler)
static bool32 HandleEndTurnEmergencyExit(enum BattlerId battler)
{
bool32 effect = FALSE;
enum Ability ability = GetBattlerAbility(battler);
@ -201,7 +200,7 @@ static bool32 HandleEndTurnEmergencyExit(u32 battler)
return effect;
}
static bool32 HandleEndTurnAffection(u32 battler)
static bool32 HandleEndTurnAffection(enum BattlerId battler)
{
bool32 effect = FALSE;
@ -224,7 +223,7 @@ static bool32 HandleEndTurnAffection(u32 battler)
// Note: Technically Future Sight, Doom Desire and Wish need a queue but
// I think we should accept this slight inconsistency so custom moves don't have to touch this code
static bool32 HandleEndTurnFutureSight(u32 battler)
static bool32 HandleEndTurnFutureSight(enum BattlerId battler)
{
bool32 effect = FALSE;
@ -258,7 +257,7 @@ static bool32 HandleEndTurnFutureSight(u32 battler)
return effect;
}
static bool32 HandleEndTurnWish(u32 battler)
static bool32 HandleEndTurnWish(enum BattlerId battler)
{
bool32 effect = FALSE;
@ -288,7 +287,7 @@ static bool32 HandleEndTurnWish(u32 battler)
return effect;
}
static bool32 HandleEndTurnFirstEventBlock(u32 battler)
static bool32 HandleEndTurnFirstEventBlock(enum BattlerId battler)
{
bool32 effect = FALSE;
enum BattleSide side;
@ -392,7 +391,7 @@ static bool32 HandleEndTurnFirstEventBlock(u32 battler)
return effect;
}
static bool32 HandleEndTurnAquaRing(u32 battler)
static bool32 HandleEndTurnAquaRing(enum BattlerId battler)
{
bool32 effect = FALSE;
@ -411,7 +410,7 @@ static bool32 HandleEndTurnAquaRing(u32 battler)
return effect;
}
static bool32 HandleEndTurnIngrain(u32 battler)
static bool32 HandleEndTurnIngrain(enum BattlerId battler)
{
bool32 effect = FALSE;
@ -430,7 +429,7 @@ static bool32 HandleEndTurnIngrain(u32 battler)
return effect;
}
static bool32 HandleEndTurnLeechSeed(u32 battler)
static bool32 HandleEndTurnLeechSeed(enum BattlerId battler)
{
bool32 effect = FALSE;
@ -470,7 +469,7 @@ static bool32 HandleEndTurnLeechSeed(u32 battler)
return effect;
}
static bool32 HandleEndTurnPoison(u32 battler)
static bool32 HandleEndTurnPoison(enum BattlerId battler)
{
bool32 effect = FALSE;
@ -511,7 +510,7 @@ static bool32 HandleEndTurnPoison(u32 battler)
return effect;
}
static bool32 HandleEndTurnBurn(u32 battler)
static bool32 HandleEndTurnBurn(enum BattlerId battler)
{
bool32 effect = FALSE;
@ -538,7 +537,7 @@ static bool32 HandleEndTurnBurn(u32 battler)
return effect;
}
static bool32 HandleEndTurnFrostbite(u32 battler)
static bool32 HandleEndTurnFrostbite(enum BattlerId battler)
{
bool32 effect = FALSE;
@ -556,7 +555,7 @@ static bool32 HandleEndTurnFrostbite(u32 battler)
return effect;
}
static bool32 HandleEndTurnNightmare(u32 battler)
static bool32 HandleEndTurnNightmare(enum BattlerId battler)
{
bool32 effect = FALSE;
@ -581,7 +580,7 @@ static bool32 HandleEndTurnNightmare(u32 battler)
return effect;
}
static bool32 HandleEndTurnCurse(u32 battler)
static bool32 HandleEndTurnCurse(enum BattlerId battler)
{
bool32 effect = FALSE;
@ -599,7 +598,7 @@ static bool32 HandleEndTurnCurse(u32 battler)
return effect;
}
static bool32 HandleEndTurnWrap(u32 battler)
static bool32 HandleEndTurnWrap(enum BattlerId battler)
{
bool32 effect = FALSE;
@ -636,7 +635,7 @@ static bool32 HandleEndTurnWrap(u32 battler)
return effect;
}
static bool32 HandleEndTurnSaltCure(u32 battler)
static bool32 HandleEndTurnSaltCure(enum BattlerId battler)
{
bool32 effect = FALSE;
@ -660,7 +659,7 @@ static bool32 HandleEndTurnSaltCure(u32 battler)
return effect;
}
static bool32 HandleEndTurnOctolock(u32 battler)
static bool32 HandleEndTurnOctolock(enum BattlerId battler)
{
bool32 effect = FALSE;
@ -677,7 +676,7 @@ static bool32 HandleEndTurnOctolock(u32 battler)
return effect;
}
static bool32 HandleEndTurnSyrupBomb(u32 battler)
static bool32 HandleEndTurnSyrupBomb(enum BattlerId battler)
{
bool32 effect = FALSE;
@ -696,7 +695,7 @@ static bool32 HandleEndTurnSyrupBomb(u32 battler)
return effect;
}
static bool32 HandleEndTurnTaunt(u32 battler)
static bool32 HandleEndTurnTaunt(enum BattlerId battler)
{
bool32 effect = FALSE;
@ -713,7 +712,7 @@ static bool32 HandleEndTurnTaunt(u32 battler)
return effect;
}
static bool32 HandleEndTurnTorment(u32 battler)
static bool32 HandleEndTurnTorment(enum BattlerId battler)
{
bool32 effect = FALSE;
@ -730,7 +729,7 @@ static bool32 HandleEndTurnTorment(u32 battler)
return effect;
}
static bool32 HandleEndTurnEncore(u32 battler)
static bool32 HandleEndTurnEncore(enum BattlerId battler)
{
bool32 effect = FALSE;
@ -757,7 +756,7 @@ static bool32 HandleEndTurnEncore(u32 battler)
return effect;
}
static bool32 HandleEndTurnDisable(u32 battler)
static bool32 HandleEndTurnDisable(enum BattlerId battler)
{
bool32 effect = FALSE;
@ -788,7 +787,7 @@ static bool32 HandleEndTurnDisable(u32 battler)
return effect;
}
static bool32 HandleEndTurnMagnetRise(u32 battler)
static bool32 HandleEndTurnMagnetRise(enum BattlerId battler)
{
bool32 effect = FALSE;
@ -805,7 +804,7 @@ static bool32 HandleEndTurnMagnetRise(u32 battler)
return effect;
}
static bool32 HandleEndTurnTelekinesis(u32 battler)
static bool32 HandleEndTurnTelekinesis(enum BattlerId battler)
{
bool32 effect = FALSE;
@ -821,7 +820,7 @@ static bool32 HandleEndTurnTelekinesis(u32 battler)
return effect;
}
static bool32 HandleEndTurnHealBlock(u32 battler)
static bool32 HandleEndTurnHealBlock(enum BattlerId battler)
{
bool32 effect = FALSE;
@ -839,7 +838,7 @@ static bool32 HandleEndTurnHealBlock(u32 battler)
return effect;
}
static bool32 HandleEndTurnEmbargo(u32 battler)
static bool32 HandleEndTurnEmbargo(enum BattlerId battler)
{
bool32 effect = FALSE;
@ -855,7 +854,7 @@ static bool32 HandleEndTurnEmbargo(u32 battler)
return effect;
}
static bool32 HandleEndTurnYawn(u32 battler)
static bool32 HandleEndTurnYawn(enum BattlerId battler)
{
bool32 effect = FALSE;
@ -919,7 +918,7 @@ static bool32 HandleEndTurnYawn(u32 battler)
return effect;
}
static bool32 HandleEndTurnPerishSong(u32 battler)
static bool32 HandleEndTurnPerishSong(enum BattlerId battler)
{
bool32 effect = FALSE;
@ -945,7 +944,7 @@ static bool32 HandleEndTurnPerishSong(u32 battler)
return effect;
}
static bool32 HandleEndTurnRoost(u32 battler)
static bool32 HandleEndTurnRoost(enum BattlerId battler)
{
bool32 effect = FALSE;
@ -957,7 +956,7 @@ static bool32 HandleEndTurnRoost(u32 battler)
return effect;
}
static bool32 HandleEndTurnSecondEventBlock(u32 battler)
static bool32 HandleEndTurnSecondEventBlock(enum BattlerId battler)
{
bool32 effect = FALSE;
@ -1078,7 +1077,7 @@ static bool32 HandleEndTurnSecondEventBlock(u32 battler)
return effect;
}
static bool32 HandleEndTurnTrickRoom(u32 battler)
static bool32 HandleEndTurnTrickRoom(enum BattlerId battler)
{
bool32 effect = FALSE;
@ -1094,7 +1093,7 @@ static bool32 HandleEndTurnTrickRoom(u32 battler)
return effect;
}
static bool32 HandleEndTurnGravity(u32 battler)
static bool32 HandleEndTurnGravity(enum BattlerId battler)
{
bool32 effect = FALSE;
@ -1110,7 +1109,7 @@ static bool32 HandleEndTurnGravity(u32 battler)
return effect;
}
static bool32 HandleEndTurnWaterSport(u32 battler)
static bool32 HandleEndTurnWaterSport(enum BattlerId battler)
{
bool32 effect = FALSE;
@ -1126,7 +1125,7 @@ static bool32 HandleEndTurnWaterSport(u32 battler)
return effect;
}
static bool32 HandleEndTurnMudSport(u32 battler)
static bool32 HandleEndTurnMudSport(enum BattlerId battler)
{
bool32 effect = FALSE;
@ -1142,7 +1141,7 @@ static bool32 HandleEndTurnMudSport(u32 battler)
return effect;
}
static bool32 HandleEndTurnWonderRoom(u32 battler)
static bool32 HandleEndTurnWonderRoom(enum BattlerId battler)
{
bool32 effect = FALSE;
@ -1158,7 +1157,7 @@ static bool32 HandleEndTurnWonderRoom(u32 battler)
return effect;
}
static bool32 HandleEndTurnMagicRoom(u32 battler)
static bool32 HandleEndTurnMagicRoom(enum BattlerId battler)
{
bool32 effect = FALSE;
@ -1188,7 +1187,7 @@ static bool32 EndTurnTerrain(u32 terrainFlag, u32 stringTableId)
return FALSE;
}
static bool32 HandleEndTurnTerrain(u32 battler)
static bool32 HandleEndTurnTerrain(enum BattlerId battler)
{
bool32 effect = FALSE;
@ -1206,7 +1205,7 @@ static bool32 HandleEndTurnTerrain(u32 battler)
return effect;
}
static bool32 HandleEndTurnThirdEventBlock(u32 battler)
static bool32 HandleEndTurnThirdEventBlock(enum BattlerId battler)
{
bool32 effect = FALSE;
@ -1312,7 +1311,7 @@ static bool32 HandleEndTurnThirdEventBlock(u32 battler)
return effect;
}
static bool32 HandleEndTurnFormChangeAbilities(u32 battler)
static bool32 HandleEndTurnFormChange(enum BattlerId battler)
{
bool32 effect = FALSE;
@ -1320,29 +1319,30 @@ static bool32 HandleEndTurnFormChangeAbilities(u32 battler)
gBattleStruct->eventState.endTurnBattler++;
switch (ability)
if (TryBattleFormChange(battler, FORM_CHANGE_BATTLE_TURN_END, ability)
|| TryBattleFormChange(battler, FORM_CHANGE_BATTLE_HP_PERCENT_TURN_END, ability))
{
case ABILITY_POWER_CONSTRUCT:
case ABILITY_SCHOOLING:
case ABILITY_SHIELDS_DOWN:
case ABILITY_ZEN_MODE:
case ABILITY_HUNGER_SWITCH:
if (AbilityBattleEffects(ABILITYEFFECT_ENDTURN, battler, ability, MOVE_NONE, TRUE))
effect = TRUE;
default:
break;
gBattleScripting.battler = battler;
gBattleScripting.abilityPopupOverwrite = ability; // To prevent the new form's ability from pop up
if (ability == ABILITY_POWER_CONSTRUCT) // Special animation
BattleScriptExecute(BattleScript_PowerConstruct);
else if (ability == ABILITY_HUNGER_SWITCH)
BattleScriptExecute(BattleScript_BattlerFormChangeEnd3NoPopup);
else
BattleScriptExecute(BattleScript_BattlerFormChangeEnd2); // Generic animation
effect = TRUE;
}
return effect;
}
static bool32 HandleEndTurnEjectPack(u32 battler)
static bool32 HandleEndTurnEjectPack(enum BattlerId battler)
{
gBattleStruct->eventState.endTurn++;
return TrySwitchInEjectPack(END_TURN);
}
static bool32 HandleEndTurnDynamax(u32 battler)
static bool32 HandleEndTurnDynamax(enum BattlerId battler)
{
bool32 effect = FALSE;
@ -1359,7 +1359,7 @@ static bool32 HandleEndTurnDynamax(u32 battler)
return effect;
}
static bool32 TryEndTurnTrainerSlide(u32 battler)
static bool32 TryEndTurnTrainerSlide(enum BattlerId battler)
{
return ((ShouldDoTrainerSlide(battler, TRAINER_SLIDE_LAST_LOW_HP) != TRAINER_SLIDE_TARGET_NONE)
|| (ShouldDoTrainerSlide(battler, TRAINER_SLIDE_LAST_HALF_HP) != TRAINER_SLIDE_TARGET_NONE)
@ -1370,7 +1370,7 @@ static bool32 TryEndTurnTrainerSlide(u32 battler)
|| (ShouldDoTrainerSlide(battler, TRAINER_SLIDE_ENEMY_MON_UNAFFECTED) != TRAINER_SLIDE_TARGET_NONE));
}
static bool32 HandleEndTurnTrainerASlides(u32 battler)
static bool32 HandleEndTurnTrainerASlides(enum BattlerId battler)
{
gBattleStruct->eventState.endTurnBattler++;
bool32 slide = TryEndTurnTrainerSlide(B_BATTLER_1);
@ -1379,7 +1379,7 @@ static bool32 HandleEndTurnTrainerASlides(u32 battler)
return slide;
}
static bool32 HandleEndTurnTrainerBSlides(u32 battler)
static bool32 HandleEndTurnTrainerBSlides(enum BattlerId battler)
{
gBattleStruct->eventState.endTurnBattler++;
@ -1401,7 +1401,7 @@ static bool32 HandleEndTurnTrainerBSlides(u32 battler)
return slide;
}
static bool32 HandleEndTurnTrainerPartnerSlides(u32 battler)
static bool32 HandleEndTurnTrainerPartnerSlides(enum BattlerId battler)
{
gBattleStruct->eventState.endTurnBattler++;
@ -1429,7 +1429,7 @@ static bool32 HandleEndTurnTrainerPartnerSlides(u32 battler)
some commands
end2
*/
static bool32 (*const sEndTurnEffectHandlers[])(u32 battler) =
static bool32 (*const sEndTurnEffectHandlers[])(enum BattlerId battler) =
{
[ENDTURN_ORDER] = HandleEndTurnOrder,
[ENDTURN_VARIOUS] = HandleEndTurnVarious,
@ -1475,7 +1475,7 @@ static bool32 (*const sEndTurnEffectHandlers[])(u32 battler) =
[ENDTURN_TERRAIN] = HandleEndTurnTerrain,
[ENDTURN_THIRD_EVENT_BLOCK] = HandleEndTurnThirdEventBlock,
[ENDTURN_EMERGENCY_EXIT_4] = HandleEndTurnEmergencyExit,
[ENDTURN_FORM_CHANGE_ABILITIES] = HandleEndTurnFormChangeAbilities,
[ENDTURN_FORM_CHANGE] = HandleEndTurnFormChange,
[ENDTURN_EJECT_PACK] = HandleEndTurnEjectPack,
[ENDTURN_DYNAMAX] = HandleEndTurnDynamax,
[ENDTURN_TRAINER_A_SLIDES] = HandleEndTurnTrainerASlides,

View File

@ -71,15 +71,6 @@ static void Task_StartBattleAfterTransition(u8 taskId)
}
}
// placeholders
#define B_TRANSITION_GROUP_B_PALACE B_TRANSITION_BLUR
#define B_TRANSITION_GROUP_B_TOWER B_TRANSITION_BLUR
#define B_TRANSITION_GROUP_B_DOME B_TRANSITION_BLUR
#define B_TRANSITION_GROUP_B_ARENA B_TRANSITION_BLUR
#define B_TRANSITION_GROUP_B_FACTORY B_TRANSITION_BLUR
#define B_TRANSITION_GROUP_B_PIKE B_TRANSITION_BLUR
#define B_TRANSITION_GROUP_B_PYRAMID B_TRANSITION_BLUR
static void DoFacilityTrainerBattleInternal(u8 facility)
{
gBattleScripting.specialTrainerBattleType = facility;

View File

@ -26,13 +26,13 @@
#include "trainer_pokemon_sprites.h"
#include "constants/songs.h"
#include "constants/rgb.h"
// #include "constants/battle_palace.h"
#include "constants/battle_palace.h"
#include "constants/battle_move_effects.h"
#include "constants/event_objects.h" // only for SHADOW_SIZE constants
// this file's functions
// static u8 GetBattlePalaceMoveGroup(u8 battler, u16 move);
// static u16 GetBattlePalaceTarget(u32 battler);
static u8 GetBattlePalaceMoveGroup(enum BattlerId battler, enum Move move);
static u16 GetBattlePalaceTarget(enum BattlerId battler);
static void SpriteCB_TrainerSlideVertical(struct Sprite *sprite);
static bool8 ShouldAnimBeDoneRegardlessOfSubstitute(u8 animId);
static void Task_ClearBitWhenBattleTableAnimDone(u8 taskId);
@ -187,6 +187,254 @@ void FreeBattleSpritesData(void)
FREE_AND_SET_NULL(gBattleSpritesDataPtr);
}
// Pokémon chooses move to use in Battle Palace rather than player
u16 ChooseMoveAndTargetInBattlePalace(enum BattlerId battler)
{
s32 i, var1, var2;
s32 chosenMoveIndex = -1;
struct ChooseMoveStruct *moveInfo = (struct ChooseMoveStruct *)(&gBattleResources->bufferA[battler][4]);
u8 unusableMovesBits = CheckMoveLimitations(battler, 0, MOVE_LIMITATIONS_ALL);
s32 percent = Random() % 100;
// Heavy variable re-use here makes this hard to read without defines
// Possibly just optimization? might still match with additional vars
#define maxGroupNum var1
#define minGroupNum var2
#define selectedGroup percent
#define selectedMoves var2
#define numMovesPerGroup var1
#define numMultipleMoveGroups var2
#define randSelectGroup var2
// If battler is < 50% HP and not asleep, use second set of move group likelihoods
// otherwise use first set
i = (gBattleStruct->palaceFlags & (1u << battler)) ? 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 (gNaturesInfo[GetNatureFromPersonality(gBattleMons[battler].personality)].battlePalacePercents[i] > percent)
break;
}
selectedGroup = i - minGroupNum;
if (i == maxGroupNum)
selectedGroup = PALACE_MOVE_GROUP_SUPPORT;
// Flag moves that match selected group, to be passed to AI
for (selectedMoves = 0, i = 0; i < MAX_MON_MOVES; i++)
{
if (moveInfo->moves[i] == MOVE_NONE)
break;
if (selectedGroup == GetBattlePalaceMoveGroup(battler, moveInfo->moves[i]) && moveInfo->currentPp[i] != 0)
selectedMoves |= 1u << i;
}
// Pass selected moves to AI, pick one
if (selectedMoves != 0)
{
// Lower 4 bits of palaceFlags are flags for each battler.
// Clear the rest of palaceFlags, then set the selected moves in the upper 4 bits.
gBattleStruct->palaceFlags &= (1 << MAX_BATTLERS_COUNT) - 1;
gBattleStruct->palaceFlags |= (selectedMoves << MAX_BATTLERS_COUNT);
BattleAI_SetupAIData(selectedMoves, battler);
chosenMoveIndex = BattleAI_ChooseMoveIndex(battler);
}
// If no moves matched the selected group, pick a new move from groups the Pokémon 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 (chosenMoveIndex == -1 || chosenMoveIndex >= MAX_MON_MOVES)
{
chosenMoveIndex = -1;
if (unusableMovesBits != ALL_MOVES_MASK)
{
numMovesPerGroup = 0, numMultipleMoveGroups = 0;
for (i = 0; i < MAX_MON_MOVES; i++)
{
// Count the number of usable moves the battler has in each move group.
// The totals will be stored separately in 3 groups of 4 bits each in numMovesPerGroup.
if (GetBattlePalaceMoveGroup(battler, moveInfo->moves[i]) == PALACE_MOVE_GROUP_ATTACK && !((1u << i) & unusableMovesBits))
numMovesPerGroup += (1 << 0);
if (GetBattlePalaceMoveGroup(battler, moveInfo->moves[i]) == PALACE_MOVE_GROUP_DEFENSE && !((1u << i) & unusableMovesBits))
numMovesPerGroup += (1 << 4);
if (GetBattlePalaceMoveGroup(battler, moveInfo->moves[i]) == PALACE_MOVE_GROUP_SUPPORT && !((1u << i) & unusableMovesBits))
numMovesPerGroup += (1 << 8);
}
// Count the number of move groups for which the battler has at least 2 usable moves.
// This is a roundabout way to determine if there is a move group that should be
// preferred, because it has multiple move options and the others do not.
// The condition intended to check the total for the Support group is accidentally
// checking the Defense total, and is never true. As a result the preferences for
// random move selection here will skew away from the Support move group.
if ((numMovesPerGroup & 0xF) >= 2)
numMultipleMoveGroups++;
if ((numMovesPerGroup & (0xF << 4)) >= (2 << 4))
numMultipleMoveGroups++;
#ifdef BUGFIX
if ((numMovesPerGroup & (0xF << 8)) >= (2 << 8))
#else
if ((numMovesPerGroup & (0xF << 4)) >= (2 << 8))
#endif
numMultipleMoveGroups++;
// By this point we already know the battler only has usable moves from at most 2 of the 3 move groups,
// because they had no usable moves from the move group that was selected based on Nature.
//
// The below condition is effectively 'numMultipleMoveGroups != 1'.
// There is no stand-out group with multiple moves to choose from, so we pick randomly.
// Note that because of the bug above the battler may actually have any number of Support moves.
if (numMultipleMoveGroups > 1 || numMultipleMoveGroups == 0)
{
do
{
i = Random() % MAX_MON_MOVES;
if (!((1u << i) & unusableMovesBits))
chosenMoveIndex = i;
} while (chosenMoveIndex == -1);
}
else
{
// The battler has just 1 move group with multiple move options to choose from.
// Choose a move randomly from this group.
// Same bug as the previous set of conditions (the condition for Support is never true).
// This bug won't cause a softlock below, because if Support is the only group with multiple
// moves then it won't have been counted, and the 'numMultipleMoveGroups == 0' above will be true.
if ((numMovesPerGroup & 0xF) >= 2)
randSelectGroup = PALACE_MOVE_GROUP_ATTACK;
if ((numMovesPerGroup & (0xF << 4)) >= (2 << 4))
randSelectGroup = PALACE_MOVE_GROUP_DEFENSE;
#ifdef BUGFIX
if ((numMovesPerGroup & (0xF << 8)) >= (2 << 8))
#else
if ((numMovesPerGroup & (0xF << 4)) >= (2 << 8))
#endif
randSelectGroup = PALACE_MOVE_GROUP_SUPPORT;
do
{
i = Random() % MAX_MON_MOVES;
if (!((1u << i) & unusableMovesBits) && randSelectGroup == GetBattlePalaceMoveGroup(battler, moveInfo->moves[i]))
chosenMoveIndex = i;
} while (chosenMoveIndex == -1);
}
// Because the selected move was not from the Nature-chosen move group there's a 50% chance
// that it will be unable to use it. This could have been checked earlier to avoid the above work.
if (Random() % 100 >= 50)
{
gProtectStructs[battler].palaceUnableToUseMove = TRUE;
return 0;
}
}
else
{
// All the battler's moves were flagged as unusable.
gProtectStructs[battler].palaceUnableToUseMove = TRUE;
return 0;
}
}
enum MoveTarget moveTarget = GetBattlerMoveTargetType(battler, moveInfo->moves[chosenMoveIndex]);
if (moveTarget == TARGET_USER || moveTarget == TARGET_USER_OR_ALLY || moveTarget == TARGET_USER_AND_ALLY)
chosenMoveIndex |= (battler << 8);
else if (moveTarget == TARGET_SELECTED || moveTarget == TARGET_SMART)
chosenMoveIndex |= GetBattlePalaceTarget(battler);
else
chosenMoveIndex |= (GetBattlerAtPosition(BATTLE_OPPOSITE(GetBattlerSide(battler))) << 8);
return chosenMoveIndex;
}
#undef maxGroupNum
#undef minGroupNum
#undef selectedGroup
#undef selectedMoves
#undef moveTarget
#undef numMovesPerGroup
#undef numMultipleMoveGroups
#undef randSelectGroup
static u8 GetBattlePalaceMoveGroup(enum BattlerId battler, enum Move move)
{
switch (GetBattlerMoveTargetType(battler, move))
{
case TARGET_SELECTED:
case TARGET_USER_AND_ALLY:
case TARGET_SMART:
case TARGET_OPPONENT:
case TARGET_RANDOM:
case TARGET_BOTH:
case TARGET_FOES_AND_ALLY:
case TARGET_ALL_BATTLERS:
case TARGET_FIELD:
if (IsBattleMoveStatus(move))
return PALACE_MOVE_GROUP_SUPPORT;
else
return PALACE_MOVE_GROUP_ATTACK;
break;
case TARGET_DEPENDS:
case TARGET_OPPONENTS_FIELD:
case TARGET_ALLY:
case TARGET_USER_OR_ALLY:
return PALACE_MOVE_GROUP_SUPPORT;
case TARGET_USER:
return PALACE_MOVE_GROUP_DEFENSE;
default:
return PALACE_MOVE_GROUP_ATTACK;
}
}
static u16 GetBattlePalaceTarget(enum BattlerId battler)
{
if (IsDoubleBattle())
{
enum BattlerId opposing1, opposing2;
if (IsOnPlayerSide(battler))
{
opposing1 = GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT);
opposing2 = GetBattlerAtPosition(B_POSITION_OPPONENT_RIGHT);
}
else
{
opposing1 = GetBattlerAtPosition(B_POSITION_PLAYER_LEFT);
opposing2 = GetBattlerAtPosition(B_POSITION_PLAYER_RIGHT);
}
if (gBattleMons[opposing1].hp == gBattleMons[opposing2].hp)
return (BATTLE_OPPOSITE(battler & BIT_SIDE) + (Random() & 2)) << 8;
switch (gNaturesInfo[GetNatureFromPersonality(gBattleMons[battler].personality)].battlePalaceSmokescreen)
{
case PALACE_TARGET_STRONGER:
if (gBattleMons[opposing1].hp > gBattleMons[opposing2].hp)
return opposing1 << 8;
else
return opposing2 << 8;
case PALACE_TARGET_WEAKER:
if (gBattleMons[opposing1].hp < gBattleMons[opposing2].hp)
return opposing1 << 8;
else
return opposing2 << 8;
case PALACE_TARGET_RANDOM:
return (BATTLE_OPPOSITE(battler & BIT_SIDE) + (Random() & 2)) << 8;
}
}
return BATTLE_OPPOSITE(battler) << 8;
}
// Wait for the Pokémon to finish appearing out from the Poké Ball on send out
void SpriteCB_WaitForBattlerBallReleaseAnim(struct Sprite *sprite)
{
@ -719,7 +967,7 @@ void CopyBattleSpriteInvisibility(u8 battler)
gBattleSpritesDataPtr->battlerData[battler].invisible = gSprites[gBattlerSpriteIds[battler]].invisible;
}
void HandleSpeciesGfxDataChange(u8 battlerAtk, u8 battlerDef, bool32 megaEvo, bool32 trackEnemyPersonality, bool32 ghostUnveil)
void HandleSpeciesGfxDataChange(enum BattlerId battlerAtk, enum BattlerId battlerDef, u8 changeType)
{
u32 personalityValue, position, paletteOffset, targetSpecies;
bool32 isShiny;
@ -744,7 +992,7 @@ void HandleSpeciesGfxDataChange(u8 battlerAtk, u8 battlerDef, bool32 megaEvo, bo
else
{
position = GetBattlerPosition(battlerAtk);
if (gBattleSpritesDataPtr->battlerData[battlerAtk].transformSpecies == SPECIES_NONE)
if (changeType == SPECIES_GFX_CHANGE_TRANSFORM)
{
// Get base form if its currently Gigantamax
if (IsGigantamaxed(battlerDef))
@ -753,24 +1001,23 @@ void HandleSpeciesGfxDataChange(u8 battlerAtk, u8 battlerDef, bool32 megaEvo, bo
targetSpecies = GetIllusionMonSpecies(battlerDef);
else
targetSpecies = GetMonData(monDef, MON_DATA_SPECIES);
personalityValue = GetMonData(monAtk, MON_DATA_PERSONALITY);
isShiny = GetMonData(monAtk, MON_DATA_IS_SHINY);
}
else
{
targetSpecies = gBattleSpritesDataPtr->battlerData[battlerAtk].transformSpecies;
if (B_TRANSFORM_SHINY >= GEN_4 && trackEnemyPersonality && !megaEvo)
{
personalityValue = GetMonData(monDef, MON_DATA_PERSONALITY);
isShiny = GetMonData(monDef, MON_DATA_IS_SHINY);
}
else
{
personalityValue = GetMonData(monAtk, MON_DATA_PERSONALITY);
isShiny = GetMonData(monAtk, MON_DATA_IS_SHINY);
}
targetSpecies = GetMonData(monAtk, MON_DATA_SPECIES);
}
gBattleSpritesDataPtr->battlerData[battlerAtk].transformSpecies = targetSpecies;
if (changeType == SPECIES_GFX_CHANGE_TRANSFORM)
{
personalityValue = gTransformedPersonalities[battlerAtk];
isShiny = gTransformedShininess[battlerAtk];
}
else
{
personalityValue = GetMonData(monAtk, MON_DATA_PERSONALITY);
isShiny = GetMonData(monAtk, MON_DATA_IS_SHINY);
}
HandleLoadSpecialPokePic(!IsOnPlayerSide(battlerAtk),
gMonSpritesGfxPtr->spritesGfx[position],
targetSpecies,
@ -783,20 +1030,16 @@ void HandleSpeciesGfxDataChange(u8 battlerAtk, u8 battlerDef, bool32 megaEvo, bo
paletteData = GetMonSpritePalFromSpeciesAndPersonality(targetSpecies, isShiny, personalityValue);
LoadPalette(paletteData, paletteOffset, PLTT_SIZE_4BPP);
if (ghostUnveil)
if (changeType == SPECIES_GFX_CHANGE_GHOST_UNVEIL)
{
SetMonData(&gEnemyParty[gBattlerPartyIndexes[battlerAtk]], MON_DATA_NICKNAME, gSpeciesInfo[targetSpecies].speciesName);
UpdateNickInHealthbox(gHealthboxSpriteIds[battlerAtk], &gEnemyParty[gBattlerPartyIndexes[battlerAtk]]);
TryAddPokeballIconToHealthbox(gHealthboxSpriteIds[battlerAtk], 1);
TryAddPokeballIconToHealthbox(gHealthboxSpriteIds[battlerAtk], TRUE);
}
else if (!megaEvo)
else if (changeType == SPECIES_GFX_CHANGE_TRANSFORM)
{
BlendPalette(paletteOffset, 16, 6, RGB_WHITE);
CpuCopy32(&gPlttBufferFaded[paletteOffset], &gPlttBufferUnfaded[paletteOffset], PLTT_SIZEOF(16));
if (!IsContest())
{
gBattleSpritesDataPtr->battlerData[battlerAtk].transformSpecies = targetSpecies;
}
}
// dynamax tint
@ -810,6 +1053,13 @@ void HandleSpeciesGfxDataChange(u8 battlerAtk, u8 battlerDef, bool32 megaEvo, bo
CpuCopy32(gPlttBufferFaded + paletteOffset, gPlttBufferUnfaded + paletteOffset, PLTT_SIZEOF(16));
}
// Terastallization's tint
if (changeType != SPECIES_GFX_CHANGE_ILLUSION_OFF && GetActiveGimmick(battlerAtk) == GIMMICK_TERA)
{
BlendPalette(paletteOffset, 16, 8, GetTeraTypeRGB(GetBattlerTeraType(battlerAtk)));
CpuCopy32(gPlttBufferFaded + paletteOffset, gPlttBufferUnfaded + paletteOffset, PLTT_SIZEOF(16));
}
gSprites[gBattlerSpriteIds[battlerAtk]].y = GetBattlerSpriteDefault_Y(battlerAtk);
StartSpriteAnim(&gSprites[gBattlerSpriteIds[battlerAtk]], 0);
}

View File

@ -19,11 +19,10 @@
// Populates gBattleStruct->gimmick.usableGimmick for each battler.
void AssignUsableGimmicks(void)
{
u32 battler, gimmick;
for (battler = 0; battler < gBattlersCount; ++battler)
for (enum BattlerId battler = 0; battler < gBattlersCount; ++battler)
{
gBattleStruct->gimmick.usableGimmick[battler] = GIMMICK_NONE;
for (gimmick = 0; gimmick < GIMMICKS_COUNT; ++gimmick)
for (enum Gimmick gimmick = 0; gimmick < GIMMICKS_COUNT; ++gimmick)
{
if (CanActivateGimmick(battler, gimmick))
{
@ -35,44 +34,43 @@ void AssignUsableGimmicks(void)
}
// Returns whether a battler is able to use a gimmick. Checks consumption and gimmick specific functions.
bool32 CanActivateGimmick(u32 battler, enum Gimmick gimmick)
bool32 CanActivateGimmick(enum BattlerId battler, enum Gimmick gimmick)
{
return gGimmicksInfo[gimmick].CanActivate != NULL && gGimmicksInfo[gimmick].CanActivate(battler);
}
// Returns whether the player has a gimmick selected while in the move selection menu.
bool32 IsGimmickSelected(u32 battler, enum Gimmick gimmick)
bool32 IsGimmickSelected(enum BattlerId battler, enum Gimmick gimmick)
{
// There's no player select in tests, but some gimmicks need to test choice before they are fully activated.
if (TESTING)
return (gBattleStruct->gimmick.toActivate & (1u << battler)) && gBattleStruct->gimmick.usableGimmick[battler] == gimmick;
else
return gBattleStruct->gimmick.usableGimmick[battler] == gimmick && gBattleStruct->gimmick.playerSelect;
#if TESTING
return (gBattleStruct->gimmick.toActivate & (1u << battler)) && gBattleStruct->gimmick.usableGimmick[battler] == gimmick;
#else
return gBattleStruct->gimmick.usableGimmick[battler] == gimmick && gBattleStruct->gimmick.playerSelect;
#endif
}
// Sets a battler as having a gimmick active using their party index.
void SetActiveGimmick(u32 battler, enum Gimmick gimmick)
void SetActiveGimmick(enum BattlerId battler, enum Gimmick gimmick)
{
gBattleStruct->gimmick.activeGimmick[GetBattlerSide(battler)][gBattlerPartyIndexes[battler]] = gimmick;
}
// Returns a battler's active gimmick, if any.
enum Gimmick GetActiveGimmick(u32 battler)
enum Gimmick GetActiveGimmick(enum BattlerId battler)
{
return gBattleStruct->gimmick.activeGimmick[GetBattlerSide(battler)][gBattlerPartyIndexes[battler]];
}
// Returns whether a trainer mon is intended to use an unrestrictive gimmick via .useGimmick (i.e Tera).
bool32 ShouldTrainerBattlerUseGimmick(u32 battler, enum Gimmick gimmick)
bool32 ShouldTrainerBattlerUseGimmick(enum BattlerId battler, enum Gimmick gimmick)
{
// There are no trainer party settings in battles, but the AI needs to know which gimmick to use.
if (TESTING)
{
return gimmick == TestRunner_Battle_GetChosenGimmick(GetBattlerTrainer(battler), gBattlerPartyIndexes[battler]);
}
#if TESTING
return gimmick == TestRunner_Battle_GetChosenGimmick(GetBattlerTrainer(battler), gBattlerPartyIndexes[battler]);
#else
// The player can bypass these checks because they can choose through the controller.
else if (IsOnPlayerSide(battler)
&& !((gBattleTypeFlags & BATTLE_TYPE_MULTI) && battler == B_POSITION_PLAYER_RIGHT))
if (IsOnPlayerSide(battler) && !((gBattleTypeFlags & BATTLE_TYPE_MULTI) && GetBattlerPosition(battler) == B_POSITION_PLAYER_RIGHT))
{
return TRUE;
}
@ -84,16 +82,17 @@ bool32 ShouldTrainerBattlerUseGimmick(u32 battler, enum Gimmick gimmick)
if (gimmick == GIMMICK_DYNAMAX && gBattleStruct->opponentMonCanDynamax & 1 << gBattlerPartyIndexes[battler])
return TRUE;
}
#endif
return FALSE;
}
// Returns whether a trainer has used a gimmick during a battle.
bool32 HasTrainerUsedGimmick(u32 battler, enum Gimmick gimmick)
bool32 HasTrainerUsedGimmick(enum BattlerId battler, enum Gimmick gimmick)
{
if (IsDoubleBattle() && (IsPartnerMonFromSameTrainer(battler) || (gimmick == GIMMICK_DYNAMAX)))
{
u32 partner = BATTLE_PARTNER(battler);
enum BattlerId partner = BATTLE_PARTNER(battler);
if (gBattleStruct->gimmick.activated[partner][gimmick]
|| ((gBattleStruct->gimmick.toActivate & (1u << partner)) && gBattleStruct->gimmick.usableGimmick[partner] == gimmick))
return TRUE;
@ -103,7 +102,7 @@ bool32 HasTrainerUsedGimmick(u32 battler, enum Gimmick gimmick)
}
// Sets a gimmick as used by a trainer with checks for Multi Battles.
void SetGimmickAsActivated(u32 battler, enum Gimmick gimmick)
void SetGimmickAsActivated(enum BattlerId battler, enum Gimmick gimmick)
{
gBattleStruct->gimmick.activated[battler][gimmick] = TRUE;
if (IsDoubleBattle() && (IsPartnerMonFromSameTrainer(battler) || (gimmick == GIMMICK_DYNAMAX)))
@ -128,7 +127,7 @@ void ChangeGimmickTriggerSprite(u32 spriteId, u32 animId)
StartSpriteAnim(&gSprites[spriteId], animId);
}
void CreateGimmickTriggerSprite(u32 battler)
void CreateGimmickTriggerSprite(enum BattlerId battler)
{
const struct GimmickInfo * gimmick = &gGimmicksInfo[gBattleStruct->gimmick.usableGimmick[battler]];
@ -173,7 +172,7 @@ bool32 IsGimmickTriggerSpriteActive(void)
return FALSE;
}
bool32 IsGimmickTriggerSpriteMatchingBattler(u32 battler)
bool32 IsGimmickTriggerSpriteMatchingBattler(enum BattlerId battler)
{
if (battler == gSprites[gBattleStruct->gimmick.triggerSpriteId].tBattler)
return TRUE;
@ -274,7 +273,7 @@ void LoadIndicatorSpritesGfx(void)
static void SpriteCb_GimmickIndicator(struct Sprite *sprite)
{
u32 battler = sprite->tBattler;
enum BattlerId battler = sprite->tBattler;
sprite->x = gSprites[gHealthboxSpriteIds[battler]].x + sprite->tPosX + sprite->tLevelXDelta;
sprite->x2 = gSprites[gHealthboxSpriteIds[battler]].x2;
@ -286,7 +285,7 @@ static inline u32 GetIndicatorSpriteId(u32 healthboxId)
return gBattleStruct->gimmick.indicatorSpriteId[gSprites[healthboxId].hMain_Battler];
}
const u32 *GetIndicatorSpriteSrc(u32 battler)
const u32 *GetIndicatorSpriteSrc(enum BattlerId battler)
{
u32 gimmick = GetActiveGimmick(battler);
@ -311,7 +310,7 @@ const u32 *GetIndicatorSpriteSrc(u32 battler)
}
}
u32 GetIndicatorPalTag(u32 battler)
u32 GetIndicatorPalTag(enum BattlerId battler)
{
u32 gimmick = GetActiveGimmick(battler);
if (IsBattlerPrimalReverted(battler))
@ -326,7 +325,7 @@ u32 GetIndicatorPalTag(u32 battler)
void UpdateIndicatorVisibilityAndType(u32 healthboxId, bool32 invisible)
{
u32 battler = gSprites[healthboxId].hMain_Battler;
enum BattlerId battler = gSprites[healthboxId].hMain_Battler;
u32 palTag = GetIndicatorPalTag(battler);
struct Sprite *sprite = &gSprites[GetIndicatorSpriteId(healthboxId)];
@ -378,7 +377,7 @@ static const s8 sIndicatorPositions[][2] =
[B_POSITION_OPPONENT_RIGHT] = {40, -9},
};
void CreateIndicatorSprite(u32 battler)
void CreateIndicatorSprite(enum BattlerId battler)
{
enum BattlerPosition position;
u32 spriteId;

View File

@ -1179,50 +1179,43 @@ void SwapHpBarsWithHpText(void)
#define sSpeed data[3]
#define sIsEmptyBall data[7]
u8 CreatePartyStatusSummarySprites(u8 battlerId, struct HpAndStatus *partyInfo, bool8 isSwitchingMons, bool8 isBattleStart)
u8 CreatePartyStatusSummarySprites(enum BattlerId battler, struct HpAndStatus *partyInfo, bool8 skipPlayer, bool8 isBattleStart)
{
bool8 isOpponent;
s8 nValidMons;
s16 x, y, x2, speed;
s32 i;
s16 bar_X, bar_Y, bar_pos2_X, bar_data0;
s32 i, j, var;
u8 summaryBarSpriteId;
u8 ballIconSpritesIds[PARTY_SIZE];
u8 taskId;
if (!isSwitchingMons || GetBattlerPosition(battlerId) != B_POSITION_OPPONENT_RIGHT)
if (!skipPlayer || GetBattlerPosition(battler) != B_POSITION_OPPONENT_RIGHT)
{
if (GetBattlerSide(battlerId) == B_SIDE_PLAYER)
if (IsOnPlayerSide(battler))
{
isOpponent = FALSE;
x = 136, y = 96;
x2 = 100;
speed = -5;
bar_X = 136, bar_Y = 96;
bar_pos2_X = 100;
bar_data0 = -5;
}
else
{
isOpponent = TRUE;
if (!isSwitchingMons || !GetBattlerCoordsIndex(battlerId))
x = 104, y = 40;
if (!skipPlayer || GetBattlerCoordsIndex(battler) == BATTLE_COORDS_SINGLES)
bar_X = 104, bar_Y = 40;
else
x = 104, y = 16;
bar_X = 104, bar_Y = 16;
x2 = -100;
speed = 5;
bar_pos2_X = -100;
bar_data0 = 5;
}
}
else
{
isOpponent = TRUE;
x = 104, y = 40;
x2 = -100;
speed = 5;
}
for (i = 0, nValidMons = 0; i < PARTY_SIZE; i++)
{
if (partyInfo[i].hp != HP_EMPTY_SLOT)
nValidMons++;
bar_X = 104, bar_Y = 40;
bar_pos2_X = -100;
bar_data0 = 5;
}
LoadCompressedSpriteSheetUsingHeap(&sStatusSummaryBarSpriteSheet);
@ -1230,10 +1223,10 @@ u8 CreatePartyStatusSummarySprites(u8 battlerId, struct HpAndStatus *partyInfo,
LoadSpritePalette(&sPartySummaryBarSpritePals);
LoadSpritePalette(&sPartySummaryBallSpritePals);
summaryBarSpriteId = CreateSprite(&sPartySummaryBarSpriteTemplates[isOpponent], x, y, 10);
summaryBarSpriteId = CreateSprite(&sPartySummaryBarSpriteTemplates[isOpponent], bar_X, bar_Y, 10);
SetSubspriteTables(&gSprites[summaryBarSpriteId], sStatusSummaryBar_SubspriteTable_Enter);
gSprites[summaryBarSpriteId].x2 = x2;
gSprites[summaryBarSpriteId].sEnterSpeed = speed;
gSprites[summaryBarSpriteId].x2 = bar_pos2_X;
gSprites[summaryBarSpriteId].sEnterSpeed = bar_data0;
if (isOpponent)
{
@ -1241,11 +1234,13 @@ u8 CreatePartyStatusSummarySprites(u8 battlerId, struct HpAndStatus *partyInfo,
gSprites[summaryBarSpriteId].oam.matrixNum = ST_OAM_HFLIP;
}
else
{
gSprites[summaryBarSpriteId].x += 96;
}
for (i = 0; i < PARTY_SIZE; i++)
{
ballIconSpritesIds[i] = CreateSpriteAtEnd(&sPartySummaryBallSpriteTemplates[isOpponent], x, y - 4, 9);
ballIconSpritesIds[i] = CreateSpriteAtEnd(&sPartySummaryBallSpriteTemplates[isOpponent], bar_X, bar_Y - 4, 9);
if (!isBattleStart)
gSprites[ballIconSpritesIds[i]].callback = SpriteCB_PartySummaryBall_OnSwitchout;
@ -1274,81 +1269,132 @@ u8 CreatePartyStatusSummarySprites(u8 battlerId, struct HpAndStatus *partyInfo,
gSprites[ballIconSpritesIds[i]].sIsOpponent = isOpponent;
}
if (GetBattlerSide(battlerId) == B_SIDE_PLAYER)
if (IsOnPlayerSide(battler))
{
for (i = 0; i < PARTY_SIZE; i++)
if (gBattleTypeFlags & BATTLE_TYPE_MULTI)
{
if (gBattleTypeFlags & BATTLE_TYPE_MULTI)
for (i = 0; i < PARTY_SIZE; i++)
{
if (partyInfo[i].hp == HP_EMPTY_SLOT)
{
// empty slot or an egg
gSprites[ballIconSpritesIds[i]].oam.tileNum += 1;
gSprites[ballIconSpritesIds[i]].sIsEmptyBall = TRUE;
}
else if (partyInfo[i].hp == 0)
gSprites[ballIconSpritesIds[i]].oam.tileNum += 3;
else if (partyInfo[i].status != STATUS1_NONE)
gSprites[ballIconSpritesIds[i]].oam.tileNum += 2;
}
else
{
if (i >= nValidMons)
{
gSprites[ballIconSpritesIds[i]].oam.tileNum += 1;
gSprites[ballIconSpritesIds[i]].sIsEmptyBall = TRUE;
}
else if (partyInfo[i].hp == 0)
// fainted mon
gSprites[ballIconSpritesIds[i]].oam.tileNum += 3;
}
else if (partyInfo[i].status != STATUS1_NONE)
{
// mon with major status
gSprites[ballIconSpritesIds[i]].oam.tileNum += 2;
}
}
}
else
{
for (i = 0, var = PARTY_SIZE - 1, j = 0; j < PARTY_SIZE; j++)
{
if (partyInfo[j].hp == HP_EMPTY_SLOT)
{
// empty slot or an egg
gSprites[ballIconSpritesIds[var]].oam.tileNum += 1;
gSprites[ballIconSpritesIds[var]].sIsEmptyBall = TRUE;
var--;
continue;
}
else if (partyInfo[j].hp == 0)
{
// fainted mon
gSprites[ballIconSpritesIds[i]].oam.tileNum += 3;
}
else if (gBattleTypeFlags & BATTLE_TYPE_ARENA && gBattleStruct->arenaLostPlayerMons & (1u << j))
{
// fainted arena mon
gSprites[ballIconSpritesIds[i]].oam.tileNum += 3;
}
else if (partyInfo[j].status != STATUS1_NONE)
{
// mon with primary status
gSprites[ballIconSpritesIds[i]].oam.tileNum += 2;
}
i++;
}
}
}
else
{
for (i = 0; i < PARTY_SIZE; i++)
if (gBattleTypeFlags & (BATTLE_TYPE_MULTI | BATTLE_TYPE_TWO_OPPONENTS))
{
if (gBattleTypeFlags & BATTLE_TYPE_MULTI)
for (var = PARTY_SIZE - 1, i = 0; i < PARTY_SIZE; i++)
{
if (partyInfo[i].hp == HP_EMPTY_SLOT)
{
gSprites[ballIconSpritesIds[5 - i]].oam.tileNum += 1;
gSprites[ballIconSpritesIds[5 - i]].sIsEmptyBall = TRUE;
// empty slot or an egg
gSprites[ballIconSpritesIds[var]].oam.tileNum += 1;
gSprites[ballIconSpritesIds[var]].sIsEmptyBall = TRUE;
}
else if (partyInfo[i].hp == 0)
gSprites[ballIconSpritesIds[5 - i]].oam.tileNum += 3;
{
// fainted mon
gSprites[ballIconSpritesIds[var]].oam.tileNum += 3;
}
else if (partyInfo[i].status != STATUS1_NONE)
gSprites[ballIconSpritesIds[5 - i]].oam.tileNum += 2;
{
// mon with primary status
gSprites[ballIconSpritesIds[var]].oam.tileNum += 2;
}
var--;
}
else
}
else
{
for (var = 0, i = 0, j = 0; j < PARTY_SIZE; j++)
{
ballIconSpritesIds[5 - i] += 0;
if (i >= nValidMons)
if (partyInfo[j].hp == HP_EMPTY_SLOT)
{
gSprites[ballIconSpritesIds[5 - i]].oam.tileNum += 1;
gSprites[ballIconSpritesIds[5 - i]].sIsEmptyBall = TRUE;
// empty slot or an egg
gSprites[ballIconSpritesIds[i]].oam.tileNum += 1;
gSprites[ballIconSpritesIds[i]].sIsEmptyBall = TRUE;
i++;
continue;
}
else if (partyInfo[i].hp == 0)
gSprites[ballIconSpritesIds[5 - i]].oam.tileNum += 3;
else if (partyInfo[i].status != STATUS1_NONE)
else if (partyInfo[j].hp == 0)
{
do
{
gSprites[ballIconSpritesIds[5 - i]].oam.tileNum += 2;
} while (0);
// fainted mon
gSprites[ballIconSpritesIds[PARTY_SIZE - 1 - var]].oam.tileNum += 3;
}
else if (gBattleTypeFlags & BATTLE_TYPE_ARENA && gBattleStruct->arenaLostOpponentMons & (1u << j))
{
// fainted arena mon
gSprites[ballIconSpritesIds[PARTY_SIZE - 1 - var]].oam.tileNum += 3;
}
else if (partyInfo[j].status != STATUS1_NONE)
{
// mon with primary status
gSprites[ballIconSpritesIds[PARTY_SIZE - 1 - var]].oam.tileNum += 2;
}
var++;
}
}
}
taskId = CreateTask(TaskDummy, 5);
gTasks[taskId].tBattler = battlerId;
gTasks[taskId].tBattler = battler;
gTasks[taskId].tSummaryBarSpriteId = summaryBarSpriteId;
for (i = 0; i < PARTY_SIZE; i++)
gTasks[taskId].tBallIconSpriteId(i) = ballIconSpritesIds[i];
gTasks[taskId].tIsBattleStart = isBattleStart;
if (isBattleStart)
{
gBattleSpritesDataPtr->animationData->field_9_x1C++;
}
PlaySE12WithPanning(SE_BALL_TRAY_ENTER, 0);
return taskId;
}

View File

@ -12,6 +12,7 @@ static void BattleIntroSlide1(u8 taskId);
static void BattleIntroSlide2(u8 taskId);
static void BattleIntroSlide3(u8 taskId);
static void BattleIntroSlideLink(u8 taskId);
static void BattleIntroSlidePartner(u8);
static const u8 sBattleAnimBgCnts[] = {REG_OFFSET_BG0CNT, REG_OFFSET_BG1CNT, REG_OFFSET_BG2CNT, REG_OFFSET_BG3CNT};
@ -97,10 +98,17 @@ void HandleIntroSlide(u8 environment)
{
u8 taskId;
if (gBattleTypeFlags & BATTLE_TYPE_LINK)
if ((gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER) && gPartnerTrainerId < TRAINER_PARTNER(PARTNER_NONE))
{
taskId = CreateTask(BattleIntroSlidePartner, 0);
} else if (gBattleTypeFlags & BATTLE_TYPE_LINK)
{
taskId = CreateTask(BattleIntroSlideLink, 0);
}
else if (gBattleTypeFlags & BATTLE_TYPE_FRONTIER)
{
taskId = CreateTask(BattleIntroSlide3, 0);
}
else if ((gBattleTypeFlags & BATTLE_TYPE_LEGENDARY) && GetMonData(&gEnemyParty[0], MON_DATA_SPECIES, NULL) == SPECIES_KYOGRE)
{
environment = BATTLE_ENVIRONMENT_UNDERWATER;
@ -524,6 +532,76 @@ static void BattleIntroSlideLink(u8 taskId)
}
}
static void BattleIntroSlidePartner(u8 taskId)
{
switch (gTasks[taskId].tState)
{
case 0:
gTasks[taskId].data[2] = 1;
gTasks[taskId].tState++;
break;
case 1:
if (--gTasks[taskId].data[2] == 0)
{
gTasks[taskId].tState++;
SetGpuReg(REG_OFFSET_BG1CNT, BGCNT_PRIORITY(2) | BGCNT_CHARBASE(2) | BGCNT_16COLOR | BGCNT_SCREENBASE(28) | BGCNT_TXT512x256);
SetGpuReg(REG_OFFSET_BG2CNT, BGCNT_PRIORITY(2) | BGCNT_CHARBASE(2) | BGCNT_16COLOR | BGCNT_SCREENBASE(30) | BGCNT_TXT512x256);
SetGpuReg(REG_OFFSET_DISPCNT, GetGpuReg(REG_OFFSET_DISPCNT) | DISPCNT_OBJ_1D_MAP | DISPCNT_OBJ_ON | DISPCNT_WIN0_ON | DISPCNT_WIN1_ON | DISPCNT_OBJWIN_ON);
SetGpuReg(REG_OFFSET_WININ, WININ_WIN1_BG1 | WININ_WIN1_BG2 | WININ_WIN1_BG3 | WININ_WIN1_OBJ | WININ_WIN1_CLR);
SetGpuReg(REG_OFFSET_WINOUT, WINOUT_WIN01_BG_ALL | WINOUT_WIN01_OBJ | WINOUT_WIN01_CLR | WINOUT_WINOBJ_BG_ALL | WINOUT_WINOBJ_OBJ | WINOUT_WINOBJ_CLR);
gBattle_BG0_Y = -48;
gBattle_BG1_X = DISPLAY_WIDTH;
gBattle_BG2_X = -DISPLAY_WIDTH;
}
break;
case 2:
gBattle_WIN0V += 0x100;
if ((gBattle_WIN0V & 0xFF00) != 0x100)
gBattle_WIN0V--;
if ((gBattle_WIN0V & 0xFF00) == 0x2000)
{
gTasks[taskId].tState++;
gTasks[taskId].data[2] = DISPLAY_WIDTH;
gIntroSlideFlags &= ~1;
}
break;
case 3:
if ((gBattle_WIN0V & 0xFF00) != 0x4C00)
gBattle_WIN0V += 0x3FC;
if (gTasks[taskId].data[2])
gTasks[taskId].data[2] -= 2;
gBattle_BG1_X = gTasks[taskId].data[2];
gBattle_BG2_X = -gTasks[taskId].data[2];
if (gTasks[taskId].data[2] == 0)
gTasks[taskId].tState++;
break;
case 4:
gBattle_BG0_Y += 2;
gBattle_BG2_Y += 2;
if ((gBattle_WIN0V & 0xFF00) != 0x5000)
gBattle_WIN0V += 0xFF;
if (!gBattle_BG0_Y)
{
CpuFill32(0, (void *)BG_SCREEN_ADDR(28), BG_SCREEN_SIZE * 4);
SetGpuReg(REG_OFFSET_DISPCNT, GetGpuReg(REG_OFFSET_DISPCNT) & ~DISPCNT_WIN1_ON);
SetBgAttribute(1, BG_ATTR_CHARBASEINDEX, 0);
SetBgAttribute(2, BG_ATTR_CHARBASEINDEX, 0);
SetGpuReg(REG_OFFSET_BG1CNT, BGCNT_PRIORITY(0) | BGCNT_CHARBASE(0) | BGCNT_16COLOR | BGCNT_SCREENBASE(28) | BGCNT_TXT256x512);
SetGpuReg(REG_OFFSET_BG2CNT, BGCNT_PRIORITY(0) | BGCNT_CHARBASE(0) | BGCNT_16COLOR | BGCNT_SCREENBASE(30) | BGCNT_TXT512x256);
gScanlineEffect.state = 3;
gTasks[taskId].tState++;
}
break;
case 5:
BattleIntroSlideEnd(taskId);
break;
}
}
void DrawBattlerOnBg(int bgId, u8 x, u8 y, u8 battlerPosition, u8 paletteId, u8 *tiles, u16 *tilemap, u16 tilesOffset)
{
int i, j;

File diff suppressed because it is too large Load Diff

View File

@ -10,6 +10,7 @@
#include "event_data.h"
#include "event_scripts.h"
#include "field_specials.h"
#include "frontier_util.h"
#include "graphics.h"
#include "item.h"
#include "line_break.h"
@ -22,6 +23,7 @@
#include "constants/abilities.h"
#include "constants/battle_dome.h"
#include "constants/battle_string_ids.h"
#include "constants/frontier_util.h"
#include "constants/moves.h"
#include "constants/items.h"
#include "constants/trainers.h"
@ -87,7 +89,12 @@ static const u8 sText_LinkTrainerSentOutPkmn[] = _("{B_LINK_OPPONENT1_NAME} sent
static const u8 sText_LinkTrainerSentOutTwoPkmn[] = _("{B_LINK_OPPONENT1_NAME} sent out {B_OPPONENT_MON1_NAME} and {B_OPPONENT_MON2_NAME}!");
static const u8 sText_TwoLinkTrainersSentOutPkmn[] = _("{B_LINK_OPPONENT1_NAME} sent out {B_LINK_OPPONENT_MON1_NAME}! {B_LINK_OPPONENT2_NAME} sent out {B_LINK_OPPONENT_MON2_NAME}!");
static const u8 sText_LinkTrainerSentOutPkmn2[] = _("{B_LINK_OPPONENT1_NAME} sent out {B_BUFF1}!");
static const u8 sText_LinkTrainer2SentOutPkmn2[] = _("{B_LINK_OPPONENT2_NAME} sent out {B_OPPONENT_MON2_NAME}!");
static const u8 sText_LinkTrainerMultiSentOutPkmn[] = _("{B_LINK_SCR_TRAINER_NAME} sent out {B_BUFF1}!");
static const u8 sText_LinkPartnerSentOutPkmn1GoPkmn[] = _("{B_LINK_PARTNER_NAME} sent out {B_LINK_PLAYER_MON1_NAME}! Go! {B_LINK_PLAYER_MON2_NAME}!");
static const u8 sText_LinkPartnerSentOutPkmn2GoPkmn[] = _("{B_LINK_PARTNER_NAME} sent out {B_LINK_PLAYER_MON2_NAME}! Go! {B_LINK_PLAYER_MON1_NAME}!");
static const u8 sText_LinkPartnerSentOutPkmn1[] = _("{B_LINK_PARTNER_NAME} sent out {B_LINK_PLAYER_MON1_NAME}!");
static const u8 sText_LinkPartnerSentOutPkmn2[] = _("{B_LINK_PARTNER_NAME} sent out {B_LINK_PLAYER_MON2_NAME}!");
static const u8 sText_GoPkmn[] = _("Go! {B_PLAYER_MON1_NAME}!");
static const u8 sText_GoTwoPkmn[] = _("Go! {B_PLAYER_MON1_NAME} and {B_PLAYER_MON2_NAME}!");
static const u8 sText_GoPkmn2[] = _("Go! {B_BUFF1}!");
@ -104,7 +111,9 @@ static const u8 sText_PkmnGoodComeBack[] = _("Good job, {B_BUFF1}! Come back!");
static const u8 sText_Trainer1WithdrewPkmn[] = _("{B_TRAINER1_NAME_WITH_CLASS} withdrew {B_BUFF1}!");
static const u8 sText_Trainer2WithdrewPkmn[] = _("{B_TRAINER2_NAME_WITH_CLASS} withdrew {B_BUFF1}!");
static const u8 sText_LinkTrainer1WithdrewPkmn[] = _("{B_LINK_OPPONENT1_NAME} withdrew {B_BUFF1}!");
static const u8 sText_LinkTrainer2WithdrewPkmn[] = _("{B_LINK_SCR_TRAINER_NAME} withdrew {B_BUFF1}!");
static const u8 sText_LinkTrainer2WithdrewPkmn[] = _("{B_LINK_OPPONENT2_NAME} withdrew {B_BUFF1}!");
static const u8 sText_LinkPartnerWithdrewPkmn1[] = _("{B_LINK_PARTNER_NAME} withdrew {B_LINK_PLAYER_MON1_NAME}!");
static const u8 sText_LinkPartnerWithdrewPkmn2[] = _("{B_LINK_PARTNER_NAME} withdrew {B_LINK_PLAYER_MON2_NAME}!");
static const u8 sText_WildPkmnPrefix[] = _("The wild ");
static const u8 sText_FoePkmnPrefix[] = _("The opposing ");
static const u8 sText_WildPkmnPrefixLower[] = _("the wild ");
@ -230,7 +239,9 @@ static const u8 sText_TwoTrainersSentPkmn[] = _("{B_TRAINER1_NAME_WITH_CLASS} se
static const u8 sText_Trainer2SentOutPkmn[] = _("{B_TRAINER2_NAME_WITH_CLASS} sent out {B_BUFF1}!");
static const u8 sText_TwoTrainersWantToBattle[] = _("You are challenged by {B_TRAINER1_NAME_WITH_CLASS} and {B_TRAINER2_NAME_WITH_CLASS}!\p");
static const u8 sText_InGamePartnerSentOutZGoN[] = _("{B_PARTNER_NAME_WITH_CLASS} sent out {B_PLAYER_MON2_NAME}! Go, {B_PLAYER_MON1_NAME}!");
static const u8 sText_InGamePartnerSentOutPkmn1[] = _("{B_PARTNER_NAME_WITH_CLASS} sent out {B_PLAYER_MON1_NAME}!");
static const u8 sText_InGamePartnerSentOutPkmn2[] = _("{B_PARTNER_NAME_WITH_CLASS} sent out {B_PLAYER_MON2_NAME}!");
static const u8 sText_InGamePartnerWithdrewPkmn1[] = _("{B_PARTNER_NAME_WITH_CLASS} withdrew {B_PLAYER_MON1_NAME}!");
static const u8 sText_InGamePartnerWithdrewPkmn2[] = _("{B_PARTNER_NAME_WITH_CLASS} withdrew {B_PLAYER_MON2_NAME}!");
const u16 gBattlePalaceFlavorTextTable[] =
@ -322,7 +333,6 @@ const u8 *const gBattleStringsTable[STRINGID_COUNT] =
[STRINGID_ATTACKMISSED] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX}'s attack missed!"),
[STRINGID_PKMNPROTECTEDITSELF] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX} protected itself!"),
[STRINGID_STATSWONTINCREASE2] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX}'s stats won't go any higher!"),
[STRINGID_AVOIDEDDAMAGE] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX} avoided damage with {B_DEF_ABILITY}!"), //not in gen 5+, ability popup
[STRINGID_ITDOESNTAFFECT] = COMPOUND_STRING("It doesn't affect {B_DEF_NAME_WITH_PREFIX2}…"),
[STRINGID_SCR_ITDOESNTAFFECT] = COMPOUND_STRING("It doesn't affect {B_SCR_NAME_WITH_PREFIX2}…"),
[STRINGID_BATTLERFAINTED] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX} fainted!\p"),
@ -414,7 +424,7 @@ const u8 *const gBattleStringsTable[STRINGID_COUNT] =
[STRINGID_PKMNSTAYEDAWAKEUSING] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX} stayed awake using its {B_DEF_ABILITY}!"), //not in gen 5+, ability popup
[STRINGID_PKMNSTORINGENERGY] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} is storing energy!"),
[STRINGID_PKMNUNLEASHEDENERGY] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} unleashed its energy!"),
[STRINGID_PKMNFATIGUECONFUSION] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} became confused due to fatigue!"),
[STRINGID_PKMNFATIGUECONFUSION] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX} became confused due to fatigue!"),
[STRINGID_PLAYERPICKEDUPMONEY] = COMPOUND_STRING("You picked up ¥{B_BUFF1}!\p"),
[STRINGID_PKMNUNAFFECTED] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX} is unaffected!"),
[STRINGID_PKMNTRANSFORMEDINTO] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} transformed into {B_BUFF1}!"),
@ -488,11 +498,11 @@ const u8 *const gBattleStringsTable[STRINGID_COUNT] =
[STRINGID_PKMNMADEITRAIN] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX}'s {B_SCR_ABILITY} made it rain!"), //not in gen 5+, ability popup
[STRINGID_PKMNPROTECTEDBY] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX} was protected by {B_DEF_ABILITY}!"), //not in gen 5+, ability popup
[STRINGID_PKMNPREVENTSUSAGE] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX}'s {B_DEF_ABILITY} prevents {B_ATK_NAME_WITH_PREFIX2} from using {B_CURRENT_MOVE}!"), //I don't see this in SV text
[STRINGID_PKMNRESTOREDHPUSING] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX} restored HP using its {B_DEF_ABILITY}!"), //not in gen 5+, ability popup
[STRINGID_PKMNRESTOREDHPUSING] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX} restored HP using its {B_SCR_ABILITY}!"), //not in gen 5+, ability popup
[STRINGID_PKMNCHANGEDTYPEWITH] = COMPOUND_STRING("{B_EFF_NAME_WITH_PREFIX}'s {B_EFF_ABILITY} made it the {B_BUFF1} type!"), //not in gen 5+, ability popup
[STRINGID_PKMNPREVENTSROMANCEWITH] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX}'s {B_DEF_ABILITY} prevents romance!"), //not in gen 5+, ability popup
[STRINGID_PKMNPREVENTSCONFUSIONWITH] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX}'s {B_SCR_ABILITY} prevents confusion!"), //not in gen 5+, ability popup
[STRINGID_PKMNRAISEDFIREPOWERWITH] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX}'s {B_DEF_ABILITY} raised the power of Fire-type moves!"), //not in gen 5+, ability popup
[STRINGID_PKMNRAISEDFIREPOWERWITH] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX}'s {B_SCR_ABILITY} raised the power of Fire-type moves!"), //not in gen 5+, ability popup
[STRINGID_PKMNANCHORSITSELFWITH] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX} anchors itself with {B_DEF_ABILITY}!"), //not in gen 5+, ability popup
[STRINGID_PKMNCUTSATTACKWITH] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX}'s {B_SCR_ABILITY} cuts {B_DEF_NAME_WITH_PREFIX2}'s Attack!"), //not in gen 5+, ability popup
[STRINGID_PKMNPREVENTSSTATLOSSWITH] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX}'s {B_SCR_ABILITY} prevents stat loss!"), //not in gen 5+, ability popup
@ -595,7 +605,7 @@ const u8 *const gBattleStringsTable[STRINGID_COUNT] =
[STRINGID_PKMNSXWHIPPEDUPSANDSTORM] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX}'s {B_SCR_ABILITY} whipped up a sandstorm!"), //not in gen 5+, ability popup
[STRINGID_PKMNSXPREVENTSYLOSS] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX}'s {B_SCR_ABILITY} prevents {B_BUFF1} loss!"), //not in gen 5+, ability popup
[STRINGID_PKMNSXINFATUATEDY] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX}'s {B_DEF_ABILITY} infatuated {B_ATK_NAME_WITH_PREFIX2}!"), //not in gen 5+, ability popup
[STRINGID_PKMNSXMADEYINEFFECTIVE] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX}'s {B_DEF_ABILITY} made {B_CURRENT_MOVE} ineffective!"), //not in gen 5+, ability popup
[STRINGID_PKMNSXMADEYINEFFECTIVE] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX}'s {B_SCR_ABILITY} made {B_CURRENT_MOVE} ineffective!"), //not in gen 5+, ability popup
[STRINGID_PKMNSXCUREDYPROBLEM] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX}'s {B_SCR_ABILITY} cured its {B_BUFF1} problem!"), //not in gen 5+, ability popup
[STRINGID_ITSUCKEDLIQUIDOOZE] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} sucked up the liquid ooze!"),
[STRINGID_PKMNTRANSFORMED] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX} transformed!"),
@ -611,12 +621,11 @@ const u8 *const gBattleStringsTable[STRINGID_COUNT] =
[STRINGID_USINGITEMSTATOFPKMNROSE] = COMPOUND_STRING("Using {B_LAST_ITEM}, the {B_BUFF1} of {B_SCR_NAME_WITH_PREFIX2} {B_BUFF2}rose!"), //todo: update this, will require code changes
[STRINGID_USINGITEMSTATOFPKMNFELL] = COMPOUND_STRING("Using {B_LAST_ITEM}, the {B_BUFF1} of {B_SCR_NAME_WITH_PREFIX2} {B_BUFF2}fell!"),
[STRINGID_PKMNUSEDXTOGETPUMPED] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX} used the {B_LAST_ITEM} to get pumped!"),
[STRINGID_PKMNSXMADEYUSELESS] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX}'s {B_DEF_ABILITY} made {B_CURRENT_MOVE} useless!"), //not in gen 5+, ability popup
[STRINGID_PKMNSXMADEYUSELESS] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX}'s {B_SCR_ABILITY} made {B_CURRENT_MOVE} useless!"), //not in gen 5+, ability popup
[STRINGID_PKMNTRAPPEDBYSANDTOMB] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX} became trapped by the quicksand!"),
[STRINGID_EMPTYSTRING4] = COMPOUND_STRING(""),
[STRINGID_ABOOSTED] = COMPOUND_STRING(" a boosted"),
[STRINGID_PKMNSXINTENSIFIEDSUN] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX}'s {B_SCR_ABILITY} intensified the sun's rays!"), //not in gen 5+, ability popup
[STRINGID_PKMNMAKESGROUNDMISS] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX} makes Ground-type moves miss with {B_DEF_ABILITY}!"), //not in gen 5+, ability popup
[STRINGID_YOUTHROWABALLNOWRIGHT] = COMPOUND_STRING("You throw a Ball now, right? I… I'll do my best!"),
[STRINGID_PKMNSXTOOKATTACK] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX}'s {B_DEF_ABILITY} took the attack!"), //In gen 5+ but without naming the ability
[STRINGID_PKMNCHOSEXASDESTINY] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} chose Doom Desire as its destiny!"),
@ -756,7 +765,7 @@ const u8 *const gBattleStringsTable[STRINGID_COUNT] =
[STRINGID_HEALINGWISHCAMETRUE] = COMPOUND_STRING("The healing wish came true for {B_SCR_NAME_WITH_PREFIX2}!"),
[STRINGID_HEALINGWISHHEALED] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX} regained health!"),
[STRINGID_LUNARDANCECAMETRUE] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX} became cloaked in mystical moonlight!"),
[STRINGID_CURSEDBODYDISABLED] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX}'s {B_BUFF1} was disabled by {B_DEF_NAME_WITH_PREFIX2}'s {B_DEF_ABILITY}!"),
[STRINGID_CURSEDBODYDISABLED] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX}'s {B_BUFF1} was disabled by {B_DEF_NAME_WITH_PREFIX2}'s {B_DEF_ABILITY}!"),
[STRINGID_ATTACKERACQUIREDABILITY] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} acquired {B_ATK_ABILITY}!"),
[STRINGID_TARGETABILITYSTATLOWER] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX}'s {B_DEF_ABILITY} {B_BUFF2}lowered its {B_BUFF1}!"),
[STRINGID_TARGETSTATWONTGOHIGHER] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX}'s {B_BUFF1} won't go any higher!"),
@ -797,8 +806,8 @@ const u8 *const gBattleStringsTable[STRINGID_COUNT] =
[STRINGID_MISTYTERRAINPREVENTS] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX} surrounds itself with a protective mist!"),
[STRINGID_GRASSYTERRAINHEALS] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} is healed by the grassy terrain!"),
[STRINGID_ELECTRICTERRAINPREVENTS] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX} surrounds itself with electrified terrain!"),
[STRINGID_PSYCHICTERRAINPREVENTS] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX} is protected by the Psychic Terrain!"),
[STRINGID_SAFETYGOGGLESPROTECTED] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX} is not affected thanks to its {B_LAST_ITEM}!"),
[STRINGID_PSYCHICTERRAINPREVENTS] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX} is protected by the Psychic Terrain!"),
[STRINGID_SAFETYGOGGLESPROTECTED] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX} is not affected thanks to its {B_LAST_ITEM}!"),
[STRINGID_FLOWERVEILPROTECTED] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX} surrounded itself with a veil of petals!"),
[STRINGID_SWEETVEILPROTECTED] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX} can't fall asleep due to a veil of sweetness!"),
[STRINGID_AROMAVEILPROTECTED] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX} is protected by an aromatic veil!"),
@ -1015,16 +1024,17 @@ const u8 *const gBattleStringsTable[STRINGID_COUNT] =
[STRINGID_SILPHSCOPEUNVEILED] = COMPOUND_STRING("SILPH SCOPE unveiled the GHOST's\nidentity!"),
[STRINGID_GHOSTWASMAROWAK] = COMPOUND_STRING("The GHOST was MAROWAK!\p\n"),
[STRINGID_TRAINER1MON1COMEBACK] = COMPOUND_STRING("{B_TRAINER1_NAME}: {B_OPPONENT_MON1_NAME}, come back!"),
[STRINGID_THREWROCK] = COMPOUND_STRING("{B_PLAYER_NAME} threw a ROCK\nat the {B_OPPONENT_MON1_NAME}!"),
[STRINGID_THREWBAIT] = COMPOUND_STRING("{B_PLAYER_NAME} threw some BAIT\nat the {B_OPPONENT_MON1_NAME}!"),
[STRINGID_PKMNANGRY] = COMPOUND_STRING("{B_OPPONENT_MON1_NAME} is angry!"),
[STRINGID_PKMNEATING] = COMPOUND_STRING("{B_OPPONENT_MON1_NAME} is eating!"),
[STRINGID_PKMNDISGUISEWASBUSTED] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX}'s disguise was busted!"),
// pokefirered strings
[STRINGID_PKMNTRANSFERREDBILLSPC] = gText_PkmnTransferredBillsPC,
[STRINGID_PKMNBOXBILLSPCFULL] = gText_PkmnTransferredBillsPCBoxFull,
[STRINGID_OLDMANUSEDITEM] = COMPOUND_STRING("The old man used\n{B_LAST_ITEM}!"),
[STRINGID_GOTCHAPKMNCAUGHTOLDMAN] = COMPOUND_STRING("Gotcha!\n{B_OPPONENT_MON1_NAME} was caught!{WAIT_SE}{PLAY_BGM MUS_CAUGHT}{PAUSE 127}"),
[STRINGID_THREWROCK] = COMPOUND_STRING("{B_PLAYER_NAME} threw a ROCK\nat the {B_OPPONENT_MON1_NAME}!"),
[STRINGID_THREWBAIT] = COMPOUND_STRING("{B_PLAYER_NAME} threw some BAIT\nat the {B_OPPONENT_MON1_NAME}!"),
[STRINGID_PKMNANGRY] = COMPOUND_STRING("{B_OPPONENT_MON1_NAME} is angry!"),
[STRINGID_PKMNEATING] = COMPOUND_STRING("{B_OPPONENT_MON1_NAME} is eating!"),
[STRINGID_POKEDUDEUSED] = COMPOUND_STRING("The POKé DUDE used\n{B_LAST_ITEM}!"),
[STRINGID_TRAINER1MON2COMEBACK] = COMPOUND_STRING("{B_TRAINER1_NAME}: {B_OPPONENT_MON2_NAME}, come back!"),
[STRINGID_TRAINER1MON1AND2COMEBACK] = COMPOUND_STRING("{B_TRAINER1_NAME}: {B_OPPONENT_MON1_NAME} and\n{B_OPPONENT_MON2_NAME}, come back!"),
@ -1141,8 +1151,6 @@ const u16 gMissStringIds[] =
[B_MSG_MISSED] = STRINGID_ATTACKMISSED,
[B_MSG_PROTECTED] = STRINGID_PKMNPROTECTEDITSELF,
[B_MSG_AVOIDED_ATK] = STRINGID_PKMNAVOIDEDATTACK,
[B_MSG_AVOIDED_DMG] = STRINGID_AVOIDEDDAMAGE,
[B_MSG_GROUND_MISS] = STRINGID_PKMNMAKESGROUNDMISS
};
const u16 gNoEscapeStringIds[] =
@ -1807,7 +1815,7 @@ void BufferStringBattle(enum StringID stringID, u32 battler)
}
else
{
if (!(gBattleTypeFlags & (BATTLE_TYPE_LINK | BATTLE_TYPE_RECORDED_LINK)))
if (!(BattlerIsLink(battler) || (BattlerIsRecorded(battler) && BattlerIsOpponent(battler))))
stringPtr = sText_Trainer1SentOutPkmn;
else if (TRAINER_BATTLE_PARAM.opponentA == TRAINER_UNION_ROOM)
stringPtr = sText_Trainer1SentOutPkmn;
@ -1817,120 +1825,156 @@ void BufferStringBattle(enum StringID stringID, u32 battler)
}
break;
case STRINGID_RETURNMON: // sending poke to ball msg
if (IsOnPlayerSide(battler))
if ((GetBattlerPosition(battler) & BIT_FLANK) == B_FLANK_LEFT) // battler 0 and 1
{
if (gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER && GetBattlerPosition(battler) == B_POSITION_PLAYER_RIGHT)
stringPtr = sText_InGamePartnerWithdrewPkmn2;
else if (*(&gBattleStruct->hpScale) == 0)
stringPtr = sText_PkmnThatsEnough;
else if (*(&gBattleStruct->hpScale) == 1 || IsDoubleBattle())
stringPtr = sText_PkmnComeBack;
else if (*(&gBattleStruct->hpScale) == 2)
stringPtr = sText_PkmnOkComeBack;
else
stringPtr = sText_PkmnGoodComeBack;
}
else
{
if (TRAINER_BATTLE_PARAM.opponentA == TRAINER_LINK_OPPONENT || gBattleTypeFlags & BATTLE_TYPE_RECORDED_LINK)
if (BattlerIsPlayer(battler) || BattlerIsOldMan(battler)) // Player
{
if (gBattleTypeFlags & BATTLE_TYPE_MULTI)
if (*(&gBattleStruct->hpScale) == 0)
stringPtr = sText_PkmnThatsEnough;
else if (*(&gBattleStruct->hpScale) == 1 || IsDoubleBattle())
stringPtr = sText_PkmnComeBack;
else if (*(&gBattleStruct->hpScale) == 2)
stringPtr = sText_PkmnOkComeBack;
else
stringPtr = sText_PkmnGoodComeBack;
}
else if (BattlerIsPartner(battler))
{
if (BattlerIsLink(battler)) // Link Partner
{
stringPtr = sText_LinkPartnerWithdrewPkmn1;
}
else // In-game Partner
{
stringPtr = sText_InGamePartnerWithdrewPkmn1;
}
}
else if (BattlerIsLink(battler) || TRAINER_BATTLE_PARAM.opponentA == TRAINER_LINK_OPPONENT
|| gBattleTypeFlags & BATTLE_TYPE_RECORDED_LINK) // Link Opponent 1 and test opponent
{
stringPtr = sText_LinkTrainer1WithdrewPkmn;
}
else // Opponent A
{
stringPtr = sText_Trainer1WithdrewPkmn;
}
}
else // battler 2 and 3
{
if (BattlerIsPlayer(battler)) // Player
{
if (*(&gBattleStruct->hpScale) == 0)
stringPtr = sText_PkmnThatsEnough;
else if (*(&gBattleStruct->hpScale) == 1 || IsDoubleBattle())
stringPtr = sText_PkmnComeBack;
else if (*(&gBattleStruct->hpScale) == 2)
stringPtr = sText_PkmnOkComeBack;
else
stringPtr = sText_PkmnGoodComeBack;
}
else if (BattlerIsPartner(battler))
{
if (BattlerIsLink(battler)) // Link Partner
{
stringPtr = sText_LinkPartnerWithdrewPkmn2;
}
else // In-game Partner
{
stringPtr = sText_InGamePartnerWithdrewPkmn2;
}
}
else if (BattlerIsLink(battler) || TRAINER_BATTLE_PARAM.opponentA == TRAINER_LINK_OPPONENT
|| TRAINER_BATTLE_PARAM.opponentB == TRAINER_LINK_OPPONENT || gBattleTypeFlags & BATTLE_TYPE_RECORDED_LINK) // Link Opponent B and test opponent
{
if (gBattleTypeFlags & BATTLE_TYPE_TWO_OPPONENTS)
stringPtr = sText_LinkTrainer2WithdrewPkmn;
else
stringPtr = sText_LinkTrainer1WithdrewPkmn;
}
else
else if (gBattleTypeFlags & BATTLE_TYPE_TWO_OPPONENTS) // Opponent B
{
if (gBattleTypeFlags & BATTLE_TYPE_TWO_OPPONENTS)
{
if (GetBattlerPosition(battler) == B_POSITION_OPPONENT_LEFT)
stringPtr = sText_Trainer1WithdrewPkmn;
else
stringPtr = sText_Trainer2WithdrewPkmn;
}
else
{
stringPtr = sText_Trainer1WithdrewPkmn;
}
stringPtr = sText_Trainer2WithdrewPkmn;
}
else // Opponent A
{
stringPtr = sText_Trainer1WithdrewPkmn;
}
}
break;
case STRINGID_SWITCHINMON: // switch-in msg
if (IsOnPlayerSide(gBattleScripting.battler))
if ((GetBattlerPosition(gBattleScripting.battler) & BIT_FLANK) == B_FLANK_LEFT) // battler 0 and 1
{
if ((gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER) && (GetBattlerAtPosition(gBattleScripting.battler) == 2))
stringPtr = sText_InGamePartnerSentOutPkmn2;
else if (*(&gBattleStruct->hpScale) == 0 || IsDoubleBattle())
stringPtr = sText_GoPkmn2;
else if (*(&gBattleStruct->hpScale) == 1)
stringPtr = sText_DoItPkmn;
else if (*(&gBattleStruct->hpScale) == 2)
stringPtr = sText_GoForItPkmn;
else
stringPtr = sText_YourFoesWeakGetEmPkmn;
}
else
{
if (gBattleTypeFlags & (BATTLE_TYPE_LINK | BATTLE_TYPE_RECORDED_LINK))
if (BattlerIsPlayer(gBattleScripting.battler)) // Player
{
if (gBattleTypeFlags & BATTLE_TYPE_TOWER_LINK_MULTI)
{
if (gBattleScripting.battler == 1)
stringPtr = sText_Trainer1SentOutPkmn2;
else
stringPtr = sText_Trainer2SentOutPkmn;
}
if (*(&gBattleStruct->hpScale) == 0)
stringPtr = sText_GoPkmn2;
else if (*(&gBattleStruct->hpScale) == 1 || IsDoubleBattle())
stringPtr = sText_DoItPkmn;
else if (*(&gBattleStruct->hpScale) == 2)
stringPtr = sText_GoForItPkmn;
else
stringPtr = sText_YourFoesWeakGetEmPkmn;
}
else if (BattlerIsPartner(gBattleScripting.battler))
{
if (BattlerIsLink(gBattleScripting.battler)) // Link Partner
{
if (TESTING && gBattleTypeFlags & BATTLE_TYPE_MULTI)
{
if (gBattleScripting.battler == 1)
{
stringPtr = sText_Trainer1SentOutPkmn;
}
else
{
if (gBattleTypeFlags & BATTLE_TYPE_TWO_OPPONENTS)
stringPtr = sText_Trainer2SentOutPkmn;
else
stringPtr = sText_Trainer1SentOutPkmn2;
}
}
else if (TESTING && gBattleTypeFlags & BATTLE_TYPE_TWO_OPPONENTS)
{
if (gBattleScripting.battler == 1)
stringPtr = sText_Trainer1SentOutPkmn;
else
stringPtr = sText_Trainer2SentOutPkmn;
}
else if (gBattleTypeFlags & BATTLE_TYPE_MULTI)
{
stringPtr = sText_LinkTrainerMultiSentOutPkmn;
}
else if (TRAINER_BATTLE_PARAM.opponentA == TRAINER_UNION_ROOM)
{
stringPtr = sText_Trainer1SentOutPkmn2;
}
else
{
stringPtr = sText_LinkTrainerSentOutPkmn2;
}
stringPtr = sText_LinkPartnerSentOutPkmn1;
}
else // In-game Partner
{
stringPtr = sText_InGamePartnerSentOutPkmn1;
}
}
else
else if (BattlerIsLink(gBattleScripting.battler) || TRAINER_BATTLE_PARAM.opponentA == TRAINER_LINK_OPPONENT
|| gBattleTypeFlags & BATTLE_TYPE_RECORDED_LINK) // Link Opponent 1 and test opponent
{
stringPtr = sText_LinkTrainerSentOutPkmn;
}
else // Opponent A
{
stringPtr = sText_Trainer1SentOutPkmn;
}
}
else // battler 2 and 3
{
if (BattlerIsPlayer(gBattleScripting.battler)) // Player
{
if (*(&gBattleStruct->hpScale) == 0)
stringPtr = sText_GoPkmn2;
else if (*(&gBattleStruct->hpScale) == 1 || IsDoubleBattle())
stringPtr = sText_DoItPkmn;
else if (*(&gBattleStruct->hpScale) == 2)
stringPtr = sText_GoForItPkmn;
else
stringPtr = sText_YourFoesWeakGetEmPkmn;
}
else if (BattlerIsPartner(gBattleScripting.battler))
{
if (BattlerIsLink(gBattleScripting.battler)) // Link Partner
{
stringPtr = sText_LinkPartnerSentOutPkmn2;
}
else // In-game Partner
{
stringPtr = sText_InGamePartnerSentOutPkmn2;
}
}
else if (BattlerIsLink(gBattleScripting.battler) || TRAINER_BATTLE_PARAM.opponentA == TRAINER_LINK_OPPONENT
|| TRAINER_BATTLE_PARAM.opponentB == TRAINER_LINK_OPPONENT || gBattleTypeFlags & BATTLE_TYPE_RECORDED_LINK) // Link Opponent B and test opponent
{
if (gBattleTypeFlags & BATTLE_TYPE_TWO_OPPONENTS)
{
if (gBattleScripting.battler == 1)
stringPtr = sText_Trainer1SentOutPkmn2;
else
stringPtr = sText_Trainer2SentOutPkmn;
}
stringPtr = sText_LinkTrainer2SentOutPkmn2;
else
{
stringPtr = sText_Trainer1SentOutPkmn2;
}
stringPtr = sText_LinkTrainerSentOutPkmn2;
}
else if (gBattleTypeFlags & BATTLE_TYPE_TWO_OPPONENTS) // Opponent B
{
stringPtr = sText_Trainer2SentOutPkmn;
}
else // Opponent A
{
stringPtr = sText_Trainer1SentOutPkmn2;
}
}
break;
@ -2151,9 +2195,15 @@ static const u8 *BattleStringGetOpponentNameByTrainerId(u16 trainerId, u8 *text,
else
toCpy = gLinkPlayers[GetBattlerMultiplayerId(battler) & BIT_SIDE].name;
}
else if (gBattleTypeFlags & BATTLE_TYPE_BATTLE_TOWER)
else if (trainerId == TRAINER_FRONTIER_BRAIN)
{
StringCopy(text, gText_Placeholder);
CopyFrontierBrainTrainerName(text);
toCpy = text;
}
else if (gBattleTypeFlags & BATTLE_TYPE_FRONTIER)
{
GetFrontierTrainerName(text, trainerId);
toCpy = text;
}
else if (gBattleTypeFlags & BATTLE_TYPE_TRAINER_TOWER)
{
@ -2256,8 +2306,10 @@ static const u8 *BattleStringGetOpponentClassByTrainerId(u16 trainerId)
toCpy = gTrainerClasses[GetSecretBaseTrainerClass()].name;
else if (trainerId == TRAINER_UNION_ROOM)
toCpy = gTrainerClasses[GetUnionRoomTrainerClass()].name;
else if (gBattleTypeFlags & BATTLE_TYPE_BATTLE_TOWER)
toCpy = gTrainerClasses[TRAINER_CLASS_PLAYER].name;
else if (trainerId == TRAINER_FRONTIER_BRAIN)
toCpy = gTrainerClasses[GetFrontierBrainTrainerClass()].name;
else if (gBattleTypeFlags & BATTLE_TYPE_FRONTIER)
toCpy = gTrainerClasses[GetFrontierOpponentClass(trainerId)].name;
else if (gBattleTypeFlags & BATTLE_TYPE_TRAINER_TOWER)
toCpy = gTrainerClasses[GetTrainerTowerOpponentClass()].name;
else if (gBattleTypeFlags & BATTLE_TYPE_EREADER_TRAINER)
@ -2598,7 +2650,12 @@ u32 BattleStringExpandPlaceholders(const u8 *src, u8 *dst, u32 dstSize)
toCpy = BattleStringGetPlayerName(text, GetBattlerAtPosition(B_POSITION_PLAYER_LEFT));
break;
case B_TXT_TRAINER1_LOSE_TEXT: // trainerA lose text
if (gBattleTypeFlags & BATTLE_TYPE_TRAINER_TOWER)
if (gBattleTypeFlags & BATTLE_TYPE_FRONTIER)
{
CopyFrontierTrainerText(FRONTIER_PLAYER_WON_TEXT, TRAINER_BATTLE_PARAM.opponentA);
toCpy = gStringVar4;
}
else if (gBattleTypeFlags & BATTLE_TYPE_TRAINER_TOWER)
{
GetTrainerTowerOpponentLoseText(gStringVar4, 0);
toCpy = gStringVar4;
@ -2609,7 +2666,12 @@ u32 BattleStringExpandPlaceholders(const u8 *src, u8 *dst, u32 dstSize)
}
break;
case B_TXT_TRAINER1_WIN_TEXT: // trainerA win text
if (gBattleTypeFlags & BATTLE_TYPE_TRAINER_TOWER)
if (gBattleTypeFlags & BATTLE_TYPE_FRONTIER)
{
CopyFrontierTrainerText(FRONTIER_PLAYER_LOST_TEXT, TRAINER_BATTLE_PARAM.opponentA);
toCpy = gStringVar4;
}
else if (gBattleTypeFlags & BATTLE_TYPE_TRAINER_TOWER)
{
GetTrainerTowerOpponentWinText(gStringVar4, 0);
toCpy = gStringVar4;
@ -2620,7 +2682,12 @@ u32 BattleStringExpandPlaceholders(const u8 *src, u8 *dst, u32 dstSize)
}
break;
case B_TXT_TRAINER2_LOSE_TEXT:
if (gBattleTypeFlags & BATTLE_TYPE_TRAINER_TOWER)
if (gBattleTypeFlags & BATTLE_TYPE_FRONTIER)
{
CopyFrontierTrainerText(FRONTIER_PLAYER_WON_TEXT, TRAINER_BATTLE_PARAM.opponentB);
toCpy = gStringVar4;
}
else if (gBattleTypeFlags & BATTLE_TYPE_TRAINER_TOWER)
{
GetTrainerTowerOpponentLoseText(gStringVar4, 1);
toCpy = gStringVar4;
@ -2631,7 +2698,11 @@ u32 BattleStringExpandPlaceholders(const u8 *src, u8 *dst, u32 dstSize)
}
break;
case B_TXT_TRAINER2_WIN_TEXT:
if (gBattleTypeFlags & BATTLE_TYPE_TRAINER_TOWER)
if (gBattleTypeFlags & BATTLE_TYPE_FRONTIER)
{
CopyFrontierTrainerText(FRONTIER_PLAYER_LOST_TEXT, TRAINER_BATTLE_PARAM.opponentB);
toCpy = gStringVar4;
} else if (gBattleTypeFlags & BATTLE_TYPE_TRAINER_TOWER)
{
GetTrainerTowerOpponentWinText(gStringVar4, 1);
toCpy = gStringVar4;

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -2,6 +2,7 @@
#include "battle.h"
#include "load_save.h"
#include "battle_setup.h"
#include "battle_tower.h"
#include "battle_transition.h"
#include "main.h"
#include "task.h"
@ -29,9 +30,11 @@
#include "string_util.h"
#include "overworld.h"
#include "field_weather.h"
#include "battle_tower.h"
// #include "gym_leader_rematch.h"
// #include "battle_pike.h"
// #include "battle_pyramid.h"
#include "battle_frontier.h"
#include "battle_pike.h"
#include "battle_pyramid.h"
#include "fldeff.h"
// #include "fldeff_misc.h"
#include "field_control_avatar.h"
@ -40,6 +43,8 @@
#include "data.h"
#include "vs_seeker.h"
#include "item.h"
#include "script.h"
// #include "field_name_box.h"
#include "constants/battle_frontier.h"
#include "constants/battle_setup.h"
#include "constants/event_objects.h"
@ -50,11 +55,13 @@
#include "constants/trainers.h"
// #include "constants/trainer_hill.h"
#include "constants/weather.h"
#include "fishing.h"
#include "wild_encounter.h"
#include "help_system.h"
#include "quest_log.h"
enum {
enum TransitionType
{
TRANSITION_TYPE_NORMAL,
TRANSITION_TYPE_CAVE,
TRANSITION_TYPE_FLASH,
@ -68,6 +75,7 @@ static void DoGhostBattle(void);
static void DoStandardWildBattle(bool32 isDouble);
static void CB2_EndWildBattle(void);
static void CB2_EndScriptedWildBattle(void);
static void CB2_EndMarowakBattle(void);
// static void TryUpdateGymLeaderRematchFromWild(void);
// static void TryUpdateGymLeaderRematchFromTrainer(void);
// static void CB2_GiveStarter(void);
@ -75,7 +83,6 @@ static void CB2_EndScriptedWildBattle(void);
// static void CB2_EndFirstBattle(void);
// static void SaveChangesToPlayerParty(void);
// static void HandleBattleVariantEndParty(void);
static void CB2_EndMarowakBattle(void);
static void CB2_EndTrainerBattle(void);
static bool32 IsPlayerDefeated(u32 battleOutcome);
// #if FREE_MATCH_CALL == FALSE
@ -110,6 +117,38 @@ static const u8 sBattleTransitionTable_Trainer[][2] =
[TRANSITION_TYPE_WATER] = {B_TRANSITION_SWIRL, B_TRANSITION_RIPPLE},
};
// Battle Frontier (excluding Pyramid and Dome, which have their own tables below)
static const u8 sBattleTransitionTable_BattleFrontier[] =
{
B_TRANSITION_FRONTIER_LOGO_WIGGLE,
B_TRANSITION_FRONTIER_LOGO_WAVE,
B_TRANSITION_FRONTIER_SQUARES,
B_TRANSITION_FRONTIER_SQUARES_SCROLL,
B_TRANSITION_FRONTIER_CIRCLES_MEET,
B_TRANSITION_FRONTIER_CIRCLES_CROSS,
B_TRANSITION_FRONTIER_CIRCLES_ASYMMETRIC_SPIRAL,
B_TRANSITION_FRONTIER_CIRCLES_SYMMETRIC_SPIRAL,
B_TRANSITION_FRONTIER_CIRCLES_MEET_IN_SEQ,
B_TRANSITION_FRONTIER_CIRCLES_CROSS_IN_SEQ,
B_TRANSITION_FRONTIER_CIRCLES_ASYMMETRIC_SPIRAL_IN_SEQ,
B_TRANSITION_FRONTIER_CIRCLES_SYMMETRIC_SPIRAL_IN_SEQ
};
static const u8 sBattleTransitionTable_BattlePyramid[] =
{
B_TRANSITION_FRONTIER_SQUARES,
B_TRANSITION_FRONTIER_SQUARES_SCROLL,
B_TRANSITION_FRONTIER_SQUARES_SPIRAL
};
static const u8 sBattleTransitionTable_BattleDome[] =
{
B_TRANSITION_FRONTIER_LOGO_WIGGLE,
B_TRANSITION_FRONTIER_SQUARES,
B_TRANSITION_FRONTIER_SQUARES_SCROLL,
B_TRANSITION_FRONTIER_SQUARES_SPIRAL
};
#define tState data[0]
#define tTransition data[1]
@ -143,7 +182,7 @@ static void Task_BattleStart(u8 taskId)
}
}
static void CreateBattleStartTask(u8 transition, u16 song)
static void CreateBattleStartTask(enum BattleTransition transition, u16 song)
{
u8 taskId = CreateTask(Task_BattleStart, 1);
@ -240,11 +279,11 @@ static void DoStandardWildBattle(bool32 isDouble)
}
else if (isDouble)
gBattleTypeFlags |= BATTLE_TYPE_DOUBLE;
// if (InBattlePyramid())
// {
// VarSet(VAR_TEMP_E, 0);
// gBattleTypeFlags |= BATTLE_TYPE_PYRAMID;
// }
if (CurrentBattlePyramidLocation() != PYRAMID_LOCATION_NONE)
{
VarSet(VAR_TEMP_E, 0);
gBattleTypeFlags |= BATTLE_TYPE_PYRAMID;
}
CreateBattleStartTask(GetWildBattleTransition(), 0);
IncrementGameStat(GAME_STAT_TOTAL_BATTLES);
IncrementGameStat(GAME_STAT_WILD_BATTLES);
@ -259,11 +298,11 @@ void DoStandardWildBattle_Debug(void)
StopPlayerAvatar();
gMain.savedCallback = CB2_EndWildBattle;
gBattleTypeFlags = 0;
// if (InBattlePyramid())
// {
// VarSet(VAR_TEMP_PLAYING_PYRAMID_MUSIC, 0);
// gBattleTypeFlags |= BATTLE_TYPE_PYRAMID;
// }
if (CurrentBattlePyramidLocation() != PYRAMID_LOCATION_NONE)
{
VarSet(VAR_TEMP_PLAYING_PYRAMID_MUSIC, 0);
gBattleTypeFlags |= BATTLE_TYPE_PYRAMID;
}
CreateBattleStartTask_Debug(GetWildBattleTransition(), 0);
//IncrementGameStat(GAME_STAT_TOTAL_BATTLES);
//IncrementGameStat(GAME_STAT_WILD_BATTLES);
@ -330,16 +369,26 @@ static void DoTrainerBattle(void)
// TryUpdateGymLeaderRematchFromTrainer();
}
// static void DoBattlePyramidTrainerHillBattle(void)
// {
// if (InBattlePyramid())
// CreateBattleStartTask(GetSpecialBattleTransition(B_TRANSITION_GROUP_B_PYRAMID), 0);
// else
// CreateBattleStartTask(GetSpecialBattleTransition(B_TRANSITION_GROUP_TRAINER_HILL), 0);
static void DoBattlePyramidTrainerHillBattle(void)
{
if (CurrentBattlePyramidLocation() != PYRAMID_LOCATION_NONE)
CreateBattleStartTask(GetSpecialBattleTransition(B_TRANSITION_GROUP_B_PYRAMID), 0);
else
CreateBattleStartTask(GetSpecialBattleTransition(B_TRANSITION_GROUP_TRAINER_TOWER), 0);
// IncrementGameStat(GAME_STAT_TOTAL_BATTLES);
// IncrementGameStat(GAME_STAT_TRAINER_BATTLES);
// TryUpdateGymLeaderRematchFromTrainer();
IncrementGameStat(GAME_STAT_TOTAL_BATTLES);
IncrementGameStat(GAME_STAT_TRAINER_BATTLES);
// TryUpdateGymLeaderRematchFromTrainer();
}
// Initiates battle where Wally catches Ralts
// void StartWallyTutorialBattle(void)
// {
// CreateMaleMon(&gEnemyParty[0], SPECIES_RALTS, 5);
// LockPlayerFieldControls();
// gMain.savedCallback = CB2_ReturnToFieldContinueScriptPlayMapMusic;
// gBattleTypeFlags = BATTLE_TYPE_CATCH_TUTORIAL;
// CreateBattleStartTask(B_TRANSITION_SLICE, 0);
// }
void StartOldManTutorialBattle(void)
@ -387,6 +436,7 @@ void StartMarowakBattle(void)
CreateMonWithIVsPersonality(&gEnemyParty[0], SPECIES_MAROWAK, 30, 31, personality);
}
CreateBattleStartTask(GetWildBattleTransition(), 0);
SetMonData(&gEnemyParty[0], MON_DATA_NICKNAME, gText_Ghost);
IncrementGameStat(GAME_STAT_TOTAL_BATTLES);
@ -407,13 +457,24 @@ void BattleSetup_StartLatiBattle(void)
void BattleSetup_StartLegendaryBattle(void)
{
u16 species;
LockPlayerFieldControls();
gMain.savedCallback = CB2_EndScriptedWildBattle;
gBattleTypeFlags = BATTLE_TYPE_LEGENDARY;
species = GetMonData(&gEnemyParty[0], MON_DATA_SPECIES);
switch (species)
switch (GetMonData(&gEnemyParty[0], MON_DATA_SPECIES))
{
case SPECIES_GROUDON:
case SPECIES_GROUDON_PRIMAL:
CreateBattleStartTask(B_TRANSITION_GROUDON, MUS_VS_KYOGRE_GROUDON);
break;
case SPECIES_KYOGRE:
case SPECIES_KYOGRE_PRIMAL:
CreateBattleStartTask(B_TRANSITION_KYOGRE, MUS_VS_KYOGRE_GROUDON);
break;
case SPECIES_RAYQUAZA:
case SPECIES_RAYQUAZA_MEGA:
CreateBattleStartTask(B_TRANSITION_RAYQUAZA, MUS_VS_RAYQUAZA);
break;
case SPECIES_MEWTWO:
case SPECIES_MEWTWO_MEGA_X:
case SPECIES_MEWTWO_MEGA_Y:
@ -425,9 +486,14 @@ void BattleSetup_StartLegendaryBattle(void)
case SPECIES_DEOXYS_SPEED:
CreateBattleStartTask(B_TRANSITION_BLUR, MUS_VS_DEOXYS);
break;
case SPECIES_LUGIA:
case SPECIES_HO_OH:
default:
CreateBattleStartTask(B_TRANSITION_BLUR, MUS_VS_LEGEND);
break;
case SPECIES_MEW:
CreateBattleStartTask(B_TRANSITION_GRID_SQUARES, MUS_VS_MEW);
break;
}
IncrementGameStat(GAME_STAT_TOTAL_BATTLES);
@ -442,7 +508,10 @@ void StartGroudonKyogreBattle(void)
gMain.savedCallback = CB2_EndScriptedWildBattle;
gBattleTypeFlags = BATTLE_TYPE_LEGENDARY;
CreateBattleStartTask(B_TRANSITION_ANGLED_WIPES, MUS_RS_VS_TRAINER);
if (gGameVersion == VERSION_RUBY)
CreateBattleStartTask(B_TRANSITION_ANGLED_WIPES, MUS_VS_KYOGRE_GROUDON); // GROUDON
else
CreateBattleStartTask(B_TRANSITION_RIPPLE, MUS_VS_KYOGRE_GROUDON); // KYOGRE
IncrementGameStat(GAME_STAT_TOTAL_BATTLES);
IncrementGameStat(GAME_STAT_WILD_BATTLES);
@ -452,14 +521,30 @@ void StartGroudonKyogreBattle(void)
void StartRegiBattle(void)
{
u8 transitionId = B_TRANSITION_BLUR;
// u16 species;
enum BattleTransition transitionId;
u16 species;
LockPlayerFieldControls();
gMain.savedCallback = CB2_EndScriptedWildBattle;
gBattleTypeFlags = BATTLE_TYPE_LEGENDARY;
CreateBattleStartTask(transitionId, MUS_RS_VS_TRAINER);
species = GetMonData(&gEnemyParty[0], MON_DATA_SPECIES);
switch (species)
{
case SPECIES_REGIROCK:
transitionId = B_TRANSITION_REGIROCK;
break;
case SPECIES_REGICE:
transitionId = B_TRANSITION_REGICE;
break;
case SPECIES_REGISTEEL:
transitionId = B_TRANSITION_REGISTEEL;
break;
default:
transitionId = B_TRANSITION_GRID_SQUARES;
break;
}
CreateBattleStartTask(transitionId, MUS_VS_REGI);
IncrementGameStat(GAME_STAT_TOTAL_BATTLES);
IncrementGameStat(GAME_STAT_WILD_BATTLES);
@ -494,7 +579,7 @@ static void CB2_EndWildBattle(void)
HealPlayerParty();
}
if (IsPlayerDefeated(gBattleOutcome) == TRUE)
if (IsPlayerDefeated(gBattleOutcome) == TRUE && CurrentBattlePyramidLocation() == PYRAMID_LOCATION_NONE && !InBattlePike())
{
SetMainCallback2(CB2_WhiteOut);
}
@ -513,7 +598,10 @@ static void CB2_EndScriptedWildBattle(void)
if (IsPlayerDefeated(gBattleOutcome) == TRUE)
{
SetMainCallback2(CB2_WhiteOut);
if (CurrentBattlePyramidLocation() != PYRAMID_LOCATION_NONE)
SetMainCallback2(CB2_ReturnToFieldContinueScriptPlayMapMusic);
else
SetMainCallback2(CB2_WhiteOut);
}
else
{
@ -526,6 +614,7 @@ static void CB2_EndMarowakBattle(void)
{
CpuFill16(0, (void *)BG_PLTT, BG_PLTT_SIZE);
ResetOamRange(0, 128);
if (IsPlayerDefeated(gBattleOutcome))
{
SetMainCallback2(CB2_WhiteOut);
@ -542,12 +631,12 @@ static void CB2_EndMarowakBattle(void)
}
}
u8 BattleSetup_GetEnvironmentId(void)
enum BattleEnvironments BattleSetup_GetEnvironmentId(void)
{
u16 tileBehavior;
s16 x, y;
if (I_FISHING_ENVIRONMENT >= GEN_4 && gIsFishingEncounter)
if (ShouldUseFishingEnvironmentInBattle())
GetXYCoordsOneStepInFrontOfPlayer(&x, &y);
else
PlayerGetDestCoords(&x, &y);
@ -593,13 +682,17 @@ u8 BattleSetup_GetEnvironmentId(void)
{
if (MetatileBehavior_GetBridgeType(tileBehavior))
return BATTLE_ENVIRONMENT_POND;
if (MetatileBehavior_IsBridge(tileBehavior) == TRUE)
return BATTLE_ENVIRONMENT_WATER;
}
if (GetSavedWeather() == WEATHER_SANDSTORM)
return BATTLE_ENVIRONMENT_SAND;
return BATTLE_ENVIRONMENT_PLAIN;
}
static u8 GetBattleTransitionTypeByMap(void)
static enum TransitionType GetBattleTransitionTypeByMap(void)
{
u16 tileBehavior;
s16 x, y;
@ -662,7 +755,7 @@ static u8 GetSumOfEnemyPartyLevel(u16 opponentId, u8 numMons)
return sum;
}
u8 GetWildBattleTransition(void)
enum BattleTransition GetWildBattleTransition(void)
{
u8 transitionType = GetBattleTransitionTypeByMap();
u8 enemyLevel = GetMonData(&gEnemyParty[0], MON_DATA_LEVEL);
@ -670,25 +763,42 @@ u8 GetWildBattleTransition(void)
if (enemyLevel < playerLevel)
{
return sBattleTransitionTable_Wild[transitionType][0];
if (CurrentBattlePyramidLocation() != PYRAMID_LOCATION_NONE)
return B_TRANSITION_BLUR;
else
return sBattleTransitionTable_Wild[transitionType][0];
}
else
{
return sBattleTransitionTable_Wild[transitionType][1];
if (CurrentBattlePyramidLocation() != PYRAMID_LOCATION_NONE)
return B_TRANSITION_GRID_SQUARES;
else
return sBattleTransitionTable_Wild[transitionType][1];
}
}
u8 GetTrainerBattleTransition(void)
enum BattleTransition GetTrainerBattleTransition(void)
{
u8 minPartyCount = 1;
u8 transitionType;
u8 enemyLevel;
u8 playerLevel;
u32 trainerId = SanitizeTrainerId(TRAINER_BATTLE_PARAM.opponentA);
enum TrainerClassID trainerClass = GetTrainerClassFromId(TRAINER_BATTLE_PARAM.opponentA);
if (DoesTrainerHaveMugshot(trainerId))
return B_TRANSITION_MUGSHOT;
if (trainerClass == TRAINER_CLASS_TEAM_MAGMA
|| trainerClass == TRAINER_CLASS_MAGMA_LEADER
|| trainerClass == TRAINER_CLASS_MAGMA_ADMIN)
return B_TRANSITION_MAGMA;
if (trainerClass == TRAINER_CLASS_TEAM_AQUA
|| trainerClass == TRAINER_CLASS_AQUA_LEADER
|| trainerClass == TRAINER_CLASS_AQUA_ADMIN)
return B_TRANSITION_AQUA;
switch (GetTrainerBattleType(trainerId))
{
case TRAINER_BATTLE_TYPE_SINGLES:
@ -709,21 +819,56 @@ u8 GetTrainerBattleTransition(void)
return sBattleTransitionTable_Trainer[transitionType][1];
}
// TODO: transitions
u8 GetSpecialBattleTransition(s32 id)
{
return B_TRANSITION_POKEBALLS_TRAIL;
}
u8 BattleSetup_GetBattleTowerBattleTransition(void)
#define RANDOM_TRANSITION(table) (table[Random() % ARRAY_COUNT(table)])
enum BattleTransition GetSpecialBattleTransition(enum BattleTransitionGroup id)
{
u16 var;
u8 enemyLevel = GetMonData(&gEnemyParty[0], MON_DATA_LEVEL);
u8 playerLevel = GetSumOfPlayerPartyLevel(1);
if (enemyLevel < playerLevel)
return B_TRANSITION_POKEBALLS_TRAIL;
{
switch (id)
{
case B_TRANSITION_GROUP_TRAINER_TOWER:
case B_TRANSITION_GROUP_SECRET_BASE:
case B_TRANSITION_GROUP_E_READER:
return B_TRANSITION_POKEBALLS_TRAIL;
case B_TRANSITION_GROUP_B_PYRAMID:
return RANDOM_TRANSITION(sBattleTransitionTable_BattlePyramid);
case B_TRANSITION_GROUP_B_DOME:
return RANDOM_TRANSITION(sBattleTransitionTable_BattleDome);
default:
break;
}
if (VarGet(VAR_FRONTIER_BATTLE_MODE) != FRONTIER_MODE_LINK_MULTIS)
return RANDOM_TRANSITION(sBattleTransitionTable_BattleFrontier);
}
else
return B_TRANSITION_BIG_POKEBALL;
{
switch (id)
{
case B_TRANSITION_GROUP_TRAINER_TOWER:
case B_TRANSITION_GROUP_SECRET_BASE:
case B_TRANSITION_GROUP_E_READER:
return B_TRANSITION_BIG_POKEBALL;
case B_TRANSITION_GROUP_B_PYRAMID:
return RANDOM_TRANSITION(sBattleTransitionTable_BattlePyramid);
case B_TRANSITION_GROUP_B_DOME:
return RANDOM_TRANSITION(sBattleTransitionTable_BattleDome);
default:
break;
}
if (VarGet(VAR_FRONTIER_BATTLE_MODE) != FRONTIER_MODE_LINK_MULTIS)
return RANDOM_TRANSITION(sBattleTransitionTable_BattleFrontier);
}
var = gSaveBlock2Ptr->frontier.trainerIds[gSaveBlock2Ptr->frontier.curChallengeBattleNum * 2 + 0]
+ gSaveBlock2Ptr->frontier.trainerIds[gSaveBlock2Ptr->frontier.curChallengeBattleNum * 2 + 1];
return sBattleTransitionTable_BattleFrontier[var % ARRAY_COUNT(sBattleTransitionTable_BattleFrontier)];
}
static u16 GetTrainerAFlag(void)
@ -812,7 +957,7 @@ void TrainerBattleLoadArgsSecondTrainer(const u8 *data)
void SetMapVarsToTrainerA(void)
{
if (TRAINER_BATTLE_PARAM.objEventLocalIdA != 0)
if (TRAINER_BATTLE_PARAM.objEventLocalIdA != LOCALID_NONE)
{
gSpecialVar_LastTalked = TRAINER_BATTLE_PARAM.objEventLocalIdA;
gSelectedObjectEvent = GetObjectEventIdByLocalIdAndMap(TRAINER_BATTLE_PARAM.objEventLocalIdA, gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup);
@ -866,8 +1011,10 @@ const u8 *BattleSetup_ConfigureTrainerBattle(const u8 *data)
case TRAINER_BATTLE_EARLY_RIVAL:
SetMapVarsToTrainerA();
return EventScript_DoNoIntroTrainerBattle;
case TRAINER_BATTLE_SET_TRAINERS_FOR_MULTI_BATTLE:
return sTrainerBattleEndScript;
case TRAINER_BATTLE_TWO_TRAINERS_NO_INTRO:
gNoOfApproachingTrainers = 2; // set TWO_OPPONENTS gBattleTypeFlags
gApproachingTrainerId = 1; // prevent trainer approach
return EventScript_DoNoIntroTrainerBattle;
default:
if (gApproachingTrainerId == 0)
{
@ -883,28 +1030,17 @@ const u8* BattleSetup_ConfigureFacilityTrainerBattle(u8 facility, const u8* scri
switch (facility)
{
// case FACILITY_BATTLE_PYRAMID:
// if (gApproachingTrainerId == 0)
// {
// SetMapVarsToTrainerA();
// TRAINER_BATTLE_PARAM.opponentA = LocalIdToPyramidTrainerId(gSpecialVar_LastTalked);
// }
// else
// {
// TRAINER_BATTLE_PARAM.opponentB = LocalIdToPyramidTrainerId(gSpecialVar_LastTalked);
// }
// return EventScript_TryDoNormalTrainerBattle;
// case FACILITY_BATTLE_TRAINER_HILL:
// if (gApproachingTrainerId == 0)
// {
// SetMapVarsToTrainerA();
// TRAINER_BATTLE_PARAM.opponentA = LocalIdToHillTrainerId(gSpecialVar_LastTalked);
// }
// else
// {
// TRAINER_BATTLE_PARAM.opponentB = LocalIdToHillTrainerId(gSpecialVar_LastTalked);
// }
// return EventScript_TryDoNormalTrainerBattle;
case FACILITY_BATTLE_PYRAMID:
if (gApproachingTrainerId == 0)
{
SetMapVarsToTrainerA();
TRAINER_BATTLE_PARAM.opponentA = LocalIdToPyramidTrainerId(gSpecialVar_LastTalked);
}
else
{
TRAINER_BATTLE_PARAM.opponentB = LocalIdToPyramidTrainerId(gSpecialVar_LastTalked);
}
return EventScript_TryDoNormalTrainerBattle;
default:
return sTrainerBattleEndScript;
}
@ -950,7 +1086,7 @@ bool32 GetTrainerFlagFromScriptPointer(const u8 *data)
// Set trainer's movement type so they stop and remain facing that direction
// Note: Only for trainers who are spoken to directly
// For trainers who spot the player this is handled by PlayerFaceApproachingTrainer
void SetUpTrainerMovement(void)
void SetTrainerFacingDirection(void)
{
struct ObjectEvent *objectEvent = &gObjectEvents[gSelectedObjectEvent];
SetTrainerMovementType(objectEvent, GetTrainerFacingDirectionMovementType(objectEvent->facingDirection));
@ -966,9 +1102,12 @@ u16 GetRivalBattleFlags(void)
return TRAINER_BATTLE_PARAM.rivalBattleFlags;
}
u16 Script_HasTrainerBeenFought(void)
bool8 GetTrainerFlag(void)
{
return FlagGet(GetTrainerAFlag());
if (CurrentBattlePyramidLocation() != PYRAMID_LOCATION_NONE)
return GetBattlePyramidTrainerFlag(gSelectedObjectEvent);
else
return FlagGet(GetTrainerAFlag());
}
static void SetBattledTrainersFlags(void)
@ -1023,24 +1162,69 @@ void BattleSetup_StartTrainerBattle(void)
if (GetTrainerBattleMode() == TRAINER_BATTLE_EARLY_RIVAL && GetRivalBattleFlags() & RIVAL_BATTLE_TUTORIAL)
gBattleTypeFlags |= BATTLE_TYPE_FIRST_BATTLE;
if (CurrentBattlePyramidLocation() != PYRAMID_LOCATION_NONE)
{
VarSet(VAR_TEMP_PLAYING_PYRAMID_MUSIC, 0);
gBattleTypeFlags |= BATTLE_TYPE_PYRAMID;
if (gNoOfApproachingTrainers == 2)
{
FillFrontierTrainersParties(1);
ZeroMonData(&gEnemyParty[1]);
ZeroMonData(&gEnemyParty[2]);
ZeroMonData(&gEnemyParty[4]);
ZeroMonData(&gEnemyParty[5]);
}
else
{
FillFrontierTrainerParty(1);
ZeroMonData(&gEnemyParty[1]);
ZeroMonData(&gEnemyParty[2]);
}
MarkApproachingPyramidTrainersAsBattled();
}
else if (GetTrainerBattleType(TRAINER_BATTLE_PARAM.opponentA) == TRAINER_BATTLE_TYPE_DOUBLES)
{
gBattleTypeFlags |= BATTLE_TYPE_DOUBLE;
}
sNoOfPossibleTrainerRetScripts = gNoOfApproachingTrainers;
gNoOfApproachingTrainers = 0;
sShouldCheckTrainerBScript = FALSE;
gWhichTrainerToFaceAfterBattle = 0;
gMain.savedCallback = CB2_EndTrainerBattle;
DoTrainerBattle();
if (CurrentBattlePyramidLocation() != PYRAMID_LOCATION_NONE)
DoBattlePyramidTrainerHillBattle();
else
DoTrainerBattle();
ScriptContext_Stop();
}
static void CB2_EndDebugBattle(void)
{
if (gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER)
{
for (u32 i = 0; i < 3; i++)
{
u16 monId = gSaveBlock2Ptr->frontier.selectedPartyMons[i] - 1;
if (monId < PARTY_SIZE)
SavePlayerPartyMon(gSaveBlock2Ptr->frontier.selectedPartyMons[i] - 1, &gPlayerParty[i]);
}
LoadPlayerParty();
}
SetMainCallback2(CB2_EndTrainerBattle);
}
void BattleSetup_StartTrainerBattle_Debug(void)
{
sNoOfPossibleTrainerRetScripts = gNoOfApproachingTrainers;
gNoOfApproachingTrainers = 0;
sShouldCheckTrainerBScript = FALSE;
gWhichTrainerToFaceAfterBattle = 0;
gMain.savedCallback = CB2_EndTrainerBattle;
gMain.savedCallback = CB2_EndDebugBattle;
CreateBattleStartTask_Debug(GetWildBattleTransition(), 0);
@ -1055,7 +1239,7 @@ static void SaveChangesToPlayerParty(void)
{
if ((participatedPokemon >> i & 1) == 1)
{
gSaveBlock1Ptr->playerParty[i] = gPlayerParty[j];
SavePlayerPartyMon(i, &gPlayerParty[j]);
j++;
}
}
@ -1098,42 +1282,38 @@ static void CB2_EndTrainerBattle(void)
SetMainCallback2(CB2_WhiteOut);
return;
}
SetMainCallback2(CB2_ReturnToFieldContinueScriptPlayMapMusic);
SetBattledTrainerFlag();
QuestLogEvents_HandleEndTrainerBattle();
}
else
{
gSpecialVar_Result = FALSE;
DowngradeBadPoison();
SetMainCallback2(CB2_ReturnToFieldContinueScriptPlayMapMusic);
SetBattledTrainerFlag();
QuestLogEvents_HandleEndTrainerBattle();
}
DowngradeBadPoison();
SetMainCallback2(CB2_ReturnToFieldContinueScriptPlayMapMusic);
SetBattledTrainerFlag();
QuestLogEvents_HandleEndTrainerBattle();
}
else if (TRAINER_BATTLE_PARAM.opponentA == TRAINER_SECRET_BASE)
{
DowngradeBadPoison();
SetMainCallback2(CB2_ReturnToFieldContinueScriptPlayMapMusic);
}
else if (IsPlayerDefeated(gBattleOutcome) == TRUE)
{
if (CurrentBattlePyramidLocation() != PYRAMID_LOCATION_NONE || (!NoAliveMonsForPlayer()) || FlagGet(B_FLAG_NO_WHITEOUT))
SetMainCallback2(CB2_ReturnToFieldContinueScriptPlayMapMusic);
else
SetMainCallback2(CB2_WhiteOut);
}
else if (DidPlayerForfeitNormalTrainerBattle())
{
SetMainCallback2(CB2_WhiteOut);
}
else
{
if (TRAINER_BATTLE_PARAM.opponentA == TRAINER_SECRET_BASE)
SetMainCallback2(CB2_ReturnToFieldContinueScriptPlayMapMusic);
DowngradeBadPoison();
if (CurrentBattlePyramidLocation() == PYRAMID_LOCATION_NONE)
{
DowngradeBadPoison();
SetMainCallback2(CB2_ReturnToFieldContinueScriptPlayMapMusic);
}
else if (IsPlayerDefeated(gBattleOutcome) == TRUE)
{
// if (InBattlePyramid() || InTrainerHillChallenge() || (!NoAliveMonsForPlayer()) || FlagGet(B_FLAG_NO_WHITEOUT))
// SetMainCallback2(CB2_ReturnToFieldContinueScriptPlayMapMusic);
// else
SetMainCallback2(CB2_WhiteOut);
}
// else if (DidPlayerForfeitNormalTrainerBattle())
// {
// SetMainCallback2(CB2_WhiteOut);
// }
else
{
SetMainCallback2(CB2_ReturnToFieldContinueScriptPlayMapMusic);
DowngradeBadPoison();
SetBattledTrainersFlags();
QuestLogEvents_HandleEndTrainerBattle();
}
@ -1173,7 +1353,19 @@ void BattleSetup_StartRematchBattle(void)
void ShowTrainerIntroSpeech(void)
{
ShowFieldMessage(GetIntroSpeechOfApproachingTrainer());
if (CurrentBattlePyramidLocation() != PYRAMID_LOCATION_NONE)
{
if (gNoOfApproachingTrainers == 0 || gNoOfApproachingTrainers == 1)
CopyPyramidTrainerSpeechBefore(LocalIdToPyramidTrainerId(gSpecialVar_LastTalked));
else
CopyPyramidTrainerSpeechBefore(LocalIdToPyramidTrainerId(gObjectEvents[gApproachingTrainers[gApproachingTrainerId].objectEventId].localId));
ShowFieldMessageFromBuffer();
}
else
{
ShowFieldMessage(GetIntroSpeechOfApproachingTrainer());
}
}
const u8 *BattleSetup_GetScriptAddrAfterBattle(void)
@ -1204,7 +1396,7 @@ const u8 *BattleSetup_GetTrainerPostBattleScript(void)
}
}
return EventScript_TestSignpostMsg;
return EventScript_TryGetTrainerScript;
}
void ShowTrainerCantBattleSpeech(void)
@ -1236,8 +1428,8 @@ void PlayTrainerEncounterMusic(void)
trainerId = TRAINER_BATTLE_PARAM.opponentB;
if (!QL_IS_PLAYBACK_STATE
&& GetTrainerBattleMode() != TRAINER_BATTLE_CONTINUE_SCRIPT_NO_MUSIC
&& GetTrainerBattleMode() != TRAINER_BATTLE_CONTINUE_SCRIPT_DOUBLE_NO_MUSIC)
&& TRAINER_BATTLE_PARAM.mode != TRAINER_BATTLE_CONTINUE_SCRIPT_NO_MUSIC
&& TRAINER_BATTLE_PARAM.mode != TRAINER_BATTLE_CONTINUE_SCRIPT_DOUBLE_NO_MUSIC)
{
switch (GetTrainerEncounterMusicId(trainerId))
{
@ -1305,6 +1497,21 @@ static const u8 *GetTrainerCantBattleSpeech(void)
return ReturnEmptyStringIfNull(TRAINER_BATTLE_PARAM.cannotBattleText);
}
void ShouldTryGetTrainerScript(void)
{
if (sNoOfPossibleTrainerRetScripts > 1)
{
sNoOfPossibleTrainerRetScripts = 0;
sShouldCheckTrainerBScript = TRUE;
gSpecialVar_Result = TRUE;
}
else
{
sShouldCheckTrainerBScript = FALSE;
gSpecialVar_Result = FALSE;
}
}
u16 CountMaxPossibleRematch(u16 trainerId)
{
for (u32 i = 1; i < MAX_REMATCH_PARTIES; i++)
@ -1341,3 +1548,4 @@ void SetMultiTrainerBattle(struct ScriptContext *ctx)
TRAINER_BATTLE_PARAM.defeatTextB = (u8*)ScriptReadWord(ctx);
gPartnerTrainerId = TRAINER_PARTNER(ScriptReadHalfword(ctx));
};

View File

@ -60,7 +60,7 @@ void DoSpecialTrainerBattle(void)
CreateTask(Task_StartBattleAfterTransition, 1);
PlayMapChosenOrBattleBGM(0);
BattleTransition_StartOnField(BattleSetup_GetBattleTowerBattleTransition());
BattleTransition_StartOnField(GetSpecialBattleTransition(B_TRANSITION_GROUP_E_READER));
#endif //FREE_BATTLE_TOWER_E_READER
break;
}

View File

@ -10,12 +10,12 @@
#include "constants/moves.h"
static bool32 FirstEventBlockEvents(struct BattleCalcValues *calcValues);
static bool32 TryHazardsOnSwitchIn(u32 battler, enum Ability ability, enum HoldEffect holdEffect, enum Hazards hazardType);
static bool32 TryHazardsOnSwitchIn(enum BattlerId battler, enum Ability ability, enum HoldEffect holdEffect, enum Hazards hazardType);
static bool32 SecondEventBlockEvents(struct BattleCalcValues *calcValues);
bool32 DoSwitchInEvents(void)
{
u32 battler;
enum BattlerId battler;
struct BattleCalcValues calcValues = {0};
for (battler = 0; battler < gBattlersCount; battler++)
@ -29,7 +29,7 @@ bool32 DoSwitchInEvents(void)
switch (gBattleStruct->eventState.switchIn)
{
case SWITCH_IN_EVENTS_ORDER_BY_SPEED:
for (u32 i = 0; i < gBattlersCount; i++)
for (enum BattlerId i = 0; i < gBattlersCount; i++)
gBattlersBySpeed[i] = i;
SortBattlersBySpeed(gBattlersBySpeed, FALSE);
gBattleStruct->battlersSorted = TRUE;
@ -92,6 +92,16 @@ bool32 DoSwitchInEvents(void)
gBattleStruct->switchInBattlerCounter = 0;
gBattleStruct->eventState.switchIn++;
break;
case SWITCH_IN_EVENTS_FORM_CHANGE:
while (gBattleStruct->switchInBattlerCounter < gBattlersCount)
{
battler = gBattlersBySpeed[gBattleStruct->switchInBattlerCounter++];
if (AbilityBattleEffects(ABILITYEFFECT_SWITCH_IN_FORM_CHANGE, battler, calcValues.abilities[battler], 0, gBattleStruct->battlerState[battler].switchIn))
return TRUE;
}
gBattleStruct->switchInBattlerCounter = 0;
gBattleStruct->eventState.switchIn++;
break;
case SWITCH_IN_EVENTS_SECOND_BLOCK:
while (gBattleStruct->switchInBattlerCounter < gBattlersCount)
{
@ -120,7 +130,7 @@ bool32 DoSwitchInEvents(void)
case SWITCH_IN_EVENTS_WHITE_HERB:
while (gBattleStruct->switchInBattlerCounter < gBattlersCount)
{
u32 battler = gBattlersBySpeed[gBattleStruct->switchInBattlerCounter++];
enum BattlerId battler = gBattlersBySpeed[gBattleStruct->switchInBattlerCounter++];
if (ItemBattleEffects(battler, 0, calcValues.holdEffects[battler], IsWhiteHerbActivation))
return TRUE;
}
@ -130,7 +140,7 @@ bool32 DoSwitchInEvents(void)
case SWITCH_IN_EVENTS_OPPORTUNIST:
while (gBattleStruct->switchInBattlerCounter < gBattlersCount)
{
u32 battler = gBattlersBySpeed[gBattleStruct->switchInBattlerCounter++];
enum BattlerId battler = gBattlersBySpeed[gBattleStruct->switchInBattlerCounter++];
if (AbilityBattleEffects(ABILITYEFFECT_OPPORTUNIST, battler, calcValues.abilities[battler], 0, TRUE))
return TRUE;
}
@ -140,7 +150,7 @@ bool32 DoSwitchInEvents(void)
case SWITCH_IN_EVENTS_MIRROR_HERB:
while (gBattleStruct->switchInBattlerCounter < gBattlersCount)
{
u32 battler = gBattlersBySpeed[gBattleStruct->switchInBattlerCounter++];
enum BattlerId battler = gBattlersBySpeed[gBattleStruct->switchInBattlerCounter++];
if (ItemBattleEffects(battler, 0, GetBattlerHoldEffect(battler), IsMirrorHerbActivation))
return TRUE;
}
@ -171,7 +181,7 @@ bool32 DoSwitchInEvents(void)
return FALSE;
}
static bool32 CanBattlerBeHealed(u32 battler)
static bool32 CanBattlerBeHealed(enum BattlerId battler)
{
if (GetConfig(CONFIG_HEALING_WISH_SWITCH) < GEN_8)
return TRUE;
@ -194,7 +204,7 @@ static bool32 CanBattlerBeHealed(u32 battler)
static bool32 FirstEventBlockEvents(struct BattleCalcValues *calcValues)
{
bool32 effect = FALSE;
u32 battler = calcValues->battlerAtk;
enum BattlerId battler = calcValues->battlerAtk;
switch (gBattleStruct->eventState.battlerSwitchIn)
{
@ -282,14 +292,14 @@ static bool32 FirstEventBlockEvents(struct BattleCalcValues *calcValues)
return effect;
}
static void SetDmgHazardsBattlescript(u8 battler, u8 multistringId)
static void SetDmgHazardsBattlescript(enum BattlerId battler, u8 multistringId)
{
gBattleScripting.battler = battler;
gBattleCommunication[MULTISTRING_CHOOSER] = multistringId;
BattleScriptCall(BattleScript_DmgHazardsOnBattler);
}
static bool32 TryHazardsOnSwitchIn(u32 battler, enum Ability ability, enum HoldEffect holdEffect, enum Hazards hazardType)
static bool32 TryHazardsOnSwitchIn(enum BattlerId battler, enum Ability ability, enum HoldEffect holdEffect, enum Hazards hazardType)
{
bool32 effect = FALSE;
enum BattleSide side = GetBattlerSide(battler);
@ -389,7 +399,7 @@ static bool32 TryHazardsOnSwitchIn(u32 battler, enum Ability ability, enum HoldE
static bool32 SecondEventBlockEvents(struct BattleCalcValues *calcValues)
{
bool32 effect = FALSE;
u32 battler = calcValues->battlerAtk;
enum BattlerId battler = calcValues->battlerAtk;
switch (gBattleStruct->eventState.battlerSwitchIn)
{

Some files were not shown because too many files have changed in this diff Show More