expansion sync: battle_anim_normal

This commit is contained in:
cawtds
2025-01-20 23:23:11 +01:00
parent fd03858c3d
commit 0e6894a26f
3 changed files with 219 additions and 64 deletions

View File

@@ -89,6 +89,8 @@ bool32 BeginNormalPaletteFade(u32 selectedPalettes, s8 delay, u8 startY, u8 targ
bool32 BeginTimeOfDayPaletteFade(u32, s8, u8, u8, struct BlendSettings *, struct BlendSettings *, u32, u32);
void ResetPaletteFadeControl(void);
void InvertPlttBuffer(u32 selectedPalettes);
void TintPlttBuffer(u32 selectedPalettes, s8 r, s8 g, s8 b);
void UnfadePlttBuffer(u32 selectedPalettes);
void BeginFastPaletteFade(u32 submode);
void BeginHardwarePaletteFade(u32 blendCnt, u32 delay, u32 y, u32 targetY, u32 shouldResetBlendRegisters);
void BlendPalettes(u32 selectedPalettes, u8 coeff, u32 color);

View File

@@ -4,32 +4,32 @@
#include "random.h"
#include "task.h"
#include "trig.h"
#include "constants/rgb.h"
static void AnimConfusionDuck(struct Sprite *sprite);
static void AnimSimplePaletteBlend(struct Sprite *sprite);
static void AnimComplexPaletteBlend(struct Sprite *sprite);
static void AnimCirclingSparkle(struct Sprite *sprite);
static void AnimShakeMonOrBattleTerrain(struct Sprite *sprite);
static void AnimHitSplatHandleInvert(struct Sprite *sprite);
static void AnimHitSplatPersistent(struct Sprite *sprite);
static void AnimConfusionDuck_Step(struct Sprite *sprite);
static void AnimSimplePaletteBlend_Step(struct Sprite *sprite);
static void AnimComplexPaletteBlend_Step1(struct Sprite *sprite);
static void AnimComplexPaletteBlend_Step2(struct Sprite *sprite);
static void BlendColorCycle(u8 taskId, u8 initialBlendAmount, u8 targetBlendAmount);
static void AnimTask_BlendColorCycleLoop(u8 taskId);
static void BlendColorCycleExclude(u8 taskId, u8 initialBlendAmount, u8 targetBlendAmount);
static void AnimTask_BlendColorCycleExcludeLoop(u8 taskId);
static void BlendColorCycleByTag(u8 taskId, u8 initialBlendAmount, u8 targetBlendAmount);
static void AnimTask_BlendColorCycleByTagLoop(u8 taskId);
static void AnimTask_FlashAnimTagWithColor_Step1(u8 taskId);
static void AnimTask_FlashAnimTagWithColor_Step2(u8 taskId);
static void AnimConfusionDuck(struct Sprite *);
static void AnimSimplePaletteBlend(struct Sprite *);
static void AnimSimplePaletteBlend_Step(struct Sprite *);
static void AnimComplexPaletteBlend(struct Sprite *);
static void AnimComplexPaletteBlend_Step1(struct Sprite *);
static void AnimComplexPaletteBlend_Step2(struct Sprite *);
static void AnimCirclingSparkle(struct Sprite *);
static void AnimShakeMonOrBattleTerrain(struct Sprite *);
static void AnimShakeMonOrBattleTerrain_Step(struct Sprite *);
static void AnimShakeMonOrBattleTerrain_UpdateCoordOffsetEnabled(void);
static void AnimShakeMonOrBattleTerrain_Step(struct Sprite *sprite);
static void AnimTask_ShakeBattleTerrain_Step(u8 taskId);
static void AnimHitSplatPersistent(struct Sprite *);
static void AnimHitSplatHandleInvert(struct Sprite *);
static void AnimConfusionDuck_Step(struct Sprite *);
static void BlendColorCycle(u8, u8, u8);
static void AnimTask_BlendColorCycleLoop(u8);
static void BlendColorCycleExclude(u8, u8, u8);
static void AnimTask_BlendColorCycleExcludeLoop(u8);
static void BlendColorCycleByTag(u8, u8, u8);
static void AnimTask_BlendColorCycleByTagLoop(u8);
static void AnimTask_FlashAnimTagWithColor_Step1(u8);
static void AnimTask_FlashAnimTagWithColor_Step2(u8);
static void AnimTask_ShakeBattleTerrain_Step(u8);
static void AnimMovePowerSwapGuardSwap(struct Sprite *);
static const union AnimCmd sAnim_ConfusionDuck_0[] =
{
ANIMCMD_FRAME(0, 8),
@@ -258,7 +258,7 @@ const struct SpriteTemplate gRandomPosHitSplatSpriteTemplate =
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gAffineAnims_HitSplat,
.callback = AnimHitSplatRandom,
.callback = SpriteCB_RandomCentredHits,
};
const struct SpriteTemplate gMonEdgeHitSplatSpriteTemplate =
@@ -360,6 +360,7 @@ static void AnimConfusionDuck(struct Sprite *sprite)
sprite->data[4] = 0;
StartSpriteAnim(sprite, 1);
}
sprite->data[3] = gBattleAnimArgs[4];
sprite->callback = AnimConfusionDuck_Step;
sprite->callback(sprite);
@@ -369,10 +370,12 @@ static void AnimConfusionDuck_Step(struct Sprite *sprite)
{
sprite->x2 = Cos(sprite->data[0], 30);
sprite->y2 = Sin(sprite->data[0], 10);
if ((u16)sprite->data[0] < 128)
sprite->oam.priority = 1;
else
sprite->oam.priority = 3;
sprite->data[0] = (sprite->data[0] + sprite->data[1]) & 0xFF;
if (++sprite->data[2] == sprite->data[3])
DestroyAnimSprite(sprite);
@@ -387,7 +390,6 @@ static void AnimConfusionDuck_Step(struct Sprite *sprite)
static void AnimSimplePaletteBlend(struct Sprite *sprite)
{
u32 selectedPalettes = UnpackSelectedBattlePalettes(gBattleAnimArgs[0]);
BeginNormalPaletteFade(selectedPalettes, gBattleAnimArgs[1], gBattleAnimArgs[2], gBattleAnimArgs[3], gBattleAnimArgs[4]);
sprite->invisible = TRUE;
sprite->callback = AnimSimplePaletteBlend_Step;
@@ -400,17 +402,35 @@ static void AnimSimplePaletteBlend(struct Sprite *sprite)
// 2: F_PAL_TARGET, gBattleAnimTarget OBJ palette
// 3: F_PAL_ATK_PARTNER, gBattleAnimAttacker partner OBJ palette
// 4: F_PAL_DEF_PARTNER, gBattleAnimTarget partner OBJ palette
// 5: F_PAL_ANIM_1, BG palette 8
// 5: F_PAL_ANIM_1, BG palette 8 (or 14, if in Contest)
// 6: F_PAL_ANIM_2, BG palette 9
u32 UnpackSelectedBattlePalettes(s16 selector)
{
u8 battleBackground = selector & 1;
u8 attacker = (selector >> 1) & 1;
u8 target = (selector >> 2) & 1;
u8 attackerPartner = (selector >> 3) & 1;
u8 targetPartner = (selector >> 4) & 1;
u8 anim1 = (selector >> 5) & 1;
u8 anim2 = (selector >> 6) & 1;
bool8 battleBackground = selector & 1;
bool8 attacker = (selector >> 1) & 1;
bool8 target = (selector >> 2) & 1;
bool8 attackerPartner = (selector >> 3) & 1;
bool8 targetPartner = (selector >> 4) & 1;
bool8 anim1 = (selector >> 5) & 1;
bool8 anim2 = (selector >> 6) & 1;
u32 moveTarget = GetBattlerMoveTargetType(gBattlerAttacker, gAnimMoveIndex);
switch (moveTarget)
{
case MOVE_TARGET_BOTH:
if (target)
{
targetPartner |= 1;
}
break;
case MOVE_TARGET_FOES_AND_ALLY:
if (target)
{
targetPartner |= 1;
attackerPartner |= 1;
}
break;
}
return GetBattlePalettesMask(battleBackground, attacker, target, attackerPartner, targetPartner, anim1, anim2);
}
@@ -433,6 +453,7 @@ static void AnimComplexPaletteBlend(struct Sprite *sprite)
sprite->data[5] = gBattleAnimArgs[5];
sprite->data[6] = gBattleAnimArgs[6];
sprite->data[7] = gBattleAnimArgs[0];
selectedPalettes = UnpackSelectedBattlePalettes(sprite->data[7]);
BlendPalettes(selectedPalettes, gBattleAnimArgs[4], gBattleAnimArgs[3]);
sprite->invisible = TRUE;
@@ -445,24 +466,28 @@ static void AnimComplexPaletteBlend_Step1(struct Sprite *sprite)
if (sprite->data[0] > 0)
{
--sprite->data[0];
sprite->data[0]--;
return;
}
if (gPaletteFade.active)
return;
if (sprite->data[2] == 0)
{
sprite->callback = AnimComplexPaletteBlend_Step2;
return;
}
selectedPalettes = UnpackSelectedBattlePalettes(sprite->data[7]);
if (sprite->data[1] & 0x100)
BlendPalettes(selectedPalettes, sprite->data[4], sprite->data[3]);
else
BlendPalettes(selectedPalettes, sprite->data[6], sprite->data[5]);
sprite->data[1] ^= 0x100;
sprite->data[0] = sprite->data[1] & 0xFF;
--sprite->data[2];
sprite->data[2]--;
}
static void AnimComplexPaletteBlend_Step2(struct Sprite *sprite)
@@ -725,12 +750,15 @@ void AnimTask_FlashAnimTagWithColor(u8 taskId)
gTasks[taskId].data[5] = gBattleAnimArgs[5];
gTasks[taskId].data[6] = gBattleAnimArgs[6];
gTasks[taskId].data[7] = gBattleAnimArgs[0];
paletteIndex = IndexOfSpritePaletteTag(gBattleAnimArgs[0]);
BeginNormalPaletteFade(1 << (paletteIndex + 16),
0,
gBattleAnimArgs[4],
gBattleAnimArgs[4],
gBattleAnimArgs[3]);
BeginNormalPaletteFade(
1 << (paletteIndex + 16),
0,
gBattleAnimArgs[4],
gBattleAnimArgs[4],
gBattleAnimArgs[3]);
gTasks[taskId].func = AnimTask_FlashAnimTagWithColor_Step1;
}
@@ -740,32 +768,42 @@ static void AnimTask_FlashAnimTagWithColor_Step1(u8 taskId)
if (gTasks[taskId].data[0] > 0)
{
--gTasks[taskId].data[0];
gTasks[taskId].data[0]--;
return;
}
if (gPaletteFade.active)
return;
if (gTasks[taskId].data[2] == 0)
{
gTasks[taskId].func = AnimTask_FlashAnimTagWithColor_Step2;
return;
}
selectedPalettes = 1 << (IndexOfSpritePaletteTag(gTasks[taskId].data[7]) + 16);
if (gTasks[taskId].data[1] & 0x100)
BeginNormalPaletteFade(selectedPalettes,
0,
gTasks[taskId].data[4],
gTasks[taskId].data[4],
gTasks[taskId].data[3]);
{
BeginNormalPaletteFade(
selectedPalettes,
0,
gTasks[taskId].data[4],
gTasks[taskId].data[4],
gTasks[taskId].data[3]);
}
else
BeginNormalPaletteFade(selectedPalettes,
0,
gTasks[taskId].data[6],
gTasks[taskId].data[6],
gTasks[taskId].data[5]);
{
BeginNormalPaletteFade(
selectedPalettes,
0,
gTasks[taskId].data[6],
gTasks[taskId].data[6],
gTasks[taskId].data[5]);
}
gTasks[taskId].data[1] ^= 0x100;
gTasks[taskId].data[0] = gTasks[taskId].data[1] & 0xFF;
--gTasks[taskId].data[2];
gTasks[taskId].data[2]--;
}
static void AnimTask_FlashAnimTagWithColor_Step2(u8 taskId)
@@ -775,7 +813,7 @@ static void AnimTask_FlashAnimTagWithColor_Step2(u8 taskId)
if (!gPaletteFade.active)
{
selectedPalettes = 1 << (IndexOfSpritePaletteTag(gTasks[taskId].data[7]) + 16);
BeginNormalPaletteFade(selectedPalettes, 0, 0, 0, RGB(0, 0, 0));
BeginNormalPaletteFade(selectedPalettes, 0, 0, 0, RGB_BLACK);
DestroyAnimVisualTask(taskId);
}
}
@@ -792,11 +830,75 @@ void AnimTask_InvertScreenColor(u8 taskId)
selectedPalettes |= (0x10000 << gBattleAnimTarget);
if (gBattleAnimArgs[0] & 0x8 && IsBattlerAlive(BATTLE_PARTNER(gBattleAnimTarget)))
selectedPalettes |= (0x10000 << BATTLE_PARTNER(gBattleAnimTarget));
if (gBattleAnimArgs[0] & 0x10 && IsBattlerAlive(BATTLE_PARTNER(gBattleAnimAttacker)))
selectedPalettes |= (0x10000 << BATTLE_PARTNER(gBattleAnimAttacker));
InvertPlttBuffer(selectedPalettes);
DestroyAnimVisualTask(taskId);
}
// Unused
#define tTimer data[0]
#define tLength data[1]
#define tFlagsScenery data[2]
#define tFlagsAttacker data[3]
#define tFlagsTarget data[4]
#define tColorR data[5]
#define tColorG data[6]
#define tColorB data[7]
void AnimTask_TintPalettes(u8 taskId)
{
u8 attackerBattler;
u8 targetBattler;
u8 paletteIndex;
u32 selectedPalettes = 0;
if (gTasks[taskId].tTimer == 0)
{
gTasks[taskId].tFlagsScenery = gBattleAnimArgs[0];
gTasks[taskId].tFlagsAttacker = gBattleAnimArgs[1];
gTasks[taskId].tFlagsTarget = gBattleAnimArgs[2];
gTasks[taskId].tLength = gBattleAnimArgs[3];
gTasks[taskId].tColorR = gBattleAnimArgs[4];
gTasks[taskId].tColorG = gBattleAnimArgs[5];
gTasks[taskId].tColorB = gBattleAnimArgs[6];
}
gTasks[taskId].tTimer++;
attackerBattler = gBattleAnimAttacker;
targetBattler = gBattleAnimTarget;
if (gTasks[taskId].tFlagsScenery & (1 << 8))
selectedPalettes = PALETTES_BG;
if (gTasks[taskId].tFlagsScenery & 1)
{
paletteIndex = IndexOfSpritePaletteTag(gSprites[gHealthboxSpriteIds[attackerBattler]].template->paletteTag);
selectedPalettes |= (1 << paletteIndex) << 16;
}
if (gTasks[taskId].tFlagsAttacker & (1 << 8))
selectedPalettes |= (1 << attackerBattler) << 16;
if (gTasks[taskId].tFlagsTarget & (1 << 8))
selectedPalettes |= (1 << targetBattler) << 16;
TintPlttBuffer(selectedPalettes, gTasks[taskId].tColorR, gTasks[taskId].tColorG, gTasks[taskId].tColorB);
if (gTasks[taskId].tTimer == gTasks[taskId].tLength)
{
UnfadePlttBuffer(selectedPalettes);
DestroyAnimVisualTask(taskId);
}
}
#undef tTimer
#undef tLength
#undef tFlagsScenery
#undef tFlagsAttacker
#undef tFlagsTarget
#undef tColorR
#undef tColorG
#undef tColorB
static void AnimShakeMonOrBattleTerrain(struct Sprite *sprite)
{
u16 var0;
@@ -822,11 +924,13 @@ static void AnimShakeMonOrBattleTerrain(struct Sprite *sprite)
StoreSpriteCallbackInData6(sprite, (void *)&gSpriteCoordOffsetY);
break;
}
sprite->data[4] = *(u16 *)(sprite->data[6] | (sprite->data[7] << 16));
sprite->data[5] = gBattleAnimArgs[3];
var0 = sprite->data[5] - 2;
if (var0 < 2)
AnimShakeMonOrBattleTerrain_UpdateCoordOffsetEnabled();
sprite->callback = AnimShakeMonOrBattleTerrain_Step;
}
@@ -837,10 +941,10 @@ static void AnimShakeMonOrBattleTerrain_Step(struct Sprite *sprite)
if (sprite->data[3] > 0)
{
--sprite->data[3];
sprite->data[3]--;
if (sprite->data[1] > 0)
{
--sprite->data[1];
sprite->data[1]--;
}
else
{
@@ -854,8 +958,11 @@ static void AnimShakeMonOrBattleTerrain_Step(struct Sprite *sprite)
*(u16 *)(sprite->data[6] | (sprite->data[7] << 16)) = sprite->data[4];
var0 = sprite->data[5] - 2;
if (var0 < 2)
for (i = 0; i < gBattlersCount; ++i)
{
for (i = 0; i < gBattlersCount; i++)
gSprites[gBattlerSpriteIds[i]].coordOffsetEnabled = FALSE;
}
DestroyAnimSprite(sprite);
}
}
@@ -864,6 +971,7 @@ static void AnimShakeMonOrBattleTerrain_UpdateCoordOffsetEnabled(void)
{
gSprites[gBattlerSpriteIds[gBattleAnimAttacker]].coordOffsetEnabled = FALSE;
gSprites[gBattlerSpriteIds[gBattleAnimTarget]].coordOffsetEnabled = FALSE;
if (gBattleAnimArgs[4] == 2)
{
gSprites[gBattlerSpriteIds[gBattleAnimAttacker]].coordOffsetEnabled = TRUE;
@@ -940,10 +1048,11 @@ static void AnimTask_ShakeBattleTerrain_Step(u8 taskId)
void AnimHitSplatBasic(struct Sprite *sprite)
{
StartSpriteAffineAnim(sprite, gBattleAnimArgs[3]);
if (gBattleAnimArgs[2] == 0)
if (gBattleAnimArgs[2] == ANIM_ATTACKER)
InitSpritePosToAnimAttacker(sprite, TRUE);
else
InitSpritePosToAnimTarget(sprite, TRUE);
sprite->callback = RunStoredCallbackWhenAffineAnimEnds;
StoreSpriteCallbackInData6(sprite, DestroyAnimSprite);
}
@@ -952,10 +1061,11 @@ void AnimHitSplatBasic(struct Sprite *sprite)
static void AnimHitSplatPersistent(struct Sprite *sprite)
{
StartSpriteAffineAnim(sprite, gBattleAnimArgs[3]);
if (gBattleAnimArgs[2] == 0)
if (gBattleAnimArgs[2] == ANIM_ATTACKER)
InitSpritePosToAnimAttacker(sprite, TRUE);
else
InitSpritePosToAnimTarget(sprite, TRUE);
sprite->data[0] = gBattleAnimArgs[4];
sprite->callback = RunStoredCallbackWhenAffineAnimEnds;
StoreSpriteCallbackInData6(sprite, DestroyAnimSpriteAfterTimer);
@@ -967,20 +1077,22 @@ static void AnimHitSplatHandleInvert(struct Sprite *sprite)
{
if (GetBattlerSide(gBattleAnimAttacker) != B_SIDE_PLAYER && !IsContest())
gBattleAnimArgs[1] = -gBattleAnimArgs[1];
AnimHitSplatBasic(sprite);
}
void AnimHitSplatRandom(struct Sprite *sprite)
{
if (gBattleAnimArgs[1] == -1)
gBattleAnimArgs[1] = Random() & 3;
gBattleAnimArgs[1] = Random2() & 3;
if (!InitSpritePosToAnimBattler(gBattleAnimArgs[0], sprite, FALSE))
return;
StartSpriteAffineAnim(sprite, gBattleAnimArgs[1]);
if (gBattleAnimArgs[0] == ANIM_ATTACKER)
InitSpritePosToAnimAttacker(sprite, FALSE);
else
InitSpritePosToAnimTarget(sprite, FALSE);
sprite->x2 += (Random() % 48) - 24;
sprite->y2 += (Random() % 24) - 12;
sprite->x2 += (Random2() % 48) - 24;
sprite->y2 += (Random2() % 24) - 12;
StoreSpriteCallbackInData6(sprite, DestroySpriteAndMatrix);
sprite->callback = RunStoredCallbackWhenAffineAnimEnds;
}
@@ -1003,6 +1115,7 @@ void AnimCrossImpact(struct Sprite *sprite)
InitSpritePosToAnimAttacker(sprite, TRUE);
else
InitSpritePosToAnimTarget(sprite, TRUE);
sprite->data[0] = gBattleAnimArgs[3];
StoreSpriteCallbackInData6(sprite, DestroyAnimSprite);
sprite->callback = WaitAnimForDuration;
@@ -1015,6 +1128,7 @@ void AnimFlashingHitSplat(struct Sprite *sprite)
InitSpritePosToAnimAttacker(sprite, TRUE);
else
InitSpritePosToAnimTarget(sprite, TRUE);
sprite->callback = AnimFlashingHitSplat_Step;
}

View File

@@ -411,6 +411,45 @@ void InvertPlttBuffer(u32 selectedPalettes)
}
}
void TintPlttBuffer(u32 selectedPalettes, s8 r, s8 g, s8 b)
{
u16 paletteOffset = 0;
while (selectedPalettes)
{
if (selectedPalettes & 1)
{
u32 i;
for (i = 0; i < 16; i++)
{
struct PlttData *data = (struct PlttData *)&gPlttBufferFaded[paletteOffset + i];
data->r += r;
data->g += g;
data->b += b;
}
}
selectedPalettes >>= 1;
paletteOffset += 16;
}
}
void UnfadePlttBuffer(u32 selectedPalettes)
{
u16 paletteOffset = 0;
while (selectedPalettes)
{
if (selectedPalettes & 1)
{
u8 i;
for (i = 0; i < 16; i++)
gPlttBufferFaded[paletteOffset + i] = gPlttBufferUnfaded[paletteOffset + i];
}
selectedPalettes >>= 1;
paletteOffset += 16;
}
}
void BeginFastPaletteFade(u32 submode)
{
gPaletteFade.deltaY = 2;