sovereignx/src/battle_anim_smokescreen.c
Rachel b478881fc6
Add in-battle shadows underneath all enemy battlers (#5178)
* Add data to SpeciesInfo entries for in-battle shadows

* Implement sized shadows in the sprite visualizer

* Implement sized shadows in game code

* Show shadows for the lead battler for opponents during their battle anim

* Feedback on shadows, round 1

* Revert removal of Goomy and Sliggoo shadows

* Fixed GEN_3 setting

* Code cleanup + remove pre-processor branches

* Fix bugs with gen-3 configuration branch

* Style corrections, final shadow coordinate adjustments

* Adjustments to Garbodor and Araquanid
2024-09-10 21:27:49 +02:00

166 lines
4.7 KiB
C

#include "global.h"
#include "battle_gfx_sfx_util.h"
#include "data.h"
#include "decompress.h"
#include "graphics.h"
#include "sprite.h"
#include "util.h"
#include "constants/battle_palace.h"
#define TAG_SMOKESCREEN 55019
static void SpriteCB_SmokescreenImpactMain(struct Sprite *);
static void SpriteCB_SmokescreenImpact(struct Sprite *);
// The below data for smokescreen starts and ends with some data that belongs to battle_gfx_sfx_util.c
static const struct CompressedSpriteSheet sSmokescreenImpactSpriteSheet =
{
.data = gSmokescreenImpactTiles, .size = 0x180, .tag = TAG_SMOKESCREEN
};
static const struct CompressedSpritePalette sSmokescreenImpactSpritePalette =
{
.data = gSmokescreenImpactPalette, .tag = TAG_SMOKESCREEN
};
static const struct OamData sOamData_SmokescreenImpact =
{
.y = 0,
.affineMode = ST_OAM_AFFINE_OFF,
.objMode = ST_OAM_OBJ_NORMAL,
.mosaic = FALSE,
.bpp = ST_OAM_4BPP,
.shape = SPRITE_SHAPE(16x16),
.x = 0,
.matrixNum = 0,
.size = SPRITE_SIZE(16x16),
.tileNum = 0,
.priority = 1,
.paletteNum = 0,
.affineParam = 0
};
static const union AnimCmd sAnim_SmokescreenImpact_0[] =
{
ANIMCMD_FRAME(0, 4),
ANIMCMD_FRAME(4, 4),
ANIMCMD_FRAME(8, 4),
ANIMCMD_END
};
static const union AnimCmd sAnim_SmokescreenImpact_1[] =
{
ANIMCMD_FRAME(0, 4, .hFlip = TRUE),
ANIMCMD_FRAME(4, 4, .hFlip = TRUE),
ANIMCMD_FRAME(8, 4, .hFlip = TRUE),
ANIMCMD_END
};
static const union AnimCmd sAnim_SmokescreenImpact_2[] =
{
ANIMCMD_FRAME(0, 4, .vFlip = TRUE),
ANIMCMD_FRAME(4, 4, .vFlip = TRUE),
ANIMCMD_FRAME(8, 4, .vFlip = TRUE),
ANIMCMD_END
};
static const union AnimCmd sAnim_SmokescreenImpact_3[] =
{
ANIMCMD_FRAME(0, 4, .hFlip = TRUE, .vFlip = TRUE),
ANIMCMD_FRAME(4, 4, .hFlip = TRUE, .vFlip = TRUE),
ANIMCMD_FRAME(8, 4, .hFlip = TRUE, .vFlip = TRUE),
ANIMCMD_END
};
static const union AnimCmd *const sAnims_SmokescreenImpact[] =
{
sAnim_SmokescreenImpact_0,
sAnim_SmokescreenImpact_1,
sAnim_SmokescreenImpact_2,
sAnim_SmokescreenImpact_3,
};
static const struct SpriteTemplate sSmokescreenImpactSpriteTemplate =
{
.tileTag = TAG_SMOKESCREEN,
.paletteTag = TAG_SMOKESCREEN,
.oam = &sOamData_SmokescreenImpact,
.anims = sAnims_SmokescreenImpact,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = SpriteCB_SmokescreenImpact
};
#define sActiveSprites data[0]
#define sPersist data[1]
#define sMainSpriteId data[0]
u8 SmokescreenImpact(s16 x, s16 y, bool8 persist)
{
u8 mainSpriteId;
u8 spriteId1, spriteId2, spriteId3, spriteId4;
struct Sprite *mainSprite;
if (GetSpriteTileStartByTag(sSmokescreenImpactSpriteSheet.tag) == 0xFFFF)
{
LoadCompressedSpriteSheetUsingHeap(&sSmokescreenImpactSpriteSheet);
LoadCompressedSpritePaletteUsingHeap(&sSmokescreenImpactSpritePalette);
}
mainSpriteId = CreateInvisibleSpriteWithCallback(SpriteCB_SmokescreenImpactMain);
mainSprite = &gSprites[mainSpriteId];
mainSprite->sPersist = persist;
// Top left sprite
spriteId1 = CreateSprite(&sSmokescreenImpactSpriteTemplate, x - 16, y - 16, 2);
gSprites[spriteId1].sMainSpriteId = mainSpriteId;
mainSprite->sActiveSprites++;
AnimateSprite(&gSprites[spriteId1]);
// Top right sprite
spriteId2 = CreateSprite(&sSmokescreenImpactSpriteTemplate, x, y - 16, 2);
gSprites[spriteId2].sMainSpriteId = mainSpriteId;
mainSprite->sActiveSprites++;
StartSpriteAnim(&gSprites[spriteId2], 1);
AnimateSprite(&gSprites[spriteId2]);
// Bottom left sprite
spriteId3 = CreateSprite(&sSmokescreenImpactSpriteTemplate, x - 16, y, 2);
gSprites[spriteId3].sMainSpriteId = mainSpriteId;
mainSprite->sActiveSprites++;
StartSpriteAnim(&gSprites[spriteId3], 2);
AnimateSprite(&gSprites[spriteId3]);
// Bottom right sprite
spriteId4 = CreateSprite(&sSmokescreenImpactSpriteTemplate, x, y, 2);
gSprites[spriteId4].sMainSpriteId = mainSpriteId;
mainSprite->sActiveSprites++;
StartSpriteAnim(&gSprites[spriteId4], 3);
AnimateSprite(&gSprites[spriteId4]);
return mainSpriteId;
}
static void SpriteCB_SmokescreenImpactMain(struct Sprite *sprite)
{
if (sprite->sActiveSprites == 0)
{
FreeSpriteTilesByTag(sSmokescreenImpactSpriteSheet.tag);
FreeSpritePaletteByTag(sSmokescreenImpactSpritePalette.tag);
if (!sprite->sPersist)
DestroySprite(sprite);
else
sprite->callback = SpriteCallbackDummy;
}
}
static void SpriteCB_SmokescreenImpact(struct Sprite *sprite)
{
if (sprite->animEnded)
{
gSprites[sprite->sMainSpriteId].sActiveSprites--;
DestroySprite(sprite);
}
}