pokeemerald/src/battle_anim.c

1854 lines
49 KiB
C
Raw Normal View History

2017-10-14 16:55:25 +02:00
#include "global.h"
#include "battle.h"
#include "battle_anim.h"
2018-11-13 23:28:46 +01:00
#include "battle_controllers.h"
2017-10-14 16:55:25 +02:00
#include "battle_interface.h"
2018-11-13 23:28:46 +01:00
#include "bg.h"
#include "contest.h"
2017-10-14 16:55:25 +02:00
#include "decompress.h"
#include "dma3.h"
#include "gpu_regs.h"
2018-11-13 23:28:46 +01:00
#include "graphics.h"
2017-10-14 23:37:44 +02:00
#include "main.h"
2018-11-13 23:28:46 +01:00
#include "m4a.h"
#include "palette.h"
#include "pokemon.h"
#include "sound.h"
#include "sprite.h"
#include "task.h"
#include "constants/battle_anim.h"
2017-10-14 16:55:25 +02:00
/*
This file handles the commands for the macros defined in
battle_anim_script.inc and used in battle_anim_scripts.s
*/
2017-10-14 16:55:25 +02:00
#define ANIM_SPRITE_INDEX_COUNT 8
2018-09-10 21:19:19 +02:00
extern const u16 gMovesWithQuietBGM[];
2018-09-15 00:30:20 +02:00
extern const u8 *const gBattleAnims_Moves[];
2017-10-14 16:55:25 +02:00
static void Cmd_loadspritegfx(void);
static void Cmd_unloadspritegfx(void);
static void Cmd_createsprite(void);
static void Cmd_createvisualtask(void);
static void Cmd_delay(void);
static void Cmd_waitforvisualfinish(void);
static void Cmd_nop(void);
static void Cmd_nop2(void);
static void Cmd_end(void);
static void Cmd_playse(void);
static void Cmd_monbg(void);
static void Cmd_clearmonbg(void);
static void Cmd_setalpha(void);
static void Cmd_blendoff(void);
static void Cmd_call(void);
static void Cmd_return(void);
static void Cmd_setarg(void);
static void Cmd_choosetwoturnanim(void);
static void Cmd_jumpifmoveturn(void);
static void Cmd_goto(void);
static void Cmd_fadetobg(void);
static void Cmd_restorebg(void);
static void Cmd_waitbgfadeout(void);
static void Cmd_waitbgfadein(void);
static void Cmd_changebg(void);
static void Cmd_playsewithpan(void);
static void Cmd_setpan(void);
static void Cmd_panse(void);
static void Cmd_loopsewithpan(void);
static void Cmd_waitplaysewithpan(void);
static void Cmd_setbldcnt(void);
static void Cmd_createsoundtask(void);
static void Cmd_waitsound(void);
static void Cmd_jumpargeq(void);
static void Cmd_monbg_static(void);
static void Cmd_clearmonbg_static(void);
static void Cmd_jumpifcontest(void);
static void Cmd_fadetobgfromset(void);
static void Cmd_panse_adjustnone(void);
static void Cmd_panse_adjustall(void);
static void Cmd_splitbgprio(void);
static void Cmd_splitbgprio_all(void);
static void Cmd_splitbgprio_foes(void);
static void Cmd_invisible(void);
static void Cmd_visible(void);
static void Cmd_teamattack_moveback(void);
static void Cmd_teamattack_movefwd(void);
static void Cmd_stopsound(void);
2017-10-15 23:21:59 +02:00
static void RunAnimScriptCommand(void);
static void Task_UpdateMonBg(u8 taskId);
2021-10-04 16:21:03 +02:00
static void FlipBattlerBgTiles(void);
static void Task_ClearMonBg(u8 taskId);
static void Task_ClearMonBgStatic(u8 taskId);
2017-10-15 23:21:59 +02:00
static void Task_FadeToBg(u8 taskId);
static void Task_PanFromInitialToTarget(u8 taskId);
static void Task_LoopAndPlaySE(u8 taskId);
static void Task_WaitAndPlaySE(u8 taskId);
static void LoadDefaultBg(void);
static void LoadMoveBg(u16 bgId);
EWRAM_DATA static const u8 *sBattleAnimScriptPtr = NULL;
EWRAM_DATA static const u8 *sBattleAnimScriptRetAddr = NULL;
EWRAM_DATA void (*gAnimScriptCallback)(void) = NULL;
2021-10-04 16:21:03 +02:00
EWRAM_DATA static s8 sAnimFramesToWait = 0;
2017-10-15 23:21:59 +02:00
EWRAM_DATA bool8 gAnimScriptActive = FALSE;
EWRAM_DATA u8 gAnimVisualTaskCount = 0;
EWRAM_DATA u8 gAnimSoundTaskCount = 0;
EWRAM_DATA struct DisableStruct *gAnimDisableStructPtr = NULL;
2018-10-07 17:45:37 +02:00
EWRAM_DATA s32 gAnimMoveDmg = 0;
2017-10-15 23:21:59 +02:00
EWRAM_DATA u16 gAnimMovePower = 0;
EWRAM_DATA static u16 sAnimSpriteIndexArray[ANIM_SPRITE_INDEX_COUNT] = {0};
EWRAM_DATA u8 gAnimFriendship = 0;
EWRAM_DATA u16 gWeatherMoveAnim = 0;
EWRAM_DATA s16 gBattleAnimArgs[ANIM_ARGS_COUNT] = {0};
EWRAM_DATA static u16 sSoundAnimFramesToWait = 0;
EWRAM_DATA static u8 sMonAnimTaskIdArray[2] = {0};
EWRAM_DATA u8 gAnimMoveTurn = 0;
EWRAM_DATA static u8 sAnimBackgroundFadeState = 0;
2018-06-17 16:48:58 +02:00
EWRAM_DATA static u16 sAnimMoveIndex = 0; // Set but unused.
2018-02-06 20:48:02 +01:00
EWRAM_DATA u8 gBattleAnimAttacker = 0;
EWRAM_DATA u8 gBattleAnimTarget = 0;
2018-04-18 16:03:15 +02:00
EWRAM_DATA u16 gAnimBattlerSpecies[MAX_BATTLERS_COUNT] = {0};
2020-02-20 06:04:42 +01:00
EWRAM_DATA u8 gAnimCustomPanning = 0;
2017-10-15 23:21:59 +02:00
#include "data/battle_anim.h"
2018-10-22 04:30:20 +02:00
2017-10-15 23:21:59 +02:00
static void (* const sScriptCmdTable[])(void) =
{
Cmd_loadspritegfx, // 0x00
Cmd_unloadspritegfx, // 0x01
Cmd_createsprite, // 0x02
Cmd_createvisualtask, // 0x03
Cmd_delay, // 0x04
Cmd_waitforvisualfinish, // 0x05
Cmd_nop, // 0x06
Cmd_nop2, // 0x07
Cmd_end, // 0x08
Cmd_playse, // 0x09
Cmd_monbg, // 0x0A
Cmd_clearmonbg, // 0x0B
Cmd_setalpha, // 0x0C
Cmd_blendoff, // 0x0D
Cmd_call, // 0x0E
Cmd_return, // 0x0F
Cmd_setarg, // 0x10
Cmd_choosetwoturnanim, // 0x11
Cmd_jumpifmoveturn, // 0x12
Cmd_goto, // 0x13
Cmd_fadetobg, // 0x14
Cmd_restorebg, // 0x15
Cmd_waitbgfadeout, // 0x16
Cmd_waitbgfadein, // 0x17
Cmd_changebg, // 0x18
Cmd_playsewithpan, // 0x19
Cmd_setpan, // 0x1A
Cmd_panse, // 0x1B
Cmd_loopsewithpan, // 0x1C
Cmd_waitplaysewithpan, // 0x1D
Cmd_setbldcnt, // 0x1E
Cmd_createsoundtask, // 0x1F
Cmd_waitsound, // 0x20
Cmd_jumpargeq, // 0x21
Cmd_monbg_static, // 0x22
Cmd_clearmonbg_static, // 0x23
Cmd_jumpifcontest, // 0x24
Cmd_fadetobgfromset, // 0x25
Cmd_panse_adjustnone, // 0x26
Cmd_panse_adjustall, // 0x27
Cmd_splitbgprio, // 0x28
Cmd_splitbgprio_all, // 0x29
Cmd_splitbgprio_foes, // 0x2A
Cmd_invisible, // 0x2B
Cmd_visible, // 0x2C
Cmd_teamattack_moveback, // 0x2D
Cmd_teamattack_movefwd, // 0x2E
Cmd_stopsound, // 0x2F
2017-10-15 23:21:59 +02:00
};
2017-10-14 16:55:25 +02:00
void ClearBattleAnimationVars(void)
{
s32 i;
2021-10-04 16:21:03 +02:00
sAnimFramesToWait = 0;
2017-10-14 16:55:25 +02:00
gAnimScriptActive = FALSE;
gAnimVisualTaskCount = 0;
gAnimSoundTaskCount = 0;
gAnimDisableStructPtr = NULL;
gAnimMoveDmg = 0;
gAnimMovePower = 0;
gAnimFriendship = 0;
2018-06-17 16:48:58 +02:00
// Clear index array.
2017-10-14 16:55:25 +02:00
for (i = 0; i < ANIM_SPRITE_INDEX_COUNT; i++)
2019-01-13 12:12:27 +01:00
sAnimSpriteIndexArray[i] = 0xFFFF;
2017-10-14 16:55:25 +02:00
2018-06-17 16:48:58 +02:00
// Clear anim args.
2017-10-14 16:55:25 +02:00
for (i = 0; i < ANIM_ARGS_COUNT; i++)
gBattleAnimArgs[i] = 0;
2021-02-20 05:22:26 +01:00
sMonAnimTaskIdArray[0] = TASK_NONE;
sMonAnimTaskIdArray[1] = TASK_NONE;
2017-10-14 23:37:44 +02:00
gAnimMoveTurn = 0;
2017-10-15 23:21:59 +02:00
sAnimBackgroundFadeState = 0;
sAnimMoveIndex = 0;
2018-02-06 20:48:02 +01:00
gBattleAnimAttacker = 0;
gBattleAnimTarget = 0;
2020-02-20 06:04:42 +01:00
gAnimCustomPanning = 0;
2017-10-14 16:55:25 +02:00
}
void DoMoveAnim(u16 move)
{
2018-02-06 23:09:39 +01:00
gBattleAnimAttacker = gBattlerAttacker;
gBattleAnimTarget = gBattlerTarget;
2017-10-22 18:43:15 +02:00
LaunchBattleAnimation(gBattleAnims_Moves, move, TRUE);
2017-10-14 16:55:25 +02:00
}
2017-10-22 18:43:15 +02:00
void LaunchBattleAnimation(const u8 *const animsTable[], u16 tableId, bool8 isMoveAnim)
2017-10-14 16:55:25 +02:00
{
s32 i;
if (!IsContest())
{
2021-10-04 16:21:03 +02:00
InitPrioritiesForVisibleBattlers();
2017-10-20 10:49:21 +02:00
UpdateOamPriorityInAllHealthboxes(0);
2018-02-06 02:46:59 +01:00
for (i = 0; i < MAX_BATTLERS_COUNT; i++)
2017-10-14 16:55:25 +02:00
{
if (GetBattlerSide(i) != B_SIDE_PLAYER)
2018-04-18 16:03:15 +02:00
gAnimBattlerSpecies[i] = GetMonData(&gEnemyParty[gBattlerPartyIndexes[i]], MON_DATA_SPECIES);
2017-10-14 16:55:25 +02:00
else
2018-04-18 16:03:15 +02:00
gAnimBattlerSpecies[i] = GetMonData(&gPlayerParty[gBattlerPartyIndexes[i]], MON_DATA_SPECIES);
2017-10-14 16:55:25 +02:00
}
}
else
{
2020-08-14 01:10:23 +02:00
for (i = 0; i < CONTESTANT_COUNT; i++)
gAnimBattlerSpecies[i] = gContestResources->moveAnim->species;
2017-10-14 16:55:25 +02:00
}
if (!isMoveAnim)
2017-10-15 23:21:59 +02:00
sAnimMoveIndex = 0;
2017-10-14 16:55:25 +02:00
else
2017-10-15 23:21:59 +02:00
sAnimMoveIndex = tableId;
2017-10-14 16:55:25 +02:00
for (i = 0; i < ANIM_ARGS_COUNT; i++)
gBattleAnimArgs[i] = 0;
2021-02-20 05:22:26 +01:00
sMonAnimTaskIdArray[0] = TASK_NONE;
sMonAnimTaskIdArray[1] = TASK_NONE;
2017-10-15 23:21:59 +02:00
sBattleAnimScriptPtr = animsTable[tableId];
2017-10-14 16:55:25 +02:00
gAnimScriptActive = TRUE;
2021-10-04 16:21:03 +02:00
sAnimFramesToWait = 0;
2017-10-14 16:55:25 +02:00
gAnimScriptCallback = RunAnimScriptCommand;
for (i = 0; i < ANIM_SPRITE_INDEX_COUNT; i++)
2019-01-13 12:12:27 +01:00
sAnimSpriteIndexArray[i] = 0xFFFF;
2017-10-14 16:55:25 +02:00
if (isMoveAnim)
{
for (i = 0; gMovesWithQuietBGM[i] != 0xFFFF; i++)
2017-10-14 16:55:25 +02:00
{
2018-09-10 21:19:19 +02:00
if (tableId == gMovesWithQuietBGM[i])
2017-10-14 16:55:25 +02:00
{
2021-10-09 17:33:37 +02:00
m4aMPlayVolumeControl(&gMPlayInfo_BGM, TRACKS_ALL, 128);
2017-10-14 16:55:25 +02:00
break;
}
}
}
gBattle_WIN0H = 0;
gBattle_WIN0V = 0;
gBattle_WIN1H = 0;
gBattle_WIN1V = 0;
}
void DestroyAnimSprite(struct Sprite *sprite)
{
FreeSpriteOamMatrix(sprite);
DestroySprite(sprite);
gAnimVisualTaskCount--;
}
void DestroyAnimVisualTask(u8 taskId)
{
DestroyTask(taskId);
gAnimVisualTaskCount--;
}
void DestroyAnimSoundTask(u8 taskId)
{
DestroyTask(taskId);
gAnimSoundTaskCount--;
}
2017-10-15 23:21:59 +02:00
static void AddSpriteIndex(u16 index)
2017-10-14 16:55:25 +02:00
{
s32 i;
for (i = 0; i < ANIM_SPRITE_INDEX_COUNT; i++)
{
if (sAnimSpriteIndexArray[i] == 0xFFFF)
2017-10-14 16:55:25 +02:00
{
2017-10-15 23:21:59 +02:00
sAnimSpriteIndexArray[i] = index;
2017-10-14 16:55:25 +02:00
return;
}
}
}
2017-10-15 23:21:59 +02:00
static void ClearSpriteIndex(u16 index)
2017-10-14 16:55:25 +02:00
{
s32 i;
for (i = 0; i < ANIM_SPRITE_INDEX_COUNT; i++)
{
2017-10-15 23:21:59 +02:00
if (sAnimSpriteIndexArray[i] == index)
2017-10-14 16:55:25 +02:00
{
2019-01-13 12:12:27 +01:00
sAnimSpriteIndexArray[i] = 0xFFFF;
2017-10-14 16:55:25 +02:00
return;
}
}
}
2017-10-15 23:21:59 +02:00
static void WaitAnimFrameCount(void)
2017-10-14 16:55:25 +02:00
{
2021-10-04 16:21:03 +02:00
if (sAnimFramesToWait <= 0)
2017-10-14 16:55:25 +02:00
{
gAnimScriptCallback = RunAnimScriptCommand;
2021-10-04 16:21:03 +02:00
sAnimFramesToWait = 0;
2017-10-14 16:55:25 +02:00
}
else
{
2021-10-04 16:21:03 +02:00
sAnimFramesToWait--;
2017-10-14 16:55:25 +02:00
}
}
2017-10-15 23:21:59 +02:00
static void RunAnimScriptCommand(void)
2017-10-14 16:55:25 +02:00
{
do
{
2017-10-15 23:21:59 +02:00
sScriptCmdTable[sBattleAnimScriptPtr[0]]();
2021-10-04 16:21:03 +02:00
} while (sAnimFramesToWait == 0 && gAnimScriptActive);
2017-10-14 16:55:25 +02:00
}
static void Cmd_loadspritegfx(void)
2017-10-14 16:55:25 +02:00
{
u16 index;
2017-10-15 23:21:59 +02:00
sBattleAnimScriptPtr++;
2018-03-01 00:59:52 +01:00
index = T1_READ_16(sBattleAnimScriptPtr);
2018-12-17 23:00:08 +01:00
LoadCompressedSpriteSheetUsingHeap(&gBattleAnimPicTable[GET_TRUE_SPRITE_INDEX(index)]);
LoadCompressedSpritePaletteUsingHeap(&gBattleAnimPaletteTable[GET_TRUE_SPRITE_INDEX(index)]);
2017-10-15 23:21:59 +02:00
sBattleAnimScriptPtr += 2;
2017-10-14 16:55:25 +02:00
AddSpriteIndex(GET_TRUE_SPRITE_INDEX(index));
2021-10-04 16:21:03 +02:00
sAnimFramesToWait = 1;
2017-10-14 16:55:25 +02:00
gAnimScriptCallback = WaitAnimFrameCount;
}
static void Cmd_unloadspritegfx(void)
2017-10-14 16:55:25 +02:00
{
u16 index;
2017-10-15 23:21:59 +02:00
sBattleAnimScriptPtr++;
2018-03-01 00:59:52 +01:00
index = T1_READ_16(sBattleAnimScriptPtr);
2017-10-14 16:55:25 +02:00
FreeSpriteTilesByTag(gBattleAnimPicTable[GET_TRUE_SPRITE_INDEX(index)].tag);
FreeSpritePaletteByTag(gBattleAnimPicTable[GET_TRUE_SPRITE_INDEX(index)].tag);
2017-10-15 23:21:59 +02:00
sBattleAnimScriptPtr += 2;
2017-10-14 16:55:25 +02:00
ClearSpriteIndex(GET_TRUE_SPRITE_INDEX(index));
}
static void Cmd_createsprite(void)
2017-10-14 16:55:25 +02:00
{
s32 i;
const struct SpriteTemplate *template;
u8 argVar;
u8 argsCount;
s16 subpriority;
2017-10-15 23:21:59 +02:00
sBattleAnimScriptPtr++;
2018-03-01 00:59:52 +01:00
template = (const struct SpriteTemplate *)(T2_READ_32(sBattleAnimScriptPtr));
2017-10-15 23:21:59 +02:00
sBattleAnimScriptPtr += 4;
2017-10-14 16:55:25 +02:00
2017-10-15 23:21:59 +02:00
argVar = sBattleAnimScriptPtr[0];
sBattleAnimScriptPtr++;
2017-10-14 16:55:25 +02:00
2017-10-15 23:21:59 +02:00
argsCount = sBattleAnimScriptPtr[0];
sBattleAnimScriptPtr++;
2017-10-14 16:55:25 +02:00
for (i = 0; i < argsCount; i++)
{
2018-03-01 00:59:52 +01:00
gBattleAnimArgs[i] = T1_READ_16(sBattleAnimScriptPtr);
2017-10-15 23:21:59 +02:00
sBattleAnimScriptPtr += 2;
2017-10-14 16:55:25 +02:00
}
if (argVar & ANIMSPRITE_IS_TARGET)
2017-10-14 16:55:25 +02:00
{
argVar ^= ANIMSPRITE_IS_TARGET;
if (argVar >= 64)
argVar -= 64;
2017-10-14 16:55:25 +02:00
else
argVar *= -1;
2018-12-18 05:08:08 +01:00
subpriority = GetBattlerSpriteSubpriority(gBattleAnimTarget) + (s8)(argVar);
2017-10-14 16:55:25 +02:00
}
else
{
if (argVar >= 64)
argVar -= 64;
2017-10-14 16:55:25 +02:00
else
argVar *= -1;
2018-12-18 05:08:08 +01:00
subpriority = GetBattlerSpriteSubpriority(gBattleAnimAttacker) + (s8)(argVar);
2017-10-14 16:55:25 +02:00
}
if (subpriority < 3)
subpriority = 3;
2018-12-20 04:13:26 +01:00
CreateSpriteAndAnimate(
template,
GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X_2),
GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y_PIC_OFFSET),
subpriority);
2017-10-14 16:55:25 +02:00
gAnimVisualTaskCount++;
}
static void Cmd_createvisualtask(void)
2017-10-14 16:55:25 +02:00
{
TaskFunc taskFunc;
u8 taskPriority;
u8 taskId;
u8 numArgs;
s32 i;
2017-10-15 23:21:59 +02:00
sBattleAnimScriptPtr++;
2017-10-14 16:55:25 +02:00
2018-03-01 00:59:52 +01:00
taskFunc = (TaskFunc)T2_READ_32(sBattleAnimScriptPtr);
2017-10-15 23:21:59 +02:00
sBattleAnimScriptPtr += 4;
2017-10-14 16:55:25 +02:00
2017-10-15 23:21:59 +02:00
taskPriority = sBattleAnimScriptPtr[0];
sBattleAnimScriptPtr++;
2017-10-14 16:55:25 +02:00
2017-10-15 23:21:59 +02:00
numArgs = sBattleAnimScriptPtr[0];
sBattleAnimScriptPtr++;
2017-10-14 16:55:25 +02:00
for (i = 0; i < numArgs; i++)
{
2018-03-01 00:59:52 +01:00
gBattleAnimArgs[i] = T1_READ_16(sBattleAnimScriptPtr);
2017-10-15 23:21:59 +02:00
sBattleAnimScriptPtr += 2;
2017-10-14 16:55:25 +02:00
}
taskId = CreateTask(taskFunc, taskPriority);
taskFunc(taskId);
gAnimVisualTaskCount++;
}
static void Cmd_delay(void)
2017-10-14 16:55:25 +02:00
{
2017-10-15 23:21:59 +02:00
sBattleAnimScriptPtr++;
2021-10-04 16:21:03 +02:00
sAnimFramesToWait = sBattleAnimScriptPtr[0];
if (sAnimFramesToWait == 0)
sAnimFramesToWait = -1;
2017-10-15 23:21:59 +02:00
sBattleAnimScriptPtr++;
2017-10-14 16:55:25 +02:00
gAnimScriptCallback = WaitAnimFrameCount;
}
2018-06-17 16:48:58 +02:00
// Wait for visual tasks to finish.
static void Cmd_waitforvisualfinish(void)
2017-10-14 16:55:25 +02:00
{
if (gAnimVisualTaskCount == 0)
{
2017-10-15 23:21:59 +02:00
sBattleAnimScriptPtr++;
2021-10-04 16:21:03 +02:00
sAnimFramesToWait = 0;
2017-10-14 16:55:25 +02:00
}
else
{
2021-10-04 16:21:03 +02:00
sAnimFramesToWait = 1;
2017-10-14 16:55:25 +02:00
}
}
static void Cmd_nop(void)
2017-10-14 16:55:25 +02:00
{
}
static void Cmd_nop2(void)
2017-10-14 16:55:25 +02:00
{
}
static void Cmd_end(void)
2017-10-14 16:55:25 +02:00
{
s32 i;
bool32 continuousAnim = FALSE;
2018-06-17 16:48:58 +02:00
// Keep waiting as long as there are animations to be done.
2017-10-14 16:55:25 +02:00
if (gAnimVisualTaskCount != 0 || gAnimSoundTaskCount != 0
2021-02-20 05:22:26 +01:00
|| sMonAnimTaskIdArray[0] != TASK_NONE || sMonAnimTaskIdArray[1] != TASK_NONE)
2017-10-14 16:55:25 +02:00
{
2017-10-15 23:21:59 +02:00
sSoundAnimFramesToWait = 0;
2021-10-04 16:21:03 +02:00
sAnimFramesToWait = 1;
2017-10-14 16:55:25 +02:00
return;
}
2018-06-17 16:48:58 +02:00
// Finish the sound effects.
2017-10-14 16:55:25 +02:00
if (IsSEPlaying())
{
2018-06-17 16:48:58 +02:00
if (++sSoundAnimFramesToWait <= 90) // Wait 90 frames, then halt the sound effect.
2017-10-14 16:55:25 +02:00
{
2021-10-04 16:21:03 +02:00
sAnimFramesToWait = 1;
2017-10-14 16:55:25 +02:00
return;
}
else
{
m4aMPlayStop(&gMPlayInfo_SE1);
m4aMPlayStop(&gMPlayInfo_SE2);
2017-10-14 16:55:25 +02:00
}
}
2018-06-17 16:48:58 +02:00
// The SE has halted, so set the SE Frame Counter to 0 and continue.
2017-10-15 23:21:59 +02:00
sSoundAnimFramesToWait = 0;
2017-10-14 16:55:25 +02:00
for (i = 0; i < ANIM_SPRITE_INDEX_COUNT; i++)
{
if (sAnimSpriteIndexArray[i] != 0xFFFF)
2017-10-14 16:55:25 +02:00
{
2017-10-15 23:21:59 +02:00
FreeSpriteTilesByTag(gBattleAnimPicTable[sAnimSpriteIndexArray[i]].tag);
FreeSpritePaletteByTag(gBattleAnimPicTable[sAnimSpriteIndexArray[i]].tag);
2019-01-13 12:12:27 +01:00
sAnimSpriteIndexArray[i] = 0xFFFF; // set terminator.
2017-10-14 16:55:25 +02:00
}
}
2018-06-17 16:48:58 +02:00
if (!continuousAnim) // May have been used for debug?
2017-10-14 16:55:25 +02:00
{
2021-10-09 17:33:37 +02:00
m4aMPlayVolumeControl(&gMPlayInfo_BGM, TRACKS_ALL, 256);
2017-10-14 16:55:25 +02:00
if (!IsContest())
{
2021-10-04 16:21:03 +02:00
InitPrioritiesForVisibleBattlers();
2017-10-20 10:49:21 +02:00
UpdateOamPriorityInAllHealthboxes(1);
2017-10-14 16:55:25 +02:00
}
gAnimScriptActive = FALSE;
}
}
static void Cmd_playse(void)
2017-10-14 16:55:25 +02:00
{
2017-10-15 23:21:59 +02:00
sBattleAnimScriptPtr++;
2018-03-01 00:59:52 +01:00
PlaySE(T1_READ_16(sBattleAnimScriptPtr));
2017-10-15 23:21:59 +02:00
sBattleAnimScriptPtr += 2;
2017-10-14 16:55:25 +02:00
}
2021-10-04 16:21:03 +02:00
// These two tasks share context and similar task data
// To differentiate them the task data for Task_UpdateMonBg is prefixed t2
2017-10-14 16:55:25 +02:00
// Task data for Task_InitUpdateMonBg
#define tBattlerId data[0]
#define tInBg2 data[1]
#define tActive data[2]
#define tIsPartner data[3]
2017-10-14 16:55:25 +02:00
// Task data for Task_UpdateMonBg
#define t2_SpriteId data[0]
#define t2_SpriteX data[1]
#define t2_SpriteY data[2]
#define t2_BgX data[3]
#define t2_BgY data[4]
#define t2_InBg2 data[5]
#define t2_BattlerId data[6]
2017-10-14 16:55:25 +02:00
static void Task_InitUpdateMonBg(u8 taskId)
2017-10-14 16:55:25 +02:00
{
u8 updateTaskId;
2017-10-14 16:55:25 +02:00
2021-10-04 16:21:03 +02:00
s16 *data = gTasks[taskId].data;
u8 battlerSpriteId = gBattlerSpriteIds[tBattlerId];
gSprites[battlerSpriteId].invisible = TRUE;
2017-10-14 16:55:25 +02:00
if (!tActive)
2017-10-14 16:55:25 +02:00
{
DestroyAnimVisualTask(taskId);
return;
}
updateTaskId = CreateTask(Task_UpdateMonBg, 10);
gTasks[updateTaskId].t2_SpriteId = battlerSpriteId;
gTasks[updateTaskId].t2_SpriteX = gSprites[battlerSpriteId].x + gSprites[battlerSpriteId].x2;
gTasks[updateTaskId].t2_SpriteY = gSprites[battlerSpriteId].y + gSprites[battlerSpriteId].y2;
2017-10-14 16:55:25 +02:00
if (!tInBg2)
2017-10-14 16:55:25 +02:00
{
gTasks[updateTaskId].t2_BgX = gBattle_BG1_X;
gTasks[updateTaskId].t2_BgY = gBattle_BG1_Y;
2017-10-14 16:55:25 +02:00
}
else
{
gTasks[updateTaskId].t2_BgX = gBattle_BG2_X;
gTasks[updateTaskId].t2_BgY = gBattle_BG2_Y;
2017-10-14 16:55:25 +02:00
}
gTasks[updateTaskId].t2_InBg2 = tInBg2;
gTasks[updateTaskId].t2_BattlerId = tBattlerId;
sMonAnimTaskIdArray[tIsPartner] = updateTaskId;
2017-10-14 16:55:25 +02:00
DestroyAnimVisualTask(taskId);
}
static void Cmd_monbg(void)
2017-10-14 16:55:25 +02:00
{
bool8 toBG_2;
u8 taskId;
2018-03-01 00:59:52 +01:00
u8 battlerId;
2018-06-17 16:48:58 +02:00
u8 animBattler;
2017-10-14 16:55:25 +02:00
2017-10-15 23:21:59 +02:00
sBattleAnimScriptPtr++;
2017-10-14 16:55:25 +02:00
2018-06-17 16:48:58 +02:00
animBattler = sBattleAnimScriptPtr[0];
if (animBattler & ANIM_TARGET)
2018-03-01 00:59:52 +01:00
battlerId = gBattleAnimTarget;
2017-10-14 16:55:25 +02:00
else
2018-03-01 00:59:52 +01:00
battlerId = gBattleAnimAttacker;
2017-10-14 16:55:25 +02:00
// Move designated battler to background
2018-03-01 00:59:52 +01:00
if (IsBattlerSpriteVisible(battlerId))
2017-10-14 16:55:25 +02:00
{
2018-03-01 00:59:52 +01:00
u8 position = GetBattlerPosition(battlerId);
2018-01-16 23:42:31 +01:00
if (position == B_POSITION_OPPONENT_LEFT || position == B_POSITION_PLAYER_RIGHT || IsContest())
2017-10-14 16:55:25 +02:00
toBG_2 = FALSE;
else
toBG_2 = TRUE;
2018-12-24 16:51:15 +01:00
MoveBattlerSpriteToBG(battlerId, toBG_2, FALSE);
taskId = CreateTask(Task_InitUpdateMonBg, 10);
2017-10-14 16:55:25 +02:00
gAnimVisualTaskCount++;
gTasks[taskId].tBattlerId = battlerId;
gTasks[taskId].tInBg2 = toBG_2;
gTasks[taskId].tActive = TRUE;
gTasks[taskId].tIsPartner = FALSE;
2017-10-14 16:55:25 +02:00
}
// Move battler's partner to background
2018-03-01 00:59:52 +01:00
battlerId ^= BIT_FLANK;
if (IsBattlerSpriteVisible(battlerId))
2017-10-14 16:55:25 +02:00
{
2018-03-01 00:59:52 +01:00
u8 position = GetBattlerPosition(battlerId);
2018-01-16 23:42:31 +01:00
if (position == B_POSITION_OPPONENT_LEFT || position == B_POSITION_PLAYER_RIGHT || IsContest())
2017-10-14 16:55:25 +02:00
toBG_2 = FALSE;
else
toBG_2 = TRUE;
2018-12-24 16:51:15 +01:00
MoveBattlerSpriteToBG(battlerId, toBG_2, FALSE);
taskId = CreateTask(Task_InitUpdateMonBg, 10);
2017-10-14 16:55:25 +02:00
gAnimVisualTaskCount++;
gTasks[taskId].tBattlerId = battlerId;
gTasks[taskId].tInBg2 = toBG_2;
gTasks[taskId].tActive = TRUE;
gTasks[taskId].tIsPartner = TRUE;
2017-10-14 16:55:25 +02:00
}
2017-10-15 23:21:59 +02:00
sBattleAnimScriptPtr++;
2021-10-04 16:21:03 +02:00
sAnimFramesToWait = 1;
2017-10-14 16:55:25 +02:00
gAnimScriptCallback = WaitAnimFrameCount;
}
2018-03-01 00:59:52 +01:00
bool8 IsBattlerSpriteVisible(u8 battlerId)
2017-10-14 16:55:25 +02:00
{
if (IsContest())
{
2018-03-01 00:59:52 +01:00
if (battlerId == gBattleAnimAttacker)
2017-10-14 16:55:25 +02:00
return TRUE;
else
return FALSE;
}
2018-03-01 00:59:52 +01:00
if (!IsBattlerSpritePresent(battlerId))
2017-10-14 16:55:25 +02:00
return FALSE;
if (IsContest())
2018-06-17 16:48:58 +02:00
return TRUE; // This line won't ever be reached.
2018-03-01 00:59:52 +01:00
if (!gBattleSpritesDataPtr->battlerData[battlerId].invisible || !gSprites[gBattlerSpriteIds[battlerId]].invisible)
2017-10-14 16:55:25 +02:00
return TRUE;
return FALSE;
}
2018-12-24 16:51:15 +01:00
void MoveBattlerSpriteToBG(u8 battlerId, bool8 toBG_2, bool8 setSpriteInvisible)
2017-10-14 16:55:25 +02:00
{
2019-02-06 20:17:09 +01:00
struct BattleAnimBgData animBg;
2018-03-01 00:59:52 +01:00
u8 battlerSpriteId;
2017-10-14 16:55:25 +02:00
if (!toBG_2)
{
2018-03-01 00:59:52 +01:00
u8 battlerPosition;
2017-10-14 16:55:25 +02:00
if (IsContest() == TRUE)
{
RequestDma3Fill(0, (void*)(BG_SCREEN_ADDR(16)), 0x2000, 1);
RequestDma3Fill(0xFF, (void*)(BG_SCREEN_ADDR(30)), 0x1000, 0);
2017-10-14 16:55:25 +02:00
}
else
{
RequestDma3Fill(0, (void*)(BG_SCREEN_ADDR(8)), 0x2000, 1);
RequestDma3Fill(0xFF, (void*)(BG_SCREEN_ADDR(28)), 0x1000, 0);
2017-10-14 16:55:25 +02:00
}
2021-02-28 00:41:30 +01:00
GetBattleAnimBg1Data(&animBg);
2019-02-06 20:17:09 +01:00
CpuFill16(0, animBg.bgTiles, 0x1000);
CpuFill16(0xFF, animBg.bgTilemap, 0x800);
2017-10-14 16:55:25 +02:00
SetAnimBgAttribute(1, BG_ANIM_PRIORITY, 2);
SetAnimBgAttribute(1, BG_ANIM_SCREEN_SIZE, 1);
SetAnimBgAttribute(1, BG_ANIM_AREA_OVERFLOW_MODE, 0);
2018-03-01 00:59:52 +01:00
battlerSpriteId = gBattlerSpriteIds[battlerId];
2017-10-14 16:55:25 +02:00
2021-07-07 15:11:52 +02:00
gBattle_BG1_X = -(gSprites[battlerSpriteId].x + gSprites[battlerSpriteId].x2) + 0x20;
2020-08-14 01:10:23 +02:00
if (IsContest() && IsSpeciesNotUnown(gContestResources->moveAnim->species))
2017-10-14 16:55:25 +02:00
gBattle_BG1_X--;
2021-07-07 15:11:52 +02:00
gBattle_BG1_Y = -(gSprites[battlerSpriteId].y + gSprites[battlerSpriteId].y2) + 0x20;
2017-10-14 16:55:25 +02:00
if (setSpriteInvisible)
gSprites[gBattlerSpriteIds[battlerId]].invisible = TRUE;
2017-10-14 16:55:25 +02:00
SetGpuReg(REG_OFFSET_BG1HOFS, gBattle_BG1_X);
SetGpuReg(REG_OFFSET_BG1VOFS, gBattle_BG1_Y);
2019-02-06 20:17:09 +01:00
LoadPalette(&gPlttBufferUnfaded[0x100 + battlerId * 16], animBg.paletteId * 16, 0x20);
CpuCopy32(&gPlttBufferUnfaded[0x100 + battlerId * 16], (void*)(BG_PLTT + animBg.paletteId * 32), 0x20);
2017-10-14 16:55:25 +02:00
if (IsContest())
2018-03-01 00:59:52 +01:00
battlerPosition = 0;
2017-10-14 16:55:25 +02:00
else
2018-03-01 00:59:52 +01:00
battlerPosition = GetBattlerPosition(battlerId);
2017-10-14 16:55:25 +02:00
2021-10-04 16:21:03 +02:00
DrawBattlerOnBg(1, 0, 0, battlerPosition, animBg.paletteId, animBg.bgTiles, animBg.bgTilemap, animBg.tilesOffset);
2017-10-14 16:55:25 +02:00
if (IsContest())
2021-10-04 16:21:03 +02:00
FlipBattlerBgTiles();
2017-10-14 16:55:25 +02:00
}
else
{
RequestDma3Fill(0, (void*)(BG_SCREEN_ADDR(12)), 0x2000, 1);
RequestDma3Fill(0, (void*)(BG_SCREEN_ADDR(30)), 0x1000, 1);
2021-02-28 00:41:30 +01:00
GetBattleAnimBgData(&animBg, 2);
2019-02-06 20:17:09 +01:00
CpuFill16(0, animBg.bgTiles + 0x1000, 0x1000);
CpuFill16(0, animBg.bgTilemap + 0x400, 0x800);
2017-10-14 16:55:25 +02:00
SetAnimBgAttribute(2, BG_ANIM_PRIORITY, 2);
SetAnimBgAttribute(2, BG_ANIM_SCREEN_SIZE, 1);
SetAnimBgAttribute(2, BG_ANIM_AREA_OVERFLOW_MODE, 0);
2018-03-01 00:59:52 +01:00
battlerSpriteId = gBattlerSpriteIds[battlerId];
2017-10-14 16:55:25 +02:00
2021-07-07 15:11:52 +02:00
gBattle_BG2_X = -(gSprites[battlerSpriteId].x + gSprites[battlerSpriteId].x2) + 0x20;
gBattle_BG2_Y = -(gSprites[battlerSpriteId].y + gSprites[battlerSpriteId].y2) + 0x20;
2017-10-14 16:55:25 +02:00
if (setSpriteInvisible)
gSprites[gBattlerSpriteIds[battlerId]].invisible = TRUE;
2017-10-14 16:55:25 +02:00
SetGpuReg(REG_OFFSET_BG2HOFS, gBattle_BG2_X);
SetGpuReg(REG_OFFSET_BG2VOFS, gBattle_BG2_Y);
2018-03-01 00:59:52 +01:00
LoadPalette(&gPlttBufferUnfaded[0x100 + battlerId * 16], 0x90, 0x20);
CpuCopy32(&gPlttBufferUnfaded[0x100 + battlerId * 16], (void*)(BG_PLTT + 0x120), 0x20);
2017-10-14 16:55:25 +02:00
2021-10-04 16:21:03 +02:00
DrawBattlerOnBg(2, 0, 0, GetBattlerPosition(battlerId), animBg.paletteId, animBg.bgTiles + 0x1000, animBg.bgTilemap + 0x400, animBg.tilesOffset);
2017-10-14 16:55:25 +02:00
}
}
2021-10-04 16:21:03 +02:00
static void FlipBattlerBgTiles(void)
2017-10-14 23:37:44 +02:00
{
s32 i, j;
2019-02-06 20:17:09 +01:00
struct BattleAnimBgData animBg;
2017-10-14 23:37:44 +02:00
u16 *ptr;
2020-08-14 01:10:23 +02:00
if (IsSpeciesNotUnown(gContestResources->moveAnim->species))
2017-10-14 23:37:44 +02:00
{
2021-02-28 00:41:30 +01:00
GetBattleAnimBg1Data(&animBg);
2019-02-06 20:17:09 +01:00
ptr = animBg.bgTilemap;
2017-10-14 23:37:44 +02:00
for (i = 0; i < 8; i++)
{
for (j = 0; j < 4; j++)
{
2021-10-04 16:21:03 +02:00
u16 temp;
SWAP(ptr[j + i * 32], ptr[7 - j + i * 32], temp);
2017-10-14 23:37:44 +02:00
}
}
for (i = 0; i < 8; i++)
{
for (j = 0; j < 8; j++)
ptr[j + i * 32] ^= 0x400;
}
}
}
2021-10-04 16:21:03 +02:00
void RelocateBattleBgPal(u16 paletteNum, u16 *dest, u32 offset, bool8 largeScreen)
2017-10-14 23:37:44 +02:00
{
s32 i, j;
2021-10-04 16:21:03 +02:00
s32 size;
2017-10-14 23:37:44 +02:00
2021-10-04 16:21:03 +02:00
if (!largeScreen)
size = 32;
2017-10-14 23:37:44 +02:00
else
2021-10-04 16:21:03 +02:00
size = 64;
paletteNum <<= 12;
for (i = 0; i < size; i++)
2017-10-14 23:37:44 +02:00
{
for (j = 0; j < 32; j++)
2021-10-04 16:21:03 +02:00
dest[j + i * 32] = ((dest[j + i * 32] & 0xFFF) | paletteNum) + offset;
2017-10-14 23:37:44 +02:00
}
}
2021-02-28 00:41:30 +01:00
void ResetBattleAnimBg(bool8 toBG2)
2017-10-14 23:37:44 +02:00
{
2019-02-06 20:17:09 +01:00
struct BattleAnimBgData animBg;
2021-02-28 00:41:30 +01:00
GetBattleAnimBg1Data(&animBg);
2017-10-14 23:37:44 +02:00
2021-02-28 00:41:30 +01:00
if (!toBG2 || IsContest())
2017-10-14 23:37:44 +02:00
{
2021-02-28 00:41:30 +01:00
ClearBattleAnimBg(1);
2017-10-14 23:37:44 +02:00
gBattle_BG1_X = 0;
gBattle_BG1_Y = 0;
}
else
{
2021-02-28 00:41:30 +01:00
ClearBattleAnimBg(2);
2017-10-14 23:37:44 +02:00
gBattle_BG2_X = 0;
gBattle_BG2_Y = 0;
}
}
static void Task_UpdateMonBg(u8 taskId)
2017-10-14 23:37:44 +02:00
{
u8 spriteId, battlerId;
2017-10-20 00:01:17 +02:00
s16 x, y;
2019-02-06 20:17:09 +01:00
struct BattleAnimBgData animBg;
2017-10-14 23:37:44 +02:00
spriteId = gTasks[taskId].t2_SpriteId;
battlerId = gTasks[taskId].t2_BattlerId;
2021-02-28 00:41:30 +01:00
GetBattleAnimBg1Data(&animBg);
x = gTasks[taskId].t2_SpriteX - (gSprites[spriteId].x + gSprites[spriteId].x2);
y = gTasks[taskId].t2_SpriteY - (gSprites[spriteId].y + gSprites[spriteId].y2);
2017-10-14 23:37:44 +02:00
if (!gTasks[taskId].t2_InBg2)
2017-10-14 23:37:44 +02:00
{
u16 *src;
u16 *dst;
gBattle_BG1_X = x + gTasks[taskId].t2_BgX;
gBattle_BG1_Y = y + gTasks[taskId].t2_BgY;
src = &gPlttBufferFaded[0x100 + battlerId * 16];
2021-10-04 16:21:03 +02:00
dst = &gPlttBufferFaded[0x100 + animBg.paletteId * 16 - 256];
CpuCopy32(src, dst, 32);
2017-10-14 23:37:44 +02:00
}
else
{
u16 *src;
u16 *dst;
gBattle_BG2_X = x + gTasks[taskId].t2_BgX;
gBattle_BG2_Y = y + gTasks[taskId].t2_BgY;
src = &gPlttBufferFaded[0x100 + battlerId * 16];
2021-10-04 16:21:03 +02:00
dst = &gPlttBufferFaded[0x100 - 112];
CpuCopy32(src, dst, 32);
2017-10-14 23:37:44 +02:00
}
}
#undef tBattlerId
#undef tInBg2
#undef tActive
#undef tIsPartner
#undef t2_SpriteId
#undef t2_SpriteX
#undef t2_SpriteY
#undef t2_BgX
#undef t2_BgY
#undef t2_InBg2
#undef t2_BattlerId
static void Cmd_clearmonbg(void)
2017-10-14 23:37:44 +02:00
{
2018-06-17 16:48:58 +02:00
u8 animBattlerId;
2018-03-01 00:59:52 +01:00
u8 battlerId;
2017-10-14 23:37:44 +02:00
u8 taskId;
2017-10-15 23:21:59 +02:00
sBattleAnimScriptPtr++;
2018-06-17 16:48:58 +02:00
animBattlerId = sBattleAnimScriptPtr[0];
2017-10-14 23:37:44 +02:00
2018-06-17 16:48:58 +02:00
if (animBattlerId == ANIM_ATTACKER)
animBattlerId = ANIM_ATK_PARTNER;
else if (animBattlerId == ANIM_TARGET)
animBattlerId = ANIM_DEF_PARTNER;
2017-10-14 23:37:44 +02:00
2018-06-17 16:48:58 +02:00
if (animBattlerId == ANIM_ATTACKER || animBattlerId == ANIM_ATK_PARTNER)
2018-03-01 00:59:52 +01:00
battlerId = gBattleAnimAttacker;
2017-10-14 23:37:44 +02:00
else
2018-03-01 00:59:52 +01:00
battlerId = gBattleAnimTarget;
2017-10-14 23:37:44 +02:00
2021-02-20 05:22:26 +01:00
if (sMonAnimTaskIdArray[0] != TASK_NONE)
gSprites[gBattlerSpriteIds[battlerId]].invisible = FALSE;
2021-02-20 05:22:26 +01:00
if (animBattlerId > 1 && sMonAnimTaskIdArray[1] != TASK_NONE)
gSprites[gBattlerSpriteIds[battlerId ^ BIT_FLANK]].invisible = FALSE;
2017-10-14 23:37:44 +02:00
else
2018-06-17 16:48:58 +02:00
animBattlerId = 0;
2017-10-14 23:37:44 +02:00
2021-10-04 16:21:03 +02:00
taskId = CreateTask(Task_ClearMonBg, 5);
2018-06-17 16:48:58 +02:00
gTasks[taskId].data[0] = animBattlerId;
2018-03-01 00:59:52 +01:00
gTasks[taskId].data[2] = battlerId;
2017-10-14 23:37:44 +02:00
2017-10-15 23:21:59 +02:00
sBattleAnimScriptPtr++;
2017-10-14 23:37:44 +02:00
}
2021-10-04 16:21:03 +02:00
static void Task_ClearMonBg(u8 taskId)
2017-10-14 23:37:44 +02:00
{
gTasks[taskId].data[1]++;
if (gTasks[taskId].data[1] != 1)
{
u8 to_BG2;
2018-02-06 02:46:59 +01:00
u8 position = GetBattlerPosition(gTasks[taskId].data[2]);
2018-01-16 23:42:31 +01:00
if (position == B_POSITION_OPPONENT_LEFT || position == B_POSITION_PLAYER_RIGHT || IsContest())
2017-10-14 23:37:44 +02:00
to_BG2 = FALSE;
else
to_BG2 = TRUE;
2021-02-20 05:22:26 +01:00
if (sMonAnimTaskIdArray[0] != TASK_NONE)
2017-10-14 23:37:44 +02:00
{
2021-02-28 00:41:30 +01:00
ResetBattleAnimBg(to_BG2);
2017-10-15 23:21:59 +02:00
DestroyTask(sMonAnimTaskIdArray[0]);
2021-02-20 05:22:26 +01:00
sMonAnimTaskIdArray[0] = TASK_NONE;
2017-10-14 23:37:44 +02:00
}
if (gTasks[taskId].data[0] > 1)
{
2021-02-28 00:41:30 +01:00
ResetBattleAnimBg(to_BG2 ^ 1);
2017-10-15 23:21:59 +02:00
DestroyTask(sMonAnimTaskIdArray[1]);
2021-02-20 05:22:26 +01:00
sMonAnimTaskIdArray[1] = TASK_NONE;
2017-10-14 23:37:44 +02:00
}
DestroyTask(taskId);
}
}
// Equivalent to Cmd_monbg but never creates Task_InitUpdateMonBg / Task_UpdateMonBg
static void Cmd_monbg_static(void)
2017-10-14 23:37:44 +02:00
{
bool8 toBG_2;
2018-03-01 00:59:52 +01:00
u8 battlerId;
2018-06-17 16:48:58 +02:00
u8 animBattlerId;
2017-10-14 23:37:44 +02:00
2017-10-15 23:21:59 +02:00
sBattleAnimScriptPtr++;
2017-10-14 23:37:44 +02:00
2018-06-17 16:48:58 +02:00
animBattlerId = sBattleAnimScriptPtr[0];
2017-10-14 23:37:44 +02:00
2018-06-17 16:48:58 +02:00
if (animBattlerId == ANIM_ATTACKER)
animBattlerId = ANIM_ATK_PARTNER;
else if (animBattlerId == ANIM_TARGET)
animBattlerId = ANIM_DEF_PARTNER;
2017-10-14 23:37:44 +02:00
2018-06-17 16:48:58 +02:00
if (animBattlerId == ANIM_ATTACKER || animBattlerId == ANIM_ATK_PARTNER)
2018-03-01 00:59:52 +01:00
battlerId = gBattleAnimAttacker;
2017-10-14 23:37:44 +02:00
else
2018-03-01 00:59:52 +01:00
battlerId = gBattleAnimTarget;
2017-10-14 23:37:44 +02:00
2018-03-01 00:59:52 +01:00
if (IsBattlerSpriteVisible(battlerId))
2017-10-14 23:37:44 +02:00
{
2018-03-01 00:59:52 +01:00
u8 position = GetBattlerPosition(battlerId);
2018-01-16 23:42:31 +01:00
if (position == B_POSITION_OPPONENT_LEFT || position == B_POSITION_PLAYER_RIGHT || IsContest())
2017-10-14 23:37:44 +02:00
toBG_2 = FALSE;
else
toBG_2 = TRUE;
2018-12-24 16:51:15 +01:00
MoveBattlerSpriteToBG(battlerId, toBG_2, FALSE);
2017-10-14 23:37:44 +02:00
}
2018-03-01 00:59:52 +01:00
battlerId ^= BIT_FLANK;
2018-06-17 16:48:58 +02:00
if (animBattlerId > 1 && IsBattlerSpriteVisible(battlerId))
2017-10-14 23:37:44 +02:00
{
2018-03-01 00:59:52 +01:00
u8 position = GetBattlerPosition(battlerId);
2018-01-16 23:42:31 +01:00
if (position == B_POSITION_OPPONENT_LEFT || position == B_POSITION_PLAYER_RIGHT || IsContest())
2017-10-14 23:37:44 +02:00
toBG_2 = FALSE;
else
toBG_2 = TRUE;
2018-12-24 16:51:15 +01:00
MoveBattlerSpriteToBG(battlerId, toBG_2, FALSE);
2017-10-14 23:37:44 +02:00
}
2017-10-15 23:21:59 +02:00
sBattleAnimScriptPtr++;
2017-10-14 23:37:44 +02:00
}
static void Cmd_clearmonbg_static(void)
2017-10-14 23:37:44 +02:00
{
2018-06-17 16:48:58 +02:00
u8 animBattlerId;
2018-03-01 00:59:52 +01:00
u8 battlerId;
2017-10-14 23:37:44 +02:00
u8 taskId;
2017-10-15 23:21:59 +02:00
sBattleAnimScriptPtr++;
2018-06-17 16:48:58 +02:00
animBattlerId = sBattleAnimScriptPtr[0];
2017-10-14 23:37:44 +02:00
2018-06-17 16:48:58 +02:00
if (animBattlerId == ANIM_ATTACKER)
animBattlerId = ANIM_ATK_PARTNER;
else if (animBattlerId == ANIM_TARGET)
animBattlerId = ANIM_DEF_PARTNER;
2017-10-14 23:37:44 +02:00
2018-06-17 16:48:58 +02:00
if (animBattlerId == ANIM_ATTACKER || animBattlerId == ANIM_ATK_PARTNER)
2018-03-01 00:59:52 +01:00
battlerId = gBattleAnimAttacker;
2017-10-14 23:37:44 +02:00
else
2018-03-01 00:59:52 +01:00
battlerId = gBattleAnimTarget;
2017-10-14 23:37:44 +02:00
2018-03-01 00:59:52 +01:00
if (IsBattlerSpriteVisible(battlerId))
gSprites[gBattlerSpriteIds[battlerId]].invisible = FALSE;
2018-06-17 16:48:58 +02:00
if (animBattlerId > 1 && IsBattlerSpriteVisible(battlerId ^ BIT_FLANK))
gSprites[gBattlerSpriteIds[battlerId ^ BIT_FLANK]].invisible = FALSE;
2017-10-14 23:37:44 +02:00
else
2018-06-17 16:48:58 +02:00
animBattlerId = 0;
2017-10-14 23:37:44 +02:00
taskId = CreateTask(Task_ClearMonBgStatic, 5);
2018-06-17 16:48:58 +02:00
gTasks[taskId].data[0] = animBattlerId;
2018-03-01 00:59:52 +01:00
gTasks[taskId].data[2] = battlerId;
2017-10-14 23:37:44 +02:00
2017-10-15 23:21:59 +02:00
sBattleAnimScriptPtr++;
2017-10-14 23:37:44 +02:00
}
static void Task_ClearMonBgStatic(u8 taskId)
2017-10-14 23:37:44 +02:00
{
gTasks[taskId].data[1]++;
if (gTasks[taskId].data[1] != 1)
{
bool8 toBG_2;
2018-03-01 00:59:52 +01:00
u8 battlerId = gTasks[taskId].data[2];
u8 position = GetBattlerPosition(battlerId);
2018-01-16 23:42:31 +01:00
if (position == B_POSITION_OPPONENT_LEFT || position == B_POSITION_PLAYER_RIGHT || IsContest())
2017-10-14 23:37:44 +02:00
toBG_2 = FALSE;
else
toBG_2 = TRUE;
2018-03-01 00:59:52 +01:00
if (IsBattlerSpriteVisible(battlerId))
2021-02-28 00:41:30 +01:00
ResetBattleAnimBg(toBG_2);
2018-03-01 00:59:52 +01:00
if (gTasks[taskId].data[0] > 1 && IsBattlerSpriteVisible(battlerId ^ BIT_FLANK))
2021-02-28 00:41:30 +01:00
ResetBattleAnimBg(toBG_2 ^ 1);
2017-10-14 23:37:44 +02:00
DestroyTask(taskId);
}
}
static void Cmd_setalpha(void)
2017-10-14 23:37:44 +02:00
{
u16 half1, half2;
2017-10-15 23:21:59 +02:00
sBattleAnimScriptPtr++;
half1 = *(sBattleAnimScriptPtr++);
half2 = *(sBattleAnimScriptPtr++) << 8;
2018-12-26 13:43:07 +01:00
SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_EFFECT_BLEND | BLDCNT_TGT2_ALL);
2017-10-14 23:37:44 +02:00
SetGpuReg(REG_OFFSET_BLDALPHA, half1 | half2);
}
static void Cmd_setbldcnt(void)
2017-10-14 23:37:44 +02:00
{
u16 half1, half2;
2017-10-15 23:21:59 +02:00
sBattleAnimScriptPtr++;
half1 = *(sBattleAnimScriptPtr++);
half2 = *(sBattleAnimScriptPtr++) << 8;
2017-10-14 23:37:44 +02:00
SetGpuReg(REG_OFFSET_BLDCNT, half1 | half2);
}
static void Cmd_blendoff(void)
2017-10-14 23:37:44 +02:00
{
2017-10-15 23:21:59 +02:00
sBattleAnimScriptPtr++;
2017-10-14 23:37:44 +02:00
SetGpuReg(REG_OFFSET_BLDCNT, 0);
SetGpuReg(REG_OFFSET_BLDALPHA, 0);
}
static void Cmd_call(void)
2017-10-14 23:37:44 +02:00
{
2017-10-15 23:21:59 +02:00
sBattleAnimScriptPtr++;
sBattleAnimScriptRetAddr = sBattleAnimScriptPtr + 4;
2018-03-01 00:59:52 +01:00
sBattleAnimScriptPtr = T2_READ_PTR(sBattleAnimScriptPtr);
2017-10-14 23:37:44 +02:00
}
static void Cmd_return(void)
2017-10-14 23:37:44 +02:00
{
2017-10-15 23:21:59 +02:00
sBattleAnimScriptPtr = sBattleAnimScriptRetAddr;
2017-10-14 23:37:44 +02:00
}
static void Cmd_setarg(void)
2017-10-14 23:37:44 +02:00
{
2021-10-04 16:21:03 +02:00
// Save original address to return to
// after the T1_READ_16, + 4.
// They could have equivalently just advanced
// sBattleAnimScriptPtr by 2 afterwards.
2017-10-15 23:21:59 +02:00
const u8 *addr = sBattleAnimScriptPtr;
2017-10-14 23:37:44 +02:00
u16 value;
u8 argId;
2017-10-15 23:21:59 +02:00
sBattleAnimScriptPtr++;
argId = sBattleAnimScriptPtr[0];
sBattleAnimScriptPtr++;
2018-03-01 00:59:52 +01:00
value = T1_READ_16(sBattleAnimScriptPtr);
2017-10-15 23:21:59 +02:00
sBattleAnimScriptPtr = addr + 4;
2017-10-14 23:37:44 +02:00
gBattleAnimArgs[argId] = value;
}
static void Cmd_choosetwoturnanim(void)
2017-10-14 23:37:44 +02:00
{
2017-10-15 23:21:59 +02:00
sBattleAnimScriptPtr++;
2017-10-14 23:37:44 +02:00
if (gAnimMoveTurn & 1)
2017-10-15 23:21:59 +02:00
sBattleAnimScriptPtr += 4;
2018-03-01 00:59:52 +01:00
sBattleAnimScriptPtr = T2_READ_PTR(sBattleAnimScriptPtr);
2017-10-14 23:37:44 +02:00
}
static void Cmd_jumpifmoveturn(void)
2017-10-14 23:37:44 +02:00
{
u8 toCheck;
2017-10-15 23:21:59 +02:00
sBattleAnimScriptPtr++;
toCheck = sBattleAnimScriptPtr[0];
sBattleAnimScriptPtr++;
2017-10-14 23:37:44 +02:00
if (toCheck == gAnimMoveTurn)
2018-03-01 00:59:52 +01:00
sBattleAnimScriptPtr = T2_READ_PTR(sBattleAnimScriptPtr);
2017-10-14 23:37:44 +02:00
else
2017-10-15 23:21:59 +02:00
sBattleAnimScriptPtr += 4;
2017-10-14 23:37:44 +02:00
}
static void Cmd_goto(void)
2017-10-14 23:37:44 +02:00
{
2017-10-15 23:21:59 +02:00
sBattleAnimScriptPtr++;
2018-03-01 00:59:52 +01:00
sBattleAnimScriptPtr = T2_READ_PTR(sBattleAnimScriptPtr);
2017-10-14 23:37:44 +02:00
}
2020-02-20 06:04:42 +01:00
// Uses of this function that rely on a TRUE return are expecting inBattle to not be ticked as defined in contest behavior.
// As a result, if misused, this function cannot reliably discern between field and contest status and could result in undefined behavior.
2017-10-14 23:37:44 +02:00
bool8 IsContest(void)
{
if (!gMain.inBattle)
return TRUE;
else
return FALSE;
}
#define tBackgroundId data[0]
#define tState data[10]
static void Cmd_fadetobg(void)
2017-10-14 23:37:44 +02:00
{
u8 backgroundId;
u8 taskId;
2017-10-15 23:21:59 +02:00
sBattleAnimScriptPtr++;
backgroundId = sBattleAnimScriptPtr[0];
sBattleAnimScriptPtr++;
2017-10-14 23:37:44 +02:00
taskId = CreateTask(Task_FadeToBg, 5);
gTasks[taskId].tBackgroundId = backgroundId;
2017-10-15 23:21:59 +02:00
sAnimBackgroundFadeState = 1;
2017-10-14 23:37:44 +02:00
}
static void Cmd_fadetobgfromset(void)
2017-10-14 23:37:44 +02:00
{
u8 bg1, bg2, bg3;
u8 taskId;
2017-10-15 23:21:59 +02:00
sBattleAnimScriptPtr++;
bg1 = sBattleAnimScriptPtr[0];
bg2 = sBattleAnimScriptPtr[1];
bg3 = sBattleAnimScriptPtr[2];
sBattleAnimScriptPtr += 3;
2017-10-14 23:37:44 +02:00
taskId = CreateTask(Task_FadeToBg, 5);
if (IsContest())
gTasks[taskId].tBackgroundId = bg3;
2018-02-06 20:48:02 +01:00
else if (GetBattlerSide(gBattleAnimTarget) == B_SIDE_PLAYER)
2017-10-14 23:37:44 +02:00
gTasks[taskId].tBackgroundId = bg2;
else
gTasks[taskId].tBackgroundId = bg1;
2017-10-15 23:21:59 +02:00
sAnimBackgroundFadeState = 1;
2017-10-14 23:37:44 +02:00
}
2017-10-15 23:21:59 +02:00
static void Task_FadeToBg(u8 taskId)
2017-10-14 23:37:44 +02:00
{
if (gTasks[taskId].tState == 0)
{
BeginHardwarePaletteFade(0xE8, 0, 0, 16, 0);
gTasks[taskId].tState++;
return;
}
if (gPaletteFade.active)
return;
if (gTasks[taskId].tState == 1)
{
gTasks[taskId].tState++;
2017-10-15 23:21:59 +02:00
sAnimBackgroundFadeState = 2;
2017-10-14 23:37:44 +02:00
}
else if (gTasks[taskId].tState == 2)
{
2017-10-15 23:21:59 +02:00
s16 bgId = gTasks[taskId].tBackgroundId;
2017-10-14 23:37:44 +02:00
if (bgId == -1)
2017-10-14 23:37:44 +02:00
LoadDefaultBg();
else
LoadMoveBg(bgId);
BeginHardwarePaletteFade(0xE8, 0, 16, 0, 1);
gTasks[taskId].tState++;
return;
}
if (gPaletteFade.active)
return;
if (gTasks[taskId].tState == 3)
{
DestroyTask(taskId);
2017-10-15 23:21:59 +02:00
sAnimBackgroundFadeState = 0;
2017-10-14 23:37:44 +02:00
}
}
2017-10-15 23:21:59 +02:00
static void LoadMoveBg(u16 bgId)
2017-10-14 23:37:44 +02:00
{
if (IsContest())
{
2018-11-07 19:35:31 +01:00
const u32 *tilemap = gBattleAnimBackgroundTable[bgId].tilemap;
2017-10-14 23:37:44 +02:00
void *dmaSrc;
void *dmaDest;
LZDecompressWram(tilemap, gDecompressionBuffer);
2021-10-04 16:21:03 +02:00
RelocateBattleBgPal(GetBattleBgPaletteNum(), (void*)gDecompressionBuffer, 0x100, FALSE);
2017-10-14 23:37:44 +02:00
dmaSrc = gDecompressionBuffer;
2021-10-04 16:21:03 +02:00
dmaDest = (void *)BG_SCREEN_ADDR(26);
2017-10-14 23:37:44 +02:00
DmaCopy32(3, dmaSrc, dmaDest, 0x800);
2021-10-04 16:21:03 +02:00
LZDecompressVram(gBattleAnimBackgroundTable[bgId].image, (void *)BG_SCREEN_ADDR(4));
2019-11-24 18:00:51 +01:00
LoadCompressedPalette(gBattleAnimBackgroundTable[bgId].palette, GetBattleBgPaletteNum() * 16, 32);
2017-10-14 23:37:44 +02:00
}
else
{
2021-10-04 16:21:03 +02:00
LZDecompressVram(gBattleAnimBackgroundTable[bgId].tilemap, (void *)BG_SCREEN_ADDR(26));
LZDecompressVram(gBattleAnimBackgroundTable[bgId].image, (void *)BG_CHAR_ADDR(2));
2017-10-14 23:37:44 +02:00
LoadCompressedPalette(gBattleAnimBackgroundTable[bgId].palette, 32, 32);
}
}
2017-10-15 23:21:59 +02:00
static void LoadDefaultBg(void)
2017-10-14 23:37:44 +02:00
{
if (IsContest())
LoadContestBgAfterMoveAnim();
else
2017-10-20 00:01:17 +02:00
DrawMainBattleBackground();
2017-10-14 23:37:44 +02:00
}
static void Cmd_restorebg(void)
2017-10-14 23:37:44 +02:00
{
u8 taskId;
2017-10-15 23:21:59 +02:00
sBattleAnimScriptPtr++;
2017-10-14 23:37:44 +02:00
taskId = CreateTask(Task_FadeToBg, 5);
gTasks[taskId].tBackgroundId = -1;
2017-10-15 23:21:59 +02:00
sAnimBackgroundFadeState = 1;
2017-10-14 23:37:44 +02:00
}
2017-10-15 23:21:59 +02:00
#undef tBackgroundId
#undef tState
static void Cmd_waitbgfadeout(void)
2017-10-14 23:37:44 +02:00
{
2017-10-15 23:21:59 +02:00
if (sAnimBackgroundFadeState == 2)
2017-10-14 23:37:44 +02:00
{
2017-10-15 23:21:59 +02:00
sBattleAnimScriptPtr++;
2021-10-04 16:21:03 +02:00
sAnimFramesToWait = 0;
2017-10-14 23:37:44 +02:00
}
else
{
2021-10-04 16:21:03 +02:00
sAnimFramesToWait = 1;
2017-10-14 23:37:44 +02:00
}
}
static void Cmd_waitbgfadein(void)
2017-10-14 23:37:44 +02:00
{
2017-10-15 23:21:59 +02:00
if (sAnimBackgroundFadeState == 0)
2017-10-14 23:37:44 +02:00
{
2017-10-15 23:21:59 +02:00
sBattleAnimScriptPtr++;
2021-10-04 16:21:03 +02:00
sAnimFramesToWait = 0;
2017-10-14 23:37:44 +02:00
}
else
{
2021-10-04 16:21:03 +02:00
sAnimFramesToWait = 1;
2017-10-14 23:37:44 +02:00
}
}
static void Cmd_changebg(void)
2017-10-14 23:37:44 +02:00
{
2017-10-15 23:21:59 +02:00
sBattleAnimScriptPtr++;
LoadMoveBg(sBattleAnimScriptPtr[0]);
sBattleAnimScriptPtr++;
2017-10-14 23:37:44 +02:00
}
s8 BattleAnimAdjustPanning(s8 pan)
{
2018-02-06 20:48:02 +01:00
if (!IsContest() && gBattleSpritesDataPtr->healthBoxesData[gBattleAnimAttacker].statusAnimActive)
2017-10-14 23:37:44 +02:00
{
2018-02-06 20:48:02 +01:00
if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER)
pan = SOUND_PAN_TARGET;
2017-10-14 23:37:44 +02:00
else
pan = SOUND_PAN_ATTACKER;
2017-10-14 23:37:44 +02:00
}
else if (IsContest())
{
if (gBattleAnimAttacker != gBattleAnimTarget || gBattleAnimAttacker != 2 || pan != SOUND_PAN_TARGET)
2017-10-14 23:37:44 +02:00
pan *= -1;
}
2018-02-06 20:48:02 +01:00
else if (GetBattlerSide(gBattleAnimAttacker) == B_SIDE_PLAYER)
2017-10-14 23:37:44 +02:00
{
2018-02-06 20:48:02 +01:00
if (GetBattlerSide(gBattleAnimTarget) == B_SIDE_PLAYER)
2017-10-14 23:37:44 +02:00
{
if (pan == SOUND_PAN_TARGET)
pan = SOUND_PAN_ATTACKER;
else if (pan != SOUND_PAN_ATTACKER)
2017-10-14 23:37:44 +02:00
pan *= -1;
}
}
2018-02-06 20:48:02 +01:00
else if (GetBattlerSide(gBattleAnimTarget) == B_SIDE_OPPONENT)
2017-10-14 23:37:44 +02:00
{
if (pan == SOUND_PAN_ATTACKER)
pan = SOUND_PAN_TARGET;
2017-10-14 23:37:44 +02:00
}
else
{
pan *= -1;
}
if (pan > SOUND_PAN_TARGET)
pan = SOUND_PAN_TARGET;
else if (pan < SOUND_PAN_ATTACKER)
pan = SOUND_PAN_ATTACKER;
2017-10-14 23:37:44 +02:00
return pan;
}
s8 BattleAnimAdjustPanning2(s8 pan)
{
2018-02-06 20:48:02 +01:00
if (!IsContest() && gBattleSpritesDataPtr->healthBoxesData[gBattleAnimAttacker].statusAnimActive)
2017-10-14 23:37:44 +02:00
{
2018-02-06 20:48:02 +01:00
if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER)
pan = SOUND_PAN_TARGET;
2017-10-14 23:37:44 +02:00
else
pan = SOUND_PAN_ATTACKER;
2017-10-14 23:37:44 +02:00
}
else
{
2018-02-06 20:48:02 +01:00
if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER || IsContest())
2017-10-14 23:37:44 +02:00
pan = -pan;
}
return pan;
}
2019-04-08 03:36:10 +02:00
s16 KeepPanInRange(s16 panArg, int oldPan)
2017-10-14 23:37:44 +02:00
{
2018-04-18 16:03:15 +02:00
s16 pan = panArg;
2017-10-14 23:37:44 +02:00
if (pan > SOUND_PAN_TARGET)
pan = SOUND_PAN_TARGET;
else if (pan < SOUND_PAN_ATTACKER)
pan = SOUND_PAN_ATTACKER;
2017-10-14 23:37:44 +02:00
2018-04-18 16:03:15 +02:00
return pan;
2017-10-14 23:37:44 +02:00
}
2017-10-15 23:21:59 +02:00
s16 CalculatePanIncrement(s16 sourcePan, s16 targetPan, s16 incrementPan)
2017-10-14 23:37:44 +02:00
{
2017-10-15 23:21:59 +02:00
s16 ret;
2017-10-14 23:37:44 +02:00
2017-10-15 23:21:59 +02:00
if (sourcePan < targetPan)
ret = ((incrementPan < 0) ? -incrementPan : incrementPan);
else if (sourcePan > targetPan)
ret = -((incrementPan < 0) ? -incrementPan : incrementPan);
2017-10-14 23:37:44 +02:00
else
2017-10-15 23:21:59 +02:00
ret = 0;
2017-10-14 23:37:44 +02:00
2017-10-15 23:21:59 +02:00
return ret;
2017-10-14 23:37:44 +02:00
}
static void Cmd_playsewithpan(void)
2017-10-14 23:37:44 +02:00
{
u16 songId;
s8 pan;
2017-10-15 23:21:59 +02:00
sBattleAnimScriptPtr++;
2018-03-01 00:59:52 +01:00
songId = T1_READ_16(sBattleAnimScriptPtr);
2017-10-15 23:21:59 +02:00
pan = sBattleAnimScriptPtr[2];
2017-10-14 23:37:44 +02:00
PlaySE12WithPanning(songId, BattleAnimAdjustPanning(pan));
2017-10-15 23:21:59 +02:00
sBattleAnimScriptPtr += 3;
2017-10-14 23:37:44 +02:00
}
static void Cmd_setpan(void)
2017-10-14 23:37:44 +02:00
{
s8 pan;
2017-10-15 23:21:59 +02:00
sBattleAnimScriptPtr++;
pan = sBattleAnimScriptPtr[0];
2017-10-14 23:37:44 +02:00
SE12PanpotControl(BattleAnimAdjustPanning(pan));
2017-10-15 23:21:59 +02:00
sBattleAnimScriptPtr++;
}
#define tInitialPan data[0]
#define tTargetPan data[1]
#define tIncrementPan data[2]
#define tFramesToWait data[3]
#define tCurrentPan data[4]
#define tFrameCounter data[8]
static void Cmd_panse(void)
2017-10-15 23:21:59 +02:00
{
u16 songNum;
s8 currentPanArg, incrementPan, incrementPanArg, currentPan, targetPan;
u8 framesToWait;
u8 taskId;
sBattleAnimScriptPtr++;
2018-03-01 00:59:52 +01:00
songNum = T1_READ_16(sBattleAnimScriptPtr);
2017-10-15 23:21:59 +02:00
currentPanArg = sBattleAnimScriptPtr[2];
2021-10-04 16:21:03 +02:00
incrementPan = sBattleAnimScriptPtr[3]; // targetPan, var is re-used
2017-10-15 23:21:59 +02:00
incrementPanArg = sBattleAnimScriptPtr[4];
framesToWait = sBattleAnimScriptPtr[5];
currentPan = BattleAnimAdjustPanning(currentPanArg);
targetPan = BattleAnimAdjustPanning(incrementPan);
incrementPan = CalculatePanIncrement(currentPan, targetPan, incrementPanArg);
2021-10-04 16:21:03 +02:00
2017-10-15 23:21:59 +02:00
taskId = CreateTask(Task_PanFromInitialToTarget, 1);
gTasks[taskId].tInitialPan = currentPan;
gTasks[taskId].tTargetPan = targetPan;
gTasks[taskId].tIncrementPan = incrementPan;
gTasks[taskId].tFramesToWait = framesToWait;
gTasks[taskId].tCurrentPan = currentPan;
PlaySE12WithPanning(songNum, currentPan);
gAnimSoundTaskCount++;
sBattleAnimScriptPtr += 6;
}
void Task_PanFromInitialToTarget(u8 taskId)
{
bool32 destroyTask = FALSE;
if (gTasks[taskId].tFrameCounter++ >= gTasks[taskId].tFramesToWait)
{
s16 pan;
s16 initialPanning, targetPanning, currentPan, incrementPan;
gTasks[taskId].tFrameCounter = 0;
initialPanning = gTasks[taskId].tInitialPan;
targetPanning = gTasks[taskId].tTargetPan;
currentPan = gTasks[taskId].tCurrentPan;
incrementPan = gTasks[taskId].tIncrementPan;
pan = currentPan + incrementPan;
gTasks[taskId].tCurrentPan = pan;
2018-06-17 16:48:58 +02:00
if (incrementPan == 0) // If we're not incrementing, just cancel the task immediately.
2017-10-15 23:21:59 +02:00
{
destroyTask = TRUE;
}
2018-06-17 16:48:58 +02:00
else if (initialPanning < targetPanning) // Panning increasing.
2017-10-15 23:21:59 +02:00
{
2018-06-17 16:48:58 +02:00
if (pan >= targetPanning) // Target reached.
2017-10-15 23:21:59 +02:00
destroyTask = TRUE;
}
2018-06-17 16:48:58 +02:00
else // Panning decreasing.
2017-10-15 23:21:59 +02:00
{
2018-06-17 16:48:58 +02:00
if (pan <= targetPanning) // Target reached.
2017-10-15 23:21:59 +02:00
destroyTask = TRUE;
}
if (destroyTask)
{
pan = targetPanning;
DestroyTask(taskId);
gAnimSoundTaskCount--;
}
SE12PanpotControl(pan);
}
}
static void Cmd_panse_adjustnone(void)
2017-10-15 23:21:59 +02:00
{
u16 songId;
s8 currentPan, targetPan, incrementPan;
u8 framesToWait;
u8 taskId;
sBattleAnimScriptPtr++;
2018-03-01 00:59:52 +01:00
songId = T1_READ_16(sBattleAnimScriptPtr);
2017-10-15 23:21:59 +02:00
currentPan = sBattleAnimScriptPtr[2];
targetPan = sBattleAnimScriptPtr[3];
incrementPan = sBattleAnimScriptPtr[4];
framesToWait = sBattleAnimScriptPtr[5];
taskId = CreateTask(Task_PanFromInitialToTarget, 1);
gTasks[taskId].tInitialPan = currentPan;
gTasks[taskId].tTargetPan = targetPan;
gTasks[taskId].tIncrementPan = incrementPan;
gTasks[taskId].tFramesToWait = framesToWait;
gTasks[taskId].tCurrentPan = currentPan;
PlaySE12WithPanning(songId, currentPan);
gAnimSoundTaskCount++;
sBattleAnimScriptPtr += 6;
}
static void Cmd_panse_adjustall(void)
2017-10-15 23:21:59 +02:00
{
u16 songId;
s8 targetPanArg, incrementPanArg, currentPanArg, currentPan, targetPan, incrementPan;
u8 framesToWait;
u8 taskId;
sBattleAnimScriptPtr++;
2018-03-01 00:59:52 +01:00
songId = T1_READ_16(sBattleAnimScriptPtr);
2017-10-15 23:21:59 +02:00
currentPanArg = sBattleAnimScriptPtr[2];
targetPanArg = sBattleAnimScriptPtr[3];
incrementPanArg = sBattleAnimScriptPtr[4];
framesToWait = sBattleAnimScriptPtr[5];
currentPan = BattleAnimAdjustPanning2(currentPanArg);
targetPan = BattleAnimAdjustPanning2(targetPanArg);
incrementPan = BattleAnimAdjustPanning2(incrementPanArg);
taskId = CreateTask(Task_PanFromInitialToTarget, 1);
gTasks[taskId].tInitialPan = currentPan;
gTasks[taskId].tTargetPan = targetPan;
gTasks[taskId].tIncrementPan = incrementPan;
gTasks[taskId].tFramesToWait = framesToWait;
gTasks[taskId].tCurrentPan = currentPan;
PlaySE12WithPanning(songId, currentPan);
gAnimSoundTaskCount++;
sBattleAnimScriptPtr += 6;
}
#undef tInitialPan
#undef tTargetPan
#undef tIncrementPan
#undef tFramesToWait
#undef tCurrentPan
#undef tFrameCounter
#define tSongId data[0]
#define tPanning data[1]
#define tFramesToWait data[2]
#define tNumberOfPlays data[3]
#define tFrameCounter data[8]
static void Cmd_loopsewithpan(void)
2017-10-15 23:21:59 +02:00
{
u16 songId;
s8 panningArg, panning;
u8 framesToWait, numberOfPlays;
u8 taskId;
sBattleAnimScriptPtr++;
2018-03-01 00:59:52 +01:00
songId = T1_READ_16(sBattleAnimScriptPtr);
2017-10-15 23:21:59 +02:00
panningArg = sBattleAnimScriptPtr[2];
framesToWait = sBattleAnimScriptPtr[3];
numberOfPlays = sBattleAnimScriptPtr[4];
panning = BattleAnimAdjustPanning(panningArg);
taskId = CreateTask(Task_LoopAndPlaySE, 1);
gTasks[taskId].tSongId = songId;
gTasks[taskId].tPanning = panning;
gTasks[taskId].tFramesToWait = framesToWait;
gTasks[taskId].tNumberOfPlays = numberOfPlays;
gTasks[taskId].tFrameCounter = framesToWait;
gTasks[taskId].func(taskId);
gAnimSoundTaskCount++;
sBattleAnimScriptPtr += 5;
}
static void Task_LoopAndPlaySE(u8 taskId)
{
if (gTasks[taskId].tFrameCounter++ >= gTasks[taskId].tFramesToWait)
{
u16 songId;
s8 panning;
u8 numberOfPlays;
gTasks[taskId].tFrameCounter = 0;
songId = gTasks[taskId].tSongId;
panning = gTasks[taskId].tPanning;
numberOfPlays = --gTasks[taskId].tNumberOfPlays;
PlaySE12WithPanning(songId, panning);
if (numberOfPlays == 0)
{
DestroyTask(taskId);
gAnimSoundTaskCount--;
}
}
}
#undef tSongId
#undef tPanning
#undef tFramesToWait
#undef tNumberOfPlays
#undef tFrameCounter
#define tSongId data[0]
#define tPanning data[1]
#define tFramesToWait data[2]
static void Cmd_waitplaysewithpan(void)
2017-10-15 23:21:59 +02:00
{
u16 songId;
s8 panningArg, panning;
u8 framesToWait;
u8 taskId;
sBattleAnimScriptPtr++;
2018-03-01 00:59:52 +01:00
songId = T1_READ_16(sBattleAnimScriptPtr);
2017-10-15 23:21:59 +02:00
panningArg = sBattleAnimScriptPtr[2];
framesToWait = sBattleAnimScriptPtr[3];
panning = BattleAnimAdjustPanning(panningArg);
taskId = CreateTask(Task_WaitAndPlaySE, 1);
gTasks[taskId].tSongId = songId;
gTasks[taskId].tPanning = panning;
gTasks[taskId].tFramesToWait = framesToWait;
gAnimSoundTaskCount++;
sBattleAnimScriptPtr += 4;
}
static void Task_WaitAndPlaySE(u8 taskId)
{
if (gTasks[taskId].tFramesToWait-- <= 0)
{
PlaySE12WithPanning(gTasks[taskId].tSongId, gTasks[taskId].tPanning);
DestroyTask(taskId);
gAnimSoundTaskCount--;
}
}
#undef tSongId
#undef tPanning
#undef tFramesToWait
static void Cmd_createsoundtask(void)
2017-10-15 23:21:59 +02:00
{
TaskFunc func;
u8 numArgs, taskId;
s32 i;
sBattleAnimScriptPtr++;
2018-03-01 00:59:52 +01:00
func = (TaskFunc)T2_READ_32(sBattleAnimScriptPtr);
2017-10-15 23:21:59 +02:00
sBattleAnimScriptPtr += 4;
numArgs = sBattleAnimScriptPtr[0];
sBattleAnimScriptPtr++;
for (i = 0; i < numArgs; i++)
{
2018-03-01 00:59:52 +01:00
gBattleAnimArgs[i] = T1_READ_16(sBattleAnimScriptPtr);
2017-10-15 23:21:59 +02:00
sBattleAnimScriptPtr += 2;
}
taskId = CreateTask(func, 1);
func(taskId);
gAnimSoundTaskCount++;
}
static void Cmd_waitsound(void)
2017-10-15 23:21:59 +02:00
{
if (gAnimSoundTaskCount != 0)
{
sSoundAnimFramesToWait = 0;
2021-10-04 16:21:03 +02:00
sAnimFramesToWait = 1;
2017-10-15 23:21:59 +02:00
}
else if (IsSEPlaying())
{
if (++sSoundAnimFramesToWait > 90)
{
m4aMPlayStop(&gMPlayInfo_SE1);
m4aMPlayStop(&gMPlayInfo_SE2);
2017-10-15 23:21:59 +02:00
sSoundAnimFramesToWait = 0;
}
else
{
2021-10-04 16:21:03 +02:00
sAnimFramesToWait = 1;
2017-10-15 23:21:59 +02:00
}
}
else
{
sSoundAnimFramesToWait = 0;
sBattleAnimScriptPtr++;
2021-10-04 16:21:03 +02:00
sAnimFramesToWait = 0;
2017-10-15 23:21:59 +02:00
}
}
static void Cmd_jumpargeq(void)
2017-10-15 23:21:59 +02:00
{
u8 argId;
s16 valueToCheck;
sBattleAnimScriptPtr++;
argId = sBattleAnimScriptPtr[0];
2018-03-01 00:59:52 +01:00
valueToCheck = T1_READ_16(sBattleAnimScriptPtr + 1);
2017-10-15 23:21:59 +02:00
if (valueToCheck == gBattleAnimArgs[argId])
2018-03-01 00:59:52 +01:00
sBattleAnimScriptPtr = T2_READ_PTR(sBattleAnimScriptPtr + 3);
2017-10-15 23:21:59 +02:00
else
sBattleAnimScriptPtr += 7;
}
static void Cmd_jumpifcontest(void)
2017-10-15 23:21:59 +02:00
{
sBattleAnimScriptPtr++;
if (IsContest())
2018-03-01 00:59:52 +01:00
sBattleAnimScriptPtr = T2_READ_PTR(sBattleAnimScriptPtr);
2017-10-15 23:21:59 +02:00
else
sBattleAnimScriptPtr += 4;
}
static void Cmd_splitbgprio(void)
2017-10-15 23:21:59 +02:00
{
2018-06-17 16:48:58 +02:00
u8 wantedBattler;
2018-03-01 00:59:52 +01:00
u8 battlerId;
u8 battlerPosition;
2017-10-15 23:21:59 +02:00
2018-06-17 16:48:58 +02:00
wantedBattler = sBattleAnimScriptPtr[1];
2017-10-15 23:21:59 +02:00
sBattleAnimScriptPtr += 2;
2018-06-17 16:48:58 +02:00
if (wantedBattler != ANIM_ATTACKER)
2018-03-01 00:59:52 +01:00
battlerId = gBattleAnimTarget;
2017-10-15 23:21:59 +02:00
else
2018-03-01 00:59:52 +01:00
battlerId = gBattleAnimAttacker;
2017-10-15 23:21:59 +02:00
// Apply only if the given battler is the lead (on left from team's perspective)
2018-03-01 00:59:52 +01:00
battlerPosition = GetBattlerPosition(battlerId);
if (!IsContest() && (battlerPosition == B_POSITION_PLAYER_LEFT || battlerPosition == B_POSITION_OPPONENT_RIGHT))
2017-10-15 23:21:59 +02:00
{
SetAnimBgAttribute(1, BG_ANIM_PRIORITY, 1);
SetAnimBgAttribute(2, BG_ANIM_PRIORITY, 2);
}
}
static void Cmd_splitbgprio_all(void)
2017-10-15 23:21:59 +02:00
{
sBattleAnimScriptPtr++;
if (!IsContest())
{
SetAnimBgAttribute(1, BG_ANIM_PRIORITY, 1);
SetAnimBgAttribute(2, BG_ANIM_PRIORITY, 2);
}
}
static void Cmd_splitbgprio_foes(void)
2017-10-15 23:21:59 +02:00
{
2018-06-17 16:48:58 +02:00
u8 wantedBattler;
2018-03-01 00:59:52 +01:00
u8 battlerPosition;
u8 battlerId;
2017-10-15 23:21:59 +02:00
2018-06-17 16:48:58 +02:00
wantedBattler = sBattleAnimScriptPtr[1];
2017-10-15 23:21:59 +02:00
sBattleAnimScriptPtr += 2;
// Apply only if the attacking the opposing side
2018-02-06 20:48:02 +01:00
if (GetBattlerSide(gBattleAnimAttacker) != GetBattlerSide(gBattleAnimTarget))
2017-10-15 23:21:59 +02:00
{
2018-06-17 16:48:58 +02:00
if (wantedBattler != ANIM_ATTACKER)
2018-03-01 00:59:52 +01:00
battlerId = gBattleAnimTarget;
2017-10-15 23:21:59 +02:00
else
2018-03-01 00:59:52 +01:00
battlerId = gBattleAnimAttacker;
2017-10-15 23:21:59 +02:00
// Apply only if the given battler is the lead (on left from team's perspective)
2018-03-01 00:59:52 +01:00
battlerPosition = GetBattlerPosition(battlerId);
if (!IsContest() && (battlerPosition == B_POSITION_PLAYER_LEFT || battlerPosition == B_POSITION_OPPONENT_RIGHT))
2017-10-15 23:21:59 +02:00
{
SetAnimBgAttribute(1, BG_ANIM_PRIORITY, 1);
SetAnimBgAttribute(2, BG_ANIM_PRIORITY, 2);
}
}
}
static void Cmd_invisible(void)
2017-10-15 23:21:59 +02:00
{
u8 spriteId;
spriteId = GetAnimBattlerSpriteId(sBattleAnimScriptPtr[1]);
2021-02-20 06:30:37 +01:00
if (spriteId != SPRITE_NONE)
gSprites[spriteId].invisible = TRUE;
2017-10-15 23:21:59 +02:00
sBattleAnimScriptPtr += 2;
}
static void Cmd_visible(void)
2017-10-15 23:21:59 +02:00
{
u8 spriteId;
spriteId = GetAnimBattlerSpriteId(sBattleAnimScriptPtr[1]);
2021-02-20 06:30:37 +01:00
if (spriteId != SPRITE_NONE)
gSprites[spriteId].invisible = FALSE;
2017-10-15 23:21:59 +02:00
sBattleAnimScriptPtr += 2;
}
// Below two commands are never used
static void Cmd_teamattack_moveback(void)
2017-10-15 23:21:59 +02:00
{
2018-06-17 16:48:58 +02:00
u8 wantedBattler;
u8 priorityRank;
2017-10-15 23:21:59 +02:00
u8 spriteId;
2018-06-17 16:48:58 +02:00
wantedBattler = sBattleAnimScriptPtr[1];
2017-10-15 23:21:59 +02:00
sBattleAnimScriptPtr += 2;
// Apply to double battles when attacking own side
2017-10-15 23:21:59 +02:00
if (!IsContest() && IsDoubleBattle()
2018-02-06 20:48:02 +01:00
&& GetBattlerSide(gBattleAnimAttacker) == GetBattlerSide(gBattleAnimTarget))
2017-10-15 23:21:59 +02:00
{
2018-06-17 16:48:58 +02:00
if (wantedBattler == ANIM_ATTACKER)
2017-10-15 23:21:59 +02:00
{
priorityRank = GetBattlerSpriteBGPriorityRank(gBattleAnimAttacker);
spriteId = GetAnimBattlerSpriteId(ANIM_ATTACKER);
2017-10-15 23:21:59 +02:00
}
else
{
priorityRank = GetBattlerSpriteBGPriorityRank(gBattleAnimTarget);
spriteId = GetAnimBattlerSpriteId(ANIM_TARGET);
2017-10-15 23:21:59 +02:00
}
2021-02-20 06:30:37 +01:00
if (spriteId != SPRITE_NONE)
2017-10-15 23:21:59 +02:00
{
gSprites[spriteId].invisible = FALSE;
if (priorityRank == 2)
2017-10-15 23:21:59 +02:00
gSprites[spriteId].oam.priority = 3;
if (priorityRank == 1)
2021-02-28 00:41:30 +01:00
ResetBattleAnimBg(FALSE);
2017-10-15 23:21:59 +02:00
else
2021-02-28 00:41:30 +01:00
ResetBattleAnimBg(TRUE);
2017-10-15 23:21:59 +02:00
}
}
}
static void Cmd_teamattack_movefwd(void)
2017-10-15 23:21:59 +02:00
{
2018-06-17 16:48:58 +02:00
u8 wantedBattler;
u8 priorityRank;
2017-10-15 23:21:59 +02:00
u8 spriteId;
2018-06-17 16:48:58 +02:00
wantedBattler = sBattleAnimScriptPtr[1];
2017-10-15 23:21:59 +02:00
sBattleAnimScriptPtr += 2;
// Apply to double battles when attacking own side
2017-10-15 23:21:59 +02:00
if (!IsContest() && IsDoubleBattle()
2018-02-06 20:48:02 +01:00
&& GetBattlerSide(gBattleAnimAttacker) == GetBattlerSide(gBattleAnimTarget))
2017-10-15 23:21:59 +02:00
{
2018-06-17 16:48:58 +02:00
if (wantedBattler == ANIM_ATTACKER)
2017-10-15 23:21:59 +02:00
{
priorityRank = GetBattlerSpriteBGPriorityRank(gBattleAnimAttacker);
spriteId = GetAnimBattlerSpriteId(ANIM_ATTACKER);
2017-10-15 23:21:59 +02:00
}
else
{
priorityRank = GetBattlerSpriteBGPriorityRank(gBattleAnimTarget);
spriteId = GetAnimBattlerSpriteId(ANIM_TARGET);
2017-10-15 23:21:59 +02:00
}
if (spriteId != SPRITE_NONE && priorityRank == 2)
2017-10-15 23:21:59 +02:00
gSprites[spriteId].oam.priority = 2;
}
}
static void Cmd_stopsound(void)
2017-10-15 23:21:59 +02:00
{
m4aMPlayStop(&gMPlayInfo_SE1);
m4aMPlayStop(&gMPlayInfo_SE2);
2017-10-15 23:21:59 +02:00
sBattleAnimScriptPtr++;
2017-10-14 23:37:44 +02:00
}