pokeemerald/src/battle_anim_smokescreen.c

232 lines
6.7 KiB
C
Raw Normal View History

2018-02-12 12:14:04 +01:00
#include "global.h"
2020-02-11 19:54:23 +01:00
#include "battle_gfx_sfx_util.h"
2019-04-04 23:53:06 +02:00
#include "data.h"
2018-02-12 12:14:04 +01:00
#include "decompress.h"
2020-02-11 19:54:23 +01:00
#include "graphics.h"
2018-02-12 12:14:04 +01:00
#include "sprite.h"
#include "util.h"
2020-07-17 02:12:12 +02:00
#include "constants/battle_palace.h"
2018-02-12 12:14:04 +01:00
2022-06-01 18:41:57 +02:00
#define TAG_SMOKESCREEN 55019
#define PALTAG_SHADOW 55039
#define GFXTAG_SHADOW 55129
static void SpriteCB_SmokescreenImpactMain(struct Sprite *);
static void SpriteCB_SmokescreenImpact(struct Sprite *);
2018-02-12 12:14:04 +01:00
2020-02-11 19:54:23 +01:00
// The below data for smokescreen starts and ends with some data that belongs to battle_gfx_sfx_util.c
const u8 gBattlePalaceNatureToMoveTarget[NUM_NATURES] =
2020-02-11 19:54:23 +01:00
{
2020-07-17 02:12:12 +02:00
[NATURE_HARDY] = PALACE_TARGET_STRONGER,
[NATURE_LONELY] = PALACE_TARGET_STRONGER,
[NATURE_BRAVE] = PALACE_TARGET_WEAKER,
[NATURE_ADAMANT] = PALACE_TARGET_STRONGER,
[NATURE_NAUGHTY] = PALACE_TARGET_WEAKER,
[NATURE_BOLD] = PALACE_TARGET_WEAKER,
[NATURE_DOCILE] = PALACE_TARGET_RANDOM,
2020-07-17 02:12:12 +02:00
[NATURE_RELAXED] = PALACE_TARGET_STRONGER,
[NATURE_IMPISH] = PALACE_TARGET_STRONGER,
[NATURE_LAX] = PALACE_TARGET_STRONGER,
[NATURE_TIMID] = PALACE_TARGET_WEAKER,
[NATURE_HASTY] = PALACE_TARGET_WEAKER,
[NATURE_SERIOUS] = PALACE_TARGET_WEAKER,
[NATURE_JOLLY] = PALACE_TARGET_STRONGER,
[NATURE_NAIVE] = PALACE_TARGET_RANDOM,
2020-07-17 02:12:12 +02:00
[NATURE_MODEST] = PALACE_TARGET_WEAKER,
[NATURE_MILD] = PALACE_TARGET_STRONGER,
[NATURE_QUIET] = PALACE_TARGET_WEAKER,
[NATURE_BASHFUL] = PALACE_TARGET_WEAKER,
[NATURE_RASH] = PALACE_TARGET_STRONGER,
[NATURE_CALM] = PALACE_TARGET_STRONGER,
[NATURE_GENTLE] = PALACE_TARGET_STRONGER,
[NATURE_SASSY] = PALACE_TARGET_WEAKER,
[NATURE_CAREFUL] = PALACE_TARGET_WEAKER,
[NATURE_QUIRKY] = PALACE_TARGET_STRONGER,
2020-02-11 19:54:23 +01:00
};
static const struct CompressedSpriteSheet sSmokescreenImpactSpriteSheet =
2020-02-11 19:54:23 +01:00
{
2022-06-01 18:41:57 +02:00
.data = gSmokescreenImpactTiles, .size = 0x180, .tag = TAG_SMOKESCREEN
2020-02-11 19:54:23 +01:00
};
static const struct CompressedSpritePalette sSmokescreenImpactSpritePalette =
2020-02-11 19:54:23 +01:00
{
2022-06-01 18:41:57 +02:00
.data = gSmokescreenImpactPalette, .tag = TAG_SMOKESCREEN
2020-02-11 19:54:23 +01:00
};
static const struct OamData sOamData_SmokescreenImpact =
2020-02-11 19:54:23 +01:00
{
.y = 0,
2020-02-11 19:54:23 +01:00
.affineMode = ST_OAM_AFFINE_OFF,
.objMode = ST_OAM_OBJ_NORMAL,
2022-07-30 03:27:39 +02:00
.mosaic = FALSE,
2020-02-11 19:54:23 +01:00
.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[] =
2020-02-11 19:54:23 +01:00
{
ANIMCMD_FRAME(0, 4),
ANIMCMD_FRAME(4, 4),
ANIMCMD_FRAME(8, 4),
2020-02-11 19:54:23 +01:00
ANIMCMD_END
};
static const union AnimCmd sAnim_SmokescreenImpact_1[] =
2020-02-11 19:54:23 +01:00
{
ANIMCMD_FRAME(0, 4, .hFlip = TRUE),
ANIMCMD_FRAME(4, 4, .hFlip = TRUE),
ANIMCMD_FRAME(8, 4, .hFlip = TRUE),
2020-02-11 19:54:23 +01:00
ANIMCMD_END
};
static const union AnimCmd sAnim_SmokescreenImpact_2[] =
2020-02-11 19:54:23 +01:00
{
ANIMCMD_FRAME(0, 4, .vFlip = TRUE),
ANIMCMD_FRAME(4, 4, .vFlip = TRUE),
ANIMCMD_FRAME(8, 4, .vFlip = TRUE),
2020-02-11 19:54:23 +01:00
ANIMCMD_END
};
static const union AnimCmd sAnim_SmokescreenImpact_3[] =
2020-02-11 19:54:23 +01:00
{
ANIMCMD_FRAME(0, 4, .hFlip = TRUE, .vFlip = TRUE),
ANIMCMD_FRAME(4, 4, .hFlip = TRUE, .vFlip = TRUE),
ANIMCMD_FRAME(8, 4, .hFlip = TRUE, .vFlip = TRUE),
2020-02-11 19:54:23 +01:00
ANIMCMD_END
};
static const union AnimCmd *const sAnims_SmokescreenImpact[] =
2020-02-11 19:54:23 +01:00
{
sAnim_SmokescreenImpact_0,
sAnim_SmokescreenImpact_1,
sAnim_SmokescreenImpact_2,
sAnim_SmokescreenImpact_3,
2020-02-11 19:54:23 +01:00
};
static const struct SpriteTemplate sSmokescreenImpactSpriteTemplate =
2020-02-11 19:54:23 +01:00
{
2022-06-01 18:41:57 +02:00
.tileTag = TAG_SMOKESCREEN,
.paletteTag = TAG_SMOKESCREEN,
.oam = &sOamData_SmokescreenImpact,
.anims = sAnims_SmokescreenImpact,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
2022-06-01 18:41:57 +02:00
.callback = SpriteCB_SmokescreenImpact
2020-02-11 19:54:23 +01:00
};
const struct CompressedSpriteSheet gSpriteSheet_EnemyShadow =
{
2022-06-01 18:41:57 +02:00
.data = gEnemyMonShadow_Gfx, .size = 0x80, .tag = GFXTAG_SHADOW
2020-02-11 19:54:23 +01:00
};
2021-02-28 00:41:30 +01:00
static const struct OamData sOamData_EnemyShadow =
2020-02-11 19:54:23 +01:00
{
.y = 0,
2020-02-11 19:54:23 +01:00
.affineMode = ST_OAM_AFFINE_OFF,
.objMode = ST_OAM_OBJ_NORMAL,
2022-07-30 03:27:39 +02:00
.mosaic = FALSE,
2020-02-11 19:54:23 +01:00
.bpp = ST_OAM_4BPP,
.shape = SPRITE_SHAPE(32x8),
.x = 0,
.matrixNum = 0,
.size = SPRITE_SIZE(32x8),
.tileNum = 0,
.priority = 3,
.paletteNum = 0,
.affineParam = 0
};
const struct SpriteTemplate gSpriteTemplate_EnemyShadow =
{
2022-06-01 18:41:57 +02:00
.tileTag = GFXTAG_SHADOW,
.paletteTag = PALTAG_SHADOW,
.oam = &sOamData_EnemyShadow,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
2020-02-11 19:54:23 +01:00
.callback = SpriteCB_SetInvisible
};
2019-04-04 23:53:06 +02:00
2022-06-01 18:41:57 +02:00
#define sActiveSprites data[0]
#define sPersist data[1]
#define sMainSpriteId data[0]
u8 SmokescreenImpact(s16 x, s16 y, bool8 persist)
2018-02-12 12:14:04 +01:00
{
u8 mainSpriteId;
u8 spriteId1, spriteId2, spriteId3, spriteId4;
struct Sprite *mainSprite;
if (GetSpriteTileStartByTag(sSmokescreenImpactSpriteSheet.tag) == 0xFFFF)
2018-02-12 12:14:04 +01:00
{
LoadCompressedSpriteSheetUsingHeap(&sSmokescreenImpactSpriteSheet);
LoadCompressedSpritePaletteUsingHeap(&sSmokescreenImpactSpritePalette);
2018-02-12 12:14:04 +01:00
}
2022-06-01 18:41:57 +02:00
mainSpriteId = CreateInvisibleSpriteWithCallback(SpriteCB_SmokescreenImpactMain);
2018-02-12 12:14:04 +01:00
mainSprite = &gSprites[mainSpriteId];
2022-06-01 18:41:57 +02:00
mainSprite->sPersist = persist;
2018-02-12 12:14:04 +01:00
2022-06-01 18:41:57 +02:00
// Top left sprite
spriteId1 = CreateSprite(&sSmokescreenImpactSpriteTemplate, x - 16, y - 16, 2);
2022-06-01 18:41:57 +02:00
gSprites[spriteId1].sMainSpriteId = mainSpriteId;
mainSprite->sActiveSprites++;
2018-02-12 12:14:04 +01:00
AnimateSprite(&gSprites[spriteId1]);
2022-06-01 18:41:57 +02:00
// Top right sprite
spriteId2 = CreateSprite(&sSmokescreenImpactSpriteTemplate, x, y - 16, 2);
2022-06-01 18:41:57 +02:00
gSprites[spriteId2].sMainSpriteId = mainSpriteId;
mainSprite->sActiveSprites++;
2018-02-12 12:14:04 +01:00
StartSpriteAnim(&gSprites[spriteId2], 1);
AnimateSprite(&gSprites[spriteId2]);
2022-06-01 18:41:57 +02:00
// Bottom left sprite
spriteId3 = CreateSprite(&sSmokescreenImpactSpriteTemplate, x - 16, y, 2);
2022-06-01 18:41:57 +02:00
gSprites[spriteId3].sMainSpriteId = mainSpriteId;
mainSprite->sActiveSprites++;
2018-02-12 12:14:04 +01:00
StartSpriteAnim(&gSprites[spriteId3], 2);
AnimateSprite(&gSprites[spriteId3]);
2022-06-01 18:41:57 +02:00
// Bottom right sprite
spriteId4 = CreateSprite(&sSmokescreenImpactSpriteTemplate, x, y, 2);
2022-06-01 18:41:57 +02:00
gSprites[spriteId4].sMainSpriteId = mainSpriteId;
mainSprite->sActiveSprites++;
2018-02-12 12:14:04 +01:00
StartSpriteAnim(&gSprites[spriteId4], 3);
AnimateSprite(&gSprites[spriteId4]);
return mainSpriteId;
}
2022-06-01 18:41:57 +02:00
static void SpriteCB_SmokescreenImpactMain(struct Sprite *sprite)
2018-02-12 12:14:04 +01:00
{
2022-06-01 18:41:57 +02:00
if (sprite->sActiveSprites == 0)
2018-02-12 12:14:04 +01:00
{
FreeSpriteTilesByTag(sSmokescreenImpactSpriteSheet.tag);
FreeSpritePaletteByTag(sSmokescreenImpactSpritePalette.tag);
2022-06-01 18:41:57 +02:00
if (!sprite->sPersist)
2018-02-12 12:14:04 +01:00
DestroySprite(sprite);
else
sprite->callback = SpriteCallbackDummy;
}
}
2022-06-01 18:41:57 +02:00
static void SpriteCB_SmokescreenImpact(struct Sprite *sprite)
2018-02-12 12:14:04 +01:00
{
if (sprite->animEnded)
{
2022-06-01 18:41:57 +02:00
gSprites[sprite->sMainSpriteId].sActiveSprites--;
2018-02-12 12:14:04 +01:00
DestroySprite(sprite);
}
}