summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPikalaxALT <PikalaxALT@users.noreply.github.com>2019-11-19 10:58:44 -0500
committerGitHub <noreply@github.com>2019-11-19 10:58:44 -0500
commit89dc26755ad2818c10b37a34ed46f5c79dc571c8 (patch)
treeabd075a205c401b3a5406efb37378544e94c9190 /src
parent83cba310335678aa8ecac24b58708b3c924b581a (diff)
parent63f8834b6bc2d6413da606d7df88a304edc3c625 (diff)
Merge pull request #138 from jiangzhengwenjz/battle
battle (4th take)
Diffstat (limited to 'src')
-rw-r--r--src/battle_anim_mon_movement.c2
-rw-r--r--src/battle_anim_mons.c14
-rw-r--r--src/battle_anim_utility_funcs.c4
-rw-r--r--src/battle_controller_oak_old_man.c6
-rw-r--r--src/battle_controller_opponent.c2
-rw-r--r--src/battle_controller_player.c3
-rw-r--r--src/battle_controller_pokedude.c2739
-rw-r--r--src/battle_controllers.c12
-rw-r--r--src/battle_script_commands.c2
-rw-r--r--src/battle_setup.c2
-rw-r--r--src/bug.c14
-rw-r--r--src/electric.c1272
-rw-r--r--src/fighting.c971
-rw-r--r--src/fire.c1193
-rw-r--r--src/flying.c30
-rw-r--r--src/ghost.c12
-rw-r--r--src/ground.c8
-rw-r--r--src/ice.c1477
-rw-r--r--src/poison.c298
-rw-r--r--src/pokemon.c20
-rw-r--r--src/psychic.c22
-rw-r--r--src/quest_log.c2
-rw-r--r--src/quest_log_815A008.c (renamed from src/unk_8159F40.c)147
-rw-r--r--src/rock.c8
-rw-r--r--src/teachy_tv.c2
25 files changed, 8032 insertions, 230 deletions
diff --git a/src/battle_anim_mon_movement.c b/src/battle_anim_mon_movement.c
index 21d07246f..ffd66871c 100644
--- a/src/battle_anim_mon_movement.c
+++ b/src/battle_anim_mon_movement.c
@@ -888,7 +888,7 @@ void sub_8099BD4(u8 taskId)
gTasks[taskId].data[12] = 0;
gTasks[taskId].data[10] = gBattleAnimArgs[3];
gTasks[taskId].data[11] = gBattleAnimArgs[4];
- gTasks[taskId].data[7] = GetAnimBattlerSpriteId(1);
+ gTasks[taskId].data[7] = GetAnimBattlerSpriteId(ANIM_TARGET);
gTasks[taskId].data[8] = gSprites[gTasks[taskId].data[7]].pos2.x;
gTasks[taskId].data[9] = gSprites[gTasks[taskId].data[7]].pos2.y;
gTasks[taskId].data[0] = 0;
diff --git a/src/battle_anim_mons.c b/src/battle_anim_mons.c
index c19af4cb7..a3bd26898 100644
--- a/src/battle_anim_mons.c
+++ b/src/battle_anim_mons.c
@@ -1393,7 +1393,7 @@ void TranslateAnimSpriteToTargetMonLocation(struct Sprite *sprite)
void AnimThrowProjectile(struct Sprite *sprite)
{
InitSpritePosToAnimAttacker(sprite, 1);
- if (GetBattlerSide(gBattleAnimAttacker))
+ if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER)
gBattleAnimArgs[2] = -gBattleAnimArgs[2];
sprite->data[0] = gBattleAnimArgs[4];
sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X_2) + gBattleAnimArgs[2];
@@ -1409,7 +1409,7 @@ static void AnimThrowProjectile_Step(struct Sprite *sprite)
DestroyAnimSprite(sprite);
}
-void sub_8075F0C(struct Sprite *sprite)
+void AnimSnoreZ(struct Sprite *sprite)
{
bool8 r4;
u8 battlerId, coordType;
@@ -1434,7 +1434,7 @@ void sub_8075F0C(struct Sprite *sprite)
InitSpritePosToAnimTarget(sprite, r4);
battlerId = gBattleAnimTarget;
}
- if (GetBattlerSide(gBattleAnimAttacker))
+ if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER)
gBattleAnimArgs[2] = -gBattleAnimArgs[2];
InitSpritePosToAnimTarget(sprite, r4);
sprite->data[0] = gBattleAnimArgs[4];
@@ -2070,7 +2070,7 @@ u8 sub_8076E34(s32 battlerId, u8 spriteId, s32 species)
void sub_8076ED8(struct Sprite *sprite)
{
SetSpriteCoordsToAnimAttackerCoords(sprite);
- if (GetBattlerSide(gBattleAnimAttacker))
+ if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER)
{
sprite->pos1.x -= gBattleAnimArgs[0];
gBattleAnimArgs[3] = -gBattleAnimArgs[3];
@@ -2113,7 +2113,7 @@ void sub_8076F58(struct Sprite *sprite)
void sub_8076FD0(struct Sprite *sprite)
{
SetSpriteCoordsToAnimAttackerCoords(sprite);
- if (GetBattlerSide(gBattleAnimAttacker))
+ if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER)
sprite->pos1.x -= gBattleAnimArgs[0];
else
sprite->pos1.x += gBattleAnimArgs[0];
@@ -2210,7 +2210,7 @@ void sub_807729C(struct Sprite *sprite)
{
sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X_2);
sprite->pos1.y = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y_PIC_OFFSET);
- if (!GetBattlerSide(gBattleAnimAttacker))
+ if (GetBattlerSide(gBattleAnimAttacker) == B_SIDE_PLAYER)
sprite->data[0] = 5;
else
sprite->data[0] = -10;
@@ -2237,7 +2237,7 @@ void sub_8077350(struct Sprite *sprite)
sprite->data[0] = gBattleAnimArgs[2];
sprite->data[2] = sprite->pos1.x + gBattleAnimArgs[4];
sprite->data[4] = sprite->pos1.y + gBattleAnimArgs[5];
- if (!GetBattlerSide(gBattleAnimTarget))
+ if (GetBattlerSide(gBattleAnimTarget) == B_SIDE_PLAYER)
{
x = (u16)gBattleAnimArgs[4] + 30;
sprite->pos1.x += x;
diff --git a/src/battle_anim_utility_funcs.c b/src/battle_anim_utility_funcs.c
index 14c5ef6c8..d9a6754c7 100644
--- a/src/battle_anim_utility_funcs.c
+++ b/src/battle_anim_utility_funcs.c
@@ -309,7 +309,7 @@ void sub_80BACEC(u8 taskId)
species = GetMonData(&gEnemyParty[gBattlerPartyIndexes[gBattleAnimAttacker]], MON_DATA_SPECIES);
else
species = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gBattleAnimAttacker]], MON_DATA_SPECIES);
- spriteId = GetAnimBattlerSpriteId(0);
+ spriteId = GetAnimBattlerSpriteId(ANIM_ATTACKER);
newSpriteId = sub_8076E34(gBattleAnimAttacker, spriteId, species);
sub_80752A0(&animBgData);
AnimLoadCompressedBgTilemap(animBgData.bgId, gFile_graphics_battle_anims_masks_curse_tilemap);
@@ -354,7 +354,7 @@ static void sub_80BAF38(u8 taskId)
SetGpuReg(REG_OFFSET_DISPCNT, GetGpuReg(REG_OFFSET_DISPCNT) ^ DISPCNT_OBJWIN_ON);
SetGpuReg(REG_OFFSET_BLDCNT, 0);
SetGpuReg(REG_OFFSET_BLDALPHA, 0);
- sprite = &gSprites[GetAnimBattlerSpriteId(0)]; // unused
+ sprite = &gSprites[GetAnimBattlerSpriteId(ANIM_ATTACKER)]; // unused
sprite = &gSprites[gTasks[taskId].data[0]];
DestroySprite(sprite);
sub_80752A0(&animBgData);
diff --git a/src/battle_controller_oak_old_man.c b/src/battle_controller_oak_old_man.c
index 99391ab3e..a6730cbbb 100644
--- a/src/battle_controller_oak_old_man.c
+++ b/src/battle_controller_oak_old_man.c
@@ -181,7 +181,7 @@ static void OakOldManBufferRunCommand(void)
{
if (gBattleControllerExecFlags & gBitTable[gActiveBattler])
{
- if (gBattleBufferA[gActiveBattler][0] < ARRAY_COUNT(sOakOldManBufferCommands))
+ if (gBattleBufferA[gActiveBattler][0] < NELEMS(sOakOldManBufferCommands))
sOakOldManBufferCommands[gBattleBufferA[gActiveBattler][0]]();
else
OakOldManBufferExecCompleted();
@@ -463,7 +463,7 @@ static void sub_80E7CD8(void)
static void Task_GiveExpToMon(u8 taskId)
{
- u32 monId = (u8)(gTasks[taskId].tExpTask_monId);
+ u32 monId = (u8)gTasks[taskId].tExpTask_monId;
u8 battlerId = gTasks[taskId].tExpTask_battler;
s16 gainedExp = gTasks[taskId].tExpTask_gainedExp;
@@ -487,7 +487,7 @@ static void Task_GiveExpToMon(u8 taskId)
BtlController_EmitTwoReturnValues(1, RET_VALUE_LEVELED_UP, gainedExp);
gActiveBattler = savedActiveBattler;
if (IsDoubleBattle() == TRUE
- && ((u16)(monId) == gBattlerPartyIndexes[battlerId] || (u16)(monId) == gBattlerPartyIndexes[battlerId ^ BIT_FLANK]))
+ && ((u16)monId == gBattlerPartyIndexes[battlerId] || (u16)monId == gBattlerPartyIndexes[battlerId ^ BIT_FLANK]))
gTasks[taskId].func = Task_LaunchLvlUpAnim;
else
gTasks[taskId].func = DestroyExpTaskAndCompleteOnInactiveTextPrinter;
diff --git a/src/battle_controller_opponent.c b/src/battle_controller_opponent.c
index a9173f1a9..3cb6d1432 100644
--- a/src/battle_controller_opponent.c
+++ b/src/battle_controller_opponent.c
@@ -1497,7 +1497,7 @@ static void OpponentHandleStatusIconUpdate(void)
UpdateHealthboxAttribute(gHealthboxSpriteIds[gActiveBattler], &gEnemyParty[gBattlerPartyIndexes[gActiveBattler]], HEALTHBOX_STATUS_ICON);
battlerId = gActiveBattler;
- gBattleSpritesDataPtr->healthBoxesData[battlerId].statusAnimActive = 0;
+ gBattleSpritesDataPtr->healthBoxesData[battlerId].statusAnimActive = FALSE;
gBattlerControllerFuncs[gActiveBattler] = CompleteOnFinishedStatusAnimation;
}
}
diff --git a/src/battle_controller_player.c b/src/battle_controller_player.c
index f8d5958ba..16bf1ec87 100644
--- a/src/battle_controller_player.c
+++ b/src/battle_controller_player.c
@@ -1003,7 +1003,6 @@ static void CompleteOnHealthbarDone(void)
s16 hpValue = MoveBattleBar(gActiveBattler, gHealthboxSpriteIds[gActiveBattler], HEALTH_BAR, 0);
SetHealthboxSpriteVisible(gHealthboxSpriteIds[gActiveBattler]);
-
if (hpValue != -1)
{
UpdateHpTextInHealthbox(gHealthboxSpriteIds[gActiveBattler], hpValue, HP_CURRENT);
@@ -2544,7 +2543,7 @@ static void PlayerHandleStatusIconUpdate(void)
UpdateHealthboxAttribute(gHealthboxSpriteIds[gActiveBattler], &gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], HEALTHBOX_STATUS_ICON);
battlerId = gActiveBattler;
- gBattleSpritesDataPtr->healthBoxesData[battlerId].statusAnimActive = 0;
+ gBattleSpritesDataPtr->healthBoxesData[battlerId].statusAnimActive = FALSE;
gBattlerControllerFuncs[gActiveBattler] = CompleteOnFinishedStatusAnimation;
}
}
diff --git a/src/battle_controller_pokedude.c b/src/battle_controller_pokedude.c
new file mode 100644
index 000000000..57a405f3c
--- /dev/null
+++ b/src/battle_controller_pokedude.c
@@ -0,0 +1,2739 @@
+#include "global.h"
+#include "task.h"
+#include "pokemon.h"
+#include "party_menu.h"
+#include "pokeball.h"
+#include "bg.h"
+#include "data.h"
+#include "palette.h"
+#include "util.h"
+#include "m4a.h"
+#include "link.h"
+#include "sound.h"
+#include "event_data.h"
+#include "item.h"
+#include "item_menu.h"
+#include "text.h"
+#include "strings.h"
+#include "string_util.h"
+#include "window.h"
+#include "battle.h"
+#include "battle_anim.h"
+#include "battle_controllers.h"
+#include "battle_interface.h"
+#include "battle_message.h"
+#include "reshow_battle_screen.h"
+#include "constants/songs.h"
+#include "constants/items.h"
+#include "constants/moves.h"
+#include "constants/pokemon.h"
+#include "constants/trainers.h"
+
+struct Unk_84790E8
+{
+ u8 unk_0;
+ u8 unk_1;
+ u16 unk_2;
+ void (*unk_4)(void);
+};
+
+struct PokedudeBattlePartyInfo
+{
+ u8 side;
+ u8 level;
+ u16 species;
+ u16 moves[4];
+ u8 nature;
+ u8 gender;
+};
+
+static void PokedudeHandleGetMonData(void);
+static void PokedudeHandleGetRawMonData(void);
+static void PokedudeHandleSetMonData(void);
+static void PokedudeHandleSetRawMonData(void);
+static void PokedudeHandleLoadMonSprite(void);
+static void PokedudeHandleSwitchInAnim(void);
+static void PokedudeHandleReturnMonToBall(void);
+static void PokedudeHandleDrawTrainerPic(void);
+static void PokedudeHandleTrainerSlide(void);
+static void PokedudeHandleTrainerSlideBack(void);
+static void PokedudeHandleFaintAnimation(void);
+static void PokedudeHandlePaletteFade(void);
+static void PokedudeHandleSuccessBallThrowAnim(void);
+static void PokedudeHandleBallThrowAnim(void);
+static void PokedudeHandlePause(void);
+static void PokedudeHandleMoveAnimation(void);
+static void PokedudeHandlePrintString(void);
+static void PokedudeHandlePrintSelectionString(void);
+static void PokedudeHandleChooseAction(void);
+static void PokedudeHandleUnknownYesNoBox(void);
+static void PokedudeHandleChooseMove(void);
+static void PokedudeHandleChooseItem(void);
+static void PokedudeHandleChoosePokemon(void);
+static void PokedudeHandleCmd23(void);
+static void PokedudeHandleHealthBarUpdate(void);
+static void PokedudeHandleExpUpdate(void);
+static void PokedudeHandleStatusIconUpdate(void);
+static void PokedudeHandleStatusAnimation(void);
+static void PokedudeHandleStatusXor(void);
+static void PokedudeHandleDataTransfer(void);
+static void PokedudeHandleDMA3Transfer(void);
+static void PokedudeHandlePlayBGM(void);
+static void PokedudeHandleCmd32(void);
+static void PokedudeHandleTwoReturnValues(void);
+static void PokedudeHandleChosenMonReturnValue(void);
+static void PokedudeHandleOneReturnValue(void);
+static void PokedudeHandleOneReturnValue_Duplicate(void);
+static void PokedudeHandleCmd37(void);
+static void PokedudeHandleCmd38(void);
+static void PokedudeHandleCmd39(void);
+static void PokedudeHandleCmd40(void);
+static void PokedudeHandleHitAnimation(void);
+static void PokedudeHandleCmd42(void);
+static void PokedudeHandlePlaySE(void);
+static void PokedudeHandlePlayFanfare(void);
+static void PokedudeHandleFaintingCry(void);
+static void PokedudeHandleIntroSlide(void);
+static void PokedudeHandleIntroTrainerBallThrow(void);
+static void PokedudeHandleDrawPartyStatusSummary(void);
+static void PokedudeHandleHidePartyStatusSummary(void);
+static void PokedudeHandleEndBounceEffect(void);
+static void PokedudeHandleSpriteInvisibility(void);
+static void PokedudeHandleBattleAnimation(void);
+static void PokedudeHandleLinkStandbyMsg(void);
+static void PokedudeHandleResetActionMoveSelection(void);
+static void PokedudeHandleCmd55(void);
+static void PokedudeCmdEnd(void);
+
+static void sub_8159BA8(void);
+static void sub_8159D04(void);
+static void PokedudeBufferExecCompleted(void);
+static void sub_8159824(void);
+static void PokedudeBufferRunCommand(void);
+static bool8 sub_8159AB8(void);
+static void sub_8159998(void);
+static void WaitForMonSelection(void);
+static void CompleteWhenChoseItem(void);
+static void sub_81567B0(void);
+static void Task_LaunchLvlUpAnim(u8 taskId);
+static void DestroyExpTaskAndCompleteOnInactiveTextPrinter(u8 taskId);
+static void CompleteOnInactiveTextPrinter2(void);
+static void Task_PrepareToGiveExpWithExpBar(u8 taskId);
+static void sub_8156B24(u8 taskId);
+static void Task_UpdateLvlInHealthbox(u8 taskId);
+static u32 CopyPokedudeMonData(u8 monId, u8 *dst);
+static void SetPokedudeMonData(u8 monId);
+static void sub_8159478(u8 battlerId);
+static void PokedudeDoMoveAnimation(void);
+static void sub_81595EC(u8 taskId);
+static const u8 *sub_8159EF0(void);
+
+u8 *gUnknown_3005EE0[MAX_BATTLERS_COUNT];
+
+static void (*const sPokedudeBufferCommands[CONTROLLER_CMDS_COUNT])(void) =
+{
+ PokedudeHandleGetMonData,
+ PokedudeHandleGetRawMonData,
+ PokedudeHandleSetMonData,
+ PokedudeHandleSetRawMonData,
+ PokedudeHandleLoadMonSprite,
+ PokedudeHandleSwitchInAnim,
+ PokedudeHandleReturnMonToBall,
+ PokedudeHandleDrawTrainerPic,
+ PokedudeHandleTrainerSlide,
+ PokedudeHandleTrainerSlideBack,
+ PokedudeHandleFaintAnimation,
+ PokedudeHandlePaletteFade,
+ PokedudeHandleSuccessBallThrowAnim,
+ PokedudeHandleBallThrowAnim,
+ PokedudeHandlePause,
+ PokedudeHandleMoveAnimation,
+ PokedudeHandlePrintString,
+ PokedudeHandlePrintSelectionString,
+ PokedudeHandleChooseAction,
+ PokedudeHandleUnknownYesNoBox,
+ PokedudeHandleChooseMove,
+ PokedudeHandleChooseItem,
+ PokedudeHandleChoosePokemon,
+ PokedudeHandleCmd23,
+ PokedudeHandleHealthBarUpdate,
+ PokedudeHandleExpUpdate,
+ PokedudeHandleStatusIconUpdate,
+ PokedudeHandleStatusAnimation,
+ PokedudeHandleStatusXor,
+ PokedudeHandleDataTransfer,
+ PokedudeHandleDMA3Transfer,
+ PokedudeHandlePlayBGM,
+ PokedudeHandleCmd32,
+ PokedudeHandleTwoReturnValues,
+ PokedudeHandleChosenMonReturnValue,
+ PokedudeHandleOneReturnValue,
+ PokedudeHandleOneReturnValue_Duplicate,
+ PokedudeHandleCmd37,
+ PokedudeHandleCmd38,
+ PokedudeHandleCmd39,
+ PokedudeHandleCmd40,
+ PokedudeHandleHitAnimation,
+ PokedudeHandleCmd42,
+ PokedudeHandlePlaySE,
+ PokedudeHandlePlayFanfare,
+ PokedudeHandleFaintingCry,
+ PokedudeHandleIntroSlide,
+ PokedudeHandleIntroTrainerBallThrow,
+ PokedudeHandleDrawPartyStatusSummary,
+ PokedudeHandleHidePartyStatusSummary,
+ PokedudeHandleEndBounceEffect,
+ PokedudeHandleSpriteInvisibility,
+ PokedudeHandleBattleAnimation,
+ PokedudeHandleLinkStandbyMsg,
+ PokedudeHandleResetActionMoveSelection,
+ PokedudeHandleCmd55,
+ PokedudeCmdEnd,
+};
+
+// not used
+static const u8 gUnknown_8479000[] = { 0x48, 0x48, 0x20, 0x5a, 0x50, 0x50, 0x50, 0x58 };
+
+static const u8 gUnknown_8479008[][8] =
+{
+ { 0, 0, 0, 0, 64, 0, 0, 0 },
+ { 4, 4, 0, 0, 0, 0, 0, 0 },
+};
+
+static const u8 gUnknown_8479018[][8] =
+{
+ { 0, 0, 0, 0, 64, 0, 0, 0 },
+ { 1, 0, 0, 0, 64, 0, 0, 0 },
+ { 0, 0, 0, 0, 64, 0, 0, 0 },
+};
+
+static const u8 gUnknown_8479030[][8] =
+{
+ { 0, 0, 0, 0, 64, 0, 0, 0 },
+ { 2, 0, 0, 0, 64, 0, 0, 0 },
+ { 0, 0, 0, 0, 64, 0, 0, 0 },
+};
+
+static const u8 gUnknown_8479048[][8] =
+{
+ { 0, 0, 0, 0, 64, 0, 0, 0 },
+ { 0, 0, 0, 0, 64, 0, 0, 0 },
+ { 1, 0, 0, 0, 64, 0, 0, 0 },
+};
+
+static const u8 (*const gUnknown_8479060[])[8] =
+{
+ gUnknown_8479008,
+ gUnknown_8479018,
+ gUnknown_8479030,
+ gUnknown_8479048,
+};
+
+static const u8 gUnknown_8479070[][8] =
+{
+ { 2, 2, 0, 0, 64, 0, 0, 0 },
+ { 255, 255, 0, 0, 0, 0, 0, 0 },
+};
+
+static const u8 gUnknown_8479080[][8] =
+{
+ { 2, 2, 0, 0, 64, 0, 0, 0 },
+ { 2, 0, 0, 0, 64, 0, 0, 0 },
+ { 2, 0, 0, 0, 64, 0, 0, 0 },
+ { 255, 255, 0, 0, 0, 0, 0, 0 },
+};
+
+static const u8 gUnknown_84790A0[][8] =
+{
+ { 2, 0, 0, 0, 64, 0, 0, 0 },
+ { 0, 0, 0, 0, 64, 0, 0, 0 },
+ { 0, 0, 0, 0, 64, 0, 0, 0 },
+ { 255, 255, 0, 0, 0, 0, 0, 0 },
+};
+
+static const u8 gUnknown_84790C0[][8] =
+{
+ { 0, 2, 0, 0, 64, 0, 0, 0 },
+ { 2, 2, 0, 0, 64, 0, 0, 0 },
+ { 255, 255, 0, 0, 0, 0, 0, 0 },
+};
+
+static const u8 (*const gUnknown_84790D8[])[8] =
+{
+ gUnknown_8479070,
+ gUnknown_8479080,
+ gUnknown_84790A0,
+ gUnknown_84790C0,
+};
+
+static const struct Unk_84790E8 gUnknown_84790E8[] =
+{
+ {
+ .unk_0 = 18,
+ .unk_1 = 0,
+ .unk_2 = 0,
+ .unk_4 = sub_8159BA8,
+ },
+ {
+ .unk_0 = 16,
+ .unk_1 = 1,
+ .unk_2 = 4,
+ .unk_4 = sub_8159BA8,
+ },
+ {
+ .unk_0 = 18,
+ .unk_1 = 0,
+ .unk_2 = 0,
+ .unk_4 = sub_8159BA8,
+ },
+ {
+ .unk_0 = 16,
+ .unk_1 = 0,
+ .unk_2 = 13,
+ .unk_4 = sub_8159BA8,
+ },
+};
+
+static const struct Unk_84790E8 gUnknown_8479108[] =
+{
+ {
+ .unk_0 = 18,
+ .unk_1 = 0,
+ .unk_2 = 0,
+ .unk_4 = NULL,
+ },
+ {
+ .unk_0 = 18,
+ .unk_1 = 0,
+ .unk_2 = 0,
+ .unk_4 = sub_8159D04,
+ },
+ {
+ .unk_0 = 21,
+ .unk_1 = 0,
+ .unk_2 = 0,
+ .unk_4 = sub_8159BA8,
+ },
+ {
+ .unk_0 = 16,
+ .unk_1 = 1,
+ .unk_2 = 4,
+ .unk_4 = sub_8159BA8,
+ },
+ {
+ .unk_0 = 16,
+ .unk_1 = 0,
+ .unk_2 = 13,
+ .unk_4 = sub_8159BA8,
+ },
+};
+
+static const struct Unk_84790E8 gUnknown_8479130[] =
+{
+ {
+ .unk_0 = 16,
+ .unk_1 = 1,
+ .unk_2 = 4,
+ .unk_4 = sub_8159BA8,
+ },
+ {
+ .unk_0 = 18,
+ .unk_1 = 0,
+ .unk_2 = 0,
+ .unk_4 = sub_8159BA8,
+ },
+ {
+ .unk_0 = 22,
+ .unk_1 = 0,
+ .unk_2 = 0,
+ .unk_4 = sub_8159BA8,
+ },
+ {
+ .unk_0 = 16,
+ .unk_1 = 1,
+ .unk_2 = 4,
+ .unk_4 = sub_8159BA8,
+ },
+ {
+ .unk_0 = 18,
+ .unk_1 = 0,
+ .unk_2 = 0,
+ .unk_4 = sub_8159BA8,
+ },
+ {
+ .unk_0 = 20,
+ .unk_1 = 0,
+ .unk_2 = 0,
+ .unk_4 = sub_8159BA8,
+ },
+ {
+ .unk_0 = 16,
+ .unk_1 = 0,
+ .unk_2 = 13,
+ .unk_4 = sub_8159BA8,
+ },
+};
+
+static const struct Unk_84790E8 gUnknown_8479168[] =
+{
+ {
+ .unk_0 = 18,
+ .unk_1 = 0,
+ .unk_2 = 0,
+ .unk_4 = sub_8159BA8,
+ },
+ {
+ .unk_0 = 18,
+ .unk_1 = 0,
+ .unk_2 = 0,
+ .unk_4 = NULL,
+ },
+ {
+ .unk_0 = 18,
+ .unk_1 = 0,
+ .unk_2 = 0,
+ .unk_4 = sub_8159BA8,
+ },
+ {
+ .unk_0 = 16,
+ .unk_1 = 1,
+ .unk_2 = 107,
+ .unk_4 = sub_8159BA8,
+ },
+ {
+ .unk_0 = 21,
+ .unk_1 = 0,
+ .unk_2 = 0,
+ .unk_4 = sub_8159BA8,
+ },
+ {
+ .unk_0 = 55,
+ .unk_1 = 0,
+ .unk_2 = 0,
+ .unk_4 = sub_8159BA8,
+ },
+};
+
+static const struct Unk_84790E8 *const gUnknown_8479198[] =
+{
+ gUnknown_84790E8,
+ gUnknown_8479108,
+ gUnknown_8479130,
+ gUnknown_8479168,
+};
+
+static const u8 *const gUnknown_84791A8[] =
+{
+ gUnknown_81C5F69,
+ gUnknown_81C5FA7,
+ gUnknown_81C5FDC,
+ gUnknown_81C601C,
+};
+
+static const u8 *const gUnknown_84791B8[] =
+{
+ gUnknown_81C60FA,
+ gUnknown_81C60FA,
+ gUnknown_81C615A,
+ gUnknown_81C6196,
+ gUnknown_81C61EA,
+};
+
+static const u8 *const gUnknown_84791CC[] =
+{
+ gUnknown_81C6202,
+ gUnknown_81C6301,
+ gUnknown_81C63A9,
+ gUnknown_81C63F9,
+ gUnknown_81C6446,
+ gUnknown_81C657A,
+ gUnknown_81C6637,
+};
+
+static const u8 *const gUnknown_84791E8[] =
+{
+ gUnknown_81C6645,
+ gUnknown_81C6645,
+ gUnknown_81C66CF,
+ gUnknown_81C6787,
+ gUnknown_81C684B,
+ gUnknown_81C686C,
+};
+
+static const struct PokedudeBattlePartyInfo sParties_Battle[] =
+{
+ {
+ .side = B_SIDE_PLAYER,
+ .level = 15,
+ .species = SPECIES_RATTATA,
+ .moves = { MOVE_TACKLE, MOVE_TAIL_WHIP, MOVE_HYPER_FANG, MOVE_QUICK_ATTACK },
+ .nature = NATURE_LONELY,
+ .gender = MALE,
+ },
+ {
+ .side = B_SIDE_OPPONENT,
+ .level = 18,
+ .species = SPECIES_PIDGEY,
+ .moves = { MOVE_TACKLE, MOVE_SAND_ATTACK, MOVE_GUST, MOVE_QUICK_ATTACK },
+ .nature = NATURE_NAUGHTY,
+ .gender = MALE,
+ },
+ {0xFF}
+};
+
+static const struct PokedudeBattlePartyInfo sParties_Status[] =
+{
+ {
+ .side = B_SIDE_PLAYER,
+ .level = 15,
+ .species = SPECIES_RATTATA,
+ .moves = { MOVE_TACKLE, MOVE_TAIL_WHIP, MOVE_HYPER_FANG, MOVE_QUICK_ATTACK },
+ .nature = NATURE_LONELY,
+ .gender = MALE,
+ },
+ {
+ .side = B_SIDE_OPPONENT,
+ .level = 14,
+ .species = SPECIES_ODDISH,
+ .moves = { MOVE_ABSORB, MOVE_SWEET_SCENT, MOVE_POISON_POWDER },
+ .nature = NATURE_RASH,
+ .gender = MALE,
+ },
+ {0xFF}
+};
+
+static const struct PokedudeBattlePartyInfo sParties_Matchups[] =
+{
+ {
+ .side = B_SIDE_PLAYER,
+ .level = 15,
+ .species = SPECIES_POLIWAG,
+ .moves = { MOVE_WATER_GUN, MOVE_HYPNOSIS, MOVE_BUBBLE },
+ .nature = NATURE_RASH,
+ .gender = MALE,
+ },
+ {
+ .side = B_SIDE_PLAYER,
+ .level = 15,
+ .species = SPECIES_BUTTERFREE,
+ .moves = { MOVE_CONFUSION, MOVE_POISON_POWDER, MOVE_STUN_SPORE, MOVE_SLEEP_POWDER },
+ .nature = NATURE_RASH,
+ .gender = MALE,
+ },
+ {
+ .side = B_SIDE_OPPONENT,
+ .level = 14,
+ .species = SPECIES_ODDISH,
+ .moves = { MOVE_ABSORB, MOVE_SWEET_SCENT, MOVE_POISON_POWDER },
+ .nature = NATURE_RASH,
+ .gender = MALE,
+ },
+ {0xFF}
+};
+
+static const struct PokedudeBattlePartyInfo sParties_Catching[] =
+{
+ {
+ .side = B_SIDE_PLAYER,
+ .level = 15,
+ .species = SPECIES_BUTTERFREE,
+ .moves = { MOVE_CONFUSION, MOVE_POISON_POWDER, MOVE_SLEEP_POWDER, MOVE_STUN_SPORE },
+ .nature = NATURE_RASH,
+ .gender = MALE,
+ },
+ {
+ .side = B_SIDE_OPPONENT,
+ .level = 11,
+ .species = SPECIES_JIGGLYPUFF,
+ .moves = { MOVE_SING, MOVE_DEFENSE_CURL, MOVE_POUND },
+ .nature = NATURE_CAREFUL,
+ .gender = MALE,
+ },
+ {0xFF}
+};
+
+
+static const struct PokedudeBattlePartyInfo *const sPokedudeBattlePartyPointers[] =
+{
+ sParties_Battle,
+ sParties_Status,
+ sParties_Matchups,
+ sParties_Catching,
+};
+
+static void nullsub_99(void)
+{
+}
+
+void SetControllerToPokedude(void)
+{
+ gBattlerControllerFuncs[gActiveBattler] = PokedudeBufferRunCommand;
+ *(&gBattleStruct->field_96) = gSpecialVar_0x8004;
+ gBattleStruct->field_97 = 0;
+}
+
+static void PokedudeBufferRunCommand(void)
+{
+ if (gBattleControllerExecFlags & gBitTable[gActiveBattler])
+ {
+ if (gBattleBufferA[gActiveBattler][0] < NELEMS(sPokedudeBufferCommands))
+ {
+ if (!sub_8159AB8())
+ sPokedudeBufferCommands[gBattleBufferA[gActiveBattler][0]]();
+ }
+ else
+ {
+ PokedudeBufferExecCompleted();
+ }
+ }
+}
+
+static void sub_8156140(void)
+{
+ sub_8159824();
+}
+
+static void CompleteOnBattlerSpriteCallbackDummy(void)
+{
+ if (gSprites[gBattlerSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy)
+ PokedudeBufferExecCompleted();
+}
+
+static void sub_8156184(void)
+{
+ if (gSprites[gBattlerSpriteIds[gActiveBattler]].animEnded == TRUE
+ && gSprites[gBattlerSpriteIds[gActiveBattler]].pos2.x == 0)
+ {
+ if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].flag_x80)
+ {
+ sub_80F1720(gActiveBattler, &gEnemyParty[gBattlerPartyIndexes[gActiveBattler]]);
+ }
+ else if (gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].field_1_x1)
+ {
+ gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].flag_x80 = 0;
+ gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].field_1_x1 = 0;
+ FreeSpriteTilesByTag(0x27F9);
+ FreeSpritePaletteByTag(0x27F9);
+ PokedudeBufferExecCompleted();
+ }
+ }
+}
+
+static void CompleteOnInactiveTextPrinter(void)
+{
+ if (!IsTextPrinterActive(0))
+ PokedudeBufferExecCompleted();
+}
+
+static void sub_8156254(void)
+{
+ if (!gPaletteFade.active)
+ {
+ gMain.inBattle = FALSE;
+ gMain.callback1 = gPreBattleCallback1;
+ SetMainCallback2(gMain.savedCallback);
+ }
+}
+
+static void sub_8156294(void)
+{
+ if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].specialAnimActive)
+ {
+ CreateTask(c3_0802FDF4, 10);
+ HandleLowHpMusicChange(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], gActiveBattler);
+ PokedudeBufferExecCompleted();
+ }
+}
+
+static void sub_81562F0(void)
+{
+ if (gSprites[gHealthboxSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy
+ && gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].field_1_x1)
+ {
+ gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].flag_x80 = 0;
+ gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].field_1_x1 = 0;
+ FreeSpriteTilesByTag(0x27F9);
+ FreeSpritePaletteByTag(0x27F9);
+ if (gBattleSpritesDataPtr->battlerData[gActiveBattler].behindSubstitute)
+ InitAndLaunchSpecialAnimation(gActiveBattler, gActiveBattler, gActiveBattler, B_ANIM_MON_TO_SUBSTITUTE);
+ gBattlerControllerFuncs[gActiveBattler] = sub_8156294;
+ }
+}
+
+static void sub_81563A8(void)
+{
+ if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].flag_x80
+ && !gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].ballAnimActive)
+ sub_80F1720(gActiveBattler, &gPlayerParty[gBattlerPartyIndexes[gActiveBattler]]);
+ if (gSprites[gUnknown_3004FFC[gActiveBattler]].callback == SpriteCallbackDummy
+ && !(gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].ballAnimActive))
+ {
+ DestroySprite(&gSprites[gUnknown_3004FFC[gActiveBattler]]);
+ UpdateHealthboxAttribute(gHealthboxSpriteIds[gActiveBattler],
+ &gPlayerParty[gBattlerPartyIndexes[gActiveBattler]],
+ HEALTHBOX_ALL);
+ sub_804BD94(gActiveBattler);
+ SetHealthboxSpriteVisible(gHealthboxSpriteIds[gActiveBattler]);
+ CopyBattleSpriteInvisibility(gActiveBattler);
+ gBattlerControllerFuncs[gActiveBattler] = sub_81562F0;
+ }
+}
+
+static void CompleteOnSpecialAnimDone(void)
+{
+ if (!gDoingBattleAnim)
+ PokedudeBufferExecCompleted();
+}
+
+static void sub_815649C(void)
+{
+ if (--gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].field_9 == 255)
+ {
+ gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].field_9 = 0;
+ PokedudeBufferExecCompleted();
+ }
+}
+
+static void sub_81564E4(void)
+{
+ sub_8159998();
+}
+
+static void OpenPartyMenuToChooseMon(void)
+{
+ if (!gPaletteFade.active)
+ {
+ gBattlerControllerFuncs[gActiveBattler] = WaitForMonSelection;
+ DestroyTask(gUnknown_3004FFC[gActiveBattler]);
+ FreeAllWindowBuffers();
+ sub_8127968();
+ }
+}
+
+static void WaitForMonSelection(void)
+{
+ if (gMain.callback2 == BattleMainCB2 && !gPaletteFade.active)
+ {
+ if (gUnknown_203B0C0 == 1)
+ BtlController_EmitChosenMonReturnValue(1, gUnknown_203B0C1, gUnknown_203B0DC);
+ else
+ BtlController_EmitChosenMonReturnValue(1, 6, NULL);
+ PokedudeBufferExecCompleted();
+ }
+}
+
+static void OpenBagAndChooseItem(void)
+{
+ u8 callbackId;
+
+ if (!gPaletteFade.active)
+ {
+ gBattlerControllerFuncs[gActiveBattler] = CompleteWhenChoseItem;
+ nullsub_44();
+ FreeAllWindowBuffers();
+ switch (gSpecialVar_0x8004)
+ {
+ case 1:
+ default:
+ callbackId = 7;
+ break;
+ case 3:
+ callbackId = 8;
+ break;
+ }
+ sub_810B108(callbackId);
+ }
+}
+
+static void CompleteWhenChoseItem(void)
+{
+ if (gMain.callback2 == BattleMainCB2 && !gPaletteFade.active)
+ {
+ BtlController_EmitOneReturnValue(1, gSpecialVar_ItemId);
+ PokedudeBufferExecCompleted();
+ }
+}
+
+static void sub_8156624(void)
+{
+ if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].flag_x80
+ && !gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].ballAnimActive)
+ sub_80F1720(gActiveBattler, &gPlayerParty[gBattlerPartyIndexes[gActiveBattler]]);
+ if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler ^ BIT_FLANK].flag_x80
+ && !gBattleSpritesDataPtr->healthBoxesData[gActiveBattler ^ BIT_FLANK].ballAnimActive)
+ sub_80F1720(gActiveBattler ^ BIT_FLANK, &gPlayerParty[gBattlerPartyIndexes[gActiveBattler ^ BIT_FLANK]]);
+ if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].ballAnimActive && !gBattleSpritesDataPtr->healthBoxesData[gActiveBattler ^ BIT_FLANK].ballAnimActive)
+ {
+ if (IsDoubleBattle() && !(gBattleTypeFlags & BATTLE_TYPE_MULTI))
+ {
+ DestroySprite(&gSprites[gUnknown_3004FFC[gActiveBattler ^ BIT_FLANK]]);
+ UpdateHealthboxAttribute(gHealthboxSpriteIds[gActiveBattler ^ BIT_FLANK],
+ &gPlayerParty[gBattlerPartyIndexes[gActiveBattler ^ BIT_FLANK]],
+ HEALTHBOX_ALL);
+ sub_804BD94(gActiveBattler ^ BIT_FLANK);
+ SetHealthboxSpriteVisible(gHealthboxSpriteIds[gActiveBattler ^ BIT_FLANK]);
+ }
+ DestroySprite(&gSprites[gUnknown_3004FFC[gActiveBattler]]);
+ UpdateHealthboxAttribute(gHealthboxSpriteIds[gActiveBattler],
+ &gPlayerParty[gBattlerPartyIndexes[gActiveBattler]],
+ HEALTHBOX_ALL);
+ sub_804BD94(gActiveBattler);
+ SetHealthboxSpriteVisible(gHealthboxSpriteIds[gActiveBattler]);
+ gBattleSpritesDataPtr->animationData->field_9_x1 = 0;
+ gBattlerControllerFuncs[gActiveBattler] = sub_81567B0;
+ }
+}
+
+static void sub_81567B0(void)
+{
+ bool32 r4 = FALSE;
+
+ if (gSprites[gHealthboxSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy)
+ r4 = TRUE;
+ if (r4
+ && gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].field_1_x1
+ && gBattleSpritesDataPtr->healthBoxesData[gActiveBattler ^ BIT_FLANK].field_1_x1)
+ {
+ gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].flag_x80 = 0;
+ gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].field_1_x1 = 0;
+ gBattleSpritesDataPtr->healthBoxesData[gActiveBattler ^ BIT_FLANK].flag_x80 = 0;
+ gBattleSpritesDataPtr->healthBoxesData[gActiveBattler ^ BIT_FLANK].field_1_x1 = 0;
+ FreeSpriteTilesByTag(0x27F9);
+ FreeSpritePaletteByTag(0x27F9);
+ CreateTask(c3_0802FDF4, 10);
+ HandleLowHpMusicChange(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], gActiveBattler);
+ gBattlerControllerFuncs[gActiveBattler] = sub_815649C;
+ }
+}
+
+#define tExpTask_monId data[0]
+#define tExpTask_gainedExp data[1]
+#define tExpTask_battler data[2]
+#define tExpTask_frames data[10]
+
+static void Task_GiveExpToMon(u8 taskId)
+{
+ u32 monId = (u8)gTasks[taskId].tExpTask_monId;
+ u8 battlerId = gTasks[taskId].tExpTask_battler;
+ s16 gainedExp = gTasks[taskId].tExpTask_gainedExp;
+
+ if (IsDoubleBattle() == TRUE || monId != gBattlerPartyIndexes[battlerId]) // Give exp without moving the expbar.
+ {
+ struct Pokemon *mon = &gPlayerParty[monId];
+ u16 species = GetMonData(mon, MON_DATA_SPECIES);
+ u8 level = GetMonData(mon, MON_DATA_LEVEL);
+ u32 currExp = GetMonData(mon, MON_DATA_EXP);
+ u32 nextLvlExp = gExperienceTables[gBaseStats[species].growthRate][level + 1];
+
+ if (currExp + gainedExp >= nextLvlExp)
+ {
+ u8 savedActiveBattler;
+
+ SetMonData(mon, MON_DATA_EXP, &nextLvlExp);
+ CalculateMonStats(mon);
+ gainedExp -= nextLvlExp - currExp;
+ savedActiveBattler = gActiveBattler;
+ gActiveBattler = battlerId;
+ BtlController_EmitTwoReturnValues(1, RET_VALUE_LEVELED_UP, gainedExp);
+ gActiveBattler = savedActiveBattler;
+ if (IsDoubleBattle() == TRUE
+ && ((u16)monId == gBattlerPartyIndexes[battlerId] || (u16)monId == gBattlerPartyIndexes[battlerId ^ BIT_FLANK]))
+ gTasks[taskId].func = Task_LaunchLvlUpAnim;
+ else
+ gTasks[taskId].func = DestroyExpTaskAndCompleteOnInactiveTextPrinter;
+ }
+ else
+ {
+ currExp += gainedExp;
+ SetMonData(mon, MON_DATA_EXP, &currExp);
+ gBattlerControllerFuncs[battlerId] = CompleteOnInactiveTextPrinter2;
+ DestroyTask(taskId);
+ }
+ }
+ else
+ {
+ gTasks[taskId].func = Task_PrepareToGiveExpWithExpBar;
+ }
+}
+
+static void Task_PrepareToGiveExpWithExpBar(u8 taskId)
+{
+ u8 monIndex = gTasks[taskId].tExpTask_monId;
+ s32 gainedExp = gTasks[taskId].tExpTask_gainedExp;
+ u8 battlerId = gTasks[taskId].tExpTask_battler;
+ struct Pokemon *mon = &gPlayerParty[monIndex];
+ u8 level = GetMonData(mon, MON_DATA_LEVEL);
+ u16 species = GetMonData(mon, MON_DATA_SPECIES);
+ u32 exp = GetMonData(mon, MON_DATA_EXP);
+ u32 currLvlExp = gExperienceTables[gBaseStats[species].growthRate][level];
+ u32 expToNextLvl;
+
+ exp -= currLvlExp;
+ expToNextLvl = gExperienceTables[gBaseStats[species].growthRate][level + 1] - currLvlExp;
+ SetBattleBarStruct(battlerId, gHealthboxSpriteIds[battlerId], expToNextLvl, exp, -gainedExp);
+ PlaySE(SE_EXP);
+ gTasks[taskId].func = sub_8156B24;
+}
+
+static void sub_8156B24(u8 taskId)
+{
+ if (gTasks[taskId].tExpTask_frames < 13)
+ {
+ ++gTasks[taskId].tExpTask_frames;
+ }
+ else
+ {
+ u8 monId = gTasks[taskId].tExpTask_monId;
+ s16 gainedExp = gTasks[taskId].tExpTask_gainedExp;
+ u8 battlerId = gTasks[taskId].tExpTask_battler;
+ s16 newExpPoints;
+
+ newExpPoints = MoveBattleBar(battlerId, gHealthboxSpriteIds[battlerId], EXP_BAR, 0);
+ SetHealthboxSpriteVisible(gHealthboxSpriteIds[battlerId]);
+ if (newExpPoints == -1) // The bar has been filled with given exp points.
+ {
+ u8 level;
+ s32 currExp;
+ u16 species;
+ s32 expOnNextLvl;
+
+ m4aSongNumStop(SE_EXP);
+ level = GetMonData(&gPlayerParty[monId], MON_DATA_LEVEL);
+ currExp = GetMonData(&gPlayerParty[monId], MON_DATA_EXP);
+ species = GetMonData(&gPlayerParty[monId], MON_DATA_SPECIES);
+ expOnNextLvl = gExperienceTables[gBaseStats[species].growthRate][level + 1];
+ if (currExp + gainedExp >= expOnNextLvl)
+ {
+ u8 savedActiveBattler;
+
+ SetMonData(&gPlayerParty[monId], MON_DATA_EXP, &expOnNextLvl);
+ CalculateMonStats(&gPlayerParty[monId]);
+ gainedExp -= expOnNextLvl - currExp;
+ savedActiveBattler = gActiveBattler;
+ gActiveBattler = battlerId;
+ BtlController_EmitTwoReturnValues(1, RET_VALUE_LEVELED_UP, gainedExp);
+ gActiveBattler = savedActiveBattler;
+ gTasks[taskId].func = Task_LaunchLvlUpAnim;
+ }
+ else
+ {
+ currExp += gainedExp;
+ SetMonData(&gPlayerParty[monId], MON_DATA_EXP, &currExp);
+ gBattlerControllerFuncs[battlerId] = CompleteOnInactiveTextPrinter2;
+ DestroyTask(taskId);
+ }
+ }
+ }
+}
+
+static void Task_LaunchLvlUpAnim(u8 taskId)
+{
+ u8 battlerId = gTasks[taskId].tExpTask_battler;
+ u8 monIndex = gTasks[taskId].tExpTask_monId;
+
+ if (IsDoubleBattle() == TRUE && monIndex == gBattlerPartyIndexes[battlerId ^ BIT_FLANK])
+ battlerId ^= BIT_FLANK;
+ InitAndLaunchSpecialAnimation(battlerId, battlerId, battlerId, B_ANIM_LVL_UP);
+ gTasks[taskId].func = Task_UpdateLvlInHealthbox;
+}
+
+static void Task_UpdateLvlInHealthbox(u8 taskId)
+{
+ u8 battlerId = gTasks[taskId].tExpTask_battler;
+
+ if (!gBattleSpritesDataPtr->healthBoxesData[battlerId].specialAnimActive)
+ {
+ u8 monIndex = gTasks[taskId].tExpTask_monId;
+
+ GetMonData(&gPlayerParty[monIndex], MON_DATA_LEVEL); // Unused return value.
+ if (IsDoubleBattle() == TRUE && monIndex == gBattlerPartyIndexes[battlerId ^ BIT_FLANK])
+ UpdateHealthboxAttribute(gHealthboxSpriteIds[battlerId ^ BIT_FLANK], &gPlayerParty[monIndex], HEALTHBOX_ALL);
+ else
+ UpdateHealthboxAttribute(gHealthboxSpriteIds[battlerId], &gPlayerParty[monIndex], HEALTHBOX_ALL);
+ gTasks[taskId].func = DestroyExpTaskAndCompleteOnInactiveTextPrinter;
+ }
+}
+
+static void DestroyExpTaskAndCompleteOnInactiveTextPrinter(u8 taskId)
+{
+ u8 monIndex = gTasks[taskId].tExpTask_monId;
+ u8 battlerId;
+
+ GetMonData(&gPlayerParty[monIndex], MON_DATA_LEVEL); // Unused return value
+ battlerId = gTasks[taskId].tExpTask_battler;
+ gBattlerControllerFuncs[battlerId] = CompleteOnInactiveTextPrinter2;
+ DestroyTask(taskId);
+}
+
+static void sub_8156DCC(void)
+{
+ if (GetBattlerSide(gActiveBattler) == B_SIDE_PLAYER)
+ {
+ if (gSprites[gBattlerSpriteIds[gActiveBattler]].pos1.y + gSprites[gBattlerSpriteIds[gActiveBattler]].pos2.y > DISPLAY_HEIGHT)
+ {
+ FreeOamMatrix(gSprites[gBattlerSpriteIds[gActiveBattler]].oam.matrixNum);
+ DestroySprite(&gSprites[gBattlerSpriteIds[gActiveBattler]]);
+ SetHealthboxSpriteInvisible(gHealthboxSpriteIds[gActiveBattler]);
+ PokedudeBufferExecCompleted();
+ }
+ }
+ else
+ {
+ if (!gSprites[gBattlerSpriteIds[gActiveBattler]].inUse)
+ {
+ SetHealthboxSpriteInvisible(gHealthboxSpriteIds[gActiveBattler]);
+ PokedudeBufferExecCompleted();
+ }
+ }
+}
+
+static void CompleteOnHealthbarDone(void)
+{
+ s16 hpValue = MoveBattleBar(gActiveBattler, gHealthboxSpriteIds[gActiveBattler], HEALTH_BAR, 0);
+
+ SetHealthboxSpriteVisible(gHealthboxSpriteIds[gActiveBattler]);
+ if (hpValue != -1)
+ {
+ UpdateHpTextInHealthbox(gHealthboxSpriteIds[gActiveBattler], hpValue, HP_CURRENT);
+ }
+ else
+ {
+ HandleLowHpMusicChange(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], gActiveBattler);
+ PokedudeBufferExecCompleted();
+ }
+}
+
+static void CompleteOnInactiveTextPrinter2(void)
+{
+ if (!IsTextPrinterActive(0))
+ PokedudeBufferExecCompleted();
+}
+
+static void DoHitAnimBlinkSpriteEffect(void)
+{
+ u8 spriteId = gBattlerSpriteIds[gActiveBattler];
+
+ if (gSprites[spriteId].data[1] == 32)
+ {
+ gSprites[spriteId].data[1] = 0;
+ gSprites[spriteId].invisible = FALSE;
+ gDoingBattleAnim = FALSE;
+ PokedudeBufferExecCompleted();
+ }
+ else
+ {
+ if ((gSprites[spriteId].data[1] % 4) == 0)
+ gSprites[spriteId].invisible ^= 1;
+ ++gSprites[spriteId].data[1];
+ }
+}
+
+static void sub_8156F7C(void)
+{
+ if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].specialAnimActive)
+ {
+ FreeSpriteOamMatrix(&gSprites[gBattlerSpriteIds[gActiveBattler]]);
+ DestroySprite(&gSprites[gBattlerSpriteIds[gActiveBattler]]);
+ SetHealthboxSpriteInvisible(gHealthboxSpriteIds[gActiveBattler]);
+ PokedudeBufferExecCompleted();
+ }
+}
+
+static void CompleteOnBattlerSpriteCallbackDummy2(void)
+{
+ if (gSprites[gBattlerSpriteIds[gActiveBattler]].callback == SpriteCallbackDummy)
+ PokedudeBufferExecCompleted();
+}
+
+static void CompleteOnFinishedBattleAnimation(void)
+{
+ if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].animFromTableActive)
+ PokedudeBufferExecCompleted();
+}
+
+static void CompleteOnFinishedStatusAnimation(void)
+{
+ if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].statusAnimActive)
+ PokedudeBufferExecCompleted();
+}
+
+static void PokedudeBufferExecCompleted(void)
+{
+ gBattlerControllerFuncs[gActiveBattler] = PokedudeBufferRunCommand;
+ if (gBattleTypeFlags & BATTLE_TYPE_LINK)
+ {
+ u8 playerId = GetMultiplayerId();
+
+ PrepareBufferDataTransferLink(2, 4, &playerId);
+ gBattleBufferA[gActiveBattler][0] = CONTROLLER_TERMINATOR_NOP;
+ }
+ else
+ {
+ gBattleControllerExecFlags &= ~gBitTable[gActiveBattler];
+ }
+}
+
+// not used
+static void CompleteOnFinishedStatusAnimation2(void)
+{
+ if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].statusAnimActive)
+ PokedudeBufferExecCompleted();
+}
+
+static void PokedudeHandleGetMonData(void)
+{
+ u8 monData[sizeof(struct Pokemon) * 2 + 56]; // this allows to get full data of two pokemon, trying to get more will result in overwriting data
+ u32 size = 0;
+ u8 monToCheck;
+ s32 i;
+
+ if (gBattleBufferA[gActiveBattler][2] == 0)
+ {
+ size += CopyPokedudeMonData(gBattlerPartyIndexes[gActiveBattler], monData);
+ }
+ else
+ {
+ monToCheck = gBattleBufferA[gActiveBattler][2];
+ for (i = 0; i < PARTY_SIZE; ++i)
+ {
+ if (monToCheck & 1)
+ size += CopyPokedudeMonData(i, monData + size);
+ monToCheck >>= 1;
+ }
+ }
+ BtlController_EmitDataTransfer(1, size, monData);
+ PokedudeBufferExecCompleted();
+}
+
+static u32 CopyPokedudeMonData(u8 monId, u8 *dst)
+{
+ struct BattlePokemon battleMon;
+ struct MovePpInfo moveData;
+ u8 nickname[20];
+ u8 *src;
+ s16 data16;
+ u32 data32;
+ s32 size = 0;
+ struct Pokemon *mon;
+
+ if (GetBattlerSide(gActiveBattler) == B_SIDE_PLAYER)
+ mon = &gPlayerParty[monId];
+ else
+ mon = &gEnemyParty[monId];
+ switch (gBattleBufferA[gActiveBattler][1])
+ {
+ case REQUEST_ALL_BATTLE:
+ battleMon.species = GetMonData(mon, MON_DATA_SPECIES);
+ battleMon.item = GetMonData(mon, MON_DATA_HELD_ITEM);
+ for (size = 0; size < MAX_MON_MOVES; ++size)
+ {
+ battleMon.moves[size] = GetMonData(mon, MON_DATA_MOVE1 + size);
+ battleMon.pp[size] = GetMonData(mon, MON_DATA_PP1 + size);
+ }
+ battleMon.ppBonuses = GetMonData(mon, MON_DATA_PP_BONUSES);
+ battleMon.friendship = GetMonData(mon, MON_DATA_FRIENDSHIP);
+ battleMon.experience = GetMonData(mon, MON_DATA_EXP);
+ battleMon.hpIV = GetMonData(mon, MON_DATA_HP_IV);
+ battleMon.attackIV = GetMonData(mon, MON_DATA_ATK_IV);
+ battleMon.defenseIV = GetMonData(mon, MON_DATA_DEF_IV);
+ battleMon.speedIV = GetMonData(mon, MON_DATA_SPEED_IV);
+ battleMon.spAttackIV = GetMonData(mon, MON_DATA_SPATK_IV);
+ battleMon.spDefenseIV = GetMonData(mon, MON_DATA_SPDEF_IV);
+ battleMon.personality = GetMonData(mon, MON_DATA_PERSONALITY);
+ battleMon.status1 = GetMonData(mon, MON_DATA_STATUS);
+ battleMon.level = GetMonData(mon, MON_DATA_LEVEL);
+ battleMon.hp = GetMonData(mon, MON_DATA_HP);
+ battleMon.maxHP = GetMonData(mon, MON_DATA_MAX_HP);
+ battleMon.attack = GetMonData(mon, MON_DATA_ATK);
+ battleMon.defense = GetMonData(mon, MON_DATA_DEF);
+ battleMon.speed = GetMonData(mon, MON_DATA_SPEED);
+ battleMon.spAttack = GetMonData(mon, MON_DATA_SPATK);
+ battleMon.spDefense = GetMonData(mon, MON_DATA_SPDEF);
+ battleMon.isEgg = GetMonData(mon, MON_DATA_IS_EGG);
+ battleMon.abilityNum = GetMonData(mon, MON_DATA_ABILITY_NUM);
+ battleMon.otId = GetMonData(mon, MON_DATA_OT_ID);
+ GetMonData(mon, MON_DATA_NICKNAME, nickname);
+ StringCopy10(battleMon.nickname, nickname);
+ GetMonData(mon, MON_DATA_OT_NAME, battleMon.otName);
+ src = (u8 *)&battleMon;
+ for (size = 0; size < sizeof(battleMon); ++size)
+ dst[size] = src[size];
+ break;
+ case REQUEST_SPECIES_BATTLE:
+ data16 = GetMonData(mon, MON_DATA_SPECIES);
+ dst[0] = data16;
+ dst[1] = data16 >> 8;
+ size = 2;
+ break;
+ case REQUEST_HELDITEM_BATTLE:
+ data16 = GetMonData(mon, MON_DATA_HELD_ITEM);
+ dst[0] = data16;
+ dst[1] = data16 >> 8;
+ size = 2;
+ break;
+ case REQUEST_MOVES_PP_BATTLE:
+ for (size = 0; size < MAX_MON_MOVES; ++size)
+ {
+ moveData.moves[size] = GetMonData(mon, MON_DATA_MOVE1 + size);
+ moveData.pp[size] = GetMonData(mon, MON_DATA_PP1 + size);
+ }
+ moveData.ppBonuses = GetMonData(mon, MON_DATA_PP_BONUSES);
+ src = (u8 *)(&moveData);
+ for (size = 0; size < sizeof(moveData); ++size)
+ dst[size] = src[size];
+ break;
+ case REQUEST_MOVE1_BATTLE:
+ case REQUEST_MOVE2_BATTLE:
+ case REQUEST_MOVE3_BATTLE:
+ case REQUEST_MOVE4_BATTLE:
+ data16 = GetMonData(mon, MON_DATA_MOVE1 + gBattleBufferA[gActiveBattler][1] - REQUEST_MOVE1_BATTLE);
+ dst[0] = data16;
+ dst[1] = data16 >> 8;
+ size = 2;
+ break;
+ case REQUEST_PP_DATA_BATTLE:
+ for (size = 0; size < MAX_MON_MOVES; ++size)
+ dst[size] = GetMonData(mon, MON_DATA_PP1 + size);
+ dst[size] = GetMonData(mon, MON_DATA_PP_BONUSES);
+ ++size;
+ break;
+ case REQUEST_PPMOVE1_BATTLE:
+ case REQUEST_PPMOVE2_BATTLE:
+ case REQUEST_PPMOVE3_BATTLE:
+ case REQUEST_PPMOVE4_BATTLE:
+ dst[0] = GetMonData(mon, MON_DATA_PP1 + gBattleBufferA[gActiveBattler][1] - REQUEST_PPMOVE1_BATTLE);
+ size = 1;
+ break;
+ case REQUEST_OTID_BATTLE:
+ data32 = GetMonData(mon, MON_DATA_OT_ID);
+ dst[0] = (data32 & 0x000000FF);
+ dst[1] = (data32 & 0x0000FF00) >> 8;
+ dst[2] = (data32 & 0x00FF0000) >> 16;
+ size = 3;
+ break;
+ case REQUEST_EXP_BATTLE:
+ data32 = GetMonData(mon, MON_DATA_EXP);
+ dst[0] = (data32 & 0x000000FF);
+ dst[1] = (data32 & 0x0000FF00) >> 8;
+ dst[2] = (data32 & 0x00FF0000) >> 16;
+ size = 3;
+ break;
+ case REQUEST_HP_EV_BATTLE:
+ dst[0] = GetMonData(mon, MON_DATA_HP_EV);
+ size = 1;
+ break;
+ case REQUEST_ATK_EV_BATTLE:
+ dst[0] = GetMonData(mon, MON_DATA_ATK_EV);
+ size = 1;
+ break;
+ case REQUEST_DEF_EV_BATTLE:
+ dst[0] = GetMonData(mon, MON_DATA_DEF_EV);
+ size = 1;
+ break;
+ case REQUEST_SPEED_EV_BATTLE:
+ dst[0] = GetMonData(mon, MON_DATA_SPEED_EV);
+ size = 1;
+ break;
+ case REQUEST_SPATK_EV_BATTLE:
+ dst[0] = GetMonData(mon, MON_DATA_SPATK_EV);
+ size = 1;
+ break;
+ case REQUEST_SPDEF_EV_BATTLE:
+ dst[0] = GetMonData(mon, MON_DATA_SPDEF_EV);
+ size = 1;
+ break;
+ case REQUEST_FRIENDSHIP_BATTLE:
+ dst[0] = GetMonData(mon, MON_DATA_FRIENDSHIP);
+ size = 1;
+ break;
+ case REQUEST_POKERUS_BATTLE:
+ dst[0] = GetMonData(mon, MON_DATA_POKERUS);
+ size = 1;
+ break;
+ case REQUEST_MET_LOCATION_BATTLE:
+ dst[0] = GetMonData(mon, MON_DATA_MET_LOCATION);
+ size = 1;
+ break;
+ case REQUEST_MET_LEVEL_BATTLE:
+ dst[0] = GetMonData(mon, MON_DATA_MET_LEVEL);
+ size = 1;
+ break;
+ case REQUEST_MET_GAME_BATTLE:
+ dst[0] = GetMonData(mon, MON_DATA_MET_GAME);
+ size = 1;
+ break;
+ case REQUEST_POKEBALL_BATTLE:
+ dst[0] = GetMonData(mon, MON_DATA_POKEBALL);
+ size = 1;
+ break;
+ case REQUEST_ALL_IVS_BATTLE:
+ dst[0] = GetMonData(mon, MON_DATA_HP_IV);
+ dst[1] = GetMonData(mon, MON_DATA_ATK_IV);
+ dst[2] = GetMonData(mon, MON_DATA_DEF_IV);
+ dst[3] = GetMonData(mon, MON_DATA_SPEED_IV);
+ dst[4] = GetMonData(mon, MON_DATA_SPATK_IV);
+ dst[5] = GetMonData(mon, MON_DATA_SPDEF_IV);
+ size = 6;
+ break;
+ case REQUEST_HP_IV_BATTLE:
+ dst[0] = GetMonData(mon, MON_DATA_HP_IV);
+ size = 1;
+ break;
+ case REQUEST_ATK_IV_BATTLE:
+ dst[0] = GetMonData(mon, MON_DATA_ATK_IV);
+ size = 1;
+ break;
+ case REQUEST_DEF_IV_BATTLE:
+ dst[0] = GetMonData(mon, MON_DATA_DEF_IV);
+ size = 1;
+ break;
+ case REQUEST_SPEED_IV_BATTLE:
+ dst[0] = GetMonData(mon, MON_DATA_SPEED_IV);
+ size = 1;
+ break;
+ case REQUEST_SPATK_IV_BATTLE:
+ dst[0] = GetMonData(mon, MON_DATA_SPATK_IV);
+ size = 1;
+ break;
+ case REQUEST_SPDEF_IV_BATTLE:
+ dst[0] = GetMonData(mon, MON_DATA_SPDEF_IV);
+ size = 1;
+ break;
+ case REQUEST_PERSONALITY_BATTLE:
+ data32 = GetMonData(mon, MON_DATA_PERSONALITY);
+ dst[0] = (data32 & 0x000000FF);
+ dst[1] = (data32 & 0x0000FF00) >> 8;
+ dst[2] = (data32 & 0x00FF0000) >> 16;
+ dst[3] = (data32 & 0xFF000000) >> 24;
+ size = 4;
+ break;
+ case REQUEST_CHECKSUM_BATTLE:
+ data16 = GetMonData(mon, MON_DATA_CHECKSUM);
+ dst[0] = data16;
+ dst[1] = data16 >> 8;
+ size = 2;
+ break;
+ case REQUEST_STATUS_BATTLE:
+ data32 = GetMonData(mon, MON_DATA_STATUS);
+ dst[0] = (data32 & 0x000000FF);
+ dst[1] = (data32 & 0x0000FF00) >> 8;
+ dst[2] = (data32 & 0x00FF0000) >> 16;
+ dst[3] = (data32 & 0xFF000000) >> 24;
+ size = 4;
+ break;
+ case REQUEST_LEVEL_BATTLE:
+ dst[0] = GetMonData(mon, MON_DATA_LEVEL);
+ size = 1;
+ break;
+ case REQUEST_HP_BATTLE:
+ data16 = GetMonData(mon, MON_DATA_HP);
+ dst[0] = data16;
+ dst[1] = data16 >> 8;
+ size = 2;
+ break;
+ case REQUEST_MAX_HP_BATTLE:
+ data16 = GetMonData(mon, MON_DATA_MAX_HP);
+ dst[0] = data16;
+ dst[1] = data16 >> 8;
+ size = 2;
+ break;
+ case REQUEST_ATK_BATTLE:
+ data16 = GetMonData(mon, MON_DATA_ATK);
+ dst[0] = data16;
+ dst[1] = data16 >> 8;
+ size = 2;
+ break;
+ case REQUEST_DEF_BATTLE:
+ data16 = GetMonData(mon, MON_DATA_DEF);
+ dst[0] = data16;
+ dst[1] = data16 >> 8;
+ size = 2;
+ break;
+ case REQUEST_SPEED_BATTLE:
+ data16 = GetMonData(mon, MON_DATA_SPEED);
+ dst[0] = data16;
+ dst[1] = data16 >> 8;
+ size = 2;
+ break;
+ case REQUEST_SPATK_BATTLE:
+ data16 = GetMonData(mon, MON_DATA_SPATK);
+ dst[0] = data16;
+ dst[1] = data16 >> 8;
+ size = 2;
+ break;
+ case REQUEST_SPDEF_BATTLE:
+ data16 = GetMonData(mon, MON_DATA_SPDEF);
+ dst[0] = data16;
+ dst[1] = data16 >> 8;
+ size = 2;
+ break;
+ case REQUEST_COOL_BATTLE:
+ dst[0] = GetMonData(mon, MON_DATA_COOL);
+ size = 1;
+ break;
+ case REQUEST_BEAUTY_BATTLE:
+ dst[0] = GetMonData(mon, MON_DATA_BEAUTY);
+ size = 1;
+ break;
+ case REQUEST_CUTE_BATTLE:
+ dst[0] = GetMonData(mon, MON_DATA_CUTE);
+ size = 1;
+ break;
+ case REQUEST_SMART_BATTLE:
+ dst[0] = GetMonData(mon, MON_DATA_SMART);
+ size = 1;
+ break;
+ case REQUEST_TOUGH_BATTLE:
+ dst[0] = GetMonData(mon, MON_DATA_TOUGH);
+ size = 1;
+ break;
+ case REQUEST_SHEEN_BATTLE:
+ dst[0] = GetMonData(mon, MON_DATA_SHEEN);
+ size = 1;
+ break;
+ case REQUEST_COOL_RIBBON_BATTLE:
+ dst[0] = GetMonData(mon, MON_DATA_COOL_RIBBON);
+ size = 1;
+ break;
+ case REQUEST_BEAUTY_RIBBON_BATTLE:
+ dst[0] = GetMonData(mon, MON_DATA_BEAUTY_RIBBON);
+ size = 1;
+ break;
+ case REQUEST_CUTE_RIBBON_BATTLE:
+ dst[0] = GetMonData(mon, MON_DATA_CUTE_RIBBON);
+ size = 1;
+ break;
+ case REQUEST_SMART_RIBBON_BATTLE:
+ dst[0] = GetMonData(mon, MON_DATA_SMART_RIBBON);
+ size = 1;
+ break;
+ case REQUEST_TOUGH_RIBBON_BATTLE:
+ dst[0] = GetMonData(mon, MON_DATA_TOUGH_RIBBON);
+ size = 1;
+ break;
+ }
+ return size;
+}
+
+static void PokedudeHandleGetRawMonData(void)
+{
+ PlayerHandleGetRawMonData();
+}
+
+static void PokedudeHandleSetMonData(void)
+{
+ u8 monToCheck;
+ u8 i;
+
+ if (gBattleBufferA[gActiveBattler][2] == 0)
+ {
+ SetPokedudeMonData(gBattlerPartyIndexes[gActiveBattler]);
+ }
+ else
+ {
+ monToCheck = gBattleBufferA[gActiveBattler][2];
+ for (i = 0; i < PARTY_SIZE; ++i)
+ {
+ if (monToCheck & 1)
+ SetPokedudeMonData(i);
+ monToCheck >>= 1;
+ }
+ }
+ PokedudeBufferExecCompleted();
+}
+
+static void SetPokedudeMonData(u8 monId)
+{
+ struct BattlePokemon *battlePokemon = (struct BattlePokemon *)&gBattleBufferA[gActiveBattler][3];
+ struct MovePpInfo *moveData = (struct MovePpInfo *)&gBattleBufferA[gActiveBattler][3];
+ s32 i;
+ struct Pokemon *mon;
+
+ if (GetBattlerSide(gActiveBattler) == B_SIDE_PLAYER)
+ mon = &gPlayerParty[monId];
+ else
+ mon = &gEnemyParty[monId];
+ switch (gBattleBufferA[gActiveBattler][1])
+ {
+ case REQUEST_ALL_BATTLE:
+ {
+ u8 iv;
+
+ SetMonData(mon, MON_DATA_SPECIES, &battlePokemon->species);
+ SetMonData(mon, MON_DATA_HELD_ITEM, &battlePokemon->item);
+ for (i = 0; i < MAX_MON_MOVES; ++i)
+ {
+ SetMonData(mon, MON_DATA_MOVE1 + i, &battlePokemon->moves[i]);
+ SetMonData(mon, MON_DATA_PP1 + i, &battlePokemon->pp[i]);
+ }
+ SetMonData(mon, MON_DATA_PP_BONUSES, &battlePokemon->ppBonuses);
+ SetMonData(mon, MON_DATA_FRIENDSHIP, &battlePokemon->friendship);
+ SetMonData(mon, MON_DATA_EXP, &battlePokemon->experience);
+ iv = battlePokemon->hpIV;
+ SetMonData(mon, MON_DATA_HP_IV, &iv);
+ iv = battlePokemon->attackIV;
+ SetMonData(mon, MON_DATA_ATK_IV, &iv);
+ iv = battlePokemon->defenseIV;
+ SetMonData(mon, MON_DATA_DEF_IV, &iv);
+ iv = battlePokemon->speedIV;
+ SetMonData(mon, MON_DATA_SPEED_IV, &iv);
+ iv = battlePokemon->spAttackIV;
+ SetMonData(mon, MON_DATA_SPATK_IV, &iv);
+ iv = battlePokemon->spDefenseIV;
+ SetMonData(mon, MON_DATA_SPDEF_IV, &iv);
+ SetMonData(mon, MON_DATA_PERSONALITY, &battlePokemon->personality);
+ SetMonData(mon, MON_DATA_STATUS, &battlePokemon->status1);
+ SetMonData(mon, MON_DATA_LEVEL, &battlePokemon->level);
+ SetMonData(mon, MON_DATA_HP, &battlePokemon->hp);
+ SetMonData(mon, MON_DATA_MAX_HP, &battlePokemon->maxHP);
+ SetMonData(mon, MON_DATA_ATK, &battlePokemon->attack);
+ SetMonData(mon, MON_DATA_DEF, &battlePokemon->defense);
+ SetMonData(mon, MON_DATA_SPEED, &battlePokemon->speed);
+ SetMonData(mon, MON_DATA_SPATK, &battlePokemon->spAttack);
+ SetMonData(mon, MON_DATA_SPDEF, &battlePokemon->spDefense);
+ }
+ break;
+ case REQUEST_SPECIES_BATTLE:
+ SetMonData(mon, MON_DATA_SPECIES, &gBattleBufferA[gActiveBattler][3]);
+ break;
+ case REQUEST_HELDITEM_BATTLE:
+ SetMonData(mon, MON_DATA_HELD_ITEM, &gBattleBufferA[gActiveBattler][3]);
+ break;
+ case REQUEST_MOVES_PP_BATTLE:
+ for (i = 0; i < MAX_MON_MOVES; ++i)
+ {
+ SetMonData(mon, MON_DATA_MOVE1 + i, &moveData->moves[i]);
+ SetMonData(mon, MON_DATA_PP1 + i, &moveData->pp[i]);
+ }
+ SetMonData(mon, MON_DATA_PP_BONUSES, &moveData->ppBonuses);
+ break;
+ case REQUEST_MOVE1_BATTLE:
+ case REQUEST_MOVE2_BATTLE:
+ case REQUEST_MOVE3_BATTLE:
+ case REQUEST_MOVE4_BATTLE:
+ SetMonData(mon, MON_DATA_MOVE1 + gBattleBufferA[gActiveBattler][1] - REQUEST_MOVE1_BATTLE, &gBattleBufferA[gActiveBattler][3]);
+ break;
+ case REQUEST_PP_DATA_BATTLE:
+ SetMonData(mon, MON_DATA_PP1, &gBattleBufferA[gActiveBattler][3]);
+ SetMonData(mon, MON_DATA_PP2, &gBattleBufferA[gActiveBattler][4]);
+ SetMonData(mon, MON_DATA_PP3, &gBattleBufferA[gActiveBattler][5]);
+ SetMonData(mon, MON_DATA_PP4, &gBattleBufferA[gActiveBattler][6]);
+ SetMonData(mon, MON_DATA_PP_BONUSES, &gBattleBufferA[gActiveBattler][7]);
+ break;
+ case REQUEST_PPMOVE1_BATTLE:
+ case REQUEST_PPMOVE2_BATTLE:
+ case REQUEST_PPMOVE3_BATTLE:
+ case REQUEST_PPMOVE4_BATTLE:
+ SetMonData(mon, MON_DATA_PP1 + gBattleBufferA[gActiveBattler][1] - REQUEST_PPMOVE1_BATTLE, &gBattleBufferA[gActiveBattler][3]);
+ break;
+ case REQUEST_OTID_BATTLE:
+ SetMonData(mon, MON_DATA_OT_ID, &gBattleBufferA[gActiveBattler][3]);
+ break;
+ case REQUEST_EXP_BATTLE:
+ SetMonData(mon, MON_DATA_EXP, &gBattleBufferA[gActiveBattler][3]);
+ break;
+ case REQUEST_HP_EV_BATTLE:
+ SetMonData(mon, MON_DATA_HP_EV, &gBattleBufferA[gActiveBattler][3]);
+ break;
+ case REQUEST_ATK_EV_BATTLE:
+ SetMonData(mon, MON_DATA_ATK_EV, &gBattleBufferA[gActiveBattler][3]);
+ break;
+ case REQUEST_DEF_EV_BATTLE:
+ SetMonData(mon, MON_DATA_DEF_EV, &gBattleBufferA[gActiveBattler][3]);
+ break;
+ case REQUEST_SPEED_EV_BATTLE:
+ SetMonData(mon, MON_DATA_SPEED_EV, &gBattleBufferA[gActiveBattler][3]);
+ break;
+ case REQUEST_SPATK_EV_BATTLE:
+ SetMonData(mon, MON_DATA_SPATK_EV, &gBattleBufferA[gActiveBattler][3]);
+ break;
+ case REQUEST_SPDEF_EV_BATTLE:
+ SetMonData(mon, MON_DATA_SPDEF_EV, &gBattleBufferA[gActiveBattler][3]);
+ break;
+ case REQUEST_FRIENDSHIP_BATTLE:
+ SetMonData(mon, MON_DATA_FRIENDSHIP, &gBattleBufferA[gActiveBattler][3]);
+ break;
+ case REQUEST_POKERUS_BATTLE:
+ SetMonData(mon, MON_DATA_POKERUS, &gBattleBufferA[gActiveBattler][3]);
+ break;
+ case REQUEST_MET_LOCATION_BATTLE:
+ SetMonData(mon, MON_DATA_MET_LOCATION, &gBattleBufferA[gActiveBattler][3]);
+ break;
+ case REQUEST_MET_LEVEL_BATTLE:
+ SetMonData(mon, MON_DATA_MET_LEVEL, &gBattleBufferA[gActiveBattler][3]);
+ break;
+ case REQUEST_MET_GAME_BATTLE:
+ SetMonData(mon, MON_DATA_MET_GAME, &gBattleBufferA[gActiveBattler][3]);
+ break;
+ case REQUEST_POKEBALL_BATTLE:
+ SetMonData(mon, MON_DATA_POKEBALL, &gBattleBufferA[gActiveBattler][3]);
+ break;
+ case REQUEST_ALL_IVS_BATTLE:
+ SetMonData(mon, MON_DATA_HP_IV, &gBattleBufferA[gActiveBattler][3]);
+ SetMonData(mon, MON_DATA_ATK_IV, &gBattleBufferA[gActiveBattler][4]);
+ SetMonData(mon, MON_DATA_DEF_IV, &gBattleBufferA[gActiveBattler][5]);
+ SetMonData(mon, MON_DATA_SPEED_IV, &gBattleBufferA[gActiveBattler][6]);
+ SetMonData(mon, MON_DATA_SPATK_IV, &gBattleBufferA[gActiveBattler][7]);
+ SetMonData(mon, MON_DATA_SPDEF_IV, &gBattleBufferA[gActiveBattler][8]);
+ break;
+ case REQUEST_HP_IV_BATTLE:
+ SetMonData(mon, MON_DATA_HP_IV, &gBattleBufferA[gActiveBattler][3]);
+ break;
+ case REQUEST_ATK_IV_BATTLE:
+ SetMonData(mon, MON_DATA_ATK_IV, &gBattleBufferA[gActiveBattler][3]);
+ break;
+ case REQUEST_DEF_IV_BATTLE:
+ SetMonData(mon, MON_DATA_DEF_IV, &gBattleBufferA[gActiveBattler][3]);
+ break;
+ case REQUEST_SPEED_IV_BATTLE:
+ SetMonData(mon, MON_DATA_SPEED_IV, &gBattleBufferA[gActiveBattler][3]);
+ break;
+ case REQUEST_SPATK_IV_BATTLE:
+ SetMonData(mon, MON_DATA_SPATK_IV, &gBattleBufferA[gActiveBattler][3]);
+ break;
+ case REQUEST_SPDEF_IV_BATTLE:
+ SetMonData(mon, MON_DATA_SPDEF_IV, &gBattleBufferA[gActiveBattler][3]);
+ break;
+ case REQUEST_PERSONALITY_BATTLE:
+ SetMonData(mon, MON_DATA_PERSONALITY, &gBattleBufferA[gActiveBattler][3]);
+ break;
+ case REQUEST_CHECKSUM_BATTLE:
+ SetMonData(mon, MON_DATA_CHECKSUM, &gBattleBufferA[gActiveBattler][3]);
+ break;
+ case REQUEST_STATUS_BATTLE:
+ SetMonData(mon, MON_DATA_STATUS, &gBattleBufferA[gActiveBattler][3]);
+ break;
+ case REQUEST_LEVEL_BATTLE:
+ SetMonData(mon, MON_DATA_LEVEL, &gBattleBufferA[gActiveBattler][3]);
+ break;
+ case REQUEST_HP_BATTLE:
+ SetMonData(mon, MON_DATA_HP, &gBattleBufferA[gActiveBattler][3]);
+ break;
+ case REQUEST_MAX_HP_BATTLE:
+ SetMonData(mon, MON_DATA_MAX_HP, &gBattleBufferA[gActiveBattler][3]);
+ break;
+ case REQUEST_ATK_BATTLE:
+ SetMonData(mon, MON_DATA_ATK, &gBattleBufferA[gActiveBattler][3]);
+ break;
+ case REQUEST_DEF_BATTLE:
+ SetMonData(mon, MON_DATA_DEF, &gBattleBufferA[gActiveBattler][3]);
+ break;
+ case REQUEST_SPEED_BATTLE:
+ SetMonData(mon, MON_DATA_SPEED, &gBattleBufferA[gActiveBattler][3]);
+ break;
+ case REQUEST_SPATK_BATTLE:
+ SetMonData(mon, MON_DATA_SPATK, &gBattleBufferA[gActiveBattler][3]);
+ break;
+ case REQUEST_SPDEF_BATTLE:
+ SetMonData(mon, MON_DATA_SPDEF, &gBattleBufferA[gActiveBattler][3]);
+ break;
+ case REQUEST_COOL_BATTLE:
+ SetMonData(mon, MON_DATA_COOL, &gBattleBufferA[gActiveBattler][3]);
+ break;
+ case REQUEST_BEAUTY_BATTLE:
+ SetMonData(mon, MON_DATA_BEAUTY, &gBattleBufferA[gActiveBattler][3]);
+ break;
+ case REQUEST_CUTE_BATTLE:
+ SetMonData(mon, MON_DATA_CUTE, &gBattleBufferA[gActiveBattler][3]);
+ break;
+ case REQUEST_SMART_BATTLE:
+ SetMonData(mon, MON_DATA_SMART, &gBattleBufferA[gActiveBattler][3]);
+ break;
+ case REQUEST_TOUGH_BATTLE:
+ SetMonData(mon, MON_DATA_TOUGH, &gBattleBufferA[gActiveBattler][3]);
+ break;
+ case REQUEST_SHEEN_BATTLE:
+ SetMonData(mon, MON_DATA_SHEEN, &gBattleBufferA[gActiveBattler][3]);
+ break;
+ case REQUEST_COOL_RIBBON_BATTLE:
+ SetMonData(mon, MON_DATA_COOL_RIBBON, &gBattleBufferA[gActiveBattler][3]);
+ break;
+ case REQUEST_BEAUTY_RIBBON_BATTLE:
+ SetMonData(mon, MON_DATA_BEAUTY_RIBBON, &gBattleBufferA[gActiveBattler][3]);
+ break;
+ case REQUEST_CUTE_RIBBON_BATTLE:
+ SetMonData(mon, MON_DATA_CUTE_RIBBON, &gBattleBufferA[gActiveBattler][3]);
+ break;
+ case REQUEST_SMART_RIBBON_BATTLE:
+ SetMonData(mon, MON_DATA_SMART_RIBBON, &gBattleBufferA[gActiveBattler][3]);
+ break;
+ case REQUEST_TOUGH_RIBBON_BATTLE:
+ SetMonData(mon, MON_DATA_TOUGH_RIBBON, &gBattleBufferA[gActiveBattler][3]);
+ break;
+ }
+ HandleLowHpMusicChange(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], gActiveBattler);
+}
+
+static void PokedudeHandleSetRawMonData(void)
+{
+ PokedudeBufferExecCompleted();
+}
+
+static void PokedudeHandleLoadMonSprite(void)
+{
+ u32 y;
+ u16 species = GetMonData(&gEnemyParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_SPECIES);
+
+ BattleLoadOpponentMonSpriteGfx(&gEnemyParty[gBattlerPartyIndexes[gActiveBattler]], gActiveBattler);
+ y = GetBattlerSpriteDefault_Y(gActiveBattler);
+ SetMultiuseSpriteTemplateToPokemon(species, GetBattlerPosition(gActiveBattler));
+ gBattlerSpriteIds[gActiveBattler] = CreateSprite(&gMultiuseSpriteTemplate,
+ GetBattlerSpriteCoord(gActiveBattler, 2),
+ y,
+ GetBattlerSpriteSubpriority(gActiveBattler));
+ gSprites[gBattlerSpriteIds[gActiveBattler]].pos2.x = -240;
+ gSprites[gBattlerSpriteIds[gActiveBattler]].data[0] = gActiveBattler;
+ gSprites[gBattlerSpriteIds[gActiveBattler]].data[2] = species;
+ gSprites[gBattlerSpriteIds[gActiveBattler]].oam.paletteNum = gActiveBattler;
+ StartSpriteAnim(&gSprites[gBattlerSpriteIds[gActiveBattler]], gBattleMonForms[gActiveBattler]);
+ SetBattlerShadowSpriteCallback(gActiveBattler, GetMonData(&gEnemyParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_SPECIES));
+ gBattlerControllerFuncs[gActiveBattler] = sub_8156184;
+ PokedudeBufferExecCompleted();
+}
+
+static void PokedudeHandleSwitchInAnim(void)
+{
+ ClearTemporarySpeciesSpriteData(gActiveBattler, gBattleBufferA[gActiveBattler][2]);
+ gBattlerPartyIndexes[gActiveBattler] = gBattleBufferA[gActiveBattler][1];
+ BattleLoadPlayerMonSpriteGfx(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], gActiveBattler);
+ gActionSelectionCursor[gActiveBattler] = 0;
+ gMoveSelectionCursor[gActiveBattler] = 0;
+ sub_8159478(gActiveBattler);
+ gBattlerControllerFuncs[gActiveBattler] = sub_81563A8;
+}
+
+static void PokedudeHandleReturnMonToBall(void)
+{
+ if (gBattleBufferA[gActiveBattler][1] == 0)
+ {
+ InitAndLaunchSpecialAnimation(gActiveBattler, gActiveBattler, gActiveBattler, B_ANIM_SWITCH_OUT_PLAYER_MON);
+ gBattlerControllerFuncs[gActiveBattler] = sub_8156F7C;
+ }
+ else
+ {
+ FreeSpriteOamMatrix(&gSprites[gBattlerSpriteIds[gActiveBattler]]);
+ DestroySprite(&gSprites[gBattlerSpriteIds[gActiveBattler]]);
+ SetHealthboxSpriteInvisible(gHealthboxSpriteIds[gActiveBattler]);
+ PokedudeBufferExecCompleted();
+ }
+}
+
+static void PokedudeHandleDrawTrainerPic(void)
+{
+ if (GetBattlerSide(gActiveBattler) == B_SIDE_PLAYER)
+ {
+ DecompressTrainerBackPalette(4, gActiveBattler);
+ SetMultiuseSpriteTemplateToTrainerBack(4, GetBattlerPosition(gActiveBattler));
+ gBattlerSpriteIds[gActiveBattler] = CreateSprite(&gMultiuseSpriteTemplate,
+ 80,
+ (8 - gTrainerBackPicCoords[4].size) * 4 + 80,
+ 30);
+ gSprites[gBattlerSpriteIds[gActiveBattler]].pos2.x = 240;
+ gSprites[gBattlerSpriteIds[gActiveBattler]].data[0] = -2;
+ gSprites[gBattlerSpriteIds[gActiveBattler]].oam.paletteNum = gActiveBattler;
+ gSprites[gBattlerSpriteIds[gActiveBattler]].callback = sub_8033EEC;
+ }
+ else
+ {
+ u32 tranerPicid = TRAINER_PIC_PROFESSOR_OAK;
+ DecompressTrainerFrontPic(tranerPicid, gActiveBattler);
+ SetMultiuseSpriteTemplateToTrainerBack(tranerPicid, GetBattlerPosition(gActiveBattler));
+ gBattlerSpriteIds[gActiveBattler] = CreateSprite(&gMultiuseSpriteTemplate,
+ 176,
+ (8 - gTrainerFrontPicCoords[tranerPicid].size) * 4 + 40,
+ GetBattlerSpriteSubpriority(gActiveBattler));
+ gSprites[gBattlerSpriteIds[gActiveBattler]].pos2.x = -240;
+ gSprites[gBattlerSpriteIds[gActiveBattler]].data[0] = 2;
+ gSprites[gBattlerSpriteIds[gActiveBattler]].oam.paletteNum = IndexOfSpritePaletteTag(gTrainerFrontPicPaletteTable[tranerPicid].tag);
+ gSprites[gBattlerSpriteIds[gActiveBattler]].data[5] = gSprites[gBattlerSpriteIds[gActiveBattler]].oam.tileNum;
+ gSprites[gBattlerSpriteIds[gActiveBattler]].oam.tileNum = GetSpriteTileStartByTag(gTrainerFrontPicTable[tranerPicid].tag);
+ gSprites[gBattlerSpriteIds[gActiveBattler]].oam.affineParam = tranerPicid;
+ gSprites[gBattlerSpriteIds[gActiveBattler]].callback = sub_8033EEC;
+ }
+ gBattlerControllerFuncs[gActiveBattler] = CompleteOnBattlerSpriteCallbackDummy;
+}
+
+static void PokedudeHandleTrainerSlide(void)
+{
+ DecompressTrainerBackPalette(4, gActiveBattler);
+ SetMultiuseSpriteTemplateToTrainerBack(4, GetBattlerPosition(gActiveBattler));
+ gBattlerSpriteIds[gActiveBattler] = CreateSprite(&gMultiuseSpriteTemplate,
+ 80,
+ (8 - gTrainerBackPicCoords[4].size) * 4 + 80,
+ 30);
+ gSprites[gBattlerSpriteIds[gActiveBattler]].oam.paletteNum = gActiveBattler;
+ gSprites[gBattlerSpriteIds[gActiveBattler]].pos2.x = -96;
+ gSprites[gBattlerSpriteIds[gActiveBattler]].data[0] = 2;
+ gSprites[gBattlerSpriteIds[gActiveBattler]].callback = sub_8033EEC;
+ gBattlerControllerFuncs[gActiveBattler] = CompleteOnBattlerSpriteCallbackDummy2;
+}
+
+static void PokedudeHandleTrainerSlideBack(void)
+{
+ PokedudeBufferExecCompleted();
+}
+
+static void PokedudeHandleFaintAnimation(void)
+{
+ if (gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].animationState == 0)
+ {
+ if (gBattleSpritesDataPtr->battlerData[gActiveBattler].behindSubstitute)
+ InitAndLaunchSpecialAnimation(gActiveBattler, gActiveBattler, gActiveBattler, B_ANIM_SUBSTITUTE_TO_MON);
+ ++gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].animationState;
+ }
+ else
+ {
+ if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].specialAnimActive)
+ {
+ gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].animationState = 0;
+ if (GetBattlerSide(gActiveBattler) == B_SIDE_PLAYER)
+ {
+ HandleLowHpMusicChange(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], gActiveBattler);
+ PlaySE12WithPanning(SE_POKE_DEAD, SOUND_PAN_ATTACKER);
+ gSprites[gBattlerSpriteIds[gActiveBattler]].data[1] = 0;
+ gSprites[gBattlerSpriteIds[gActiveBattler]].data[2] = 5;
+ gSprites[gBattlerSpriteIds[gActiveBattler]].callback = sub_8012110;
+ }
+ else
+ {
+ PlaySE12WithPanning(SE_POKE_DEAD, SOUND_PAN_TARGET);
+ gSprites[gBattlerSpriteIds[gActiveBattler]].callback = SpriteCB_FaintOpponentMon;
+ }
+ gBattlerControllerFuncs[gActiveBattler] = sub_8156DCC;
+ }
+ }
+}
+
+static void PokedudeHandlePaletteFade(void)
+{
+ PokedudeBufferExecCompleted();
+}
+
+static void PokedudeHandleSuccessBallThrowAnim(void)
+{
+ gBattleSpritesDataPtr->animationData->ballThrowCaseId = BALL_3_SHAKES_SUCCESS;
+ gDoingBattleAnim = TRUE;
+ InitAndLaunchSpecialAnimation(gActiveBattler, gActiveBattler, GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT), B_ANIM_BALL_THROW);
+ gBattlerControllerFuncs[gActiveBattler] = CompleteOnSpecialAnimDone;
+}
+
+static void PokedudeHandleBallThrowAnim(void)
+{
+ u8 ballThrowCaseId = gBattleBufferA[gActiveBattler][1];
+
+ gBattleSpritesDataPtr->animationData->ballThrowCaseId = ballThrowCaseId;
+ gDoingBattleAnim = TRUE;
+ InitAndLaunchSpecialAnimation(gActiveBattler, gActiveBattler, GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT), B_ANIM_BALL_THROW);
+ gBattlerControllerFuncs[gActiveBattler] = CompleteOnSpecialAnimDone;
+}
+
+static void PokedudeHandlePause(void)
+{
+ PokedudeBufferExecCompleted();
+}
+
+static void PokedudeHandleMoveAnimation(void)
+{
+ u16 move = gBattleBufferA[gActiveBattler][1] | (gBattleBufferA[gActiveBattler][2] << 8);
+
+ gAnimMoveTurn = gBattleBufferA[gActiveBattler][3];
+ gAnimMovePower = gBattleBufferA[gActiveBattler][4] | (gBattleBufferA[gActiveBattler][5] << 8);
+ gAnimMoveDmg = gBattleBufferA[gActiveBattler][6] | (gBattleBufferA[gActiveBattler][7] << 8) | (gBattleBufferA[gActiveBattler][8] << 16) | (gBattleBufferA[gActiveBattler][9] << 24);
+ gAnimFriendship = gBattleBufferA[gActiveBattler][10];
+ gWeatherMoveAnim = gBattleBufferA[gActiveBattler][12] | (gBattleBufferA[gActiveBattler][13] << 8);
+ gAnimDisableStructPtr = (struct DisableStruct *)&gBattleBufferA[gActiveBattler][16];
+ gTransformedPersonalities[gActiveBattler] = gAnimDisableStructPtr->transformedMonPersonality;
+ if (IsMoveWithoutAnimation(move, gAnimMoveTurn)) // always returns FALSE
+ {
+ PokedudeBufferExecCompleted();
+ }
+ else
+ {
+ gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].animationState = 0;
+ gBattlerControllerFuncs[gActiveBattler] = PokedudeDoMoveAnimation;
+ }
+}
+
+static void PokedudeDoMoveAnimation(void)
+{
+ u16 move = gBattleBufferA[gActiveBattler][1] | (gBattleBufferA[gActiveBattler][2] << 8);
+
+ switch (gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].animationState)
+ {
+ case 0:
+ if (gBattleSpritesDataPtr->battlerData[gActiveBattler].behindSubstitute)
+ InitAndLaunchSpecialAnimation(gActiveBattler, gActiveBattler, gActiveBattler, B_ANIM_SUBSTITUTE_TO_MON);
+ gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].animationState = 1;
+ break;
+ case 1:
+ if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].specialAnimActive)
+ {
+ sub_8035450(0);
+ DoMoveAnim(move);
+ gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].animationState = 2;
+ }
+ break;
+ case 2:
+ gAnimScriptCallback();
+ if (!gAnimScriptActive)
+ {
+ sub_8035450(1);
+ if (gBattleSpritesDataPtr->battlerData[gActiveBattler].behindSubstitute)
+ InitAndLaunchSpecialAnimation(gActiveBattler, gActiveBattler, gActiveBattler, B_ANIM_MON_TO_SUBSTITUTE);
+ gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].animationState = 3;
+ }
+ break;
+ case 3:
+ if (!gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].specialAnimActive)
+ {
+ CopyAllBattleSpritesInvisibilities();
+ TrySetBehindSubstituteSpriteBit(gActiveBattler, gBattleBufferA[gActiveBattler][1] | (gBattleBufferA[gActiveBattler][2] << 8));
+ gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].animationState = 0;
+ PokedudeBufferExecCompleted();
+ }
+ break;
+ }
+}
+
+static void PokedudeHandlePrintString(void)
+{
+ u16 *stringId;
+
+ gBattle_BG0_X = 0;
+ gBattle_BG0_Y = 0;
+ stringId = (u16 *)(&gBattleBufferA[gActiveBattler][2]);
+ BufferStringBattle(*stringId);
+ if (sub_80D89B0(*stringId))
+ BattlePutTextOnWindow(gDisplayedStringBattle, 64);
+ else
+ BattlePutTextOnWindow(gDisplayedStringBattle, 0);
+ gBattlerControllerFuncs[gActiveBattler] = CompleteOnInactiveTextPrinter;
+}
+
+static void PokedudeHandlePrintSelectionString(void)
+{
+ if (GetBattlerSide(gActiveBattler) == B_SIDE_PLAYER)
+ PokedudeHandlePrintString();
+ else
+ PokedudeBufferExecCompleted();
+}
+
+static void sub_8158B20(void)
+{
+ if (!IsDma3ManagerBusyWithBgCopy())
+ {
+ gBattle_BG0_X = 0;
+ gBattle_BG0_Y = 160;
+ gBattlerControllerFuncs[gActiveBattler] = sub_8156140;
+ }
+}
+
+static void PokedudeHandleChooseAction(void)
+{
+ s32 i;
+
+ if (GetBattlerSide(gActiveBattler) == B_SIDE_PLAYER)
+ {
+ gBattlerControllerFuncs[gActiveBattler] = sub_8158B20;
+ BattlePutTextOnWindow(gUnknown_83FDA4C, 0);
+ BattlePutTextOnWindow(gUnknown_83FE725, 2);
+ for (i = 0; i < MAX_MON_MOVES; ++i)
+ ActionSelectionDestroyCursorAt((u8)i);
+ ActionSelectionCreateCursorAt(gActionSelectionCursor[gActiveBattler], 0);
+ BattleStringExpandPlaceholdersToDisplayedString(gText_WhatWillPkmnDo);
+ BattlePutTextOnWindow(gDisplayedStringBattle, 1);
+ }
+ else
+ {
+ gBattlerControllerFuncs[gActiveBattler] = sub_8156140;
+ }
+}
+
+static void PokedudeHandleUnknownYesNoBox(void)
+{
+ PokedudeBufferExecCompleted();
+}
+
+static void sub_8158C04(void)
+{
+ if (!IsDma3ManagerBusyWithBgCopy())
+ {
+ gBattle_BG0_X = 0;
+ gBattle_BG0_Y = 320;
+ gBattlerControllerFuncs[gActiveBattler] = sub_81564E4;
+ }
+}
+
+static void PokedudeHandleChooseMove(void)
+{
+ if (GetBattlerSide(gActiveBattler) == B_SIDE_PLAYER)
+ {
+ InitMoveSelectionsVarsAndStrings();
+ gBattlerControllerFuncs[gActiveBattler] = sub_8158C04;
+ }
+ else
+ {
+ gBattlerControllerFuncs[gActiveBattler] = sub_81564E4;
+ }
+}
+
+static void PokedudeHandleChooseItem(void)
+{
+ s32 i;
+
+ BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 0x10, RGB_BLACK);
+ gBattlerControllerFuncs[gActiveBattler] = OpenBagAndChooseItem;
+ gBattlerInMenuId = gActiveBattler;
+ for (i = 0; i < 3; ++i)
+ gUnknown_203B0DC[i] = gBattleBufferA[gActiveBattler][i + 1];
+}
+
+static void PokedudeHandleChoosePokemon(void)
+{
+ s32 i;
+
+ gUnknown_3004FFC[gActiveBattler] = CreateTask(TaskDummy, 0xFF);
+ gTasks[gUnknown_3004FFC[gActiveBattler]].data[0] = gBattleBufferA[gActiveBattler][1] & 0xF;
+ *(&gBattleStruct->battlerPreventingSwitchout) = gBattleBufferA[gActiveBattler][1] >> 4;
+ *(&gBattleStruct->field_8B) = gBattleBufferA[gActiveBattler][2];
+ *(&gBattleStruct->abilityPreventingSwitchout) = gBattleBufferA[gActiveBattler][3];
+ for (i = 0; i < 3; ++i)
+ gUnknown_203B0DC[i] = gBattleBufferA[gActiveBattler][4 + i];
+ BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 0x10, RGB_BLACK);
+ gBattlerControllerFuncs[gActiveBattler] = OpenPartyMenuToChooseMon;
+ gBattlerInMenuId = gActiveBattler;
+}
+
+static void PokedudeHandleCmd23(void)
+{
+ PokedudeBufferExecCompleted();
+}
+
+static void PokedudeHandleHealthBarUpdate(void)
+{
+ s16 hpVal;
+ struct Pokemon *mon;
+
+ if (GetBattlerSide(gActiveBattler) == B_SIDE_PLAYER)
+ mon = &gPlayerParty[gBattlerPartyIndexes[gActiveBattler]];
+ else
+ mon = &gEnemyParty[gBattlerPartyIndexes[gActiveBattler]];
+ LoadBattleBarGfx(0);
+ hpVal = gBattleBufferA[gActiveBattler][2] | (gBattleBufferA[gActiveBattler][3] << 8);
+ if (hpVal != INSTANT_HP_BAR_DROP)
+ {
+ u32 maxHP = GetMonData(mon, MON_DATA_MAX_HP);
+ u32 curHP = GetMonData(mon, MON_DATA_HP);
+
+ SetBattleBarStruct(gActiveBattler, gHealthboxSpriteIds[gActiveBattler], maxHP, curHP, hpVal);
+ }
+ else
+ {
+ u32 maxHP = GetMonData(mon, MON_DATA_MAX_HP);
+
+ SetBattleBarStruct(gActiveBattler, gHealthboxSpriteIds[gActiveBattler], maxHP, 0, hpVal);
+ UpdateHpTextInHealthbox(gHealthboxSpriteIds[gActiveBattler], 0, HP_CURRENT);
+ }
+ gBattlerControllerFuncs[gActiveBattler] = CompleteOnHealthbarDone;
+}
+
+static void PokedudeHandleExpUpdate(void)
+{
+ u8 monId = gBattleBufferA[gActiveBattler][1];
+
+ if (GetMonData(&gPlayerParty[monId], MON_DATA_LEVEL) >= MAX_LEVEL)
+ {
+ PokedudeBufferExecCompleted();
+ }
+ else
+ {
+ s16 expPointsToGive;
+ u8 taskId;
+
+ LoadBattleBarGfx(1);
+ GetMonData(&gPlayerParty[monId], MON_DATA_SPECIES); // Unused return value.
+ expPointsToGive = T1_READ_16(&gBattleBufferA[gActiveBattler][2]);
+ taskId = CreateTask(Task_GiveExpToMon, 10);
+ gTasks[taskId].tExpTask_monId = monId;
+ gTasks[taskId].tExpTask_gainedExp = expPointsToGive;
+ gTasks[taskId].tExpTask_battler = gActiveBattler;
+ gBattlerControllerFuncs[gActiveBattler] = nullsub_99;
+ }
+}
+
+static void PokedudeHandleStatusIconUpdate(void)
+{
+ if (!mplay_80342A4(gActiveBattler))
+ {
+ u8 battlerId;
+ struct Pokemon *mon;
+
+ if (GetBattlerSide(gActiveBattler) == B_SIDE_PLAYER)
+ mon = &gPlayerParty[gBattlerPartyIndexes[gActiveBattler]];
+ else
+ mon = &gEnemyParty[gBattlerPartyIndexes[gActiveBattler]];
+ UpdateHealthboxAttribute(gHealthboxSpriteIds[gActiveBattler], mon, HEALTHBOX_STATUS_ICON);
+ battlerId = gActiveBattler;
+ gBattleSpritesDataPtr->healthBoxesData[battlerId].statusAnimActive = FALSE;
+ gBattlerControllerFuncs[gActiveBattler] = CompleteOnFinishedStatusAnimation;
+ }
+}
+
+static void PokedudeHandleStatusAnimation(void)
+{
+ if (!mplay_80342A4(gActiveBattler))
+ {
+ InitAndLaunchChosenStatusAnimation(gBattleBufferA[gActiveBattler][1],
+ gBattleBufferA[gActiveBattler][2] | (gBattleBufferA[gActiveBattler][3] << 8) | (gBattleBufferA[gActiveBattler][4] << 16) | (gBattleBufferA[gActiveBattler][5] << 24));
+ gBattlerControllerFuncs[gActiveBattler] = CompleteOnFinishedStatusAnimation;
+ }
+}
+
+static void PokedudeHandleStatusXor(void)
+{
+ struct Pokemon *mon;
+ u8 val;
+
+ if (GetBattlerSide(gActiveBattler) == B_SIDE_PLAYER)
+ mon = &gPlayerParty[gBattlerPartyIndexes[gActiveBattler]];
+ else
+ mon = &gEnemyParty[gBattlerPartyIndexes[gActiveBattler]];
+ val = GetMonData(mon, MON_DATA_STATUS) ^ gBattleBufferA[gActiveBattler][1];
+ SetMonData(mon, MON_DATA_STATUS, &val);
+ PokedudeBufferExecCompleted();
+}
+
+static void PokedudeHandleDataTransfer(void)
+{
+ PokedudeBufferExecCompleted();
+}
+
+static void PokedudeHandleDMA3Transfer(void)
+{
+ PokedudeBufferExecCompleted();
+}
+
+static void PokedudeHandlePlayBGM(void)
+{
+ PokedudeBufferExecCompleted();
+}
+
+static void PokedudeHandleCmd32(void)
+{
+ PokedudeBufferExecCompleted();
+}
+
+static void PokedudeHandleTwoReturnValues(void)
+{
+ PokedudeBufferExecCompleted();
+}
+
+static void PokedudeHandleChosenMonReturnValue(void)
+{
+ PokedudeBufferExecCompleted();
+}
+
+static void PokedudeHandleOneReturnValue(void)
+{
+ PokedudeBufferExecCompleted();
+}
+
+static void PokedudeHandleOneReturnValue_Duplicate(void)
+{
+ PokedudeBufferExecCompleted();
+}
+
+static void PokedudeHandleCmd37(void)
+{
+ PokedudeBufferExecCompleted();
+}
+
+static void PokedudeHandleCmd38(void)
+{
+ PokedudeBufferExecCompleted();
+}
+
+static void PokedudeHandleCmd39(void)
+{
+ PokedudeBufferExecCompleted();
+}
+
+static void PokedudeHandleCmd40(void)
+{
+ PokedudeBufferExecCompleted();
+}
+
+static void PokedudeHandleHitAnimation(void)
+{
+ if (gSprites[gBattlerSpriteIds[gActiveBattler]].invisible == TRUE)
+ {
+ PokedudeBufferExecCompleted();
+ }
+ else
+ {
+ gDoingBattleAnim = TRUE;
+ gSprites[gBattlerSpriteIds[gActiveBattler]].data[1] = 0;
+ DoHitAnimHealthboxEffect(gActiveBattler);
+ gBattlerControllerFuncs[gActiveBattler] = DoHitAnimBlinkSpriteEffect;
+ }
+}
+
+static void PokedudeHandleCmd42(void)
+{
+ PokedudeBufferExecCompleted();
+}
+
+static void PokedudeHandlePlaySE(void)
+{
+ PlaySE(gBattleBufferA[gActiveBattler][1] | (gBattleBufferA[gActiveBattler][2] << 8));
+ PokedudeBufferExecCompleted();
+}
+
+static void PokedudeHandlePlayFanfare(void)
+{
+ PlayFanfare(gBattleBufferA[gActiveBattler][1] | (gBattleBufferA[gActiveBattler][2] << 8));
+ PokedudeBufferExecCompleted();
+}
+
+static void PokedudeHandleFaintingCry(void)
+{
+ struct Pokemon *mon;
+ u16 species;
+
+ if (GetBattlerSide(gActiveBattler) == B_SIDE_PLAYER)
+ mon = &gPlayerParty[gBattlerPartyIndexes[gActiveBattler]];
+ else
+ mon = &gEnemyParty[gBattlerPartyIndexes[gActiveBattler]];
+ species = GetMonData(mon, MON_DATA_SPECIES);
+ PlayCry1(species, 25);
+ PokedudeBufferExecCompleted();
+}
+
+static void PokedudeHandleIntroSlide(void)
+{
+ HandleIntroSlide(gBattleBufferA[gActiveBattler][1]);
+ gIntroSlideFlags |= 1;
+ PokedudeBufferExecCompleted();
+}
+
+static void PokedudeHandleIntroTrainerBallThrow(void)
+{
+ u8 paletteNum;
+ u8 taskId;
+
+ SetSpritePrimaryCoordsFromSecondaryCoords(&gSprites[gBattlerSpriteIds[gActiveBattler]]);
+ gSprites[gBattlerSpriteIds[gActiveBattler]].data[0] = 50;
+ gSprites[gBattlerSpriteIds[gActiveBattler]].data[2] = -40;
+ gSprites[gBattlerSpriteIds[gActiveBattler]].data[4] = gSprites[gBattlerSpriteIds[gActiveBattler]].pos1.y;
+ gSprites[gBattlerSpriteIds[gActiveBattler]].callback = StartAnimLinearTranslation;
+ gSprites[gBattlerSpriteIds[gActiveBattler]].data[5] = gActiveBattler;
+ StoreSpriteCallbackInData6(&gSprites[gBattlerSpriteIds[gActiveBattler]], sub_80335F8);
+ StartSpriteAnim(&gSprites[gBattlerSpriteIds[gActiveBattler]], 1);
+ paletteNum = AllocSpritePalette(0xD6F8);
+ LoadCompressedPalette(gTrainerBackPicPaletteTable[4].data, 0x100 + paletteNum * 16, 32);
+ gSprites[gBattlerSpriteIds[gActiveBattler]].oam.paletteNum = paletteNum;
+ taskId = CreateTask(sub_81595EC, 5);
+ gTasks[taskId].data[0] = gActiveBattler;
+ if (gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].partyStatusSummaryShown)
+ gTasks[gBattlerStatusSummaryTaskId[gActiveBattler]].func = Task_HidePartyStatusSummary;
+ gBattleSpritesDataPtr->animationData->field_9_x1 = 1;
+ gBattlerControllerFuncs[gActiveBattler] = nullsub_99;
+}
+
+static void sub_8159478(u8 battlerId)
+{
+ u16 species;
+
+ gBattleSpritesDataPtr->battlerData[battlerId].transformSpecies = SPECIES_NONE;
+ gBattlerPartyIndexes[battlerId] = gBattleBufferA[battlerId][1];
+ species = GetMonData(&gPlayerParty[gBattlerPartyIndexes[battlerId]], MON_DATA_SPECIES);
+ gUnknown_3004FFC[battlerId] = CreateInvisibleSpriteWithCallback(sub_8033E3C);
+ SetMultiuseSpriteTemplateToPokemon(species, GetBattlerPosition(battlerId));
+ gBattlerSpriteIds[battlerId] = CreateSprite(&gMultiuseSpriteTemplate,
+ GetBattlerSpriteCoord(battlerId, 2),
+ GetBattlerSpriteDefault_Y(battlerId),
+ GetBattlerSpriteSubpriority(battlerId));
+ gSprites[gUnknown_3004FFC[battlerId]].data[1] = gBattlerSpriteIds[battlerId];
+ gSprites[gBattlerSpriteIds[battlerId]].data[0] = battlerId;
+ gSprites[gBattlerSpriteIds[battlerId]].data[2] = species;
+ gSprites[gBattlerSpriteIds[battlerId]].oam.paletteNum = battlerId;
+ StartSpriteAnim(&gSprites[gBattlerSpriteIds[battlerId]], gBattleMonForms[battlerId]);
+ gSprites[gBattlerSpriteIds[battlerId]].invisible = TRUE;
+ gSprites[gBattlerSpriteIds[battlerId]].callback = SpriteCallbackDummy;
+ gSprites[gUnknown_3004FFC[battlerId]].data[0] = DoPokeballSendOutAnimation(0, POKEBALL_PLAYER_SENDOUT);
+}
+
+static void sub_81595EC(u8 taskId)
+{
+ if (gTasks[taskId].data[1] < 31)
+ {
+ ++gTasks[taskId].data[1];
+ }
+ else
+ {
+ u8 savedActiveBattler = gActiveBattler;
+
+ gActiveBattler = gTasks[taskId].data[0];
+ gBattleBufferA[gActiveBattler][1] = gBattlerPartyIndexes[gActiveBattler];
+ sub_8159478(gActiveBattler);
+ gBattlerControllerFuncs[gActiveBattler] = sub_8156624;
+ gActiveBattler = savedActiveBattler;
+ DestroyTask(taskId);
+ }
+}
+
+static void PokedudeHandleDrawPartyStatusSummary(void)
+{
+ if (gBattleBufferA[gActiveBattler][1] != 0
+ && GetBattlerSide(gActiveBattler) == B_SIDE_PLAYER)
+ {
+ PokedudeBufferExecCompleted();
+ }
+ else
+ {
+ gBattleSpritesDataPtr->healthBoxesData[gActiveBattler].partyStatusSummaryShown = TRUE;
+ gBattlerStatusSummaryTaskId[gActiveBattler] = CreatePartyStatusSummarySprites(gActiveBattler,
+ (struct HpAndStatus *)&gBattleBufferA[gActiveBattler][4],
+ gBattleBufferA[gActiveBattler][1],
+ gBattleBufferA[gActiveBattler][2]);
+ PokedudeBufferExecCompleted();
+ }
+}
+
+static void PokedudeHandleHidePartyStatusSummary(void)
+{
+ PokedudeBufferExecCompleted();
+}
+
+static void PokedudeHandleEndBounceEffect(void)
+{
+ EndBounceEffect(gActiveBattler, BOUNCE_HEALTHBOX);
+ EndBounceEffect(gActiveBattler, BOUNCE_MON);
+ PokedudeBufferExecCompleted();
+}
+
+static void PokedudeHandleSpriteInvisibility(void)
+{
+ PokedudeBufferExecCompleted();
+}
+
+static void PokedudeHandleBattleAnimation(void)
+{
+ u8 animationId = gBattleBufferA[gActiveBattler][1];
+ u16 argument = gBattleBufferA[gActiveBattler][2] | (gBattleBufferA[gActiveBattler][3] << 8);
+
+ if (TryHandleLaunchBattleTableAnimation(gActiveBattler, gActiveBattler, gActiveBattler, animationId, argument))
+ PokedudeBufferExecCompleted();
+ else
+ gBattlerControllerFuncs[gActiveBattler] = CompleteOnFinishedBattleAnimation;
+}
+
+static void PokedudeHandleLinkStandbyMsg(void)
+{
+ switch (gBattleBufferA[gActiveBattler][1])
+ {
+ case 0:
+ case 1:
+ EndBounceEffect(gActiveBattler, BOUNCE_HEALTHBOX);
+ EndBounceEffect(gActiveBattler, BOUNCE_MON);
+ break;
+ case 2:
+ break;
+ }
+ PokedudeBufferExecCompleted();
+}
+
+static void PokedudeHandleResetActionMoveSelection(void)
+{
+ PokedudeBufferExecCompleted();
+}
+
+static void PokedudeHandleCmd55(void)
+{
+ gBattleOutcome = gBattleBufferA[gActiveBattler][1];
+ FadeOutMapMusic(5);
+ BeginFastPaletteFade(3);
+ PokedudeBufferExecCompleted();
+ if (!(gBattleTypeFlags & BATTLE_TYPE_IS_MASTER) && gBattleTypeFlags & BATTLE_TYPE_LINK)
+ gBattlerControllerFuncs[gActiveBattler] = sub_8156254;
+}
+
+static void PokedudeCmdEnd(void)
+{
+}
+
+static void sub_8159824(void)
+{
+ const u8 (*r7)[8] = gUnknown_8479060[gBattleStruct->field_96];
+
+ if (GetBattlerSide(gActiveBattler) == B_SIDE_PLAYER)
+ {
+ DoBounceEffect(gActiveBattler, BOUNCE_HEALTHBOX, 7, 1);
+ DoBounceEffect(gActiveBattler, BOUNCE_MON, 7, 1);
+ }
+ if (*(r7[gUnknown_3005EE0[gActiveBattler][0]] + gActiveBattler + 4) == gUnknown_3005EE0[gActiveBattler][2])
+ {
+ if (GetBattlerSide(gActiveBattler) == B_SIDE_PLAYER)
+ PlaySE(SE_SELECT);
+ gUnknown_3005EE0[gActiveBattler][2] = 0;
+ switch (r7[gUnknown_3005EE0[gActiveBattler][0]][gActiveBattler])
+ {
+ case 0:
+ BtlController_EmitTwoReturnValues(1, B_ACTION_USE_MOVE, 0);
+ break;
+ case 1:
+ BtlController_EmitTwoReturnValues(1, B_ACTION_USE_ITEM, 0);
+ break;
+ case 2:
+ BtlController_EmitTwoReturnValues(1, B_ACTION_SWITCH, 0);
+ break;
+ case 3:
+ BtlController_EmitTwoReturnValues(1, B_ACTION_RUN, 0);
+ break;
+ }
+ PokedudeBufferExecCompleted();
+ ++gUnknown_3005EE0[gActiveBattler][0];
+ if (r7[gUnknown_3005EE0[gActiveBattler][0]][gActiveBattler] == 4)
+ gUnknown_3005EE0[gActiveBattler][0] = 0;
+ }
+ else
+ {
+ if (gActionSelectionCursor[gActiveBattler] != r7[gUnknown_3005EE0[gActiveBattler][0]][gActiveBattler]
+ && r7[gUnknown_3005EE0[gActiveBattler][0]][gActiveBattler + 4] / 2 == gUnknown_3005EE0[gActiveBattler][2])
+ {
+ PlaySE(SE_SELECT);
+ ActionSelectionDestroyCursorAt(gActionSelectionCursor[gActiveBattler]);
+ gActionSelectionCursor[gActiveBattler] = r7[gUnknown_3005EE0[gActiveBattler][0]][gActiveBattler];
+ ActionSelectionCreateCursorAt(gActionSelectionCursor[gActiveBattler], 0);
+ }
+ ++gUnknown_3005EE0[gActiveBattler][2];
+ }
+}
+
+static void sub_8159998(void)
+{
+ const u8 (*r7)[8] = gUnknown_84790D8[gBattleStruct->field_96];
+
+ if (*(r7[gUnknown_3005EE0[gActiveBattler][1]] + gActiveBattler + 4) == gUnknown_3005EE0[gActiveBattler][2])
+ {
+ if (GetBattlerSide(gActiveBattler) == B_SIDE_PLAYER)
+ PlaySE(SE_SELECT);
+ gUnknown_3005EE0[gActiveBattler][2] = 0;
+ BtlController_EmitTwoReturnValues(1,
+ B_ACTION_EXEC_SCRIPT,
+ r7[gUnknown_3005EE0[gActiveBattler][1]][gActiveBattler] | ((gActiveBattler ^ BIT_SIDE) << 8));
+ PokedudeBufferExecCompleted();
+ ++gUnknown_3005EE0[gActiveBattler][1];
+ if (r7[gUnknown_3005EE0[gActiveBattler][1]][gActiveBattler] == 255)
+ gUnknown_3005EE0[gActiveBattler][1] = 0;
+ }
+ else
+ {
+ if (r7[gUnknown_3005EE0[gActiveBattler][1]][gActiveBattler] != gMoveSelectionCursor[gActiveBattler]
+ && r7[gUnknown_3005EE0[gActiveBattler][1]][gActiveBattler + 4] / 2 == gUnknown_3005EE0[gActiveBattler][2])
+ {
+ PlaySE(SE_SELECT);
+ MoveSelectionDestroyCursorAt(gMoveSelectionCursor[gActiveBattler]);
+ gMoveSelectionCursor[gActiveBattler] = r7[gUnknown_3005EE0[gActiveBattler][1]][gActiveBattler];
+ MoveSelectionCreateCursorAt(gMoveSelectionCursor[gActiveBattler], 0);
+ }
+ ++gUnknown_3005EE0[gActiveBattler][2];
+ }
+}
+
+#ifdef NONMATCHING
+static bool8 sub_8159AB8(void)
+{
+ const struct Unk_84790E8 *r6 = gUnknown_8479198[gBattleStruct->field_96];
+ // why is address of unk_2 loaded first?
+ const struct Unk_84790E8 *r12 = (const struct Unk_84790E8 *)gBattleBufferA[gActiveBattler];
+
+ if (r12->unk_0 == r6[gBattleStruct->field_97].unk_0
+ && gActiveBattler == r6[gBattleStruct->field_97].unk_1
+ && (r12->unk_0 != 16 || r6[gBattleStruct->field_97].unk_2 == r12->unk_2))
+ {
+ // why is mem reloaded here?
+ // asm("":::"memory");
+ if (r6[gBattleStruct->field_97].unk_4 != NULL)
+ {
+ gBattlerControllerFuncs[gActiveBattler] = r6[gBattleStruct->field_97].unk_4;
+ gUnknown_3005EE0[gActiveBattler][2] = 0;
+ gUnknown_3005EE0[gActiveBattler][3] = r6[gBattleStruct->field_97].unk_2;
+ ++gBattleStruct->field_97;
+ return TRUE;
+ }
+ ++gBattleStruct->field_97;
+ }
+ return FALSE;
+}
+#else
+NAKED
+static bool8 sub_8159AB8(void)
+{
+ asm_unified("\n\
+ push {r4-r7,lr}\n\
+ ldr r1, _08159B54 @ =gUnknown_8479198\n\
+ ldr r4, _08159B58 @ =gBattleStruct\n\
+ ldr r2, [r4]\n\
+ adds r0, r2, 0\n\
+ adds r0, 0x96\n\
+ ldrb r0, [r0]\n\
+ lsls r0, 2\n\
+ adds r0, r1\n\
+ ldr r6, [r0]\n\
+ ldr r3, _08159B5C @ =gActiveBattler\n\
+ ldrb r5, [r3]\n\
+ lsls r1, r5, 9\n\
+ ldr r0, _08159B60 @ =gBattleBufferA + 2\n\
+ adds r7, r1, r0\n\
+ mov r12, r7\n\
+ subs r0, 0x2\n\
+ adds r1, r0\n\
+ adds r2, 0x97\n\
+ ldrb r0, [r2]\n\
+ lsls r0, 3\n\
+ adds r0, r6\n\
+ ldrb r1, [r1]\n\
+ adds r7, r4, 0\n\
+ adds r4, r3, 0\n\
+ ldrb r2, [r0]\n\
+ cmp r1, r2\n\
+ bne _08159B70\n\
+ ldrb r2, [r0, 0x1]\n\
+ cmp r5, r2\n\
+ bne _08159B70\n\
+ cmp r1, 0x10\n\
+ bne _08159B04\n\
+ ldrh r0, [r0, 0x2]\n\
+ mov r1, r12\n\
+ ldrh r1, [r1]\n\
+ cmp r0, r1\n\
+ bne _08159B70\n\
+ _08159B04:\n\
+ ldr r0, [r7]\n\
+ adds r3, r0, 0\n\
+ adds r3, 0x97\n\
+ ldrb r1, [r3]\n\
+ lsls r0, r1, 3\n\
+ adds r0, r6\n\
+ ldr r2, [r0, 0x4]\n\
+ cmp r2, 0\n\
+ beq _08159B6C\n\
+ ldr r1, _08159B64 @ =gBattlerControllerFuncs\n\
+ ldrb r0, [r4]\n\
+ lsls r0, 2\n\
+ adds r0, r1\n\
+ str r2, [r0]\n\
+ ldr r2, _08159B68 @ =gUnknown_3005EE0\n\
+ ldrb r0, [r4]\n\
+ lsls r0, 2\n\
+ adds r0, r2\n\
+ ldr r1, [r0]\n\
+ movs r0, 0\n\
+ strb r0, [r1, 0x2]\n\
+ ldrb r0, [r4]\n\
+ lsls r0, 2\n\
+ adds r0, r2\n\
+ ldr r1, [r0]\n\
+ ldr r0, [r7]\n\
+ adds r0, 0x97\n\
+ ldrb r0, [r0]\n\
+ lsls r0, 3\n\
+ adds r0, r6\n\
+ ldrh r0, [r0, 0x2]\n\
+ strb r0, [r1, 0x3]\n\
+ ldr r1, [r7]\n\
+ adds r1, 0x97\n\
+ ldrb r0, [r1]\n\
+ adds r0, 0x1\n\
+ strb r0, [r1]\n\
+ movs r0, 0x1\n\
+ b _08159B72\n\
+ .align 2, 0\n\
+ _08159B54: .4byte gUnknown_8479198\n\
+ _08159B58: .4byte gBattleStruct\n\
+ _08159B5C: .4byte gActiveBattler\n\
+ _08159B60: .4byte gBattleBufferA + 2\n\
+ _08159B64: .4byte gBattlerControllerFuncs\n\
+ _08159B68: .4byte gUnknown_3005EE0\n\
+ _08159B6C:\n\
+ adds r0, r1, 0x1\n\
+ strb r0, [r3]\n\
+ _08159B70:\n\
+ movs r0, 0\n\
+ _08159B72:\n\
+ pop {r4-r7}\n\
+ pop {r1}\n\
+ bx r1\n\
+ ");
+}
+#endif
+
+static void sub_8159B78(void)
+{
+ gUnknown_3005EE0[gActiveBattler][2] = 0;
+ gBattlerControllerFuncs[gActiveBattler] = PokedudeBufferRunCommand;
+}
+
+static void sub_8159BA8(void)
+{
+ switch (gUnknown_3005EE0[gActiveBattler][2])
+ {
+ case 0:
+ if (!gPaletteFade.active)
+ {
+ BeginNormalPaletteFade(0xFFFFFF7F, 4, 0, 8, RGB_BLACK);
+ ++gUnknown_3005EE0[gActiveBattler][2];
+ }
+ break;
+ case 1:
+ if (!gPaletteFade.active)
+ {
+ gUnknown_3005EE0[gActiveBattler][4] = gBattle_BG0_Y;
+ sub_80EB30C();
+ ++gUnknown_3005EE0[gActiveBattler][2];
+ }
+ break;
+ case 2:
+ gBattle_BG0_Y = 0;
+ BattleStringExpandPlaceholdersToDisplayedString(sub_8159EF0());
+ BattlePutTextOnWindow(gDisplayedStringBattle, 24);
+ ++gUnknown_3005EE0[gActiveBattler][2];
+ break;
+ case 3:
+ if (!IsTextPrinterActive(24) && JOY_NEW(A_BUTTON))
+ {
+ PlaySE(SE_SELECT);
+ BeginNormalPaletteFade(0xFFFFFF7F, 4, 8, 0, RGB_BLACK);
+ ++gUnknown_3005EE0[gActiveBattler][2];
+ }
+ break;
+ case 4:
+ if (!gPaletteFade.active)
+ {
+ if (gUnknown_3005EE0[gActiveBattler][3] == 13)
+ {
+ BattleStopLowHpSound();
+ PlayBGM(MUS_WIN_YASEI);
+ }
+ gBattle_BG0_Y = gUnknown_3005EE0[gActiveBattler][4];
+ sub_80EB524();
+ sub_8159B78();
+ }
+ break;
+ }
+}
+
+static void sub_8159D04(void)
+{
+ switch (gUnknown_3005EE0[gActiveBattler][2])
+ {
+ case 0:
+ if (!gPaletteFade.active)
+ {
+ sub_80EEFC8(&gBattleStruct->field_95,
+ &gBattleStruct->field_94,
+ GetBattlerAtPosition(B_POSITION_PLAYER_LEFT));
+ BeginNormalPaletteFade(0xFFFFFF7F, 4, 0, 8, RGB_BLACK);
+ ++gUnknown_3005EE0[gActiveBattler][2];
+ }
+ break;
+ case 1:
+ if (!gPaletteFade.active)
+ {
+ u32 mask = (gBitTable[gBattleStruct->field_95] | gBitTable[gBattleStruct->field_94]) << 16;
+
+ ++mask; // It's possible that this is influenced by other functions, as
+ --mask; // this also striked in battle_controller_oak_old_man.c but was naturally fixed.
+ BeginNormalPaletteFade(mask, 4, 8, 0, RGB_BLACK);
+ ++gUnknown_3005EE0[gActiveBattler][2];
+ }
+ break;
+ case 2:
+ if (!gPaletteFade.active)
+ {
+ sub_80EB30C();
+ ++gUnknown_3005EE0[gActiveBattler][2];
+ }
+ break;
+ case 3:
+ BattleStringExpandPlaceholdersToDisplayedString(sub_8159EF0());
+ BattlePutTextOnWindow(gDisplayedStringBattle, 24);
+ ++gUnknown_3005EE0[gActiveBattler][2];
+ break;
+ case 4:
+ if (!IsTextPrinterActive(24) && JOY_NEW(A_BUTTON))
+ {
+ u32 mask;
+
+ PlaySE(SE_SELECT);
+ mask = (gBitTable[gBattleStruct->field_95] | gBitTable[gBattleStruct->field_94]) << 16;
+ ++mask;
+ --mask;
+ BeginNormalPaletteFade(mask, 4, 0, 8, RGB_BLACK);
+ ++gUnknown_3005EE0[gActiveBattler][2];
+ }
+ break;
+ case 5:
+ if (!gPaletteFade.active)
+ {
+ BeginNormalPaletteFade(0xFFFFFF7F, 4, 8, 0, RGB_BLACK);
+ ++gUnknown_3005EE0[gActiveBattler][2];
+ }
+ break;
+ case 6:
+ if (!gPaletteFade.active)
+ {
+ if (gUnknown_3005EE0[gActiveBattler][3] == 13)
+ {
+ BattleStopLowHpSound();
+ PlayBGM(MUS_WIN_YASEI);
+ }
+ sub_80EF0E0(GetBattlerAtPosition(B_POSITION_PLAYER_LEFT));
+ sub_80EB524();
+ sub_8159B78();
+ }
+ break;
+ }
+}
+
+static const u8 *sub_8159EF0(void)
+{
+ switch (gBattleStruct->field_96)
+ {
+ case 0:
+ default:
+ return gUnknown_84791A8[gBattleStruct->field_97 - 1];
+ case 1:
+ return gUnknown_84791B8[gBattleStruct->field_97 - 1];
+ case 2:
+ return gUnknown_84791CC[gBattleStruct->field_97 - 1];
+ case 3:
+ return gUnknown_84791E8[gBattleStruct->field_97 - 1];
+ }
+}
+
+void InitPokedudePartyAndOpponent(void)
+{
+ s32 i, j;
+ struct Pokemon *mon;
+ s32 myIdx = 0;
+ s32 opIdx = 0;
+ const struct PokedudeBattlePartyInfo *data;
+
+ gBattleTypeFlags = BATTLE_TYPE_POKEDUDE;
+ ZeroPlayerPartyMons();
+ ZeroEnemyPartyMons();
+ data = sPokedudeBattlePartyPointers[gSpecialVar_0x8004];
+ i = 0;
+ do
+ {
+ if (data[i].side == B_SIDE_PLAYER)
+ mon = &gPlayerParty[myIdx++];
+ else
+ mon = &gEnemyParty[opIdx++];
+ CreateMonWithGenderNatureLetter(mon, data[i].species, data[i].level, 0, data[i].gender, data[i].nature, 0);
+ for (j = 0; j < 4; ++j)
+ SetMonMoveSlot(mon, data[i].moves[j], j);
+ } while (data[++i].side != 0xFF);
+}
diff --git a/src/battle_controllers.c b/src/battle_controllers.c
index f3530fc4b..6fb090307 100644
--- a/src/battle_controllers.c
+++ b/src/battle_controllers.c
@@ -85,9 +85,9 @@ static void InitSinglePlayerBtlControllers(void)
gBattleMainFunc = BeginBattleIntro;
if (gBattleTypeFlags & BATTLE_TYPE_POKEDUDE)
{
- gBattlerControllerFuncs[0] = SetControllerToPokeDude;
+ gBattlerControllerFuncs[0] = SetControllerToPokedude;
gBattlerPositions[0] = B_POSITION_PLAYER_LEFT;
- gBattlerControllerFuncs[1] = SetControllerToPokeDude;
+ gBattlerControllerFuncs[1] = SetControllerToPokedude;
gBattlerPositions[1] = B_POSITION_OPPONENT_LEFT;
gBattlersCount = 2;
}
@@ -110,13 +110,13 @@ static void InitSinglePlayerBtlControllers(void)
gBattleMainFunc = BeginBattleIntro;
if (gBattleTypeFlags & BATTLE_TYPE_POKEDUDE)
{
- gBattlerControllerFuncs[0] = SetControllerToPokeDude;
+ gBattlerControllerFuncs[0] = SetControllerToPokedude;
gBattlerPositions[0] = B_POSITION_PLAYER_LEFT;
- gBattlerControllerFuncs[1] = SetControllerToPokeDude;
+ gBattlerControllerFuncs[1] = SetControllerToPokedude;
gBattlerPositions[1] = B_POSITION_OPPONENT_LEFT;
- gBattlerControllerFuncs[2] = SetControllerToPokeDude;
+ gBattlerControllerFuncs[2] = SetControllerToPokedude;
gBattlerPositions[2] = B_POSITION_PLAYER_RIGHT;
- gBattlerControllerFuncs[3] = SetControllerToPokeDude;
+ gBattlerControllerFuncs[3] = SetControllerToPokedude;
gBattlerPositions[3] = B_POSITION_OPPONENT_RIGHT;
gBattlersCount = MAX_BATTLERS_COUNT;
}
diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c
index 181f59b09..c5c8e89a4 100644
--- a/src/battle_script_commands.c
+++ b/src/battle_script_commands.c
@@ -7064,7 +7064,7 @@ static void atk8F_forcerandomswitch(void)
u8 valid;
u8 val;
- if (!GetBattlerSide(gBattlerTarget))
+ if (GetBattlerSide(gBattlerTarget) == B_SIDE_PLAYER)
party = gPlayerParty;
else
party = gEnemyParty;
diff --git a/src/battle_setup.c b/src/battle_setup.c
index b9da39ddb..9fef6a8a5 100644
--- a/src/battle_setup.c
+++ b/src/battle_setup.c
@@ -13,7 +13,6 @@
#include "strings.h"
#include "string_util.h"
#include "event_data.h"
-#include "unk_8159F40.h"
#include "map_obj_80688E4.h"
#include "metatile_behavior.h"
#include "event_scripts.h"
@@ -28,6 +27,7 @@
#include "battle.h"
#include "battle_setup.h"
#include "battle_transition.h"
+#include "battle_controllers.h"
#include "constants/battle_setup.h"
#include "constants/flags.h"
#include "constants/items.h"
diff --git a/src/bug.c b/src/bug.c
index 9b8935744..b9f1795ab 100644
--- a/src/bug.c
+++ b/src/bug.c
@@ -172,7 +172,7 @@ static const union AffineAnimCmd gUnknown_83E733C[] =
AFFINEANIMCMD_FRAME(0x10, 0x10, 0, 0),
AFFINEANIMCMD_FRAME(0x8, 0x8, 0, 18),
AFFINEANIMCMD_LOOP(0),
- AFFINEANIMCMD_FRAME(0xFFFB, 0xFFFB, 0, 8),
+ AFFINEANIMCMD_FRAME(-0x5, -0x5, 0, 8),
AFFINEANIMCMD_FRAME(0x5, 0x5, 0, 8),
AFFINEANIMCMD_LOOP(5),
AFFINEANIMCMD_END,
@@ -202,7 +202,7 @@ static void sub_80B3FAC(struct Sprite *sprite)
gBattleAnimArgs[2] = -gBattleAnimArgs[2];
gBattleAnimArgs[0] = -gBattleAnimArgs[0];
}
- else if (!GetBattlerSide(gBattleAnimTarget))
+ else if (GetBattlerSide(gBattleAnimTarget) == B_SIDE_PLAYER)
{
StartSpriteAffineAnim(sprite, 1);
gBattleAnimArgs[1] = -gBattleAnimArgs[1];
@@ -226,7 +226,7 @@ static void sub_80B407C(struct Sprite *sprite)
gBattleAnimArgs[0] = -gBattleAnimArgs[0];
StartSpriteAffineAnim(sprite, 2);
}
- else if (!GetBattlerSide(gBattleAnimTarget))
+ else if (GetBattlerSide(gBattleAnimTarget) == B_SIDE_PLAYER)
{
gBattleAnimArgs[1] = -gBattleAnimArgs[1];
gBattleAnimArgs[0] = -gBattleAnimArgs[0];
@@ -283,12 +283,12 @@ static void sub_80B41C0(struct Sprite *sprite)
static void sub_80B41F8(struct Sprite *sprite)
{
SetAverageBattlerPositions(gBattleAnimTarget, 0, &sprite->pos1.x, &sprite->pos1.y);
- if (GetBattlerSide(gBattleAnimAttacker))
+ if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER)
sprite->pos1.x -= gBattleAnimArgs[0];
else
sprite->pos1.x += gBattleAnimArgs[0];
sprite->pos1.y += gBattleAnimArgs[1];
- if (!GetBattlerSide(gBattleAnimTarget))
+ if (GetBattlerSide(gBattleAnimTarget) == B_SIDE_PLAYER)
sprite->pos1.y += 8;
sprite->callback = sub_80B4274;
}
@@ -356,7 +356,7 @@ static void AnimTranslateStinger(struct Sprite *sprite)
{
gBattleAnimArgs[2] = -gBattleAnimArgs[2];
}
- else if (GetBattlerSide(gBattleAnimAttacker))
+ else if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER)
{
gBattleAnimArgs[2] = -gBattleAnimArgs[2];
gBattleAnimArgs[1] = -gBattleAnimArgs[1];
@@ -399,7 +399,7 @@ static void AnimTranslateStinger(struct Sprite *sprite)
static void AnimMissileArc(struct Sprite *sprite)
{
InitSpritePosToAnimAttacker(sprite, 1);
- if (GetBattlerSide(gBattleAnimAttacker))
+ if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER)
gBattleAnimArgs[2] = -gBattleAnimArgs[2];
sprite->data[0] = gBattleAnimArgs[4];
sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimTarget, 2) + gBattleAnimArgs[2];
diff --git a/src/electric.c b/src/electric.c
new file mode 100644
index 000000000..025eac48b
--- /dev/null
+++ b/src/electric.c
@@ -0,0 +1,1272 @@
+#include "global.h"
+#include "battle_anim.h"
+#include "trig.h"
+#include "sound.h"
+#include "constants/songs.h"
+
+static void sub_80ADBEC(struct Sprite *sprite);
+static void sub_80ADC58(struct Sprite *sprite);
+static void sub_80ADCB8(struct Sprite *sprite);
+static void sub_80ADD4C(struct Sprite *sprite);
+static void sub_80ADEB0(struct Sprite *sprite);
+static void sub_80AE000(struct Sprite *sprite);
+static void sub_80AE06C(struct Sprite *sprite);
+static void sub_80AE1A0(struct Sprite *sprite);
+static void sub_80AE420(struct Sprite *sprite);
+static void sub_80AE470(struct Sprite *sprite);
+static void sub_80AE71C(struct Sprite *sprite);
+static void sub_80AE774(struct Sprite *sprite);
+static void sub_80AE7DC(struct Sprite *sprite);
+static void sub_80AEC34(struct Sprite *sprite);
+static void sub_80AEC80(struct Sprite *sprite);
+static void sub_80AEF60(struct Sprite *sprite);
+static void sub_80ADC3C(struct Sprite *sprite);
+static void sub_80ADC9C(struct Sprite *sprite);
+static void sub_80ADF38(struct Sprite *sprite);
+static void sub_80AE130(struct Sprite *sprite);
+static void sub_80AE278(u8 taskId);
+static void sub_80AE4F4(struct Sprite *sprite);
+static void sub_80AE5BC(u8 taskId);
+static void sub_80AE704(struct Sprite *sprite);
+static void sub_80AE83C(struct Sprite *sprite);
+static bool8 sub_80AEB98(struct Task *task, u8 taskId);
+static bool8 sub_80AEE74(struct Task *task, u8 taskId);
+static bool8 sub_80AF058(struct Task *task, u8 taskId);
+static void sub_80AF0C8(struct Sprite *sprite);
+
+static const union AnimCmd gUnknown_83E5F1C[] =
+{
+ ANIMCMD_FRAME(0, 5),
+ ANIMCMD_FRAME(16, 5),
+ ANIMCMD_FRAME(32, 8),
+ ANIMCMD_FRAME(48, 5),
+ ANIMCMD_FRAME(64, 5),
+ ANIMCMD_END,
+};
+
+static const union AnimCmd *const gUnknown_83E5F34[] =
+{
+ gUnknown_83E5F1C,
+};
+
+const struct SpriteTemplate gUnknown_83E5F38 =
+{
+ .tileTag = ANIM_TAG_LIGHTNING,
+ .paletteTag = ANIM_TAG_LIGHTNING,
+ .oam = &gOamData_83AC9D8,
+ .anims = gUnknown_83E5F34,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = sub_80ADBEC,
+};
+
+static const union AffineAnimCmd gUnknown_83E5F50[] =
+{
+ AFFINEANIMCMD_FRAME(0x100, 0x100, 0, 0),
+ AFFINEANIMCMD_FRAME(0x0, 0x0, 0, 20),
+ AFFINEANIMCMD_FRAME(0x0, 0x0, -16, 60),
+ AFFINEANIMCMD_END,
+};
+
+static const union AffineAnimCmd *const gUnknown_83E5F70[] =
+{
+ gUnknown_83E5F50,
+};
+
+const struct SpriteTemplate gUnknown_83E5F74 =
+{
+ .tileTag = ANIM_TAG_HANDS_AND_FEET,
+ .paletteTag = ANIM_TAG_HANDS_AND_FEET,
+ .oam = &gOamData_83ACA38,
+ .anims = gDummySpriteAnimTable,
+ .images = NULL,
+ .affineAnims = gUnknown_83E5F70,
+ .callback = sub_80ADC58,
+};
+
+static const union AnimCmd gUnknown_83E5F8C[] =
+{
+ ANIMCMD_FRAME(0, 5),
+ ANIMCMD_FRAME(16, 5),
+ ANIMCMD_FRAME(32, 5),
+ ANIMCMD_FRAME(48, 5),
+ ANIMCMD_FRAME(64, 5),
+ ANIMCMD_FRAME(80, 5),
+ ANIMCMD_JUMP(0),
+};
+
+static const union AnimCmd *const gUnknown_83E5FA8[] =
+{
+ gUnknown_83E5F8C,
+};
+
+const struct SpriteTemplate gUnknown_83E5FAC =
+{
+ .tileTag = ANIM_TAG_SHOCK,
+ .paletteTag = ANIM_TAG_SHOCK,
+ .oam = &gOamData_83AC9D8,
+ .anims = gUnknown_83E5FA8,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = sub_80ADCB8,
+};
+
+const struct SpriteTemplate gUnknown_83E5FC4 =
+{
+ .tileTag = ANIM_TAG_SPARK_2,
+ .paletteTag = ANIM_TAG_SPARK_2,
+ .oam = &gOamData_83ACA30,
+ .anims = gDummySpriteAnimTable,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = sub_80ADD4C,
+};
+
+const struct SpriteTemplate gUnknown_83E5FDC =
+{
+ .tileTag = ANIM_TAG_BLACK_BALL_2,
+ .paletteTag = ANIM_TAG_BLACK_BALL_2,
+ .oam = &gOamData_83AC9D0,
+ .anims = gDummySpriteAnimTable,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = TranslateAnimSpriteToTargetMonLocation,
+};
+
+static const union AffineAnimCmd gUnknown_83E5FF4[] =
+{
+ AFFINEANIMCMD_FRAME(0x0, 0x0, 20, 1),
+ AFFINEANIMCMD_JUMP(0),
+};
+
+static const union AffineAnimCmd *const gUnknown_83E6004[] =
+{
+ gUnknown_83E5FF4,
+};
+
+const struct SpriteTemplate gUnknown_83E6008 =
+{
+ .tileTag = ANIM_TAG_SPARK_2,
+ .paletteTag = ANIM_TAG_SPARK_2,
+ .oam = &gOamData_83ACA30,
+ .anims = gDummySpriteAnimTable,
+ .images = NULL,
+ .affineAnims = gUnknown_83E6004,
+ .callback = sub_80ADEB0,
+};
+
+static const union AnimCmd gUnknown_83E6020[] =
+{
+ ANIMCMD_FRAME(0, 6),
+ ANIMCMD_FRAME(16, 6),
+ ANIMCMD_FRAME(32, 6),
+ ANIMCMD_JUMP(0),
+};
+
+static const union AnimCmd *const gUnknown_83E6030[] =
+{
+ gUnknown_83E6020,
+};
+
+static const union AffineAnimCmd gUnknown_83E6034[] =
+{
+ AFFINEANIMCMD_FRAME(0xE8, 0xE8, 0, 0),
+ AFFINEANIMCMD_FRAME(-0x8, -0x8, 0, 10),
+ AFFINEANIMCMD_FRAME(0x8, 0x8, 0, 10),
+ AFFINEANIMCMD_JUMP(1),
+};
+
+static const union AffineAnimCmd *const gUnknown_83E6054[] =
+{
+ gUnknown_83E6034,
+};
+
+const struct SpriteTemplate gUnknown_83E6058 =
+{
+ .tileTag = ANIM_TAG_SHOCK_3,
+ .paletteTag = ANIM_TAG_SHOCK_3,
+ .oam = &gOamData_83ACA38,
+ .anims = gUnknown_83E6030,
+ .images = NULL,
+ .affineAnims = gUnknown_83E6054,
+ .callback = sub_80AE000,
+};
+
+const struct SpriteTemplate gUnknown_83E6070 =
+{
+ .tileTag = ANIM_TAG_SPARK_2,
+ .paletteTag = ANIM_TAG_SPARK_2,
+ .oam = &gOamData_83ACA30,
+ .anims = gDummySpriteAnimTable,
+ .images = NULL,
+ .affineAnims = gUnknown_83E6004,
+ .callback = sub_80AE06C,
+};
+
+const struct SpriteTemplate gElectricitySpriteTemplate =
+{
+ .tileTag = ANIM_TAG_SPARK_2,
+ .paletteTag = ANIM_TAG_SPARK_2,
+ .oam = &gOamData_83AC9D0,
+ .anims = gDummySpriteAnimTable,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = sub_80AE1A0,
+};
+
+static const struct SpriteTemplate gUnknown_83E60A0 =
+{
+ .tileTag = ANIM_TAG_SPARK,
+ .paletteTag = ANIM_TAG_SPARK,
+ .oam = &gOamData_83AC9C8,
+ .anims = gDummySpriteAnimTable,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = sub_80AE420,
+};
+
+const struct SpriteTemplate gUnknown_83E60B8 =
+{
+ .tileTag = ANIM_TAG_SPARK_H,
+ .paletteTag = ANIM_TAG_SPARK_H,
+ .oam = &gOamData_83AC9F8,
+ .anims = gDummySpriteAnimTable,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = sub_80AE470,
+};
+
+static const s8 gUnknown_83E60D0[][2] =
+{
+ { 58, -60},
+ {-56, -36},
+ { 8, -56},
+ {-16, 56},
+ { 58, -10},
+ {-58, 10},
+ { 48, -18},
+ {-8, 56},
+ { 16, -56},
+ {-58, -42},
+ { 58, 30},
+ {-48, 40},
+ { 12, -48},
+ { 48, -12},
+ {-56, 18},
+ { 48, 48},
+};
+
+static const union AnimCmd gUnknown_83E60F0[] =
+{
+ ANIMCMD_FRAME(3, 1),
+ ANIMCMD_FRAME(2, 1),
+ ANIMCMD_FRAME(1, 1),
+ ANIMCMD_FRAME(0, 1),
+ ANIMCMD_END,
+};
+
+static const union AnimCmd gUnknown_83E6104[] =
+{
+ ANIMCMD_FRAME(0, 5),
+ ANIMCMD_FRAME(1, 5),
+ ANIMCMD_FRAME(2, 5),
+ ANIMCMD_FRAME(3, 5),
+ ANIMCMD_END,
+};
+
+static const union AnimCmd *const gUnknown_83E6118[] =
+{
+ gUnknown_83E60F0,
+ gUnknown_83E6104,
+};
+
+static const struct SpriteTemplate gUnknown_83E6120 =
+{
+ .tileTag = ANIM_TAG_ELECTRIC_ORBS,
+ .paletteTag = ANIM_TAG_ELECTRIC_ORBS,
+ .oam = &gOamData_83AC9C8,
+ .anims = gUnknown_83E6118,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = SpriteCallbackDummy,
+};
+
+static const union AffineAnimCmd gUnknown_83E6138[] =
+{
+ AFFINEANIMCMD_FRAME(0x10, 0x10, 0, 0),
+ AFFINEANIMCMD_FRAME(0x4, 0x4, 0, 60),
+ AFFINEANIMCMD_FRAME(0x100, 0x100, 0, 0),
+ AFFINEANIMCMD_LOOP(0),
+ AFFINEANIMCMD_FRAME(-0x4, -0x4, 0, 5),
+ AFFINEANIMCMD_FRAME(0x4, 0x4, 0, 5),
+ AFFINEANIMCMD_LOOP(10),
+ AFFINEANIMCMD_END,
+};
+
+static const union AffineAnimCmd gUnknown_83E6178[] =
+{
+ AFFINEANIMCMD_FRAME(0x10, 0x10, 0, 0),
+ AFFINEANIMCMD_FRAME(0x8, 0x8, 0, 30),
+ AFFINEANIMCMD_FRAME(0x100, 0x100, 0, 0),
+ AFFINEANIMCMD_FRAME(-0x4, -0x4, 0, 5),
+ AFFINEANIMCMD_FRAME(0x4, 0x4, 0, 5),
+ AFFINEANIMCMD_JUMP(3),
+};
+
+static const union AffineAnimCmd gUnknown_83E61A8[] =
+{
+ AFFINEANIMCMD_FRAME(0x10, 0x10, 0, 0),
+ AFFINEANIMCMD_FRAME(0x8, 0x8, 0, 30),
+ AFFINEANIMCMD_FRAME(-0x8, -0x8, 0, 30),
+ AFFINEANIMCMD_END,
+};
+
+static const union AffineAnimCmd *const gUnknown_83E61C8[] =
+{
+ gUnknown_83E6138,
+ gUnknown_83E6178,
+ gUnknown_83E61A8,
+};
+
+const struct SpriteTemplate gUnknown_83E61D4 =
+{
+ .tileTag = ANIM_TAG_CIRCLE_OF_LIGHT,
+ .paletteTag = ANIM_TAG_CIRCLE_OF_LIGHT,
+ .oam = &gOamData_83ACB60,
+ .anims = gDummySpriteAnimTable,
+ .images = NULL,
+ .affineAnims = gUnknown_83E61C8,
+ .callback = sub_80AE71C,
+};
+
+static const union AnimCmd gUnknown_83E61EC[] =
+{
+ ANIMCMD_FRAME(0, 3),
+ ANIMCMD_FRAME(16, 3),
+ ANIMCMD_FRAME(32, 3),
+ ANIMCMD_FRAME(48, 3),
+ ANIMCMD_END,
+};
+
+static const union AnimCmd *const gUnknown_83E6200[] =
+{
+ gUnknown_83E61EC,
+};
+
+const struct SpriteTemplate gUnknown_83E6204 =
+{
+ .tileTag = ANIM_TAG_ELECTRICITY,
+ .paletteTag = ANIM_TAG_ELECTRICITY,
+ .oam = &gOamData_83AC9D8,
+ .anims = gUnknown_83E6200,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = sub_80AE774,
+};
+
+const struct SpriteTemplate gUnknown_83E621C =
+{
+ .tileTag = ANIM_TAG_CIRCLE_OF_LIGHT,
+ .paletteTag = ANIM_TAG_CIRCLE_OF_LIGHT,
+ .oam = &gOamData_83ACB60,
+ .anims = gDummySpriteAnimTable,
+ .images = NULL,
+ .affineAnims = gUnknown_83E61C8,
+ .callback = sub_80AE7DC,
+};
+
+static const union AnimCmd gUnknown_83E6234[] =
+{
+ ANIMCMD_FRAME(0, 3),
+ ANIMCMD_END,
+};
+
+static const union AnimCmd gUnknown_83E623C[] =
+{
+ ANIMCMD_FRAME(2, 3),
+ ANIMCMD_END,
+};
+
+static const union AnimCmd gUnknown_83E6244[] =
+{
+ ANIMCMD_FRAME(4, 3),
+ ANIMCMD_END,
+};
+
+static const union AnimCmd gUnknown_83E624C[] =
+{
+ ANIMCMD_FRAME(6, 3),
+ ANIMCMD_END,
+};
+
+static const union AnimCmd *const gUnknown_83E6254[] =
+{
+ gUnknown_83E6234,
+ gUnknown_83E623C,
+ gUnknown_83E6244,
+ gUnknown_83E624C,
+};
+
+static const union AffineAnimCmd gUnknown_83E6264[] =
+{
+ AFFINEANIMCMD_FRAME(0x100, 0x100, 64, 0),
+ AFFINEANIMCMD_END,
+};
+
+static const union AffineAnimCmd *const gUnknown_83E6274[] =
+{
+ gUnknown_83E6264,
+};
+
+static const struct SpriteTemplate gUnknown_83E6278 =
+{
+ .tileTag = ANIM_TAG_SPARK,
+ .paletteTag = ANIM_TAG_SPARK,
+ .oam = &gOamData_83ACAC8,
+ .anims = gUnknown_83E6254,
+ .images = NULL,
+ .affineAnims = gUnknown_83E6274,
+ .callback = sub_80AEC34,
+};
+
+const struct SpriteTemplate gUnknown_83E6290 =
+{
+ .tileTag = ANIM_TAG_CIRCLE_OF_LIGHT,
+ .paletteTag = ANIM_TAG_CIRCLE_OF_LIGHT,
+ .oam = &gOamData_83ACB60,
+ .anims = gDummySpriteAnimTable,
+ .images = NULL,
+ .affineAnims = gUnknown_83E61C8,
+ .callback = sub_80AEC80,
+};
+
+static const struct SpriteTemplate gUnknown_83E62A8 =
+{
+ .tileTag = ANIM_TAG_SPARK,
+ .paletteTag = ANIM_TAG_SPARK,
+ .oam = &gOamData_83AC9C8,
+ .anims = gDummySpriteAnimTable,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = sub_80AEF60,
+};
+
+static void sub_80ADBEC(struct Sprite *sprite)
+{
+ if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER)
+ sprite->pos1.x -= gBattleAnimArgs[0];
+ else
+ sprite->pos1.x += gBattleAnimArgs[0];
+ sprite->pos1.y += gBattleAnimArgs[1];
+ sprite->callback = sub_80ADC3C;
+}
+
+static void sub_80ADC3C(struct Sprite *sprite)
+{
+ if (sprite->animEnded)
+ DestroyAnimSprite(sprite);
+}
+
+static void sub_80ADC58(struct Sprite *sprite)
+{
+ if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER)
+ sprite->pos1.x -= gBattleAnimArgs[0];
+ else
+ sprite->pos1.x += gBattleAnimArgs[0];
+ sprite->callback = sub_80ADC9C;
+}
+
+static void sub_80ADC9C(struct Sprite *sprite)
+{
+ if (sprite->affineAnimEnded)
+ DestroySpriteAndMatrix(sprite);
+}
+
+static void sub_80ADCB8(struct Sprite *sprite)
+{
+ sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X_2);
+ sprite->pos1.y = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y_PIC_OFFSET);
+ if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER)
+ {
+ sprite->pos1.x -= gBattleAnimArgs[0];
+ sprite->pos1.y -= gBattleAnimArgs[1];
+ }
+ else
+ {
+ sprite->pos1.x += gBattleAnimArgs[0];
+ sprite->pos1.y += gBattleAnimArgs[1];
+ }
+ sprite->data[0] = 0;
+ sprite->data[1] = gBattleAnimArgs[2];
+ sprite->data[2] = gBattleAnimArgs[3];
+ sprite->data[3] = gBattleAnimArgs[4];
+ StoreSpriteCallbackInData6(sprite, DestroySpriteAndMatrix);
+ sprite->callback = TranslateSpriteInCircleOverDuration;
+}
+
+static void sub_80ADD4C(struct Sprite *sprite)
+{
+ u8 battler;
+ u32 matrixNum;
+ s16 sineVal;
+
+ switch (gBattleAnimArgs[4])
+ {
+ case 0:
+ battler = gBattleAnimAttacker;
+ break;
+ case 1:
+ default:
+ battler = gBattleAnimTarget;
+ break;
+ case 2:
+ if (!IsBattlerSpriteVisible(BATTLE_PARTNER(gBattleAnimAttacker)))
+ battler = gBattleAnimAttacker;
+ else
+ battler = BATTLE_PARTNER(gBattleAnimAttacker);
+ break;
+ case 3:
+ if (IsBattlerSpriteVisible(BATTLE_PARTNER(gBattleAnimAttacker)))
+ battler = BATTLE_PARTNER(gBattleAnimTarget);
+ else
+ battler = gBattleAnimTarget;
+ break;
+ }
+ if (gBattleAnimArgs[5] == 0)
+ {
+ sprite->pos1.x = GetBattlerSpriteCoord(battler, BATTLER_COORD_X);
+ sprite->pos1.y = GetBattlerSpriteCoord(battler, BATTLER_COORD_Y);
+ }
+ else
+ {
+ sprite->pos1.x = GetBattlerSpriteCoord(battler, BATTLER_COORD_X_2);
+ sprite->pos1.y = GetBattlerSpriteCoord(battler, BATTLER_COORD_Y_PIC_OFFSET);
+ }
+ sprite->pos2.x = (gSineTable[gBattleAnimArgs[0]] * gBattleAnimArgs[1]) >> 8;
+ sprite->pos2.y = (gSineTable[gBattleAnimArgs[0] + 64] * gBattleAnimArgs[1]) >> 8;
+ if (gBattleAnimArgs[6] & 1)
+ sprite->oam.priority = GetBattlerSpriteBGPriority(battler) + 1;
+ matrixNum = sprite->oam.matrixNum;
+ sineVal = gSineTable[gBattleAnimArgs[2]];
+ gOamMatrices[matrixNum].a = gOamMatrices[matrixNum].d = gSineTable[gBattleAnimArgs[2] + 64];
+ gOamMatrices[matrixNum].b = sineVal;
+ gOamMatrices[matrixNum].c = -sineVal;
+ sprite->data[0] = gBattleAnimArgs[3];
+ sprite->callback = sub_80B1D3C;
+}
+
+static void sub_80ADEB0(struct Sprite *sprite)
+{
+ InitSpritePosToAnimAttacker(sprite, 1);
+ sprite->data[0] = gBattleAnimArgs[3];
+ sprite->data[1] = sprite->pos1.x;
+ sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X_2);
+ sprite->data[3] = sprite->pos1.y;
+ sprite->data[4] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y_PIC_OFFSET);
+ InitAnimLinearTranslation(sprite);
+ sprite->data[5] = gBattleAnimArgs[2];
+ sprite->data[6] = gBattleAnimArgs[5];
+ sprite->data[7] = gBattleAnimArgs[4];
+ sprite->oam.tileNum += gBattleAnimArgs[6] * 4;
+ sprite->callback = sub_80ADF38;
+ sprite->callback(sprite);
+}
+
+static void sub_80ADF38(struct Sprite *sprite)
+{
+ if (!AnimTranslateLinear(sprite))
+ {
+ sprite->pos2.x += Sin(sprite->data[7], sprite->data[5]);
+ sprite->pos2.y += Cos(sprite->data[7], sprite->data[5]);
+ sprite->data[7] = (sprite->data[7] + sprite->data[6]) & 0xFF;
+ if(!(sprite->data[7] % 3))
+ sprite->invisible ^= 1;
+ }
+ else
+ {
+ DestroyAnimSprite(sprite);
+ }
+}
+
+static void sub_80ADFB0(struct Sprite *sprite)
+{
+ if (--sprite->data[5] == -1)
+ {
+ sprite->invisible ^= 1;
+ sprite->data[5] = sprite->data[4];
+ }
+ if (sprite->data[3]-- <= 0)
+ DestroyAnimSprite(sprite);
+}
+
+static void sub_80AE000(struct Sprite *sprite)
+{
+ if (IsContest() || GetBattlerSide(gBattleAnimTarget) == B_SIDE_PLAYER)
+ gBattleAnimArgs[1] = -gBattleAnimArgs[1];
+ sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X_2) + gBattleAnimArgs[1];
+ sprite->pos1.y = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y_PIC_OFFSET) + gBattleAnimArgs[2];
+ sprite->data[3] = gBattleAnimArgs[0];
+ sprite->data[4] = gBattleAnimArgs[3];
+ sprite->data[5] = gBattleAnimArgs[3];
+ sprite->callback = sub_80ADFB0;
+}
+
+static void sub_80AE06C(struct Sprite *sprite)
+{
+ u8 battler;
+
+ sprite->data[0] = gBattleAnimArgs[3];
+ if (gBattleAnimArgs[7] & 0x8000)
+ battler = gBattleAnimTarget;
+ else
+ battler = gBattleAnimAttacker;
+ if (IsContest() || GetBattlerSide(battler) == B_SIDE_PLAYER)
+ gBattleAnimArgs[0] = -gBattleAnimArgs[0];
+ sprite->pos1.x = GetBattlerSpriteCoord(battler, BATTLER_COORD_X_2) + gBattleAnimArgs[0];
+ sprite->pos1.y = GetBattlerSpriteCoord(battler, BATTLER_COORD_Y_PIC_OFFSET) + gBattleAnimArgs[1];
+ sprite->data[4] = gBattleAnimArgs[7] & 0x7FFF;
+ sprite->data[5] = gBattleAnimArgs[2];
+ sprite->data[6] = gBattleAnimArgs[5];
+ sprite->data[7] = gBattleAnimArgs[4];
+ sprite->oam.tileNum += gBattleAnimArgs[6] * 4;
+ sprite->callback = sub_80AE130;
+ sprite->callback(sprite);
+}
+
+static void sub_80AE130(struct Sprite *sprite)
+{
+ sprite->pos2.x = Sin(sprite->data[7], sprite->data[5]);
+ sprite->pos2.y = Cos(sprite->data[7], sprite->data[5]);
+ sprite->data[7] = (sprite->data[7] + sprite->data[6]) & 0xFF;
+ if (sprite->data[7] % sprite->data[4] == 0)
+ sprite->invisible ^= 1;
+ if (sprite->data[0]-- <= 0)
+ DestroyAnimSprite(sprite);
+}
+
+static void sub_80AE1A0(struct Sprite *sprite)
+{
+ InitSpritePosToAnimTarget(sprite, FALSE);
+ sprite->oam.tileNum += gBattleAnimArgs[3] * 4;
+ if (gBattleAnimArgs[3] == 1)
+ sprite->oam.matrixNum = ST_OAM_HFLIP;
+ else if (gBattleAnimArgs[3] == 2)
+ sprite->oam.matrixNum = ST_OAM_VFLIP;
+ sprite->data[0] = gBattleAnimArgs[2];
+ sprite->callback = WaitAnimForDuration;
+ StoreSpriteCallbackInData6(sprite, DestroyAnimSprite);
+}
+
+void sub_80AE220(u8 taskId)
+{
+ gTasks[taskId].data[0] = GetBattlerSpriteCoord(gBattleAnimTarget, 0) + gBattleAnimArgs[0];
+ gTasks[taskId].data[1] = GetBattlerSpriteCoord(gBattleAnimTarget, 1) + gBattleAnimArgs[1];
+ gTasks[taskId].data[2] = gBattleAnimArgs[2];
+ gTasks[taskId].func = sub_80AE278;
+}
+
+static void sub_80AE278(u8 taskId)
+{
+ u16 r8;
+ u16 r2;
+ s16 r12;
+ u8 spriteId = 0;
+ u8 r7 = 0;
+ u8 sp = gTasks[taskId].data[2];
+ s16 x = gTasks[taskId].data[0];
+ s16 y = gTasks[taskId].data[1];
+
+ if (!gTasks[taskId].data[2])
+ {
+ r8 = 0;
+ r2 = 1;
+ r12 = 16;
+ }
+ else
+ {
+ r12 = 16;
+ r8 = 8;
+ r2 = 4;
+ }
+ switch (gTasks[taskId].data[10])
+ {
+ case 0:
+ r12 *= 1;
+ spriteId = CreateSprite(&gUnknown_83E60A0, x, y + r12, 2);
+ ++r7;
+ break;
+ case 2:
+ r12 *= 2;
+ r8 += r2;
+ spriteId = CreateSprite(&gUnknown_83E60A0, x, y + r12, 2);
+ ++r7;
+ break;
+ case 4:
+ r12 *= 3;
+ r8 += r2 * 2;
+ spriteId = CreateSprite(&gUnknown_83E60A0, x, y + r12, 2);
+ ++r7;
+ break;
+ case 6:
+ r12 *= 4;
+ r8 += r2 * 3;
+ spriteId = CreateSprite(&gUnknown_83E60A0, x, y + r12, 2);
+ ++r7;
+ break;
+ case 8:
+ r12 *= 5;
+ spriteId = CreateSprite(&gUnknown_83E60A0, x, y + r12, 2);
+ ++r7;
+ break;
+ case 10:
+ DestroyAnimVisualTask(taskId);
+ return;
+ }
+ if (r7)
+ {
+ gSprites[spriteId].oam.tileNum += r8;
+ gSprites[spriteId].data[0] = sp;
+ gSprites[spriteId].callback(&gSprites[spriteId]);
+ }
+ ++gTasks[taskId].data[10];
+}
+
+static void sub_80AE420(struct Sprite *sprite)
+{
+ if (!sprite->data[0])
+ {
+ sprite->oam.shape = ST_OAM_V_RECTANGLE;
+ sprite->oam.size = ST_OAM_SIZE_0;
+ }
+ else
+ {
+ sprite->oam.shape = ST_OAM_SQUARE;
+ sprite->oam.size = ST_OAM_SIZE_1;
+ }
+ if (++sprite->data[1] == 15)
+ DestroySprite(sprite);
+}
+
+static void sub_80AE470(struct Sprite *sprite)
+{
+ u8 spriteId;
+
+ sprite->pos1.x += gBattleAnimArgs[0];
+ sprite->pos1.y += gBattleAnimArgs[1];
+ spriteId = CreateSprite(&gUnknown_83E60B8, sprite->pos1.x + 32, sprite->pos1.y, sprite->subpriority);
+ gSprites[spriteId].oam.tileNum += 8;
+ ++gAnimVisualTaskCount;
+ gSprites[spriteId].callback = sub_80AE4F4;
+ sprite->callback = sub_80AE4F4;
+}
+
+static void sub_80AE4F4(struct Sprite *sprite)
+{
+ if (++sprite->data[0] == 3)
+ {
+ sprite->data[0] = 0;
+ sprite->invisible ^= 1;
+ }
+ if (++sprite->data[1] == 51)
+ DestroyAnimSprite(sprite);
+}
+
+void sub_80AE540(u8 taskId)
+{
+ struct Task *task = &gTasks[taskId];
+
+ if (!gBattleAnimArgs[0])
+ {
+ task->data[14] = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X_2);
+ task->data[15] = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y_PIC_OFFSET);
+ }
+ else
+ {
+ task->data[14] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X_2);
+ task->data[15] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y_PIC_OFFSET);
+ }
+ task->data[6] = gBattleAnimArgs[1];
+ task->data[7] = 0;
+ task->data[8] = 0;
+ task->data[9] = 0;
+ task->data[10] = 0;
+ task->data[11] = gBattleAnimArgs[3];
+ task->data[12] = 0;
+ task->data[13] = gBattleAnimArgs[2];
+ task->func = sub_80AE5BC;
+}
+
+static void sub_80AE5BC(u8 taskId)
+{
+ struct Task *task = &gTasks[taskId];
+
+ if (task->data[6])
+ {
+ if (++task->data[12] > task->data[13])
+ {
+ u8 spriteId;
+
+ task->data[12] = 0;
+ spriteId = CreateSprite(&gUnknown_83E6120, task->data[14], task->data[15], 2);
+ if (spriteId != MAX_SPRITES)
+ {
+ struct Sprite *sprite = &gSprites[spriteId];
+
+ sprite->pos1.x += gUnknown_83E60D0[task->data[9]][0];
+ sprite->pos1.y += gUnknown_83E60D0[task->data[9]][1];
+ sprite->data[0] = 40 - task->data[8] * 5;
+ sprite->data[1] = sprite->pos1.x;
+ sprite->data[2] = task->data[14];
+ sprite->data[3] = sprite->pos1.y;
+ sprite->data[4] = task->data[15];
+ sprite->data[5] = taskId;
+ InitAnimLinearTranslation(sprite);
+ StoreSpriteCallbackInData6(sprite, sub_80AE704);
+ sprite->callback = RunStoredCallbackWhenAnimEnds;
+ if (++task->data[9] > 15)
+ task->data[9] = 0;
+ if (++task->data[10] >= task->data[11])
+ {
+ task->data[10] = 0;
+ if (task->data[8] <= 5)
+ ++task->data[8];
+ }
+ ++task->data[7];
+ --task->data[6];
+ }
+ }
+ }
+ else if(task->data[7] == 0)
+ {
+ DestroyAnimVisualTask(taskId);
+ }
+}
+
+static void sub_80AE6D0(struct Sprite *sprite)
+{
+ if (AnimTranslateLinear(sprite))
+ {
+ --gTasks[sprite->data[5]].data[7];
+ DestroySprite(sprite);
+ }
+}
+
+static void sub_80AE704(struct Sprite *sprite)
+{
+ StartSpriteAnim(sprite, 1);
+ sprite->callback = sub_80AE6D0;
+}
+
+static void sub_80AE71C(struct Sprite *sprite)
+{
+ if (!gBattleAnimArgs[0])
+ {
+ sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X_2);
+ sprite->pos1.y = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y_PIC_OFFSET);
+ }
+ else
+ {
+ sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X_2);
+ sprite->pos1.y = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y_PIC_OFFSET);
+ }
+ StoreSpriteCallbackInData6(sprite, DestroySpriteAndMatrix);
+ sprite->callback = RunStoredCallbackWhenAffineAnimEnds;
+}
+
+static void sub_80AE774(struct Sprite *sprite)
+{
+ if (!gBattleAnimArgs[0])
+ {
+ sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X_2);
+ sprite->pos1.y = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y_PIC_OFFSET);
+ }
+ else
+ {
+ sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X_2);
+ sprite->pos1.y = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y_PIC_OFFSET);
+ }
+ sprite->pos2.x = gBattleAnimArgs[1];
+ sprite->pos2.y = gBattleAnimArgs[2];
+ StoreSpriteCallbackInData6(sprite, DestroyAnimSprite);
+ sprite->callback = RunStoredCallbackWhenAnimEnds;
+}
+
+static void sub_80AE7DC(struct Sprite *sprite)
+{
+ StartSpriteAffineAnim(sprite, 1);
+ sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X_2);
+ sprite->pos1.y = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y_PIC_OFFSET);
+ sprite->data[6] = GetAnimBattlerSpriteId(ANIM_ATTACKER);
+ sprite->data[7] = 16;
+ if (GetBattlerSide(gBattleAnimAttacker) == B_SIDE_OPPONENT)
+ sprite->data[7] *= -1;
+ sprite->callback = sub_80AE83C;
+}
+
+static void sub_80AE83C(struct Sprite *sprite)
+{
+ switch (sprite->data[0])
+ {
+ case 0:
+ if (++sprite->data[1] > 40)
+ ++sprite->data[0];
+ break;
+ case 1:
+ sprite->pos1.x += sprite->data[7];
+ gSprites[sprite->data[6]].pos2.x += sprite->data[7];
+ if ((u16)(sprite->pos1.x + 80) > 400)
+ DestroySpriteAndMatrix(sprite);
+ break;
+ }
+}
+
+void sub_80AE8A0(u8 taskId)
+{
+ struct Task *task = &gTasks[taskId];
+
+ switch (task->data[0])
+ {
+ case 0:
+ task->data[15] = GetAnimBattlerSpriteId(ANIM_ATTACKER);
+ task->data[14] = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X_2);
+ if (GetBattlerSide(gBattleAnimAttacker) == B_SIDE_PLAYER)
+ {
+ task->data[14] = -32;
+ task->data[13] = 2;
+ }
+ else
+ {
+ task->data[14] = 32;
+ task->data[13] = -2;
+ }
+ gSprites[task->data[15]].pos2.x = task->data[14];
+ ++task->data[0];
+ break;
+ case 1:
+ if (++task->data[1] > 1)
+ {
+ task->data[1] = 0;
+ gSprites[task->data[15]].invisible ^= 1;
+
+ if (task->data[14])
+ {
+ task->data[14] += task->data[13];
+ gSprites[task->data[15]].pos2.x = task->data[14];
+ }
+ else
+ {
+ ++task->data[0];
+ }
+ }
+ break;
+ case 2:
+ if (++task->data[1] > 1)
+ {
+ task->data[1] = 0;
+ gSprites[task->data[15]].invisible ^= 1;
+ if (++task->data[2] == 8)
+ ++task->data[0];
+ }
+ break;
+ case 3:
+ gSprites[task->data[15]].invisible = FALSE;
+ DestroyAnimVisualTask(taskId);
+ break;
+ }
+}
+
+void sub_80AEA10(u8 taskId)
+{
+ struct Task *task = &gTasks[taskId];
+
+ switch(task->data[0])
+ {
+ case 0:
+ task->data[1] = GetBattlerSide(gBattleAnimAttacker) == B_SIDE_PLAYER ? 1 : -1;
+ switch (gBattleAnimArgs[0])
+ {
+ case 0:
+ task->data[3] = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X_2);
+ task->data[5] = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y_PIC_OFFSET);
+ task->data[4] = (task->data[1] * 128) + 120;
+ break;
+ case 4:
+ task->data[3] = 120 - (task->data[1] * 128);
+ task->data[5] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y_PIC_OFFSET);
+ task->data[4] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X_2) - (task->data[1] * 32);
+ break;
+ default:
+ if ((gBattleAnimArgs[0] & 1) != 0)
+ {
+ task->data[3] = 256;
+ task->data[4] = -16;
+ }
+ else
+ {
+ task->data[3] = -16;
+ task->data[4] = 256;
+ }
+ if (task->data[1] == 1)
+ {
+ task->data[5] = 80 - gBattleAnimArgs[0] * 10;
+ }
+ else
+ {
+ u16 temp;
+
+ task->data[5] = gBattleAnimArgs[0] * 10 + 40;
+ temp = task->data[3];
+ task->data[3] = task->data[4];
+ task->data[4] = temp;
+ }
+ }
+ if (task->data[3] < task->data[4])
+ {
+ task->data[1] = 1;
+ task->data[6] = 0;
+ }
+ else
+ {
+ task->data[1] = -1;
+ task->data[6] = 3;
+ }
+ ++task->data[0];
+ break;
+ case 1:
+ if (++task->data[2] > 0)
+ {
+ task->data[2] = 0;
+ if (sub_80AEB98(task, taskId) || sub_80AEB98(task, taskId))
+ ++task->data[0];
+ }
+ break;
+ case 2:
+ if (task->data[7] == 0)
+ DestroyAnimVisualTask(taskId);
+ break;
+ }
+}
+
+static bool8 sub_80AEB98(struct Task *task, u8 taskId)
+{
+ u8 spriteId = CreateSprite(&gUnknown_83E6278, task->data[3], task->data[5], 35);
+
+ if (spriteId != MAX_SPRITES)
+ {
+ gSprites[spriteId].data[6] = taskId;
+ gSprites[spriteId].data[7] = 7;
+ ++task->data[7];
+ }
+ task->data[6] += task->data[1];
+ if (task->data[6] < 0)
+ task->data[6] = 3;
+ if (task->data[6] > 3)
+ task->data[6] = 0;
+ task->data[3] += task->data[1] * 16;
+ if ((task->data[1] == 1 && task->data[3] >= task->data[4])
+ || (task->data[1] == -1 && task->data[3] <= task->data[4]))
+ return TRUE;
+ else
+ return FALSE;
+}
+
+static void sub_80AEC34(struct Sprite *sprite)
+{
+ if (++sprite->data[0] > 12)
+ {
+ --gTasks[sprite->data[6]].data[sprite->data[7]];
+ FreeOamMatrix(sprite->oam.matrixNum);
+ DestroySprite(sprite);
+ }
+}
+
+static void sub_80AEC80(struct Sprite *sprite)
+{
+ switch (sprite->data[0])
+ {
+ case 0:
+ sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X_2);
+ sprite->pos1.y = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y_PIC_OFFSET);
+ StartSpriteAffineAnim(sprite, 2);
+ ++sprite->data[0];
+ break;
+ case 1:
+ if (sprite->affineAnimEnded)
+ DestroySpriteAndMatrix(sprite);
+ break;
+ }
+}
+
+void sub_80AECE0(u8 taskId)
+{
+ struct Task *task = &gTasks[taskId];
+
+ switch (task->data[0])
+ {
+ case 0:
+ task->data[6] = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X_2);
+ task->data[7] = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y_PIC_OFFSET);
+ task->data[8] = 4;
+ task->data[10] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X_2);
+ task->data[9] = (task->data[10] - task->data[6]) / 5;
+ task->data[4] = 7;
+ task->data[5] = -1;
+ task->data[11] = 12;
+ task->data[12] = BattleAnimAdjustPanning(task->data[11] - 76);
+ task->data[13] = BattleAnimAdjustPanning(SOUND_PAN_TARGET);
+ task->data[14] = task->data[12];
+ task->data[15] = (task->data[13] - task->data[12]) / 3;
+ ++task->data[0];
+ break;
+ case 1:
+ if (++task->data[1] > 0)
+ {
+ task->data[1] = 0;
+ if (sub_80AEE74(task, taskId))
+ {
+ if (task->data[2] == 5)
+ task->data[0] = 3;
+ else
+ ++task->data[0];
+ }
+ }
+ if (task->data[11])
+ --task->data[11];
+ break;
+ case 2:
+ if (task->data[11])
+ --task->data[11];
+ if (++task->data[1] > 4)
+ {
+ task->data[1] = 0;
+ if (task->data[2] & 1)
+ {
+ task->data[7] = 4;
+ task->data[8] = 68;
+ task->data[4] = 0;
+ task->data[5] = 1;
+ }
+ else
+ {
+ task->data[7] = 68;
+ task->data[8] = 4;
+ task->data[4] = 7;
+ task->data[5] = -1;
+ }
+ if (task->data[11])
+ task->data[0] = 4;
+ else
+ task->data[0] = 1;
+ }
+ break;
+ case 3:
+ if (task->data[3] == 0)
+ DestroyAnimVisualTask(taskId);
+ break;
+ case 4:
+ if (task->data[11])
+ --task->data[11];
+ else
+ task->data[0] = 1;
+ break;
+ }
+}
+
+static bool8 sub_80AEE74(struct Task *task, u8 taskId)
+{
+ u8 spriteId = CreateSprite(&gUnknown_83E62A8, task->data[6], task->data[7], 35);
+ if (spriteId != MAX_SPRITES)
+ {
+ gSprites[spriteId].oam.tileNum += task->data[4];
+ task->data[4] += task->data[5];
+ if (task->data[4] < 0)
+ task->data[4] = 7;
+ if (task->data[4] > 7)
+ task->data[4] = 0;
+ gSprites[spriteId].data[6] = taskId;
+ gSprites[spriteId].data[7] = 3;
+ ++task->data[3];
+ }
+ if (task->data[4] == 0 && task->data[5] > 0)
+ {
+ task->data[14] += task->data[15];
+ PlaySE12WithPanning(SE_W085, task->data[14]);
+ }
+ if ((task->data[5] < 0 && task->data[7] <= task->data[8])
+ || (task->data[5] > 0 && task->data[7] >= task->data[8]))
+ {
+ ++task->data[2];
+ task->data[6] += task->data[9];
+ return TRUE;
+ }
+ else
+ {
+ task->data[7] += task->data[5] * 8;
+ return FALSE;
+ }
+}
+
+static void sub_80AEF60(struct Sprite *sprite)
+{
+ if (++sprite->data[0] > 12)
+ {
+ --gTasks[sprite->data[6]].data[sprite->data[7]];
+ DestroySprite(sprite);
+ }
+}
+
+void sub_80AEFA0(u8 taskId)
+{
+ struct Task *task = &gTasks[taskId];
+
+ switch (task->data[0])
+ {
+ case 0:
+ task->data[15] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y) + 32;
+ task->data[14] = task->data[15];
+ while (task->data[14] > 16)
+ task->data[14] -= 32;
+ task->data[13] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X_2);
+ task->data[12] = GetBattlerSpriteSubpriority(gBattleAnimTarget) - 2;
+ ++task->data[0];
+ break;
+ case 1:
+ if (++task->data[1] > 1)
+ {
+ task->data[1] = 0;
+ if (sub_80AF058(task, taskId))
+ ++task->data[0];
+ }
+ break;
+ case 2:
+ if (task->data[10] == 0)
+ DestroyAnimVisualTask(taskId);
+ break;
+ }
+}
+
+static bool8 sub_80AF058(struct Task *task, u8 taskId)
+{
+ u8 spriteId = CreateSprite(&gUnknown_83E5F38, task->data[13], task->data[14], task->data[12]);
+
+ if (spriteId != MAX_SPRITES)
+ {
+ gSprites[spriteId].callback = sub_80AF0C8;
+ gSprites[spriteId].data[6] = taskId;
+ gSprites[spriteId].data[7] = 10;
+ ++task->data[10];
+ }
+ if (task->data[14] >= task->data[15])
+ return TRUE;
+ task->data[14] += 32;
+ return FALSE;
+}
+
+static void sub_80AF0C8(struct Sprite *sprite)
+{
+ if (sprite->animEnded)
+ {
+ --gTasks[sprite->data[6]].data[sprite->data[7]];
+ DestroySprite(sprite);
+ }
+}
diff --git a/src/fighting.c b/src/fighting.c
new file mode 100644
index 000000000..496f752ef
--- /dev/null
+++ b/src/fighting.c
@@ -0,0 +1,971 @@
+#include "global.h"
+#include "battle_anim.h"
+#include "gpu_regs.h"
+#include "random.h"
+#include "task.h"
+#include "trig.h"
+
+static void unc_080B08A0(struct Sprite *sprite);
+static void sub_80B08DC(struct Sprite *sprite);
+static void sub_80B0928(struct Sprite *sprite);
+static void AnimBasicFistOrFoot(struct Sprite *sprite);
+static void sub_80B09A4(struct Sprite *sprite);
+static void sub_80B0B80(struct Sprite *sprite);
+static void sub_80B0C28(struct Sprite *sprite);
+static void AnimSpinningKickOrPunch(struct Sprite *sprite);
+static void AnimStompFoot(struct Sprite *sprite);
+static void sub_80B0DF0(struct Sprite *sprite);
+static void sub_80B0E80(struct Sprite *sprite);
+static void sub_80B0F68(struct Sprite *sprite);
+static void sub_80B107C(struct Sprite *sprite);
+static void sub_80B1188(struct Sprite *sprite);
+static void sub_80B12E8(struct Sprite *sprite);
+static void sub_80B13F8(struct Sprite *sprite);
+static void sub_80B1484(struct Sprite *sprite);
+static void sub_80B14F0(struct Sprite *sprite);
+static void sub_80B0B2C(struct Sprite *sprite);
+static void sub_80B0BD8(struct Sprite *sprite);
+static void sub_80B0CB4(struct Sprite *sprite);
+static void AnimSpinningKickOrPunchFinish(struct Sprite *sprite);
+static void AnimStompFootStep(struct Sprite *sprite);
+static void AnimStompFootEnd(struct Sprite *sprite);
+static void sub_80B0EF0(struct Sprite *sprite);
+static void sub_80B1050(struct Sprite *sprite);
+static void sub_80B111C(struct Sprite *sprite);
+static void sub_80B11E4(struct Sprite *sprite);
+static void sub_80B12A4(struct Sprite *sprite);
+
+const struct SpriteTemplate gUnknown_83E668C =
+{
+ .tileTag = ANIM_TAG_HUMANOID_FOOT,
+ .paletteTag = ANIM_TAG_HUMANOID_FOOT,
+ .oam = &gOamData_83AC9D8,
+ .anims = gDummySpriteAnimTable,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = unc_080B08A0,
+};
+
+static const union AnimCmd gUnknown_83E66A4[] =
+{
+ ANIMCMD_FRAME(0, 1),
+ ANIMCMD_END,
+};
+
+static const union AnimCmd gUnknown_83E66AC[] =
+{
+ ANIMCMD_FRAME(16, 1),
+ ANIMCMD_END,
+};
+
+static const union AnimCmd gUnknown_83E66B4[] =
+{
+ ANIMCMD_FRAME(32, 1),
+ ANIMCMD_END,
+};
+
+static const union AnimCmd gUnknown_83E66BC[] =
+{
+ ANIMCMD_FRAME(48, 1),
+ ANIMCMD_END,
+};
+
+static const union AnimCmd gUnknown_83E66C4[] =
+{
+ ANIMCMD_FRAME(48, 1, .hFlip = TRUE),
+ ANIMCMD_END,
+};
+
+static const union AnimCmd *const gUnknown_83E66CC[] =
+{
+ gUnknown_83E66A4,
+};
+
+static const union AnimCmd *const gUnknown_83E66D0[] =
+{
+ gUnknown_83E66AC,
+ gUnknown_83E66B4,
+};
+
+static const union AnimCmd *const gUnknown_83E66D8[] =
+{
+ gUnknown_83E66BC,
+ gUnknown_83E66C4,
+};
+
+const struct SpriteTemplate gUnknown_83E66E0 =
+{
+ .tileTag = ANIM_TAG_HANDS_AND_FEET,
+ .paletteTag = ANIM_TAG_HANDS_AND_FEET,
+ .oam = &gOamData_83AC9D8,
+ .anims = gUnknown_83E66CC,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = sub_80B08DC,
+};
+
+const struct SpriteTemplate gUnknown_83E66F8 =
+{
+ .tileTag = ANIM_TAG_HANDS_AND_FEET,
+ .paletteTag = ANIM_TAG_HANDS_AND_FEET,
+ .oam = &gOamData_83AC9D8,
+ .anims = gUnknown_83E66CC,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = sub_80B0928,
+};
+
+const struct SpriteTemplate gFistFootSpriteTemplate =
+{
+ .tileTag = ANIM_TAG_HANDS_AND_FEET,
+ .paletteTag = ANIM_TAG_HANDS_AND_FEET,
+ .oam = &gOamData_83AC9D8,
+ .anims = gUnknown_83E66CC,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = AnimBasicFistOrFoot,
+};
+
+const struct SpriteTemplate gUnknown_83E6728 =
+{
+ .tileTag = ANIM_TAG_HANDS_AND_FEET,
+ .paletteTag = ANIM_TAG_HANDS_AND_FEET,
+ .oam = &gOamData_83AC9D8,
+ .anims = gUnknown_83E66CC,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = sub_80B09A4,
+};
+
+const struct SpriteTemplate gUnknown_83E6740 =
+{
+ .tileTag = ANIM_TAG_HANDS_AND_FEET,
+ .paletteTag = ANIM_TAG_HANDS_AND_FEET,
+ .oam = &gOamData_83AC9D8,
+ .anims = gUnknown_83E66D8,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = sub_80B0B80,
+};
+
+const struct SpriteTemplate gUnknown_83E6758 =
+{
+ .tileTag = ANIM_TAG_HANDS_AND_FEET,
+ .paletteTag = ANIM_TAG_HANDS_AND_FEET,
+ .oam = &gOamData_83AC9D8,
+ .anims = gUnknown_83E66D0,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = sub_80B0C28,
+};
+
+static const union AffineAnimCmd gUnknown_83E6770[] =
+{
+ AFFINEANIMCMD_FRAME(0x100, 0x100, 0, 0),
+ AFFINEANIMCMD_FRAME(-0x8, -0x8, 20, 1),
+ AFFINEANIMCMD_JUMP(1),
+};
+
+static const union AffineAnimCmd *const gUnknown_83E6788[] =
+{
+ gUnknown_83E6770,
+};
+
+const struct SpriteTemplate gUnknown_83E678C =
+{
+ .tileTag = ANIM_TAG_HANDS_AND_FEET,
+ .paletteTag = ANIM_TAG_HANDS_AND_FEET,
+ .oam = &gOamData_83ACA98,
+ .anims = gUnknown_83E66CC,
+ .images = NULL,
+ .affineAnims = gUnknown_83E6788,
+ .callback = AnimSpinningKickOrPunch,
+};
+
+static const union AffineAnimCmd gUnknown_83E67A4[] =
+{
+ AFFINEANIMCMD_FRAME(0x100, 0x100, 0, 0),
+ AFFINEANIMCMD_FRAME(-0x4, -0x4, 20, 1),
+ AFFINEANIMCMD_JUMP(1),
+};
+
+static const union AffineAnimCmd *const gUnknown_83E67BC[] =
+{
+ gUnknown_83E67A4,
+};
+
+const struct SpriteTemplate gMegaPunchKickSpriteTemplate =
+{
+ .tileTag = ANIM_TAG_HANDS_AND_FEET,
+ .paletteTag = ANIM_TAG_HANDS_AND_FEET,
+ .oam = &gOamData_83ACA98,
+ .anims = gUnknown_83E66CC,
+ .images = NULL,
+ .affineAnims = gUnknown_83E67BC,
+ .callback = AnimSpinningKickOrPunch,
+};
+
+const struct SpriteTemplate gUnknown_83E67D8 =
+{
+ .tileTag = ANIM_TAG_HANDS_AND_FEET,
+ .paletteTag = ANIM_TAG_HANDS_AND_FEET,
+ .oam = &gOamData_83AC9D8,
+ .anims = gUnknown_83E66D0,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = AnimStompFoot,
+};
+
+const struct SpriteTemplate gUnknown_83E67F0 =
+{
+ .tileTag = ANIM_TAG_DUCK,
+ .paletteTag = ANIM_TAG_DUCK,
+ .oam = &gOamData_83AC9D0,
+ .anims = gDummySpriteAnimTable,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = sub_80B0DF0,
+};
+
+const struct SpriteTemplate gUnknown_83E6808 =
+{
+ .tileTag = ANIM_TAG_BLUE_LIGHT_WALL,
+ .paletteTag = ANIM_TAG_BLUE_LIGHT_WALL,
+ .oam = &gOamData_83ACB00,
+ .anims = gDummySpriteAnimTable,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = sub_80B0E80,
+};
+
+const struct SpriteTemplate gUnknown_83E6820 =
+{
+ .tileTag = ANIM_TAG_TORN_METAL,
+ .paletteTag = ANIM_TAG_TORN_METAL,
+ .oam = &gOamData_83AC9D8,
+ .anims = gDummySpriteAnimTable,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = sub_80B0F68,
+};
+
+static const union AffineAnimCmd gUnknown_83E6838[] =
+{
+ AFFINEANIMCMD_FRAME(0x20, 0x20, 0, 0),
+ AFFINEANIMCMD_FRAME(0x4, 0x4, 0, 64),
+ AFFINEANIMCMD_FRAME(-0x6, -0x6, 0, 8),
+ AFFINEANIMCMD_FRAME(0x6, 0x6, 0, 8),
+ AFFINEANIMCMD_JUMP(2),
+};
+
+static const union AffineAnimCmd *const gUnknown_83E6860[] =
+{
+ gUnknown_83E6838,
+};
+
+const struct SpriteTemplate gUnknown_83E6864 =
+{
+ .tileTag = ANIM_TAG_CIRCLE_OF_LIGHT,
+ .paletteTag = ANIM_TAG_CIRCLE_OF_LIGHT,
+ .oam = &gOamData_83ACBC0,
+ .anims = gDummySpriteAnimTable,
+ .images = NULL,
+ .affineAnims = gUnknown_83E6860,
+ .callback = sub_80B107C,
+};
+
+const struct SpriteTemplate gUnknown_83E687C =
+{
+ .tileTag = ANIM_TAG_FLAT_ROCK,
+ .paletteTag = ANIM_TAG_FLAT_ROCK,
+ .oam = &gOamData_83AC9D0,
+ .anims = gDummySpriteAnimTable,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = sub_80B1188,
+};
+
+const struct SpriteTemplate gUnknown_83E6894 =
+{
+ .tileTag = ANIM_TAG_METEOR,
+ .paletteTag = ANIM_TAG_METEOR,
+ .oam = &gOamData_83AC9E0,
+ .anims = gDummySpriteAnimTable,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = sub_80B12E8,
+};
+
+const struct SpriteTemplate gUnknown_83E68AC =
+{
+ .tileTag = ANIM_TAG_HANDS_AND_FEET,
+ .paletteTag = ANIM_TAG_HANDS_AND_FEET,
+ .oam = &gOamData_83AC9D8,
+ .anims = gUnknown_83E66CC,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = sub_80B13F8,
+};
+
+static const union AnimCmd gUnknown_83E68C4[] =
+{
+ ANIMCMD_FRAME(0, 4),
+ ANIMCMD_FRAME(16, 4),
+ ANIMCMD_FRAME(32, 4),
+ ANIMCMD_END,
+};
+
+static const union AnimCmd gUnknown_83E68D4[] =
+{
+ ANIMCMD_FRAME(0, 4, .vFlip = TRUE),
+ ANIMCMD_FRAME(16, 4, .vFlip = TRUE),
+ ANIMCMD_FRAME(32, 4, .vFlip = TRUE),
+ ANIMCMD_END,
+};
+
+static const union AnimCmd gUnknown_83E68E4[] =
+{
+ ANIMCMD_FRAME(0, 4, .hFlip = TRUE),
+ ANIMCMD_FRAME(16, 4, .hFlip = TRUE),
+ ANIMCMD_FRAME(32, 4, .hFlip = TRUE),
+ ANIMCMD_END,
+};
+
+static const union AnimCmd *const gUnknown_83E68F4[] =
+{
+ gUnknown_83E68C4,
+ gUnknown_83E68D4,
+ gUnknown_83E68E4,
+};
+
+const struct SpriteTemplate gUnknown_83E6900 =
+{
+ .tileTag = ANIM_TAG_PURPLE_SCRATCH,
+ .paletteTag = ANIM_TAG_PURPLE_SCRATCH,
+ .oam = &gOamData_83AC9D8,
+ .anims = gUnknown_83E68F4,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = sub_80B1484,
+};
+
+static const union AnimCmd gUnknown_83E6918[] =
+{
+ ANIMCMD_FRAME(0, 6),
+ ANIMCMD_FRAME(64, 6),
+ ANIMCMD_END,
+};
+
+static const union AnimCmd gUnknown_83E6924[] =
+{
+ ANIMCMD_FRAME(0, 6, .vFlip = TRUE, .hFlip = TRUE),
+ ANIMCMD_FRAME(64, 6, .vFlip = TRUE, .hFlip = TRUE),
+ ANIMCMD_END,
+};
+
+static const union AnimCmd gUnknown_83E6930[] =
+{
+ ANIMCMD_FRAME(0, 6, .hFlip = TRUE),
+ ANIMCMD_FRAME(64, 6, .hFlip = TRUE),
+ ANIMCMD_END,
+};
+
+static const union AnimCmd *const gUnknown_83E693C[] =
+{
+ gUnknown_83E6918,
+ gUnknown_83E6924,
+ gUnknown_83E6930,
+};
+
+const struct SpriteTemplate gUnknown_83E6948 =
+{
+ .tileTag = ANIM_TAG_PURPLE_SWIPE,
+ .paletteTag = ANIM_TAG_PURPLE_SWIPE,
+ .oam = &gOamData_83AC9E0,
+ .anims = gUnknown_83E693C,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = sub_80B1484,
+};
+
+static const union AffineAnimCmd gUnknown_83E6960[] =
+{
+ AFFINEANIMCMD_FRAME(0x200, 0x200, 0, 0),
+ AFFINEANIMCMD_FRAME(-0x20, -0x20, 0, 8),
+ AFFINEANIMCMD_END,
+};
+
+static const union AffineAnimCmd *const gUnknown_83E6978[] =
+{
+ gUnknown_83E6960,
+};
+
+const struct SpriteTemplate gUnknown_83E697C =
+{
+ .tileTag = ANIM_TAG_HANDS_AND_FEET,
+ .paletteTag = ANIM_TAG_HANDS_AND_FEET,
+ .oam = &gOamData_83ACA98,
+ .anims = gUnknown_83E66CC,
+ .images = NULL,
+ .affineAnims = gUnknown_83E6978,
+ .callback = sub_80B14F0,
+};
+
+static void unc_080B08A0(struct Sprite *sprite)
+{
+ SetAnimSpriteInitialXOffset(sprite, gBattleAnimArgs[0]);
+ sprite->pos1.y += gBattleAnimArgs[1];
+ sprite->data[0] = 15;
+ sprite->callback = WaitAnimForDuration;
+ StoreSpriteCallbackInData6(sprite, DestroyAnimSprite);
+}
+
+static void sub_80B08DC(struct Sprite *sprite)
+{
+ if (gBattleAnimArgs[7] == 1 && GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER)
+ {
+ gBattleAnimArgs[1] = -gBattleAnimArgs[1];
+ gBattleAnimArgs[3] = -gBattleAnimArgs[3];
+ }
+ StartSpriteAnim(sprite, gBattleAnimArgs[6]);
+ gBattleAnimArgs[6] = 0;
+ AnimSnoreZ(sprite);
+}
+
+static void sub_80B0928(struct Sprite *sprite)
+{
+ if (IsContest())
+ {
+ gBattleAnimArgs[1] = -gBattleAnimArgs[1];
+ gBattleAnimArgs[3] = -gBattleAnimArgs[3];
+ }
+ sub_80B08DC(sprite);
+}
+
+// Displays a basic fist or foot sprite for a given duration.
+// Used by many fighting moves (and elemental "punch" moves).
+// arg 0: initial x pixel offset
+// arg 1: initial y pixel offset
+// arg 2: duration
+// arg 3: ? (todo: related to initial pixel offsets)
+// arg 4: anim num
+static void AnimBasicFistOrFoot(struct Sprite *sprite)
+{
+ StartSpriteAnim(sprite, gBattleAnimArgs[4]);
+ if (gBattleAnimArgs[3] == 0)
+ InitSpritePosToAnimAttacker(sprite, 1);
+ else
+ InitSpritePosToAnimTarget(sprite, TRUE);
+ sprite->data[0] = gBattleAnimArgs[2];
+ sprite->callback = WaitAnimForDuration;
+ StoreSpriteCallbackInData6(sprite, DestroyAnimSprite);
+}
+
+static void sub_80B09A4(struct Sprite *sprite)
+{
+ u8 battler;
+ s16 xMod, yMod;
+ s16 x, y;
+
+ if (gBattleAnimArgs[0] == 0)
+ battler = gBattleAnimAttacker;
+ else
+ battler = gBattleAnimTarget;
+
+ if (gBattleAnimArgs[2] < 0)
+ gBattleAnimArgs[2] = Random() % 5;
+ StartSpriteAnim(sprite, gBattleAnimArgs[2]);
+ sprite->pos1.x = GetBattlerSpriteCoord(battler, 2);
+ sprite->pos1.y = GetBattlerSpriteCoord(battler, 3);
+ xMod = GetBattlerSpriteCoordAttr(battler, BATTLER_COORD_ATTR_WIDTH) / 2;
+ yMod = GetBattlerSpriteCoordAttr(battler, BATTLER_COORD_ATTR_HEIGHT) / 4;
+ x = Random() % xMod;
+ y = Random() % yMod;
+ if (Random() & 1)
+ x *= -1;
+ if (Random() & 1)
+ y *= -1;
+ if ((gBattlerPositions[battler] & BIT_SIDE) == B_SIDE_PLAYER)
+ y += 0xFFF0;
+ sprite->pos1.x += x;
+ sprite->pos1.y += y;
+ sprite->data[0] = gBattleAnimArgs[1];
+ sprite->data[7] = CreateSprite(&gBasicHitSplatSpriteTemplate, sprite->pos1.x, sprite->pos1.y, sprite->subpriority + 1);
+ if (sprite->data[7] != 64)
+ {
+ StartSpriteAffineAnim(&gSprites[sprite->data[7]], 0);
+ gSprites[sprite->data[7]].callback = SpriteCallbackDummy;
+ }
+ sprite->callback = sub_80B0B2C;
+}
+
+static void sub_80B0B2C(struct Sprite *sprite)
+{
+ if (sprite->data[0] == 0)
+ {
+ if (sprite->data[7] != 64)
+ {
+ FreeOamMatrix(gSprites[sprite->data[7]].oam.matrixNum);
+ DestroySprite(&gSprites[sprite->data[7]]);
+ }
+ DestroyAnimSprite(sprite);
+ }
+ else
+ {
+ --sprite->data[0];
+ }
+}
+
+static void sub_80B0B80(struct Sprite *sprite)
+{
+ InitSpritePosToAnimTarget(sprite, TRUE);
+ sprite->data[0] = 30;
+ if (gBattleAnimArgs[2] == 0)
+ {
+ sprite->data[2] = sprite->pos1.x - 20;
+ }
+ else
+ {
+ sprite->data[2] = sprite->pos1.x + 20;
+ sprite->hFlip = 1;
+ }
+ sprite->data[4] = sprite->pos1.y - 20;
+ sprite->callback = StartAnimLinearTranslation;
+ StoreSpriteCallbackInData6(sprite, sub_80B0BD8);
+}
+
+static void sub_80B0BD8(struct Sprite *sprite)
+{
+ if (++sprite->data[5] == 11)
+ {
+ sprite->data[2] = sprite->pos1.x - sprite->pos2.x;
+ sprite->data[4] = sprite->pos1.y - sprite->pos2.y;
+ sprite->data[0] = 8;
+ sprite->pos1.x += sprite->pos2.x;
+ sprite->pos1.y += sprite->pos2.y;
+ sprite->pos2.y = 0;
+ sprite->pos2.x = 0;
+ sprite->callback = StartAnimLinearTranslation;
+ StoreSpriteCallbackInData6(sprite, DestroyAnimSprite);
+ }
+}
+
+static void sub_80B0C28(struct Sprite *sprite)
+{
+ if (BATTLE_PARTNER(gBattleAnimAttacker) == gBattleAnimTarget && GetBattlerPosition(gBattleAnimTarget) < B_POSITION_PLAYER_RIGHT)
+ gBattleAnimArgs[0] *= -1;
+ InitSpritePosToAnimTarget(sprite, TRUE);
+ if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER)
+ gBattleAnimArgs[2] = -gBattleAnimArgs[2];
+ sprite->data[0] = gBattleAnimArgs[3];
+ sprite->data[1] = sprite->pos1.x;
+ sprite->data[2] = sprite->pos1.x + gBattleAnimArgs[2];
+ sprite->data[3] = sprite->pos1.y;
+ sprite->data[4] = sprite->pos1.y;
+ InitAnimLinearTranslation(sprite);
+ sprite->data[5] = gBattleAnimArgs[5];
+ sprite->data[6] = gBattleAnimArgs[4];
+ sprite->data[7] = 0;
+ sprite->callback = sub_80B0CB4;
+}
+
+static void sub_80B0CB4(struct Sprite *sprite)
+{
+ if (!AnimTranslateLinear(sprite))
+ {
+ sprite->pos2.y += Sin(sprite->data[7] >> 8, sprite->data[5]);
+ sprite->data[7] += sprite->data[6];
+ }
+ else
+ {
+ DestroyAnimSprite(sprite);
+ }
+}
+
+// Animates the spinning, shrinking kick or punch, which then
+// reappears at full size. Used by moves such as MOVE_MEGA_PUNCH and MOVE_MEGA_KICK.
+// arg 0: initial x pixel offset
+// arg 1: initial y pixel offset
+// arg 2: anim num
+// arg 3: spin duration
+static void AnimSpinningKickOrPunch(struct Sprite *sprite)
+{
+ InitSpritePosToAnimTarget(sprite, TRUE);
+ StartSpriteAnim(sprite, gBattleAnimArgs[2]);
+ sprite->data[0] = gBattleAnimArgs[3];
+ sprite->callback = WaitAnimForDuration;
+ StoreSpriteCallbackInData6(sprite, AnimSpinningKickOrPunchFinish);
+}
+
+static void AnimSpinningKickOrPunchFinish(struct Sprite *sprite)
+{
+ StartSpriteAffineAnim(sprite, 0);
+ sprite->affineAnimPaused = 1;
+ sprite->data[0] = 20;
+ sprite->callback = WaitAnimForDuration;
+ StoreSpriteCallbackInData6(sprite, DestroyAnimSprite);
+}
+
+// Animates MOVE_STOMP's foot that slides downward.
+// arg 0: initial x pixel offset
+// arg 1: initial y pixel offset
+// arg 2: initial wait duration
+static void AnimStompFoot(struct Sprite *sprite)
+{
+ InitSpritePosToAnimTarget(sprite, TRUE);
+ sprite->data[0] = gBattleAnimArgs[2];
+ sprite->callback = AnimStompFootStep;
+}
+
+static void AnimStompFootStep(struct Sprite *sprite)
+{
+ if (--sprite->data[0] == -1)
+ {
+ sprite->data[0] = 6;
+ sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimTarget, 2);
+ sprite->data[4] = GetBattlerSpriteCoord(gBattleAnimTarget, 3);
+ sprite->callback = StartAnimLinearTranslation;
+ StoreSpriteCallbackInData6(sprite, AnimStompFootEnd);
+ }
+}
+
+static void AnimStompFootEnd(struct Sprite *sprite)
+{
+ sprite->data[0] = 15;
+ sprite->callback = WaitAnimForDuration;
+ StoreSpriteCallbackInData6(sprite, DestroyAnimSprite);
+}
+
+static void sub_80B0DF0(struct Sprite *sprite)
+{
+ if (sprite->data[0] == 0)
+ {
+ InitSpritePosToAnimTarget(sprite, TRUE);
+ sprite->data[1] = gBattleAnimArgs[2];
+ sprite->data[2] = gBattleAnimArgs[3];
+ ++sprite->data[0];
+ }
+ else
+ {
+ sprite->data[4] += sprite->data[1];
+ sprite->pos2.x = sprite->data[4] >> 8;
+ sprite->pos2.y = Sin(sprite->data[3], sprite->data[2]);
+ sprite->data[3] = (sprite->data[3] + 3) & 0xFF;
+ if (sprite->data[3] > 100)
+ sprite->invisible = sprite->data[3] % 2;
+ if (sprite->data[3] > 120)
+ DestroyAnimSprite(sprite);
+ }
+}
+
+static void sub_80B0E80(struct Sprite *sprite)
+{
+ if (gBattleAnimArgs[0] == 0)
+ {
+ sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimAttacker, 0);
+ sprite->pos1.y = GetBattlerSpriteCoord(gBattleAnimAttacker, 1);
+ }
+ else
+ {
+ sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimTarget, 0);
+ sprite->pos1.y = GetBattlerSpriteCoord(gBattleAnimTarget, 1);
+ }
+ sprite->pos1.x += gBattleAnimArgs[1];
+ sprite->pos1.y += gBattleAnimArgs[2];
+ sprite->data[0] = 0;
+ sprite->data[1] = gBattleAnimArgs[3];
+ sprite->data[2] = gBattleAnimArgs[4];
+ sprite->data[3] = 0;
+ sprite->callback = sub_80B0EF0;
+}
+
+static void sub_80B0EF0(struct Sprite *sprite)
+{
+ switch (sprite->data[0])
+ {
+ case 0:
+ if (--sprite->data[1] == 0)
+ {
+ if (sprite->data[2] == 0)
+ DestroyAnimSprite(sprite);
+ else
+ ++sprite->data[0];
+ }
+ break;
+ case 1:
+ if (++sprite->data[1] > 1)
+ {
+ sprite->data[1] = 0;
+ ++sprite->data[3];
+ if (sprite->data[3] & 1)
+ sprite->pos2.x = 2;
+ else
+ sprite->pos2.x = -2;
+ }
+
+ if (--sprite->data[2] == 0)
+ DestroyAnimSprite(sprite);
+ break;
+ }
+}
+
+static void sub_80B0F68(struct Sprite *sprite)
+{
+ if (gBattleAnimArgs[0] == 0)
+ {
+ sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimAttacker, 0) + gBattleAnimArgs[2];
+ sprite->pos1.y = GetBattlerSpriteCoord(gBattleAnimAttacker, 1) + gBattleAnimArgs[3];
+ }
+ else
+ {
+ sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimTarget, 0) + gBattleAnimArgs[2];
+ sprite->pos1.y = GetBattlerSpriteCoord(gBattleAnimTarget, 1) + gBattleAnimArgs[3];
+ }
+ sprite->oam.tileNum += gBattleAnimArgs[1] * 16;
+ sprite->data[0] = 0;
+ switch (gBattleAnimArgs[1])
+ {
+ case 0:
+ sprite->data[6] = -3;
+ sprite->data[7] = -3;
+ break;
+ case 1:
+ sprite->data[6] = 3;
+ sprite->data[7] = -3;
+ break;
+ case 2:
+ sprite->data[6] = -3;
+ sprite->data[7] = 3;
+ break;
+ case 3:
+ sprite->data[6] = 3;
+ sprite->data[7] = 3;
+ break;
+ default:
+ DestroyAnimSprite(sprite);
+ return;
+ }
+ sprite->callback = sub_80B1050;
+}
+
+static void sub_80B1050(struct Sprite *sprite)
+{
+ sprite->pos1.x += sprite->data[6];
+ sprite->pos1.y += sprite->data[7];
+ if (++sprite->data[0] > 40)
+ DestroyAnimSprite(sprite);
+}
+
+static void sub_80B107C(struct Sprite *sprite)
+{
+ if (gBattleAnimArgs[0] == 0)
+ {
+ sprite->pos1.x = GetBattlerSpriteCoord(gBattlerAttacker, 2);
+ sprite->pos1.y = GetBattlerSpriteCoord(gBattlerAttacker, 3);
+ sprite->oam.priority = GetBattlerSpriteBGPriority(gBattleAnimAttacker);
+ sprite->data[7] = gBattleAnimTarget;
+ }
+ else
+ {
+ sprite->oam.priority = GetBattlerSpriteBGPriority(gBattleAnimTarget);
+ sprite->data[7] = gBattleAnimAttacker;
+ }
+ sprite->data[0] = 0;
+ sprite->data[1] = 12;
+ sprite->data[2] = 8;
+ sprite->callback = sub_80B111C;
+}
+
+static void sub_80B111C(struct Sprite *sprite)
+{
+ if (++sprite->data[0] == 180)
+ {
+ SetGpuReg(REG_OFFSET_BLDCNT, 0);
+ sprite->data[0] = 16;
+ sprite->data[1] = sprite->pos1.x;
+ sprite->data[2] = GetBattlerSpriteCoord(sprite->data[7], 2);
+ sprite->data[3] = sprite->pos1.y;
+ sprite->data[4] = GetBattlerSpriteCoord(sprite->data[7], 3);
+ InitAnimLinearTranslation(sprite);
+ StoreSpriteCallbackInData6(sprite, DestroySpriteAndMatrix);
+ sprite->callback = sub_807563C;
+ }
+}
+
+static void sub_80B1188(struct Sprite *sprite)
+{
+ sprite->pos1.x = gBattleAnimArgs[0];
+ sprite->pos1.y = 120;
+ sprite->data[0] = gBattleAnimArgs[3];
+ StorePointerInVars(&sprite->data[4], &sprite->data[5], (void *)(sprite->pos1.y << 8));
+ sprite->data[6] = gBattleAnimArgs[1];
+ sprite->oam.tileNum += gBattleAnimArgs[2] * 4;
+ sprite->callback = sub_80B11E4;
+}
+
+static void sub_80B11E4(struct Sprite *sprite)
+{
+ void *var0;
+
+ if (sprite->data[0] != 0)
+ {
+ var0 = LoadPointerFromVars(sprite->data[4], sprite->data[5]);
+ var0 -= sprite->data[6];
+ StorePointerInVars(&sprite->data[4], &sprite->data[5], var0);
+ var0 = (void *)(((intptr_t)var0) >> 8);
+ sprite->pos1.y = (intptr_t)var0;
+ if (sprite->pos1.y < -8)
+ DestroyAnimSprite(sprite);
+ else
+ --sprite->data[0];
+ }
+ else
+ {
+ s16 pos0 = GetBattlerSpriteCoord(gBattleAnimAttacker, 2);
+ s16 pos1 = GetBattlerSpriteCoord(gBattleAnimAttacker, 3);
+ s16 pos2 = GetBattlerSpriteCoord(gBattleAnimTarget, 2);
+ s16 pos3 = GetBattlerSpriteCoord(gBattleAnimTarget, 3);
+
+ sprite->data[0] = pos2 - pos0;
+ sprite->data[1] = pos3 - pos1;
+ sprite->data[2] = sprite->pos1.x << 4;
+ sprite->data[3] = sprite->pos1.y << 4;
+ sprite->callback = sub_80B12A4;
+ }
+}
+
+static void sub_80B12A4(struct Sprite *sprite)
+{
+ u16 edgeX;
+
+ sprite->data[2] += sprite->data[0];
+ sprite->data[3] += sprite->data[1];
+ sprite->pos1.x = sprite->data[2] >> 4;
+ sprite->pos1.y = sprite->data[3] >> 4;
+ edgeX = sprite->pos1.x + 8;
+ if (edgeX > 256 || sprite->pos1.y < -8 || sprite->pos1.y > 120)
+ DestroyAnimSprite(sprite);
+}
+
+static void sub_80B12E8(struct Sprite *sprite)
+{
+ u8 battler;
+
+ if (gBattleAnimArgs[0] == 0)
+ {
+ sprite->pos1.x = GetBattlerSpriteCoord(gBattlerAttacker, 2);
+ sprite->pos1.y = GetBattlerSpriteCoord(gBattlerAttacker, 3);
+ battler = gBattleAnimTarget;
+ sprite->oam.priority = GetBattlerSpriteBGPriority(gBattleAnimAttacker);
+ }
+ else
+ {
+ battler = gBattleAnimAttacker;
+ sprite->oam.priority = GetBattlerSpriteBGPriority(gBattleAnimTarget);
+ }
+ if (IsContest())
+ sprite->oam.matrixNum |= ST_OAM_HFLIP;
+ else if (GetBattlerSide(battler) == B_SIDE_PLAYER)
+ sprite->oam.matrixNum |= (ST_OAM_HFLIP | ST_OAM_VFLIP);
+ sprite->data[0] = 16;
+ sprite->data[1] = sprite->pos1.x;
+ sprite->data[2] = GetBattlerSpriteCoord(battler, 2);
+ sprite->data[3] = sprite->pos1.y;
+ sprite->data[4] = GetBattlerSpriteCoord(battler, 3);
+ InitAnimLinearTranslation(sprite);
+ StoreSpriteCallbackInData6(sprite, DestroyAnimSprite);
+ sprite->callback = sub_807563C;
+}
+
+static void sub_80B13D4(struct Sprite *sprite)
+{
+ if (sprite->data[0] == sprite->data[4])
+ DestroyAnimSprite(sprite);
+ ++sprite->data[0];
+}
+
+static void sub_80B13F8(struct Sprite *sprite)
+{
+ u8 turn;
+
+ sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimTarget, 2);
+ sprite->pos1.y = GetBattlerSpriteCoord(gBattleAnimTarget, 3);
+ sprite->data[1] = gBattleAnimArgs[3];
+ sprite->data[2] = gBattleAnimArgs[0];
+ sprite->data[3] = gBattleAnimArgs[1];
+ sprite->data[4] = gBattleAnimArgs[2];
+ turn = gAnimMoveTurn;
+ if (GetBattlerSide(gBattleAnimTarget) == B_SIDE_PLAYER)
+ ++turn;
+ if (turn & 1)
+ {
+ sprite->data[2] = -sprite->data[2];
+ ++sprite->data[1];
+ }
+ StartSpriteAnim(sprite, sprite->data[1]);
+ sprite->pos2.x = sprite->data[2];
+ sprite->pos2.y = sprite->data[3];
+ sprite->callback = sub_80B13D4;
+}
+
+static void sub_80B1484(struct Sprite *sprite)
+{
+ if (gBattleAnimArgs[2] == 0)
+ InitSpritePosToAnimAttacker(sprite, 0);
+ else
+ InitSpritePosToAnimTarget(sprite, FALSE);
+ if (IsContest())
+ StartSpriteAnim(sprite, 2);
+ else if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER)
+ StartSpriteAnim(sprite, 1);
+ sprite->callback = RunStoredCallbackWhenAnimEnds;
+ StoreSpriteCallbackInData6(sprite, DestroyAnimSprite);
+}
+
+static void sub_80B14F0(struct Sprite *sprite)
+{
+ if (sprite->affineAnimEnded)
+ {
+ sprite->data[1] = (sprite->data[1] + 40) & 0xFF;
+ sprite->pos2.x = Sin(sprite->data[1], 2);
+ if (++sprite->data[0] > 40)
+ DestroyAnimSprite(sprite);
+ }
+}
+
+void sub_80B1530(u8 taskId)
+{
+ struct Task *task = &gTasks[taskId];
+
+ switch (task->data[0])
+ {
+ case 0:
+ sub_8075458(0);
+ task->data[8] = gBattleAnimArgs[0];
+ ++task->data[0];
+ break;
+ case 1:
+ if (--task->data[8] == -1)
+ ++task->data[0];
+ break;
+ case 2:
+ default:
+ task->data[9] += 1280;
+ break;
+ }
+ task->data[10] += 2816;
+ if (GetBattlerSide(gBattleAnimTarget) == B_SIDE_PLAYER)
+ gBattle_BG3_X += task->data[9] >> 8;
+ else
+ gBattle_BG3_X -= task->data[9] >> 8;
+ gBattle_BG3_Y += task->data[10] >> 8;
+ task->data[9] &= 0xFF;
+ task->data[10] &= 0xFF;
+ if (gBattleAnimArgs[7] == -1)
+ {
+ gBattle_BG3_X = 0;
+ gBattle_BG3_Y = 0;
+ sub_8075458(1);
+ DestroyAnimVisualTask(taskId);
+ }
+}
diff --git a/src/fire.c b/src/fire.c
new file mode 100644
index 000000000..014413f5b
--- /dev/null
+++ b/src/fire.c
@@ -0,0 +1,1193 @@
+#include "global.h"
+#include "battle_anim.h"
+#include "sound.h"
+#include "util.h"
+#include "task.h"
+#include "trig.h"
+#include "constants/songs.h"
+
+static void sub_80AC90C(struct Sprite *sprite);
+static void sub_80AC94C(struct Sprite *sprite);
+static void sub_80ACA00(struct Sprite *sprite);
+static void sub_80AC990(struct Sprite *sprite);
+static void sub_80ACAA8(struct Sprite *sprite);
+static void sub_80ACBB0(struct Sprite *sprite);
+static void AnimEmberFlare(struct Sprite *sprite);
+static void sub_80ACC44(struct Sprite *sprite);
+static void AnimFireRing(struct Sprite *sprite);
+static void AnimFireCross(struct Sprite *sprite);
+static void sub_80ACDE8(struct Sprite *sprite);
+static void sub_80AD330(struct Sprite *sprite);
+static void sub_80AD454(struct Sprite *sprite);
+static void sub_80AD540(struct Sprite *sprite);
+static void sub_80AD6F4(struct Sprite *sprite);
+static void sub_80ACA6C(struct Sprite *sprite);
+static void sub_80ACB1C(struct Sprite *sprite);
+static void AnimFireRing_Step1(struct Sprite *sprite);
+static void AnimFireRing_Step2(struct Sprite *sprite);
+static void AnimFireRing_Step3(struct Sprite *sprite);
+static void UpdateFireRingCircleOffset(struct Sprite *sprite);
+static void sub_80ACE28(struct Sprite *sprite);
+static void sub_80ACE50(struct Sprite *sprite);
+static void sub_80ACF14(u8 taskId);
+static void sub_80AD1F8(u8 spriteId, u8 taskId, u8 a3);
+static u16 sub_80AD374(u8 spriteId);
+static void sub_80AD3C8(struct Sprite *sprite, s16 x, s16 y);
+static void sub_80AD3E4(struct Sprite *sprite);
+static void sub_80AD4A8(struct Sprite *sprite);
+static void sub_80AD690(struct Sprite *sprite);
+static void sub_80AD870(u8 taskId);
+
+static const union AnimCmd gUnknown_83E5BB8[] =
+{
+ ANIMCMD_FRAME(16, 4),
+ ANIMCMD_FRAME(32, 4),
+ ANIMCMD_FRAME(48, 4),
+ ANIMCMD_JUMP(0),
+};
+
+static const union AnimCmd gUnknown_83E5BC8[] =
+{
+ ANIMCMD_FRAME(16, 4, .vFlip = TRUE, .hFlip = TRUE),
+ ANIMCMD_FRAME(32, 4, .vFlip = TRUE, .hFlip = TRUE),
+ ANIMCMD_FRAME(48, 4, .vFlip = TRUE, .hFlip = TRUE),
+ ANIMCMD_JUMP(0),
+};
+
+static const union AnimCmd *const gUnknown_83E5BD8[] =
+{
+ gUnknown_83E5BB8,
+ gUnknown_83E5BC8,
+};
+
+const struct SpriteTemplate gUnknown_83E5BE0 =
+{
+ .tileTag = ANIM_TAG_SMALL_EMBER,
+ .paletteTag = ANIM_TAG_SMALL_EMBER,
+ .oam = &gOamData_83AC9D8,
+ .anims = gUnknown_83E5BD8,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = sub_80AC90C,
+};
+
+const struct SpriteTemplate gUnknown_83E5BF8 =
+{
+ .tileTag = ANIM_TAG_SMALL_EMBER,
+ .paletteTag = ANIM_TAG_SMALL_EMBER,
+ .oam = &gOamData_83AC9D8,
+ .anims = gUnknown_83E5BD8,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = sub_80AC94C,
+};
+
+static const union AnimCmd gUnknown_83E5C10[] =
+{
+ ANIMCMD_FRAME(0, 3),
+ ANIMCMD_FRAME(16, 3),
+ ANIMCMD_FRAME(32, 3),
+ ANIMCMD_FRAME(48, 3),
+ ANIMCMD_FRAME(64, 3),
+ ANIMCMD_FRAME(80, 3),
+ ANIMCMD_FRAME(96, 3),
+ ANIMCMD_FRAME(112, 3),
+ ANIMCMD_JUMP(0),
+};
+
+static const union AnimCmd *const gUnknown_83E5C34[] =
+{
+ gUnknown_83E5C10,
+};
+
+static const union AnimCmd gUnknown_83E5C38[] =
+{
+ ANIMCMD_FRAME(0, 5),
+ ANIMCMD_FRAME(16, 5),
+ ANIMCMD_FRAME(32, 5),
+ ANIMCMD_FRAME(48, 5),
+ ANIMCMD_FRAME(64, 5),
+ ANIMCMD_JUMP(0),
+};
+
+static const union AnimCmd *const gUnknown_83E5C50[] =
+{
+ gUnknown_83E5C38,
+};
+
+static const union AffineAnimCmd gUnknown_83E5C54[] =
+{
+ AFFINEANIMCMD_FRAME(0x32, 0x100, 0, 0),
+ AFFINEANIMCMD_FRAME(0x20, 0x0, 0, 7),
+ AFFINEANIMCMD_END,
+};
+
+static const union AffineAnimCmd *const gUnknown_83E5C6C[] =
+{
+ gUnknown_83E5C54,
+};
+
+const struct SpriteTemplate gUnknown_83E5C70 =
+{
+ .tileTag = ANIM_TAG_FIRE,
+ .paletteTag = ANIM_TAG_FIRE,
+ .oam = &gOamData_83ACA38,
+ .anims = gUnknown_83E5C34,
+ .images = NULL,
+ .affineAnims = gUnknown_83E5C6C,
+ .callback = sub_80ACA00,
+};
+
+const struct SpriteTemplate gUnknown_83E5C88 =
+{
+ .tileTag = ANIM_TAG_FIRE,
+ .paletteTag = ANIM_TAG_FIRE,
+ .oam = &gOamData_83AC9D8,
+ .anims = gUnknown_83E5C34,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = sub_80ACA00,
+};
+
+const struct SpriteTemplate gUnknown_83E5CA0 =
+{
+ .tileTag = ANIM_TAG_FIRE_PLUME,
+ .paletteTag = ANIM_TAG_FIRE_PLUME,
+ .oam = &gOamData_83AC9D8,
+ .anims = gUnknown_83E5C50,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = sub_80AC990,
+};
+
+const struct SpriteTemplate gUnknown_83E5CB8 =
+{
+ .tileTag = ANIM_TAG_SMALL_EMBER,
+ .paletteTag = ANIM_TAG_SMALL_EMBER,
+ .oam = &gOamData_83AC9D8,
+ .anims = gUnknown_83E5C50,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = sub_80AC990,
+};
+
+static const union AnimCmd gUnknown_83E5CD0[] =
+{
+ ANIMCMD_FRAME(16, 6),
+ ANIMCMD_FRAME(32, 6),
+ ANIMCMD_FRAME(48, 6),
+ ANIMCMD_JUMP(0),
+};
+
+static const union AnimCmd *const gUnknown_83E5CE0[] =
+{
+ gUnknown_83E5CD0,
+};
+
+const struct SpriteTemplate gUnknown_83E5CE4 =
+{
+ .tileTag = ANIM_TAG_SMALL_EMBER,
+ .paletteTag = ANIM_TAG_SMALL_EMBER,
+ .oam = &gOamData_83AC9D8,
+ .anims = gUnknown_83E5CE0,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = sub_80ACAA8,
+};
+
+static const union AffineAnimCmd gUnknown_83E5CFC[] =
+{
+ AFFINEANIMCMD_FRAME(0x50, 0x50, 0, 0),
+ AFFINEANIMCMD_FRAME(0x2, 0x2, 10, 1),
+ AFFINEANIMCMD_JUMP(1),
+};
+
+static const union AffineAnimCmd *const gUnknown_83E5D14[] =
+{
+ gUnknown_83E5CFC,
+};
+
+const struct SpriteTemplate gUnknown_83E5D18 =
+{
+ .tileTag = ANIM_TAG_SUNLIGHT,
+ .paletteTag = ANIM_TAG_SUNLIGHT,
+ .oam = &gOamData_83ACB58,
+ .anims = gDummySpriteAnimTable,
+ .images = NULL,
+ .affineAnims = gUnknown_83E5D14,
+ .callback = sub_80ACBB0,
+};
+
+static const union AnimCmd gUnknown_83E5D30[] =
+{
+ ANIMCMD_FRAME(0, 4),
+ ANIMCMD_FRAME(16, 4),
+ ANIMCMD_FRAME(32, 4),
+ ANIMCMD_FRAME(48, 4),
+ ANIMCMD_FRAME(64, 4),
+ ANIMCMD_JUMP(0),
+};
+
+const union AnimCmd *const gUnknown_83E5D48[] =
+{
+ gUnknown_83E5D30,
+};
+
+const struct SpriteTemplate gEmberSpriteTemplate =
+{
+ .tileTag = ANIM_TAG_SMALL_EMBER,
+ .paletteTag = ANIM_TAG_SMALL_EMBER,
+ .oam = &gOamData_83AC9D8,
+ .anims = gDummySpriteAnimTable,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = TranslateAnimSpriteToTargetMonLocation,
+};
+
+const struct SpriteTemplate gEmberFlareSpriteTemplate =
+{
+ .tileTag = ANIM_TAG_SMALL_EMBER,
+ .paletteTag = ANIM_TAG_SMALL_EMBER,
+ .oam = &gOamData_83AC9D8,
+ .anims = gUnknown_83E5D48,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = AnimEmberFlare,
+};
+
+const struct SpriteTemplate gUnknown_83E5D7C =
+{
+ .tileTag = ANIM_TAG_SMALL_EMBER,
+ .paletteTag = ANIM_TAG_SMALL_EMBER,
+ .oam = &gOamData_83AC9D8,
+ .anims = gUnknown_83E5D48,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = sub_80ACC44,
+};
+
+const struct SpriteTemplate gUnknown_83E5D94 =
+{
+ .tileTag = ANIM_TAG_SMALL_EMBER,
+ .paletteTag = ANIM_TAG_SMALL_EMBER,
+ .oam = &gOamData_83AC9D8,
+ .anims = gUnknown_83E5D48,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = AnimFireRing,
+};
+
+static const union AnimCmd gUnknown_83E5DAC[] =
+{
+ ANIMCMD_FRAME(32, 6),
+ ANIMCMD_FRAME(48, 6),
+ ANIMCMD_JUMP(0),
+};
+
+static const union AnimCmd *const gUnknown_83E5DB8[] =
+{
+ gUnknown_83E5DAC,
+};
+
+static const union AffineAnimCmd gUnknown_83E5DBC[] =
+{
+ AFFINEANIMCMD_FRAME(0x0, 0x0, 0, 1),
+ AFFINEANIMCMD_END,
+};
+
+static const union AffineAnimCmd gUnknown_83E5DCC[] =
+{
+ AFFINEANIMCMD_FRAME(0xA0, 0xA0, 0, 0),
+ AFFINEANIMCMD_END,
+};
+
+static const union AffineAnimCmd *const gUnknown_83E5DDC[] =
+{
+ gUnknown_83E5DBC,
+ gUnknown_83E5DCC,
+};
+
+const struct SpriteTemplate gUnknown_83E5DE4 =
+{
+ .tileTag = ANIM_TAG_SMALL_EMBER,
+ .paletteTag = ANIM_TAG_SMALL_EMBER,
+ .oam = &gOamData_83AC9D8,
+ .anims = gUnknown_83E5DB8,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = AnimFireCross,
+};
+
+const struct SpriteTemplate gUnknown_83E5DFC =
+{
+ .tileTag = ANIM_TAG_SMALL_EMBER,
+ .paletteTag = ANIM_TAG_SMALL_EMBER,
+ .oam = &gOamData_83AC9D8,
+ .anims = gUnknown_83E5D48,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = sub_80ACDE8,
+};
+
+const struct SpriteTemplate gUnknown_83E5E14 =
+{
+ .tileTag = ANIM_TAG_SMALL_EMBER,
+ .paletteTag = ANIM_TAG_SMALL_EMBER,
+ .oam = &gOamData_83AC9D8,
+ .anims = gUnknown_83E5D48,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = sub_8077350,
+};
+
+static const struct SpriteTemplate gUnknown_83E5E2C =
+{
+ .tileTag = ANIM_TAG_WARM_ROCK,
+ .paletteTag = ANIM_TAG_WARM_ROCK,
+ .oam = &gOamData_83AC9D0,
+ .anims = gDummySpriteAnimTable,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = sub_80AD330,
+};
+
+static const s16 sHeatedRockCoords[][2] =
+{
+ {-2, -5},
+ {-1, -1},
+ { 3, -6},
+ { 4, -2},
+ { 2, -8},
+ {-5, -5},
+ { 4, -7},
+};
+
+const struct SpriteTemplate gUnknown_83E5E60 =
+{
+ .tileTag = ANIM_TAG_WARM_ROCK,
+ .paletteTag = ANIM_TAG_WARM_ROCK,
+ .oam = &gOamData_83AC9D8,
+ .anims = gDummySpriteAnimTable,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = sub_80AD454,
+};
+
+static const union AnimCmd gUnknown_83E5E78[] =
+{
+ ANIMCMD_FRAME(0, 5),
+ ANIMCMD_FRAME(4, 5),
+ ANIMCMD_FRAME(8, 5),
+ ANIMCMD_FRAME(12, 5),
+ ANIMCMD_JUMP(0),
+};
+
+static const union AnimCmd gUnknown_83E5E8C[] =
+{
+ ANIMCMD_FRAME(16, 5),
+ ANIMCMD_END,
+};
+
+static const union AnimCmd gUnknown_83E5E94[] =
+{
+ ANIMCMD_FRAME(20, 5),
+ ANIMCMD_END,
+};
+
+static const union AnimCmd gUnknown_83E5E9C[] =
+{
+ ANIMCMD_FRAME(20, 5),
+ ANIMCMD_END,
+};
+
+static const union AnimCmd *const gUnknown_83E5EA4[] =
+{
+ gUnknown_83E5E78,
+ gUnknown_83E5E8C,
+ gUnknown_83E5E94,
+ gUnknown_83E5E9C,
+};
+
+const struct SpriteTemplate gUnknown_83E5EB4 =
+{
+ .tileTag = ANIM_TAG_WISP_ORB,
+ .paletteTag = ANIM_TAG_WISP_ORB,
+ .oam = &gOamData_83AC9D0,
+ .anims = gUnknown_83E5EA4,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = sub_80AD540,
+};
+
+static const union AnimCmd gUnknown_83E5ECC[] =
+{
+ ANIMCMD_FRAME(0, 5),
+ ANIMCMD_FRAME(16, 5),
+ ANIMCMD_FRAME(32, 5),
+ ANIMCMD_FRAME(48, 5),
+ ANIMCMD_JUMP(0),
+};
+
+static const union AnimCmd *const gUnknown_83E5EE0[] =
+{
+ gUnknown_83E5ECC,
+};
+
+const struct SpriteTemplate gUnknown_83E5EE4 =
+{
+ .tileTag = ANIM_TAG_WISP_FIRE,
+ .paletteTag = ANIM_TAG_WISP_FIRE,
+ .oam = &gOamData_83AC9D8,
+ .anims = gUnknown_83E5EE0,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = sub_80AD6F4,
+};
+
+static const s8 gUnknown_83E5EFC[16] =
+{
+ -1, -1, 0, 1, 1, 0, 0, -1, -1, 1, 1, 0, 0, -1, 0, 1,
+};
+
+static const s8 gUnknown_83E5F0C[16] =
+{
+ -1, 0, 1, 0, -1, 1, 0, -1, 0, 1, 0, -1, 0, 1, 0, 1,
+};
+
+static void sub_80AC90C(struct Sprite *sprite)
+{
+ sprite->data[0] = gBattleAnimArgs[0];
+ sprite->data[1] = 0x3C;
+ sprite->data[2] = 0x9;
+ sprite->data[3] = 0x1E;
+ sprite->data[4] = 0xFE00;
+ StoreSpriteCallbackInData6(sprite, DestroyAnimSprite);
+ sprite->callback = TranslateSpriteInGrowingCircleOverDuration;
+ sprite->callback(sprite);
+}
+
+static void sub_80AC94C(struct Sprite *sprite)
+{
+ SetAnimSpriteInitialXOffset(sprite, gBattleAnimArgs[0]);
+ sprite->pos1.y += gBattleAnimArgs[1];
+ sprite->data[0] = gBattleAnimArgs[4];
+ sprite->data[1] = gBattleAnimArgs[2];
+ sprite->data[2] = gBattleAnimArgs[3];
+ sprite->callback = TranslateSpriteLinearFixedPoint;
+ StoreSpriteCallbackInData6(sprite, DestroyAnimSprite);
+}
+
+static void sub_80AC990(struct Sprite *sprite)
+{
+ SetSpriteCoordsToAnimAttackerCoords(sprite);
+ if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER)
+ {
+ sprite->pos1.x -= gBattleAnimArgs[0];
+ sprite->pos1.y += gBattleAnimArgs[1];
+ sprite->data[2] = -gBattleAnimArgs[4];
+ }
+ else
+ {
+ sprite->pos1.x += gBattleAnimArgs[0];
+ sprite->pos1.y += gBattleAnimArgs[1];
+ sprite->data[2] = gBattleAnimArgs[4];
+ }
+ sprite->data[1] = gBattleAnimArgs[2];
+ sprite->data[4] = gBattleAnimArgs[3];
+ sprite->data[3] = gBattleAnimArgs[5];
+ sprite->callback = sub_80ACA6C;
+}
+
+static void sub_80ACA00(struct Sprite *sprite)
+{
+ if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER)
+ {
+ sprite->pos1.x -= gBattleAnimArgs[0];
+ sprite->pos1.y += gBattleAnimArgs[1];
+ sprite->data[2] = gBattleAnimArgs[4];
+ }
+ else
+ {
+ sprite->pos1.x += gBattleAnimArgs[0];
+ sprite->pos1.y += gBattleAnimArgs[1];
+ sprite->data[2] = -gBattleAnimArgs[4];
+ }
+ sprite->data[1] = gBattleAnimArgs[2];
+ sprite->data[4] = gBattleAnimArgs[3];
+ sprite->data[3] = gBattleAnimArgs[5];
+ sprite->callback = sub_80ACA6C;
+}
+
+static void sub_80ACA6C(struct Sprite *sprite)
+{
+ if (++sprite->data[0] < sprite->data[4])
+ {
+ sprite->pos2.x += sprite->data[2];
+ sprite->pos2.y += sprite->data[3];
+ }
+ if (sprite->data[0] == sprite->data[1])
+ DestroySpriteAndMatrix(sprite);
+}
+
+static void sub_80ACAA8(struct Sprite *sprite)
+{
+ SetSpriteCoordsToAnimAttackerCoords(sprite);
+ if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER)
+ {
+ sprite->pos1.x -= gBattleAnimArgs[0];
+ }
+ else
+ {
+ sprite->pos1.x += gBattleAnimArgs[0];
+ sprite->subpriority = 8;
+ }
+ sprite->pos1.y += gBattleAnimArgs[1];
+ sprite->data[0] = gBattleAnimArgs[2];
+ sprite->data[1] = gBattleAnimArgs[3];
+ sprite->data[2] = gBattleAnimArgs[4];
+ sprite->data[3] = gBattleAnimArgs[5];
+ sprite->data[4] = gBattleAnimArgs[6];
+ sprite->data[5] = 0;
+ sprite->callback = sub_80ACB1C;
+}
+
+static void sub_80ACB1C(struct Sprite *sprite)
+{
+ if (sprite->data[3])
+ {
+ if(sprite->data[5] > 10000)
+ sprite->subpriority = 1;
+ sprite->pos2.x = Sin(sprite->data[0], sprite->data[1] + (sprite->data[5] >> 8));
+ sprite->pos2.y = Cos(sprite->data[0], sprite->data[1] + (sprite->data[5] >> 8));
+ sprite->data[0] += sprite->data[2];
+ sprite->data[5] += sprite->data[4];
+ if (sprite->data[0] > 255)
+ sprite->data[0] -= 256;
+ else if (sprite->data[0] < 0)
+ sprite->data[0] += 256;
+ --sprite->data[3];
+ }
+ else
+ {
+ DestroySpriteAndMatrix(sprite);
+ }
+}
+
+//sunlight
+static void sub_80ACBB0(struct Sprite *sprite)
+{
+ sprite->pos1.x = 0;
+ sprite->pos1.y = 0;
+ sprite->data[0] = 60;
+ sprite->data[2] = 140;
+ sprite->data[4] = 80;
+ sprite->callback = StartAnimLinearTranslation;
+ StoreSpriteCallbackInData6(sprite, DestroyAnimSprite);
+}
+
+//fire 2
+
+// Animates the secondary effect of MOVE_EMBER, where the flames grow and slide
+// horizontally a bit.
+// arg 0: initial x pixel offset
+// arg 1: initial y pixel offset
+// arg 2: target x pixel offset
+// arg 3: target y pixel offset
+// arg 4: duration
+// arg 5: ? (TODO: something related to which mon the pixel offsets are based on)
+// arg 6: ? (TODO: something related to which mon the pixel offsets are based on)
+static void AnimEmberFlare(struct Sprite *sprite)
+{
+ if (GetBattlerSide(gBattleAnimAttacker) == GetBattlerSide(gBattleAnimTarget)
+ && (gBattleAnimAttacker == GetBattlerAtPosition(B_POSITION_PLAYER_RIGHT)
+ || gBattleAnimAttacker == GetBattlerAtPosition(B_POSITION_OPPONENT_RIGHT)))
+ gBattleAnimArgs[2] = -gBattleAnimArgs[2];
+ sprite->callback = AnimSnoreZ;
+ sprite->callback(sprite);
+}
+
+static void sub_80ACC44(struct Sprite *sprite)
+{
+ gBattleAnimArgs[0] = -gBattleAnimArgs[0];
+ gBattleAnimArgs[2] = -gBattleAnimArgs[2];
+ sprite->callback = AnimSnoreZ;
+}
+
+// Animates the a fire sprite in the first-half of the MOVE_FIRE_BLAST
+// animation. The fire sprite first moves in a circle around the mon,
+// and then it is translated towards the target mon, while still rotating.
+// Lastly, it moves in a circle around the target mon.
+// arg 0: initial x pixel offset
+// arg 1: initial y pixel offset
+// arg 2: initial wave offset
+//void AnimFireRing(struct Sprite *sprite)
+static void AnimFireRing(struct Sprite *sprite)
+{
+ InitSpritePosToAnimAttacker(sprite, 1);
+ sprite->data[7] = gBattleAnimArgs[2];
+ sprite->data[0] = 0;
+ sprite->callback = AnimFireRing_Step1;
+}
+
+static void AnimFireRing_Step1(struct Sprite *sprite)
+{
+ UpdateFireRingCircleOffset(sprite);
+
+ if (++sprite->data[0] == 0x12)
+ {
+ sprite->data[0] = 0x19;
+ sprite->data[1] = sprite->pos1.x;
+ sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimTarget, 2);
+ sprite->data[3] = sprite->pos1.y;
+ sprite->data[4] = GetBattlerSpriteCoord(gBattleAnimTarget, 3);
+ InitAnimLinearTranslation(sprite);
+ sprite->callback = AnimFireRing_Step2;
+ }
+}
+
+static void AnimFireRing_Step2(struct Sprite *sprite)
+{
+ if (AnimTranslateLinear(sprite))
+ {
+ sprite->data[0] = 0;
+
+ sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimTarget, 2);
+ sprite->pos1.y = GetBattlerSpriteCoord(gBattleAnimTarget, 3);
+ sprite->pos2.x = sprite->pos2.y = 0;
+ sprite->callback = AnimFireRing_Step3;
+ sprite->callback(sprite);
+ }
+ else
+ {
+ sprite->pos2.x += Sin(sprite->data[7], 28);
+ sprite->pos2.y += Cos(sprite->data[7], 28);
+ sprite->data[7] = (sprite->data[7] + 20) & 0xFF;
+ }
+}
+
+static void AnimFireRing_Step3(struct Sprite *sprite)
+{
+ UpdateFireRingCircleOffset(sprite);
+ if (++sprite->data[0] == 0x1F)
+ DestroyAnimSprite(sprite);
+}
+
+static void UpdateFireRingCircleOffset(struct Sprite *sprite)
+{
+ sprite->pos2.x = Sin(sprite->data[7], 28);
+ sprite->pos2.y = Cos(sprite->data[7], 28);
+ sprite->data[7] = (sprite->data[7] + 20) & 0xFF;
+}
+
+// arg 0: initial x pixel offset
+// arg 1: initial y pixel offset
+// arg 2: duration
+// arg 3: x delta
+// arg 4: y delta
+// AnimFireCross(struct Sprite *sprite)
+static void AnimFireCross(struct Sprite *sprite)
+{
+ sprite->pos1.x += gBattleAnimArgs[0];
+ sprite->pos1.y += gBattleAnimArgs[1];
+ sprite->data[0] = gBattleAnimArgs[2];
+ sprite->data[1] = gBattleAnimArgs[3];
+ sprite->data[2] = gBattleAnimArgs[4];
+ StoreSpriteCallbackInData6(sprite, DestroyAnimSprite);
+ sprite->callback = TranslateSpriteLinear;
+}
+
+static void sub_80ACDE8(struct Sprite *sprite)
+{
+ InitSpritePosToAnimAttacker(sprite, 1);
+ sprite->data[1] = gBattleAnimArgs[2];
+ sprite->data[0] = gBattleAnimArgs[3];
+ sprite->invisible = TRUE;
+ sprite->callback = WaitAnimForDuration;
+ StoreSpriteCallbackInData6(sprite, sub_80ACE28);
+}
+
+static void sub_80ACE28(struct Sprite *sprite)
+{
+ sprite->invisible = FALSE;
+ sprite->data[0] = sprite->data[1];
+ sprite->data[1] = 0;
+ sprite->callback = sub_80ACE50;
+ sprite->callback(sprite);
+}
+
+static void sub_80ACE50(struct Sprite *sprite)
+{
+ sprite->pos2.x = Sin(sprite->data[1], sprite->data[2] >> 8);
+ sprite->pos2.y = Cos(sprite->data[1], sprite->data[2] >> 8);
+ sprite->data[1] = (sprite->data[1] + 10) & 0xFF;
+ sprite->data[2] += 0xD0;
+ if (--sprite->data[0] == -1)
+ DestroyAnimSprite(sprite);
+}
+
+void sub_80ACEA4(u8 taskId) // initialize animation task for Move_ERUPTION?
+{
+ struct Task *task = &gTasks[taskId];
+
+ task->data[15] = GetAnimBattlerSpriteId(ANIM_ATTACKER);
+ task->data[0] = 0;
+ task->data[1] = 0;
+ task->data[2] = 0;
+ task->data[3] = 0;
+ task->data[4] = gSprites[task->data[15]].pos1.y;
+ task->data[5] = GetBattlerSide(gBattleAnimAttacker);
+ task->data[6] = 0;
+ PrepareBattlerSpriteForRotScale(task->data[15], ST_OAM_OBJ_NORMAL);
+ task->func = sub_80ACF14;
+}
+
+static void sub_80ACF14(u8 taskId) // animate Move_ERUPTION?
+{
+ struct Task *task = &gTasks[taskId];
+
+ switch (task->data[0])
+ {
+ case 0:
+ sub_80765D4(task, task->data[15], 0x100, 0x100, 0xE0, 0x200, 0x20);
+ ++task->data[0];
+ // fall through
+ case 1:
+ if (++task->data[1] > 1)
+ {
+ task->data[1] = 0;
+ if (++task->data[2] & 0x1)
+ gSprites[task->data[15]].pos2.x = 3;
+ else
+ gSprites[task->data[15]].pos2.x = -3;
+ }
+ if (task->data[5])
+ {
+ if (++task->data[3] > 4)
+ {
+ task->data[3] = 0;
+ ++gSprites[task->data[15]].pos1.y;
+ }
+ }
+ if(!sub_8076640(task))
+ {
+ SetBattlerSpriteYOffsetFromYScale(task->data[15]);
+ gSprites[task->data[15]].pos2.x = 0;
+ task->data[1] = 0;
+ task->data[2] = 0;
+ task->data[3] = 0;
+ ++task->data[0];
+ }
+ break;
+ case 2:
+ if (++task->data[1] > 4)
+ {
+ if (task->data[5])
+ sub_80765D4(task, task->data[15], 0xE0, 0x200, 0x180, 0xF0, 0x6);
+ else
+ sub_80765D4(task, task->data[15], 0xE0, 0x200, 0x180, 0xC0, 0x6);
+ task->data[1] = 0;
+ ++task->data[0];
+ }
+ break;
+ case 3:
+ if (!sub_8076640(task))
+ {
+ sub_80AD1F8(task->data[15], taskId, 6);
+ ++task->data[0];
+ }
+ break;
+ case 4:
+ if (++task->data[1] > 1)
+ {
+ task->data[1] = 0;
+ if (++task->data[2] & 1)
+ gSprites[task->data[15]].pos2.y += 3;
+ else
+ gSprites[task->data[15]].pos2.y -= 3;
+ }
+ if (++task->data[3] > 0x18)
+ {
+ if (task->data[5])
+ sub_80765D4(task, task->data[15], 0x180, 0xF0, 0x100, 0x100, 0x8);
+ else
+ sub_80765D4(task, task->data[15], 0x180, 0xC0, 0x100, 0x100, 0x8);
+ if (task->data[2] & 1)
+ gSprites[task->data[15]].pos2.y -= 3;
+ task->data[1] = 0;
+ task->data[2] = 0;
+ task->data[3] = 0;
+ ++task->data[0];
+ }
+ break;
+ case 5:
+ if (task->data[5])
+ --gSprites[task->data[15]].pos1.y;
+ if (!sub_8076640(task))
+ {
+ gSprites[task->data[15]].pos1.y = task->data[4];
+ ResetSpriteRotScale(task->data[15]);
+
+ task->data[2] = 0;
+ ++task->data[0];
+ }
+ break;
+ case 6:
+ if (!task->data[6])
+ DestroyAnimVisualTask(taskId);
+ break;
+ }
+}
+
+static void sub_80AD1F8(u8 spriteId, u8 taskId, u8 a3)
+{
+ u16 i, j;
+ s8 sign;
+ u16 y = sub_80AD374(spriteId);
+ u16 x = gSprites[spriteId].pos1.x;
+
+ if(GetBattlerSide(gBattleAnimAttacker) == B_SIDE_PLAYER)
+ {
+ x -= 0xC;
+ sign = 1;
+ }
+ else
+ {
+ x += 0x10;
+ sign = -1;
+ }
+ for (i = 0, j = 0; i <= 6; ++i)
+ {
+ u8 spriteId = CreateSprite(&gUnknown_83E5E2C, x, y, 2);
+
+ if (spriteId != 0x40)
+ {
+ gSprites[spriteId].oam.tileNum += j * 4 + 0x40;
+ if (++j >= 5)
+ j = 0;
+ sub_80AD3C8(&gSprites[spriteId], sHeatedRockCoords[i][0] * sign, sHeatedRockCoords[i][1]);
+ gSprites[spriteId].data[6] = taskId;
+ gSprites[spriteId].data[7] = a3;
+ ++gTasks[taskId].data[a3];
+ }
+ }
+}
+
+static void sub_80AD330(struct Sprite *sprite)
+{
+ sub_80AD3E4(sprite);
+ if (sprite->invisible)
+ {
+ --gTasks[sprite->data[6]].data[sprite->data[7]];
+ DestroySprite(sprite);
+ }
+}
+
+static u16 sub_80AD374(u8 spriteId)
+{
+ u16 var1 = gSprites[spriteId].pos1.y + gSprites[spriteId].pos2.y + gSprites[spriteId].centerToCornerVecY;
+
+ if (GetBattlerSide(gBattleAnimAttacker) == B_SIDE_PLAYER)
+ var1 = ((var1 << 16) + 0x4A0000) >> 16;
+ else
+ var1 = ((var1 << 16) + 0x2C0000) >> 16;
+ return var1;
+}
+
+static void sub_80AD3C8(struct Sprite *sprite, s16 x, s16 y)
+{
+ sprite->data[0] = 0;
+ sprite->data[1] = 0;
+ sprite->data[2] = (u16)sprite->pos1.x * 8;
+ sprite->data[3] = (u16)sprite->pos1.y * 8;
+ sprite->data[4] = x * 8;
+ sprite->data[5] = y * 8;
+}
+
+static void sub_80AD3E4(struct Sprite *sprite)
+{
+ s32 var1;
+
+ if (++sprite->data[0] > 2)
+ {
+ sprite->data[0] = 0;
+ ++sprite->data[1];
+ var1 = (u16)sprite->data[1] * (u16)sprite->data[1];
+ sprite->data[3] += var1;
+ }
+ sprite->data[2] += sprite->data[4];
+ sprite->pos1.x = sprite->data[2] >> 3;
+ sprite->data[3] += sprite->data[5];
+ sprite->pos1.y = sprite->data[3] >> 3;
+ if (sprite->pos1.x < -8 || sprite->pos1.x > 0xf8 || sprite->pos1.y < -8 || sprite->pos1.y > 120)
+ sprite->invisible = TRUE;
+}
+
+static void sub_80AD454(struct Sprite *sprite)
+{
+ sprite->pos1.x = gBattleAnimArgs[0];
+ sprite->pos1.y = gBattleAnimArgs[1];
+ sprite->data[0] = 0;
+ sprite->data[1] = 0;
+ sprite->data[2] = 0;
+ sprite->data[6] = gBattleAnimArgs[2];
+ sprite->data[7] = gBattleAnimArgs[3];
+ sprite->oam.tileNum += gBattleAnimArgs[4] * 16;
+ sprite->callback = sub_80AD4A8;
+}
+
+static void sub_80AD4A8(struct Sprite *sprite)
+{
+ switch (sprite->data[0])
+ {
+ case 0:
+ if (sprite->data[6] != 0)
+ {
+ --sprite->data[6];
+ return;
+ }
+ ++sprite->data[0];
+ // fall through
+ case 1:
+ sprite->pos1.y += 8;
+ if (sprite->pos1.y >= sprite->data[7])
+ {
+ sprite->pos1.y = sprite->data[7];
+ ++sprite->data[0];
+ }
+ break;
+ case 2:
+ if (++sprite->data[1] > 1)
+ {
+ sprite->data[1] = 0;
+ if ((++sprite->data[2] & 1) != 0)
+ sprite->pos2.y = -3;
+ else
+ sprite->pos2.y = 3;
+ }
+ if (++sprite->data[3] > 16)
+ DestroyAnimSprite(sprite);
+ break;
+ }
+}
+
+//wisp orb
+static void sub_80AD540(struct Sprite *sprite)
+{
+ switch (sprite->data[0])
+ {
+ case 0:
+ InitSpritePosToAnimAttacker(sprite, 0);
+ StartSpriteAnim(sprite, gBattleAnimArgs[2]);
+ sprite->data[7] = gBattleAnimArgs[2];
+ if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER)
+ sprite->data[4] = 4;
+ else
+ sprite->data[4] = -4;
+ sprite->oam.priority = GetBattlerSpriteBGPriority(gBattleAnimTarget);
+ ++sprite->data[0];
+ break;
+ case 1:
+ sprite->data[1] += 192;
+ if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER)
+ sprite->pos2.y = -(sprite->data[1] >> 8);
+ else
+ sprite->pos2.y = sprite->data[1] >> 8;
+ sprite->pos2.x = Sin(sprite->data[2], sprite->data[4]);
+ sprite->data[2] = (sprite->data[2] + 4) & 0xFF;
+ if (++sprite->data[3] == 1)
+ {
+ sprite->data[3] = 0;
+ ++sprite->data[0];
+ }
+ break;
+ case 2:
+ sprite->pos2.x = Sin(sprite->data[2], sprite->data[4]);
+ sprite->data[2] = (sprite->data[2] + 4) & 0xFF;
+ if (++sprite->data[3] == 31)
+ {
+ sprite->pos1.x += sprite->pos2.x;
+ sprite->pos1.y += sprite->pos2.y;
+ sprite->pos2.x = sprite->pos2.y = 0;
+ sprite->data[0] = 256;
+ sprite->data[1] = sprite->pos1.x;
+ sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimTarget, 2);
+ sprite->data[3] = sprite->pos1.y;
+ sprite->data[4] = GetBattlerSpriteCoord(gBattleAnimTarget, 3);
+ sub_8075678(sprite);
+ sprite->callback = sub_80AD690;
+ }
+ break;
+ }
+}
+
+static void sub_80AD690(struct Sprite *sprite)
+{
+ s16 initialData5, newData5;
+
+ if (!AnimTranslateLinear(sprite))
+ {
+ sprite->pos2.x += Sin(sprite->data[5], 16);
+ initialData5 = sprite->data[5];
+ sprite->data[5] = (sprite->data[5] + 4) & 0xFF;
+ newData5 = sprite->data[5];
+ if ((initialData5 == 0 || initialData5 > 196) && newData5 > 0 && sprite->data[7] == 0)
+ PlaySE12WithPanning(SE_W172, gUnknown_2037F24);
+ }
+ else
+ {
+ DestroyAnimSprite(sprite);
+ }
+}
+
+//wisp fire
+static void sub_80AD6F4(struct Sprite *sprite)
+{
+ if (!sprite->data[0])
+ {
+ sprite->data[1] = gBattleAnimArgs[0];
+ ++sprite->data[0];
+ }
+ sprite->data[3] += 0xC0 * 2;
+ sprite->data[4] += 0xA0;
+ sprite->pos2.x = Sin(sprite->data[1], sprite->data[3] >> 8);
+ sprite->pos2.y = Cos(sprite->data[1], sprite->data[4] >> 8);
+ sprite->data[1] = (sprite->data[1] + 7) & 0xFF;
+ if (!IsContest())
+ {
+ if (sprite->data[1] < 64 || sprite->data[1] > 195)
+ sprite->oam.priority = GetBattlerSpriteBGPriority(gBattleAnimTarget);
+ else
+ sprite->oam.priority = GetBattlerSpriteBGPriority(gBattleAnimTarget) + 1;
+ }
+ else
+ {
+ if (sprite->data[1] < 64 || sprite->data[1] > 195)
+ sprite->subpriority = 0x1D;
+ else
+ sprite->subpriority = 0x1F;
+ }
+ if (++sprite->data[2] > 0x14)
+ sprite->invisible ^= 1;
+ if (sprite->data[2] == 0x1E)
+ DestroyAnimSprite(sprite);
+}
+
+void sub_80AD800(u8 taskId)
+{
+ struct Task *task = &gTasks[taskId];
+
+ task->data[12] = GetBattlerSide(gBattleAnimAttacker) == B_SIDE_PLAYER ? 1 : -1;
+ task->data[13] = IsBattlerSpriteVisible(gBattleAnimTarget ^ BIT_FLANK) + 1;
+ task->data[14] = GetAnimBattlerSpriteId(ANIM_TARGET);
+ task->data[15] = GetAnimBattlerSpriteId(ANIM_DEF_PARTNER);
+ task->func = sub_80AD870;
+}
+
+static void sub_80AD870(u8 taskId)
+{
+ struct Task *task = &gTasks[taskId];
+
+ switch (task->data[0])
+ {
+ case 0:
+ task->data[10] += task->data[12] * 2;
+ if (++task->data[1] >= 2)
+ {
+ task->data[1] = 0;
+ ++task->data[2];
+ if (task->data[2] & 1)
+ task->data[11] = 2;
+ else
+ task->data[11] = -2;
+ }
+ for (task->data[3] = 0; task->data[3] < task->data[13]; task->data[3]++)
+ gSprites[task->data[task->data[3] + 14]].pos2.x = task->data[10] + task->data[11];
+ if (++task->data[9] == 16)
+ {
+ task->data[9] = 0;
+ ++task->data[0];
+ }
+ break;
+ case 1:
+ if (++task->data[1] >= 5)
+ {
+ task->data[1] = 0;
+ ++task->data[2];
+ if (task->data[2] & 1)
+ task->data[11] = 2;
+ else
+ task->data[11] = -2;
+ }
+ for (task->data[3] = 0; task->data[3] < task->data[13]; task->data[3]++)
+ gSprites[task->data[task->data[3] + 14]].pos2.x = task->data[10] + task->data[11];
+ if (++task->data[9] == 96)
+ {
+ task->data[9] = 0;
+ ++task->data[0];
+ }
+ break;
+ case 2:
+ task->data[10] -= task->data[12] * 2;
+ if (++task->data[1] >= 2)
+ {
+ task->data[1] = 0;
+ ++task->data[2];
+ if (task->data[2] & 1)
+ task->data[11] = 2;
+ else
+ task->data[11] = -2;
+ }
+ for (task->data[3] = 0; task->data[3] < task->data[13]; task->data[3]++)
+ gSprites[task->data[task->data[3] + 14]].pos2.x = task->data[10] + task->data[11];
+ if (++task->data[9] == 16)
+ ++task->data[0];
+ break;
+ case 3:
+ for (task->data[3] = 0; task->data[3] < task->data[13]; task->data[3]++)
+ gSprites[task->data[task->data[3] + 14]].pos2.x = 0;
+ DestroyAnimVisualTask(taskId);
+ break;
+ }
+}
+
+// Used to add a color mask to the battle interface / HUD in Heat Wave.
+// arg 0: opacity
+// arg 1: color code
+void AnimTask_BlendBackground(u8 taskId)
+{
+ struct BattleAnimBgData animBg;
+
+ sub_80752A0(&animBg);
+ BlendPalette(animBg.paletteId * 16, 16, gBattleAnimArgs[0], gBattleAnimArgs[1]);
+ DestroyAnimVisualTask(taskId);
+}
+
+void sub_80ADAD8(u8 taskId)
+{
+ s8 unk;
+ u8 spriteId;
+
+ if (gTasks[taskId].data[0] == 0)
+ {
+ gTasks[taskId].data[1] = gBattleAnimArgs[0];
+ gTasks[taskId].data[2] = gBattleAnimArgs[1];
+ gTasks[taskId].data[3] = gBattleAnimArgs[2];
+ gTasks[taskId].data[4] = gBattleAnimArgs[3];
+ }
+ ++gTasks[taskId].data[0];
+ spriteId = gBattlerSpriteIds[gBattleAnimTarget];
+ if (!gTasks[taskId].data[4])
+ unk = gUnknown_83E5EFC[gTasks[taskId].data[0] % 10];
+ else
+ unk = gUnknown_83E5F0C[gTasks[taskId].data[0] % 10];
+ if (gTasks[taskId].data[3] == 1)
+ gSprites[spriteId].pos2.y = gBattleAnimArgs[1] * unk < 0 ? -(gBattleAnimArgs[1] * unk) : gBattleAnimArgs[1] * unk;
+ else
+ gSprites[spriteId].pos2.x = gBattleAnimArgs[1] * unk;
+ if (gTasks[taskId].data[0] == gTasks[taskId].data[1])
+ {
+ gSprites[spriteId].pos2.x = 0;
+ gSprites[spriteId].pos2.y = 0;
+ DestroyAnimVisualTask(taskId);
+ }
+}
diff --git a/src/flying.c b/src/flying.c
index 8c3ccb52a..59378c2f1 100644
--- a/src/flying.c
+++ b/src/flying.c
@@ -98,8 +98,8 @@ static const union AffineAnimCmd gUnknown_83E6B64[] =
{
AFFINEANIMCMD_FRAME(0x10, 0x100, 0, 0),
AFFINEANIMCMD_FRAME(0x28, 0x0, 0, 6),
- AFFINEANIMCMD_FRAME(0x0, 0xFFE0, 0, 5),
- AFFINEANIMCMD_FRAME(0xFFF0, 0x20, 0, 10),
+ AFFINEANIMCMD_FRAME(0x0, -0x20, 0, 5),
+ AFFINEANIMCMD_FRAME(-0x10, 0x20, 0, 10),
AFFINEANIMCMD_END,
};
@@ -232,9 +232,9 @@ static const union AffineAnimCmd gUnknown_83E6C9C[] =
{
AFFINEANIMCMD_FRAME(0x10, 0x100, 0, 0),
AFFINEANIMCMD_FRAME(0x28, 0x0, 0, 6),
- AFFINEANIMCMD_FRAME(0x0, 0xFFE0, 0, 5),
- AFFINEANIMCMD_FRAME(0xFFEC, 0x0, 0, 7),
- AFFINEANIMCMD_FRAME(0xFFEC, 0xFFEC, 0, 5),
+ AFFINEANIMCMD_FRAME(0x0, -0x20, 0, 5),
+ AFFINEANIMCMD_FRAME(-0x14, 0x0, 0, 7),
+ AFFINEANIMCMD_FRAME(-0x14, -0x14, 0, 5),
AFFINEANIMCMD_END,
};
@@ -280,8 +280,8 @@ static const union AffineAnimCmd gUnknown_83E6D14[] =
{
AFFINEANIMCMD_FRAME(0x10, 0x100, 0, 0),
AFFINEANIMCMD_FRAME(0x28, 0x0, 0, 6),
- AFFINEANIMCMD_FRAME(0x0, 0xFFE0, 0, 5),
- AFFINEANIMCMD_FRAME(0xFFF0, 0x20, 0, 10),
+ AFFINEANIMCMD_FRAME(0x0, -0x20, 0, 5),
+ AFFINEANIMCMD_FRAME(-0x10, 0x20, 0, 10),
AFFINEANIMCMD_END,
};
@@ -306,7 +306,7 @@ static const union AffineAnimCmd gUnknown_83E6D58[] =
{
AFFINEANIMCMD_FRAME(0x100, 0x0, 0, 0),
AFFINEANIMCMD_FRAME(0x0, 0x20, 0, 12),
- AFFINEANIMCMD_FRAME(0x0, 0xFFE0, 0, 11),
+ AFFINEANIMCMD_FRAME(0x0, -0x20, 0, 11),
AFFINEANIMCMD_END,
};
@@ -995,8 +995,8 @@ static void sub_80B2780(struct Sprite *sprite)
InitSpritePosToAnimAttacker(sprite, 0);
else
InitSpritePosToAnimTarget(sprite, FALSE);
- if ((!gBattleAnimArgs[2] && !GetBattlerSide(gBattleAnimAttacker))
- || (gBattleAnimArgs[2] == 1 && !GetBattlerSide(gBattleAnimTarget)))
+ if ((!gBattleAnimArgs[2] && GetBattlerSide(gBattleAnimAttacker) == B_SIDE_PLAYER)
+ || (gBattleAnimArgs[2] == 1 && GetBattlerSide(gBattleAnimTarget) == B_SIDE_PLAYER))
sprite->pos1.x += 8;
SeekSpriteAnim(sprite, gBattleAnimArgs[4]);
sprite->pos1.x -= 32;
@@ -1048,7 +1048,7 @@ static void sub_80B2914(struct Sprite *sprite)
{
case 0:
InitSpritePosToAnimAttacker(sprite, 1);
- gSprites[GetAnimBattlerSpriteId(0)].invisible = TRUE;
+ gSprites[GetAnimBattlerSpriteId(ANIM_ATTACKER)].invisible = TRUE;
++sprite->data[0];
break;
case 1:
@@ -1076,7 +1076,7 @@ static void sub_80B2974(struct Sprite *sprite)
sprite->pos2.y -= 10;
if (sprite->pos1.y + sprite->pos2.y < -32)
{
- gSprites[GetAnimBattlerSpriteId(0)].invisible = FALSE;
+ gSprites[GetAnimBattlerSpriteId(ANIM_ATTACKER)].invisible = FALSE;
DestroyAnimSprite(sprite);
}
break;
@@ -1089,7 +1089,7 @@ static void sub_80B2A08(struct Sprite *sprite)
sprite->data[0] = gBattleAnimArgs[2];
sprite->data[1] = gBattleAnimArgs[3];
sprite->callback = sub_80B2A50;
- gSprites[GetAnimBattlerSpriteId(0)].invisible = TRUE;
+ gSprites[GetAnimBattlerSpriteId(ANIM_ATTACKER)].invisible = TRUE;
}
static void sub_80B2A50(struct Sprite *sprite)
@@ -1275,13 +1275,13 @@ static void sub_80B2E64(u8 taskId)
{
if (gBattleAnimArgs[0] == 0)
{
- u8 spriteId = GetAnimBattlerSpriteId(0);
+ u8 spriteId = GetAnimBattlerSpriteId(ANIM_ATTACKER);
gSprites[spriteId].invisible = TRUE;
}
else
{
- u8 spriteId = GetAnimBattlerSpriteId(0);
+ u8 spriteId = GetAnimBattlerSpriteId(ANIM_ATTACKER);
gSprites[spriteId].invisible = FALSE;
}
diff --git a/src/ghost.c b/src/ghost.c
index fbf452af6..30430309e 100644
--- a/src/ghost.c
+++ b/src/ghost.c
@@ -50,7 +50,7 @@ static void sub_80B71B0(struct Sprite *sprite);
static const union AffineAnimCmd gUnknown_83E75A8[] =
{
AFFINEANIMCMD_FRAME(0x1E, 0x1E, 10, 5),
- AFFINEANIMCMD_FRAME(0xFFE2, 0xFFE2, 10, 5),
+ AFFINEANIMCMD_FRAME(-0x1E, -0x1E, 10, 5),
AFFINEANIMCMD_JUMP(0),
};
@@ -342,7 +342,7 @@ void sub_80B54E8(u8 taskId)
SetGpuReg(REG_OFFSET_BLDCNT, (BLDCNT_EFFECT_BLEND | BLDCNT_TGT2_ALL));
SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(0, 0x10));
- spriteId = GetAnimBattlerSpriteId(0);
+ spriteId = GetAnimBattlerSpriteId(ANIM_ATTACKER);
PrepareBattlerSpriteForRotScale(spriteId, ST_OAM_OBJ_BLEND);
SetSpriteRotScale(spriteId, 128, 128, 0);
gSprites[spriteId].invisible = FALSE;
@@ -377,7 +377,7 @@ static void sub_80B55C8(u8 taskId)
gTasks[taskId].data[1] -= 1;
return;
}
- spriteId = GetAnimBattlerSpriteId(0);
+ spriteId = GetAnimBattlerSpriteId(ANIM_ATTACKER);
gTasks[taskId].data[0] += 8;
if (gTasks[taskId].data[0] <= 0xFF)
{
@@ -626,7 +626,7 @@ static void sub_80B5AD4(u8 taskId)
task->data[1] = 0;
task->data[2] = 0;
task->data[3] = 16;
- task->data[13] = GetAnimBattlerSpriteId(1);
+ task->data[13] = GetAnimBattlerSpriteId(ANIM_TARGET);
task->data[4] = (gSprites[task->data[13]].oam.paletteNum + 16) * 16;
if (position == 1)
{
@@ -711,7 +711,7 @@ static void sub_80B5DCC(u8 taskId)
{
case 0:
gScanlineEffect.state = 3;
- task->data[14] = GetAnimBattlerSpriteId(1);
+ task->data[14] = GetAnimBattlerSpriteId(ANIM_TARGET);
if (rank == 1)
ClearGpuRegBits(REG_OFFSET_DISPCNT, DISPCNT_BG1_ON);
else
@@ -1288,7 +1288,7 @@ static void sub_80B6BE4(u8 taskId)
task->data[1] = 0;
task->data[2] = 0;
task->data[3] = 16;
- task->data[4] = GetAnimBattlerSpriteId(0);
+ task->data[4] = GetAnimBattlerSpriteId(ANIM_ATTACKER);
task->data[5] = gSprites[task->data[4]].oam.priority;
task->data[6] = (gSprites[task->data[4]].oam.paletteNum + 16) << 4;
gSprites[task->data[4]].oam.objMode = ST_OAM_OBJ_BLEND;
diff --git a/src/ground.c b/src/ground.c
index 97f42e5c5..7ab6b6e95 100644
--- a/src/ground.c
+++ b/src/ground.c
@@ -298,7 +298,7 @@ static void sub_80B8ED4(u8 taskId)
switch (task->data[0])
{
case 0:
- task->data[10] = GetAnimBattlerSpriteId(0);
+ task->data[10] = GetAnimBattlerSpriteId(ANIM_ATTACKER);
task->data[11] = GetBattlerSpriteBGPriorityRank(gBattleAnimAttacker);
if (task->data[11] == 1)
{
@@ -360,7 +360,7 @@ static void sub_80B8ED4(u8 taskId)
static void sub_80B908C(u8 taskId)
{
- u8 spriteId = GetAnimBattlerSpriteId(0);
+ u8 spriteId = GetAnimBattlerSpriteId(ANIM_ATTACKER);
gSprites[spriteId].invisible = TRUE;
gSprites[spriteId].pos2.x = 0;
@@ -391,7 +391,7 @@ static void sub_80B912C(u8 taskId)
switch (task->data[0])
{
case 0:
- task->data[10] = GetAnimBattlerSpriteId(0);
+ task->data[10] = GetAnimBattlerSpriteId(ANIM_ATTACKER);
gSprites[task->data[10]].invisible = FALSE;
gSprites[task->data[10]].pos2.x = 0;
gSprites[task->data[10]].pos2.y = 160 - gSprites[task->data[10]].pos1.y;
@@ -410,7 +410,7 @@ static void sub_80B91B0(u8 taskId)
switch (task->data[0])
{
case 0:
- task->data[10] = GetAnimBattlerSpriteId(0);
+ task->data[10] = GetAnimBattlerSpriteId(ANIM_ATTACKER);
task->data[11] = GetBattlerSpriteBGPriorityRank(gBattleAnimAttacker);
if (task->data[11] == 1)
task->data[12] = gBattle_BG1_X;
diff --git a/src/ice.c b/src/ice.c
new file mode 100644
index 000000000..9914a6992
--- /dev/null
+++ b/src/ice.c
@@ -0,0 +1,1477 @@
+#include "global.h"
+#include "battle_anim.h"
+#include "bg.h"
+#include "field_weather.h"
+#include "gpu_regs.h"
+#include "graphics.h"
+#include "main.h"
+#include "palette.h"
+#include "random.h"
+#include "sprite.h"
+#include "task.h"
+#include "trig.h"
+#include "constants/battle_anim.h"
+
+struct HailStruct
+{
+ s32 unk0:10;
+ s32 unk1:10;
+ s32 unk2:8;
+ s32 unk3:4;
+};
+
+static void sub_80AF108(struct Sprite *sprite);
+static void sub_80AF28C(struct Sprite *sprite);
+static void AnimIcePunchSwirlingParticle(struct Sprite *sprite);
+static void AnimIceBeamParticle(struct Sprite *sprite);
+static void AnimIceEffectParticle(struct Sprite *sprite);
+static void AnimFlickerIceEffectParticle(struct Sprite *sprite);
+static void AnimSwirlingSnowball_Step1(struct Sprite *sprite);
+static void AnimSwirlingSnowball_Step2(struct Sprite *sprite);
+static void AnimSwirlingSnowball_Step3(struct Sprite *sprite);
+static void AnimSwirlingSnowball_End(struct Sprite *sprite);
+static void AnimMoveParticleBeyondTarget(struct Sprite *sprite);
+static void AnimWiggleParticleTowardsTarget(struct Sprite *sprite);
+static void AnimWaveFromCenterOfTarget(struct Sprite *sprite);
+static void InitSwirlingFogAnim(struct Sprite *sprite);
+static void AnimSwirlingFogAnim(struct Sprite *sprite);
+static void AnimThrowMistBall(struct Sprite *sprite);
+static void InitPoisonGasCloudAnim(struct Sprite *sprite);
+static void MovePoisonGasCloud(struct Sprite *sprite);
+static void AnimHailBegin(struct Sprite *sprite);
+static void AnimHailContinue(struct Sprite *sprite);
+static void InitIceBallAnim(struct Sprite *sprite);
+static void AnimThrowIceBall(struct Sprite *sprite);
+static void InitIceBallParticle(struct Sprite *sprite);
+static void AnimIceBallParticle(struct Sprite *sprite);
+static void AnimTask_Haze2(u8 taskId);
+static void AnimTask_OverlayFogTiles(u8 taskId);
+static void AnimTask_Hail2(u8 taskId);
+static bool8 GenerateHailParticle(u8 hailStructId, u8 affineAnimNum, u8 taskId, u8 c);
+
+static const union AnimCmd gUnknown_83E62C0[] =
+{
+ ANIMCMD_FRAME(0, 5, .hFlip = TRUE),
+ ANIMCMD_FRAME(1, 5, .hFlip = TRUE),
+ ANIMCMD_JUMP(0),
+};
+
+static const union AnimCmd *const gUnknown_83E62CC[] =
+{
+ gUnknown_83E62C0,
+};
+
+// not used
+static const struct SpriteTemplate gUnknown_83E62D0 =
+{
+ .tileTag = ANIM_TAG_ICE_CRYSTALS,
+ .paletteTag = ANIM_TAG_ICE_CRYSTALS,
+ .oam = &gOamData_83AC9C8,
+ .anims = gDummySpriteAnimTable,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = sub_80AF108,
+};
+
+static const union AnimCmd gUnknown_83E62E8[] =
+{
+ ANIMCMD_FRAME(0, 1),
+ ANIMCMD_END,
+};
+
+static const union AnimCmd gUnknown_83E62F0[] =
+{
+ ANIMCMD_FRAME(4, 1),
+ ANIMCMD_END,
+};
+
+static const union AnimCmd gUnknown_83E62F8[] =
+{
+ ANIMCMD_FRAME(6, 1),
+ ANIMCMD_END,
+};
+
+static const union AnimCmd gUnknown_83E6300[] =
+{
+ ANIMCMD_FRAME(7, 1),
+ ANIMCMD_END,
+};
+
+static const union AnimCmd gUnknown_83E6308[] =
+{
+ ANIMCMD_FRAME(8, 1),
+ ANIMCMD_END,
+};
+
+static const union AnimCmd gUnknown_83E6310[] =
+{
+ ANIMCMD_FRAME(12, 6),
+ ANIMCMD_FRAME(13, 6),
+ ANIMCMD_JUMP(0),
+};
+
+static const union AnimCmd *const gUnknown_83E631C[] =
+{
+ gUnknown_83E62E8,
+};
+
+static const union AnimCmd *const gUnknown_83E6320[] =
+{
+ gUnknown_83E62F0,
+};
+
+static const union AnimCmd *const gUnknown_83E6324[] =
+{
+ gUnknown_83E62F8,
+};
+
+static const union AnimCmd *const gUnknown_83E6328[] =
+{
+ gUnknown_83E6300,
+};
+
+static const union AnimCmd *const gUnknown_83E632C[] =
+{
+ gUnknown_83E6308,
+};
+
+static const union AnimCmd *const gUnknown_83E6330[] =
+{
+ gUnknown_83E6310,
+};
+
+static const union AffineAnimCmd gUnknown_83E6334[] =
+{
+ AFFINEANIMCMD_FRAME(0x0, 0x0, 40, 1),
+ AFFINEANIMCMD_JUMP(0),
+};
+
+static const union AffineAnimCmd *const gUnknown_83E6344[] =
+{
+ gUnknown_83E6334,
+};
+
+const struct SpriteTemplate gUnknown_83E6348 =
+{
+ .tileTag = ANIM_TAG_ICE_CRYSTALS,
+ .paletteTag = ANIM_TAG_ICE_CRYSTALS,
+ .oam = &gOamData_83ACBE8,
+ .anims = gUnknown_83E6320,
+ .images = NULL,
+ .affineAnims = gUnknown_83E6344,
+ .callback = AnimIcePunchSwirlingParticle,
+};
+
+const struct SpriteTemplate gUnknown_83E6360 =
+{
+ .tileTag = ANIM_TAG_ICE_CRYSTALS,
+ .paletteTag = ANIM_TAG_ICE_CRYSTALS,
+ .oam = &gOamData_83ACAE8,
+ .anims = gUnknown_83E6324,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = AnimIcePunchSwirlingParticle,
+};
+
+static const union AffineAnimCmd gUnknown_83E6378[] =
+{
+ AFFINEANIMCMD_FRAME(0x0, 0x0, 10, 1),
+ AFFINEANIMCMD_JUMP(0),
+};
+
+static const union AffineAnimCmd *const gUnknown_83E6388[] =
+{
+ gUnknown_83E6378,
+};
+
+const struct SpriteTemplate gUnknown_83E638C =
+{
+ .tileTag = ANIM_TAG_ICE_CRYSTALS,
+ .paletteTag = ANIM_TAG_ICE_CRYSTALS,
+ .oam = &gOamData_83ACB88,
+ .anims = gUnknown_83E6320,
+ .images = NULL,
+ .affineAnims = gUnknown_83E6388,
+ .callback = AnimIceBeamParticle,
+};
+
+const struct SpriteTemplate gUnknown_83E63A4 =
+{
+ .tileTag = ANIM_TAG_ICE_CRYSTALS,
+ .paletteTag = ANIM_TAG_ICE_CRYSTALS,
+ .oam = &gOamData_83ACAE8,
+ .anims = gUnknown_83E6324,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = AnimIceBeamParticle,
+};
+
+static const union AffineAnimCmd gUnknown_83E63BC[] =
+{
+ AFFINEANIMCMD_FRAME(0xCE, 0xCE, 0, 0),
+ AFFINEANIMCMD_FRAME(0x5, 0x5, 0, 10),
+ AFFINEANIMCMD_FRAME(0x0, 0x0, 0, 6),
+ AFFINEANIMCMD_END,
+};
+
+static const union AffineAnimCmd *const gUnknown_83E63DC[] =
+{
+ gUnknown_83E63BC,
+};
+
+const struct SpriteTemplate gUnknown_83E63E0 =
+{
+ .tileTag = ANIM_TAG_ICE_CRYSTALS,
+ .paletteTag = ANIM_TAG_ICE_CRYSTALS,
+ .oam = &gOamData_83ACB88,
+ .anims = gUnknown_83E6320,
+ .images = NULL,
+ .affineAnims = gUnknown_83E63DC,
+ .callback = AnimIceEffectParticle,
+};
+
+const struct SpriteTemplate gUnknown_83E63F8 =
+{
+ .tileTag = ANIM_TAG_ICE_CRYSTALS,
+ .paletteTag = ANIM_TAG_ICE_CRYSTALS,
+ .oam = &gOamData_83ACB48,
+ .anims = gUnknown_83E6324,
+ .images = NULL,
+ .affineAnims = gUnknown_83E63DC,
+ .callback = AnimIceEffectParticle,
+};
+
+const struct SpriteTemplate gUnknown_83E6410 =
+{
+ .tileTag = ANIM_TAG_ICE_CRYSTALS,
+ .paletteTag = ANIM_TAG_ICE_CRYSTALS,
+ .oam = &gOamData_83AC9C8,
+ .anims = gUnknown_83E6328,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = AnimSwirlingSnowball_Step1,
+};
+
+const struct SpriteTemplate gUnknown_83E6428 =
+{
+ .tileTag = ANIM_TAG_ICE_CRYSTALS,
+ .paletteTag = ANIM_TAG_ICE_CRYSTALS,
+ .oam = &gOamData_83AC9D0,
+ .anims = gUnknown_83E632C,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = AnimMoveParticleBeyondTarget,
+};
+
+const struct SpriteTemplate gUnknown_83E6440 =
+{
+ .tileTag = ANIM_TAG_ICE_CRYSTALS,
+ .paletteTag = ANIM_TAG_ICE_CRYSTALS,
+ .oam = &gOamData_83AC9C8,
+ .anims = gUnknown_83E6328,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = AnimMoveParticleBeyondTarget,
+};
+
+static const union AnimCmd gUnknown_83E6458[] =
+{
+ ANIMCMD_FRAME(0, 5),
+ ANIMCMD_FRAME(2, 5),
+ ANIMCMD_FRAME(4, 5),
+ ANIMCMD_FRAME(6, 5),
+ ANIMCMD_FRAME(4, 5),
+ ANIMCMD_FRAME(2, 5),
+ ANIMCMD_FRAME(0, 5),
+ ANIMCMD_END,
+};
+
+static const union AnimCmd *const gUnknown_83E6478[] =
+{
+ gUnknown_83E6458,
+};
+
+const struct SpriteTemplate gUnknown_83E647C =
+{
+ .tileTag = ANIM_TAG_ICE_SPIKES,
+ .paletteTag = ANIM_TAG_ICE_SPIKES,
+ .oam = &gOamData_83ACB28,
+ .anims = gUnknown_83E6478,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = AnimWaveFromCenterOfTarget,
+};
+
+static const union AnimCmd gUnknown_83E6494[] =
+{
+ ANIMCMD_FRAME(0, 8),
+ ANIMCMD_FRAME(8, 8),
+ ANIMCMD_JUMP(0),
+};
+
+static const union AnimCmd *const gUnknown_83E64A0[] =
+{
+ gUnknown_83E6494,
+};
+
+const struct SpriteTemplate gUnknown_83E64A4 =
+{
+ .tileTag = ANIM_TAG_MIST_CLOUD,
+ .paletteTag = ANIM_TAG_MIST_CLOUD,
+ .oam = &gOamData_83ACB18,
+ .anims = gUnknown_83E64A0,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = InitSwirlingFogAnim,
+};
+
+const struct SpriteTemplate gUnknown_83E64BC =
+{
+ .tileTag = ANIM_TAG_PURPLE_GAS_CLOUD,
+ .paletteTag = ANIM_TAG_PURPLE_GAS_CLOUD,
+ .oam = &gOamData_83ACB18,
+ .anims = gUnknown_83E64A0,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = InitSwirlingFogAnim,
+};
+
+static const u8 gUnknown_83E64D4[] =
+{
+ 0, 1, 2, 2, 2, 2, 3, 4, 4, 4, 5, 6, 6, 6, 6, 7, 8, 8, 8, 9,
+};
+
+const struct SpriteTemplate gUnknown_83E64E8 =
+{
+ .tileTag = ANIM_TAG_SMALL_BUBBLES,
+ .paletteTag = ANIM_TAG_SMALL_BUBBLES,
+ .oam = &gOamData_83AC9D0,
+ .anims = gDummySpriteAnimTable,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = AnimThrowMistBall,
+};
+
+static const u8 gUnknown_83E6500[] =
+{
+ 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5,
+};
+
+const struct SpriteTemplate gUnknown_83E6514 =
+{
+ .tileTag = ANIM_TAG_PURPLE_GAS_CLOUD,
+ .paletteTag = ANIM_TAG_PURPLE_GAS_CLOUD,
+ .oam = &gOamData_83ACB18,
+ .anims = gUnknown_83E64A0,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = InitPoisonGasCloudAnim,
+};
+
+static const struct HailStruct gUnknown_83E652C[] =
+{
+ {100, 120, 0, 2},
+ {85, 120, 0, 0},
+ {242, 120, 1, 1},
+ {66, 120, 2, 1},
+ {182, 120, 3, 0},
+ {60, 120, 0, 2},
+ {214, 120, 1, 0},
+ {113, 120, 0, 1},
+ {210, 120, 3, 1},
+ {38, 120, 2, 0},
+};
+
+static const union AffineAnimCmd gUnknown_83E6554[] =
+{
+ AFFINEANIMCMD_FRAME(0x100, 0x100, 0, 0),
+ AFFINEANIMCMD_END,
+};
+
+static const union AffineAnimCmd gUnknown_83E6564[] =
+{
+ AFFINEANIMCMD_FRAME(0xF0, 0xF0, 0, 0),
+ AFFINEANIMCMD_END,
+};
+
+static const union AffineAnimCmd gUnknown_83E6574[] =
+{
+ AFFINEANIMCMD_FRAME(0xE0, 0xE0, 0, 0),
+ AFFINEANIMCMD_END,
+};
+
+static const union AffineAnimCmd gUnknown_83E6584[] =
+{
+ AFFINEANIMCMD_FRAME(0x150, 0x150, 0, 0),
+ AFFINEANIMCMD_END,
+};
+
+static const union AffineAnimCmd *const gUnknown_83E6594[] =
+{
+ gUnknown_83E6554,
+ gUnknown_83E6564,
+ gUnknown_83E6574,
+};
+
+static const union AffineAnimCmd *const gUnknown_83E65A0[] =
+{
+ gUnknown_83E6584,
+};
+
+static const struct SpriteTemplate gUnknown_83E65A4 =
+{
+ .tileTag = ANIM_TAG_HAIL,
+ .paletteTag = ANIM_TAG_HAIL,
+ .oam = &gOamData_83ACA30,
+ .anims = gDummySpriteAnimTable,
+ .images = NULL,
+ .affineAnims = gUnknown_83E6594,
+ .callback = AnimHailBegin,
+};
+
+const struct SpriteTemplate gUnknown_83E65BC =
+{
+ .tileTag = ANIM_TAG_HAIL,
+ .paletteTag = ANIM_TAG_HAIL,
+ .oam = &gOamData_83ACA30,
+ .anims = gDummySpriteAnimTable,
+ .images = NULL,
+ .affineAnims = gUnknown_83E65A0,
+ .callback = sub_8077350,
+};
+
+static const union AnimCmd gUnknown_83E65D4[] =
+{
+ ANIMCMD_FRAME(0, 1),
+ ANIMCMD_END,
+};
+
+static const union AnimCmd gUnknown_83E65DC[] =
+{
+ ANIMCMD_FRAME(16, 4),
+ ANIMCMD_FRAME(32, 4),
+ ANIMCMD_FRAME(48, 4),
+ ANIMCMD_FRAME(64, 4),
+ ANIMCMD_END,
+};
+
+static const union AnimCmd *const gUnknown_83E65F0[] =
+{
+ gUnknown_83E65D4,
+ gUnknown_83E65DC,
+};
+
+static const union AffineAnimCmd gUnknown_83E65F8[] =
+{
+ AFFINEANIMCMD_FRAME(0xE0, 0xE0, 0, 0),
+ AFFINEANIMCMD_END,
+};
+
+static const union AffineAnimCmd gUnknown_83E6608[] =
+{
+ AFFINEANIMCMD_FRAME(0x118, 0x118, 0, 0),
+ AFFINEANIMCMD_END,
+};
+
+static const union AffineAnimCmd gUnknown_83E6618[] =
+{
+ AFFINEANIMCMD_FRAME(0x150, 0x150, 0, 0),
+ AFFINEANIMCMD_END,
+};
+
+static const union AffineAnimCmd gUnknown_83E6628[] =
+{
+ AFFINEANIMCMD_FRAME(0x180, 0x180, 0, 0),
+ AFFINEANIMCMD_END,
+};
+
+static const union AffineAnimCmd gUnknown_83E6638[] =
+{
+ AFFINEANIMCMD_FRAME(0x1C0, 0x1C0, 0, 0),
+ AFFINEANIMCMD_END,
+};
+
+static const union AffineAnimCmd *const gUnknown_83E6648[] =
+{
+ gUnknown_83E65F8,
+ gUnknown_83E6608,
+ gUnknown_83E6618,
+ gUnknown_83E6628,
+ gUnknown_83E6638,
+};
+
+const struct SpriteTemplate gUnknown_83E665C =
+{
+ .tileTag = ANIM_TAG_ICE_CHUNK,
+ .paletteTag = ANIM_TAG_ICE_CHUNK,
+ .oam = &gOamData_83ACA98,
+ .anims = gUnknown_83E65F0,
+ .images = NULL,
+ .affineAnims = gUnknown_83E6648,
+ .callback = InitIceBallAnim,
+};
+
+const struct SpriteTemplate gUnknown_83E6674 =
+{
+ .tileTag = ANIM_TAG_ICE_CRYSTALS,
+ .paletteTag = ANIM_TAG_ICE_CRYSTALS,
+ .oam = &gOamData_83AC9C8,
+ .anims = gUnknown_83E6324,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = InitIceBallParticle,
+};
+
+// not used
+static void sub_80AF108(struct Sprite *sprite)
+{
+ s16 targetX, targetY, attackerX, attackerY;
+
+ sprite->oam.tileNum += 7;
+ targetX = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X_2);
+ targetY = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y_PIC_OFFSET);
+ attackerX = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X_2);
+ attackerY = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y_PIC_OFFSET);
+ sprite->data[0] = gBattleAnimArgs[4];
+ sprite->data[1] = gBattleAnimArgs[0] + attackerX;
+ sprite->data[2] = gBattleAnimArgs[2] + targetX;
+ sprite->data[3] = gBattleAnimArgs[1] + attackerY;
+ sprite->data[4] = gBattleAnimArgs[3] + targetY;
+ sub_8074C80(sprite);
+ // won't match with while loop
+ for (; (targetX >= -32 && targetX <= 272) && (targetY >= -32 && targetY <= 192); targetX += sprite->data[1], targetY += sprite->data[2])
+ ;
+ sprite->data[1] = -sprite->data[1];
+ sprite->data[2] = -sprite->data[2];
+ for (; (attackerX >= -32 && attackerX <= 272) && (attackerY >= -32 && attackerY <= 192); attackerX += sprite->data[1], attackerY += sprite->data[2])
+ ;
+ sprite->pos1.x = attackerX;
+ sprite->pos1.y = attackerY;
+ sprite->data[0] = gBattleAnimArgs[4];
+ sprite->data[1] = attackerX;
+ sprite->data[2] = targetX;
+ sprite->data[3] = attackerY;
+ sprite->data[4] = targetY;
+ sub_8074C80(sprite);
+ sprite->data[3] = gBattleAnimArgs[5];
+ sprite->data[4] = gBattleAnimArgs[6];
+ sprite->callback = sub_80AF28C;
+}
+
+// not used
+static void sub_80AF28C(struct Sprite *sprite)
+{
+ if (sprite->data[0] != 0)
+ {
+ sprite->data[5] += sprite->data[1];
+ sprite->data[6] += sprite->data[2];
+ sprite->pos2.x = sprite->data[5];
+ sprite->pos2.y = sprite->data[6];
+ sprite->pos2.x += Sin(sprite->data[7], sprite->data[3]);
+ sprite->pos2.y += Sin(sprite->data[7], sprite->data[3]);
+ sprite->data[7] = (sprite->data[7] + sprite->data[4]) & 0xFF;
+ --sprite->data[0];
+ }
+ else
+ {
+ DestroyAnimSprite(sprite);
+ }
+}
+
+// Animates the swirling ice crystals in Ice Punch.
+// arg 0: initial position angle around circle (0-256)
+static void AnimIcePunchSwirlingParticle(struct Sprite *sprite)
+{
+ sprite->data[0] = gBattleAnimArgs[0];
+ sprite->data[1] = 60;
+ sprite->data[2] = 9;
+ sprite->data[3] = 30;
+ sprite->data[4] = -512;
+ StoreSpriteCallbackInData6(sprite, DestroyAnimSprite);
+ sprite->callback = TranslateSpriteInGrowingCircleOverDuration;
+ sprite->callback(sprite);
+}
+
+// Animates the ice particles in Ice Beam.
+// arg 0: initial x pixel offset
+// arg 1: initial y pixel offset
+// arg 2: target x offset
+// arg 3: target y offset
+// arg 4: duration
+static void AnimIceBeamParticle(struct Sprite *sprite)
+{
+ InitSpritePosToAnimAttacker(sprite, TRUE);
+ sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X_2);
+ if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER)
+ sprite->data[2] -= gBattleAnimArgs[2];
+ else
+ sprite->data[2] += gBattleAnimArgs[2];
+ sprite->data[4] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y_PIC_OFFSET) + gBattleAnimArgs[3];
+ sprite->data[0] = gBattleAnimArgs[4];
+ StoreSpriteCallbackInData6(sprite, DestroyAnimSprite);
+ sprite->callback = StartAnimLinearTranslation;
+}
+
+// Animates the ice crystals at the end of Ice Punch, Ice Beam, Tri Attack,
+// Weather Ball (Hail), Blizzard, and Powder Snow.
+// arg 0: target x offset
+// arg 1: target y offset
+// arg 2: ??? unknown boolean
+static void AnimIceEffectParticle(struct Sprite *sprite)
+{
+ if (gBattleAnimArgs[2] == 0)
+ {
+ InitSpritePosToAnimTarget(sprite, TRUE);
+ }
+ else
+ {
+ SetAverageBattlerPositions(gBattleAnimTarget, 1, &sprite->pos1.x, &sprite->pos1.y);
+ if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER)
+ gBattleAnimArgs[0] = -gBattleAnimArgs[0];
+ sprite->pos1.x += gBattleAnimArgs[0];
+ sprite->pos1.y += gBattleAnimArgs[1];
+ }
+ StoreSpriteCallbackInData6(sprite, AnimFlickerIceEffectParticle);
+ sprite->callback = RunStoredCallbackWhenAffineAnimEnds;
+}
+
+static void AnimFlickerIceEffectParticle(struct Sprite *sprite)
+{
+ sprite->invisible ^= 1;
+ if (++sprite->data[0] == 20)
+ DestroySpriteAndMatrix(sprite);
+}
+
+// Animates the small snowballs that swirl around the target in Blizzard and Icy Wind.
+// arg 0: initial x pixel offset
+// arg 1: initial y pixel offset
+// arg 2: target x offset
+// arg 3: target y offset
+// arg 4: particle speed
+// arg 5: multiple targets? (boolean)
+static void AnimSwirlingSnowball_Step1(struct Sprite *sprite)
+{
+ s32 i;
+ s16 tempDataHolder[8];
+
+ InitSpritePosToAnimAttacker(sprite, TRUE);
+ sprite->data[0] = gBattleAnimArgs[4];
+ sprite->data[1] = sprite->pos1.x;
+ sprite->data[3] = sprite->pos1.y;
+ if (!gBattleAnimArgs[5])
+ {
+ sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X_2);
+ sprite->data[4] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y_PIC_OFFSET) + gBattleAnimArgs[3];
+ }
+ else
+ {
+ SetAverageBattlerPositions(gBattleAnimTarget, 1, &sprite->data[2], &sprite->data[4]);
+ }
+ if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER)
+ sprite->data[2] -= gBattleAnimArgs[2];
+ else
+ sprite->data[2] += gBattleAnimArgs[2];
+ for (i = 0; i < 8; ++i)
+ tempDataHolder[i] = sprite->data[i];
+ InitAnimFastLinearTranslationWithSpeed(sprite);
+ sprite->data[1] ^= 1;
+ sprite->data[2] ^= 1;
+ while (1)
+ {
+ sprite->data[0] = 1;
+ AnimFastTranslateLinear(sprite);
+ if ((u32)(sprite->pos1.x + sprite->pos2.x + 16) > 272
+ || sprite->pos1.y + sprite->pos2.y > 160
+ || sprite->pos1.y + sprite->pos2.y < -16)
+ break;
+ }
+ sprite->pos1.x += sprite->pos2.x;
+ sprite->pos1.y += sprite->pos2.y;
+ sprite->pos2.x = sprite->pos2.y = 0;
+ for (i = 0; i < 8; ++i)
+ sprite->data[i] = tempDataHolder[i];
+ sprite->callback = sub_8075830;
+ StoreSpriteCallbackInData6(sprite, AnimSwirlingSnowball_Step2);
+}
+
+static void AnimSwirlingSnowball_Step2(struct Sprite *sprite)
+{
+ s16 tempVar;
+
+ sprite->pos1.x += sprite->pos2.x;
+ sprite->pos1.y += sprite->pos2.y;
+ sprite->pos2.y = 0;
+ sprite->pos2.x = 0;
+ sprite->data[0] = 128;
+ tempVar = GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER ? 20 : -20;
+ sprite->data[3] = Sin(sprite->data[0], tempVar);
+ sprite->data[4] = Cos(sprite->data[0], 0xF);
+ sprite->data[5] = 0;
+ sprite->callback = AnimSwirlingSnowball_Step3;
+ sprite->callback(sprite);
+}
+
+static void AnimSwirlingSnowball_Step3(struct Sprite *sprite)
+{
+ s16 tempVar = GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER ? 20 : -20;
+
+ if (sprite->data[5] <= 31)
+ {
+ sprite->pos2.x = Sin(sprite->data[0], tempVar) - sprite->data[3];
+ sprite->pos2.y = Cos(sprite->data[0], 15) - sprite->data[4];
+ sprite->data[0] = (sprite->data[0] + 16) & 0xFF;
+ sprite->data[5] += 1;
+ }
+ else
+ {
+ sprite->pos1.x += sprite->pos2.x;
+ sprite->pos1.y += sprite->pos2.y;
+ sprite->pos2.x = sprite->pos2.y = 0;
+ sprite->data[3] = sprite->data[4] = 0;
+ sprite->callback = AnimSwirlingSnowball_End;
+ }
+}
+
+static void AnimSwirlingSnowball_End(struct Sprite *sprite)
+{
+ sprite->data[0] = 1;
+ AnimFastTranslateLinear(sprite);
+ if ((u32)(sprite->pos1.x + sprite->pos2.x + 16) > 272
+ || sprite->pos1.y + sprite->pos2.y > 256
+ || sprite->pos1.y + sprite->pos2.y < -16)
+ DestroyAnimSprite(sprite);
+}
+
+// Moves particles towards the target mon and off the screen. Used to animate
+// the large snowballs in Blizzard and the small snowballs in Powder Snow.
+// arg 0: initial x pixel offset
+// arg 1: initial y pixel offset
+// arg 2: target x offset
+// arg 3: target y offset
+// arg 4: speed
+// arg 5: wave amplitude
+// arg 6: wave frequency
+// arg 7: multiple targets? (boolean)
+static void AnimMoveParticleBeyondTarget(struct Sprite *sprite)
+{
+ s32 i;
+ s16 tempDataHolder[8];
+
+ InitSpritePosToAnimAttacker(sprite, TRUE);
+ sprite->data[0] = gBattleAnimArgs[4];
+ sprite->data[1] = sprite->pos1.x;
+ sprite->data[3] = sprite->pos1.y;
+ if (!gBattleAnimArgs[7])
+ {
+ sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X_2);
+ sprite->data[4] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y_PIC_OFFSET);
+ }
+ else
+ {
+ SetAverageBattlerPositions(gBattleAnimTarget, 1, &sprite->data[2], &sprite->data[4]);
+ }
+ if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER)
+ sprite->data[2] -= gBattleAnimArgs[2];
+ else
+ sprite->data[2] += gBattleAnimArgs[2];
+ sprite->data[4] += gBattleAnimArgs[3];
+ InitAnimFastLinearTranslationWithSpeed(sprite);
+ for (i = 0; i < 8; ++i)
+ tempDataHolder[i] = sprite->data[i];
+ sprite->data[1] ^= 1;
+ sprite->data[2] ^= 1;
+ while (1)
+ {
+ sprite->data[0] = 1;
+ AnimFastTranslateLinear(sprite);
+ if ((u32)(sprite->pos1.x + sprite->pos2.x + 16) > 272
+ || sprite->pos1.y + sprite->pos2.y > 160
+ || sprite->pos1.y + sprite->pos2.y < -16)
+ break;
+ }
+ sprite->pos1.x += sprite->pos2.x;
+ sprite->pos1.y += sprite->pos2.y;
+ sprite->pos2.y = 0;
+ sprite->pos2.x = 0;
+ for (i = 0; i < 8; ++i)
+ sprite->data[i] = tempDataHolder[i];
+ sprite->data[5] = gBattleAnimArgs[5];
+ sprite->data[6] = gBattleAnimArgs[6];
+ sprite->callback = AnimWiggleParticleTowardsTarget;
+}
+
+// Moves particles in a sine wave towards the target.
+static void AnimWiggleParticleTowardsTarget(struct Sprite *sprite)
+{
+ AnimFastTranslateLinear(sprite);
+ if (sprite->data[0] == 0)
+ sprite->data[0] = 1;
+ sprite->pos2.y += Sin(sprite->data[7], sprite->data[5]);
+ sprite->data[7] = (sprite->data[7] + sprite->data[6]) & 0xFF;
+ if (sprite->data[0] == 1)
+ {
+ if ((u32)(sprite->pos1.x + sprite->pos2.x + 16) > 272
+ || sprite->pos1.y + sprite->pos2.y > 160
+ || sprite->pos1.y + sprite->pos2.y < -16)
+ DestroyAnimSprite(sprite);
+ }
+}
+
+// Animates the ice pilar wave used by Icy Wind.
+// arg 0: initial x pixel offset
+// arg 1: initial y pixel offset
+// arg 2: ??? unknown boolean
+static void AnimWaveFromCenterOfTarget(struct Sprite *sprite)
+{
+ if (sprite->data[0] == 0)
+ {
+ if (gBattleAnimArgs[2] == 0)
+ {
+ InitSpritePosToAnimTarget(sprite, FALSE);
+ }
+ else
+ {
+ SetAverageBattlerPositions(gBattleAnimTarget, 0, &sprite->pos1.x, &sprite->pos1.y);
+ if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER)
+ gBattleAnimArgs[0] = -gBattleAnimArgs[0];
+ sprite->pos1.x += gBattleAnimArgs[0];
+ sprite->pos1.y += gBattleAnimArgs[1];
+ }
+ ++sprite->data[0];
+ }
+ else
+ {
+ if (sprite->animEnded)
+ DestroyAnimSprite(sprite);
+ }
+}
+
+// Animates the fog that swirls around the mon in Mist and Smog.
+// arg 0: initial x pixel offset
+// arg 1: initial y pixel offset
+// arg 2: change in y pixels per rotation
+// arg 3: duration
+// arg 4: animate on opponent? (boolean)
+// arg 5: ??? unknown boolean
+static void InitSwirlingFogAnim(struct Sprite *sprite)
+{
+ s16 tempVar;
+ u8 battler;
+
+ if (gBattleAnimArgs[4] == 0)
+ {
+ if (gBattleAnimArgs[5] == 0)
+ {
+ InitSpritePosToAnimAttacker(sprite, FALSE);
+ }
+ else
+ {
+ SetAverageBattlerPositions(gBattleAnimAttacker, 0, &sprite->pos1.x, &sprite->pos1.y);
+ if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER)
+ sprite->pos1.x -= gBattleAnimArgs[0];
+ else
+ sprite->pos1.x += gBattleAnimArgs[0];
+ sprite->pos1.y += gBattleAnimArgs[1];
+ }
+ battler = gBattleAnimAttacker;
+ }
+ else
+ {
+ if (gBattleAnimArgs[5] == 0)
+ {
+ InitSpritePosToAnimTarget(sprite, FALSE);
+ }
+ else
+ {
+ SetAverageBattlerPositions(gBattleAnimTarget, 0, &sprite->pos1.x, &sprite->pos1.y);
+ if (GetBattlerSide(gBattleAnimTarget) != B_SIDE_PLAYER)
+ sprite->pos1.x -= gBattleAnimArgs[0];
+ else
+ sprite->pos1.x += gBattleAnimArgs[0];
+ sprite->pos1.y += gBattleAnimArgs[1];
+ }
+ battler = gBattleAnimTarget;
+ }
+ sprite->data[7] = battler;
+ if (gBattleAnimArgs[5] == 0 || !IsDoubleBattle())
+ tempVar = 0x20;
+ else
+ tempVar = 0x40;
+ sprite->data[6] = tempVar;
+ if (GetBattlerSide(gBattleAnimTarget) == B_SIDE_PLAYER)
+ sprite->pos1.y += 8;
+ sprite->data[0] = gBattleAnimArgs[3];
+ sprite->data[1] = sprite->pos1.x;
+ sprite->data[2] = sprite->pos1.x;
+ sprite->data[3] = sprite->pos1.y;
+ sprite->data[4] = sprite->pos1.y + gBattleAnimArgs[2];
+ InitAnimLinearTranslation(sprite);
+ sprite->data[5] = 64;
+ sprite->callback = AnimSwirlingFogAnim;
+ sprite->callback(sprite);
+}
+
+// Animates swirling fog initialized by InitSwirlingFogAnim.
+static void AnimSwirlingFogAnim(struct Sprite *sprite)
+{
+ if (!AnimTranslateLinear(sprite))
+ {
+ sprite->pos2.x += Sin(sprite->data[5], sprite->data[6]);
+ sprite->pos2.y += Cos(sprite->data[5], -6);
+ if ((u16)(sprite->data[5] - 64) <= 0x7F)
+ sprite->oam.priority = GetBattlerSpriteBGPriority(sprite->data[7]);
+ else
+ sprite->oam.priority = GetBattlerSpriteBGPriority(sprite->data[7]) + 1;
+ sprite->data[5] = (sprite->data[5] + 3) & 0xFF;
+ }
+ else
+ {
+ DestroyAnimSprite(sprite);
+ }
+}
+
+// Fades mons to black and places foggy overlay in Haze.
+void AnimTask_Haze1(u8 taskId)
+{
+ struct BattleAnimBgData animBg;
+
+ SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT1_BG1 | BLDCNT_EFFECT_BLEND | BLDCNT_TGT2_ALL);
+ SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(0, 16));
+ SetAnimBgAttribute(1, BG_ANIM_PRIORITY, 1);
+ SetAnimBgAttribute(1, BG_ANIM_SCREEN_SIZE, 0);
+ if (!IsContest())
+ SetAnimBgAttribute(1, BG_ANIM_CHAR_BASE_BLOCK, 1);
+ gBattle_BG1_X = 0;
+ gBattle_BG1_Y = 0;
+ SetGpuReg(REG_OFFSET_BG1HOFS, gBattle_BG1_X);
+ SetGpuReg(REG_OFFSET_BG1VOFS, gBattle_BG1_Y);
+ sub_80752A0(&animBg);
+ LoadBgTiles(animBg.bgId, gWeatherFog1Tiles, 0x800, animBg.tilesOffset);
+ AnimLoadCompressedBgTilemap(animBg.bgId, gBattleAnimFogTilemap);
+ LoadPalette(&gUnknown_83C2CE0, animBg.paletteId * 16, 32);
+ if (IsContest())
+ sub_80730C0(animBg.paletteId, animBg.bgTilemap, 0, 0);
+ gTasks[taskId].func = AnimTask_Haze2;
+}
+
+static void AnimTask_Haze2(u8 taskId)
+{
+ struct BattleAnimBgData animBg;
+
+ gBattle_BG1_X += -1;
+ switch (gTasks[taskId].data[12])
+ {
+ case 0:
+ if (++gTasks[taskId].data[10] == 4)
+ {
+ gTasks[taskId].data[10] = 0;
+ ++gTasks[taskId].data[9];
+ gTasks[taskId].data[11] = gUnknown_83E64D4[gTasks[taskId].data[9]];
+ SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(gTasks[taskId].data[11], 16 - gTasks[taskId].data[11]));
+ if (gTasks[taskId].data[11] == 9)
+ {
+ ++gTasks[taskId].data[12];
+ gTasks[taskId].data[11] = 0;
+ }
+ }
+ break;
+ case 1:
+ if (++gTasks[taskId].data[11] == 0x51)
+ {
+ gTasks[taskId].data[11] = 9;
+ ++gTasks[taskId].data[12];
+ }
+ break;
+ case 2:
+ if (++gTasks[taskId].data[10] == 4)
+ {
+ gTasks[taskId].data[10] = 0;
+ --gTasks[taskId].data[11];
+ SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(gTasks[taskId].data[11], 16 - gTasks[taskId].data[11]));
+ if (gTasks[taskId].data[11] == 0)
+ {
+ ++gTasks[taskId].data[12];
+ gTasks[taskId].data[11] = 0;
+ }
+ }
+ break;
+ case 3:
+ sub_80752A0(&animBg);
+ sub_8075358(1);
+ sub_8075358(2);
+ ++gTasks[taskId].data[12];
+ // fall through
+ case 4:
+ if (!IsContest())
+ SetAnimBgAttribute(1, BG_ANIM_CHAR_BASE_BLOCK, 0);
+ gBattle_BG1_X = 0;
+ gBattle_BG1_Y = 0;
+ SetGpuReg(REG_OFFSET_BLDCNT, 0);
+ SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(0, 0));
+ SetAnimBgAttribute(1, BG_ANIM_PRIORITY, 1);
+ DestroyAnimVisualTask(taskId);
+ break;
+ }
+}
+
+// Throws the ball in Mist Ball.
+// arg 0: initial x pixel offset
+// arg 1: initial y pixel offset
+// arg 2: targey x offset
+// arg 3: target y offset
+// arg 4: duration
+// arg 5: ??? unknown (seems to vibrate target mon somehow)
+static void AnimThrowMistBall(struct Sprite *sprite)
+{
+ sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X_2);
+ sprite->pos1.y = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y_PIC_OFFSET);
+ sprite->callback = TranslateAnimSpriteToTargetMonLocation;
+}
+
+// Displays misty background in Mist Ball.
+void AnimTask_LoadMistTiles(u8 taskId)
+{
+ struct BattleAnimBgData animBg;
+
+ SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT1_BG1 | BLDCNT_EFFECT_BLEND | BLDCNT_TGT2_ALL);
+ SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(0, 16));
+ SetAnimBgAttribute(1, BG_ANIM_PRIORITY, 1);
+ SetAnimBgAttribute(1, BG_ANIM_SCREEN_SIZE, 0);
+ if (!IsContest())
+ SetAnimBgAttribute(1, BG_ANIM_CHAR_BASE_BLOCK, 1);
+ gBattle_BG1_X = 0;
+ gBattle_BG1_Y = 0;
+ SetGpuReg(REG_OFFSET_BG1HOFS, gBattle_BG1_X);
+ SetGpuReg(REG_OFFSET_BG1VOFS, gBattle_BG1_Y);
+ sub_80752A0(&animBg);
+ LoadBgTiles(animBg.bgId, gWeatherFog1Tiles, 0x800, animBg.tilesOffset);
+ AnimLoadCompressedBgTilemap(animBg.bgId, gBattleAnimFogTilemap);
+ LoadPalette(&gUnknown_83C2CE0, animBg.paletteId * 16, 32);
+ if (IsContest())
+ sub_80730C0(animBg.paletteId, animBg.bgTilemap, 0, 0);
+ gTasks[taskId].data[15] = -1;
+ gTasks[taskId].func = AnimTask_OverlayFogTiles;
+}
+
+static void AnimTask_OverlayFogTiles(u8 taskId)
+{
+ struct BattleAnimBgData animBg;
+
+ gBattle_BG1_X += gTasks[taskId].data[15];
+ switch (gTasks[taskId].data[12])
+ {
+ case 0:
+ gTasks[taskId].data[9] += 1;
+ gTasks[taskId].data[11] = gUnknown_83E6500[gTasks[taskId].data[9]];
+ SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(gTasks[taskId].data[11], 17 - gTasks[taskId].data[11]));
+ if (gTasks[taskId].data[11] == 5)
+ {
+ ++gTasks[taskId].data[12];
+ gTasks[taskId].data[11] = 0;
+ }
+ break;
+ case 1:
+ if (++gTasks[taskId].data[11] == 0x51)
+ {
+ gTasks[taskId].data[11] = 5;
+ ++gTasks[taskId].data[12];
+ }
+ break;
+ case 2:
+ if (++gTasks[taskId].data[10] == 4)
+ {
+ gTasks[taskId].data[10] = 0;
+ gTasks[taskId].data[11] -= 1;
+ SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(gTasks[taskId].data[11], 16 - gTasks[taskId].data[11]));
+ if (gTasks[taskId].data[11] == 0)
+ {
+ ++gTasks[taskId].data[12];
+ gTasks[taskId].data[11] = 0;
+ }
+ }
+ break;
+ case 3:
+ sub_80752A0(&animBg);
+ sub_8075358(1);
+ sub_8075358(2);
+ ++gTasks[taskId].data[12];
+ // fall through
+ case 4:
+ if (!IsContest())
+ SetAnimBgAttribute(1, BG_ANIM_CHAR_BASE_BLOCK, 0);
+ gBattle_BG1_X = 0;
+ gBattle_BG1_Y = 0;
+ SetGpuReg(REG_OFFSET_BLDCNT, 0);
+ SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(0, 0));
+ SetAnimBgAttribute(1, BG_ANIM_PRIORITY, 1);
+ DestroyAnimVisualTask(taskId);
+ break;
+ }
+}
+
+// Initializes gas clouds in the Poison Gas animation.
+// arg 0: duration
+// arg 1: ? target x offset
+// arg 2: ? target y offset
+// arg 3: ? swirl start x
+// arg 4: ? swirl start y
+// arg 5: ??? unknown
+// arg 6: ??? unknown
+// arg 7: ??? unknown boolean
+static void InitPoisonGasCloudAnim(struct Sprite *sprite)
+{
+ sprite->data[0] = gBattleAnimArgs[0];
+ if (GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X_2) < GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X_2))
+ sprite->data[7] = 0x8000;
+ if ((gBattlerPositions[gBattleAnimTarget] & BIT_SIDE) == B_SIDE_PLAYER)
+ {
+ gBattleAnimArgs[1] = -gBattleAnimArgs[1];
+ gBattleAnimArgs[3] = -gBattleAnimArgs[3];
+ if ((sprite->data[7] & 0x8000) && (gBattlerPositions[gBattleAnimAttacker] & BIT_SIDE) == B_SIDE_PLAYER)
+ sprite->subpriority = gSprites[GetAnimBattlerSpriteId(ANIM_TARGET)].subpriority + 1;
+ sprite->data[6] = 1;
+ }
+ sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X_2);
+ sprite->pos1.y = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y_PIC_OFFSET);
+ if (gBattleAnimArgs[7])
+ {
+ sprite->data[1] = sprite->pos1.x + gBattleAnimArgs[1];
+ sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X_2) + gBattleAnimArgs[3];
+ sprite->data[3] = sprite->pos1.y + gBattleAnimArgs[2];
+ sprite->data[4] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y_PIC_OFFSET) + gBattleAnimArgs[4];
+ sprite->data[7] |= GetBattlerSpriteBGPriority(gBattleAnimTarget) << 8;
+ }
+ else
+ {
+ sprite->data[1] = sprite->pos1.x + gBattleAnimArgs[1];
+ sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X) + gBattleAnimArgs[3];
+ sprite->data[3] = sprite->pos1.y + gBattleAnimArgs[2];
+ sprite->data[4] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y) + gBattleAnimArgs[4];
+ sprite->data[7] |= GetBattlerSpriteBGPriority(gBattleAnimTarget) << 8;
+ }
+ if (IsContest())
+ {
+ sprite->data[6] = 1;
+ sprite->subpriority = 0x80;
+ }
+ InitAnimLinearTranslation(sprite);
+ sprite->callback = MovePoisonGasCloud;
+}
+
+static void MovePoisonGasCloud(struct Sprite *sprite)
+{
+ s32 value;
+
+ switch (sprite->data[7] & 0xFF)
+ {
+ case 0:
+ AnimTranslateLinear(sprite);
+ value = gSineTable[sprite->data[5]];
+ sprite->pos2.x += value >> 4;
+ if (sprite->data[6])
+ sprite->data[5] = (sprite->data[5] - 8) & 0xFF;
+ else
+ sprite->data[5] = (sprite->data[5] + 8) & 0xFF;
+ if (sprite->data[0] <= 0)
+ {
+ sprite->data[0] = 80;
+ sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X);
+ sprite->data[1] = sprite->pos1.x;
+ sprite->data[2] = sprite->pos1.x;
+ sprite->pos1.y += sprite->pos2.y;
+ sprite->data[3] = sprite->pos1.y;
+ sprite->data[4] = sprite->pos1.y + 29;
+ ++sprite->data[7];
+ if (IsContest())
+ sprite->data[5] = 80;
+ else if (GET_BATTLER_SIDE2(gBattleAnimTarget) != B_SIDE_PLAYER)
+ sprite->data[5] = 204;
+ else
+ sprite->data[5] = 80;
+ sprite->pos2.y = 0;
+ value = gSineTable[sprite->data[5]];
+ sprite->pos2.x = value >> 3;
+ sprite->data[5] = (sprite->data[5] + 2) & 0xFF;
+ InitAnimLinearTranslation(sprite);
+ }
+ break;
+ case 1:
+ AnimTranslateLinear(sprite);
+ value = gSineTable[sprite->data[5]];
+ sprite->pos2.x += value >> 3;
+ sprite->pos2.y += (gSineTable[sprite->data[5] + 0x40] * -3) >> 8;
+ if (!IsContest())
+ {
+ u16 var0 = sprite->data[5] - 0x40;
+
+ if (var0 <= 0x7F)
+ sprite->oam.priority = sprite->data[7] >> 8;
+ else
+ sprite->oam.priority = (sprite->data[7] >> 8) + 1;
+ sprite->data[5] = (sprite->data[5] + 4) & 0xFF;
+ }
+ else
+ {
+ u16 var0 = sprite->data[5] - 0x40;
+
+ if (var0 <= 0x7F)
+ sprite->subpriority = 128;
+ else
+ sprite->subpriority = 140;
+ sprite->data[5] = (sprite->data[5] - 4) & 0xFF;
+ }
+ if (sprite->data[0] <= 0)
+ {
+ sprite->data[0] = 0x300;
+ sprite->data[1] = sprite->pos1.x += sprite->pos2.x;
+ sprite->data[3] = sprite->pos1.y += sprite->pos2.y;
+ sprite->data[4] = sprite->pos1.y + 4;
+ if (IsContest())
+ sprite->data[2] = -0x10;
+ else if (GET_BATTLER_SIDE2(gBattleAnimTarget) != B_SIDE_PLAYER)
+ sprite->data[2] = 0x100;
+ else
+ sprite->data[2] = -0x10;
+ ++sprite->data[7];
+ sprite->pos2.x = sprite->pos2.y = 0;
+ sub_8075678(sprite);
+ }
+ break;
+ case 2:
+ if (AnimTranslateLinear(sprite))
+ {
+ if (sprite->oam.affineMode & 1)
+ {
+ FreeOamMatrix(sprite->oam.matrixNum);
+ sprite->oam.affineMode = ST_OAM_AFFINE_OFF;
+ }
+ DestroySprite(sprite);
+ --gAnimVisualTaskCount;
+ }
+ break;
+ }
+}
+
+// Creates Hail.
+void AnimTask_Hail1(u8 taskId)
+{
+ struct Task *task = &gTasks[taskId];
+
+ task->func = AnimTask_Hail2;
+}
+
+static void AnimTask_Hail2(u8 taskId)
+{
+ struct Task *task = &gTasks[taskId];
+
+ switch (task->data[0])
+ {
+ case 0:
+ if (++task->data[4] > 2)
+ {
+ task->data[4] = 0;
+ task->data[5] = 0;
+ task->data[2] = 0;
+ ++task->data[0];
+ }
+ break;
+ case 1:
+ if (task->data[5] == 0)
+ {
+ if (GenerateHailParticle(task->data[3], task->data[2], taskId, 1))
+ ++task->data[1];
+ if (++task->data[2] == 3)
+ {
+ if (++task->data[3] == 10)
+ ++task->data[0];
+ else
+ --task->data[0];
+ }
+ else
+ {
+ task->data[5] = 1;
+ }
+ }
+ else
+ {
+ --task->data[5];
+ }
+ break;
+ case 2:
+ if (task->data[1] == 0)
+ DestroyAnimVisualTask(taskId);
+ break;
+ }
+}
+
+static bool8 GenerateHailParticle(u8 hailStructId, u8 affineAnimNum, u8 taskId, u8 c)
+{
+ u8 id;
+ s16 battlerX, battlerY;
+ s16 spriteX;
+ bool8 possibleBool = FALSE;
+ s8 unk = gUnknown_83E652C[hailStructId].unk3;
+
+ if (unk != 2)
+ {
+ id = GetBattlerAtPosition(gUnknown_83E652C[hailStructId].unk2);
+ if (IsBattlerSpriteVisible(id))
+ {
+ possibleBool = TRUE;
+ battlerX = GetBattlerSpriteCoord(id, BATTLER_COORD_X_2);
+ battlerY = GetBattlerSpriteCoord(id, BATTLER_COORD_Y_PIC_OFFSET);
+ switch (unk)
+ {
+ case 0:
+ battlerX -= GetBattlerSpriteCoordAttr(id, BATTLER_COORD_ATTR_WIDTH) / 6;
+ battlerY -= GetBattlerSpriteCoordAttr(id, BATTLER_COORD_ATTR_HEIGHT) / 6;
+ break;
+ case 1:
+ battlerX += GetBattlerSpriteCoordAttr(id, BATTLER_COORD_ATTR_WIDTH) / 6;
+ battlerY += GetBattlerSpriteCoordAttr(id, BATTLER_COORD_ATTR_HEIGHT) / 6;
+ break;
+ }
+ }
+ else
+ {
+ battlerX = (gUnknown_83E652C[hailStructId].unk0);
+ battlerY = (gUnknown_83E652C[hailStructId].unk1);
+ }
+ }
+ else
+ {
+ battlerX = (gUnknown_83E652C[hailStructId].unk0);
+ battlerY = (gUnknown_83E652C[hailStructId].unk1);
+ }
+ spriteX = battlerX - ((battlerY + 8) / 2);
+ id = CreateSprite(&gUnknown_83E65A4, spriteX, -8, 18);
+ if (id == MAX_SPRITES)
+ {
+ return FALSE;
+ }
+ else
+ {
+ StartSpriteAffineAnim(&gSprites[id], affineAnimNum);
+ gSprites[id].data[0] = possibleBool;
+ gSprites[id].data[3] = battlerX;
+ gSprites[id].data[4] = battlerY;
+ gSprites[id].data[5] = affineAnimNum;
+ gSprites[id].data[6] = taskId;
+ gSprites[id].data[7] = c;
+ return TRUE;
+ }
+}
+
+static void AnimHailBegin(struct Sprite *sprite)
+{
+ u8 spriteId;
+
+ sprite->pos1.x += 4;
+ sprite->pos1.y += 8;
+ if (sprite->pos1.x < sprite->data[3] && sprite->pos1.y < sprite->data[4])
+ return;
+ if (sprite->data[0] == 1 && sprite->data[5] == 0)
+ {
+ spriteId = CreateSprite(&gUnknown_83E63E0, sprite->data[3], sprite->data[4], sprite->subpriority);
+ sprite->data[0] = spriteId;
+ if (spriteId != 64)
+ {
+ gSprites[sprite->data[0]].callback = AnimHailContinue;
+ gSprites[sprite->data[0]].data[6] = sprite->data[6];
+ gSprites[sprite->data[0]].data[7] = sprite->data[7];
+ }
+ FreeOamMatrix(sprite->oam.matrixNum);
+ DestroySprite(sprite);
+ }
+ else
+ {
+ --gTasks[sprite->data[6]].data[sprite->data[7]];
+ FreeOamMatrix(sprite->oam.matrixNum);
+ DestroySprite(sprite);
+ }
+}
+
+static void AnimHailContinue(struct Sprite *sprite)
+{
+ if (++sprite->data[0] == 20)
+ {
+ --gTasks[sprite->data[6]].data[sprite->data[7]];
+ FreeOamMatrix(sprite->oam.matrixNum);
+ DestroySprite(sprite);
+ }
+}
+
+// Initializes the animation for Ice Ball.
+// arg 0: initial x pixel offset
+// arg 1: initial y pixel offset
+// arg 2: target x offset
+// arg 3: target y offset
+// arg 4: duration
+// arg 5: arc height (negative)
+static void InitIceBallAnim(struct Sprite *sprite)
+{
+ u8 animNum = gAnimDisableStructPtr->rolloutTimerStartValue - gAnimDisableStructPtr->rolloutTimer - 1;
+
+ if (animNum > 4)
+ animNum = 4;
+ StartSpriteAffineAnim(sprite, animNum);
+ InitSpritePosToAnimAttacker(sprite, 1);
+ sprite->data[0] = gBattleAnimArgs[4];
+ if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER)
+ gBattleAnimArgs[2] = -gBattleAnimArgs[2];
+ sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X_2) + gBattleAnimArgs[2];
+ sprite->data[4] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y_PIC_OFFSET) + gBattleAnimArgs[3];
+ sprite->data[5] = gBattleAnimArgs[5];
+ InitAnimArcTranslation(sprite);
+ sprite->callback = AnimThrowIceBall;
+}
+
+// Throws the ball of ice in Ice Ball.
+static void AnimThrowIceBall(struct Sprite *sprite)
+{
+ if (TranslateAnimHorizontalArc(sprite))
+ {
+ StartSpriteAnim(sprite, 1);
+ sprite->callback = RunStoredCallbackWhenAnimEnds;
+ StoreSpriteCallbackInData6(sprite, DestroyAnimSprite);
+ }
+}
+
+// Initializes the particles that scatter at the end of the Ice Ball animation.
+static void InitIceBallParticle(struct Sprite *sprite)
+{
+ s16 randA, randB;
+
+ sprite->oam.tileNum += 8;
+ InitSpritePosToAnimTarget(sprite, TRUE);
+ randA = (Random() & 0xFF) + 256;
+ randB = Random() & 0x1FF;
+ if (randB > 0xFF)
+ randB = 256 - randB;
+ sprite->data[1] = randA;
+ sprite->data[2] = randB;
+ sprite->callback = AnimIceBallParticle;
+}
+
+// Animates the particles created by InitIceBallParticle.
+static void AnimIceBallParticle(struct Sprite *sprite)
+{
+ sprite->data[3] += sprite->data[1];
+ sprite->data[4] += sprite->data[2];
+ if (sprite->data[1] & 1)
+ sprite->pos2.x = -(sprite->data[3] >> 8);
+ else
+ sprite->pos2.x = sprite->data[3] >> 8;
+ sprite->pos2.y = sprite->data[4] >> 8;
+ if (++sprite->data[0] == 21)
+ DestroyAnimSprite(sprite);
+}
+
+// Counter for Ice Ball.
+void AnimTask_GetRolloutCounter(u8 taskId)
+{
+ u8 arg = gBattleAnimArgs[0];
+
+ gBattleAnimArgs[arg] = gAnimDisableStructPtr->rolloutTimerStartValue - gAnimDisableStructPtr->rolloutTimer - 1;
+ DestroyAnimVisualTask(taskId);
+}
diff --git a/src/poison.c b/src/poison.c
new file mode 100644
index 000000000..004e9aa98
--- /dev/null
+++ b/src/poison.c
@@ -0,0 +1,298 @@
+#include "global.h"
+#include "battle_anim.h"
+#include "trig.h"
+
+static void sub_80B1620(struct Sprite *sprite);
+static void sub_80B16A0(struct Sprite *sprite);
+static void sub_80B1744(struct Sprite *sprite);
+static void sub_80B17C4(struct Sprite *sprite);
+static void AnimBubbleEffect(struct Sprite *sprite);
+static void sub_80B1684(struct Sprite *sprite);
+static void sub_80B1728(struct Sprite *sprite);
+static void sub_80B1798(struct Sprite *sprite);
+static void AnimBubbleEffectStep(struct Sprite *sprite);
+
+static const union AnimCmd gUnknown_83E6994[] =
+{
+ ANIMCMD_FRAME(0, 5),
+ ANIMCMD_FRAME(8, 5),
+ ANIMCMD_FRAME(16, 5),
+ ANIMCMD_FRAME(24, 5),
+ ANIMCMD_END,
+};
+
+static const union AnimCmd *const gUnknown_83E69A8[] =
+{
+ gUnknown_83E6994,
+};
+
+const struct SpriteTemplate gUnknown_83E69AC =
+{
+ .tileTag = ANIM_TAG_TOXIC_BUBBLE,
+ .paletteTag = ANIM_TAG_TOXIC_BUBBLE,
+ .oam = &gOamData_83ACA18,
+ .anims = gUnknown_83E69A8,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = AnimSpriteOnMonPos,
+};
+
+static const union AnimCmd gUnknown_83E69C4[] =
+{
+ ANIMCMD_FRAME(0, 1),
+ ANIMCMD_END,
+};
+
+static const union AnimCmd gUnknown_83E69CC[] =
+{
+ ANIMCMD_FRAME(4, 1),
+ ANIMCMD_END,
+};
+
+static const union AnimCmd gUnknown_83E69D4[] =
+{
+ ANIMCMD_FRAME(8, 1),
+ ANIMCMD_END,
+};
+
+static const union AnimCmd *const gUnknown_83E69DC[] =
+{
+ gUnknown_83E69C4,
+};
+
+static const union AnimCmd *const gUnknown_83E69E0[] =
+{
+ gUnknown_83E69CC,
+};
+
+static const union AnimCmd *const gUnknown_83E69E4[] =
+{
+ gUnknown_83E69D4,
+};
+
+static const union AffineAnimCmd gUnknown_83E69E8[] =
+{
+ AFFINEANIMCMD_FRAME(0x160, 0x160, 0, 0),
+ AFFINEANIMCMD_FRAME(-0xA, -0xA, 0, 10),
+ AFFINEANIMCMD_FRAME(0xA, 0xA, 0, 10),
+ AFFINEANIMCMD_JUMP(0),
+};
+
+static const union AffineAnimCmd gUnknown_83E6A08[] =
+{
+ AFFINEANIMCMD_FRAME(0xEC, 0xEC, 0, 0),
+ AFFINEANIMCMD_END,
+};
+
+static const union AffineAnimCmd *const gUnknown_83E6A18[] =
+{
+ gUnknown_83E69E8,
+};
+
+static const union AffineAnimCmd *const gUnknown_83E6A1C[] =
+{
+ gUnknown_83E6A08,
+};
+
+const struct SpriteTemplate gUnknown_83E6A20 =
+{
+ .tileTag = ANIM_TAG_POISON_BUBBLE,
+ .paletteTag = ANIM_TAG_POISON_BUBBLE,
+ .oam = &gOamData_83ACA90,
+ .anims = gUnknown_83E69DC,
+ .images = NULL,
+ .affineAnims = gUnknown_83E6A18,
+ .callback = sub_80B1620,
+};
+
+const struct SpriteTemplate gUnknown_83E6A38 =
+{
+ .tileTag = ANIM_TAG_POISON_BUBBLE,
+ .paletteTag = ANIM_TAG_POISON_BUBBLE,
+ .oam = &gOamData_83ACA90,
+ .anims = gUnknown_83E69DC,
+ .images = NULL,
+ .affineAnims = gUnknown_83E6A18,
+ .callback = sub_80B16A0,
+};
+
+const struct SpriteTemplate gUnknown_83E6A50 =
+{
+ .tileTag = ANIM_TAG_POISON_BUBBLE,
+ .paletteTag = ANIM_TAG_POISON_BUBBLE,
+ .oam = &gOamData_83ACA30,
+ .anims = gUnknown_83E69E4,
+ .images = NULL,
+ .affineAnims = gUnknown_83E6A1C,
+ .callback = sub_80B1744,
+};
+
+static const union AffineAnimCmd gUnknown_83E6A68[] =
+{
+ AFFINEANIMCMD_FRAME(-0x10, 0x10, 0, 6),
+ AFFINEANIMCMD_FRAME(0x10, -0x10, 0, 6),
+ AFFINEANIMCMD_JUMP(0),
+};
+
+static const union AffineAnimCmd *const gUnknown_83E6A80[] =
+{
+ gUnknown_83E6A68,
+};
+
+const struct SpriteTemplate gUnknown_83E6A84 =
+{
+ .tileTag = ANIM_TAG_POISON_BUBBLE,
+ .paletteTag = ANIM_TAG_POISON_BUBBLE,
+ .oam = &gOamData_83ACA90,
+ .anims = gUnknown_83E69E0,
+ .images = NULL,
+ .affineAnims = gUnknown_83E6A80,
+ .callback = sub_80B17C4,
+};
+
+static const union AffineAnimCmd gUnknown_83E6A9C[] =
+{
+ AFFINEANIMCMD_FRAME(0x9C, 0x9C, 0, 0),
+ AFFINEANIMCMD_FRAME(0x5, 0x5, 0, 20),
+ AFFINEANIMCMD_END,
+};
+
+static const union AffineAnimCmd *const gUnknown_83E6AB4[] =
+{
+ gUnknown_83E6A9C,
+};
+
+const struct SpriteTemplate gPoisonBubbleSpriteTemplate =
+{
+ .tileTag = ANIM_TAG_POISON_BUBBLE,
+ .paletteTag = ANIM_TAG_POISON_BUBBLE,
+ .oam = &gOamData_83ACA30,
+ .anims = gUnknown_83E69DC,
+ .images = NULL,
+ .affineAnims = gUnknown_83E6AB4,
+ .callback = AnimBubbleEffect,
+};
+
+const struct SpriteTemplate gWaterBubbleSpriteTemplate =
+{
+ .tileTag = ANIM_TAG_SMALL_BUBBLES,
+ .paletteTag = ANIM_TAG_SMALL_BUBBLES,
+ .oam = &gOamData_83ACB50,
+ .anims = gUnknown_83E5A78,
+ .images = NULL,
+ .affineAnims = gUnknown_83E6AB4,
+ .callback = AnimBubbleEffect,
+};
+
+static void sub_80B1620(struct Sprite *sprite)
+{
+ if (!gBattleAnimArgs[3])
+ StartSpriteAnim(sprite, 2);
+ InitSpritePosToAnimAttacker(sprite, 1);
+ sprite->data[0] = gBattleAnimArgs[2];
+ sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimTarget, 2);
+ sprite->data[4] = GetBattlerSpriteCoord(gBattleAnimTarget, 3);
+ sprite->data[5] = -30;
+ InitAnimArcTranslation(sprite);
+ sprite->callback = sub_80B1684;
+}
+
+static void sub_80B1684(struct Sprite *sprite)
+{
+ if (TranslateAnimHorizontalArc(sprite))
+ DestroyAnimSprite(sprite);
+}
+
+static void sub_80B16A0(struct Sprite *sprite)
+{
+ s16 l1, l2;
+
+ if (!gBattleAnimArgs[3])
+ StartSpriteAnim(sprite, 2);
+ InitSpritePosToAnimAttacker(sprite, 1);
+ SetAverageBattlerPositions(gBattleAnimTarget, 1, &l1, &l2);
+ if (GetBattlerSide(gBattleAnimAttacker))
+ gBattleAnimArgs[4] = -gBattleAnimArgs[4];
+ sprite->data[0] = gBattleAnimArgs[2];
+ sprite->data[2] = l1 + gBattleAnimArgs[4];
+ sprite->data[4] = l2 + gBattleAnimArgs[5];
+ sprite->data[5] = -30;
+ InitAnimArcTranslation(sprite);
+ sprite->callback = sub_80B1728;
+}
+
+static void sub_80B1728(struct Sprite *sprite)
+{
+ if (TranslateAnimHorizontalArc(sprite))
+ DestroyAnimSprite(sprite);
+}
+
+static void sub_80B1744(struct Sprite *sprite)
+{
+ sprite->data[0] = gBattleAnimArgs[2];
+ sprite->data[1] = sprite->pos1.x;
+ sprite->data[2] = sprite->pos1.x + gBattleAnimArgs[0];
+ sprite->data[3] = sprite->pos1.y;
+ sprite->data[4] = sprite->pos1.y + gBattleAnimArgs[1];
+ InitSpriteDataForLinearTranslation(sprite);
+ sprite->data[5] = sprite->data[1] / gBattleAnimArgs[2];
+ sprite->data[6] = sprite->data[2] / gBattleAnimArgs[2];
+ sprite->callback = sub_80B1798;
+}
+
+static void sub_80B1798(struct Sprite *sprite)
+{
+ TranslateSpriteLinearFixedPoint(sprite);
+ sprite->data[1] -= sprite->data[5];
+ sprite->data[2] -= sprite->data[6];
+ if (!sprite->data[0])
+ DestroyAnimSprite(sprite);
+}
+
+static void sub_80B17C4(struct Sprite *sprite)
+{
+ SetAverageBattlerPositions(gBattleAnimTarget, TRUE, &sprite->pos1.x, &sprite->pos1.y);
+ if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER)
+ gBattleAnimArgs[0] = -gBattleAnimArgs[0];
+ sprite->pos1.x += gBattleAnimArgs[0];
+ sprite->pos1.y += gBattleAnimArgs[1];
+ sprite->data[0] = gBattleAnimArgs[4];
+ sprite->data[2] = sprite->pos1.x + gBattleAnimArgs[2];
+ sprite->data[4] = sprite->pos1.y + sprite->data[0];
+ sprite->callback = StartAnimLinearTranslation;
+ StoreSpriteCallbackInData6(sprite, DestroyAnimSprite);
+}
+
+// Animates a bubble by rising upward, swaying side to side, and
+// enlarging the sprite. This is used as an after-effect by poison-type
+// moves, along with MOVE_BUBBLE, and MOVE_BUBBLEBEAM.
+// arg 0: initial x pixel offset
+// arg 1: initial y pixel offset
+// arg 2: 0 = single-target, 1 = multi-target
+static void AnimBubbleEffect(struct Sprite *sprite)
+{
+ if (!gBattleAnimArgs[2])
+ {
+ InitSpritePosToAnimTarget(sprite, TRUE);
+ }
+ else
+ {
+ SetAverageBattlerPositions(gBattleAnimTarget, TRUE, &sprite->pos1.x, &sprite->pos1.y);
+
+ if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER)
+ gBattleAnimArgs[0] = -gBattleAnimArgs[0];
+ sprite->pos1.x += gBattleAnimArgs[0];
+ sprite->pos1.y += gBattleAnimArgs[1];
+ }
+ sprite->callback = AnimBubbleEffectStep;
+}
+
+static void AnimBubbleEffectStep(struct Sprite *sprite)
+{
+ sprite->data[0] = (sprite->data[0] + 0xB) & 0xFF;
+ sprite->pos2.x = Sin(sprite->data[0], 4);
+ sprite->data[1] += 0x30;
+ sprite->pos2.y = -(sprite->data[1] >> 8);
+ if (sprite->affineAnimEnded)
+ DestroyAnimSprite(sprite);
+}
diff --git a/src/pokemon.c b/src/pokemon.c
index c4ae0c4da..57633dbad 100644
--- a/src/pokemon.c
+++ b/src/pokemon.c
@@ -2365,25 +2365,25 @@ s32 CalculateBaseDamage(struct BattlePokemon *attacker, struct BattlePokemon *de
if (!(gBattleTypeFlags & (BATTLE_TYPE_LINK | /*BATTLE_TYPE_BATTLE_TOWER |*/ BATTLE_TYPE_EREADER_TRAINER)))
{
if (FlagGet(FLAG_BADGE01_GET)
- && !GetBattlerSide(battlerIdAtk))
+ && GetBattlerSide(battlerIdAtk) == B_SIDE_PLAYER)
attack = (110 * attack) / 100;
}
if (!(gBattleTypeFlags & (BATTLE_TYPE_LINK | /*BATTLE_TYPE_BATTLE_TOWER |*/ BATTLE_TYPE_EREADER_TRAINER)))
{
if (FlagGet(FLAG_BADGE05_GET)
- && !GetBattlerSide(battlerIdDef))
+ && GetBattlerSide(battlerIdDef) == B_SIDE_PLAYER)
defense = (110 * defense) / 100;
}
if (!(gBattleTypeFlags & (BATTLE_TYPE_LINK | /*BATTLE_TYPE_BATTLE_TOWER |*/ BATTLE_TYPE_EREADER_TRAINER)))
{
if (FlagGet(FLAG_BADGE07_GET)
- && !GetBattlerSide(battlerIdAtk))
+ && GetBattlerSide(battlerIdAtk) == B_SIDE_PLAYER)
spAttack = (110 * spAttack) / 100;
}
if (!(gBattleTypeFlags & (BATTLE_TYPE_LINK | /*BATTLE_TYPE_BATTLE_TOWER |*/ BATTLE_TYPE_EREADER_TRAINER)))
{
if (FlagGet(FLAG_BADGE07_GET)
- && !GetBattlerSide(battlerIdDef))
+ && GetBattlerSide(battlerIdDef) == B_SIDE_PLAYER)
spDefense = (110 * spDefense) / 100;
}
@@ -3917,7 +3917,7 @@ bool8 PokemonUseItemEffects(struct Pokemon *mon, u16 item, u8 partyIndex, u8 mov
if (gMain.inBattle)
{
gActiveBattler = gBattlerInMenuId;
- cmdIndex = (GetBattlerSide(gActiveBattler) != 0);
+ cmdIndex = (GetBattlerSide(gActiveBattler) != B_SIDE_PLAYER);
while (cmdIndex < gBattlersCount)
{
if (gBattlerPartyIndexes[cmdIndex] == partyIndex)
@@ -4118,13 +4118,13 @@ bool8 PokemonUseItemEffects(struct Pokemon *mon, u16 item, u8 partyIndex, u8 mov
{
gAbsentBattlerFlags &= ~gBitTable[sp34];
CopyPlayerPartyMonToBattleData(sp34, pokemon_order_func(gBattlerPartyIndexes[sp34]));
- if (GetBattlerSide(gActiveBattler) == 0 && gBattleResults.numRevivesUsed < 255)
+ if (GetBattlerSide(gActiveBattler) == B_SIDE_PLAYER && gBattleResults.numRevivesUsed < 255)
gBattleResults.numRevivesUsed++;
}
else
{
gAbsentBattlerFlags &= ~gBitTable[gActiveBattler ^ 2];
- if (GetBattlerSide(gActiveBattler) == 0 && gBattleResults.numRevivesUsed < 255)
+ if (GetBattlerSide(gActiveBattler) == B_SIDE_PLAYER && gBattleResults.numRevivesUsed < 255)
gBattleResults.numRevivesUsed++;
}
}
@@ -4163,7 +4163,7 @@ bool8 PokemonUseItemEffects(struct Pokemon *mon, u16 item, u8 partyIndex, u8 mov
if (gMain.inBattle && sp34 != 4)
{
gBattleMons[sp34].hp = data;
- if (!(r10 & 0x10) && GetBattlerSide(gActiveBattler) == 0)
+ if (!(r10 & 0x10) && GetBattlerSide(gActiveBattler) == B_SIDE_PLAYER)
{
if (gBattleResults.numHealingItemsUsed < 255)
gBattleResults.numHealingItemsUsed++;
@@ -6039,11 +6039,11 @@ void HandleSetPokedexFlag(u16 nationalNum, u8 caseId, u32 personality)
}
}
-bool8 CheckBattleTypeGhost(struct Pokemon *mon, u8 bank)
+bool8 CheckBattleTypeGhost(struct Pokemon *mon, u8 battlerId)
{
u8 buffer[12];
- if (gBattleTypeFlags & BATTLE_TYPE_GHOST && GetBattlerSide(bank))
+ if (gBattleTypeFlags & BATTLE_TYPE_GHOST && GetBattlerSide(battlerId) != B_SIDE_PLAYER)
{
GetMonData(mon, MON_DATA_NICKNAME, buffer);
StringGetEnd10(buffer);
diff --git a/src/psychic.c b/src/psychic.c
index a8108c55a..bbb6c3ed5 100644
--- a/src/psychic.c
+++ b/src/psychic.c
@@ -30,7 +30,7 @@ static void sub_80B3D78(u8 taskId);
static const union AffineAnimCmd gUnknown_83E6DDC[] =
{
AFFINEANIMCMD_FRAME(0x100, 0x100, 0, 0),
- AFFINEANIMCMD_FRAME(0xFFFE, 0xFFFE, -10, 120),
+ AFFINEANIMCMD_FRAME(-0x2, -0x2, -10, 120),
AFFINEANIMCMD_END,
};
@@ -305,7 +305,7 @@ const struct SpriteTemplate gUnknown_83E705C =
static const union AffineAnimCmd gUnknown_83E7074[] =
{
- AFFINEANIMCMD_FRAME(0xFFF8, 0xFFF8, 0, 8),
+ AFFINEANIMCMD_FRAME(-0x8, -0x8, 0, 8),
AFFINEANIMCMD_FRAME(0x8, 0x8, 0, 8),
AFFINEANIMCMD_JUMP(0),
};
@@ -313,27 +313,27 @@ static const union AffineAnimCmd gUnknown_83E7074[] =
static const union AffineAnimCmd gUnknown_83E708C[] =
{
AFFINEANIMCMD_FRAME(0xF0, 0xF0, 0, 0),
- AFFINEANIMCMD_FRAME(0xFFF8, 0xFFF8, 0, 6),
+ AFFINEANIMCMD_FRAME(-0x8, -0x8, 0, 6),
AFFINEANIMCMD_FRAME(0x8, 0x8, 0, 8),
- AFFINEANIMCMD_FRAME(0xFFF8, 0xFFF8, 0, 2),
+ AFFINEANIMCMD_FRAME(-0x8, -0x8, 0, 2),
AFFINEANIMCMD_JUMP(1),
};
static const union AffineAnimCmd gUnknown_83E70B4[] =
{
AFFINEANIMCMD_FRAME(0xD0, 0xD0, 0, 0),
- AFFINEANIMCMD_FRAME(0xFFF8, 0xFFF8, 0, 4),
+ AFFINEANIMCMD_FRAME(-0x8, -0x8, 0, 4),
AFFINEANIMCMD_FRAME(0x8, 0x8, 0, 8),
- AFFINEANIMCMD_FRAME(0xFFF8, 0xFFF8, 0, 4),
+ AFFINEANIMCMD_FRAME(-0x8, -0x8, 0, 4),
AFFINEANIMCMD_JUMP(1),
};
static const union AffineAnimCmd gUnknown_83E70DC[] =
{
AFFINEANIMCMD_FRAME(0xB0, 0xB0, 0, 0),
- AFFINEANIMCMD_FRAME(0xFFF8, 0xFFF8, 0, 2),
+ AFFINEANIMCMD_FRAME(-0x8, -0x8, 0, 2),
AFFINEANIMCMD_FRAME(0x8, 0x8, 0, 8),
- AFFINEANIMCMD_FRAME(0xFFF8, 0xFFF8, 0, 6),
+ AFFINEANIMCMD_FRAME(-0x8, -0x8, 0, 6),
AFFINEANIMCMD_JUMP(1),
};
@@ -384,11 +384,11 @@ static const union AffineAnimCmd gUnknown_83E7160[] =
AFFINEANIMCMD_FRAME(0x20, 0x20, 0, 0),
AFFINEANIMCMD_FRAME(0x10, 0x10, 0, 17),
AFFINEANIMCMD_LOOP(0),
- AFFINEANIMCMD_FRAME(0xFFF8, 0xFFF8, 0, 10),
+ AFFINEANIMCMD_FRAME(-0x8, -0x8, 0, 10),
AFFINEANIMCMD_FRAME(0x8, 0x8, 0, 10),
AFFINEANIMCMD_LOOP(4),
AFFINEANIMCMD_LOOP(0),
- AFFINEANIMCMD_FRAME(0xFFF0, 0xFFF0, 0, 5),
+ AFFINEANIMCMD_FRAME(-0x10, -0x10, 0, 5),
AFFINEANIMCMD_FRAME(0x10, 0x10, 0, 5),
AFFINEANIMCMD_LOOP(7),
AFFINEANIMCMD_END,
@@ -396,7 +396,7 @@ static const union AffineAnimCmd gUnknown_83E7160[] =
static const union AffineAnimCmd gUnknown_83E71B8[] =
{
- AFFINEANIMCMD_FRAME(0xFFEC, 0x18, 0, 15),
+ AFFINEANIMCMD_FRAME(-0x14, 0x18, 0, 15),
AFFINEANIMCMD_END,
};
diff --git a/src/quest_log.c b/src/quest_log.c
index 78fa73de7..d7b544882 100644
--- a/src/quest_log.c
+++ b/src/quest_log.c
@@ -31,10 +31,10 @@
#include "wild_encounter.h"
#include "help_system.h"
#include "party_menu.h"
-#include "unk_8159F40.h"
#include "pokemon_storage_system.h"
#include "save.h"
#include "link.h"
+#include "quest_log_815A008.h"
#include "quest_log_8150454.h"
#include "quest_log.h"
#include "new_menu_helpers.h"
diff --git a/src/unk_8159F40.c b/src/quest_log_815A008.c
index ef21d19d0..2d488a845 100644
--- a/src/unk_8159F40.c
+++ b/src/quest_log_815A008.c
@@ -1,5 +1,4 @@
#include "global.h"
-#include "battle.h"
#include "event_data.h"
#include "quest_log.h"
#include "fieldmap.h"
@@ -7,152 +6,6 @@
#include "metatile_behavior.h"
#include "link.h"
#include "link_rfu.h"
-#include "constants/species.h"
-#include "constants/moves.h"
-#include "constants/pokemon.h"
-
-struct PokedudeBattlePartyInfo
-{
- u8 side;
- u8 level;
- u16 species;
- u16 moves[4];
- u8 nature;
- u8 gender;
-};
-
-static const struct PokedudeBattlePartyInfo sParties_Battle[] = {
- {
- .side = 0,
- .level = 15,
- .species = SPECIES_RATTATA,
- .moves = {MOVE_TACKLE, MOVE_TAIL_WHIP, MOVE_HYPER_FANG, MOVE_QUICK_ATTACK},
- .nature = NATURE_LONELY,
- .gender = MALE
- },
- {
- .side = 1,
- .level = 18,
- .species = SPECIES_PIDGEY,
- .moves = {MOVE_TACKLE, MOVE_SAND_ATTACK, MOVE_GUST, MOVE_QUICK_ATTACK},
- .nature = NATURE_NAUGHTY,
- .gender = MALE
- },
- {0xFF}
-};
-
-static const struct PokedudeBattlePartyInfo sParties_Status[] = {
- {
- .side = 0,
- .level = 15,
- .species = SPECIES_RATTATA,
- .moves = {MOVE_TACKLE, MOVE_TAIL_WHIP, MOVE_HYPER_FANG, MOVE_QUICK_ATTACK},
- .nature = NATURE_LONELY,
- .gender = MALE
- },
- {
- .side = 1,
- .level = 14,
- .species = SPECIES_ODDISH,
- .moves = {MOVE_ABSORB, MOVE_SWEET_SCENT, MOVE_POISON_POWDER},
- .nature = NATURE_RASH,
- .gender = MALE
- },
- {0xFF}
-};
-
-static const struct PokedudeBattlePartyInfo sParties_Matchups[] = {
- {
- .side = 0,
- .level = 15,
- .species = SPECIES_POLIWAG,
- .moves = {MOVE_WATER_GUN, MOVE_HYPNOSIS, MOVE_BUBBLE},
- .nature = NATURE_RASH,
- .gender = MALE
- },
- {
- .side = 0,
- .level = 15,
- .species = SPECIES_BUTTERFREE,
- .moves = {MOVE_CONFUSION, MOVE_POISON_POWDER, MOVE_STUN_SPORE, MOVE_SLEEP_POWDER},
- .nature = NATURE_RASH,
- .gender = MALE
- },
- {
- .side = 1,
- .level = 14,
- .species = SPECIES_ODDISH,
- .moves = {MOVE_ABSORB, MOVE_SWEET_SCENT, MOVE_POISON_POWDER},
- .nature = NATURE_RASH,
- .gender = MALE
- },
- {0xFF}
-};
-
-static const struct PokedudeBattlePartyInfo sParties_Catching[] = {
- {
- .side = 0,
- .level = 15,
- .species = SPECIES_BUTTERFREE,
- .moves = {MOVE_CONFUSION, MOVE_POISON_POWDER, MOVE_SLEEP_POWDER, MOVE_STUN_SPORE},
- .nature = NATURE_RASH,
- .gender = MALE
- },
- {
- .side = 1,
- .level = 11,
- .species = SPECIES_JIGGLYPUFF,
- .moves = {MOVE_SING, MOVE_DEFENSE_CURL, MOVE_POUND},
- .nature = NATURE_CAREFUL,
- .gender = MALE
- },
- {0xFF}
-};
-
-
-static const struct PokedudeBattlePartyInfo *const sPokedudeBattlePartyPointers[] = {
- sParties_Battle,
- sParties_Status,
- sParties_Matchups,
- sParties_Catching
-};
-
-void InitPokedudePartyAndOpponent(void)
-{
- s32 i, j;
- struct Pokemon * mon;
- s32 myIdx = 0;
- s32 opIdx = 0;
- const struct PokedudeBattlePartyInfo * data;
-
- gBattleTypeFlags = BATTLE_TYPE_POKEDUDE;
- ZeroPlayerPartyMons();
- ZeroEnemyPartyMons();
- data = sPokedudeBattlePartyPointers[gSpecialVar_0x8004];
-
- i = 0;
- do
- {
- if (data[i].side == 0)
- {
- mon = &gPlayerParty[myIdx];
- myIdx++;
- }
- else
- {
- mon = &gEnemyParty[opIdx];
- opIdx++;
- }
- CreateMonWithGenderNatureLetter(mon, data[i].species, data[i].level, 0, data[i].gender, data[i].nature, 0);
- for (j = 0; j < 4; j++)
- {
- SetMonMoveSlot(mon, data[i].moves[j], j);
- }
- i++;
- } while (data[i].side != 0xFF);
-}
-
-// file boundary?
void sub_815A008(struct QuestLog * questLog)
{
diff --git a/src/rock.c b/src/rock.c
index 4db903344..c4b668941 100644
--- a/src/rock.c
+++ b/src/rock.c
@@ -87,8 +87,8 @@ const struct SpriteTemplate gUnknown_83E73E4 =
static const union AffineAnimCmd gUnknown_83E73FC[] =
{
AFFINEANIMCMD_FRAME(0xC0, 0xC0, 0, 0),
- AFFINEANIMCMD_FRAME(0x2, 0xFFFD, 0, 5),
- AFFINEANIMCMD_FRAME(0xFFFE, 0x3, 0, 5),
+ AFFINEANIMCMD_FRAME(0x2, -0x3, 0, 5),
+ AFFINEANIMCMD_FRAME(-0x2, 0x3, 0, 5),
AFFINEANIMCMD_JUMP(1),
};
@@ -152,7 +152,7 @@ static const struct Subsprite gUnknown_83E7468[] =
static const struct SubspriteTable gUnknown_83E7470[] =
{
- { ARRAY_COUNT(gUnknown_83E7468), gUnknown_83E7468 },
+ { NELEMS(gUnknown_83E7468), gUnknown_83E7468 },
};
static const union AnimCmd gUnknown_83E7478[] =
@@ -588,7 +588,7 @@ void sub_80B4BD0(u8 taskId)
task->data[13] = pan1;
task->data[14] = (pan2 - pan1) / task->data[8];
task->data[1] = var4;
- task->data[15] = GetAnimBattlerSpriteId(0);
+ task->data[15] = GetAnimBattlerSpriteId(ANIM_ATTACKER);
task->func = sub_80B4D00;
}
diff --git a/src/teachy_tv.c b/src/teachy_tv.c
index e33cb9d2e..2720f3204 100644
--- a/src/teachy_tv.c
+++ b/src/teachy_tv.c
@@ -25,11 +25,11 @@
#include "battle_transition.h"
#include "battle_main.h"
#include "battle.h"
+#include "battle_controllers.h"
#include "global.fieldmap.h"
#include "teachy_tv.h"
#include "help_system.h"
#include "overworld.h"
-#include "unk_8159F40.h"
#include "graphics.h"
#include "fieldmap.h"
#include "strings.h"