diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/battle_anim.c | 27 | ||||
-rw-r--r-- | src/battle_anim_80A5C6C.c | 2460 | ||||
-rw-r--r-- | src/battle_anim_80A9C70.c | 360 | ||||
-rw-r--r-- | src/battle_anim_80D51AC.c | 1004 | ||||
-rw-r--r-- | src/battle_anim_sound_tasks.c | 6 | ||||
-rw-r--r-- | src/battle_gfx_sfx_util.c | 12 | ||||
-rw-r--r-- | src/battle_script_commands.c | 25 | ||||
-rw-r--r-- | src/contest.c | 2 | ||||
-rw-r--r-- | src/data/pokemon_graphics/back_pic_coordinates.h | 2 | ||||
-rw-r--r-- | src/intro.c | 101 | ||||
-rw-r--r-- | src/item_menu_icons.c | 24 | ||||
-rw-r--r-- | src/main.c | 2 | ||||
-rw-r--r-- | src/pokeball.c | 14 |
13 files changed, 3929 insertions, 110 deletions
diff --git a/src/battle_anim.c b/src/battle_anim.c index 2d514c955..0a5395b02 100644 --- a/src/battle_anim.c +++ b/src/battle_anim.c @@ -16,9 +16,6 @@ #include "palette.h" #include "main.h" -// sprites start at 10000 and thus must be subtracted of 10000 to account for the true index. -#define GET_TRUE_SPRITE_INDEX(i) ((i - 10000)) - #define ANIM_SPRITE_INDEX_COUNT 8 extern u16 gBattle_WIN0H; @@ -33,8 +30,8 @@ extern struct MusicPlayerInfo gMPlayInfo_BGM; extern struct MusicPlayerInfo gMPlayInfo_SE1; extern struct MusicPlayerInfo gMPlayInfo_SE2; -extern const u16 gUnknown_082C8D64[]; -extern const u8 * const gBattleAnims_Moves[]; +extern const u16 gMovesWithQuietBGM[]; +extern const u8 *const gBattleAnims_Moves[]; extern const struct CompressedSpriteSheet gBattleAnimPicTable[]; extern const struct CompressedSpritePalette gBattleAnimPaletteTable[]; extern const struct BattleAnimBackground gBattleAnimBackgroundTable[]; @@ -110,7 +107,7 @@ EWRAM_DATA bool8 gAnimScriptActive = FALSE; EWRAM_DATA u8 gAnimVisualTaskCount = 0; EWRAM_DATA u8 gAnimSoundTaskCount = 0; EWRAM_DATA struct DisableStruct *gAnimDisableStructPtr = NULL; -EWRAM_DATA u32 gAnimMoveDmg = 0; +EWRAM_DATA s32 gAnimMoveDmg = 0; EWRAM_DATA u16 gAnimMovePower = 0; EWRAM_DATA static u16 sAnimSpriteIndexArray[ANIM_SPRITE_INDEX_COUNT] = {0}; EWRAM_DATA u8 gAnimFriendship = 0; @@ -237,7 +234,7 @@ void LaunchBattleAnimation(const u8 *const animsTable[], u16 tableId, bool8 isMo else { for (i = 0; i < 4; i++) - gAnimBattlerSpecies[i] = gContestResources->field_18->field_0; + gAnimBattlerSpecies[i] = gContestResources->field_18->unk0; } if (!isMoveAnim) @@ -260,9 +257,9 @@ void LaunchBattleAnimation(const u8 *const animsTable[], u16 tableId, bool8 isMo if (isMoveAnim) { - for (i = 0; gUnknown_082C8D64[i] != 0xFFFF; i++) + for (i = 0; gMovesWithQuietBGM[i] != 0xFFFF; i++) { - if (tableId == gUnknown_082C8D64[i]) + if (tableId == gMovesWithQuietBGM[i]) { m4aMPlayVolumeControl(&gMPlayInfo_BGM, 0xFFFF, 128); break; @@ -684,7 +681,7 @@ void sub_80A438C(u8 battlerId, bool8 toBG_2, bool8 setSpriteInvisible) } sub_80A6B30(&unknownStruct); - CpuFill16(0, unknownStruct.unk0, 0x1000); + CpuFill16(0, unknownStruct.bgTiles, 0x1000); CpuFill16(0xFF, unknownStruct.unk4, 0x800); SetAnimBgAttribute(1, BG_ANIM_PRIORITY, 2); @@ -694,7 +691,7 @@ void sub_80A438C(u8 battlerId, bool8 toBG_2, bool8 setSpriteInvisible) battlerSpriteId = gBattlerSpriteIds[battlerId]; gBattle_BG1_X = -(gSprites[battlerSpriteId].pos1.x + gSprites[battlerSpriteId].pos2.x) + 0x20; - if (IsContest() && IsSpeciesNotUnown(gContestResources->field_18->field_0)) + if (IsContest() && IsSpeciesNotUnown(gContestResources->field_18->unk0)) gBattle_BG1_X--; gBattle_BG1_Y = -(gSprites[battlerSpriteId].pos1.y + gSprites[battlerSpriteId].pos2.y) + 0x20; @@ -712,7 +709,7 @@ void sub_80A438C(u8 battlerId, bool8 toBG_2, bool8 setSpriteInvisible) else battlerPosition = GetBattlerPosition(battlerId); - sub_8118FBC(1, 0, 0, battlerPosition, unknownStruct.unk8, unknownStruct.unk0, unknownStruct.unk4, unknownStruct.unkA); + sub_8118FBC(1, 0, 0, battlerPosition, unknownStruct.unk8, unknownStruct.bgTiles, unknownStruct.unk4, unknownStruct.tilesOffset); if (IsContest()) sub_80A46A0(); @@ -722,7 +719,7 @@ void sub_80A438C(u8 battlerId, bool8 toBG_2, bool8 setSpriteInvisible) RequestDma3Fill(0, (void*)(VRAM + 0x6000), 0x2000, 1); RequestDma3Fill(0, (void*)(VRAM + 0xF000), 0x1000, 1); sub_80A6B90(&unknownStruct, 2); - CpuFill16(0, unknownStruct.unk0 + 0x1000, 0x1000); + CpuFill16(0, unknownStruct.bgTiles + 0x1000, 0x1000); CpuFill16(0, unknownStruct.unk4 + 0x400, 0x800); SetAnimBgAttribute(2, BG_ANIM_PRIORITY, 2); SetAnimBgAttribute(2, BG_ANIM_SCREEN_SIZE, 1); @@ -742,7 +739,7 @@ void sub_80A438C(u8 battlerId, bool8 toBG_2, bool8 setSpriteInvisible) LoadPalette(&gPlttBufferUnfaded[0x100 + battlerId * 16], 0x90, 0x20); CpuCopy32(&gPlttBufferUnfaded[0x100 + battlerId * 16], (void*)(BG_PLTT + 0x120), 0x20); - sub_8118FBC(2, 0, 0, GetBattlerPosition(battlerId), unknownStruct.unk8, unknownStruct.unk0 + 0x1000, unknownStruct.unk4 + 0x400, unknownStruct.unkA); + sub_8118FBC(2, 0, 0, GetBattlerPosition(battlerId), unknownStruct.unk8, unknownStruct.bgTiles + 0x1000, unknownStruct.unk4 + 0x400, unknownStruct.tilesOffset); } } @@ -752,7 +749,7 @@ static void sub_80A46A0(void) struct UnknownAnimStruct2 unknownStruct; u16 *ptr; - if (IsSpeciesNotUnown(gContestResources->field_18->field_0)) + if (IsSpeciesNotUnown(gContestResources->field_18->unk0)) { sub_80A6B30(&unknownStruct); ptr = unknownStruct.unk4; diff --git a/src/battle_anim_80A5C6C.c b/src/battle_anim_80A5C6C.c new file mode 100644 index 000000000..f4a4946c3 --- /dev/null +++ b/src/battle_anim_80A5C6C.c @@ -0,0 +1,2460 @@ +#include "global.h" +#include "constants/battle_anim.h" +#include "constants/species.h" +#include "battle.h" +#include "battle_anim.h" +#include "blend_palette.h" +#include "contest.h" +#include "data2.h" +#include "decompress.h" +#include "palette.h" +#include "pokemon_icon.h" +#include "sprite.h" +#include "task.h" +#include "trig.h" +#include "util.h" +#include "gpu_regs.h" +#include "bg.h" +#include "malloc.h" +#include "dma3.h" + +#define GET_UNOWN_LETTER(personality) (( \ + (((personality & 0x03000000) >> 24) << 6) \ + | (((personality & 0x00030000) >> 16) << 4) \ + | (((personality & 0x00000300) >> 8) << 2) \ + | (((personality & 0x00000003) >> 0) << 0) \ +) % 28) + +#define IS_DOUBLE_BATTLE() ((gBattleTypeFlags & BATTLE_TYPE_DOUBLE)) + +extern const struct OamData gUnknown_0852497C; +extern const struct MonCoords gMonFrontPicCoords[]; +extern const struct MonCoords gMonBackPicCoords[]; +extern const u8 gEnemyMonElevation[]; +extern const struct CompressedSpriteSheet gMonFrontPicTable[]; +extern const union AffineAnimCmd *gUnknown_082FF6C0[]; + +// This file's functions. +void sub_80A64EC(struct Sprite *sprite); +void sub_80A653C(struct Sprite *sprite); +void InitAnimLinearTranslation(struct Sprite *sprite); +void sub_80A6FB4(struct Sprite *sprite); +void sub_80A6F98(struct Sprite *sprite); +void sub_80A7144(struct Sprite *sprite); +void sub_80A791C(struct Sprite *sprite); +void sub_80A8DFC(struct Sprite *sprite); +void sub_80A8E88(struct Sprite *sprite); +void sub_80A7E6C(u8 spriteId); +u16 sub_80A7F18(u8 spriteId); +void AnimTask_BlendMonInAndOutSetup(struct Task *task); +void sub_80A7AFC(u8 taskId); +void sub_80A8CAC(u8 taskId); +void AnimTask_BlendMonInAndOutStep(u8 taskId); +bool8 sub_80A7238(void); +void sub_80A8048(s16 *bottom, s16 *top, const void *ptr); +void *sub_80A8050(s16 bottom, s16 top); +u8 sub_80A82E4(u8 battlerId); +void sub_80A8D78(struct Task *task, u8 taskId); + +// EWRAM vars +EWRAM_DATA static union AffineAnimCmd *gUnknown_02038444 = NULL; + +// Const rom data +static const struct UCoords8 sBattlerCoords[][4] = +{ + { + { 72, 80 }, + { 176, 40 }, + { 48, 40 }, + { 112, 80 }, + }, + { + { 32, 80 }, + { 200, 40 }, + { 90, 88 }, + { 152, 32 }, + }, +}; + +// One entry for each of the four Castform forms. +const struct MonCoords gCastformFrontSpriteCoords[] = +{ + { 0x44, 17 }, // NORMAL + { 0x66, 9 }, // SUN + { 0x46, 9 }, // RAIN + { 0x86, 8 }, // HAIL +}; + +static const u8 sCastformElevations[] = +{ + 13, // NORMAL + 14, // SUN + 13, // RAIN + 13, // HAIL +}; + +// Y position of the backsprite for each of the four Castform forms. +static const u8 sCastformBackSpriteYCoords[] = +{ + 0, // NORMAL + 0, // SUN + 0, // RAIN + 0, // HAIL +}; + +static const struct SpriteTemplate sUnknown_08525F90[] = +{ + { + .tileTag = 55125, + .paletteTag = 55125, + .oam = &gUnknown_0852497C, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = SpriteCallbackDummy, + }, + { + .tileTag = 55126, + .paletteTag = 55126, + .oam = &gUnknown_0852497C, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = SpriteCallbackDummy, + } +}; + +static const struct SpriteSheet sUnknown_08525FC0[] = +{ + { gMiscBlank_Gfx, 0x800, 55125, }, + { gMiscBlank_Gfx, 0x800, 55126, }, +}; + +// code +u8 GetBattlerSpriteCoord(u8 battlerId, u8 attributeId) +{ + u8 retVal; + u16 species; + struct BattleSpriteInfo *spriteInfo; + + if (IsContest()) + { + if (attributeId == BATTLER_COORD_3 && battlerId == 3) + attributeId = BATTLER_COORD_Y; + } + + switch (attributeId) + { + case BATTLER_COORD_X: + case BATTLER_COORD_X_2: + retVal = sBattlerCoords[IS_DOUBLE_BATTLE()][GetBattlerPosition(battlerId)].x; + break; + case BATTLER_COORD_Y: + retVal = sBattlerCoords[IS_DOUBLE_BATTLE()][GetBattlerPosition(battlerId)].y; + break; + case BATTLER_COORD_3: + case BATTLER_COORD_4: + default: + if (IsContest()) + { + if (shared19348.unk4_0) + species = shared19348.unk2; + else + species = shared19348.unk0; + } + else + { + if (GetBattlerSide(battlerId) != B_SIDE_PLAYER) + { + spriteInfo = gBattleSpritesDataPtr->battlerData; + if (!spriteInfo[battlerId].transformSpecies) + species = GetMonData(&gEnemyParty[gBattlerPartyIndexes[battlerId]], MON_DATA_SPECIES); + else + species = spriteInfo[battlerId].transformSpecies; + } + else + { + spriteInfo = gBattleSpritesDataPtr->battlerData; + if (!spriteInfo[battlerId].transformSpecies) + species = GetMonData(&gPlayerParty[gBattlerPartyIndexes[battlerId]], MON_DATA_SPECIES); + else + species = spriteInfo[battlerId].transformSpecies; + } + } + if (attributeId == BATTLER_COORD_3) + retVal = GetBattlerSpriteFinal_Y(battlerId, species, TRUE); + else + retVal = GetBattlerSpriteFinal_Y(battlerId, species, FALSE); + break; + } + + return retVal; +} + +u8 GetBattlerYDelta(u8 battlerId, u16 species) +{ + u16 letter; + u32 personality; + struct BattleSpriteInfo *spriteInfo; + u8 ret; + u16 coordSpecies; + + if (GetBattlerSide(battlerId) == B_SIDE_PLAYER || IsContest()) + { + if (species == SPECIES_UNOWN) + { + if (IsContest()) + { + if (shared19348.unk4_0) + personality = shared19348.unk10; + else + personality = shared19348.unk8; + } + else + { + spriteInfo = gBattleSpritesDataPtr->battlerData; + if (!spriteInfo[battlerId].transformSpecies) + personality = GetMonData(&gPlayerParty[gBattlerPartyIndexes[battlerId]], MON_DATA_PERSONALITY); + else + personality = gTransformedPersonalities[battlerId]; + } + letter = GET_UNOWN_LETTER(personality); + if (!letter) + coordSpecies = species; + else + coordSpecies = letter + SPECIES_UNOWN_B - 1; + ret = gMonBackPicCoords[coordSpecies].y_offset; + } + else if (species == SPECIES_CASTFORM) + { + ret = sCastformBackSpriteYCoords[gBattleMonForms[battlerId]]; + } + else if (species > NUM_SPECIES) + { + ret = gMonBackPicCoords[0].y_offset; + } + else + { + ret = gMonBackPicCoords[species].y_offset; + } + } + else + { + if (species == SPECIES_UNOWN) + { + spriteInfo = gBattleSpritesDataPtr->battlerData; + if (!spriteInfo[battlerId].transformSpecies) + personality = GetMonData(&gEnemyParty[gBattlerPartyIndexes[battlerId]], MON_DATA_PERSONALITY); + else + personality = gTransformedPersonalities[battlerId]; + letter = GET_UNOWN_LETTER(personality); + if (!letter) + coordSpecies = species; + else + coordSpecies = letter + SPECIES_UNOWN_B - 1; + ret = gMonFrontPicCoords[coordSpecies].y_offset; + } + else if (species == SPECIES_CASTFORM) + { + ret = gCastformFrontSpriteCoords[gBattleMonForms[battlerId]].y_offset; + } + else if (species > NUM_SPECIES) + { + ret = gMonFrontPicCoords[0].y_offset; + } + else + { + ret = gMonFrontPicCoords[species].y_offset; + } + } + return ret; +} + +u8 GetBattlerElevation(u8 battlerId, u16 species) +{ + u8 ret = 0; + if (GetBattlerSide(battlerId) == B_SIDE_OPPONENT) + { + if (!IsContest()) + { + if (species == SPECIES_CASTFORM) + ret = sCastformElevations[gBattleMonForms[battlerId]]; + else if (species > NUM_SPECIES) + ret = gEnemyMonElevation[0]; + else + ret = gEnemyMonElevation[species]; + } + } + return ret; +} + +u8 GetBattlerSpriteFinal_Y(u8 battlerId, u16 species, bool8 a3) +{ + u16 offset; + u8 y; + + if (GetBattlerSide(battlerId) == B_SIDE_PLAYER || IsContest()) + { + offset = GetBattlerYDelta(battlerId, species); + } + else + { + offset = GetBattlerYDelta(battlerId, species); + offset -= GetBattlerElevation(battlerId, species); + } + y = offset + sBattlerCoords[IS_DOUBLE_BATTLE()][GetBattlerPosition(battlerId)].y; + if (a3) + { + if (GetBattlerSide(battlerId) == B_SIDE_PLAYER) + y += 8; + if (y > 104) + y = 104; + } + return y; +} + +u8 GetBattlerSpriteCoord2(u8 battlerId, u8 attributeId) +{ + u16 species; + struct BattleSpriteInfo *spriteInfo; + + if (attributeId == BATTLER_COORD_3 || attributeId == BATTLER_COORD_4) + { + if (IsContest()) + { + if (shared19348.unk4_0) + species = shared19348.unk2; + else + species = shared19348.unk0; + } + else + { + spriteInfo = gBattleSpritesDataPtr->battlerData; + if (!spriteInfo[battlerId].transformSpecies) + species = gAnimBattlerSpecies[battlerId]; + else + species = spriteInfo[battlerId].transformSpecies; + } + if (attributeId == BATTLER_COORD_3) + return GetBattlerSpriteFinal_Y(battlerId, species, TRUE); + else + return GetBattlerSpriteFinal_Y(battlerId, species, FALSE); + } + else + { + return GetBattlerSpriteCoord(battlerId, attributeId); + } +} + +u8 GetBattlerSpriteDefault_Y(u8 battlerId) +{ + return GetBattlerSpriteCoord(battlerId, BATTLER_COORD_4); +} + +u8 GetSubstituteSpriteDefault_Y(u8 battlerId) +{ + u16 y; + if (GetBattlerSide(battlerId) != B_SIDE_PLAYER) + y = GetBattlerSpriteCoord(battlerId, BATTLER_COORD_Y) + 16; + else + y = GetBattlerSpriteCoord(battlerId, BATTLER_COORD_Y) + 17; + return y; +} + +u8 GetBattlerYCoordWithElevation(u8 battlerId) +{ + u16 species; + u8 y; + struct BattleSpriteInfo *spriteInfo; + + y = GetBattlerSpriteCoord(battlerId, BATTLER_COORD_Y); + if (!IsContest()) + { + if (GetBattlerSide(battlerId) != B_SIDE_PLAYER) + { + spriteInfo = gBattleSpritesDataPtr->battlerData; + if (!spriteInfo[battlerId].transformSpecies) + species = GetMonData(&gEnemyParty[gBattlerPartyIndexes[battlerId]], MON_DATA_SPECIES); + else + species = spriteInfo[battlerId].transformSpecies; + } + else + { + spriteInfo = gBattleSpritesDataPtr->battlerData; + if (!spriteInfo[battlerId].transformSpecies) + species = GetMonData(&gPlayerParty[gBattlerPartyIndexes[battlerId]], MON_DATA_SPECIES); + else + species = spriteInfo[battlerId].transformSpecies; + } + if (GetBattlerSide(battlerId) != B_SIDE_PLAYER) + y -= GetBattlerElevation(battlerId, species); + } + return y; +} + +u8 GetAnimBattlerSpriteId(u8 which) +{ + u8 *sprites; + + if (which == ANIM_ATTACKER) + { + if (IsBattlerSpritePresent(gBattleAnimAttacker)) + { + sprites = gBattlerSpriteIds; + return sprites[gBattleAnimAttacker]; + } + else + { + return 0xff; + } + } + else if (which == ANIM_TARGET) + { + if (IsBattlerSpritePresent(gBattleAnimTarget)) + { + sprites = gBattlerSpriteIds; + return sprites[gBattleAnimTarget]; + } + else + { + return 0xff; + } + } + else if (which == ANIM_ATK_PARTNER) + { + if (!IsBattlerSpriteVisible(BATTLE_PARTNER(gBattleAnimAttacker))) + return 0xff; + else + return gBattlerSpriteIds[BATTLE_PARTNER(gBattleAnimAttacker)]; + } + else + { + if (IsBattlerSpriteVisible(BATTLE_PARTNER(gBattleAnimTarget))) + return gBattlerSpriteIds[BATTLE_PARTNER(gBattleAnimTarget)]; + else + return 0xff; + } +} + +void StoreSpriteCallbackInData6(struct Sprite *sprite, void (*callback)(struct Sprite*)) +{ + sprite->data[6] = (u32)(callback) & 0xffff; + sprite->data[7] = (u32)(callback) >> 16; +} + +void SetCallbackToStoredInData6(struct Sprite *sprite) +{ + u32 callback = (u16)sprite->data[6] | (sprite->data[7] << 16); + sprite->callback = (void (*)(struct Sprite *))callback; +} + +void sub_80A62EC(struct Sprite *sprite) +{ + if (sprite->data[3]) + { + sprite->pos2.x = Sin(sprite->data[0], sprite->data[1]); + sprite->pos2.y = Cos(sprite->data[0], sprite->data[1]); + sprite->data[0] += sprite->data[2]; + if (sprite->data[0] >= 0x100) + sprite->data[0] -= 0x100; + else if (sprite->data[0] < 0) + sprite->data[0] += 0x100; + sprite->data[3]--; + } + else + { + SetCallbackToStoredInData6(sprite); + } +} + +void sub_80A634C(struct Sprite *sprite) +{ + if (sprite->data[3]) + { + sprite->pos2.x = Sin(sprite->data[0], (sprite->data[5] >> 8) + sprite->data[1]); + sprite->pos2.y = Cos(sprite->data[0], (sprite->data[5] >> 8) + sprite->data[1]); + sprite->data[0] += sprite->data[2]; + sprite->data[5] += sprite->data[4]; + if (sprite->data[0] >= 0x100) + sprite->data[0] -= 0x100; + else if (sprite->data[0] < 0) + sprite->data[0] += 0x100; + sprite->data[3]--; + } + else + { + SetCallbackToStoredInData6(sprite); + } +} + +void sub_80A63C8(struct Sprite *sprite) +{ + if (sprite->data[3]) + { + sprite->pos2.x = Sin(sprite->data[0], sprite->data[1]); + sprite->pos2.y = Cos(sprite->data[4], sprite->data[1]); + sprite->data[0] += sprite->data[2]; + sprite->data[4] += sprite->data[5]; + if (sprite->data[0] >= 0x100) + sprite->data[0] -= 0x100; + else if (sprite->data[0] < 0) + sprite->data[0] += 0x100; + if (sprite->data[4] >= 0x100) + sprite->data[4] -= 0x100; + else if (sprite->data[4] < 0) + sprite->data[4] += 0x100; + sprite->data[3]--; + } + else + { + SetCallbackToStoredInData6(sprite); + } +} + +void sub_80A6450(struct Sprite *sprite) +{ + if (sprite->data[3]) + { + sprite->pos2.x = Sin(sprite->data[0], sprite->data[1]); + sprite->pos2.y = Cos(sprite->data[0], sprite->data[4]); + sprite->data[0] += sprite->data[2]; + if (sprite->data[0] >= 0x100) + sprite->data[0] -= 0x100; + else if (sprite->data[0] < 0) + sprite->data[0] += 0x100; + sprite->data[3]--; + } + else + { + SetCallbackToStoredInData6(sprite); + } +} + +// Simply waits until the sprite's data[0] hits zero. +// This is used to let sprite anims or affine anims to run for a designated +// duration. +void sub_80A64B0(struct Sprite *sprite) +{ + if (sprite->data[0] > 0) + sprite->data[0]--; + else + SetCallbackToStoredInData6(sprite); +} + +void sub_80A64D0(struct Sprite *sprite) +{ + sub_80A64EC(sprite); + sprite->callback = sub_80A653C; + sprite->callback(sprite); +} + +void sub_80A64EC(struct Sprite *sprite) +{ + s16 old; + int v1; + + if (sprite->data[1] > sprite->data[2]) + sprite->data[0] = -sprite->data[0]; + v1 = sprite->data[2] - sprite->data[1]; + old = sprite->data[0]; + sprite->data[0] = abs(v1 / sprite->data[0]); + sprite->data[2] = (sprite->data[4] - sprite->data[3]) / sprite->data[0]; + sprite->data[1] = old; +} + +void sub_80A653C(struct Sprite *sprite) +{ + if (sprite->data[0] > 0) + { + sprite->data[0]--; + sprite->pos2.x += sprite->data[1]; + sprite->pos2.y += sprite->data[2]; + } + else + { + SetCallbackToStoredInData6(sprite); + } +} + +void sub_80A656C(struct Sprite *sprite) +{ + if (sprite->data[0] > 0) + { + sprite->data[0]--; + sprite->data[3] += sprite->data[1]; + sprite->data[4] += sprite->data[2]; + sprite->pos2.x = sprite->data[3] >> 8; + sprite->pos2.y = sprite->data[4] >> 8; + } + else + { + SetCallbackToStoredInData6(sprite); + } +} + +void sub_80A65A8(struct Sprite *sprite) +{ + if (sprite->data[0] > 0) + { + sprite->data[0]--; + sprite->data[3] += sprite->data[1]; + sprite->data[4] += sprite->data[2]; + sprite->pos2.x = sprite->data[3] >> 8; + sprite->pos2.y = sprite->data[4] >> 8; + } + else + { + SetCallbackToStoredInData6(sprite); + } + UpdateMonIconFrame(sprite); +} + +void sub_80A65EC(struct Sprite *sprite) +{ + sprite->data[1] = sprite->pos1.x + sprite->pos2.x; + sprite->data[3] = sprite->pos1.y + sprite->pos2.y; + sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimTarget, 2); + sprite->data[4] = GetBattlerSpriteCoord(gBattleAnimTarget, 3); + sprite->callback = sub_80A64D0; +} + +void sub_80A6630(struct Sprite *sprite) +{ + if (sprite->data[0] > 0) + { + sprite->data[0]--; + gSprites[sprite->data[3]].pos2.x += sprite->data[1]; + gSprites[sprite->data[3]].pos2.y += sprite->data[2]; + } + else + { + SetCallbackToStoredInData6(sprite); + } +} + +// Same as sub_80A6630, but it operates on sub-pixel values +// to handle slower translations. +void sub_80A6680(struct Sprite *sprite) +{ + if (sprite->data[0] > 0) + { + sprite->data[0]--; + sprite->data[3] += sprite->data[1]; + sprite->data[4] += sprite->data[2]; + gSprites[sprite->data[5]].pos2.x = sprite->data[3] >> 8; + gSprites[sprite->data[5]].pos2.y = sprite->data[4] >> 8; + } + else + { + SetCallbackToStoredInData6(sprite); + } +} + +void sub_80A66DC(struct Sprite *sprite) +{ + if (sprite->data[0] > 0) + { + sprite->data[0]--; + sprite->pos2.x = sprite->data[2] >> 8; + sprite->data[2] += sprite->data[1]; + sprite->pos2.y = sprite->data[4] >> 8; + sprite->data[4] += sprite->data[3]; + if (sprite->data[0] % sprite->data[5] == 0) + { + if (sprite->data[5]) + sprite->invisible ^= 1; + } + } + else + { + SetCallbackToStoredInData6(sprite); + } +} + +void move_anim_8074EE0(struct Sprite *sprite) +{ + FreeSpriteOamMatrix(sprite); + DestroyAnimSprite(sprite); +} + +void sub_80A6760(struct Sprite *sprite) +{ + sprite->data[1] = sprite->pos1.x + sprite->pos2.x; + sprite->data[3] = sprite->pos1.y + sprite->pos2.y; + sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimAttacker, 2); + sprite->data[4] = GetBattlerSpriteCoord(gBattleAnimAttacker, 3); + sprite->callback = sub_80A64D0; +} + +void sub_80A67A4(struct Sprite *sprite) +{ + ResetPaletteStructByUid(sprite->data[5]); + move_anim_8074EE0(sprite); +} + +void sub_80A67BC(struct Sprite *sprite) +{ + if (sprite->affineAnimEnded) + SetCallbackToStoredInData6(sprite); +} + +void sub_80A67D8(struct Sprite *sprite) +{ + if (sprite->animEnded) + SetCallbackToStoredInData6(sprite); +} + +void sub_80A67F4(struct Sprite *sprite) +{ + SetGpuReg(REG_OFFSET_BLDCNT, 0); + SetGpuReg(REG_OFFSET_BLDALPHA, 0); + DestroyAnimSprite(sprite); +} + +void sub_80A6814(u8 taskId) +{ + SetGpuReg(REG_OFFSET_BLDCNT, 0); + SetGpuReg(REG_OFFSET_BLDALPHA, 0); + DestroyAnimVisualTask(taskId); +} + +void sub_80A6838(struct Sprite *sprite) +{ + sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimAttacker, 2); + sprite->pos1.y = GetBattlerSpriteCoord(gBattleAnimAttacker, 3); +} + +void sub_80A6864(struct Sprite *sprite, s16 a2) +{ + u16 v1 = GetBattlerSpriteCoord(gBattleAnimAttacker, 0); + u16 v2 = GetBattlerSpriteCoord(gBattleAnimTarget, 0); + + if (v1 > v2) + { + sprite->pos1.x -= a2; + } + else if (v1 < v2) + { + sprite->pos1.x += a2; + } + else + { + if (GetBattlerSide(gBattleAnimAttacker) != 0) + sprite->pos1.x -= a2; + else + sprite->pos1.x += a2; + } +} + +void sub_80A68D4(struct Sprite *sprite) +{ + sprite->data[1] = sprite->pos1.x; + sprite->data[3] = sprite->pos1.y; + InitAnimLinearTranslation(sprite); + sprite->data[6] = 0x8000 / sprite->data[0]; + sprite->data[7] = 0; +} + +bool8 TranslateAnimArc(struct Sprite *sprite) +{ + if (TranslateAnimLinear(sprite)) + return TRUE; + sprite->data[7] += sprite->data[6]; + sprite->pos2.y += Sin((u8)(sprite->data[7] >> 8), sprite->data[5]); + return FALSE; +} + +bool8 sub_80A6934(struct Sprite *sprite) +{ + if (TranslateAnimLinear(sprite)) + return TRUE; + sprite->data[7] += sprite->data[6]; + sprite->pos2.x += Sin((u8)(sprite->data[7] >> 8), sprite->data[5]); + return FALSE; +} + +void oamt_add_pos2_onto_pos1(struct Sprite *sprite) +{ + sprite->pos1.x += sprite->pos2.x; + sprite->pos1.y += sprite->pos2.y; + sprite->pos2.x = 0; + sprite->pos2.y = 0; +} + +void sub_80A6980(struct Sprite *sprite, bool8 a2) +{ + if (!a2) + { + sprite->pos1.x = GetBattlerSpriteCoord2(gBattleAnimTarget, 0); + sprite->pos1.y = GetBattlerSpriteCoord2(gBattleAnimTarget, 1); + } + sub_80A6864(sprite, gBattleAnimArgs[0]); + sprite->pos1.y += gBattleAnimArgs[1]; +} + +void sub_80A69CC(struct Sprite *sprite, u8 a2) +{ + if (!a2) + { + sprite->pos1.x = GetBattlerSpriteCoord2(gBattleAnimAttacker, 0); + sprite->pos1.y = GetBattlerSpriteCoord2(gBattleAnimAttacker, 1); + } + else + { + sprite->pos1.x = GetBattlerSpriteCoord2(gBattleAnimAttacker, 2); + sprite->pos1.y = GetBattlerSpriteCoord2(gBattleAnimAttacker, 3); + } + sub_80A6864(sprite, gBattleAnimArgs[0]); + sprite->pos1.y += gBattleAnimArgs[1]; +} + +u8 GetBattlerSide(u8 battlerId) +{ + return GET_BATTLER_SIDE2(battlerId); +} + +u8 GetBattlerPosition(u8 battlerId) +{ + return GET_BATTLER_POSITION(battlerId); +} + +u8 GetBattlerAtPosition(u8 position) +{ + u8 i; + + for (i = 0; i < gBattlersCount; i++) + { + if (gBattlerPositions[i] == position) + break; + } + return i; +} + +bool8 IsBattlerSpritePresent(u8 battlerId) +{ + if (IsContest()) + { + if (gBattleAnimAttacker == battlerId) + return TRUE; + else if (gBattleAnimTarget == battlerId) + return TRUE; + else + return FALSE; + } + else + { + if (gBattlerPositions[battlerId] == 0xff) + { + return FALSE; + } + else if (GetBattlerSide(battlerId) != B_SIDE_PLAYER) + { + if (GetMonData(&gEnemyParty[gBattlerPartyIndexes[battlerId]], MON_DATA_HP) != 0) + return TRUE; + } + else + { + if (GetMonData(&gPlayerParty[gBattlerPartyIndexes[battlerId]], MON_DATA_HP) != 0) + return TRUE; + } + } + return FALSE; +} + +bool8 IsDoubleBattle() +{ + return IS_DOUBLE_BATTLE(); +} + +void sub_80A6B30(struct UnknownAnimStruct2 *unk) +{ + if (IsContest()) + { + unk->bgTiles = gUnknown_0202305C; + unk->unk4 = (u16 *)gUnknown_02023060; + unk->unk8 = 0xe; + unk->bgId = 1; + unk->tilesOffset = 0; + unk->unkC = 0; + } + else + { + unk->bgTiles = gUnknown_0202305C; + unk->unk4 = (u16 *)gUnknown_02023060; + unk->unk8 = 0x8; + unk->bgId = 1; + unk->tilesOffset = 0x200; + unk->unkC = 0; + } +} + +void sub_80A6B90(struct UnknownAnimStruct2 *unk, u32 arg1) +{ + if (IsContest()) + { + unk->bgTiles = gUnknown_0202305C; + unk->unk4 = (u16 *)gUnknown_02023060; + unk->unk8 = 0xe; + unk->bgId = 1; + unk->tilesOffset = 0; + unk->unkC = 0; + } + else if (arg1 == 1) + { + sub_80A6B30(unk); + } + else + { + unk->bgTiles = gUnknown_0202305C; + unk->unk4 = (u16 *)gUnknown_02023060; + unk->unk8 = 0x9; + unk->bgId = 2; + unk->tilesOffset = 0x300; + unk->unkC = 0; + } +} + +void sub_80A6BFC(struct UnknownAnimStruct2 *unk) +{ + unk->bgTiles = gUnknown_0202305C; + unk->unk4 = (u16 *)gUnknown_02023060; + if (IsContest()) + { + unk->unk8 = 0xe; + unk->bgId = 1; + unk->tilesOffset = 0; + unk->unkC = 0; + } + else if (sub_80A8364(gBattleAnimAttacker) == 1) + { + unk->unk8 = 8; + unk->bgId = 1; + unk->tilesOffset = 0x200; + unk->unkC = 0; + } + else + { + unk->unk8 = 0x9; + unk->bgId = 2; + unk->tilesOffset = 0x300; + unk->unkC = 0; + } +} + +void sub_80A6C68(u32 arg0) +{ + struct UnknownAnimStruct2 unkStruct; + + sub_80A6B90(&unkStruct, arg0); + CpuFill32(0, unkStruct.bgTiles, 0x2000); + LoadBgTiles(unkStruct.bgId, unkStruct.bgTiles, 0x2000, unkStruct.tilesOffset); + FillBgTilemapBufferRect(unkStruct.bgId, 0, 0, 0, 0x20, 0x40, 0x11); + CopyBgTilemapBufferToVram(unkStruct.bgId); +} + +void sub_80A6CC0(u32 bgId, void *src, u32 tilesOffset) +{ + CpuFill32(0, gUnknown_0202305C, 0x2000); + LZDecompressWram(src, gUnknown_0202305C); + LoadBgTiles(bgId, gUnknown_0202305C, 0x2000, tilesOffset); +} + +void sub_80A6D10(u32 bgId, const void *src) +{ + FillBgTilemapBufferRect(bgId, 0, 0, 0, 0x20, 0x40, 0x11); + CopyToBgTilemapBuffer(bgId, src, 0, 0); +} + +void sub_80A6D48(u32 bgId, const void *src) +{ + sub_80A6D10(bgId, src); + CopyBgTilemapBufferToVram(bgId); +} + +void sub_80A6D60(struct UnknownAnimStruct2 *unk, const void *src, u32 arg2) +{ + sub_80A6D10(unk->bgId, src); + if (IsContest() == TRUE) + sub_80A4720(unk->unk8, unk->unk4, 0, arg2); + CopyBgTilemapBufferToVram(unk->bgId); +} + +u8 sub_80A6D94(void) +{ + if (IsContest()) + return 1; + else + return 2; +} + +void sub_80A6DAC(bool8 arg0) +{ + if (!arg0 || IsContest()) + { + SetAnimBgAttribute(3, BG_ANIM_SCREEN_SIZE, 0); + SetAnimBgAttribute(3, BG_ANIM_AREA_OVERFLOW_MODE, 1); + } + else + { + SetAnimBgAttribute(3, BG_ANIM_SCREEN_SIZE, 1); + SetAnimBgAttribute(3, BG_ANIM_AREA_OVERFLOW_MODE, 0); + } +} + +void sub_80A6DEC(struct Sprite *sprite) +{ + sprite->data[1] = sprite->pos1.x; + sprite->data[3] = sprite->pos1.y; + sub_80A6E14(sprite); + sprite->callback = sub_80A65A8; + sprite->callback(sprite); +} + +void sub_80A6E14(struct Sprite *sprite) +{ + s16 x = (sprite->data[2] - sprite->data[1]) << 8; + s16 y = (sprite->data[4] - sprite->data[3]) << 8; + sprite->data[1] = x / sprite->data[0]; + sprite->data[2] = y / sprite->data[0]; + sprite->data[4] = 0; + sprite->data[3] = 0; +} + +void InitAnimLinearTranslation(struct Sprite *sprite) +{ + int x = sprite->data[2] - sprite->data[1]; + int y = sprite->data[4] - sprite->data[3]; + bool8 movingLeft = x < 0; + bool8 movingUp = y < 0; + u16 xDelta = abs(x) << 8; + u16 yDelta = abs(y) << 8; + + xDelta = xDelta / sprite->data[0]; + yDelta = yDelta / sprite->data[0]; + + if (movingLeft) + xDelta |= 1; + else + xDelta &= ~1; + + if (movingUp) + yDelta |= 1; + else + yDelta &= ~1; + + sprite->data[1] = xDelta; + sprite->data[2] = yDelta; + sprite->data[4] = 0; + sprite->data[3] = 0; +} + +void sub_80A6EEC(struct Sprite *sprite) +{ + sprite->data[1] = sprite->pos1.x; + sprite->data[3] = sprite->pos1.y; + InitAnimLinearTranslation(sprite); + sprite->callback = sub_80A6F98; + sprite->callback(sprite); +} + +void sub_80A6F14(struct Sprite *sprite) +{ + sprite->data[1] = sprite->pos1.x; + sprite->data[3] = sprite->pos1.y; + InitAnimLinearTranslation(sprite); + sprite->callback = sub_80A6FB4; + sprite->callback(sprite); +} + +bool8 TranslateAnimLinear(struct Sprite *sprite) +{ + u16 v1, v2, x, y; + + if (!sprite->data[0]) + return TRUE; + + v1 = sprite->data[1]; + v2 = sprite->data[2]; + x = sprite->data[3]; + y = sprite->data[4]; + x += v1; + y += v2; + + if (v1 & 1) + sprite->pos2.x = -(x >> 8); + else + sprite->pos2.x = x >> 8; + + if (v2 & 1) + sprite->pos2.y = -(y >> 8); + else + sprite->pos2.y = y >> 8; + + sprite->data[3] = x; + sprite->data[4] = y; + sprite->data[0]--; + return FALSE; +} + +void sub_80A6F98(struct Sprite *sprite) +{ + if (TranslateAnimLinear(sprite)) + SetCallbackToStoredInData6(sprite); +} + +void sub_80A6FB4(struct Sprite *sprite) +{ + sub_8039E9C(sprite); + if (TranslateAnimLinear(sprite)) + SetCallbackToStoredInData6(sprite); +} + +void sub_80A6FD4(struct Sprite *sprite) +{ + int v1 = abs(sprite->data[2] - sprite->data[1]) << 8; + sprite->data[0] = v1 / sprite->data[0]; + InitAnimLinearTranslation(sprite); +} + +void sub_80A7000(struct Sprite *sprite) +{ + sprite->data[1] = sprite->pos1.x; + sprite->data[3] = sprite->pos1.y; + sub_80A6FD4(sprite); + sprite->callback = sub_80A6F98; + sprite->callback(sprite); +} + +void sub_80A7028(struct Sprite *sprite) +{ + int x = sprite->data[2] - sprite->data[1]; + int y = sprite->data[4] - sprite->data[3]; + bool8 x_sign = x < 0; + bool8 y_sign = y < 0; + u16 x2 = abs(x) << 4; + u16 y2 = abs(y) << 4; + + x2 /= sprite->data[0]; + y2 /= sprite->data[0]; + + if (x_sign) + x2 |= 1; + else + x2 &= ~1; + + if (y_sign) + y2 |= 1; + else + y2 &= ~1; + + sprite->data[1] = x2; + sprite->data[2] = y2; + sprite->data[4] = 0; + sprite->data[3] = 0; +} + +void sub_80A70C0(struct Sprite *sprite) +{ + sprite->data[1] = sprite->pos1.x; + sprite->data[3] = sprite->pos1.y; + sub_80A7028(sprite); + sprite->callback = sub_80A7144; + sprite->callback(sprite); +} + +bool8 sub_80A70E8(struct Sprite *sprite) +{ + u16 v1, v2, x, y; + + if (!sprite->data[0]) + return TRUE; + + v1 = sprite->data[1]; + v2 = sprite->data[2]; + x = sprite->data[3]; + y = sprite->data[4]; + x += v1; + y += v2; + + if (v1 & 1) + sprite->pos2.x = -(x >> 4); + else + sprite->pos2.x = x >> 4; + + if (v2 & 1) + sprite->pos2.y = -(y >> 4); + else + sprite->pos2.y = y >> 4; + + sprite->data[3] = x; + sprite->data[4] = y; + sprite->data[0]--; + return FALSE; +} + +void sub_80A7144(struct Sprite *sprite) +{ + if (sub_80A70E8(sprite)) + SetCallbackToStoredInData6(sprite); +} + +void sub_80A7160(struct Sprite *sprite) +{ + int v1 = abs(sprite->data[2] - sprite->data[1]) << 4; + sprite->data[0] = v1 / sprite->data[0]; + sub_80A7028(sprite); +} + +void sub_80A718C(struct Sprite *sprite) +{ + sprite->data[1] = sprite->pos1.x; + sprite->data[3] = sprite->pos1.y; + sub_80A7160(sprite); + sprite->callback = sub_80A7144; + sprite->callback(sprite); +} + +void obj_id_set_rotscale(u8 spriteId, s16 xScale, s16 yScale, u16 rotation) +{ + int i; + struct ObjAffineSrcData src; + struct OamMatrix matrix; + + src.xScale = xScale; + src.yScale = yScale; + src.rotation = rotation; + if (sub_80A7238()) + src.xScale = -src.xScale; + i = gSprites[spriteId].oam.matrixNum; + ObjAffineSet(&src, &matrix, 1, 2); + gOamMatrices[i].a = matrix.a; + gOamMatrices[i].b = matrix.b; + gOamMatrices[i].c = matrix.c; + gOamMatrices[i].d = matrix.d; +} + +bool8 sub_80A7238(void) +{ + if (IsContest()) + { + if (gSprites[GetAnimBattlerSpriteId(ANIM_ATTACKER)].data[2] == SPECIES_UNOWN) + return FALSE; + else + return TRUE; + } + else + { + return FALSE; + } +} + +void sub_80A7270(u8 spriteId, u8 objMode) +{ + u8 battlerId = gSprites[spriteId].data[0]; + + if (IsContest() || IsBattlerSpriteVisible(battlerId)) + gSprites[spriteId].invisible = FALSE; + gSprites[spriteId].oam.objMode = objMode; + gSprites[spriteId].affineAnimPaused = TRUE; + if (!IsContest() && !gSprites[spriteId].oam.affineMode) + gSprites[spriteId].oam.matrixNum = gBattleSpritesDataPtr->healthBoxesData[battlerId].field_6; + gSprites[spriteId].oam.affineMode = 3; + CalcCenterToCornerVec(&gSprites[spriteId], gSprites[spriteId].oam.shape, gSprites[spriteId].oam.size, gSprites[spriteId].oam.affineMode); +} + +void sub_80A7344(u8 spriteId) +{ + obj_id_set_rotscale(spriteId, 0x100, 0x100, 0); + gSprites[spriteId].oam.affineMode = 1; + gSprites[spriteId].oam.objMode = 0; + gSprites[spriteId].affineAnimPaused = FALSE; + CalcCenterToCornerVec(&gSprites[spriteId], gSprites[spriteId].oam.shape, gSprites[spriteId].oam.size, gSprites[spriteId].oam.affineMode); +} + +void sub_80A73A0(u8 spriteId) +{ + u16 matrix = gSprites[spriteId].oam.matrixNum; + s16 c = gOamMatrices[matrix].c; + + if (c < 0) + c = -c; + gSprites[spriteId].pos2.y = c >> 3; +} + +// related to obj_id_set_rotscale +void sub_80A73E0(struct Sprite *sprite, bool8 a2, s16 xScale, s16 yScale, u16 rotation) +{ + int i; + struct ObjAffineSrcData src; + struct OamMatrix matrix; + + if (sprite->oam.affineMode & 1) + { + sprite->affineAnimPaused = TRUE; + if (a2) + CalcCenterToCornerVec(sprite, sprite->oam.shape, sprite->oam.size, sprite->oam.affineMode); + src.xScale = xScale; + src.yScale = yScale; + src.rotation = rotation; + if (sub_80A7238()) + src.xScale = -src.xScale; + i = sprite->oam.matrixNum; + ObjAffineSet(&src, &matrix, 1, 2); + gOamMatrices[i].a = matrix.a; + gOamMatrices[i].b = matrix.b; + gOamMatrices[i].c = matrix.c; + gOamMatrices[i].d = matrix.d; + } +} + +void sub_80A749C(struct Sprite *sprite) +{ + sub_80A73E0(sprite, TRUE, 0x100, 0x100, 0); + sprite->affineAnimPaused = FALSE; + CalcCenterToCornerVec(sprite, sprite->oam.shape, sprite->oam.size, sprite->oam.affineMode); +} + +static u16 ArcTan2_(s16 a, s16 b) +{ + return ArcTan2(a, b); +} + +u16 ArcTan2Neg(s16 a, s16 b) +{ + u16 var = ArcTan2_(a, b); + return -var; +} + +void sub_80A750C(u16 a1, bool8 a2) +{ + int i; + struct PlttData *c; + struct PlttData *c2; + u16 average; + + a1 *= 0x10; + + if (!a2) + { + for (i = 0; i < 0x10; i++) + { + c = (struct PlttData *)&gPlttBufferUnfaded[a1 + i]; + average = c->r + c->g + c->b; + average /= 3; + + c2 = (struct PlttData *)&gPlttBufferFaded[a1 + i]; + c2->r = average; + c2->g = average; + c2->b = average; + } + } + else + { + CpuCopy32(&gPlttBufferUnfaded[a1], &gPlttBufferFaded[a1], 0x20); + } +} + +u32 sub_80A75AC(u8 a1, u8 a2, u8 a3, u8 a4, u8 a5, u8 a6, u8 a7) +{ + u32 var = 0; + u32 shift; + + if (a1) + { + if (!IsContest()) + var = 0xe; + else + var = 1 << sub_80A6D94(); + } + if (a2) + { + shift = gBattleAnimAttacker + 16; + var |= 1 << shift; + } + if (a3) { + shift = gBattleAnimTarget + 16; + var |= 1 << shift; + } + if (a4) + { + if (IsBattlerSpriteVisible(gBattleAnimAttacker ^ 2)) + { + shift = (gBattleAnimAttacker ^ 2) + 16; + var |= 1 << shift; + } + } + if (a5) + { + if (IsBattlerSpriteVisible(gBattleAnimTarget ^ 2)) + { + shift = (gBattleAnimTarget ^ 2) + 16; + var |= 1 << shift; + } + } + if (a6) + { + if (!IsContest()) + var |= 0x100; + else + var |= 0x4000; + } + if (a7) + { + if (!IsContest()) + var |= 0x200; + } + return var; +} + +u32 sub_80A76C4(u8 a1, u8 a2, u8 a3, u8 a4) +{ + u32 var = 0; + u32 shift; + + if (IsContest()) + { + if (a1) + { + var |= 1 << 18; + return var; + } + } + else + { + if (a1) + { + if (IsBattlerSpriteVisible(GetBattlerAtPosition(B_POSITION_PLAYER_LEFT))) + { + var |= 1 << (GetBattlerAtPosition(B_POSITION_PLAYER_LEFT) + 16); + } + } + if (a2) + { + if (IsBattlerSpriteVisible(GetBattlerAtPosition(B_POSITION_PLAYER_RIGHT))) + { + shift = GetBattlerAtPosition(B_POSITION_PLAYER_RIGHT) + 16; + var |= 1 << shift; + } + } + if (a3) + { + if (IsBattlerSpriteVisible(GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT))) + { + shift = GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT) + 16; + var |= 1 << shift; + } + } + if (a4) + { + if (IsBattlerSpriteVisible(GetBattlerAtPosition(B_POSITION_OPPONENT_RIGHT))) + { + shift = GetBattlerAtPosition(B_POSITION_OPPONENT_RIGHT) + 16; + var |= 1 << shift; + } + } + } + return var; +} + +u8 sub_80A77AC(u8 a1) +{ + return a1; +} + +u8 sub_80A77B4(u8 position) +{ + return GetBattlerAtPosition(position); +} + +void sub_80A77C8(struct Sprite *sprite) +{ + bool8 var; + + if (!sprite->data[0]) + { + if (!gBattleAnimArgs[3]) + var = TRUE; + else + var = FALSE; + if (!gBattleAnimArgs[2]) + sub_80A69CC(sprite, var); + else + sub_80A6980(sprite, var); + sprite->data[0]++; + + } + else if (sprite->animEnded || sprite->affineAnimEnded) + { + move_anim_8074EE0(sprite); + } +} + +// Linearly translates a sprite to a target position on the +// other mon's sprite. +// arg 0: initial x offset +// arg 1: initial y offset +// arg 2: target x offset +// arg 3: target y offset +// arg 4: duration +// arg 5: lower 8 bits = location on attacking mon, upper 8 bits = location on target mon pick to target +void TranslateAnimSpriteToTargetMonLocation(struct Sprite *sprite) +{ + bool8 v1; + u8 attributeId; + + if (!(gBattleAnimArgs[5] & 0xff00)) + v1 = TRUE; + else + v1 = FALSE; + + if (!(gBattleAnimArgs[5] & 0xff)) + attributeId = BATTLER_COORD_3; + else + attributeId = BATTLER_COORD_Y; + + sub_80A69CC(sprite, v1); + 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]; + sprite->data[4] = GetBattlerSpriteCoord(gBattleAnimTarget, attributeId) + gBattleAnimArgs[3]; + sprite->callback = sub_80A6EEC; + StoreSpriteCallbackInData6(sprite, DestroyAnimSprite); +} + +void sub_80A78AC(struct Sprite *sprite) +{ + sub_80A69CC(sprite, 1); + if (GetBattlerSide(gBattleAnimAttacker)) + gBattleAnimArgs[2] = -gBattleAnimArgs[2]; + sprite->data[0] = gBattleAnimArgs[4]; + sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimTarget, 2) + gBattleAnimArgs[2]; + sprite->data[4] = GetBattlerSpriteCoord(gBattleAnimTarget, 3) + gBattleAnimArgs[3]; + sprite->data[5] = gBattleAnimArgs[5]; + sub_80A68D4(sprite); + sprite->callback = sub_80A791C; +} + +void sub_80A791C(struct Sprite *sprite) +{ + if (TranslateAnimArc(sprite)) + DestroyAnimSprite(sprite); +} + +void sub_80A7938(struct Sprite *sprite) +{ + bool8 r4; + u8 battlerId, attributeId; + + if (!gBattleAnimArgs[6]) + { + r4 = TRUE; + attributeId = BATTLER_COORD_3; + } + else + { + r4 = FALSE; + attributeId = BATTLER_COORD_Y; + } + if (!gBattleAnimArgs[5]) + { + sub_80A69CC(sprite, r4); + battlerId = gBattleAnimAttacker; + } + else + { + sub_80A6980(sprite, r4); + battlerId = gBattleAnimTarget; + } + if (GetBattlerSide(gBattleAnimAttacker)) + gBattleAnimArgs[2] = -gBattleAnimArgs[2]; + sub_80A6980(sprite, r4); + sprite->data[0] = gBattleAnimArgs[4]; + sprite->data[2] = GetBattlerSpriteCoord(battlerId, BATTLER_COORD_X_2) + gBattleAnimArgs[2]; + sprite->data[4] = GetBattlerSpriteCoord(battlerId, attributeId) + gBattleAnimArgs[3]; + sprite->callback = sub_80A6EEC; + StoreSpriteCallbackInData6(sprite, DestroyAnimSprite); +} + +s16 duplicate_obj_of_side_rel2move_in_transparent_mode(u8 whichBattler) +{ + u16 i; + u8 spriteId = GetAnimBattlerSpriteId(whichBattler); + + if (spriteId != 0xff) + { + for (i = 0; i < MAX_SPRITES; i++) + { + if (!gSprites[i].inUse) + { + gSprites[i] = gSprites[spriteId]; + gSprites[i].oam.objMode = 1; + gSprites[i].invisible = FALSE; + return i; + } + } + } + return -1; +} + +void obj_delete_but_dont_free_vram(struct Sprite *sprite) +{ + sprite->usingSheet = TRUE; + DestroySprite(sprite); +} + +void sub_80A7A74(u8 taskId) +{ + s16 v1 = 0; + s16 v2 = 0; + + if (gBattleAnimArgs[2] > gBattleAnimArgs[0]) + v2 = 1; + if (gBattleAnimArgs[2] < gBattleAnimArgs[0]) + v2 = -1; + if (gBattleAnimArgs[3] > gBattleAnimArgs[1]) + v1 = 1; + if (gBattleAnimArgs[3] < gBattleAnimArgs[1]) + v1 = -1; + + gTasks[taskId].data[0] = 0; + gTasks[taskId].data[1] = gBattleAnimArgs[4]; + gTasks[taskId].data[2] = 0; + gTasks[taskId].data[3] = gBattleAnimArgs[0]; + gTasks[taskId].data[4] = gBattleAnimArgs[1]; + gTasks[taskId].data[5] = v2; + gTasks[taskId].data[6] = v1; + gTasks[taskId].data[7] = gBattleAnimArgs[2]; + gTasks[taskId].data[8] = gBattleAnimArgs[3]; + SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(gBattleAnimArgs[0], gBattleAnimArgs[1])); + gTasks[taskId].func = sub_80A7AFC; +} + +void sub_80A7AFC(u8 taskId) +{ + struct Task *task = &gTasks[taskId]; + + if (++task->data[0] > task->data[1]) + { + task->data[0] = 0; + if (++task->data[2] & 1) + { + if (task->data[3] != task->data[7]) + task->data[3] += task->data[5]; + } + else + { + if (task->data[4] != task->data[8]) + task->data[4] += task->data[6]; + } + SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(task->data[3], task->data[4])); + if (task->data[3] == task->data[7] && task->data[4] == task->data[8]) + { + DestroyAnimVisualTask(taskId); + return; + } + } +} + +// Linearly blends a mon's sprite colors with a target color with increasing +// strength, and then blends out to the original color. +// arg 0: anim bank +// arg 1: blend color +// arg 2: target blend coefficient +// arg 3: initial delay +// arg 4: number of times to blend in and out +void AnimTask_BlendMonInAndOut(u8 task) +{ + u8 spriteId = GetAnimBattlerSpriteId(gBattleAnimArgs[0]); + if (spriteId == 0xff) + { + DestroyAnimVisualTask(task); + return; + } + gTasks[task].data[0] = (gSprites[spriteId].oam.paletteNum * 0x10) + 0x101; + AnimTask_BlendMonInAndOutSetup(&gTasks[task]); +} + +void AnimTask_BlendMonInAndOutSetup(struct Task *task) +{ + task->data[1] = gBattleAnimArgs[1]; + task->data[2] = 0; + task->data[3] = gBattleAnimArgs[2]; + task->data[4] = 0; + task->data[5] = gBattleAnimArgs[3]; + task->data[6] = 0; + task->data[7] = gBattleAnimArgs[4]; + task->func = AnimTask_BlendMonInAndOutStep; +} + +void AnimTask_BlendMonInAndOutStep(u8 taskId) +{ + struct Task *task = &gTasks[taskId]; + + if (++task->data[4] >= task->data[5]) + { + task->data[4] = 0; + if (!task->data[6]) + { + task->data[2]++; + BlendPalette(task->data[0], 15, task->data[2], task->data[1]); + if (task->data[2] == task->data[3]) + task->data[6] = 1; + } + else + { + task->data[2]--; + BlendPalette(task->data[0], 15, task->data[2], task->data[1]); + if (!task->data[2]) + { + if (--task->data[7]) + { + task->data[4] = 0; + task->data[6] = 0; + } + else + { + DestroyAnimVisualTask(taskId); + return; + } + } + } + } +} + +void sub_80A7CB4(u8 task) +{ + u8 palette = IndexOfSpritePaletteTag(gBattleAnimArgs[0]); + + if (palette == 0xff) + { + DestroyAnimVisualTask(task); + return; + } + gTasks[task].data[0] = (palette * 0x10) + 0x101; + AnimTask_BlendMonInAndOutSetup(&gTasks[task]); +} + +void sub_80A7CFC(struct Task *task, u8 a2, const void *a3) +{ + task->data[7] = 0; + task->data[8] = 0; + task->data[9] = 0; + task->data[15] = a2; + task->data[10] = 0x100; + task->data[11] = 0x100; + task->data[12] = 0; + sub_80A8048(&task->data[13], &task->data[14], a3); + sub_80A7270(a2, 0); +} + +bool8 sub_80A7D34(struct Task *task) +{ + gUnknown_02038444 = sub_80A8050(task->data[13], task->data[14]) + (task->data[7] << 3); + switch (gUnknown_02038444->type) + { + default: + if (!gUnknown_02038444->frame.duration) + { + task->data[10] = gUnknown_02038444->frame.xScale; + task->data[11] = gUnknown_02038444->frame.yScale; + task->data[12] = gUnknown_02038444->frame.rotation; + task->data[7]++; + gUnknown_02038444++; + } + task->data[10] += gUnknown_02038444->frame.xScale; + task->data[11] += gUnknown_02038444->frame.yScale; + task->data[12] += gUnknown_02038444->frame.rotation; + obj_id_set_rotscale(task->data[15], task->data[10], task->data[11], task->data[12]); + sub_80A7E6C(task->data[15]); + if (++task->data[8] >= gUnknown_02038444->frame.duration) + { + task->data[8] = 0; + task->data[7]++; + } + break; + case AFFINEANIMCMDTYPE_JUMP: + task->data[7] = gUnknown_02038444->jump.target; + break; + case AFFINEANIMCMDTYPE_LOOP: + if (gUnknown_02038444->loop.count) + { + if (task->data[9]) + { + if (!--task->data[9]) + { + task->data[7]++; + break; + } + } + else + { + task->data[9] = gUnknown_02038444->loop.count; + } + if (!task->data[7]) + { + break; + } + for (;;) + { + task->data[7]--; + gUnknown_02038444--; + if (gUnknown_02038444->type == AFFINEANIMCMDTYPE_LOOP) + { + task->data[7]++; + return TRUE; + } + if (!task->data[7]) + return TRUE; + } + } + task->data[7]++; + break; + case AFFINEANIMCMDTYPE_END: + gSprites[task->data[15]].pos2.y = 0; + sub_80A7344(task->data[15]); + return FALSE; + } + + return TRUE; +} + +void sub_80A7E6C(u8 spriteId) +{ + int var = 0x40 - sub_80A7F18(spriteId) * 2; + u16 matrix = gSprites[spriteId].oam.matrixNum; + int var2 = (var << 8) / gOamMatrices[matrix].d; + + if (var2 > 0x80) + var2 = 0x80; + gSprites[spriteId].pos2.y = (var - var2) / 2; +} + +void sub_80A7EC0(u8 spriteId, u8 spriteId2) +{ + int var = 0x40 - sub_80A7F18(spriteId2) * 2; + u16 matrix = gSprites[spriteId].oam.matrixNum; + int var2 = (var << 8) / gOamMatrices[matrix].d; + + if (var2 > 0x80) + var2 = 0x80; + gSprites[spriteId].pos2.y = (var - var2) / 2; +} + +u16 sub_80A7F18(u8 spriteId) +{ + struct BattleSpriteInfo *spriteInfo; + u8 battlerId = gSprites[spriteId].data[0]; + u16 species; + u16 i; + + for (i = 0; i < MAX_BATTLERS_COUNT; i++) + { + if (gBattlerSpriteIds[i] == spriteId) + { + if (IsContest()) + { + species = shared19348.unk0; + return gMonBackPicCoords[species].y_offset; + } + else + { + if (GetBattlerSide(i) == B_SIDE_PLAYER) + { + spriteInfo = gBattleSpritesDataPtr->battlerData; + if (!spriteInfo[battlerId].transformSpecies) + species = GetMonData(&gPlayerParty[gBattlerPartyIndexes[i]], MON_DATA_SPECIES); + else + species = spriteInfo[battlerId].transformSpecies; + + if (species == SPECIES_CASTFORM) + return sCastformBackSpriteYCoords[gBattleMonForms[battlerId]]; + else + return gMonBackPicCoords[species].y_offset; + } + else + { + spriteInfo = gBattleSpritesDataPtr->battlerData; + if (!spriteInfo[battlerId].transformSpecies) + species = GetMonData(&gEnemyParty[gBattlerPartyIndexes[i]], MON_DATA_SPECIES); + else + species = spriteInfo[battlerId].transformSpecies; + + if (species == SPECIES_CASTFORM) + return sCastformElevations[gBattleMonForms[battlerId]]; + else + return gMonFrontPicCoords[species].y_offset; + } + } + } + } + return 0x40; +} + +void sub_80A8048(s16 *bottom, s16 *top, const void *ptr) +{ + *bottom = ((intptr_t) ptr) & 0xffff; + *top = (((intptr_t) ptr) >> 16) & 0xffff; +} + +void *sub_80A8050(s16 bottom, s16 top) +{ + return (void *)((u16)bottom | ((u16)top << 16)); +} + +void sub_80A805C(struct Task *task, u8 a2, s16 a3, s16 a4, s16 a5, s16 a6, u16 a7) +{ + task->data[8] = a7; + task->data[15] = a2; // spriteId + task->data[9] = a3; + task->data[10] = a4; + task->data[13] = a5; + task->data[14] = a6; + task->data[11] = (a5 - a3) / a7; + task->data[12] = (a6 - a4) / a7; +} + +u8 sub_80A80C8(struct Task *task) +{ + if (!task->data[8]) + return 0; + + if (--task->data[8] != 0) + { + task->data[9] += task->data[11]; + task->data[10] += task->data[12]; + } + else + { + task->data[9] = task->data[13]; + task->data[10] = task->data[14]; + } + obj_id_set_rotscale(task->data[15], task->data[9], task->data[10], 0); + if (task->data[8]) + sub_80A7E6C(task->data[15]); + else + gSprites[task->data[15]].pos2.y = 0; + return task->data[8]; +} + +void AnimTask_GetFrustrationPowerLevel(u8 taskId) +{ + u16 powerLevel; + + if (gAnimFriendship <= 30) + powerLevel = 0; + else if (gAnimFriendship <= 100) + powerLevel = 1; + else if (gAnimFriendship <= 200) + powerLevel = 2; + else + powerLevel = 3; + gBattleAnimArgs[7] = powerLevel; + DestroyAnimVisualTask(taskId); +} + +void sub_80A8174(u8 priority) +{ + if (IsBattlerSpriteVisible(gBattleAnimTarget)) + gSprites[gBattlerSpriteIds[gBattleAnimTarget]].oam.priority = priority; + if (IsBattlerSpriteVisible(gBattleAnimAttacker)) + gSprites[gBattlerSpriteIds[gBattleAnimAttacker]].oam.priority = priority; + if (IsBattlerSpriteVisible(BATTLE_PARTNER(gBattleAnimTarget))) + gSprites[gBattlerSpriteIds[BATTLE_PARTNER(gBattleAnimTarget)]].oam.priority = priority; + if (IsBattlerSpriteVisible(BATTLE_PARTNER(gBattleAnimAttacker))) + gSprites[gBattlerSpriteIds[BATTLE_PARTNER(gBattleAnimAttacker)]].oam.priority = priority; +} + +void sub_80A8278(void) +{ + int i; + + for (i = 0; i < gBattlersCount; i++) + { + if (IsBattlerSpriteVisible(i)) + { + gSprites[gBattlerSpriteIds[i]].subpriority = sub_80A82E4(i); + gSprites[gBattlerSpriteIds[i]].oam.priority = 2; + } + } +} + +u8 sub_80A82E4(u8 battlerId) +{ + u8 position; + u8 ret; + + if (IsContest()) + { + if (battlerId == 2) + return 30; + else + return 40; + } + else + { + position = GetBattlerPosition(battlerId); + if (position == B_POSITION_PLAYER_LEFT) + ret = 30; + else if (position == B_POSITION_PLAYER_RIGHT) + ret = 20; + else if (position == B_POSITION_OPPONENT_LEFT) + ret = 40; + else + ret = 50; + } + return ret; +} + +u8 sub_80A8328(u8 battlerId) +{ + u8 position = GetBattlerPosition(battlerId); + + if (IsContest()) + return 2; + else if (position == B_POSITION_PLAYER_LEFT || position == B_POSITION_OPPONENT_RIGHT) + return GetAnimBgAttribute(2, BG_ANIM_PRIORITY); + else + return GetAnimBgAttribute(1, BG_ANIM_PRIORITY); +} + +u8 sub_80A8364(u8 battlerId) +{ + if (!IsContest()) + { + u8 position = GetBattlerPosition(battlerId); + if (position == B_POSITION_PLAYER_LEFT || position == B_POSITION_OPPONENT_RIGHT) + return 2; + else + return 1; + } + return 1; +} + +u8 sub_80A8394(u16 species, bool8 isBackpic, u8 a3, s16 x, s16 y, u8 subpriority, u32 personality, u32 trainerId, u32 battlerId, u32 a10) +{ + u8 spriteId; + u16 sheet = LoadSpriteSheet(&sUnknown_08525FC0[a3]); + u16 palette = AllocSpritePalette(sUnknown_08525F90[a3].paletteTag); + + if (gMonSpritesGfxPtr != NULL && gMonSpritesGfxPtr->field_17C == NULL) + gMonSpritesGfxPtr->field_17C = AllocZeroed(0x2000); + if (!isBackpic) + { + LoadCompressedPalette(GetFrontSpritePalFromSpeciesAndPersonality(species, trainerId, personality), (palette * 0x10) + 0x100, 0x20); + if (a10 == 1 || sub_80688F8(5, battlerId) == 1 || gBattleSpritesDataPtr->battlerData[battlerId].transformSpecies != 0) + LoadSpecialPokePic_DontHandleDeoxys(&gMonFrontPicTable[species], + gMonSpritesGfxPtr->field_17C, + species, + personality, + TRUE); + else + LoadSpecialPokePic_2(&gMonFrontPicTable[species], + gMonSpritesGfxPtr->field_17C, + species, + personality, + TRUE); + } + else + { + LoadCompressedPalette(GetFrontSpritePalFromSpeciesAndPersonality(species, trainerId, personality), (palette * 0x10) + 0x100, 0x20); + if (a10 == 1 || sub_80688F8(5, battlerId) == 1 || gBattleSpritesDataPtr->battlerData[battlerId].transformSpecies != 0) + LoadSpecialPokePic_DontHandleDeoxys(&gMonBackPicTable[species], + gMonSpritesGfxPtr->field_17C, + species, + personality, + FALSE); + else + LoadSpecialPokePic_2(&gMonBackPicTable[species], + gMonSpritesGfxPtr->field_17C, + species, + personality, + FALSE); + } + + RequestDma3Copy(gMonSpritesGfxPtr->field_17C, (void *)(OBJ_VRAM0 + (sheet * 0x20)), 0x800, 1); + FREE_AND_SET_NULL(gMonSpritesGfxPtr->field_17C); + + if (!isBackpic) + spriteId = CreateSprite(&sUnknown_08525F90[a3], x, y + gMonFrontPicCoords[species].y_offset, subpriority); + else + spriteId = CreateSprite(&sUnknown_08525F90[a3], x, y + gMonBackPicCoords[species].y_offset, subpriority); + + if (IsContest()) + { + gSprites[spriteId].affineAnims = gUnknown_082FF6C0; + StartSpriteAffineAnim(&gSprites[spriteId], 0); + } + return spriteId; +} + +void sub_80A8610(struct Sprite *sprite) +{ + DestroySpriteAndFreeResources(sprite); +} + +s16 sub_80A861C(u8 battlerId, u8 a2) +{ + u16 species; + u32 personality; + u16 letter; + u16 var; + int ret; + const struct MonCoords *coords; + struct BattleSpriteInfo *spriteInfo; + + if (IsContest()) + { + if (shared19348.unk4_0) + { + species = shared19348.unk2; + personality = shared19348.unk10; + } + else + { + species = shared19348.unk0; + personality = shared19348.unk8; + } + if (species == SPECIES_UNOWN) + { + letter = GET_UNOWN_LETTER(personality); + if (!letter) + var = SPECIES_UNOWN; + else + var = letter + SPECIES_UNOWN_B - 1; + coords = &gMonBackPicCoords[var]; + } + else if (species == SPECIES_CASTFORM) + { + coords = &gCastformFrontSpriteCoords[gBattleMonForms[battlerId]]; + } + else if (species <= SPECIES_EGG) + { + coords = &gMonBackPicCoords[species]; + } + else + { + coords = &gMonBackPicCoords[0]; + } + } + else + { + if (GetBattlerSide(battlerId) == B_SIDE_PLAYER) + { + spriteInfo = gBattleSpritesDataPtr->battlerData; + if (!spriteInfo[battlerId].transformSpecies) + { + species = GetMonData(&gPlayerParty[gBattlerPartyIndexes[battlerId]], MON_DATA_SPECIES); + personality = GetMonData(&gPlayerParty[gBattlerPartyIndexes[battlerId]], MON_DATA_PERSONALITY); + } + else + { + species = spriteInfo[battlerId].transformSpecies; + personality = gTransformedPersonalities[battlerId]; + } + if (species == SPECIES_UNOWN) + { + letter = GET_UNOWN_LETTER(personality); + if (!letter) + var = SPECIES_UNOWN; + else + var = letter + SPECIES_UNOWN_B - 1; + coords = &gMonBackPicCoords[var]; + } + else if (species > SPECIES_EGG) + { + coords = &gMonBackPicCoords[0]; + } + else + { + coords = &gMonBackPicCoords[species]; + } + } + else + { + spriteInfo = gBattleSpritesDataPtr->battlerData; + if (!spriteInfo[battlerId].transformSpecies) + { + species = GetMonData(&gEnemyParty[gBattlerPartyIndexes[battlerId]], MON_DATA_SPECIES); + personality = GetMonData(&gEnemyParty[gBattlerPartyIndexes[battlerId]], MON_DATA_PERSONALITY); + } + else + { + species = spriteInfo[battlerId].transformSpecies; + personality = gTransformedPersonalities[battlerId]; + } + if (species == SPECIES_UNOWN) + { + letter = GET_UNOWN_LETTER(personality); + if (!letter) + var = SPECIES_UNOWN; + else + var = letter + SPECIES_UNOWN_B - 1; + coords = &gMonFrontPicCoords[var]; + } + else if (species == SPECIES_CASTFORM) + { + coords = &gCastformFrontSpriteCoords[gBattleMonForms[battlerId]]; + } + else if (species > SPECIES_EGG) + { + coords = &gMonFrontPicCoords[0]; + } + else + { + coords = &gMonFrontPicCoords[species]; + } + } + } + + switch (a2) + { + case 0: + return (coords->coords & 0xf) * 8; + case 1: + return (coords->coords >> 4) * 8; + case 4: + return GetBattlerSpriteCoord(battlerId, 2) - ((coords->coords >> 4) * 4); + case 5: + return GetBattlerSpriteCoord(battlerId, 2) + ((coords->coords >> 4) * 4); + case 2: + return GetBattlerSpriteCoord(battlerId, 3) - ((coords->coords & 0xf) * 4); + case 3: + return GetBattlerSpriteCoord(battlerId, 3) + ((coords->coords & 0xf) * 4); + case 6: + ret = GetBattlerSpriteCoord(battlerId, 1) + 0x1f; + return ret - coords->y_offset; + default: + return 0; + } +} + +void SetAverageBattlerPositions(u8 battlerId, bool8 a2, s16 *x, s16 *y) +{ + u8 v1, v2; + s16 v3, v4; + s16 v5, v6; + + if (!a2) + { + v1 = 0; + v2 = 1; + } + else + { + v1 = 2; + v2 = 3; + } + v3 = GetBattlerSpriteCoord(battlerId, v1); + v4 = GetBattlerSpriteCoord(battlerId, v2); + if (IsDoubleBattle() && !IsContest()) + { + v5 = GetBattlerSpriteCoord(BATTLE_PARTNER(battlerId), v1); + v6 = GetBattlerSpriteCoord(BATTLE_PARTNER(battlerId), v2); + } + else + { + v5 = v3; + v6 = v4; + } + *x = (v3 + v5) / 2; + *y = (v4 + v6) / 2; +} + +u8 sub_80A89C8(int battlerId, u8 spriteId, int species) +{ + u8 newSpriteId = CreateInvisibleSpriteWithCallback(SpriteCallbackDummy); + gSprites[newSpriteId] = gSprites[spriteId]; + gSprites[newSpriteId].usingSheet = TRUE; + gSprites[newSpriteId].oam.priority = 0; + gSprites[newSpriteId].oam.objMode = 2; + gSprites[newSpriteId].oam.tileNum = gSprites[spriteId].oam.tileNum; + gSprites[newSpriteId].callback = SpriteCallbackDummy; + return newSpriteId; +} + +void sub_80A8A6C(struct Sprite *sprite) +{ + sub_80A6838(sprite); + if (GetBattlerSide(gBattleAnimAttacker)) + { + sprite->pos1.x -= gBattleAnimArgs[0]; + gBattleAnimArgs[3] = -gBattleAnimArgs[3]; + sprite->hFlip = TRUE; + } + else + { + sprite->pos1.x += gBattleAnimArgs[0]; + } + sprite->pos1.y += gBattleAnimArgs[1]; + sprite->data[0] = gBattleAnimArgs[2]; + sprite->data[1] = gBattleAnimArgs[3]; + sprite->data[3] = gBattleAnimArgs[4]; + sprite->data[5] = gBattleAnimArgs[5]; + StoreSpriteCallbackInData6(sprite, move_anim_8074EE0); + sprite->callback = sub_80A66DC; +} + +void sub_80A8AEC(struct Sprite *sprite) +{ + if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER) + { + sprite->pos1.x -= gBattleAnimArgs[0]; + gBattleAnimArgs[3] *= -1; + } + else + { + sprite->pos1.x += gBattleAnimArgs[0]; + } + sprite->pos1.y += gBattleAnimArgs[1]; + sprite->data[0] = gBattleAnimArgs[2]; + sprite->data[1] = gBattleAnimArgs[3]; + sprite->data[3] = gBattleAnimArgs[4]; + sprite->data[5] = gBattleAnimArgs[5]; + StartSpriteAnim(sprite, gBattleAnimArgs[6]); + StoreSpriteCallbackInData6(sprite, move_anim_8074EE0); + sprite->callback = sub_80A66DC; +} + +void sub_80A8B64(struct Sprite *sprite) +{ + sub_80A6838(sprite); + if (GetBattlerSide(gBattleAnimAttacker)) + sprite->pos1.x -= gBattleAnimArgs[0]; + else + sprite->pos1.x += gBattleAnimArgs[0]; + sprite->pos1.y += gBattleAnimArgs[1]; + sprite->callback = sub_80A67D8; + StoreSpriteCallbackInData6(sprite, DestroyAnimSprite); +} + +void sub_80A8BC4(u8 taskId) +{ + u16 src; + u16 dest; + struct Task *task = &gTasks[taskId]; + + task->data[0] = GetAnimBattlerSpriteId(ANIM_ATTACKER); + task->data[1] = ((GetBattlerSide(gBattleAnimAttacker)) != B_SIDE_PLAYER) ? -8 : 8; + task->data[2] = 0; + task->data[3] = 0; + gSprites[task->data[0]].pos2.x -= task->data[0]; + task->data[4] = AllocSpritePalette(10097); + task->data[5] = 0; + + dest = (task->data[4] + 0x10) * 0x10; + src = (gSprites[task->data[0]].oam.paletteNum + 0x10) * 0x10; + task->data[6] = sub_80A82E4(gBattleAnimAttacker); + if (task->data[6] == 20 || task->data[6] == 40) + task->data[6] = 2; + else + task->data[6] = 3; + CpuCopy32(&gPlttBufferUnfaded[src], &gPlttBufferFaded[dest], 0x20); + BlendPalette(dest, 16, gBattleAnimArgs[1], gBattleAnimArgs[0]); + task->func = sub_80A8CAC; +} + +void sub_80A8CAC(u8 taskId) +{ + struct Task *task = &gTasks[taskId]; + switch (task->data[2]) + { + case 0: + sub_80A8D78(task, taskId); + gSprites[task->data[0]].pos2.x += task->data[1]; + if (++task->data[3] == 5) + { + task->data[3]--; + task->data[2]++; + } + break; + case 1: + sub_80A8D78(task, taskId); + gSprites[task->data[0]].pos2.x -= task->data[1]; + if (--task->data[3] == 0) + { + gSprites[task->data[0]].pos2.x = 0; + task->data[2]++; + } + break; + case 2: + if (!task->data[5]) + { + FreeSpritePaletteByTag(ANIM_TAG_BENT_SPOON); + DestroyAnimVisualTask(taskId); + } + break; + } +} + +void sub_80A8D78(struct Task *task, u8 taskId) +{ + s16 spriteId = duplicate_obj_of_side_rel2move_in_transparent_mode(0); + if (spriteId >= 0) + { + gSprites[spriteId].oam.priority = task->data[6]; + gSprites[spriteId].oam.paletteNum = task->data[4]; + gSprites[spriteId].data[0] = 8; + gSprites[spriteId].data[1] = taskId; + gSprites[spriteId].data[2] = spriteId; + gSprites[spriteId].pos2.x = gSprites[task->data[0]].pos2.x; + gSprites[spriteId].callback = sub_80A8DFC; + task->data[5]++; + } +} + +void sub_80A8DFC(struct Sprite *sprite) +{ + if (--sprite->data[0] == 0) + { + gTasks[sprite->data[1]].data[5]--; + obj_delete_but_dont_free_vram(sprite); + } +} + +void sub_80A8E30(struct Sprite *sprite) +{ + sprite->pos1.x = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X_2); + sprite->pos1.y = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_3); + if (!GetBattlerSide(gBattleAnimAttacker)) + sprite->data[0] = 5; + else + sprite->data[0] = -10; + sprite->data[1] = -40; + sprite->callback = sub_80A8E88; +} + +void sub_80A8E88(struct Sprite *sprite) +{ + sprite->data[2] += sprite->data[0]; + sprite->data[3] += sprite->data[1]; + sprite->pos2.x = sprite->data[2] / 10; + sprite->pos2.y = sprite->data[3] / 10; + if (sprite->data[1] < -20) + sprite->data[1]++; + if (sprite->pos1.y + sprite->pos2.y < -32) + DestroyAnimSprite(sprite); +} + +void sub_80A8EE4(struct Sprite *sprite) +{ + int x; + sprite->data[0] = gBattleAnimArgs[2]; + sprite->data[2] = sprite->pos1.x + gBattleAnimArgs[4]; + sprite->data[4] = sprite->pos1.y + gBattleAnimArgs[5]; + if (!GetBattlerSide(gBattleAnimTarget)) + { + x = (u16)gBattleAnimArgs[4] + 30; + sprite->pos1.x += x; + sprite->pos1.y = gBattleAnimArgs[5] - 20; + } + else + { + x = (u16)gBattleAnimArgs[4] - 30; + sprite->pos1.x += x; + sprite->pos1.y = gBattleAnimArgs[5] - 80; + } + sprite->callback = sub_80A6EEC; + StoreSpriteCallbackInData6(sprite, DestroyAnimSprite); +} diff --git a/src/battle_anim_80A9C70.c b/src/battle_anim_80A9C70.c new file mode 100644 index 000000000..1f8a53993 --- /dev/null +++ b/src/battle_anim_80A9C70.c @@ -0,0 +1,360 @@ +#include "global.h" +#include "battle.h" +#include "battle_anim.h" +#include "constants/battle_anim.h" +#include "constants/rgb.h" +#include "blend_palette.h" +#include "decompress.h" +#include "palette.h" +#include "sprite.h" +#include "task.h" +#include "trig.h" +#include "gpu_regs.h" + +extern const struct CompressedSpriteSheet gBattleAnimPicTable[]; +extern const struct CompressedSpritePalette gBattleAnimPaletteTable[]; +extern const u8 *const gBattleAnims_StatusConditions[]; +extern const struct OamData gUnknown_08524904; +extern const struct OamData gUnknown_08524A3C; + +extern void sub_8116EB4(u8 taskId); + +// This file's functions. +static void sub_80A9DB4(u8 taskId); +static void sub_80A9FD0(u8 taskId); +static void sub_80AA020(u8 taskId); +static void sub_80AA0D0(u8 taskId); +static void sub_80AA124(u8 taskId); +static void Task_DoStatusAnimation(u8 taskId); +static void sub_80A9E44(struct Sprite *sprite); +static void sub_80A9E78(struct Sprite *sprite); + +// const rom data +static const struct Subsprite gUnknown_0853EF30[] = +{ + {.x = -16, .y = -16, .shape = ST_OAM_SQUARE, .size = 3, .tileOffset = 0, .priority = 2}, + {.x = -16, .y = 48, .shape = ST_OAM_H_RECTANGLE, .size = 3, .tileOffset = 64, .priority = 2}, + {.x = 48, .y = -16, .shape = ST_OAM_V_RECTANGLE, .size = 3, .tileOffset = 96, .priority = 2}, + {.x = 48, .y = 48, .shape = ST_OAM_SQUARE, .size = 2, .tileOffset = 128, .priority = 2}, +}; + +static const struct SubspriteTable gUnknown_0853EF40[] = +{ + {ARRAY_COUNT(gUnknown_0853EF30), gUnknown_0853EF30}, +}; + +static const struct SpriteTemplate gUnknown_0853EF48 = +{ + .tileTag = ANIM_TAG_ICE_CUBE, + .paletteTag = ANIM_TAG_ICE_CUBE, + .oam = &gUnknown_08524A3C, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = SpriteCallbackDummy, +}; + +static const struct SpriteTemplate gUnknown_0853EF60 = +{ + .tileTag = ANIM_TAG_136, + .paletteTag = ANIM_TAG_136, + .oam = &gUnknown_08524904, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = sub_80A9E44, +}; + +// code +u8 sub_80A9C70(u8 battlerId, bool8 b) +{ + u8 battlerSpriteId = gBattlerSpriteIds[battlerId]; + u8 taskId = CreateTask(sub_80A9DB4, 10); + u8 spriteId2; + u8 i; + + LoadCompressedObjectPicUsingHeap(&gBattleAnimPicTable[GET_TRUE_SPRITE_INDEX(ANIM_TAG_136)]); + LoadCompressedObjectPaletteUsingHeap(&gBattleAnimPaletteTable[GET_TRUE_SPRITE_INDEX(ANIM_TAG_136)]); + gTasks[taskId].data[0] = battlerId; + if (b) + { + gTasks[taskId].data[1] = RGB_RED; + for (i = 0; i < 10; i++) + { + spriteId2 = CreateSprite(&gUnknown_0853EF60, gSprites[battlerSpriteId].pos1.x, gSprites[battlerSpriteId].pos1.y + 32, 0); + gSprites[spriteId2].data[0] = i * 51; + gSprites[spriteId2].data[1] = -256; + gSprites[spriteId2].invisible = TRUE; + if (i > 4) + gSprites[spriteId2].data[6] = 21; + } + } + else + { + gTasks[taskId].data[1] = RGB_BLUE; + for (i = 0; i < 10; i++) + { + spriteId2 = CreateSprite(&gUnknown_0853EF60, gSprites[battlerSpriteId].pos1.x, gSprites[battlerSpriteId].pos1.y - 32, 0); + gSprites[spriteId2].data[0] = i * 51; + gSprites[spriteId2].data[1] = 256; + gSprites[spriteId2].invisible = TRUE; + if (i > 4) + gSprites[spriteId2].data[6] = 21; + } + } + gSprites[spriteId2].data[7] = 1; + return taskId; +} + +static void sub_80A9DB4(u8 taskId) +{ + if (gTasks[taskId].data[2] == 2) + { + gTasks[taskId].data[2] = 0; + BlendPalette(0x100 + gTasks[taskId].data[0] * 16, 16, gTasks[taskId].data[4], gTasks[taskId].data[1]); + if (gTasks[taskId].data[5] == 0) + { + gTasks[taskId].data[4]++; + if (gTasks[taskId].data[4] > 8) + gTasks[taskId].data[5] ^= 1; + } + else + { + u16 var = gTasks[taskId].data[4]; + + gTasks[taskId].data[4]--; + if (gTasks[taskId].data[4] < 0) + { + gTasks[taskId].data[4] = var; + gTasks[taskId].data[5] ^= 1; + gTasks[taskId].data[3]++; + if (gTasks[taskId].data[3] == 2) + DestroyTask(taskId); + } + } + } + else + { + gTasks[taskId].data[2]++; + } +} + +static void sub_80A9E44(struct Sprite *sprite) +{ + if (sprite->data[6] == 0) + { + sprite->invisible = FALSE; + sprite->callback = sub_80A9E78; + sub_80A9E78(sprite); + } + else + { + sprite->data[6]--; + } +} + +static void sub_80A9E78(struct Sprite *sprite) +{ + sprite->pos2.x = Cos(sprite->data[0], 32); + sprite->pos2.y = Sin(sprite->data[0], 8); + if (sprite->data[0] < 128) + sprite->subpriority = 29; + else + sprite->subpriority = 31; + sprite->data[0] = (sprite->data[0] + 8) & 0xFF; + sprite->data[5] += sprite->data[1]; + sprite->pos2.y += sprite->data[5] >> 8; + sprite->data[2]++; + if (sprite->data[2] == 52) + { + if (sprite->data[7]) + DestroySpriteAndFreeResources(sprite); + else + DestroySprite(sprite); + } +} + +void sub_80A9EF4(u8 taskId) +{ + s16 x = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X_2) - 32; + s16 y = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_3) - 36; + u8 spriteId; + + if (IsContest()) + x -= 6; + SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_EFFECT_BLEND | BLDCNT_TGT2_ALL); + SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(0, 16)); + spriteId = CreateSprite(&gUnknown_0853EF48, x, y, 4); + if (GetSpriteTileStartByTag(ANIM_TAG_ICE_CUBE) == 0xFFFF) + gSprites[spriteId].invisible = TRUE; + SetSubspriteTables(&gSprites[spriteId], gUnknown_0853EF40); + gTasks[taskId].data[15] = spriteId; + gTasks[taskId].func = sub_80A9FD0; +} + +static void sub_80A9FD0(u8 taskId) +{ + gTasks[taskId].data[1]++; + if (gTasks[taskId].data[1] == 10) + { + gTasks[taskId].func = sub_80AA020; + gTasks[taskId].data[1] = 0; + } + else + { + u8 var = gTasks[taskId].data[1]; + + SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(var, 16 - var)); + } +} + +static void sub_80AA020(u8 taskId) +{ + u8 palIndex = IndexOfSpritePaletteTag(ANIM_TAG_ICE_CUBE); + + if (gTasks[taskId].data[1]++ > 13) + { + gTasks[taskId].data[2]++; + if (gTasks[taskId].data[2] == 3) + { + u16 temp; + + temp = gPlttBufferFaded[0x100 + palIndex * 16 + 13]; + gPlttBufferFaded[0x100 + palIndex * 16 + 13] = gPlttBufferFaded[0x100 + palIndex * 16 + 14]; + gPlttBufferFaded[0x100 + palIndex * 16 + 14] = gPlttBufferFaded[0x100 + palIndex * 16 + 15]; + gPlttBufferFaded[0x100 + palIndex * 16 + 15] = temp; + + gTasks[taskId].data[2] = 0; + gTasks[taskId].data[3]++; + if (gTasks[taskId].data[3] == 3) + { + gTasks[taskId].data[3] = 0; + gTasks[taskId].data[1] = 0; + gTasks[taskId].data[4]++; + if (gTasks[taskId].data[4] == 2) + { + gTasks[taskId].data[1] = 9; + gTasks[taskId].func = sub_80AA0D0; + } + } + } + } +} + +static void sub_80AA0D0(u8 taskId) +{ + gTasks[taskId].data[1]--; + if (gTasks[taskId].data[1] == -1) + { + gTasks[taskId].func = sub_80AA124; + gTasks[taskId].data[1] = 0; + } + else + { + u8 var = gTasks[taskId].data[1]; + + SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(var, 16 - var)); + } +} + +static void sub_80AA124(u8 taskId) +{ + gTasks[taskId].data[1]++; + if (gTasks[taskId].data[1] == 37) + { + u8 spriteId = gTasks[taskId].data[15]; + + FreeSpriteOamMatrix(&gSprites[spriteId]); + DestroySprite(&gSprites[spriteId]); + } + else if (gTasks[taskId].data[1] == 39) + { + SetGpuReg(REG_OFFSET_BLDCNT, 0); + SetGpuReg(REG_OFFSET_BLDALPHA, 0); + DestroyAnimVisualTask(taskId); + } +} + +#define CASE(by, stat) case (STAT_ANIM_##by + stat - 1) + +void AnimTask_StatsChange(u8 taskId) +{ + bool16 goesDown = FALSE; + s16 animStatId = 0; + bool16 sharply = FALSE; + + switch (gBattleSpritesDataPtr->animationData->animArg) + { + CASE(PLUS1, STAT_ATK): goesDown = FALSE; animStatId = 0; break; + CASE(PLUS1, STAT_DEF): goesDown = FALSE; animStatId = 1; break; + CASE(PLUS1, STAT_SPEED): goesDown = FALSE; animStatId = 3; break; + CASE(PLUS1, STAT_SPATK): goesDown = FALSE; animStatId = 5; break; + CASE(PLUS1, STAT_SPDEF): goesDown = FALSE; animStatId = 6; break; + CASE(PLUS1, STAT_ACC): goesDown = FALSE; animStatId = 2; break; + CASE(PLUS1, STAT_EVASION): goesDown = FALSE; animStatId = 4; break; + + CASE(MINUS1, STAT_ATK): goesDown = TRUE; animStatId = 0; break; + CASE(MINUS1, STAT_DEF): goesDown = TRUE; animStatId = 1; break; + CASE(MINUS1, STAT_SPEED): goesDown = TRUE; animStatId = 3; break; + CASE(MINUS1, STAT_SPATK): goesDown = TRUE; animStatId = 5; break; + CASE(MINUS1, STAT_SPDEF): goesDown = TRUE; animStatId = 6; break; + CASE(MINUS1, STAT_ACC): goesDown = TRUE; animStatId = 2; break; + CASE(MINUS1, STAT_EVASION): goesDown = TRUE; animStatId = 4; break; + + CASE(PLUS2, STAT_ATK): goesDown = FALSE; animStatId = 0; sharply = TRUE; break; + CASE(PLUS2, STAT_DEF): goesDown = FALSE; animStatId = 1; sharply = TRUE; break; + CASE(PLUS2, STAT_SPEED): goesDown = FALSE; animStatId = 3; sharply = TRUE; break; + CASE(PLUS2, STAT_SPATK): goesDown = FALSE; animStatId = 5; sharply = TRUE; break; + CASE(PLUS2, STAT_SPDEF): goesDown = FALSE; animStatId = 6; sharply = TRUE; break; + CASE(PLUS2, STAT_ACC): goesDown = FALSE; animStatId = 2; sharply = TRUE; break; + CASE(PLUS2, STAT_EVASION): goesDown = FALSE; animStatId = 4; sharply = TRUE; break; + + CASE(MINUS2, STAT_ATK): goesDown = TRUE; animStatId = 0; sharply = TRUE; break; + CASE(MINUS2, STAT_DEF): goesDown = TRUE; animStatId = 1; sharply = TRUE; break; + CASE(MINUS2, STAT_SPEED): goesDown = TRUE; animStatId = 3; sharply = TRUE; break; + CASE(MINUS2, STAT_SPATK): goesDown = TRUE; animStatId = 5; sharply = TRUE; break; + CASE(MINUS2, STAT_SPDEF): goesDown = TRUE; animStatId = 6; sharply = TRUE; break; + CASE(MINUS2, STAT_ACC): goesDown = TRUE; animStatId = 2; sharply = TRUE; break; + CASE(MINUS2, STAT_EVASION): goesDown = TRUE; animStatId = 4; sharply = TRUE; break; + + case STAT_ANIM_MULTIPLE_PLUS1: goesDown = FALSE; animStatId = 0xFF; sharply = FALSE; break; + case STAT_ANIM_MULTIPLE_PLUS2: goesDown = FALSE; animStatId = 0xFF; sharply = TRUE; break; + case STAT_ANIM_MULTIPLE_MINUS1: goesDown = TRUE; animStatId = 0xFF; sharply = FALSE; break; + case STAT_ANIM_MULTIPLE_MINUS2: goesDown = TRUE; animStatId = 0xFF; sharply = TRUE; break; + + default: + DestroyAnimVisualTask(taskId); + return; + } + + gBattleAnimArgs[0] = goesDown; + gBattleAnimArgs[1] = animStatId; + gBattleAnimArgs[2] = 0; + gBattleAnimArgs[3] = 0; + gBattleAnimArgs[4] = sharply; + gTasks[taskId].func = sub_8116EB4; + sub_8116EB4(taskId); +} + +#undef CASE + +void LaunchStatusAnimation(u8 battlerId, u8 statusAnimId) +{ + u8 taskId; + + gBattleAnimAttacker = battlerId; + gBattleAnimTarget = battlerId; + LaunchBattleAnimation(gBattleAnims_StatusConditions, statusAnimId, 0); + taskId = CreateTask(Task_DoStatusAnimation, 10); + gTasks[taskId].data[0] = battlerId; +} + +static void Task_DoStatusAnimation(u8 taskId) +{ + gAnimScriptCallback(); + if (!gAnimScriptActive) + { + gBattleSpritesDataPtr->healthBoxesData[gTasks[taskId].data[0]].statusAnimActive = FALSE; + DestroyTask(taskId); + } +} diff --git a/src/battle_anim_80D51AC.c b/src/battle_anim_80D51AC.c new file mode 100644 index 000000000..1864a1a7a --- /dev/null +++ b/src/battle_anim_80D51AC.c @@ -0,0 +1,1004 @@ +#include "global.h" +#include "battle.h" +#include "battle_anim.h" +#include "sprite.h" +#include "task.h" +#include "trig.h" + +// This file's functions. +void AnimTask_ShakeMonStep(u8 taskId); +void AnimTask_ShakeMon2Step(u8 taskId); +void AnimTask_ShakeMonInPlaceStep(u8 taskId); +void AnimTask_ShakeAndSinkMonStep(u8 taskId); +void sub_80D57B8(u8 taskId); +void DoHorizontalLunge(struct Sprite *sprite); +void ReverseHorizontalLungeDirection(struct Sprite *sprite); +void DoVerticalDip(struct Sprite *sprite); +void ReverseVerticalDipDirection(struct Sprite* sprite); +void SlideMonToOriginalPos(struct Sprite *sprite); +void SlideMonToOriginalPosStep(struct Sprite *sprite); +void SlideMonToOffset(struct Sprite *sprite); +void sub_80D5B48(struct Sprite *sprite); +void sub_80D5C20(struct Sprite *sprite); +void AnimTask_WindUpLungePart1(u8 taskId); +void AnimTask_WindUpLungePart2(u8 taskId); +void AnimTask_SwayMonStep(u8 taskId); +void AnimTask_ScaleMonAndRestoreStep(u8 taskId); +void sub_80D6308(u8 taskId); +void sub_80D646C(u8 taskId); +void sub_80A8B3C(u8 taskId); + +// Task to facilitate simple shaking of a pokemon's picture in battle. +// The shaking alternates between the original position and the target position. +// arg 0: anim battler +// arg 1: x pixel offset +// arg 2: y pixel offset +// arg 3: num times to shake +// arg 4: frame delay +void AnimTask_ShakeMon(u8 taskId) +{ + u8 spriteId; + spriteId = GetAnimBattlerSpriteId(gBattleAnimArgs[0]); + if (spriteId == 0xff) + { + DestroyAnimVisualTask(taskId); + return; + } + gSprites[spriteId].pos2.x = gBattleAnimArgs[1]; + gSprites[spriteId].pos2.y = gBattleAnimArgs[2]; + gTasks[taskId].data[0] = spriteId; + gTasks[taskId].data[1] = gBattleAnimArgs[3]; + gTasks[taskId].data[2] = gBattleAnimArgs[4]; + gTasks[taskId].data[3] = gBattleAnimArgs[4]; + gTasks[taskId].data[4] = gBattleAnimArgs[1]; + gTasks[taskId].data[5] = gBattleAnimArgs[2]; + gTasks[taskId].func = AnimTask_ShakeMonStep; + AnimTask_ShakeMonStep(taskId); +} + +void AnimTask_ShakeMonStep(u8 taskId) +{ + if (gTasks[taskId].data[3] == 0) + { + if (gSprites[gTasks[taskId].data[0]].pos2.x == 0) + { + gSprites[gTasks[taskId].data[0]].pos2.x = gTasks[taskId].data[4]; + } + else + { + gSprites[gTasks[taskId].data[0]].pos2.x = 0; + } + if (gSprites[gTasks[taskId].data[0]].pos2.y == 0) + { + gSprites[gTasks[taskId].data[0]].pos2.y = gTasks[taskId].data[5]; + } + else + { + gSprites[gTasks[taskId].data[0]].pos2.y = 0; + } + gTasks[taskId].data[3] = gTasks[taskId].data[2]; + if (--gTasks[taskId].data[1] == 0) + { + gSprites[gTasks[taskId].data[0]].pos2.x = 0; + gSprites[gTasks[taskId].data[0]].pos2.y = 0; + DestroyAnimVisualTask(taskId); + return; + } + } + else + { + gTasks[taskId].data[3]--; + } +} + +// Task to facilitate simple shaking of a pokemon's picture in battle. +// The shaking alternates between the positive and negative versions of the specified pixel offsets. +// arg 0: anim battler +// arg 1: x pixel offset +// arg 2: y pixel offset +// arg 3: num times to shake +// arg 4: frame delay +void AnimTask_ShakeMon2(u8 taskId) +{ + u8 spriteId; + bool8 destroy = FALSE; + u8 battlerId; + + if (gBattleAnimArgs[0] < 4) + { + spriteId = GetAnimBattlerSpriteId(gBattleAnimArgs[0]); + if (spriteId == 0xff) + { + DestroyAnimVisualTask(taskId); + return; + } + } + else if (gBattleAnimArgs[0] != 8) + { + switch (gBattleAnimArgs[0]) + { + case 4: + battlerId = GetBattlerAtPosition(B_POSITION_PLAYER_LEFT); + break; + case 5: + battlerId = GetBattlerAtPosition(B_POSITION_PLAYER_RIGHT); + break; + case 6: + battlerId = GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT); + break; + case 7: + default: + battlerId = GetBattlerAtPosition(B_POSITION_OPPONENT_RIGHT); + break; + } + + if (IsBattlerSpriteVisible(battlerId) == FALSE) + destroy = TRUE; + + spriteId = gBattlerSpriteIds[battlerId]; + } + else + { + spriteId = gBattlerSpriteIds[gBattleAnimAttacker]; + } + + if (destroy) + { + DestroyAnimVisualTask(taskId); + return; + } + + gSprites[spriteId].pos2.x = gBattleAnimArgs[1]; + gSprites[spriteId].pos2.y = gBattleAnimArgs[2]; + gTasks[taskId].data[0] = spriteId; + gTasks[taskId].data[1] = gBattleAnimArgs[3]; + gTasks[taskId].data[2] = gBattleAnimArgs[4]; + gTasks[taskId].data[3] = gBattleAnimArgs[4]; + gTasks[taskId].data[4] = gBattleAnimArgs[1]; + gTasks[taskId].data[5] = gBattleAnimArgs[2]; + gTasks[taskId].func = AnimTask_ShakeMon2Step; + gTasks[taskId].func(taskId); +} + +void AnimTask_ShakeMon2Step(u8 taskId) +{ + if (gTasks[taskId].data[3] == 0) + { + if (gSprites[gTasks[taskId].data[0]].pos2.x == gTasks[taskId].data[4]) + gSprites[gTasks[taskId].data[0]].pos2.x = -gTasks[taskId].data[4]; + else + gSprites[gTasks[taskId].data[0]].pos2.x = gTasks[taskId].data[4]; + + if (gSprites[gTasks[taskId].data[0]].pos2.y == gTasks[taskId].data[5]) + gSprites[gTasks[taskId].data[0]].pos2.y = -gTasks[taskId].data[5]; + else + gSprites[gTasks[taskId].data[0]].pos2.y = gTasks[taskId].data[5]; + + gTasks[taskId].data[3] = gTasks[taskId].data[2]; + if (--gTasks[taskId].data[1] == 0) + { + gSprites[gTasks[taskId].data[0]].pos2.x = 0; + gSprites[gTasks[taskId].data[0]].pos2.y = 0; + DestroyAnimVisualTask(taskId); + return; + } + } + else + { + gTasks[taskId].data[3]--; + } +} + +// Task to facilitate simple shaking of a pokemon's picture in battle. +// The shaking alternates between the positive and negative versions of the specified pixel offsets +// with respect to the current location of the mon's picture. +// arg 0: battler +// arg 1: x offset +// arg 2: y offset +// arg 3: num shakes +// arg 4: delay +void AnimTask_ShakeMonInPlace(u8 taskId) +{ + u8 spriteId = GetAnimBattlerSpriteId(gBattleAnimArgs[0]); + if (spriteId == 0xff) + { + DestroyAnimVisualTask(taskId); + return; + } + + gSprites[spriteId].pos2.x += gBattleAnimArgs[1]; + gSprites[spriteId].pos2.y += gBattleAnimArgs[2]; + gTasks[taskId].data[0] = spriteId; + gTasks[taskId].data[1] = 0; + gTasks[taskId].data[2] = gBattleAnimArgs[3]; + gTasks[taskId].data[3] = 0; + gTasks[taskId].data[4] = gBattleAnimArgs[4]; + gTasks[taskId].data[5] = gBattleAnimArgs[1] * 2; + gTasks[taskId].data[6] = gBattleAnimArgs[2] * 2; + gTasks[taskId].func = AnimTask_ShakeMonInPlaceStep; + gTasks[taskId].func(taskId); +} + +void AnimTask_ShakeMonInPlaceStep(u8 taskId) +{ + if (gTasks[taskId].data[3] == 0) + { + if (gTasks[taskId].data[1] & 1) + { + gSprites[gTasks[taskId].data[0]].pos2.x += gTasks[taskId].data[5]; + gSprites[gTasks[taskId].data[0]].pos2.y += gTasks[taskId].data[6]; + } + else + { + gSprites[gTasks[taskId].data[0]].pos2.x -= gTasks[taskId].data[5]; + gSprites[gTasks[taskId].data[0]].pos2.y -= gTasks[taskId].data[6]; + } + gTasks[taskId].data[3] = gTasks[taskId].data[4]; + if (++gTasks[taskId].data[1] >= gTasks[taskId].data[2]) + { + if (gTasks[taskId].data[1] & 1) + { + gSprites[gTasks[taskId].data[0]].pos2.x += gTasks[taskId].data[5] / 2; + gSprites[gTasks[taskId].data[0]].pos2.y += gTasks[taskId].data[6] / 2; + } + else + { + gSprites[gTasks[taskId].data[0]].pos2.x -= gTasks[taskId].data[5] / 2; + gSprites[gTasks[taskId].data[0]].pos2.y -= gTasks[taskId].data[6] / 2; + } + DestroyAnimVisualTask(taskId); + return; + } + } + else + { + gTasks[taskId].data[3]--; + } +} + +// Shakes a mon bg horizontally and moves it downward linearly. +// arg 0: battler +// arg 1: x offset +// arg 2: frame delay between each movement +// arg 3: downward speed (subpixel) +// arg 4: duration +void AnimTask_ShakeAndSinkMon(u8 taskId) +{ + u8 spriteId = GetAnimBattlerSpriteId(gBattleAnimArgs[0]); + gSprites[spriteId].pos2.x = gBattleAnimArgs[1]; + gTasks[taskId].data[0] = spriteId; + gTasks[taskId].data[1] = gBattleAnimArgs[1]; + gTasks[taskId].data[2] = gBattleAnimArgs[2]; + gTasks[taskId].data[3] = gBattleAnimArgs[3]; + gTasks[taskId].data[4] = gBattleAnimArgs[4]; + gTasks[taskId].func = AnimTask_ShakeAndSinkMonStep; + gTasks[taskId].func(taskId); +} + +void AnimTask_ShakeAndSinkMonStep(u8 taskId) +{ + s16 x; + u8 spriteId; + spriteId = gTasks[taskId].data[0]; + x = gTasks[taskId].data[1]; + if (gTasks[taskId].data[2] == gTasks[taskId].data[8]++) + { + gTasks[taskId].data[8] = 0; + if (gSprites[spriteId].pos2.x == x) + x = -x; + + gSprites[spriteId].pos2.x += x; + } + + gTasks[taskId].data[1] = x; + gTasks[taskId].data[9] += gTasks[taskId].data[3]; + gSprites[spriteId].pos2.y = gTasks[taskId].data[9] >> 8; + if (--gTasks[taskId].data[4] == 0) + { + DestroyAnimVisualTask(taskId); + return; + } +} + +// Moves a mon bg picture along an elliptical path that begins +// and ends at the mon's origin location. +// arg 0: battler +// arg 1: ellipse width +// arg 2: ellipse height +// arg 3: num loops +// arg 4: speed (valid values are 0-5) +void AnimTask_TranslateMonElliptical(u8 taskId) +{ + u8 i; + u8 spriteId; + u8 wavePeriod; + + wavePeriod = 1; + spriteId = GetAnimBattlerSpriteId(gBattleAnimArgs[0]); + if (gBattleAnimArgs[4] > 5) + gBattleAnimArgs[4] = 5; + + for (i = 0; i < gBattleAnimArgs[4]; i++) + { + wavePeriod <<= 1; + } + + gTasks[taskId].data[0] = spriteId; + gTasks[taskId].data[1] = gBattleAnimArgs[1]; + gTasks[taskId].data[2] = gBattleAnimArgs[2]; + gTasks[taskId].data[3] = gBattleAnimArgs[3]; + gTasks[taskId].data[4] = wavePeriod; + gTasks[taskId].func = sub_80D57B8; + gTasks[taskId].func(taskId); +} + +void sub_80D57B8(u8 taskId) +{ + u8 spriteId = gTasks[taskId].data[0]; + gSprites[spriteId].pos2.x = Sin(gTasks[taskId].data[5], gTasks[taskId].data[1]); + gSprites[spriteId].pos2.y = -Cos(gTasks[taskId].data[5], gTasks[taskId].data[2]); + gSprites[spriteId].pos2.y += gTasks[taskId].data[2]; + gTasks[taskId].data[5] += gTasks[taskId].data[4]; + gTasks[taskId].data[5] &= 0xff; + + if (gTasks[taskId].data[5] == 0) + gTasks[taskId].data[3]--; + + if (gTasks[taskId].data[3] == 0) + { + gSprites[spriteId].pos2.x = 0; + gSprites[spriteId].pos2.y = 0; + DestroyAnimVisualTask(taskId); + return; + } +} + +// Moves a mon bg picture along an elliptical path that begins +// and ends at the mon's origin location. Reverses the direction +// of the path if it's not on the player's side of the battle. +// arg 0: battler +// arg 1: ellipse width +// arg 2: ellipse height +// arg 3: num loops +// arg 4: speed (valid values are 0-5) +void AnimTask_TranslateMonEllipticalRespectSide(u8 taskId) +{ + if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER) + gBattleAnimArgs[1] = -gBattleAnimArgs[1]; + + AnimTask_TranslateMonElliptical(taskId); +} + +// Performs a simple horizontal lunge, where the mon moves +// horizontally, and then moves back in the opposite direction. +// arg 0: duration of single lunge direction +// arg 1: x pixel delta that is applied each frame +void DoHorizontalLunge(struct Sprite *sprite) +{ + sprite->invisible = TRUE; + if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER) + sprite->data[1] = -gBattleAnimArgs[1]; + else + sprite->data[1] = gBattleAnimArgs[1]; + + sprite->data[0] = gBattleAnimArgs[0]; + sprite->data[2] = 0; + sprite->data[3] = gBattlerSpriteIds[gBattleAnimAttacker]; + sprite->data[4] = gBattleAnimArgs[0]; + StoreSpriteCallbackInData6(sprite, ReverseHorizontalLungeDirection); + sprite->callback = sub_80A6630; +} + +void ReverseHorizontalLungeDirection(struct Sprite *sprite) +{ + sprite->data[0] = sprite->data[4]; + sprite->data[1] = -sprite->data[1]; + sprite->callback = sub_80A6630; + StoreSpriteCallbackInData6(sprite, DestroyAnimSprite); +} + +// Performs a simple vertical dipping motion, where moves vertically, and then +// moves back in the opposite direction. +// arg 0: duration of single dip direction +// arg 1: y pixel delta that is applied each frame +// arg 2: battler +void DoVerticalDip(struct Sprite *sprite) +{ + u8 spriteId; + sprite->invisible = TRUE; + spriteId = GetAnimBattlerSpriteId(gBattleAnimArgs[2]); + sprite->data[0] = gBattleAnimArgs[0]; + sprite->data[1] = 0; + sprite->data[2] = gBattleAnimArgs[1]; + sprite->data[3] = spriteId; + sprite->data[4] = gBattleAnimArgs[0]; + StoreSpriteCallbackInData6(sprite, ReverseVerticalDipDirection); + sprite->callback = sub_80A6630; +} + +void ReverseVerticalDipDirection(struct Sprite *sprite) +{ + sprite->data[0] = sprite->data[4]; + sprite->data[2] = -sprite->data[2]; + sprite->callback = sub_80A6630; + StoreSpriteCallbackInData6(sprite, DestroyAnimSprite); +} + +// Linearly slides a mon's bg picture back to its original sprite position. +// The sprite parameter is a dummy sprite used for facilitating the movement with its callback. +// arg 0: 1 = target or 0 = attacker +// arg 1: direction (0 = horizontal and vertical, 1 = horizontal only, 2 = vertical only) +// arg 2: duration +void SlideMonToOriginalPos(struct Sprite *sprite) +{ + u32 monSpriteId; + if (!gBattleAnimArgs[0]) + monSpriteId = gBattlerSpriteIds[gBattleAnimAttacker]; + else + monSpriteId = gBattlerSpriteIds[gBattleAnimTarget]; + + sprite->data[0] = gBattleAnimArgs[2]; + sprite->data[1] = gSprites[monSpriteId].pos1.x + gSprites[monSpriteId].pos2.x; + sprite->data[2] = gSprites[monSpriteId].pos1.x; + sprite->data[3] = gSprites[monSpriteId].pos1.y + gSprites[monSpriteId].pos2.y; + sprite->data[4] = gSprites[monSpriteId].pos1.y; + sub_80A6E14(sprite); + sprite->data[3] = 0; + sprite->data[4] = 0; + sprite->data[5] = gSprites[monSpriteId].pos2.x; + sprite->data[6] = gSprites[monSpriteId].pos2.y; + sprite->invisible = TRUE; + + if (gBattleAnimArgs[1] == 1) + sprite->data[2] = 0; + else if (gBattleAnimArgs[1] == 2) + sprite->data[1] = 0; + + sprite->data[7] = gBattleAnimArgs[1]; + sprite->data[7] |= monSpriteId << 8; + sprite->callback = SlideMonToOriginalPosStep; +} + +void SlideMonToOriginalPosStep(struct Sprite *sprite) +{ + s8 monSpriteId; + u8 lo; + struct Sprite *monSprite; + + lo = sprite->data[7] & 0xff; + monSpriteId = sprite->data[7] >> 8; + monSprite = &gSprites[monSpriteId]; + if (sprite->data[0] == 0) + { + if (lo < 2) + monSprite->pos2.x = 0; + + if (lo == 2 || lo == 0) + monSprite->pos2.y = 0; + + DestroyAnimSprite(sprite); + } + else + { + sprite->data[0]--; + sprite->data[3] += sprite->data[1]; + sprite->data[4] += sprite->data[2]; + monSprite->pos2.x = (s8)(sprite->data[3] >> 8) + sprite->data[5]; + monSprite->pos2.y = (s8)(sprite->data[4] >> 8) + sprite->data[6]; + } +} + +// Linearly translates a mon to a target offset. The horizontal offset +// is mirrored for the opponent's pokemon, and the vertical offset +// is only mirrored if arg 3 is set to 1. +// arg 0: 0 = attacker, 1 = target +// arg 1: target x pixel offset +// arg 2: target y pixel offset +// arg 3: mirror vertical translation for opposite battle side +// arg 4: duration +void SlideMonToOffset(struct Sprite *sprite) +{ + u8 battler; + u8 monSpriteId; + if (!gBattleAnimArgs[0]) + battler = gBattleAnimAttacker; + else + battler = gBattleAnimTarget; + + monSpriteId = gBattlerSpriteIds[battler]; + if (GetBattlerSide(battler) != B_SIDE_PLAYER) + { + gBattleAnimArgs[1] = -gBattleAnimArgs[1]; + if (gBattleAnimArgs[3] == 1) + { + gBattleAnimArgs[2] = -gBattleAnimArgs[2]; + } + } + + sprite->data[0] = gBattleAnimArgs[4]; + sprite->data[1] = gSprites[monSpriteId].pos1.x; + sprite->data[2] = gSprites[monSpriteId].pos1.x + gBattleAnimArgs[1]; + sprite->data[3] = gSprites[monSpriteId].pos1.y; + sprite->data[4] = gSprites[monSpriteId].pos1.y + gBattleAnimArgs[2]; + sub_80A6E14(sprite); + sprite->data[3] = 0; + sprite->data[4] = 0; + sprite->data[5] = monSpriteId; + sprite->invisible = TRUE; + StoreSpriteCallbackInData6(sprite, DestroyAnimSprite); + sprite->callback = sub_80A6680; +} + +void sub_80D5B48(struct Sprite *sprite) +{ + u8 spriteId; + u8 battlerId; + sprite->invisible = TRUE; + if (!gBattleAnimArgs[0]) + { + battlerId = gBattleAnimAttacker; + } + else + { + battlerId = gBattleAnimTarget; + } + spriteId = gBattlerSpriteIds[battlerId]; + if (GetBattlerSide(battlerId)) + { + gBattleAnimArgs[1] = -gBattleAnimArgs[1]; + if (gBattleAnimArgs[3] == 1) + { + gBattleAnimArgs[2] = -gBattleAnimArgs[2]; + } + } + sprite->data[0] = gBattleAnimArgs[4]; + sprite->data[1] = gSprites[spriteId].pos1.x + gSprites[spriteId].pos2.x; + sprite->data[2] = sprite->data[1] + gBattleAnimArgs[1]; + sprite->data[3] = gSprites[spriteId].pos1.y + gSprites[spriteId].pos2.y; + sprite->data[4] = sprite->data[3] + gBattleAnimArgs[2]; + sub_80A6E14(sprite); + sprite->data[3] = gSprites[spriteId].pos2.x << 8; + sprite->data[4] = gSprites[spriteId].pos2.y << 8; + sprite->data[5] = spriteId; + sprite->data[6] = gBattleAnimArgs[5]; + if (!gBattleAnimArgs[5]) + { + StoreSpriteCallbackInData6(sprite, DestroyAnimSprite); + } + else + { + StoreSpriteCallbackInData6(sprite, sub_80D5C20); + } + sprite->callback = sub_80A6680; +} + + +void sub_80D5C20(struct Sprite *sprite) +{ + gSprites[sprite->data[5]].pos2.x = 0; + gSprites[sprite->data[5]].pos2.y = 0; + DestroyAnimSprite(sprite); +} + +// Task to facilitate a two-part translation animation, in which the sprite +// is first translated in an arc to one position. Then, it "lunges" to a target +// x offset. Used in TAKE_DOWN, for example. +// arg 0: anim bank +// arg 1: horizontal speed (subpixel) +// arg 2: wave amplitude +// arg 3: first duration +// arg 4: delay before starting lunge +// arg 5: target x offset for lunge +// arg 6: lunge duration +void AnimTask_WindUpLunge(u8 taskId) +{ + s16 wavePeriod = 0x8000 / gBattleAnimArgs[3]; + if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER) + { + gBattleAnimArgs[1] = -gBattleAnimArgs[1]; + gBattleAnimArgs[5] = -gBattleAnimArgs[5]; + } + gTasks[taskId].data[0] = GetAnimBattlerSpriteId(gBattleAnimArgs[0]); + gTasks[taskId].data[1] = (gBattleAnimArgs[1] << 8) / gBattleAnimArgs[3]; + gTasks[taskId].data[2] = gBattleAnimArgs[2]; + gTasks[taskId].data[3] = gBattleAnimArgs[3]; + gTasks[taskId].data[4] = gBattleAnimArgs[4]; + gTasks[taskId].data[5] = (gBattleAnimArgs[5] << 8) / gBattleAnimArgs[6]; + gTasks[taskId].data[6] = gBattleAnimArgs[6]; + gTasks[taskId].data[7] = wavePeriod; + gTasks[taskId].func = AnimTask_WindUpLungePart1; +} + +void AnimTask_WindUpLungePart1(u8 taskId) +{ + u8 spriteId; + spriteId = gTasks[taskId].data[0]; + gTasks[taskId].data[11] += gTasks[taskId].data[1]; + gSprites[spriteId].pos2.x = gTasks[taskId].data[11] >> 8; + gSprites[spriteId].pos2.y = Sin((u8)(gTasks[taskId].data[10] >> 8), gTasks[taskId].data[2]); + gTasks[taskId].data[10] += gTasks[taskId].data[7]; + if (--gTasks[taskId].data[3] == 0) + { + gTasks[taskId].func = AnimTask_WindUpLungePart2; + } +} + +void AnimTask_WindUpLungePart2(u8 taskId) +{ + u8 spriteId; + if (gTasks[taskId].data[4] > 0) + { + gTasks[taskId].data[4]--; + } + else + { + spriteId = gTasks[taskId].data[0]; + gTasks[taskId].data[12] += gTasks[taskId].data[5]; + gSprites[spriteId].pos2.x = (gTasks[taskId].data[12] >> 8) + (gTasks[taskId].data[11] >> 8); + if (--gTasks[taskId].data[6] == 0) + { + DestroyAnimVisualTask(taskId); + return; + } + } +} + +void sub_80D5DB0(u8 taskId) +{ + u8 spriteId; + switch (gBattleAnimArgs[0]) + { + case 0: + case 1: + spriteId = GetAnimBattlerSpriteId(gBattleAnimArgs[0]); + break; + case 2: + if (!IsBattlerSpriteVisible(BATTLE_PARTNER(gBattleAnimAttacker))) + { + DestroyAnimVisualTask(taskId); + return; + } + spriteId = gBattlerSpriteIds[BATTLE_PARTNER(gBattleAnimAttacker)]; + break; + case 3: + if (!IsBattlerSpriteVisible(BATTLE_PARTNER(gBattleAnimTarget))) + { + DestroyAnimVisualTask(taskId); + return; + } + spriteId = gBattlerSpriteIds[BATTLE_PARTNER(gBattleAnimTarget)]; + break; + default: + DestroyAnimVisualTask(taskId); + return; + } + gTasks[taskId].data[0] = spriteId; + if (GetBattlerSide(gBattleAnimTarget) != B_SIDE_PLAYER) + { + gTasks[taskId].data[1] = gBattleAnimArgs[1]; + } + else + { + gTasks[taskId].data[1] = -gBattleAnimArgs[1]; + } + gTasks[taskId].func = sub_80A8B3C; +} + +void sub_80A8B3C(u8 taskId) +{ + u8 spriteId = gTasks[taskId].data[0]; + gSprites[spriteId].pos2.x += gTasks[taskId].data[1]; + if (gSprites[spriteId].pos2.x + gSprites[spriteId].pos1.x + 0x20 > 0x130u) + { + DestroyAnimVisualTask(taskId); + return; + } +} + +// Task that facilitates translating the mon bg picture back and forth +// in a swaying motion (uses Sine wave). It can sway either horizontally +// or vertically, but not both. +// arg 0: direction (0 = horizontal, 1 = vertical) +// arg 1: wave amplitude +// arg 2: wave period +// arg 3: num sways +// arg 4: which mon (0 = attacker, 1`= target) +void AnimTask_SwayMon(u8 taskId) +{ + u8 spriteId; + if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER) + gBattleAnimArgs[1] = -gBattleAnimArgs[1]; + + spriteId = GetAnimBattlerSpriteId(gBattleAnimArgs[4]); + gTasks[taskId].data[0] = gBattleAnimArgs[0]; + gTasks[taskId].data[1] = gBattleAnimArgs[1]; + gTasks[taskId].data[2] = gBattleAnimArgs[2]; + gTasks[taskId].data[3] = gBattleAnimArgs[3]; + gTasks[taskId].data[4] = spriteId; + + if (gBattleAnimArgs[4] == 0) + gTasks[taskId].data[5] = gBattleAnimAttacker; + else + gTasks[taskId].data[5] = gBattleAnimTarget; + + gTasks[taskId].data[12] = 1; + gTasks[taskId].func = AnimTask_SwayMonStep; +} + +void AnimTask_SwayMonStep(u8 taskId) +{ + s16 sineValue; + u8 spriteId; + int waveIndex; + u16 sineIndex; + + spriteId = gTasks[taskId].data[4]; + sineIndex = gTasks[taskId].data[10] + gTasks[taskId].data[2]; + gTasks[taskId].data[10] = sineIndex; + waveIndex = sineIndex >> 8; + sineValue = Sin(waveIndex, gTasks[taskId].data[1]); + + if (gTasks[taskId].data[0] == 0) + { + gSprites[spriteId].pos2.x = sineValue; + } + else + { + if (GetBattlerSide(gTasks[taskId].data[5]) == B_SIDE_PLAYER) + { + gSprites[spriteId].pos2.y = (sineValue >= 0) ? sineValue : -sineValue; + } + else + { + gSprites[spriteId].pos2.y = (sineValue >= 0) ? -sineValue : sineValue; + } + } + + if (((waveIndex >= 0x80u) && (gTasks[taskId].data[11] == 0) && (gTasks[taskId].data[12] == 1)) + || ((waveIndex < 0x7fu) && (gTasks[taskId].data[11] == 1) && (gTasks[taskId].data[12] == 0))) + { + gTasks[taskId].data[11] ^= 1; + gTasks[taskId].data[12] ^= 1; + if (--gTasks[taskId].data[3] == 0) + { + gSprites[spriteId].pos2.x = 0; + gSprites[spriteId].pos2.y = 0; + DestroyAnimVisualTask(taskId); + return; + } + } +} + +// Scales a mon's sprite, and then scales back to its original dimensions. +// arg 0: x scale delta +// arg 1: y scale delta +// arg 2: duration +// arg 3: anim bank +// arg 4: sprite object mode +void AnimTask_ScaleMonAndRestore(u8 taskId) +{ + u8 spriteId; + spriteId = GetAnimBattlerSpriteId(gBattleAnimArgs[3]); + sub_80A7270(spriteId, gBattleAnimArgs[4]); + gTasks[taskId].data[0] = gBattleAnimArgs[0]; + gTasks[taskId].data[1] = gBattleAnimArgs[1]; + gTasks[taskId].data[2] = gBattleAnimArgs[2]; + gTasks[taskId].data[3] = gBattleAnimArgs[2]; + gTasks[taskId].data[4] = spriteId; + gTasks[taskId].data[10] = 0x100; + gTasks[taskId].data[11] = 0x100; + gTasks[taskId].func = AnimTask_ScaleMonAndRestoreStep; +} + +void AnimTask_ScaleMonAndRestoreStep(u8 taskId) +{ + u8 spriteId; + gTasks[taskId].data[10] += gTasks[taskId].data[0]; + gTasks[taskId].data[11] += gTasks[taskId].data[1]; + spriteId = gTasks[taskId].data[4]; + obj_id_set_rotscale(spriteId, gTasks[taskId].data[10], gTasks[taskId].data[11], 0); + if (--gTasks[taskId].data[2] == 0) + { + if (gTasks[taskId].data[3] > 0) + { + gTasks[taskId].data[0] = -gTasks[taskId].data[0]; + gTasks[taskId].data[1] = -gTasks[taskId].data[1]; + gTasks[taskId].data[2] = gTasks[taskId].data[3]; + gTasks[taskId].data[3] = 0; + } + else + { + sub_80A7344(spriteId); + DestroyAnimVisualTask(taskId); + return; + } + } +} + +void sub_80D6134(u8 taskId) +{ + u8 spriteId; + spriteId = GetAnimBattlerSpriteId(gBattleAnimArgs[2]); + sub_80A7270(spriteId, 0); + gTasks[taskId].data[1] = 0; + gTasks[taskId].data[2] = gBattleAnimArgs[0]; + if (gBattleAnimArgs[3] != 1) + { + gTasks[taskId].data[3] = 0; + } + else + { + gTasks[taskId].data[3] = gBattleAnimArgs[0] * gBattleAnimArgs[1]; + } + gTasks[taskId].data[4] = gBattleAnimArgs[1]; + gTasks[taskId].data[5] = spriteId; + gTasks[taskId].data[6] = gBattleAnimArgs[3]; + if (IsContest()) + { + gTasks[taskId].data[7] = 1; + } + else + { + if (gBattleAnimArgs[2] == 0) + { + gTasks[taskId].data[7] = !GetBattlerSide(gBattleAnimAttacker); + } + else + { + gTasks[taskId].data[7] = !GetBattlerSide(gBattleAnimTarget); + } + } + if (gTasks[taskId].data[7]) + { + if (!IsContest()) + { + gTasks[taskId].data[3] *= -1; + gTasks[taskId].data[4] *= -1; + } + } + gTasks[taskId].func = sub_80D6308; +} + +void sub_80D622C(u8 taskId) +{ + u8 spriteId; + spriteId = GetAnimBattlerSpriteId(gBattleAnimArgs[2]); + sub_80A7270(spriteId, 0); + gTasks[taskId].data[1] = 0; + gTasks[taskId].data[2] = gBattleAnimArgs[0]; + if (gBattleAnimArgs[2] == 0) + { + if (GetBattlerSide(gBattleAnimAttacker)) + { + gBattleAnimArgs[1] = -gBattleAnimArgs[1]; + } + } + else + { + if (GetBattlerSide(gBattleAnimTarget)) + { + gBattleAnimArgs[1] = -gBattleAnimArgs[1]; + } + } + if (gBattleAnimArgs[3] != 1) + { + gTasks[taskId].data[3] = 0; + } + else + { + gTasks[taskId].data[3] = gBattleAnimArgs[0] * gBattleAnimArgs[1]; + } + gTasks[taskId].data[4] = gBattleAnimArgs[1]; + gTasks[taskId].data[5] = spriteId; + gTasks[taskId].data[6] = gBattleAnimArgs[3]; + gTasks[taskId].data[7] = 1; + gTasks[taskId].data[3] *= -1; + gTasks[taskId].data[4] *= -1; + gTasks[taskId].func = sub_80D6308; +} + +void sub_80D6308(u8 taskId) +{ + gTasks[taskId].data[3] += gTasks[taskId].data[4]; + obj_id_set_rotscale(gTasks[taskId].data[5], 0x100, 0x100, gTasks[taskId].data[3]); + if (gTasks[taskId].data[7]) + { + sub_80A73A0(gTasks[taskId].data[5]); + } + if (++gTasks[taskId].data[1] >= gTasks[taskId].data[2]) + { + switch (gTasks[taskId].data[6]) + { + case 1: + sub_80A7344(gTasks[taskId].data[5]); + case 0: + default: + DestroyAnimVisualTask(taskId); + return; + case 2: + gTasks[taskId].data[1] = 0; + gTasks[taskId].data[4] *= -1; + gTasks[taskId].data[6] = 1; + break; + } + } +} + +void sub_80D6388(u8 taskId) +{ + if (!gBattleAnimArgs[0]) + { + gTasks[taskId].data[15] = gAnimMovePower / 12; + if (gTasks[taskId].data[15] < 1) + { + gTasks[taskId].data[15] = 1; + } + if (gTasks[taskId].data[15] > 16) + { + gTasks[taskId].data[15] = 16; + } + } + else + { + gTasks[taskId].data[15] = gAnimMoveDmg / 12; + if (gTasks[taskId].data[15] < 1) + { + gTasks[taskId].data[15] = 1; + } + if (gTasks[taskId].data[15] > 16) + { + gTasks[taskId].data[15] = 16; + } + } + gTasks[taskId].data[14] = gTasks[taskId].data[15] / 2; + gTasks[taskId].data[13] = gTasks[taskId].data[14] + (gTasks[taskId].data[15] & 1); + 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[8] = gSprites[gTasks[taskId].data[7]].pos2.x; + gTasks[taskId].data[9] = gSprites[gTasks[taskId].data[7]].pos2.y; + gTasks[taskId].data[0] = 0; + gTasks[taskId].data[1] = gBattleAnimArgs[1]; + gTasks[taskId].data[2] = gBattleAnimArgs[2]; + gTasks[taskId].func = sub_80D646C; +} + +void sub_80D646C(u8 taskId) +{ + struct Task *task = &gTasks[taskId]; + if (++task->data[0] > task->data[1]) + { + task->data[0] = 0; + task->data[12] = (task->data[12] + 1) & 1; + if (task->data[10]) + { + if (task->data[12]) + { + gSprites[task->data[7]].pos2.x = task->data[8] + task->data[13]; + } + else + { + gSprites[task->data[7]].pos2.x = task->data[8] - task->data[14]; + } + } + if (task->data[11]) + { + if (task->data[12]) + { + gSprites[task->data[7]].pos2.y = task->data[15]; + } + else + { + gSprites[task->data[7]].pos2.y = 0; + } + } + if (!--task->data[2]) + { + gSprites[task->data[7]].pos2.x = 0; + gSprites[task->data[7]].pos2.y = 0; + DestroyAnimVisualTask(taskId); + return; + } + } +} diff --git a/src/battle_anim_sound_tasks.c b/src/battle_anim_sound_tasks.c index 5a829171e..6993bd2ee 100644 --- a/src/battle_anim_sound_tasks.c +++ b/src/battle_anim_sound_tasks.c @@ -131,7 +131,7 @@ void sub_8158D8C(u8 taskId) if (IsContest()) { if (gBattleAnimArgs[0] == ANIM_ATTACKER) - species = gContestResources->field_18->field_0; + species = gContestResources->field_18->unk0; else DestroyAnimVisualTask(taskId); // UB: function should return upon destroying task. } @@ -177,7 +177,7 @@ void sub_8158E9C(u8 taskId) if (IsContest()) { if (gBattleAnimArgs[0] == ANIM_ATTACKER) - species = gContestResources->field_18->field_0; + species = gContestResources->field_18->unk0; else DestroyAnimVisualTask(taskId); // UB: function should return upon destroying task. } @@ -281,7 +281,7 @@ void sub_81590B8(u8 taskId) pan = BattleAnimAdjustPanning(PAN_SIDE_PLAYER); if (IsContest()) - species = gContestResources->field_18->field_0; + species = gContestResources->field_18->unk0; else species = gAnimBattlerSpecies[gBattleAnimAttacker]; diff --git a/src/battle_gfx_sfx_util.c b/src/battle_gfx_sfx_util.c index b4dcf586d..80e1574a4 100644 --- a/src/battle_gfx_sfx_util.c +++ b/src/battle_gfx_sfx_util.c @@ -29,7 +29,7 @@ extern struct MusicPlayerInfo gMPlayInfo_SE2; extern struct MusicPlayerInfo gMPlayInfo_BGM; extern const u8 gUnknown_0831C604[]; -extern const u8 * const gBattleAnims_VariousTable[]; +extern const u8 * const gBattleAnims_General[]; extern const u8 * const gBattleAnims_Special[]; extern const struct CompressedSpriteSheet gMonFrontPicTable[]; extern const struct CompressedSpriteSheet gMonBackPicTable[]; @@ -437,7 +437,7 @@ bool8 TryHandleLaunchBattleTableAnimation(u8 activeBattler, u8 atkBattler, u8 de gBattleAnimAttacker = atkBattler; gBattleAnimTarget = defBattler; gBattleSpritesDataPtr->animationData->animArg = argument; - LaunchBattleAnimation(gBattleAnims_VariousTable, tableId, FALSE); + LaunchBattleAnimation(gBattleAnims_General, tableId, FALSE); taskId = CreateTask(Task_ClearBitWhenBattleTableAnimDone, 10); gTasks[taskId].tBattlerId = activeBattler; gBattleSpritesDataPtr->healthBoxesData[gTasks[taskId].tBattlerId].animFromTableActive = 1; @@ -899,14 +899,14 @@ void HandleSpeciesGfxDataChange(u8 battlerAtk, u8 battlerDef, bool8 notTransform if (IsContest()) { position = 0; - targetSpecies = gContestResources->field_18->field_2; - personalityValue = gContestResources->field_18->field_8; - otId = gContestResources->field_18->field_C; + targetSpecies = gContestResources->field_18->unk2; + personalityValue = gContestResources->field_18->unk8; + otId = gContestResources->field_18->unkC; HandleLoadSpecialPokePic_DontHandleDeoxys(&gMonBackPicTable[targetSpecies], gMonSpritesGfxPtr->sprites[0], targetSpecies, - gContestResources->field_18->field_10); + gContestResources->field_18->unk10); } else { diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 10b432d8e..0422c11e3 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -3,6 +3,7 @@ #include "constants/battle_move_effects.h" #include "constants/battle_script_commands.h" #include "battle_message.h" +#include "battle_anim.h" #include "battle_ai_script_commands.h" #include "battle_scripts.h" #include "constants/moves.h" @@ -4381,16 +4382,16 @@ static void atk47_setgraphicalstatchangevalues(void) switch (GET_STAT_BUFF_VALUE2(gBattleScripting.statChanger)) { case SET_STAT_BUFF_VALUE(1): // +1 - value = 0xF; + value = STAT_ANIM_PLUS1; break; case SET_STAT_BUFF_VALUE(2): // +2 - value = 0x27; + value = STAT_ANIM_PLUS2; break; case SET_STAT_BUFF_VALUE(1) | STAT_BUFF_NEGATIVE: // -1 - value = 0x16; + value = STAT_ANIM_MINUS1; break; case SET_STAT_BUFF_VALUE(2) | STAT_BUFF_NEGATIVE: // -2 - value = 0x2E; + value = STAT_ANIM_MINUS2; break; } gBattleScripting.animArg1 = GET_STAT_BUFF_ID(gBattleScripting.statChanger) + value - 1; @@ -4412,9 +4413,9 @@ static void atk48_playstatchangeanimation(void) { s16 startingStatAnimId; if (gBattlescriptCurrInstr[3] & ATK48_STAT_BY_TWO) - startingStatAnimId = 0x2D; + startingStatAnimId = STAT_ANIM_MINUS2 - 1; else - startingStatAnimId = 0x15; + startingStatAnimId = STAT_ANIM_MINUS1 - 1; while (statsToCheck != 0) { @@ -4447,18 +4448,18 @@ static void atk48_playstatchangeanimation(void) if (changeableStatsCount > 1) // more than one stat, so the color is gray { if (gBattlescriptCurrInstr[3] & ATK48_STAT_BY_TWO) - statAnimId = 0x3A; + statAnimId = STAT_ANIM_MULTIPLE_MINUS2; else - statAnimId = 0x39; + statAnimId = STAT_ANIM_MULTIPLE_MINUS1; } } else // goes up { s16 startingStatAnimId; if (gBattlescriptCurrInstr[3] & ATK48_STAT_BY_TWO) - startingStatAnimId = 0x26; + startingStatAnimId = STAT_ANIM_PLUS2 - 1; else - startingStatAnimId = 0xE; + startingStatAnimId = STAT_ANIM_PLUS1 - 1; while (statsToCheck != 0) { @@ -4473,9 +4474,9 @@ static void atk48_playstatchangeanimation(void) if (changeableStatsCount > 1) // more than one stat, so the color is gray { if (gBattlescriptCurrInstr[3] & ATK48_STAT_BY_TWO) - statAnimId = 0x38; + statAnimId = STAT_ANIM_MULTIPLE_PLUS2; else - statAnimId = 0x37; + statAnimId = STAT_ANIM_MULTIPLE_PLUS1; } } diff --git a/src/contest.c b/src/contest.c index 910637387..8eacc89c3 100644 --- a/src/contest.c +++ b/src/contest.c @@ -2535,7 +2535,7 @@ u8 sub_80DB174(u16 species, u32 otId, u32 personality, u32 index) LoadCompressedPalette(GetFrontSpritePalFromSpeciesAndPersonality(species, otId, personality), 0x120, 0x20); SetMultiuseSpriteTemplateToPokemon(species, 0); - spriteId = CreateSprite(&gMultiuseSpriteTemplate, 0x70, sub_80A600C(2, species, 0), 30); + spriteId = CreateSprite(&gMultiuseSpriteTemplate, 0x70, GetBattlerSpriteFinal_Y(2, species, FALSE), 30); gSprites[spriteId].oam.paletteNum = 2; gSprites[spriteId].oam.priority = 2; gSprites[spriteId].subpriority = sub_80A82E4(2); diff --git a/src/data/pokemon_graphics/back_pic_coordinates.h b/src/data/pokemon_graphics/back_pic_coordinates.h index f54b409e4..877bf3475 100644 --- a/src/data/pokemon_graphics/back_pic_coordinates.h +++ b/src/data/pokemon_graphics/back_pic_coordinates.h @@ -1,4 +1,4 @@ -const struct MonCoords gUnknown_083021D8[] = +const struct MonCoords gMonBackPicCoords[] = { {0x88, 0x00}, // SPECIES_NONE {0x64, 0x10}, // SPECIES_BULBASAUR diff --git a/src/intro.c b/src/intro.c index f21ad348d..e1d61242c 100644 --- a/src/intro.c +++ b/src/intro.c @@ -25,6 +25,7 @@ #include "blend_palette.h" #include "title_screen.h" #include "constants/rgb.h" +#include "constants/battle_anim.h" extern const struct CompressedSpriteSheet gBattleAnimPicTable[]; extern const struct CompressedSpritePalette gBattleAnimPaletteTable[]; @@ -118,7 +119,7 @@ static const struct SpriteTemplate gUnknown_085E4AB8 = }; static const u8 gUnknown_085E4AD0[][2] = { - {0x7C, 0x28}, + {0x7C, 0x28}, {0x66, 0x1E}, {0x4D, 0x1E}, {0x36, 0x0F}, @@ -664,25 +665,25 @@ static const s16 gUnknown_085E4E94[][2] = {5, 20}, {3, 28}, }; -static const union AffineAnimCmd gUnknown_085E4ED8[] = +static const union AffineAnimCmd gUnknown_085E4ED8[] = { AFFINEANIMCMD_FRAME(128, 128, 0, 0), AFFINEANIMCMD_END, }; -static const union AffineAnimCmd gUnknown_085E4EE8[] = +static const union AffineAnimCmd gUnknown_085E4EE8[] = { AFFINEANIMCMD_FRAME(128, 128, 0, 0), AFFINEANIMCMD_FRAME(16, 16, 0, 16), AFFINEANIMCMD_FRAME(-16, -16, 0, 8), AFFINEANIMCMD_END, }; -static const union AffineAnimCmd gUnknown_085E4F08[] = +static const union AffineAnimCmd gUnknown_085E4F08[] = { AFFINEANIMCMD_FRAME(256, 256, 0, 0), AFFINEANIMCMD_FRAME(8, 8, 0, 48), AFFINEANIMCMD_END, }; -static const union AffineAnimCmd gUnknown_085E4F20[] = +static const union AffineAnimCmd gUnknown_085E4F20[] = { AFFINEANIMCMD_FRAME(256, 256, 0, 0), AFFINEANIMCMD_FRAME(2, 2, 0, 48), @@ -695,7 +696,7 @@ static const union AffineAnimCmd *const gUnknown_085E4F38[] = gUnknown_085E4F08, gUnknown_085E4F20, }; -static const u16 gUnknown_085E4F48[] = +static const u16 gUnknown_085E4F48[] = { 0x100, 0xC0, 0x80, 0x40, 0x00, 0x40, 0x80, 0xC0, 0x100 }; @@ -1086,10 +1087,10 @@ static void Task_IntroWaterDrops(u8 taskId) if (gIntroFrameCounter == 256) CreateTask(Task_IntroWaterDrops_2, 0); - + if (gIntroFrameCounter == 368) CreateWaterDrop(48, 0, 0x400, 5, 0x70, TRUE); - + if (gIntroFrameCounter == 384) CreateWaterDrop(200, 60, 0x400, 9, 0x80, TRUE); @@ -1113,7 +1114,7 @@ static void Task_IntroWaterDrops_3(u8 taskId) s16 *data = gTasks[taskId].data; if (++data[2] & 1) data[3]++; - + switch (data[0]) { case 0: @@ -1127,7 +1128,7 @@ static void Task_IntroWaterDrops_3(u8 taskId) data[0] = 0; break; } - + if (data[3] > 0x3C) DestroyTask(taskId); } @@ -1206,25 +1207,25 @@ static void Task_IntroStartBikeRide(u8 taskId) LoadCompressedObjectPic(gIntro2BrendanSpriteSheet); else LoadCompressedObjectPic(gIntro2MaySpriteSheet); - + LoadCompressedObjectPic(gIntro2BicycleSpriteSheet); LoadCompressedObjectPic(gIntro2FlygonSpriteSheet); - + for (spriteId = 0; spriteId < 3; spriteId++) { LoadCompressedObjectPic(&gUnknown_085E4AE8[spriteId]); } - + LoadSpritePalettes(gUnknown_085F530C); LoadSpritePalettes(gUnknown_085E4B08); CreateSprite(&gUnknown_085E4BDC, 0x110, 0x80, 0); CreateSprite(&gUnknown_085E4BA4, 0x120, 0x6E, 1); - + if (gUnknown_0203BCC8 == 0) spriteId = intro_create_brendan_sprite(0x110, 100); else spriteId = intro_create_may_sprite(0x110, 100); - + gSprites[spriteId].callback = sub_816F9D4; gSprites[spriteId].anims = gUnknown_085E4DC4; gTasks[taskId].data[1] = spriteId; @@ -1243,7 +1244,7 @@ static void Task_IntroHandleBikeAndFlygonMovement(u8 taskId) { s16 a; u16 sine; - + if (gIntroFrameCounter == 1856) { gUnknown_0203BD28 = 2; @@ -1427,7 +1428,7 @@ static void sub_816D9C0(struct Sprite *sprite) case 4: if (sprite->animEnded) sprite->pos1.x += 4; - + if (sprite->pos1.x > 336) { StartSpriteAnim(sprite, 1); @@ -1506,7 +1507,7 @@ static void Task_IntroLoadPart3Graphics(u8 taskId) static void Task_IntroSpinAndZoomPokeball(u8 taskId) { gTasks[taskId].data[0] += 0x400; - + if (gTasks[taskId].data[1] <= 0x6BF) { gTasks[taskId].data[1] += gTasks[taskId].data[2]; @@ -1516,9 +1517,9 @@ static void Task_IntroSpinAndZoomPokeball(u8 taskId) { gTasks[taskId].func = Task_IntroWaitToSetupPart3LegendsFight; } - + sub_816F2A8(0x78, 0x50, 0x10000 / gTasks[taskId].data[1], gTasks[taskId].data[0]); - + if (gIntroFrameCounter == 28) BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 0x10, RGB_WHITEALPHA); } @@ -1531,8 +1532,6 @@ static void Task_IntroWaitToSetupPart3LegendsFight(u8 taskId) static void Task_IntroLoadPart1Graphics3(u8 taskId) { - u16 i; - if (!gPaletteFade.active) { intro_reset_and_hide_bgs(); @@ -1543,8 +1542,8 @@ static void Task_IntroLoadPart1Graphics3(u8 taskId) LZDecompressVram(gIntro3GroudonTilemap, (void *)(VRAM + 0xC000)); LZDecompressVram(gIntro3LegendBgGfx, (void *)(VRAM + 0x4000)); LZDecompressVram(gIntro3GroudonBgTilemap, (void *)(VRAM + 0xE000)); - LoadCompressedObjectPicUsingHeap(&gBattleAnimPicTable[0x3A]); - LoadCompressedObjectPaletteUsingHeap(&gBattleAnimPaletteTable[0x3A]); + LoadCompressedObjectPicUsingHeap(&gBattleAnimPicTable[GET_TRUE_SPRITE_INDEX(ANIM_TAG_058)]); + LoadCompressedObjectPaletteUsingHeap(&gBattleAnimPaletteTable[GET_TRUE_SPRITE_INDEX(ANIM_TAG_058)]); CpuCopy16(gIntro3BgPal, gPlttBufferUnfaded, sizeof(gIntro3BgPal)); gTasks[taskId].func = Task_IntroLoadPart1Graphics4; } @@ -1584,12 +1583,10 @@ static void Task_IntroLoadPart1Graphics4(u8 taskId) static void Task_IntroLoadPart1Graphics5(u8 taskId) { - u16 foo = gTasks[taskId].data[0]; - if (gTasks[taskId].data[0] != 32) { gTasks[taskId].data[0] += 4; - SetGpuReg(REG_OFFSET_WIN0V, (gTasks[taskId].data[0] * 256) - (foo -= 0x9C)); + SetGpuReg(REG_OFFSET_WIN0V, (gTasks[taskId].data[0] * 256) - (gTasks[taskId].data[0] - 160)); } else { @@ -1613,7 +1610,7 @@ static void Task_IntroLoadPart1Graphics7(u8 taskId) static void Task_IntroLoadPart1Graphics8(u8 taskId) { s16 *data = gTasks[taskId].data; - + data[5]++; if ((u16)(data[0] - 1) < 7 && data[5] % 2 == 0) data[4] ^= 3; @@ -1720,7 +1717,7 @@ static void sub_816E190(u8 a0) { int i; u8 spriteId; - + for (i = 0; i < 6; i++) { spriteId = CreateSprite(gUnknown_08596C10, gUnknown_085E4C64[i][0], 0xA0, i); @@ -1737,7 +1734,7 @@ static void sub_816E1F8(struct Sprite *sprite) sprite->data[3]++; if (sprite->data[3] % 2 == 0) sprite->pos2.y ^= 3; - + switch(sprite->data[0]) { case 0: @@ -1752,7 +1749,7 @@ static void sub_816E1F8(struct Sprite *sprite) sprite->pos1.x -= 2; else sprite->pos1.x += 2; - + if (sprite->pos1.y < 0x50) sprite->pos1.y -= 2; else @@ -1783,9 +1780,9 @@ static void Task_IntroLoadPart1Graphics9(u8 taskId) static void Task_IntroFadeIn0(u8 taskId) { s16 *data = gTasks[taskId].data; - + sub_816F2A8(data[1], data[2], data[3], 0); - + switch (data[0]) { case 0: @@ -1928,7 +1925,7 @@ static void sub_816E6D4(u8 a0) { int i; u8 spriteId; - + for (i = 0; i < 6; i++) { spriteId = CreateSprite(&gUnknown_085E4D14, gUnknown_085E4CA8[i][0], gUnknown_085E4CA8[i][1], i); @@ -1943,7 +1940,7 @@ static void sub_816E74C(void) { int i; u8 spriteId; - + for (i = 0; i < 6; i++) { spriteId = CreateSprite(&gUnknown_085E4D14, gUnknown_085E4CA8[i + 6][0], gUnknown_085E4CA8[i + 6][1], i); @@ -1980,7 +1977,7 @@ static void sub_816E7B4(struct Sprite *sprite) sprite->pos1.x -= 3; else sprite->pos1.x += 3; - + if (sprite->pos1.y < 80) sprite->pos1.y -= 3; else @@ -2053,10 +2050,10 @@ static void Task_IntroFadeIn3(u8 taskId) static void Task_IntroFadeIn4(u8 taskId) { s16 *data = gTasks[taskId].data; - + SetGpuReg(REG_OFFSET_BG0HOFS, (data[6] >> 8)); SetGpuReg(REG_OFFSET_BG1HOFS, -(data[6] >> 8)); - + switch (data[0]) { case 0: @@ -2070,7 +2067,7 @@ static void Task_IntroFadeIn4(u8 taskId) case 1: if (data[6] == 0x2800) BeginNormalPaletteFade(0x0000FFFE, 3, 0, 16, RGB(9, 10, 10)); - + if (data[6] != 0) data[6] -= 0x80; else if (!gPaletteFade.active) @@ -2103,7 +2100,7 @@ static void Task_IntroFadeIn6(u8 taskId) { s16 *data = gTasks[taskId].data; u8 spriteId; - + switch (data[0]) { case 0: @@ -2141,7 +2138,7 @@ static void sub_816EC6C(struct Sprite *sprite) { if (sprite->animEnded) sprite->invisible = TRUE; - + switch(sprite->data[0]) { case 0: @@ -2171,7 +2168,7 @@ static void sub_816EC6C(struct Sprite *sprite) static void Task_IntroFadeIn7(u8 taskId) { u8 newTaskId; - + LoadCompressedObjectPic(gUnknown_085E5048); LoadSpritePalettes(gUnknown_085E5058); SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_MODE_0 @@ -2194,12 +2191,12 @@ static void Task_IntroFadeIn7(u8 taskId) static void Task_IntroFadeIn8(u8 taskId) { s16 *data = gTasks[taskId].data; - + if (data[7] % 2 == 0) data[6] ^= 2; - + data[7]++; - + switch(data[0]) { case 0: @@ -2248,9 +2245,9 @@ static void sub_816EEA8(u8 taskId) { u8 spriteId; s16 *data = gTasks[taskId].data; - + data[2]++; - + switch(data[0]) { case 0: @@ -2377,7 +2374,7 @@ static void Task_IntroWaterDrops_1(u8 taskId) if (gTasks[taskId].data[1] != 0) { u8 tmp; - + gTasks[taskId].data[1]--; tmp = gTasks[taskId].data[1] / 2; SetGpuReg(REG_OFFSET_BLDALPHA, gUnknown_0853FF70[tmp]); @@ -2420,7 +2417,7 @@ static void Task_IntroWaterDrops_2(u8 taskId) if (gTasks[taskId].data[1] < 62) { u8 tmp; - + gTasks[taskId].data[1]++; tmp = gTasks[taskId].data[1] / 2; SetGpuReg(REG_OFFSET_BLDALPHA, gUnknown_0853FF70[tmp]); @@ -2903,7 +2900,7 @@ static u8 sub_816FDB8(s16 a0, s16 a1, s16 a2) { u16 i; u8 spriteId; - + for (i = 0; i < 9; i++) { spriteId = CreateSprite(&gUnknown_085E4F5C, gUnknown_085E4E94[i][1] + a0, a1 - 4, 0); @@ -2926,7 +2923,7 @@ static u8 sub_816FDB8(s16 a0, s16 a1, s16 a2) static void sub_816FEDC(struct Sprite *sprite) { sprite->data[7]++; - + if (sprite->data[0] != 0) { s16 sin1; @@ -2944,7 +2941,7 @@ static void sub_816FEDC(struct Sprite *sprite) SetOamMatrix(1, a, b, c, d); } - + switch (sprite->data[0]) { case 0: diff --git a/src/item_menu_icons.c b/src/item_menu_icons.c index f12bb454e..5dd5fd31d 100644 --- a/src/item_menu_icons.c +++ b/src/item_menu_icons.c @@ -19,10 +19,10 @@ struct CompressedTilesPal const u8 *pal; }; -extern void sub_80D5860(struct Sprite *sprite); -extern void sub_80D58F8(struct Sprite *sprite); -extern void sub_80D5968(struct Sprite *sprite); -extern void sub_80D5A94(struct Sprite *sprite); +extern void DoHorizontalLunge(struct Sprite *sprite); +extern void DoVerticalDip(struct Sprite *sprite); +extern void SlideMonToOriginalPos(struct Sprite *sprite); +extern void SlideMonToOffset(struct Sprite *sprite); extern void sub_80D5B48(struct Sprite *sprite); // this file's functions @@ -414,7 +414,7 @@ static const struct SpriteTemplate gUnknown_0857FE10 = .callback = SpriteCallbackDummy, }; -const struct SpriteTemplate gUnknown_0857FE28 = +const struct SpriteTemplate gHorizontalLungeSpriteTemplate = { .tileTag = 0, .paletteTag = 0, @@ -422,10 +422,10 @@ const struct SpriteTemplate gUnknown_0857FE28 = .anims = gDummySpriteAnimTable, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, - .callback = sub_80D5860, + .callback = DoHorizontalLunge, }; -const struct SpriteTemplate gUnknown_0857FE40 = +const struct SpriteTemplate gVerticalDipSpriteTemplate = { .tileTag = 0, .paletteTag = 0, @@ -433,10 +433,10 @@ const struct SpriteTemplate gUnknown_0857FE40 = .anims = gDummySpriteAnimTable, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, - .callback = sub_80D58F8, + .callback = DoVerticalDip, }; -const struct SpriteTemplate gUnknown_0857FE58 = +const struct SpriteTemplate gSlideMonToOriginalPosSpriteTemplate = { .tileTag = 0, .paletteTag = 0, @@ -444,10 +444,10 @@ const struct SpriteTemplate gUnknown_0857FE58 = .anims = gDummySpriteAnimTable, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, - .callback = sub_80D5968, + .callback = SlideMonToOriginalPos, }; -const struct SpriteTemplate gUnknown_0857FE70 = +const struct SpriteTemplate gSlideMonToOffsetSpriteTemplate = { .tileTag = 0, .paletteTag = 0, @@ -455,7 +455,7 @@ const struct SpriteTemplate gUnknown_0857FE70 = .anims = gDummySpriteAnimTable, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, - .callback = sub_80D5A94, + .callback = SlideMonToOffset, }; const struct SpriteTemplate gUnknown_0857FE88 = diff --git a/src/main.c b/src/main.c index f04f9b61b..4c71ed1f9 100644 --- a/src/main.c +++ b/src/main.c @@ -33,7 +33,7 @@ static void VCountIntr(void); static void SerialIntr(void); static void IntrDummy(void); -const u8 gGameVersion = VERSION_EMERALD; +const u8 gGameVersion = GAME_VERSION; const u8 gGameLanguage = GAME_LANGUAGE; // English diff --git a/src/pokeball.c b/src/pokeball.c index 3dbbb2967..bb02a02ba 100644 --- a/src/pokeball.c +++ b/src/pokeball.c @@ -378,8 +378,8 @@ static void Task_DoPokeballSendOutAnim(u8 taskId) gSprites[ballSpriteId].callback = SpriteCB_PlayerMonSendOut_1; break; case POKEBALL_OPPONENT_SENDOUT: - gSprites[ballSpriteId].pos1.x = GetBattlerSpriteCoord(battlerId, BANK_X_POS); - gSprites[ballSpriteId].pos1.y = GetBattlerSpriteCoord(battlerId, BANK_Y_POS) + 24; + gSprites[ballSpriteId].pos1.x = GetBattlerSpriteCoord(battlerId, BATTLER_COORD_X); + gSprites[ballSpriteId].pos1.y = GetBattlerSpriteCoord(battlerId, BATTLER_COORD_Y) + 24; gBattlerTarget = battlerId; gSprites[ballSpriteId].data[0] = 0; gSprites[ballSpriteId].callback = SpriteCB_OpponentMonSendOut; @@ -399,8 +399,8 @@ static void Task_DoPokeballSendOutAnim(u8 taskId) // this will perform an unused ball throw animation gSprites[ballSpriteId].data[0] = 0x22; - gSprites[ballSpriteId].data[2] = GetBattlerSpriteCoord(gBattlerTarget, BANK_X_POS); - gSprites[ballSpriteId].data[4] = GetBattlerSpriteCoord(gBattlerTarget, BANK_Y_POS) - 16; + gSprites[ballSpriteId].data[2] = GetBattlerSpriteCoord(gBattlerTarget, BATTLER_COORD_X); + gSprites[ballSpriteId].data[4] = GetBattlerSpriteCoord(gBattlerTarget, BATTLER_COORD_Y) - 16; gSprites[ballSpriteId].data[5] = -40; sub_80A68D4(&gSprites[ballSpriteId]); gSprites[ballSpriteId].oam.affineParam = taskId; @@ -411,7 +411,7 @@ static void Task_DoPokeballSendOutAnim(u8 taskId) static void SpriteCB_TestBallThrow(struct Sprite *sprite) { - if (AnimateBallThrow(sprite)) + if (TranslateAnimArc(sprite)) { u16 ballId; u8 taskId = sprite->oam.affineParam; @@ -922,7 +922,7 @@ static void SpriteCB_PlayerMonSendOut_2(struct Sprite *sprite) StartSpriteAffineAnim(sprite, 4); } r4 = sprite->data[0]; - sub_80A6F3C(sprite); + TranslateAnimLinear(sprite); sprite->data[7] += sprite->sBattler / 3; sprite->pos2.y += Sin(HIBYTE(sprite->data[7]), sprite->data[5]); sprite->oam.affineParam += 0x100; @@ -940,7 +940,7 @@ static void SpriteCB_PlayerMonSendOut_2(struct Sprite *sprite) } else { - if (AnimateBallThrow(sprite)) + if (TranslateAnimArc(sprite)) { sprite->pos1.x += sprite->pos2.x; sprite->pos1.y += sprite->pos2.y; |