sovereignx/src/rayquaza_scene.c

3045 lines
81 KiB
C
Raw Normal View History

2017-12-22 23:22:07 +00:00
#include "global.h"
2018-01-31 12:05:36 +00:00
#include "rayquaza_scene.h"
2017-12-22 23:22:07 +00:00
#include "sprite.h"
#include "task.h"
#include "graphics.h"
#include "bg.h"
2018-01-31 12:05:36 +00:00
#include "main.h"
#include "malloc.h"
2018-01-31 12:05:36 +00:00
#include "palette.h"
#include "scanline_effect.h"
#include "menu.h"
#include "menu_helpers.h"
#include "gpu_regs.h"
#include "decompress.h"
#include "sound.h"
#include "constants/songs.h"
2018-02-01 13:47:41 +00:00
#include "constants/species.h"
2018-02-01 10:17:07 +00:00
#include "constants/rgb.h"
#include "random.h"
2017-12-22 23:22:07 +00:00
2020-08-25 22:49:42 +01:00
/*
This file handles the cutscene showing Rayquaza arriving to settle the Groudon/Kyogre fight
It consists of 5 separate scenes:
- Groudon and Kyogre facing one another in a thunderstorm (RAY_ANIM_DUO_FIGHT)
2020-08-26 21:31:37 +01:00
- Over-the-shoulder of Rayquaza flying (RAY_ANIM_TAKES_FLIGHT)
2020-08-25 22:49:42 +01:00
- Rayquaza emerging from a spotlight down through the clouds (RAY_ANIM_DESCENDS)
- A close-up of Rayquaza flying down (RAY_ANIM_CHARGES)
- Rayquaza floating above Groudon/Kyogre as they back away offscreen (RAY_ANIM_CHASES_AWAY)
2020-08-26 21:31:37 +01:00
A shortened version of the first scene is used when the player first arrives
in Sootopolis during the Groudon/Kyogre conflict, before awakening Rayquaza (RAY_ANIM_DUO_FIGHT_PRE)
This is indicated with the first two arguments to DoRayquazaScene
2020-08-25 22:49:42 +01:00
*/
enum
{
RAY_ANIM_DUO_FIGHT_PRE,
RAY_ANIM_DUO_FIGHT,
RAY_ANIM_TAKES_FLIGHT,
RAY_ANIM_DESCENDS,
RAY_ANIM_CHARGES,
RAY_ANIM_CHASES_AWAY,
RAY_ANIM_END
};
2020-08-26 21:31:37 +01:00
#define TAG_DUOFIGHT_GROUDON 30505
#define TAG_DUOFIGHT_GROUDON_SHOULDER 30506
#define TAG_DUOFIGHT_GROUDON_CLAW 30507
#define TAG_DUOFIGHT_KYOGRE 30508
#define TAG_DUOFIGHT_KYOGRE_SHOULDER 30509
#define TAG_DUOFIGHT_KYOGRE_FIN 30510
#define TAG_FLIGHT_SMOKE 30555
#define TAG_DESCENDS_RAYQUAZA 30556
#define TAG_DESCENDS_RAYQUAZA_TAIL 30557
#define TAG_CHASE_GROUDON 30565
#define TAG_CHASE_GROUDON_TAIL 30566
#define TAG_CHASE_KYOGRE 30568
#define TAG_CHASE_RAYQUAZA 30569
#define TAG_CHASE_RAYQUAZA_TAIL 30570
#define TAG_CHASE_SPLASH 30571
2020-08-25 22:49:42 +01:00
2020-08-26 22:42:51 +01:00
#define MAX_SMOKE 10
2020-08-25 22:49:42 +01:00
struct RayquazaScene
{
MainCallback exitCallback;
u8 tilemapBuffers[4][BG_SCREEN_SIZE];
u16 unk; // never read
2018-02-01 13:47:41 +00:00
u8 animId;
2020-08-25 22:49:42 +01:00
bool8 endEarly;
2018-02-01 13:47:41 +00:00
s16 field_2008;
s16 field_200A;
2020-08-25 22:49:42 +01:00
u8 unused[12];
2018-02-01 13:47:41 +00:00
};
2020-08-25 22:49:42 +01:00
static EWRAM_DATA struct RayquazaScene *sRayScene = NULL;
static void CB2_InitRayquazaScene(void);
static void CB2_RayquazaScene(void);
static void Task_EndAfterFadeScreen(u8 taskId);
2018-02-01 13:47:41 +00:00
2020-08-25 22:49:42 +01:00
// RAY_ANIM_DUO_FIGHT_PRE / RAY_ANIM_DUO_FIGHT
2018-02-01 13:53:27 +00:00
static void Task_DuoFightAnim(u8 taskId);
2018-02-01 22:39:53 +00:00
static void Task_HandleDuoFight(u8 taskId);
2018-02-01 14:32:12 +00:00
static void Task_DuoFightEnd(u8 taskId);
2020-08-25 22:49:42 +01:00
static void DuoFightEnd(u8 taskId, s8 palDelay);
2020-08-26 21:31:37 +01:00
static void Task_DuoFight_AnimateClouds(u8 taskId);
static void DuoFight_PanOffScene(u8 taskId);
static void DuoFight_AnimateRain(void);
static void DuoFight_Lightning1(void);
static void DuoFight_Lightning2(void);
static void DuoFight_LightningLong(void);
static void SpriteCB_DuoFightPre_Groudon(struct Sprite *sprite);
static void SpriteCB_DuoFightPre_Kyogre(struct Sprite *sprite);
static void DuoFight_SlideGroudonDown(struct Sprite *sprite);
static void DuoFight_SlideKyogreDown(struct Sprite *sprite);
static void SpriteCB_DuoFight_Groudon(struct Sprite *sprite);
static void SpriteCB_DuoFight_Kyogre(struct Sprite *sprite);
static u8 CreateDuoFightGroudonSprites(void);
static u8 CreateDuoFightKyogreSprites(void);
2020-08-25 22:49:42 +01:00
// RAY_ANIM_TAKES_FLIGHT
static void Task_RayTakesFlightAnim(u8 taskId);
static void Task_HandleRayTakesFlight(u8 taskId);
static void Task_RayTakesFlightEnd(u8 taskId);
2020-08-26 22:42:51 +01:00
static void Task_TakesFlight_CreateSmoke(u8 taskId);
2020-08-26 21:31:37 +01:00
static void SpriteCB_TakesFlight_Smoke(struct Sprite *sprite);
2020-08-25 22:49:42 +01:00
// RAY_ANIM_DESCENDS
static void Task_RayDescendsAnim(u8 taskId);
static void Task_HandleRayDescends(u8 taskId);
static void Task_RayDescendsEnd(u8 taskId);
2018-02-01 13:47:41 +00:00
static void sub_81D874C(struct Sprite *sprite);
2020-08-25 22:49:42 +01:00
static u8 sub_81D86CC(void);
// RAY_ANIM_CHARGES
static void Task_RayChargesAnim(u8 taskId);
static void Task_HandleRayCharges(u8 taskId);
static void Task_RayChargesEnd(u8 taskId);
static void sub_81D8AD8(u8 taskId);
static void sub_81D8B2C(u8 taskId);
static void sub_81D8BB4(void);
// RAY_ANIM_CHASES_AWAY
static void Task_RayChasesAwayAnim(u8 taskId);
static void Task_HandleRayChasesAway(u8 taskId);
static void Task_RayChasesAwayEnd(u8 taskId);
static void sub_81D8FB0(u8 taskId);
static void sub_81D94D4(u8 taskId);
static void sub_81D93D8(u8 taskId);
static void sub_81D90A8(u8 taskId);
static void sub_81D98B4(u8 taskId);
2018-02-01 13:47:41 +00:00
static void sub_81D9420(struct Sprite *sprite);
static void sub_81D97E0(struct Sprite *sprite);
static void sub_81D9528(struct Sprite *sprite);
2020-08-26 21:31:37 +01:00
static void SpriteCB_ChasesAway_Rayquaza(struct Sprite *sprite);
2020-08-25 22:49:42 +01:00
static void sub_81D9338(struct Sprite *sprite);
2018-02-01 13:47:41 +00:00
static void sub_81D9868(struct Sprite *sprite, u8 animNum, s16 x, s16 y);
2017-12-22 23:22:07 +00:00
2018-02-01 13:47:41 +00:00
static const TaskFunc sTasksForAnimations[] =
2017-12-22 23:22:07 +00:00
{
[RAY_ANIM_DUO_FIGHT_PRE] = Task_DuoFightAnim,
2020-08-25 22:49:42 +01:00
[RAY_ANIM_DUO_FIGHT] = Task_DuoFightAnim,
[RAY_ANIM_TAKES_FLIGHT] = Task_RayTakesFlightAnim,
[RAY_ANIM_DESCENDS] = Task_RayDescendsAnim,
[RAY_ANIM_CHARGES] = Task_RayChargesAnim,
[RAY_ANIM_CHASES_AWAY] = Task_RayChasesAwayAnim,
[RAY_ANIM_END] = Task_EndAfterFadeScreen,
2017-12-22 23:22:07 +00:00
};
2020-08-26 21:31:37 +01:00
static const struct OamData sOam_64x64 =
2017-12-22 23:22:07 +00:00
{
.y = 0,
.affineMode = ST_OAM_AFFINE_OFF,
.objMode = ST_OAM_OBJ_NORMAL,
2017-12-22 23:22:07 +00:00
.mosaic = 0,
.bpp = ST_OAM_4BPP,
.shape = SPRITE_SHAPE(64x64),
2017-12-22 23:22:07 +00:00
.x = 0,
.matrixNum = 0,
.size = SPRITE_SIZE(64x64),
2017-12-22 23:22:07 +00:00
.tileNum = 0,
.priority = 2,
.paletteNum = 0,
.affineParam = 0
};
2020-08-26 21:31:37 +01:00
static const struct OamData sOam_32x32 =
2017-12-22 23:22:07 +00:00
{
.y = 0,
.affineMode = ST_OAM_AFFINE_OFF,
.objMode = ST_OAM_OBJ_NORMAL,
2017-12-22 23:22:07 +00:00
.mosaic = 0,
.bpp = ST_OAM_4BPP,
.shape = SPRITE_SHAPE(32x32),
2017-12-22 23:22:07 +00:00
.x = 0,
.matrixNum = 0,
.size = SPRITE_SIZE(32x32),
2017-12-22 23:22:07 +00:00
.tileNum = 0,
.priority = 2,
.paletteNum = 0,
.affineParam = 0
};
2020-08-26 21:31:37 +01:00
static const struct OamData sOam_64x32 =
2017-12-22 23:22:07 +00:00
{
.y = 0,
.affineMode = ST_OAM_AFFINE_OFF,
.objMode = ST_OAM_OBJ_NORMAL,
2017-12-22 23:22:07 +00:00
.mosaic = 0,
.bpp = ST_OAM_4BPP,
.shape = SPRITE_SHAPE(64x32),
2017-12-22 23:22:07 +00:00
.x = 0,
.matrixNum = 0,
.size = SPRITE_SIZE(64x32),
2017-12-22 23:22:07 +00:00
.tileNum = 0,
.priority = 2,
.paletteNum = 0,
.affineParam = 0
};
2020-08-26 21:31:37 +01:00
static const struct OamData sOam_32x16 =
2017-12-22 23:22:07 +00:00
{
.y = 0,
.affineMode = ST_OAM_AFFINE_OFF,
.objMode = ST_OAM_OBJ_NORMAL,
2017-12-22 23:22:07 +00:00
.mosaic = 0,
.bpp = ST_OAM_4BPP,
.shape = SPRITE_SHAPE(32x16),
2017-12-22 23:22:07 +00:00
.x = 0,
.matrixNum = 0,
.size = SPRITE_SIZE(32x16),
2017-12-22 23:22:07 +00:00
.tileNum = 0,
.priority = 2,
.paletteNum = 0,
.affineParam = 0
};
2020-08-26 21:31:37 +01:00
static const struct OamData sOam_16x8 =
2017-12-22 23:22:07 +00:00
{
.y = 0,
.affineMode = ST_OAM_AFFINE_OFF,
.objMode = ST_OAM_OBJ_NORMAL,
2017-12-22 23:22:07 +00:00
.mosaic = 0,
.bpp = ST_OAM_4BPP,
.shape = SPRITE_SHAPE(16x8),
2017-12-22 23:22:07 +00:00
.x = 0,
.matrixNum = 0,
.size = SPRITE_SIZE(16x8),
2017-12-22 23:22:07 +00:00
.tileNum = 0,
.priority = 2,
.paletteNum = 0,
.affineParam = 0
};
2020-08-26 21:31:37 +01:00
static const struct OamData sOam_16x32 =
2017-12-22 23:22:07 +00:00
{
.y = 0,
.affineMode = ST_OAM_AFFINE_OFF,
.objMode = ST_OAM_OBJ_NORMAL,
2017-12-22 23:22:07 +00:00
.mosaic = 0,
.bpp = ST_OAM_4BPP,
.shape = SPRITE_SHAPE(16x32),
2017-12-22 23:22:07 +00:00
.x = 0,
.matrixNum = 0,
.size = SPRITE_SIZE(16x32),
2017-12-22 23:22:07 +00:00
.tileNum = 0,
.priority = 2,
.paletteNum = 0,
.affineParam = 0
};
2020-08-26 21:31:37 +01:00
static const struct OamData sOam_16x16 =
2017-12-22 23:22:07 +00:00
{
.y = 0,
.affineMode = ST_OAM_AFFINE_OFF,
.objMode = ST_OAM_OBJ_NORMAL,
2017-12-22 23:22:07 +00:00
.mosaic = 0,
.bpp = ST_OAM_4BPP,
.shape = SPRITE_SHAPE(16x16),
2017-12-22 23:22:07 +00:00
.x = 0,
.matrixNum = 0,
.size = SPRITE_SIZE(16x16),
2017-12-22 23:22:07 +00:00
.tileNum = 0,
.priority = 2,
.paletteNum = 0,
.affineParam = 0
};
2020-08-26 21:31:37 +01:00
static const struct OamData sOam_32x8 =
2017-12-22 23:22:07 +00:00
{
.y = 0,
.affineMode = ST_OAM_AFFINE_OFF,
.objMode = ST_OAM_OBJ_NORMAL,
2017-12-22 23:22:07 +00:00
.mosaic = 0,
.bpp = ST_OAM_4BPP,
.shape = SPRITE_SHAPE(32x8),
2017-12-22 23:22:07 +00:00
.x = 0,
.matrixNum = 0,
.size = SPRITE_SIZE(32x8),
2017-12-22 23:22:07 +00:00
.tileNum = 0,
.priority = 2,
.paletteNum = 0,
.affineParam = 0
};
static const union AnimCmd sSpriteAnim_862A6FC[] =
{
ANIMCMD_FRAME(0, 30),
ANIMCMD_FRAME(64, 30),
ANIMCMD_FRAME(128, 30),
ANIMCMD_FRAME(64, 30),
ANIMCMD_JUMP(0),
};
static const union AnimCmd sSpriteAnim_862A710[] =
{
ANIMCMD_FRAME(192, 30),
ANIMCMD_FRAME(256, 30),
ANIMCMD_FRAME(320, 30),
ANIMCMD_FRAME(256, 30),
ANIMCMD_JUMP(0),
};
2020-08-26 21:31:37 +01:00
static const union AnimCmd *const sAnims_DuoFightPre_Groudon[] =
2017-12-22 23:22:07 +00:00
{
sSpriteAnim_862A6FC,
sSpriteAnim_862A710
};
2020-08-26 21:31:37 +01:00
static const struct SpriteTemplate sSpriteTemplate_DuoFightPre_Groudon =
2017-12-22 23:22:07 +00:00
{
2020-08-26 21:31:37 +01:00
.tileTag = TAG_DUOFIGHT_GROUDON,
.paletteTag = TAG_DUOFIGHT_GROUDON,
.oam = &sOam_64x64,
.anims = sAnims_DuoFightPre_Groudon,
2017-12-22 23:22:07 +00:00
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = SpriteCallbackDummy,
};
2020-08-26 21:31:37 +01:00
static const union AnimCmd sAnim_DuoFightPre_GroudonShoulderKyogreFin[] =
2017-12-22 23:22:07 +00:00
{
ANIMCMD_FRAME(0, 1),
ANIMCMD_END
};
2020-08-26 21:31:37 +01:00
static const union AnimCmd *const sAnims_DuoFightPre_GroudonShoulderKyogreFin[] =
2017-12-22 23:22:07 +00:00
{
2020-08-26 21:31:37 +01:00
sAnim_DuoFightPre_GroudonShoulderKyogreFin
2017-12-22 23:22:07 +00:00
};
2020-08-26 21:31:37 +01:00
static const struct SpriteTemplate sSpriteTemplate_DuoFightPre_GroudonShoulder =
2017-12-22 23:22:07 +00:00
{
2020-08-26 21:31:37 +01:00
.tileTag = TAG_DUOFIGHT_GROUDON_SHOULDER,
.paletteTag = TAG_DUOFIGHT_GROUDON,
.oam = &sOam_32x32,
.anims = sAnims_DuoFightPre_GroudonShoulderKyogreFin,
2017-12-22 23:22:07 +00:00
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = SpriteCallbackDummy,
};
2020-08-26 21:31:37 +01:00
static const union AnimCmd sAnim_DuoFightPre_GroudonClaw[] =
2017-12-22 23:22:07 +00:00
{
ANIMCMD_FRAME(0, 1),
ANIMCMD_END
};
2020-08-26 21:31:37 +01:00
static const union AnimCmd *const sAnims_DuoFightPre_GroudonClaw[] =
2017-12-22 23:22:07 +00:00
{
2020-08-26 21:31:37 +01:00
sAnim_DuoFightPre_GroudonClaw
2017-12-22 23:22:07 +00:00
};
2020-08-26 21:31:37 +01:00
static const struct SpriteTemplate sSpriteTemplate_DuoFightPre_GroudonClaw =
2017-12-22 23:22:07 +00:00
{
2020-08-26 21:31:37 +01:00
.tileTag = TAG_DUOFIGHT_GROUDON_CLAW,
.paletteTag = TAG_DUOFIGHT_GROUDON,
.oam = &sOam_64x32,
.anims = sAnims_DuoFightPre_GroudonClaw,
2017-12-22 23:22:07 +00:00
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = SpriteCallbackDummy,
};
static const union AnimCmd sSpriteAnim_862A78C[] =
{
ANIMCMD_FRAME(0, 1),
ANIMCMD_END
};
static const union AnimCmd sSpriteAnim_862A794[] =
{
ANIMCMD_FRAME(8, 1),
ANIMCMD_END
};
static const union AnimCmd sSpriteAnim_862A79C[] =
{
ANIMCMD_FRAME(16, 1),
ANIMCMD_END
};
static const union AnimCmd sSpriteAnim_862A7A4[] =
{
ANIMCMD_FRAME(24, 1),
ANIMCMD_END
};
static const union AnimCmd sSpriteAnim_862A7AC[] =
{
ANIMCMD_FRAME(32, 1),
ANIMCMD_END
};
static const union AnimCmd sSpriteAnim_862A7B4[] =
{
ANIMCMD_FRAME(40, 1),
ANIMCMD_END
};
static const union AnimCmd sSpriteAnim_862A7BC[] =
{
ANIMCMD_FRAME(48, 36),
ANIMCMD_FRAME(64, 36),
ANIMCMD_FRAME(80, 36),
ANIMCMD_FRAME(64, 36),
ANIMCMD_JUMP(0),
};
static const union AnimCmd sSpriteAnim_862A7D0[] =
{
ANIMCMD_FRAME(56, 36),
ANIMCMD_FRAME(72, 36),
ANIMCMD_FRAME(88, 36),
ANIMCMD_FRAME(72, 36),
ANIMCMD_JUMP(0),
};
static const union AnimCmd sSpriteAnim_862A7E4[] =
{
ANIMCMD_FRAME(96, 36),
ANIMCMD_FRAME(104, 36),
ANIMCMD_FRAME(112, 36),
ANIMCMD_FRAME(104, 36),
ANIMCMD_JUMP(0),
};
2020-08-26 21:31:37 +01:00
static const union AnimCmd *const sAnims_DuoFightPre_Kyogre[] =
2017-12-22 23:22:07 +00:00
{
sSpriteAnim_862A78C,
sSpriteAnim_862A794,
sSpriteAnim_862A79C,
sSpriteAnim_862A7A4,
sSpriteAnim_862A7AC,
sSpriteAnim_862A7B4,
sSpriteAnim_862A7BC,
sSpriteAnim_862A7D0,
sSpriteAnim_862A7E4
};
2020-08-26 21:31:37 +01:00
static const struct SpriteTemplate sSpriteTemplate_DuoFightPre_Kyogre =
2017-12-22 23:22:07 +00:00
{
2020-08-26 21:31:37 +01:00
.tileTag = TAG_DUOFIGHT_KYOGRE,
.paletteTag = TAG_DUOFIGHT_KYOGRE,
.oam = &sOam_32x16,
.anims = sAnims_DuoFightPre_Kyogre,
2017-12-22 23:22:07 +00:00
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = SpriteCallbackDummy,
};
2020-08-26 21:31:37 +01:00
static const union AnimCmd sAnim_DuoFightPre_KyogreShoulder[] =
2017-12-22 23:22:07 +00:00
{
ANIMCMD_FRAME(0, 36),
ANIMCMD_FRAME(2, 36),
ANIMCMD_FRAME(4, 36),
ANIMCMD_FRAME(2, 36),
ANIMCMD_JUMP(0),
};
2020-08-26 21:31:37 +01:00
static const union AnimCmd *const sAnims_DuoFightPre_KyogreShoulder[] =
2017-12-22 23:22:07 +00:00
{
2020-08-26 21:31:37 +01:00
sAnim_DuoFightPre_KyogreShoulder
2017-12-22 23:22:07 +00:00
};
2020-08-26 21:31:37 +01:00
static const struct SpriteTemplate sSpriteTemplate_DuoFightPre_KyogreShoulder =
2017-12-22 23:22:07 +00:00
{
2020-08-26 21:31:37 +01:00
.tileTag = TAG_DUOFIGHT_KYOGRE_SHOULDER,
.paletteTag = TAG_DUOFIGHT_KYOGRE,
.oam = &sOam_16x8,
.anims = sAnims_DuoFightPre_KyogreShoulder,
2017-12-22 23:22:07 +00:00
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = SpriteCallbackDummy,
};
2020-08-26 21:31:37 +01:00
static const struct SpriteTemplate sSpriteTemplate_DuoFightPre_KyogreFin =
2017-12-22 23:22:07 +00:00
{
2020-08-26 21:31:37 +01:00
.tileTag = TAG_DUOFIGHT_KYOGRE_FIN,
.paletteTag = TAG_DUOFIGHT_KYOGRE,
.oam = &sOam_32x32,
.anims = sAnims_DuoFightPre_GroudonShoulderKyogreFin,
2017-12-22 23:22:07 +00:00
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = SpriteCallbackDummy,
};
2020-08-26 21:31:37 +01:00
static const struct ScanlineEffectParams sScanlineParams_DuoFight_Clouds =
2018-01-31 12:05:36 +00:00
{
.dmaDest = (vu16 *)REG_ADDR_BG1HOFS,
2020-08-26 21:31:37 +01:00
.dmaControl = SCANLINE_EFFECT_DMACNT_16BIT,
2018-01-31 12:05:36 +00:00
.initState = 1
};
2017-12-22 23:22:07 +00:00
2020-08-26 21:31:37 +01:00
static const struct BgTemplate sBgTemplates_DuoFight[] =
2017-12-22 23:22:07 +00:00
{
{
.bg = 0,
.charBaseIndex = 0,
.mapBaseIndex = 31,
.screenSize = 0,
.paletteMode = 0,
.priority = 0,
.baseTile = 0
},
{
.bg = 1,
.charBaseIndex = 0,
.mapBaseIndex = 30,
.screenSize = 0,
.paletteMode = 0,
.priority = 2,
.baseTile = 0
},
{
.bg = 2,
.charBaseIndex = 0,
.mapBaseIndex = 29,
.screenSize = 0,
.paletteMode = 0,
.priority = 1,
.baseTile = 0
},
};
static const union AnimCmd sSpriteAnim_862A894[] =
{
ANIMCMD_FRAME(0, 20),
ANIMCMD_FRAME(64, 20),
ANIMCMD_FRAME(128, 20),
ANIMCMD_FRAME(64, 20),
ANIMCMD_JUMP(0),
};
static const union AnimCmd sSpriteAnim_862A8A8[] =
{
ANIMCMD_FRAME(192, 20),
ANIMCMD_FRAME(256, 20),
ANIMCMD_FRAME(320, 20),
ANIMCMD_FRAME(256, 20),
ANIMCMD_JUMP(0),
};
2020-08-26 21:31:37 +01:00
static const union AnimCmd *const sAnims_DuoFight_Groudon[] =
2017-12-22 23:22:07 +00:00
{
sSpriteAnim_862A894,
sSpriteAnim_862A8A8
};
2020-08-26 21:31:37 +01:00
static const struct CompressedSpriteSheet sSpriteSheet_DuoFight_Groudon =
2017-12-22 23:22:07 +00:00
{
2020-08-26 21:31:37 +01:00
gRaySceneDuoFight_Groudon_Gfx, 0x3000, TAG_DUOFIGHT_GROUDON
2017-12-22 23:22:07 +00:00
};
2020-08-26 21:31:37 +01:00
static const struct CompressedSpritePalette sSpritePal_DuoFight_Groudon =
2017-12-22 23:22:07 +00:00
{
2020-08-26 21:31:37 +01:00
gRaySceneDuoFight_Groudon_Pal, TAG_DUOFIGHT_GROUDON
2017-12-22 23:22:07 +00:00
};
2020-08-26 21:31:37 +01:00
static const struct SpriteTemplate sSpriteTemplate_DuoFight_Groudon =
2017-12-22 23:22:07 +00:00
{
2020-08-26 21:31:37 +01:00
.tileTag = TAG_DUOFIGHT_GROUDON,
.paletteTag = TAG_DUOFIGHT_GROUDON,
.oam = &sOam_64x64,
.anims = sAnims_DuoFight_Groudon,
2017-12-22 23:22:07 +00:00
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = SpriteCallbackDummy,
};
2020-08-26 21:31:37 +01:00
static const union AnimCmd sAnim_DuoFight_GroudonShoulderKyogreFin[] =
2017-12-22 23:22:07 +00:00
{
ANIMCMD_FRAME(0, 1),
ANIMCMD_END
};
2020-08-26 21:31:37 +01:00
static const union AnimCmd *const sAnims_DuoFight_GroudonShoulderKyogreFin[] =
2017-12-22 23:22:07 +00:00
{
2020-08-26 21:31:37 +01:00
sAnim_DuoFight_GroudonShoulderKyogreFin
2017-12-22 23:22:07 +00:00
};
2020-08-26 21:31:37 +01:00
static const struct CompressedSpriteSheet sSpriteSheet_DuoFight_GroudonShoulder =
2017-12-22 23:22:07 +00:00
{
2020-08-26 21:31:37 +01:00
gRaySceneDuoFight_GroudonShoulder_Gfx, 0x200, TAG_DUOFIGHT_GROUDON_SHOULDER
2017-12-22 23:22:07 +00:00
};
2020-08-26 21:31:37 +01:00
static const struct SpriteTemplate sSpriteTemplate_DuoFight_GroudonShoulder =
2017-12-22 23:22:07 +00:00
{
2020-08-26 21:31:37 +01:00
.tileTag = TAG_DUOFIGHT_GROUDON_SHOULDER,
.paletteTag = TAG_DUOFIGHT_GROUDON,
.oam = &sOam_32x32,
.anims = sAnims_DuoFight_GroudonShoulderKyogreFin,
2017-12-22 23:22:07 +00:00
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = SpriteCallbackDummy,
};
2020-08-26 21:31:37 +01:00
static const union AnimCmd sAnim_DuoFight_GroudonClaw[] =
2017-12-22 23:22:07 +00:00
{
ANIMCMD_FRAME(0, 1),
ANIMCMD_END
};
2020-08-26 21:31:37 +01:00
static const union AnimCmd *const sAnims_DuoFight_GroudonClaw[] =
2017-12-22 23:22:07 +00:00
{
2020-08-26 21:31:37 +01:00
sAnim_DuoFight_GroudonClaw
2017-12-22 23:22:07 +00:00
};
2020-08-26 21:31:37 +01:00
static const struct CompressedSpriteSheet sSpriteSheet_DuoFight_GroudonClaw =
2017-12-22 23:22:07 +00:00
{
2020-08-26 21:31:37 +01:00
gRaySceneDuoFight_GroudonClaw_Gfx, 0x400, TAG_DUOFIGHT_GROUDON_CLAW
2017-12-22 23:22:07 +00:00
};
2020-08-26 21:31:37 +01:00
static const struct SpriteTemplate sSpriteTemplate_DuoFight_GroudonClaw =
2017-12-22 23:22:07 +00:00
{
2020-08-26 21:31:37 +01:00
.tileTag = TAG_DUOFIGHT_GROUDON_CLAW,
.paletteTag = TAG_DUOFIGHT_GROUDON,
.oam = &sOam_64x32,
.anims = sAnims_DuoFight_GroudonClaw,
2017-12-22 23:22:07 +00:00
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = SpriteCallbackDummy,
};
static const union AnimCmd sSpriteAnim_862A944[] =
{
ANIMCMD_FRAME(0, 1),
ANIMCMD_END
};
static const union AnimCmd sSpriteAnim_862A94C[] =
{
ANIMCMD_FRAME(8, 1),
ANIMCMD_END
};
static const union AnimCmd sSpriteAnim_862A954[] =
{
ANIMCMD_FRAME(16, 1),
ANIMCMD_END
};
static const union AnimCmd sSpriteAnim_862A95C[] =
{
ANIMCMD_FRAME(24, 1),
ANIMCMD_END
};
static const union AnimCmd sSpriteAnim_862A964[] =
{
ANIMCMD_FRAME(32, 1),
ANIMCMD_END
};
static const union AnimCmd sSpriteAnim_862A96C[] =
{
ANIMCMD_FRAME(40, 1),
ANIMCMD_END
};
static const union AnimCmd sSpriteAnim_862A974[] =
{
ANIMCMD_FRAME(48, 24),
ANIMCMD_FRAME(64, 24),
ANIMCMD_FRAME(80, 24),
ANIMCMD_FRAME(64, 24),
ANIMCMD_JUMP(0),
};
static const union AnimCmd sSpriteAnim_862A988[] =
{
ANIMCMD_FRAME(56, 24),
ANIMCMD_FRAME(72, 24),
ANIMCMD_FRAME(88, 24),
ANIMCMD_FRAME(72, 24),
ANIMCMD_JUMP(0),
};
static const union AnimCmd sSpriteAnim_862A99C[] =
{
ANIMCMD_FRAME(96, 24),
ANIMCMD_FRAME(104, 24),
ANIMCMD_FRAME(112, 24),
ANIMCMD_FRAME(104, 24),
ANIMCMD_JUMP(0),
};
2020-08-26 21:31:37 +01:00
static const union AnimCmd *const sAnims_DuoFight_Kyogre[] =
2017-12-22 23:22:07 +00:00
{
sSpriteAnim_862A944,
sSpriteAnim_862A94C,
sSpriteAnim_862A954,
sSpriteAnim_862A95C,
sSpriteAnim_862A964,
sSpriteAnim_862A96C,
sSpriteAnim_862A974,
sSpriteAnim_862A988,
sSpriteAnim_862A99C
};
2020-08-26 21:31:37 +01:00
static const struct CompressedSpriteSheet sSpriteSheet_DuoFight_Kyogre =
2017-12-22 23:22:07 +00:00
{
2020-08-26 21:31:37 +01:00
gRaySceneDuoFight_Kyogre_Gfx, 0xF00, TAG_DUOFIGHT_KYOGRE
2017-12-22 23:22:07 +00:00
};
2020-08-26 21:31:37 +01:00
static const struct CompressedSpritePalette sSpritePal_DuoFight_Kyogre =
2017-12-22 23:22:07 +00:00
{
2020-08-26 21:31:37 +01:00
gRaySceneDuoFight_Kyogre_Pal, TAG_DUOFIGHT_KYOGRE
2017-12-22 23:22:07 +00:00
};
2020-08-26 21:31:37 +01:00
static const struct SpriteTemplate sSpriteTemplate_DuoFight_Kyogre =
2017-12-22 23:22:07 +00:00
{
2020-08-26 21:31:37 +01:00
.tileTag = TAG_DUOFIGHT_KYOGRE,
.paletteTag = TAG_DUOFIGHT_KYOGRE,
.oam = &sOam_32x16,
.anims = sAnims_DuoFight_Kyogre,
2017-12-22 23:22:07 +00:00
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = SpriteCallbackDummy,
};
2020-08-26 21:31:37 +01:00
static const union AnimCmd sAnim_DuoFight_KyogreShoulder[] =
2017-12-22 23:22:07 +00:00
{
ANIMCMD_FRAME(0, 24),
ANIMCMD_FRAME(2, 24),
ANIMCMD_FRAME(4, 24),
ANIMCMD_FRAME(2, 24),
ANIMCMD_JUMP(0),
};
2020-08-26 21:31:37 +01:00
static const union AnimCmd *const sAnims_DuoFight_KyogreShoulder[] =
2017-12-22 23:22:07 +00:00
{
2020-08-26 21:31:37 +01:00
sAnim_DuoFight_KyogreShoulder
2017-12-22 23:22:07 +00:00
};
2020-08-26 21:31:37 +01:00
static const struct CompressedSpriteSheet sSpriteSheet_DuoFight_KyogreShoulder =
2017-12-22 23:22:07 +00:00
{
2020-08-26 21:31:37 +01:00
gRaySceneDuoFight_KyogreShoulder_Gfx, 0xC0, TAG_DUOFIGHT_KYOGRE_SHOULDER
2017-12-22 23:22:07 +00:00
};
2020-08-26 21:31:37 +01:00
static const struct SpriteTemplate sSpriteTemplate_DuoFight_KyogreShoulder =
2017-12-22 23:22:07 +00:00
{
2020-08-26 21:31:37 +01:00
.tileTag = TAG_DUOFIGHT_KYOGRE_SHOULDER,
.paletteTag = TAG_DUOFIGHT_KYOGRE,
.oam = &sOam_16x8,
.anims = sAnims_DuoFight_KyogreShoulder,
2017-12-22 23:22:07 +00:00
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = SpriteCallbackDummy,
};
2020-08-26 21:31:37 +01:00
static const struct CompressedSpriteSheet sSpriteSheet_DuoFight_KyogreFin =
2017-12-22 23:22:07 +00:00
{
2020-08-26 21:31:37 +01:00
gRaySceneDuoFight_KyogreFin_Gfx, 0x200, TAG_DUOFIGHT_KYOGRE_FIN
2017-12-22 23:22:07 +00:00
};
2020-08-26 21:31:37 +01:00
static const struct SpriteTemplate sSpriteTemplate_DuoFight_KyogreFin =
2017-12-22 23:22:07 +00:00
{
2020-08-26 21:31:37 +01:00
.tileTag = TAG_DUOFIGHT_KYOGRE_FIN,
.paletteTag = TAG_DUOFIGHT_KYOGRE,
.oam = &sOam_32x32,
.anims = sAnims_DuoFight_GroudonShoulderKyogreFin,
2017-12-22 23:22:07 +00:00
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = SpriteCallbackDummy,
};
2020-08-26 21:31:37 +01:00
static const struct BgTemplate sBgTemplates_TakesFlight[] =
2017-12-22 23:22:07 +00:00
{
{
.bg = 0,
.charBaseIndex = 2,
.mapBaseIndex = 31,
.screenSize = 0,
.paletteMode = 0,
.priority = 0,
.baseTile = 0
},
{
.bg = 1,
.charBaseIndex = 0,
.mapBaseIndex = 30,
.screenSize = 0,
.paletteMode = 0,
.priority = 2,
.baseTile = 0
},
{
.bg = 2,
.charBaseIndex = 1,
.mapBaseIndex = 29,
.screenSize = 1,
.paletteMode = 0,
.priority = 1,
.baseTile = 0
}
};
2020-08-26 21:31:37 +01:00
static const union AnimCmd sAnim_TakesFlight_Smoke[] =
2017-12-22 23:22:07 +00:00
{
ANIMCMD_FRAME(0, 1),
ANIMCMD_END
};
2020-08-26 21:31:37 +01:00
static const union AnimCmd *const sAnims_TakesFlight_Smoke[] =
2017-12-22 23:22:07 +00:00
{
2020-08-26 21:31:37 +01:00
sAnim_TakesFlight_Smoke
2017-12-22 23:22:07 +00:00
};
2020-08-26 21:31:37 +01:00
static const union AffineAnimCmd sAffineAnim_TakesFlight_Smoke[] =
2017-12-22 23:22:07 +00:00
{
AFFINEANIMCMD_FRAME(-64, -64, 0, 1),
AFFINEANIMCMD_FRAME(32, 32, 0, 14),
AFFINEANIMCMD_FRAME(256, 256, 0, 0),
AFFINEANIMCMD_JUMP(0)
};
2020-08-26 21:31:37 +01:00
static const union AffineAnimCmd *const sAffineAnims_TakesFlight_Smoke[] =
2017-12-22 23:22:07 +00:00
{
2020-08-26 21:31:37 +01:00
sAffineAnim_TakesFlight_Smoke
2017-12-22 23:22:07 +00:00
};
2020-08-26 21:31:37 +01:00
static const struct CompressedSpriteSheet sSpriteSheet_TakesFlight_Smoke =
2017-12-22 23:22:07 +00:00
{
2020-08-26 21:31:37 +01:00
gRaySceneTakesFlight_Smoke_Gfx, 0x100, TAG_FLIGHT_SMOKE
2017-12-22 23:22:07 +00:00
};
2020-08-26 21:31:37 +01:00
static const struct CompressedSpritePalette sSpritePal_TakesFlight_Smoke =
2017-12-22 23:22:07 +00:00
{
2020-08-26 21:31:37 +01:00
gRaySceneTakesFlight_Smoke_Pal, TAG_FLIGHT_SMOKE
2017-12-22 23:22:07 +00:00
};
2020-08-26 21:31:37 +01:00
static const struct SpriteTemplate sSpriteTemplate_TakesFlight_Smoke =
2017-12-22 23:22:07 +00:00
{
2020-08-26 21:31:37 +01:00
.tileTag = TAG_FLIGHT_SMOKE,
.paletteTag = TAG_FLIGHT_SMOKE,
.oam = &sOam_32x16,
.anims = sAnims_TakesFlight_Smoke,
2017-12-22 23:22:07 +00:00
.images = NULL,
2020-08-26 21:31:37 +01:00
.affineAnims = sAffineAnims_TakesFlight_Smoke,
.callback = SpriteCB_TakesFlight_Smoke,
2017-12-22 23:22:07 +00:00
};
2020-08-26 22:42:51 +01:00
static const s8 sTakesFlight_SmokeCoords[MAX_SMOKE][2] =
2017-12-22 23:22:07 +00:00
{
2020-08-26 21:31:37 +01:00
{-1, 5},
{-3, -4},
{ 5, -3},
{-7, 2},
{-9, -1},
{ 1, -5},
{ 3, 4},
{-5, 3},
{ 7, -2},
{ 9, 1}
2017-12-22 23:22:07 +00:00
};
2020-08-26 21:31:37 +01:00
static const struct BgTemplate sBgTemplates_Descends[] =
2017-12-22 23:22:07 +00:00
{
{
.bg = 0,
.charBaseIndex = 0,
.mapBaseIndex = 31,
.screenSize = 0,
.paletteMode = 0,
.priority = 0,
.baseTile = 0
},
{
.bg = 1,
.charBaseIndex = 1,
.mapBaseIndex = 30,
.screenSize = 0,
.paletteMode = 0,
.priority = 1,
.baseTile = 0
},
{
.bg = 2,
.charBaseIndex = 2,
.mapBaseIndex = 29,
.screenSize = 0,
.paletteMode = 0,
.priority = 2,
.baseTile = 0
},
{
.bg = 3,
.charBaseIndex = 1,
.mapBaseIndex = 28,
.screenSize = 0,
.paletteMode = 0,
.priority = 3,
.baseTile = 0
}
};
2020-08-26 21:31:37 +01:00
static const union AnimCmd sAnim_Descends_Rayquaza[] =
2017-12-22 23:22:07 +00:00
{
ANIMCMD_FRAME(0, 32),
ANIMCMD_FRAME(64, 32),
ANIMCMD_JUMP(0),
};
2020-08-26 21:31:37 +01:00
static const union AnimCmd *const sAnims_Descends_Rayquaza[] =
2017-12-22 23:22:07 +00:00
{
2020-08-26 21:31:37 +01:00
sAnim_Descends_Rayquaza
2017-12-22 23:22:07 +00:00
};
2020-08-26 21:31:37 +01:00
static const union AnimCmd sAnim_Descends_RayquazaTail[] =
2017-12-22 23:22:07 +00:00
{
ANIMCMD_FRAME(0, 32),
ANIMCMD_FRAME(8, 32),
ANIMCMD_JUMP(0),
};
2020-08-26 21:31:37 +01:00
static const union AnimCmd *const sAnims_Descends_RayquazaTail[] =
2017-12-22 23:22:07 +00:00
{
2020-08-26 21:31:37 +01:00
sAnim_Descends_RayquazaTail
2017-12-22 23:22:07 +00:00
};
2020-08-26 21:31:37 +01:00
static const struct CompressedSpriteSheet sSpriteSheet_Descends_Rayquaza =
2017-12-23 12:23:23 +00:00
{
2020-08-26 21:31:37 +01:00
gRaySceneDescends_Rayquaza_Gfx, 0x1000, TAG_DESCENDS_RAYQUAZA
2017-12-23 12:23:23 +00:00
};
2020-08-26 21:31:37 +01:00
static const struct CompressedSpriteSheet sSpriteSheet_Descends_RayquazaTail =
2017-12-23 12:23:23 +00:00
{
2020-08-26 21:31:37 +01:00
gRaySceneDescends_RayquazaTail_Gfx, 0x200, TAG_DESCENDS_RAYQUAZA_TAIL
2017-12-23 12:23:23 +00:00
};
2020-08-26 21:31:37 +01:00
static const struct CompressedSpritePalette sSpritePal_Descends_Rayquaza =
2017-12-23 12:23:23 +00:00
{
2020-08-26 21:31:37 +01:00
gRaySceneTakesFlight_Rayquaza_Pal, TAG_DESCENDS_RAYQUAZA // "Takes flight" palette re-used here
2017-12-23 12:23:23 +00:00
};
2020-08-26 21:31:37 +01:00
static const struct SpriteTemplate sSpriteTemplate_Descends_Rayquaza =
2017-12-23 12:23:23 +00:00
{
2020-08-26 21:31:37 +01:00
.tileTag = TAG_DESCENDS_RAYQUAZA,
.paletteTag = TAG_DESCENDS_RAYQUAZA,
.oam = &sOam_64x64,
.anims = sAnims_Descends_Rayquaza,
2017-12-23 12:23:23 +00:00
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = SpriteCallbackDummy,
};
2020-08-26 21:31:37 +01:00
static const struct SpriteTemplate sSpriteTemplate_Descends_RayquazaTail =
2017-12-23 12:23:23 +00:00
{
2020-08-26 21:31:37 +01:00
.tileTag = TAG_DESCENDS_RAYQUAZA_TAIL,
.paletteTag = TAG_DESCENDS_RAYQUAZA,
.oam = &sOam_16x32,
.anims = sAnims_Descends_RayquazaTail,
2017-12-23 12:23:23 +00:00
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = SpriteCallbackDummy,
};
2020-08-26 21:31:37 +01:00
static const struct BgTemplate sBgTemplates_Charges[] =
2017-12-23 12:23:23 +00:00
{
{
.bg = 0,
.charBaseIndex = 2,
.mapBaseIndex = 31,
.screenSize = 0,
.paletteMode = 0,
.priority = 0,
.baseTile = 0
},
{
.bg = 1,
.charBaseIndex = 1,
.mapBaseIndex = 30,
.screenSize = 0,
.paletteMode = 0,
.priority = 1,
.baseTile = 0
},
{
.bg = 2,
.charBaseIndex = 2,
.mapBaseIndex = 29,
.screenSize = 0,
.paletteMode = 0,
.priority = 2,
.baseTile = 0
},
{
.bg = 3,
.charBaseIndex = 3,
.mapBaseIndex = 28,
.screenSize = 0,
.paletteMode = 0,
.priority = 3,
.baseTile = 0
}
};
static const union AnimCmd sSpriteAnim_862AB54[] =
{
ANIMCMD_FRAME(0, 1),
ANIMCMD_END
};
static const union AnimCmd sSpriteAnim_862AB5C[] =
{
ANIMCMD_FRAME(0, 48),
ANIMCMD_FRAME(64, 32),
ANIMCMD_FRAME(0, 48),
ANIMCMD_FRAME(128, 32),
ANIMCMD_JUMP(0)
};
2020-08-26 21:31:37 +01:00
static const union AnimCmd *const sAnims_ChasesAway_Groudon[] =
2017-12-23 12:23:23 +00:00
{
sSpriteAnim_862AB54,
sSpriteAnim_862AB5C
};
2020-08-26 21:31:37 +01:00
static const union AnimCmd sAnim_ChasesAway_GroudonTail[] =
2017-12-23 12:23:23 +00:00
{
ANIMCMD_FRAME(0, 1),
ANIMCMD_END
};
2020-08-26 21:31:37 +01:00
static const union AnimCmd *const sAnims_ChasesAway_GroudonTail[] =
2017-12-23 12:23:23 +00:00
{
2020-08-26 21:31:37 +01:00
sAnim_ChasesAway_GroudonTail,
2017-12-23 12:23:23 +00:00
};
static const union AnimCmd sSpriteAnim_862AB84[] =
{
ANIMCMD_FRAME(0, 1),
ANIMCMD_END
};
static const union AnimCmd sSpriteAnim_862AB8C[] =
{
ANIMCMD_FRAME(16, 1),
ANIMCMD_END
};
static const union AnimCmd sSpriteAnim_862AB94[] =
{
ANIMCMD_FRAME(32, 1),
ANIMCMD_END
};
2020-08-26 21:31:37 +01:00
static const union AnimCmd *const sAnims_ChasesAway_Kyogre[] =
2017-12-23 12:23:23 +00:00
{
sSpriteAnim_862AB84,
sSpriteAnim_862AB8C,
sSpriteAnim_862AB94
};
static const union AnimCmd sSpriteAnim_862ABA8[] =
{
ANIMCMD_FRAME(0, 1),
ANIMCMD_END
};
static const union AnimCmd sSpriteAnim_862ABB0[] =
{
ANIMCMD_FRAME(64, 1),
ANIMCMD_END
};
static const union AnimCmd sSpriteAnim_862ABB8[] =
{
ANIMCMD_FRAME(128, 1),
ANIMCMD_END
};
static const union AnimCmd sSpriteAnim_862ABC0[] =
{
ANIMCMD_FRAME(192, 1),
ANIMCMD_END
};
2020-08-26 21:31:37 +01:00
static const union AnimCmd *const sAnims_ChasesAway_Rayquaza[] =
2017-12-23 12:23:23 +00:00
{
sSpriteAnim_862ABA8,
sSpriteAnim_862ABB0,
sSpriteAnim_862ABB8,
sSpriteAnim_862ABC0
};
static const union AnimCmd sSpriteAnim_862ABD8[] =
{
ANIMCMD_FRAME(0, 1),
ANIMCMD_END
};
static const union AnimCmd sSpriteAnim_862ABE0[] =
{
ANIMCMD_FRAME(16, 1),
ANIMCMD_END
};
static const union AnimCmd sSpriteAnim_862ABE8[] =
{
ANIMCMD_FRAME(32, 1),
ANIMCMD_END
};
static const union AnimCmd sSpriteAnim_862ABF0[] =
{
ANIMCMD_FRAME(48, 1),
ANIMCMD_END
};
2020-08-26 21:31:37 +01:00
static const union AnimCmd *const sAnims_ChasesAway_RayquazaTail[] =
2017-12-23 12:23:23 +00:00
{
sSpriteAnim_862ABD8,
sSpriteAnim_862ABE0,
sSpriteAnim_862ABE8,
sSpriteAnim_862ABF0
};
2020-08-26 21:31:37 +01:00
static const union AnimCmd sAnim_ChasesAway_KyogreSplash[] =
2017-12-23 12:23:23 +00:00
{
ANIMCMD_FRAME(0, 8),
ANIMCMD_FRAME(4, 8),
ANIMCMD_FRAME(8, 8),
ANIMCMD_FRAME(12, 8),
ANIMCMD_FRAME(16, 8),
ANIMCMD_FRAME(20, 8),
ANIMCMD_JUMP(0)
};
2020-08-26 21:31:37 +01:00
static const union AnimCmd *const sAnims_ChasesAway_KyogreSplash[] =
2017-12-23 12:23:23 +00:00
{
2020-08-26 21:31:37 +01:00
sAnim_ChasesAway_KyogreSplash
2017-12-23 12:23:23 +00:00
};
2020-08-26 21:31:37 +01:00
static const struct CompressedSpriteSheet sSpriteSheet_ChasesAway_Groudon =
2017-12-23 12:23:23 +00:00
{
2020-08-26 21:31:37 +01:00
gRaySceneChasesAway_Groudon_Gfx, 0x1800, TAG_CHASE_GROUDON
2017-12-23 12:23:23 +00:00
};
2020-08-26 21:31:37 +01:00
static const struct CompressedSpriteSheet sSpriteSheet_ChasesAway_GroudonTail =
2017-12-23 12:23:23 +00:00
{
2020-08-26 21:31:37 +01:00
gRaySceneChasesAway_GroudonTail_Gfx, 0x80, TAG_CHASE_GROUDON_TAIL
2017-12-23 12:23:23 +00:00
};
2020-08-26 21:31:37 +01:00
static const struct CompressedSpriteSheet sSpriteSheet_ChasesAway_Kyogre =
2017-12-23 12:23:23 +00:00
{
2020-08-26 21:31:37 +01:00
gRaySceneChasesAway_Kyogre_Gfx, 0x600, TAG_CHASE_KYOGRE
2017-12-23 12:23:23 +00:00
};
2020-08-26 21:31:37 +01:00
static const struct CompressedSpriteSheet sSpriteSheet_ChasesAway_Rayquaza =
2017-12-23 12:23:23 +00:00
{
2020-08-26 21:31:37 +01:00
gRaySceneChasesAway_Rayquaza_Gfx, 0x2000, TAG_CHASE_RAYQUAZA
2017-12-23 12:23:23 +00:00
};
2020-08-26 21:31:37 +01:00
static const struct CompressedSpriteSheet sSpriteSheet_ChasesAway_RayquazaTail =
2017-12-23 12:23:23 +00:00
{
2020-08-26 21:31:37 +01:00
gRaySceneChasesAway_RayquazaTail_Gfx, 0x800, TAG_CHASE_RAYQUAZA_TAIL
2017-12-23 12:23:23 +00:00
};
2020-08-26 21:31:37 +01:00
static const struct CompressedSpriteSheet sSpriteSheet_ChasesAway_KyogreSplash =
2017-12-23 12:23:23 +00:00
{
2020-08-26 21:31:37 +01:00
gRaySceneChasesAway_KyogreSplash_Gfx, 0x300, TAG_CHASE_SPLASH
2017-12-23 12:23:23 +00:00
};
2020-08-26 21:31:37 +01:00
static const struct CompressedSpritePalette sSpritePal_ChasesAway_Groudon =
2017-12-23 12:23:23 +00:00
{
2020-08-26 21:31:37 +01:00
gRaySceneChasesAway_Groudon_Pal, TAG_CHASE_GROUDON
2017-12-23 12:23:23 +00:00
};
2020-08-26 21:31:37 +01:00
static const struct CompressedSpritePalette sSpritePal_ChasesAway_Kyogre =
2017-12-23 12:23:23 +00:00
{
2020-08-26 21:31:37 +01:00
gRaySceneChasesAway_Kyogre_Pal, TAG_CHASE_KYOGRE
2017-12-23 12:23:23 +00:00
};
2020-08-26 21:31:37 +01:00
static const struct CompressedSpritePalette sSpritePal_ChasesAway_Rayquaza =
2017-12-23 12:23:23 +00:00
{
2020-08-26 21:31:37 +01:00
gRaySceneChasesAway_Rayquaza_Pal, TAG_CHASE_RAYQUAZA
2017-12-23 12:23:23 +00:00
};
2020-08-26 21:31:37 +01:00
static const struct CompressedSpritePalette sSpritePal_ChasesAway_KyogreSplash =
2017-12-23 12:23:23 +00:00
{
2020-08-26 21:31:37 +01:00
gRaySceneChasesAway_KyogreSplash_Pal, TAG_CHASE_SPLASH
2017-12-23 12:23:23 +00:00
};
2020-08-26 21:31:37 +01:00
static const struct SpriteTemplate sSpriteTemplate_ChasesAway_Groudon =
2017-12-23 12:23:23 +00:00
{
2020-08-26 21:31:37 +01:00
.tileTag = TAG_CHASE_GROUDON,
.paletteTag = TAG_CHASE_GROUDON,
.oam = &sOam_64x64,
.anims = sAnims_ChasesAway_Groudon,
2017-12-23 12:23:23 +00:00
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = SpriteCallbackDummy,
};
2020-08-26 21:31:37 +01:00
static const struct SpriteTemplate sSpriteTemplate_ChasesAway_GroudonTail =
2017-12-23 12:23:23 +00:00
{
2020-08-26 21:31:37 +01:00
.tileTag = TAG_CHASE_GROUDON_TAIL,
.paletteTag = TAG_CHASE_GROUDON,
.oam = &sOam_16x16,
.anims = sAnims_ChasesAway_GroudonTail,
2017-12-23 12:23:23 +00:00
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = SpriteCallbackDummy,
};
2020-08-26 21:31:37 +01:00
static const struct SpriteTemplate sSpriteTemplate_ChasesAway_Kyogre =
2017-12-23 12:23:23 +00:00
{
2020-08-26 21:31:37 +01:00
.tileTag = TAG_CHASE_KYOGRE,
.paletteTag = TAG_CHASE_KYOGRE,
.oam = &sOam_32x32,
.anims = sAnims_ChasesAway_Kyogre,
2017-12-23 12:23:23 +00:00
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = SpriteCallbackDummy,
};
2020-08-26 21:31:37 +01:00
static const struct SpriteTemplate sSpriteTemplate_ChasesAway_Rayquaza =
2017-12-23 12:23:23 +00:00
{
2020-08-26 21:31:37 +01:00
.tileTag = TAG_CHASE_RAYQUAZA,
.paletteTag = TAG_CHASE_RAYQUAZA,
.oam = &sOam_64x64,
.anims = sAnims_ChasesAway_Rayquaza,
2017-12-23 12:23:23 +00:00
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
2020-08-26 21:31:37 +01:00
.callback = SpriteCB_ChasesAway_Rayquaza,
2017-12-23 12:23:23 +00:00
};
2020-08-26 21:31:37 +01:00
static const struct SpriteTemplate sSpriteTemplate_ChasesAway_RayquazaTail =
2017-12-23 12:23:23 +00:00
{
2020-08-26 21:31:37 +01:00
.tileTag = TAG_CHASE_RAYQUAZA_TAIL,
.paletteTag = TAG_CHASE_RAYQUAZA,
.oam = &sOam_32x32,
.anims = sAnims_ChasesAway_RayquazaTail,
2017-12-23 12:23:23 +00:00
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = SpriteCallbackDummy,
};
2020-08-26 21:31:37 +01:00
static const struct SpriteTemplate sSpriteTemplate_ChasesAway_KyogreSplash =
2017-12-23 12:23:23 +00:00
{
2020-08-26 21:31:37 +01:00
.tileTag = TAG_CHASE_SPLASH,
.paletteTag = TAG_CHASE_SPLASH,
.oam = &sOam_32x8,
.anims = sAnims_ChasesAway_KyogreSplash,
2017-12-23 12:23:23 +00:00
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = SpriteCallbackDummy,
};
2020-08-26 21:31:37 +01:00
static const struct BgTemplate sBgTemplates_ChasesAway[] =
2017-12-23 12:23:23 +00:00
{
{
.bg = 0,
.charBaseIndex = 1,
.mapBaseIndex = 31,
.screenSize = 0,
.paletteMode = 0,
.priority = 1,
.baseTile = 0
},
{
.bg = 1,
.charBaseIndex = 1,
.mapBaseIndex = 30,
.screenSize = 0,
.paletteMode = 0,
.priority = 2,
.baseTile = 0
},
{
.bg = 2,
.charBaseIndex = 0,
.mapBaseIndex = 29,
.screenSize = 0,
.paletteMode = 0,
.priority = 0,
.baseTile = 0
}
};
2020-08-25 22:49:42 +01:00
void DoRayquazaScene(u8 animId, bool8 endEarly, void (*exitCallback)(void))
2018-01-31 12:05:36 +00:00
{
2018-02-01 13:47:41 +00:00
sRayScene = AllocZeroed(sizeof(*sRayScene));
2018-01-31 12:05:36 +00:00
sRayScene->animId = animId;
2020-08-25 22:49:42 +01:00
sRayScene->exitCallback = exitCallback;
sRayScene->endEarly = endEarly;
2018-02-01 14:32:12 +00:00
SetMainCallback2(CB2_InitRayquazaScene);
2018-01-31 12:05:36 +00:00
}
2018-02-01 14:32:12 +00:00
static void CB2_InitRayquazaScene(void)
2018-01-31 12:05:36 +00:00
{
SetVBlankHBlankCallbacksToNull();
ClearScheduledBgCopiesToVram();
2018-01-31 12:05:36 +00:00
ScanlineEffect_Stop();
FreeAllSpritePalettes();
ResetPaletteFade();
ResetSpriteData();
ResetTasks();
2020-08-26 21:31:37 +01:00
FillPalette(RGB_BLACK, 0xF0, 32);
2018-01-31 12:05:36 +00:00
CreateTask(sTasksForAnimations[sRayScene->animId], 0);
2018-02-01 14:32:12 +00:00
SetMainCallback2(CB2_RayquazaScene);
2018-01-31 12:05:36 +00:00
}
2018-02-01 14:32:12 +00:00
static void CB2_RayquazaScene(void)
2018-01-31 12:05:36 +00:00
{
RunTasks();
AnimateSprites();
BuildOamBuffer();
DoScheduledBgTilemapCopiesToVram();
2018-01-31 12:05:36 +00:00
UpdatePaletteFade();
}
2018-02-07 18:47:55 +00:00
static void VBlankCB_RayquazaScene(void)
2018-01-31 12:05:36 +00:00
{
LoadOam();
ProcessSpriteCopyRequests();
TransferPlttBuffer();
}
2018-02-01 13:47:41 +00:00
static void Task_EndAfterFadeScreen(u8 taskId)
2018-01-31 12:05:36 +00:00
{
if (!gPaletteFade.active)
{
ResetSpriteData();
FreeAllSpritePalettes();
2020-08-25 22:49:42 +01:00
SetMainCallback2(sRayScene->exitCallback);
2018-01-31 12:05:36 +00:00
Free(sRayScene);
DestroyTask(taskId);
}
}
2018-02-01 13:47:41 +00:00
static void Task_SetNextAnim(u8 taskId)
2018-01-31 12:05:36 +00:00
{
if (!gPaletteFade.active)
{
2020-08-25 22:49:42 +01:00
if (sRayScene->endEarly == TRUE)
2018-01-31 12:05:36 +00:00
{
gTasks[taskId].func = Task_EndAfterFadeScreen;
}
else
{
sRayScene->animId++;
2020-08-25 22:49:42 +01:00
sRayScene->unk = 0;
2018-01-31 12:05:36 +00:00
gTasks[taskId].func = sTasksForAnimations[sRayScene->animId];
}
}
}
2018-02-01 13:47:41 +00:00
static void sub_81D68C8(void)
2018-01-31 12:05:36 +00:00
{
2020-08-26 21:31:37 +01:00
SetGpuReg(REG_OFFSET_WININ, WININ_WIN0_BG_ALL | WININ_WIN0_OBJ | WININ_WIN0_CLR);
2018-01-31 12:05:36 +00:00
SetGpuReg(REG_OFFSET_WINOUT, 0);
2020-08-26 21:31:37 +01:00
SetGpuReg(REG_OFFSET_WIN0H, WIN_RANGE(0, DISPLAY_WIDTH));
SetGpuReg(REG_OFFSET_WIN0V, WIN_RANGE(24, DISPLAY_HEIGHT - 24));
2018-01-31 12:05:36 +00:00
gPlttBufferUnfaded[0] = 0;
gPlttBufferFaded[0] = 0;
}
2018-02-01 13:47:41 +00:00
static void sub_81D6904(void)
2018-01-31 12:05:36 +00:00
{
2020-08-26 21:31:37 +01:00
SetGpuReg(REG_OFFSET_WININ, WININ_WIN0_BG_ALL | WININ_WIN0_OBJ | WININ_WIN0_CLR);
SetGpuReg(REG_OFFSET_WINOUT, WINOUT_WIN01_BG_ALL | WINOUT_WIN01_OBJ | WINOUT_WIN01_CLR);
2018-01-31 12:05:36 +00:00
}
2020-08-26 21:31:37 +01:00
#define tCounter data[0]
#define tHelperTaskId data[1]
#define tGroudonSpriteId data[2]
#define tKyogreSpriteId data[3]
#define sGroudonBodySpriteId data[0]
#define sGroudonShoulderSpriteId data[1]
#define sGroudonClawSpriteId data[2]
2018-02-01 22:39:53 +00:00
static void Task_HandleDuoFightPre(u8 taskId)
2018-01-31 12:05:36 +00:00
{
s16 *data = gTasks[taskId].data;
2020-08-26 21:31:37 +01:00
DuoFight_AnimateRain();
2018-01-31 12:05:36 +00:00
if (!gPaletteFade.active)
{
2020-08-26 21:31:37 +01:00
s16 counter = tCounter;
2018-01-31 12:05:36 +00:00
if (counter == 64)
{
2020-08-26 21:31:37 +01:00
DuoFight_Lightning1();
2018-01-31 12:05:36 +00:00
}
else if (counter == 144)
{
2020-08-26 21:31:37 +01:00
DuoFight_Lightning2();
2018-01-31 12:05:36 +00:00
}
else
{
switch (counter)
{
case 328:
2018-02-01 14:32:12 +00:00
DuoFightEnd(taskId, 0);
2018-01-31 12:05:36 +00:00
return;
case 148:
2020-08-26 21:31:37 +01:00
DuoFight_LightningLong();
2018-01-31 12:05:36 +00:00
break;
}
}
2020-08-26 21:31:37 +01:00
tCounter++;
2018-01-31 12:05:36 +00:00
}
}
2020-08-26 21:31:37 +01:00
static u8 CreateDuoFightPreGroudonSprites(void)
2018-01-31 12:05:36 +00:00
{
u8 spriteId;
s16 *data;
2020-08-26 21:31:37 +01:00
spriteId = CreateSprite(&sSpriteTemplate_DuoFightPre_Groudon, 88, 72, 3);
gSprites[spriteId].callback = SpriteCB_DuoFightPre_Groudon;
2018-01-31 12:05:36 +00:00
data = gSprites[spriteId].data;
2020-08-26 21:31:37 +01:00
sGroudonBodySpriteId = CreateSprite(&sSpriteTemplate_DuoFightPre_Groudon, 56, 104, 3);
sGroudonShoulderSpriteId = CreateSprite(&sSpriteTemplate_DuoFightPre_GroudonShoulder, 75, 101, 0);
sGroudonClawSpriteId = CreateSprite(&sSpriteTemplate_DuoFightPre_GroudonClaw, 109, 114, 1);
StartSpriteAnim(&gSprites[sGroudonBodySpriteId], 1);
2018-01-31 12:05:36 +00:00
return spriteId;
}
2020-08-26 21:31:37 +01:00
static void SpriteCB_DuoFightPre_Groudon(struct Sprite *sprite)
2018-01-31 12:05:36 +00:00
{
s16 *data = sprite->data;
data[5]++;
data[5] &= 0x1F;
if (data[5] == 0 && sprite->pos1.x != 72)
{
sprite->pos1.x--;
2020-08-26 21:31:37 +01:00
gSprites[sprite->sGroudonBodySpriteId].pos1.x--;
gSprites[sGroudonShoulderSpriteId].pos1.x--;
gSprites[sGroudonClawSpriteId].pos1.x--;
2018-01-31 12:05:36 +00:00
}
switch (sprite->animCmdIndex)
{
case 0:
2020-08-26 21:31:37 +01:00
gSprites[sGroudonShoulderSpriteId].pos2.x = 0;
gSprites[sGroudonShoulderSpriteId].pos2.y = 0;
gSprites[sGroudonClawSpriteId].pos2.x = 0;
gSprites[sGroudonClawSpriteId].pos2.y = 0;
2018-01-31 12:05:36 +00:00
break;
case 1:
case 3:
2020-08-26 21:31:37 +01:00
gSprites[sGroudonShoulderSpriteId].pos2.x = -1;
gSprites[sGroudonShoulderSpriteId].pos2.y = 0;
gSprites[sGroudonClawSpriteId].pos2.x = -1;
gSprites[sGroudonClawSpriteId].pos2.y = 0;
2018-01-31 12:05:36 +00:00
break;
case 2:
2020-08-26 21:31:37 +01:00
gSprites[sGroudonShoulderSpriteId].pos2.x = -1;
gSprites[sGroudonShoulderSpriteId].pos2.y = 1;
gSprites[sGroudonClawSpriteId].pos2.x = -2;
gSprites[sGroudonClawSpriteId].pos2.y = 1;
2018-01-31 12:05:36 +00:00
break;
}
}
2020-08-26 21:31:37 +01:00
static u8 CreateDuoFightPreKyogreSprites(void)
2018-01-31 12:05:36 +00:00
{
u8 spriteId;
s16 *data;
2020-08-26 21:31:37 +01:00
spriteId = CreateSprite(&sSpriteTemplate_DuoFightPre_Kyogre, 136, 96, 1);
gSprites[spriteId].callback = SpriteCB_DuoFightPre_Kyogre;
2018-01-31 12:05:36 +00:00
data = gSprites[spriteId].data;
2020-08-26 21:31:37 +01:00
data[0] = CreateSprite(&sSpriteTemplate_DuoFightPre_Kyogre, 168, 96, 1) << 8;
data[0] |= CreateSprite(&sSpriteTemplate_DuoFightPre_Kyogre, 136, 112, 1);
data[1] = CreateSprite(&sSpriteTemplate_DuoFightPre_Kyogre, 168, 112, 1) << 8;
data[1] |= CreateSprite(&sSpriteTemplate_DuoFightPre_Kyogre, 136, 128, 1);
data[2] = CreateSprite(&sSpriteTemplate_DuoFightPre_Kyogre, 168, 128, 1) << 8;
data[2] |= CreateSprite(&sSpriteTemplate_DuoFightPre_Kyogre, 104, 128, 2);
data[3] = CreateSprite(&sSpriteTemplate_DuoFightPre_Kyogre, 136, 128, 2) << 8;
data[3] |= CreateSprite(&sSpriteTemplate_DuoFightPre_Kyogre, 184, 128, 0);
data[4] = CreateSprite(&sSpriteTemplate_DuoFightPre_KyogreShoulder, 208, 132, 0) << 8;
data[4] |= CreateSprite(&sSpriteTemplate_DuoFightPre_KyogreFin, 200, 120, 1);
2018-01-31 12:05:36 +00:00
StartSpriteAnim(&gSprites[data[0] >> 8], 1);
StartSpriteAnim(&gSprites[data[0] & 0xFF], 2);
StartSpriteAnim(&gSprites[data[1] >> 8], 3);
StartSpriteAnim(&gSprites[data[1] & 0xFF], 4);
StartSpriteAnim(&gSprites[data[2] >> 8], 5);
StartSpriteAnim(&gSprites[data[2] & 0xFF], 6);
StartSpriteAnim(&gSprites[data[3] >> 8], 7);
StartSpriteAnim(&gSprites[data[3] & 0xFF], 8);
return spriteId;
}
2020-08-26 21:31:37 +01:00
static void SpriteCB_DuoFightPre_Kyogre(struct Sprite *sprite)
2018-01-31 12:05:36 +00:00
{
s16 *data = sprite->data;
data[5]++;
data[5] &= 0x1F;
if (data[5] == 0 && sprite->pos1.x != 152)
{
sprite->pos1.x++;
gSprites[sprite->data[0] >> 8].pos1.x++;
gSprites[sprite->data[0] & 0xFF].pos1.x++;
gSprites[data[1] >> 8].pos1.x++;
gSprites[data[1] & 0xFF].pos1.x++;
gSprites[data[2] >> 8].pos1.x++;
gSprites[data[2] & 0xFF].pos1.x++;
gSprites[data[3] >> 8].pos1.x++;
gSprites[data[3] & 0xFF].pos1.x++;
gSprites[data[4] >> 8].pos1.x++;
gSprites[data[4] & 0xFF].pos1.x++;
}
switch (gSprites[data[2] & 0xFF].animCmdIndex)
{
case 0:
sprite->pos2.y = 0;
gSprites[data[0] >> 8].pos2.y = 0;
gSprites[data[0] & 0xFF].pos2.y = 0;
gSprites[data[1] >> 8].pos2.y = 0;
gSprites[data[1] & 0xFF].pos2.y = 0;
gSprites[data[2] >> 8].pos2.y = 0;
gSprites[data[2] & 0xFF].pos2.y = 0;
gSprites[data[3] >> 8].pos2.y = 0;
gSprites[data[3] & 0xFF].pos2.y = 0;
gSprites[data[4] >> 8].pos2.y = 0;
gSprites[data[4] & 0xFF].pos2.y = 0;
break;
case 1:
case 3:
sprite->pos2.y = 1;
gSprites[data[0] >> 8].pos2.y = 1;
gSprites[data[0] & 0xFF].pos2.y = 1;
gSprites[data[1] >> 8].pos2.y = 1;
gSprites[data[1] & 0xFF].pos2.y = 1;
gSprites[data[2] >> 8].pos2.y = 1;
gSprites[data[2] & 0xFF].pos2.y = 1;
gSprites[data[3] >> 8].pos2.y = 1;
gSprites[data[3] & 0xFF].pos2.y = 1;
gSprites[data[4] >> 8].pos2.y = 1;
gSprites[data[4] & 0xFF].pos2.y = 1;
break;
case 2:
sprite->pos2.y = 2;
gSprites[data[0] >> 8].pos2.y = 2;
gSprites[data[0] & 0xFF].pos2.y = 2;
gSprites[data[1] >> 8].pos2.y = 2;
gSprites[data[1] & 0xFF].pos2.y = 2;
gSprites[data[2] >> 8].pos2.y = 2;
gSprites[data[4] & 0xFF].pos2.y = 2;
break;
}
}
2018-02-07 18:47:55 +00:00
static void VBlankCB_DuoFight(void)
2018-01-31 12:05:36 +00:00
{
2018-02-07 18:47:55 +00:00
VBlankCB_RayquazaScene();
2018-01-31 12:05:36 +00:00
ScanlineEffect_InitHBlankDmaTransfer();
}
2020-08-26 21:31:37 +01:00
static void InitDuoFightSceneBgs(void)
2018-01-31 12:05:36 +00:00
{
ResetVramOamAndBgCntRegs();
ResetBgsAndClearDma3BusyFlags(0);
2020-08-26 21:31:37 +01:00
InitBgsFromTemplates(0, sBgTemplates_DuoFight, ARRAY_COUNT(sBgTemplates_DuoFight));
2018-01-31 12:05:36 +00:00
SetBgTilemapBuffer(0, sRayScene->tilemapBuffers[0]);
SetBgTilemapBuffer(1, sRayScene->tilemapBuffers[1]);
SetBgTilemapBuffer(2, sRayScene->tilemapBuffers[2]);
ResetAllBgsCoordinates();
2020-05-14 09:37:09 +01:00
ScheduleBgCopyTilemapToVram(0);
ScheduleBgCopyTilemapToVram(1);
ScheduleBgCopyTilemapToVram(2);
2018-01-31 12:05:36 +00:00
SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_OBJ_ON | DISPCNT_OBJ_1D_MAP);
ShowBg(0);
ShowBg(1);
ShowBg(2);
SetGpuReg(REG_OFFSET_BLDCNT, 0);
}
2020-08-26 21:31:37 +01:00
static void LoadDuoFightSceneGfx(void)
2018-01-31 12:05:36 +00:00
{
2020-05-14 09:37:09 +01:00
ResetTempTileDataBuffers();
2020-08-26 21:31:37 +01:00
DecompressAndCopyTileDataToVram(0, gRaySceneDuoFight_Clouds_Gfx, 0, 0, 0);
while (FreeTempTileDataBuffersIfPossible())
;
LZDecompressWram(gRaySceneDuoFight_Clouds2_Tilemap, sRayScene->tilemapBuffers[0]);
LZDecompressWram(gRaySceneDuoFight_Clouds1_Tilemap, sRayScene->tilemapBuffers[1]);
LZDecompressWram(gRaySceneDuoFight_Clouds3_Tilemap, sRayScene->tilemapBuffers[2]);
LoadCompressedPalette(gRaySceneDuoFight_Clouds_Pal, 0, 0x40);
LoadCompressedSpriteSheet(&sSpriteSheet_DuoFight_Groudon);
LoadCompressedSpriteSheet(&sSpriteSheet_DuoFight_GroudonShoulder);
LoadCompressedSpriteSheet(&sSpriteSheet_DuoFight_GroudonClaw);
LoadCompressedSpriteSheet(&sSpriteSheet_DuoFight_Kyogre);
LoadCompressedSpriteSheet(&sSpriteSheet_DuoFight_KyogreShoulder);
LoadCompressedSpriteSheet(&sSpriteSheet_DuoFight_KyogreFin);
LoadCompressedSpritePalette(&sSpritePal_DuoFight_Groudon);
LoadCompressedSpritePalette(&sSpritePal_DuoFight_Kyogre);
2018-01-31 12:05:36 +00:00
}
2018-02-01 13:53:27 +00:00
static void Task_DuoFightAnim(u8 taskId)
2018-01-31 12:05:36 +00:00
{
s16 *data = gTasks[taskId].data;
ScanlineEffect_Clear();
2020-08-26 21:31:37 +01:00
InitDuoFightSceneBgs();
LoadDuoFightSceneGfx();
2018-01-31 12:05:36 +00:00
CpuFastFill16(0, gScanlineEffectRegBuffers, sizeof(gScanlineEffectRegBuffers));
2020-08-26 21:31:37 +01:00
ScanlineEffect_SetParams(sScanlineParams_DuoFight_Clouds);
tCounter = 0;
tHelperTaskId = CreateTask(Task_DuoFight_AnimateClouds, 0);
2018-01-31 12:05:36 +00:00
if (sRayScene->animId == RAY_ANIM_DUO_FIGHT_PRE)
{
2020-08-26 21:31:37 +01:00
tGroudonSpriteId = CreateDuoFightPreGroudonSprites();
tKyogreSpriteId = CreateDuoFightPreKyogreSprites();
2018-02-01 22:39:53 +00:00
gTasks[taskId].func = Task_HandleDuoFightPre;
2018-01-31 12:05:36 +00:00
}
else
{
2020-08-26 21:31:37 +01:00
tGroudonSpriteId = CreateDuoFightGroudonSprites();
tKyogreSpriteId = CreateDuoFightKyogreSprites();
2018-02-01 22:39:53 +00:00
gTasks[taskId].func = Task_HandleDuoFight;
2018-01-31 12:05:36 +00:00
StopMapMusic();
}
BlendPalettes(-1, 0x10, 0);
2019-04-04 22:05:46 +01:00
BeginNormalPaletteFade(0xFFFFFFFF, 0, 0x10, 0, RGB_BLACK);
2018-02-07 18:47:55 +00:00
SetVBlankCallback(VBlankCB_DuoFight);
2018-01-31 12:05:36 +00:00
PlaySE(SE_T_OOAME);
}
2018-02-01 10:17:07 +00:00
2020-08-26 21:31:37 +01:00
static void Task_DuoFight_AnimateClouds(u8 taskId)
2018-02-01 10:17:07 +00:00
{
s16 i;
u16 *data = gTasks[taskId].data;
for (i = 24; i < 92; i++)
{
if (i <= 47)
{
gScanlineEffectRegBuffers[0][i] = data[0] >> 8;
gScanlineEffectRegBuffers[1][i] = data[0] >> 8;
}
else if (i <= 63)
{
gScanlineEffectRegBuffers[0][i] = data[1] >> 8;
gScanlineEffectRegBuffers[1][i] = data[1] >> 8;
}
else if (i <= 75)
{
gScanlineEffectRegBuffers[0][i] = data[2] >> 8;
gScanlineEffectRegBuffers[1][i] = data[2] >> 8;
}
else if (i <= 83)
{
gScanlineEffectRegBuffers[0][i] = data[3] >> 8;
gScanlineEffectRegBuffers[1][i] = data[3] >> 8;
}
else if (i <= 87)
{
gScanlineEffectRegBuffers[0][i] = data[4] >> 8;
gScanlineEffectRegBuffers[1][i] = data[4] >> 8;
}
else
{
gScanlineEffectRegBuffers[0][i] = data[5] >> 8;
gScanlineEffectRegBuffers[1][i] = data[5] >> 8;
}
}
if (sRayScene->animId == RAY_ANIM_DUO_FIGHT_PRE)
{
data[0] += 448;
data[1] += 384;
data[2] += 320;
data[3] += 256;
data[4] += 192;
data[5] += 128;
}
else
{
data[0] += 768;
data[1] += 640;
data[2] += 512;
data[3] += 384;
data[4] += 256;
data[5] += 128;
}
}
2018-02-01 22:39:53 +00:00
static void Task_HandleDuoFight(u8 taskId)
2018-02-01 10:17:07 +00:00
{
s16 *data = gTasks[taskId].data;
2020-08-26 21:31:37 +01:00
DuoFight_AnimateRain();
2018-02-01 10:17:07 +00:00
if (!gPaletteFade.active)
{
2020-08-26 21:31:37 +01:00
s16 counter = tCounter;
2018-02-01 10:17:07 +00:00
if (counter == 32 || counter == 112)
{
2020-08-26 21:31:37 +01:00
DuoFight_Lightning1();
2018-02-01 10:17:07 +00:00
}
else if (counter == 216)
{
2020-08-26 21:31:37 +01:00
DuoFight_Lightning2();
2018-02-01 10:17:07 +00:00
}
else if (counter == 220)
{
2020-08-26 21:31:37 +01:00
DuoFight_LightningLong();
2018-02-01 10:17:07 +00:00
}
else
{
switch (counter)
{
case 412:
2018-02-01 14:32:12 +00:00
DuoFightEnd(taskId, 2);
2018-02-01 10:17:07 +00:00
return;
case 380:
2018-02-07 18:47:55 +00:00
SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT1_BG2 | BLDCNT_TGT2_BG1 | BLDCNT_EFFECT_BLEND);
2020-08-26 21:31:37 +01:00
gTasks[tHelperTaskId].func = DuoFight_PanOffScene;
gTasks[tHelperTaskId].data[0] = 0;
gTasks[tHelperTaskId].data[2] = data[2];
gTasks[tHelperTaskId].data[3] = data[3];
2018-02-01 10:17:07 +00:00
ScanlineEffect_Stop();
break;
}
}
2020-08-26 21:31:37 +01:00
tCounter++;
2018-02-01 10:17:07 +00:00
}
}
2020-08-26 21:31:37 +01:00
// In the below functions, BlendPalettesGradually flashes the bg white and the duo black
// and gradually fades them back to original color to simulate lightning
static void DuoFight_Lightning1(void)
2018-02-01 10:17:07 +00:00
{
PlaySE(SE_T_KAMI);
2020-08-26 21:31:37 +01:00
BlendPalettesGradually(0x00007FFF, 0, 16, 0, RGB_WHITEALPHA, 0, 0);
BlendPalettesGradually(0xFFFF0000, 0, 16, 0, RGB_BLACK, 0, 1);
2018-02-01 10:17:07 +00:00
}
2020-08-26 21:31:37 +01:00
static void DuoFight_Lightning2(void)
2018-02-01 10:17:07 +00:00
{
PlaySE(SE_T_KAMI);
2020-08-26 21:31:37 +01:00
BlendPalettesGradually(0x00007FFF, 0, 16, 16, RGB_WHITEALPHA, 0, 0);
BlendPalettesGradually(0xFFFF0000, 0, 16, 16, RGB_BLACK, 0, 1);
2018-02-01 10:17:07 +00:00
}
2020-08-26 21:31:37 +01:00
static void DuoFight_LightningLong(void)
2018-02-01 10:17:07 +00:00
{
2020-08-26 21:31:37 +01:00
BlendPalettesGradually(0x00007FFF, 4, 16, 0, RGB_WHITEALPHA, 0, 0);
BlendPalettesGradually(0xFFFF0000, 4, 16, 0, RGB_BLACK, 0, 1);
2018-02-01 10:17:07 +00:00
}
2020-08-26 21:31:37 +01:00
static void DuoFight_AnimateRain(void)
2018-02-01 10:17:07 +00:00
{
ChangeBgX(2, 0x400, 1);
ChangeBgY(2, 0x800, 2);
}
2020-08-26 21:31:37 +01:00
// Only used by the full version, which pans up at the end (so scene objects move down)
// DuoFightPre just fades to black with no pan
static void DuoFight_PanOffScene(u8 taskId)
2018-02-01 10:17:07 +00:00
{
u16 bgY;
s16 *data = gTasks[taskId].data;
2020-08-26 21:31:37 +01:00
DuoFight_SlideGroudonDown(&gSprites[tGroudonSpriteId]);
DuoFight_SlideKyogreDown(&gSprites[tKyogreSpriteId]);
2018-02-01 10:17:07 +00:00
bgY = GetBgY(1);
if (GetBgY(1) == 0 || bgY > 0x8000)
ChangeBgY(1, 0x400, 2);
2020-08-26 21:31:37 +01:00
if (tCounter != 16)
2018-02-01 10:17:07 +00:00
{
2020-08-26 21:31:37 +01:00
tCounter++;
SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(16 - tCounter, tCounter));
2018-02-01 10:17:07 +00:00
}
}
2018-02-01 14:32:12 +00:00
static void DuoFightEnd(u8 taskId, s8 palDelay)
2018-02-01 10:17:07 +00:00
{
PlaySE(SE_T_OOAME_E);
2019-04-04 22:05:46 +01:00
BeginNormalPaletteFade(0xFFFFFFFF, palDelay, 0, 0x10, RGB_BLACK);
2018-02-01 14:32:12 +00:00
gTasks[taskId].func = Task_DuoFightEnd;
2018-02-01 10:17:07 +00:00
}
2018-02-01 14:32:12 +00:00
static void Task_DuoFightEnd(u8 taskId)
2018-02-01 10:17:07 +00:00
{
s16 *data = gTasks[taskId].data;
2020-08-26 21:31:37 +01:00
DuoFight_AnimateRain();
2018-02-01 10:17:07 +00:00
if (!gPaletteFade.active)
{
2020-08-26 21:31:37 +01:00
DestroyTask(tHelperTaskId);
2018-02-01 10:17:07 +00:00
ChangeBgY(1, 0, 0);
SetVBlankCallback(NULL);
ScanlineEffect_Stop();
ResetSpriteData();
FreeAllSpritePalettes();
2020-08-26 21:31:37 +01:00
tCounter = 0;
2018-02-01 10:17:07 +00:00
gTasks[taskId].func = Task_SetNextAnim;
}
}
2020-08-26 21:31:37 +01:00
static u8 CreateDuoFightGroudonSprites(void)
2018-02-01 10:17:07 +00:00
{
u8 spriteId;
s16 *data;
2020-08-26 21:31:37 +01:00
spriteId = CreateSprite(&sSpriteTemplate_DuoFight_Groudon, 98, 72, 3);
gSprites[spriteId].callback = SpriteCB_DuoFight_Groudon;
2018-02-01 10:17:07 +00:00
data = gSprites[spriteId].data;
2020-08-26 21:31:37 +01:00
sGroudonBodySpriteId = CreateSprite(&sSpriteTemplate_DuoFight_Groudon, 66, 104, 3);
sGroudonShoulderSpriteId = CreateSprite(&sSpriteTemplate_DuoFight_GroudonShoulder, 85, 101, 0);
sGroudonClawSpriteId = CreateSprite(&sSpriteTemplate_DuoFight_GroudonClaw, 119, 114, 1);
StartSpriteAnim(&gSprites[sGroudonBodySpriteId], 1);
2018-02-01 10:17:07 +00:00
return spriteId;
}
2020-08-26 21:31:37 +01:00
static void SpriteCB_DuoFight_Groudon(struct Sprite *sprite)
2018-02-01 10:17:07 +00:00
{
s16 *data = sprite->data;
data[5]++;
data[5] &= 0xF;
if (!(data[5] & 7) && sprite->pos1.x != 72)
{
sprite->pos1.x--;
2020-08-26 21:31:37 +01:00
gSprites[sprite->sGroudonBodySpriteId].pos1.x--;
gSprites[sGroudonShoulderSpriteId].pos1.x--;
gSprites[sGroudonClawSpriteId].pos1.x--;
2018-02-01 10:17:07 +00:00
}
switch (sprite->animCmdIndex)
{
case 0:
2020-08-26 21:31:37 +01:00
gSprites[sGroudonShoulderSpriteId].pos2.x = 0;
gSprites[sGroudonShoulderSpriteId].pos2.y = 0;
gSprites[sGroudonClawSpriteId].pos2.x = 0;
gSprites[sGroudonClawSpriteId].pos2.y = 0;
2018-02-01 10:17:07 +00:00
break;
case 1:
case 3:
2020-08-26 21:31:37 +01:00
gSprites[sGroudonShoulderSpriteId].pos2.x = -1;
gSprites[sGroudonShoulderSpriteId].pos2.y = 0;
gSprites[sGroudonClawSpriteId].pos2.x = -1;
gSprites[sGroudonClawSpriteId].pos2.y = 0;
2018-02-01 10:17:07 +00:00
break;
case 2:
2020-08-26 21:31:37 +01:00
gSprites[sGroudonShoulderSpriteId].pos2.x = -1;
gSprites[sGroudonShoulderSpriteId].pos2.y = 1;
gSprites[sGroudonClawSpriteId].pos2.x = -2;
gSprites[sGroudonClawSpriteId].pos2.y = 1;
2018-02-01 10:17:07 +00:00
break;
}
}
2020-08-26 21:31:37 +01:00
static void DuoFight_SlideGroudonDown(struct Sprite *sprite)
2018-02-01 10:17:07 +00:00
{
s16 *data = sprite->data;
if (sprite->pos1.y <= 160)
{
sprite->pos1.y += 8;
2020-08-26 21:31:37 +01:00
gSprites[sprite->sGroudonBodySpriteId].pos1.y += 8;
gSprites[sGroudonShoulderSpriteId].pos1.y += 8;
gSprites[sGroudonClawSpriteId].pos1.y += 8;
2018-02-01 10:17:07 +00:00
}
}
2020-08-26 21:31:37 +01:00
static u8 CreateDuoFightKyogreSprites(void)
2018-02-01 10:17:07 +00:00
{
u8 spriteId;
s16 *data;
2020-08-26 21:31:37 +01:00
spriteId = CreateSprite(&sSpriteTemplate_DuoFight_Kyogre, 126, 96, 1);
gSprites[spriteId].callback = SpriteCB_DuoFight_Kyogre;
2018-02-01 10:17:07 +00:00
data = gSprites[spriteId].data;
2020-08-26 21:31:37 +01:00
data[0] = CreateSprite(&sSpriteTemplate_DuoFight_Kyogre, 158, 96, 1) << 8;
data[0] |= CreateSprite(&sSpriteTemplate_DuoFight_Kyogre, 126, 112, 1);
data[1] = CreateSprite(&sSpriteTemplate_DuoFight_Kyogre, 158, 112, 1) << 8;
data[1] |= CreateSprite(&sSpriteTemplate_DuoFight_Kyogre, 126, 128, 1);
data[2] = CreateSprite(&sSpriteTemplate_DuoFight_Kyogre, 158, 128, 1) << 8;
data[2] |= CreateSprite(&sSpriteTemplate_DuoFight_Kyogre, 94, 128, 2);
data[3] = CreateSprite(&sSpriteTemplate_DuoFight_Kyogre, 126, 128, 2) << 8;
data[3] |= CreateSprite(&sSpriteTemplate_DuoFight_Kyogre, 174, 128, 0);
data[4] = CreateSprite(&sSpriteTemplate_DuoFight_KyogreShoulder, 198, 132, 0) << 8;
data[4] |= CreateSprite(&sSpriteTemplate_DuoFight_KyogreFin, 190, 120, 1);
2018-02-01 10:17:07 +00:00
StartSpriteAnim(&gSprites[data[0] >> 8], 1);
StartSpriteAnim(&gSprites[data[0] & 0xFF], 2);
StartSpriteAnim(&gSprites[data[1] >> 8], 3);
StartSpriteAnim(&gSprites[data[1] & 0xFF], 4);
StartSpriteAnim(&gSprites[data[2] >> 8], 5);
StartSpriteAnim(&gSprites[data[2] & 0xFF], 6);
StartSpriteAnim(&gSprites[data[3] >> 8], 7);
StartSpriteAnim(&gSprites[data[3] & 0xFF], 8);
return spriteId;
}
2020-08-26 21:31:37 +01:00
static void SpriteCB_DuoFight_Kyogre(struct Sprite *sprite)
2018-02-01 10:17:07 +00:00
{
s16 *data = sprite->data;
data[5]++;
data[5] &= 0xF;
if (!(data[5] & 7) && sprite->pos1.x != 152)
{
sprite->pos1.x++;
gSprites[sprite->data[0] >> 8].pos1.x++;
gSprites[sprite->data[0] & 0xFF].pos1.x++;
gSprites[data[1] >> 8].pos1.x++;
gSprites[data[1] & 0xFF].pos1.x++;
gSprites[data[2] >> 8].pos1.x++;
gSprites[data[2] & 0xFF].pos1.x++;
gSprites[data[3] >> 8].pos1.x++;
gSprites[data[3] & 0xFF].pos1.x++;
gSprites[data[4] >> 8].pos1.x++;
gSprites[data[4] & 0xFF].pos1.x++;
}
switch (gSprites[data[2] & 0xFF].animCmdIndex)
{
case 0:
sprite->pos2.y = 0;
gSprites[data[0] >> 8].pos2.y = 0;
gSprites[data[0] & 0xFF].pos2.y = 0;
gSprites[data[1] >> 8].pos2.y = 0;
gSprites[data[1] & 0xFF].pos2.y = 0;
gSprites[data[2] >> 8].pos2.y = 0;
gSprites[data[2] & 0xFF].pos2.y = 0;
gSprites[data[3] >> 8].pos2.y = 0;
gSprites[data[3] & 0xFF].pos2.y = 0;
gSprites[data[4] >> 8].pos2.y = 0;
gSprites[data[4] & 0xFF].pos2.y = 0;
break;
case 1:
case 3:
sprite->pos2.y = 1;
gSprites[data[0] >> 8].pos2.y = 1;
gSprites[data[0] & 0xFF].pos2.y = 1;
gSprites[data[1] >> 8].pos2.y = 1;
gSprites[data[1] & 0xFF].pos2.y = 1;
gSprites[data[2] >> 8].pos2.y = 1;
gSprites[data[2] & 0xFF].pos2.y = 1;
gSprites[data[3] >> 8].pos2.y = 1;
gSprites[data[3] & 0xFF].pos2.y = 1;
gSprites[data[4] >> 8].pos2.y = 1;
gSprites[data[4] & 0xFF].pos2.y = 1;
break;
case 2:
sprite->pos2.y = 2;
gSprites[data[0] >> 8].pos2.y = 2;
gSprites[data[0] & 0xFF].pos2.y = 2;
gSprites[data[1] >> 8].pos2.y = 2;
gSprites[data[1] & 0xFF].pos2.y = 2;
gSprites[data[2] >> 8].pos2.y = 2;
gSprites[data[4] & 0xFF].pos2.y = 2;
break;
}
}
2020-08-26 21:31:37 +01:00
static void DuoFight_SlideKyogreDown(struct Sprite *sprite)
2018-02-01 10:17:07 +00:00
{
s16 *data = sprite->data;
if (sprite->pos1.y <= 160)
{
sprite->pos1.y += 8;
gSprites[sprite->data[0] >> 8].pos1.y += 8;
gSprites[sprite->data[0] & 0xFF].pos1.y += 8;
gSprites[data[1] >> 8].pos1.y += 8;
gSprites[data[1] & 0xFF].pos1.y += 8;
gSprites[data[2] >> 8].pos1.y += 8;
gSprites[data[2] & 0xFF].pos1.y += 8;
gSprites[data[3] >> 8].pos1.y += 8;
gSprites[data[3] & 0xFF].pos1.y += 8;
gSprites[data[4] >> 8].pos1.y += 8;
gSprites[data[4] & 0xFF].pos1.y += 8;
}
}
2020-08-26 22:42:51 +01:00
#undef tCounter
#undef tHelperTaskId
#undef tGroudonSpriteId
#undef tKyogreSpriteId
#undef sGroudonBodySpriteId
#undef sGroudonShoulderSpriteId
#undef sGroudonClawSpriteId
#define tState data[0]
#define tTimer data[1]
#define tScale data[2]
#define tScaleSpeed data[3]
#define tYCoord data[4]
#define tYSpeed data[5]
#define tYOffset data[6]
#define tYOffsetDir data[7]
2020-08-26 21:31:37 +01:00
static void InitTakesFlightSceneBgs(void)
2018-02-01 10:17:07 +00:00
{
ResetVramOamAndBgCntRegs();
ResetBgsAndClearDma3BusyFlags(0);
2020-08-26 21:31:37 +01:00
InitBgsFromTemplates(1, sBgTemplates_TakesFlight, ARRAY_COUNT(sBgTemplates_TakesFlight));
2018-02-01 10:17:07 +00:00
SetBgTilemapBuffer(0, sRayScene->tilemapBuffers[0]);
SetBgTilemapBuffer(1, sRayScene->tilemapBuffers[1]);
SetBgTilemapBuffer(2, sRayScene->tilemapBuffers[2]);
ResetAllBgsCoordinates();
2020-05-14 09:37:09 +01:00
ScheduleBgCopyTilemapToVram(0);
ScheduleBgCopyTilemapToVram(1);
ScheduleBgCopyTilemapToVram(2);
2018-02-01 10:17:07 +00:00
SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_OBJ_ON | DISPCNT_OBJ_1D_MAP);
ShowBg(0);
ShowBg(1);
ShowBg(2);
SetGpuReg(REG_OFFSET_BLDCNT, 0);
}
2020-08-26 21:31:37 +01:00
static void LoadTakesFlightSceneGfx(void)
2018-02-01 10:17:07 +00:00
{
2020-05-14 09:37:09 +01:00
ResetTempTileDataBuffers();
2020-08-26 22:42:51 +01:00
DecompressAndCopyTileDataToVram(0, gRaySceneDuoFight_Clouds_Gfx, 0, 0, 0); // Re-uses clouds from previous scene
2020-08-26 21:31:37 +01:00
DecompressAndCopyTileDataToVram(1, gRaySceneTakesFlight_Bg_Gfx, 0, 0, 0);
DecompressAndCopyTileDataToVram(2, gRaySceneTakesFlight_Rayquaza_Gfx, 0, 0, 0);
while (FreeTempTileDataBuffersIfPossible())
;
LZDecompressWram(gRaySceneDuoFight_Clouds2_Tilemap, sRayScene->tilemapBuffers[0]);
LZDecompressWram(gRaySceneTakesFlight_Bg_Tilemap, sRayScene->tilemapBuffers[1]);
LZDecompressWram(gRaySceneTakesFlight_Rayquaza_Tilemap, sRayScene->tilemapBuffers[2]);
2020-08-26 22:42:51 +01:00
LoadCompressedPalette(gRaySceneTakesFlight_Rayquaza_Pal, 0, 64);
2020-08-26 21:31:37 +01:00
LoadCompressedSpriteSheet(&sSpriteSheet_TakesFlight_Smoke);
LoadCompressedSpritePalette(&sSpritePal_TakesFlight_Smoke);
2018-02-01 10:17:07 +00:00
}
2018-02-01 13:53:27 +00:00
static void Task_RayTakesFlightAnim(u8 taskId)
2018-02-01 10:17:07 +00:00
{
s16 *data = gTasks[taskId].data;
PlayNewMapMusic(MUS_REKKUU_KOURIN);
2020-08-26 21:31:37 +01:00
InitTakesFlightSceneBgs();
LoadTakesFlightSceneGfx();
2018-02-07 18:47:55 +00:00
SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT1_OBJ | BLDCNT_TGT2_BG1 | BLDCNT_EFFECT_BLEND);
2018-12-26 13:03:48 +00:00
SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(8, 8));
2020-08-26 22:42:51 +01:00
BlendPalettes(-1, 16, 0);
2018-02-07 18:47:55 +00:00
SetVBlankCallback(VBlankCB_RayquazaScene);
2020-08-26 22:42:51 +01:00
CreateTask(Task_TakesFlight_CreateSmoke, 0);
tState = 0;
tTimer = 0;
2018-02-01 22:39:53 +00:00
gTasks[taskId].func = Task_HandleRayTakesFlight;
2018-02-01 10:17:07 +00:00
}
2020-08-26 22:42:51 +01:00
// Animate Rayquaza (flying up and down, and changing size as it gets further from the screen)
// In this scene Rayquaza is a bg tilemap on bg 2, not a sprite
2018-02-01 22:39:53 +00:00
static void Task_HandleRayTakesFlight(u8 taskId)
2018-02-01 10:17:07 +00:00
{
s16 *data = gTasks[taskId].data;
2020-08-26 22:42:51 +01:00
switch (tState)
2018-02-01 10:17:07 +00:00
{
case 0:
2020-08-26 22:42:51 +01:00
// Delay, then fade in
if (tTimer == 8)
2018-02-01 10:17:07 +00:00
{
2019-04-04 22:05:46 +01:00
BeginNormalPaletteFade(0xFFFFFFFF, 0, 0x10, 0, RGB_BLACK);
2020-08-26 22:42:51 +01:00
tScale = 0;
tScaleSpeed = 30;
tYCoord = 0;
tYSpeed = 7;
tTimer = 0;
tState++;
2018-02-01 10:17:07 +00:00
}
else
{
2020-08-26 22:42:51 +01:00
tTimer++;
2018-02-01 10:17:07 +00:00
}
break;
case 1:
2020-08-26 22:42:51 +01:00
// Fly in
tScale += tScaleSpeed;
tYCoord += tYSpeed;
if (tScaleSpeed > 3)
tScaleSpeed -= 3;
if (tYSpeed != 0)
tYSpeed--;
if (tScale > 255)
2018-02-01 10:17:07 +00:00
{
2020-08-26 22:42:51 +01:00
tScale = 256;
tScaleSpeed = 0;
tYOffset = 12;
tYOffsetDir = -1;
tTimer = 0;
tState++;
2018-02-01 10:17:07 +00:00
}
2020-08-26 22:42:51 +01:00
SetBgAffine(2, 0x7800, 0x1800, 0x78, tYCoord + 32, tScale, tScale, 0);
2018-02-01 10:17:07 +00:00
break;
case 2:
2020-08-26 22:42:51 +01:00
// Float up and down
tTimer++;
SetBgAffine(2, 0x7800, 0x1800, 0x78, tYCoord + 32 + (tYOffset >> 2), tScale, tScale, 0);
tYOffset += tYOffsetDir;
if (tYOffset == 12 || tYOffset == -12)
2018-02-01 10:17:07 +00:00
{
2020-08-26 22:42:51 +01:00
tYOffsetDir *= -1;
if (tTimer > 295)
2018-02-01 10:17:07 +00:00
{
2020-08-26 22:42:51 +01:00
tState++;
2019-04-04 22:05:46 +01:00
BeginNormalPaletteFade(0xFFFFFFFF, 6, 0, 0x10, RGB_BLACK);
2018-02-01 10:17:07 +00:00
}
}
break;
case 3:
2020-08-26 22:42:51 +01:00
// Fly away, fade out
tScale += 16;
SetBgAffine(2, 0x7800, 0x1800, 0x78, tYCoord + 32, tScale, tScale, 0);
2018-02-01 14:32:12 +00:00
Task_RayTakesFlightEnd(taskId);
2018-02-01 10:17:07 +00:00
break;
}
}
2020-08-26 22:42:51 +01:00
#undef tState
#undef tTimer
#undef tScale
#undef tScaleSpeed
#undef tYCoord
#undef tYSpeed
#undef tYOffset
#undef tYOffsetDir
2018-02-01 14:32:12 +00:00
static void Task_RayTakesFlightEnd(u8 taskId)
2018-02-01 10:17:07 +00:00
{
if (!gPaletteFade.active)
{
SetVBlankCallback(NULL);
ResetSpriteData();
FreeAllSpritePalettes();
gTasks[taskId].func = Task_SetNextAnim;
}
}
2020-08-26 22:42:51 +01:00
#define tSmokeId data[0]
#define tTimer data[1]
#define sSmokeId data[0]
#define sTimer data[1]
static void Task_TakesFlight_CreateSmoke(u8 taskId)
2018-02-01 10:17:07 +00:00
{
s16 *data = gTasks[taskId].data;
2020-08-26 22:42:51 +01:00
if ((tTimer & 3) == 0)
2018-02-01 10:17:07 +00:00
{
2020-08-26 21:31:37 +01:00
u8 spriteId = CreateSprite(&sSpriteTemplate_TakesFlight_Smoke,
2020-08-26 22:42:51 +01:00
(sTakesFlight_SmokeCoords[tSmokeId][0] * 4) + 120,
(sTakesFlight_SmokeCoords[tSmokeId][1] * 4) + 80,
2018-02-01 10:17:07 +00:00
0);
2020-08-26 22:42:51 +01:00
gSprites[spriteId].sSmokeId = (s8)(tSmokeId);
gSprites[spriteId].oam.objMode = ST_OAM_OBJ_BLEND;
gSprites[spriteId].oam.affineMode = ST_OAM_AFFINE_DOUBLE;
2018-02-01 10:17:07 +00:00
gSprites[spriteId].oam.priority = 2;
InitSpriteAffineAnim(&gSprites[spriteId]);
2020-08-26 22:42:51 +01:00
if (tSmokeId == MAX_SMOKE - 1)
2018-02-01 10:17:07 +00:00
{
DestroyTask(taskId);
return;
}
else
{
2020-08-26 22:42:51 +01:00
tSmokeId++;
2018-02-01 10:17:07 +00:00
}
}
2020-08-26 22:42:51 +01:00
tTimer++;
2018-02-01 10:17:07 +00:00
}
2020-08-26 21:31:37 +01:00
static void SpriteCB_TakesFlight_Smoke(struct Sprite *sprite)
2018-02-01 10:17:07 +00:00
{
2020-08-26 22:42:51 +01:00
if (sprite->sTimer == 0)
2018-02-01 10:17:07 +00:00
{
sprite->pos2.x = 0;
sprite->pos2.y = 0;
}
else
{
2020-08-26 22:42:51 +01:00
sprite->pos2.x += sTakesFlight_SmokeCoords[sprite->sSmokeId][0];
sprite->pos2.y += sTakesFlight_SmokeCoords[sprite->sSmokeId][1];
2018-02-01 10:17:07 +00:00
}
2020-08-26 22:42:51 +01:00
sprite->sTimer++;
sprite->sTimer &= 0xF;
2018-02-01 10:17:07 +00:00
}
2020-08-26 22:42:51 +01:00
#undef tSmokeId
#undef tTimer
#undef sSmokeId
#undef sTimer
2020-08-26 21:31:37 +01:00
static void InitDescendsSceneBgs(void)
2018-02-01 10:17:07 +00:00
{
ResetVramOamAndBgCntRegs();
ResetBgsAndClearDma3BusyFlags(0);
2020-08-26 21:31:37 +01:00
InitBgsFromTemplates(0, sBgTemplates_Descends, ARRAY_COUNT(sBgTemplates_Descends));
2018-02-01 10:17:07 +00:00
SetBgTilemapBuffer(0, sRayScene->tilemapBuffers[0]);
SetBgTilemapBuffer(1, sRayScene->tilemapBuffers[1]);
SetBgTilemapBuffer(2, sRayScene->tilemapBuffers[2]);
SetBgTilemapBuffer(3, sRayScene->tilemapBuffers[3]);
ResetAllBgsCoordinates();
2020-05-14 09:37:09 +01:00
ScheduleBgCopyTilemapToVram(0);
ScheduleBgCopyTilemapToVram(1);
ScheduleBgCopyTilemapToVram(2);
ScheduleBgCopyTilemapToVram(3);
2018-02-01 10:17:07 +00:00
SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_OBJ_ON | DISPCNT_OBJ_1D_MAP);
ShowBg(0);
ShowBg(1);
ShowBg(2);
ShowBg(3);
SetGpuReg(REG_OFFSET_BLDCNT, 0);
}
2020-08-26 21:31:37 +01:00
static void LoadDescendsSceneGfx(void)
2018-02-01 10:17:07 +00:00
{
2020-05-14 09:37:09 +01:00
ResetTempTileDataBuffers();
2020-08-26 21:31:37 +01:00
DecompressAndCopyTileDataToVram(0, gRaySceneDescends_Light_Gfx, 0, 0, 0);
DecompressAndCopyTileDataToVram(1, gRaySceneDescends_Bg_Gfx, 0, 0, 0);
2020-05-14 09:37:09 +01:00
while (FreeTempTileDataBuffersIfPossible());
2018-02-01 10:17:07 +00:00
2020-08-26 21:31:37 +01:00
LZDecompressWram(gRaySceneDescends_Light_Tilemap, sRayScene->tilemapBuffers[0]);
LZDecompressWram(gRaySceneDescends_Bg_Tilemap, sRayScene->tilemapBuffers[3]);
CpuFastFill16(0, sRayScene->tilemapBuffers[2], BG_SCREEN_SIZE);
CpuFastCopy(sRayScene->tilemapBuffers[3], sRayScene->tilemapBuffers[1], BG_SCREEN_SIZE);
2018-02-01 10:17:07 +00:00
CpuFastFill16(0, &sRayScene->tilemapBuffers[1][0x100], 0x340);
2020-08-26 21:31:37 +01:00
LoadCompressedPalette(gRaySceneDescends_Bg_Pal, 0, 0x40);
2018-02-01 10:17:07 +00:00
gPlttBufferUnfaded[0] = RGB_WHITE;
gPlttBufferFaded[0] = RGB_WHITE;
2020-08-26 21:31:37 +01:00
LoadCompressedSpriteSheet(&sSpriteSheet_Descends_Rayquaza);
LoadCompressedSpriteSheet(&sSpriteSheet_Descends_RayquazaTail);
LoadCompressedSpritePalette(&sSpritePal_Descends_Rayquaza);
2018-02-01 10:17:07 +00:00
}
2020-08-26 21:31:37 +01:00
static void HBlankCB_RayDescends(void)
2018-02-01 10:17:07 +00:00
{
u16 VCOUNT = GetGpuReg(REG_OFFSET_VCOUNT);
if (VCOUNT >= 24 && VCOUNT <= 135 && VCOUNT - 24 <= sRayScene->field_2008)
REG_BLDALPHA = 0xD08;
else
REG_BLDALPHA = 0x1000;
if (VCOUNT == 0)
{
if (sRayScene->field_2008 <= 0x1FFF)
{
if (sRayScene->field_2008 <= 39)
sRayScene->field_2008 += 4;
else if (sRayScene->field_2008 <= 79)
sRayScene->field_2008 += 2;
else
sRayScene->field_2008 += 1;
}
sRayScene->field_200A++;
}
}
2018-02-01 13:53:27 +00:00
static void Task_RayDescendsAnim(u8 taskId)
2018-02-01 10:17:07 +00:00
{
s16 *data = gTasks[taskId].data;
2020-08-26 21:31:37 +01:00
InitDescendsSceneBgs();
LoadDescendsSceneGfx();
2018-02-07 18:47:55 +00:00
SetGpuRegBits(REG_OFFSET_BLDCNT, BLDCNT_TGT1_BG0 | BLDCNT_TGT2_BG1 | BLDCNT_TGT2_BG2 | BLDCNT_TGT2_BG3 | BLDCNT_TGT2_OBJ | BLDCNT_EFFECT_BLEND);
2018-12-26 13:03:48 +00:00
SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(0, 16));
2018-02-01 10:17:07 +00:00
BlendPalettes(-1, 0x10, 0);
2018-02-07 18:47:55 +00:00
SetVBlankCallback(VBlankCB_RayquazaScene);
2018-02-01 10:17:07 +00:00
sRayScene->field_2008 = 0;
sRayScene->field_200A = 0;
data[0] = 0;
data[1] = 0;
data[2] = 0;
data[3] = 0;
data[4] = 0x1000;
2018-02-01 22:39:53 +00:00
gTasks[taskId].func = Task_HandleRayDescends;
2018-02-01 10:17:07 +00:00
}
2018-02-01 22:39:53 +00:00
static void Task_HandleRayDescends(u8 taskId)
2018-02-01 10:17:07 +00:00
{
s16 *data = gTasks[taskId].data;
switch (data[0])
{
case 0:
if (data[1] == 8)
{
2019-04-04 22:05:46 +01:00
BeginNormalPaletteFade(0xFFFFFFFF, 0, 0x10, 0, RGB_BLACK);
2018-02-01 10:17:07 +00:00
data[1] = 0;
data[0]++;
}
else
{
data[1]++;
}
break;
case 1:
if (!gPaletteFade.active)
{
if (data[1] == 10)
{
data[1] = 0;
data[0]++;
2020-08-26 21:31:37 +01:00
SetHBlankCallback(HBlankCB_RayDescends);
2018-02-01 10:17:07 +00:00
EnableInterrupts(INTR_FLAG_HBLANK | INTR_FLAG_VBLANK);
}
else
{
data[1]++;
}
}
break;
case 2:
if (data[1] == 80)
{
data[1] = 0;
data[0]++;
sub_81D86CC();
}
else
{
data[1]++;
}
break;
case 3:
if (++data[1] == 368)
{
data[1] = 0;
data[0]++;
}
break;
case 4:
2019-04-04 22:05:46 +01:00
BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 0x10, RGB_BLACK);
2018-02-01 14:32:12 +00:00
gTasks[taskId].func = Task_RayDescendsEnd;
2018-02-01 10:17:07 +00:00
break;
}
}
2018-02-01 14:32:12 +00:00
static void Task_RayDescendsEnd(u8 taskId)
2018-02-01 10:17:07 +00:00
{
if (!gPaletteFade.active)
{
SetVBlankCallback(NULL);
SetHBlankCallback(NULL);
ResetSpriteData();
FreeAllSpritePalettes();
gTasks[taskId].func = Task_SetNextAnim;
}
}
2018-02-01 13:47:41 +00:00
static u8 sub_81D86CC(void)
2018-02-01 10:17:07 +00:00
{
2020-08-26 21:31:37 +01:00
u8 spriteId = CreateSprite(&sSpriteTemplate_Descends_Rayquaza, 160, 0, 0);
2018-02-01 10:17:07 +00:00
s16 *data = gSprites[spriteId].data;
2020-08-26 21:31:37 +01:00
data[0] = CreateSprite(&sSpriteTemplate_Descends_RayquazaTail, 184, -48, 0);
2018-02-01 10:17:07 +00:00
gSprites[spriteId].callback = sub_81D874C;
gSprites[spriteId].oam.priority = 3;
gSprites[data[0]].oam.priority = 3;
return spriteId;
}
2018-02-01 13:47:41 +00:00
static void sub_81D874C(struct Sprite *sprite)
2018-02-01 10:17:07 +00:00
{
s16 *data = sprite->data;
s16 counter = data[2];
if (counter == 0)
{
data[3] = 12;
data[4] = 8;
}
else if (counter == 256)
{
data[3] = 9;
data[4] = 7;
}
else if (counter == 268)
{
data[3] = 8;
data[4] = 6;
}
else if (counter == 280)
{
data[3] = 7;
data[4] = 5;
}
else if (counter == 292)
{
data[3] = 6;
data[4] = 4;
}
else if (counter == 304)
{
data[3] = 5;
data[4] = 3;
}
else if (counter == 320)
{
data[3] = 4;
data[4] = 2;
}
if (data[2] % data[3] == 0)
{
sprite->pos2.x--;
gSprites[data[0]].pos2.x--;
}
if (data[2] % data[4] == 0)
{
sprite->pos2.y++;
gSprites[data[0]].pos2.y++;
}
data[2]++;
}
2020-08-26 21:31:37 +01:00
static void InitChargesSceneBgs(void)
2018-02-01 10:17:07 +00:00
{
ResetVramOamAndBgCntRegs();
ResetBgsAndClearDma3BusyFlags(0);
2020-08-26 21:31:37 +01:00
InitBgsFromTemplates(0, sBgTemplates_Charges, ARRAY_COUNT(sBgTemplates_Charges));
2018-02-01 10:17:07 +00:00
SetBgTilemapBuffer(0, sRayScene->tilemapBuffers[0]);
SetBgTilemapBuffer(1, sRayScene->tilemapBuffers[1]);
SetBgTilemapBuffer(2, sRayScene->tilemapBuffers[2]);
SetBgTilemapBuffer(3, sRayScene->tilemapBuffers[3]);
ResetAllBgsCoordinates();
2020-05-14 09:37:09 +01:00
ScheduleBgCopyTilemapToVram(0);
ScheduleBgCopyTilemapToVram(1);
ScheduleBgCopyTilemapToVram(2);
ScheduleBgCopyTilemapToVram(3);
2018-02-01 10:17:07 +00:00
SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_OBJ_ON | DISPCNT_OBJ_1D_MAP | DISPCNT_WIN0_ON);
ShowBg(0);
ShowBg(1);
ShowBg(2);
ShowBg(3);
SetGpuReg(REG_OFFSET_BLDCNT, 0);
}
2020-08-26 21:31:37 +01:00
static void LoadChargesSceneGfx(void)
2018-02-01 10:17:07 +00:00
{
2020-05-14 09:37:09 +01:00
ResetTempTileDataBuffers();
2020-08-26 21:31:37 +01:00
DecompressAndCopyTileDataToVram(1, gRaySceneCharges_Rayquaza_Gfx, 0, 0, 0);
DecompressAndCopyTileDataToVram(2, gRaySceneCharges_Streaks_Gfx, 0, 0, 0);
DecompressAndCopyTileDataToVram(3, gRaySceneCharges_Bg_Gfx, 0, 0, 0);
while (FreeTempTileDataBuffersIfPossible())
;
LZDecompressWram(gRaySceneCharges_Rayquaza2_Tilemap, sRayScene->tilemapBuffers[0]);
LZDecompressWram(gRaySceneCharges_Rayquaza_Tilemap, sRayScene->tilemapBuffers[1]);
LZDecompressWram(gRaySceneCharges_Streaks_Tilemap, sRayScene->tilemapBuffers[2]);
LZDecompressWram(gRaySceneCharges_Bg_Tilemap, sRayScene->tilemapBuffers[3]);
LoadCompressedPalette(gRaySceneCharges_Bg_Pal, 0, 0x80);
2018-02-01 10:17:07 +00:00
}
2018-02-01 13:53:27 +00:00
static void Task_RayChargesAnim(u8 taskId)
2018-02-01 10:17:07 +00:00
{
s16 *data = gTasks[taskId].data;
2020-08-26 21:31:37 +01:00
InitChargesSceneBgs();
LoadChargesSceneGfx();
2018-02-01 10:17:07 +00:00
sub_81D68C8();
BlendPalettes(-1, 0x10, 0);
2018-02-07 18:47:55 +00:00
SetVBlankCallback(VBlankCB_RayquazaScene);
2018-02-01 10:17:07 +00:00
data[0] = 0;
data[1] = 0;
data[2] = CreateTask(sub_81D8AD8, 0);
2018-02-01 22:39:53 +00:00
gTasks[taskId].func = Task_HandleRayCharges;
2018-02-01 10:17:07 +00:00
}
2018-02-01 22:39:53 +00:00
static void Task_HandleRayCharges(u8 taskId)
2018-02-01 10:17:07 +00:00
{
s16 *data = gTasks[taskId].data;
sub_81D8BB4();
if ((data[3] & 7) == 0 && data[0] <= 1 && data[1] <= 89)
PlaySE(SE_OP_BASYU);
data[3]++;
switch (data[0])
{
case 0:
if (data[1] == 8)
{
2019-04-04 22:05:46 +01:00
BeginNormalPaletteFade(0xFFFFFFFF, 0, 0x10, 0, RGB_BLACK);
2018-02-01 10:17:07 +00:00
data[1] = 0;
data[0]++;
}
else
{
data[1]++;
}
break;
case 1:
if (data[1] == 127)
{
data[1] = 0;
data[0]++;
gTasks[data[2]].func = sub_81D8B2C;
}
else
{
data[1]++;
}
break;
case 2:
if (data[1] == 12)
{
data[1] = 0;
data[0]++;
}
else
{
data[1]++;
}
break;
case 3:
2019-04-04 22:05:46 +01:00
BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 0x10, RGB_BLACK);
2018-02-01 14:32:12 +00:00
gTasks[taskId].func = Task_RayChargesEnd;
2018-02-01 10:17:07 +00:00
break;
}
}
2020-08-25 22:49:42 +01:00
// These two, BG scrolling for Rayquaza charge
2018-02-01 13:47:41 +00:00
static void sub_81D8AD8(u8 taskId)
2018-02-01 10:17:07 +00:00
{
s16 *data = gTasks[taskId].data;
if ((data[15] & 3) == 0)
{
ChangeBgX(1, (Random() % 8 - 4) << 8, 0);
ChangeBgY(1, (Random() % 8 - 4) << 8, 0);
}
data[15]++;
}
2018-02-01 13:47:41 +00:00
static void sub_81D8B2C(u8 taskId)
2018-02-01 10:17:07 +00:00
{
s16 *data = gTasks[taskId].data;
if (data[0] == 0)
{
ChangeBgX(1, 0, 0);
ChangeBgY(1, 0, 0);
data[0]++;
data[1] = 10;
data[2] = -1;
}
else if (data[0] == 1)
{
ChangeBgX(1, data[1] << 8, 2);
ChangeBgY(1, data[1] << 8, 1);
data[1] += data[2];
if (data[1] == -10)
data[2] *= -1;
}
}
2018-02-01 13:47:41 +00:00
static void sub_81D8BB4(void)
2018-02-01 10:17:07 +00:00
{
ChangeBgX(2, 0x400, 2);
ChangeBgY(2, 0x400, 1);
ChangeBgX(0, 0x800, 2);
ChangeBgY(0, 0x800, 1);
}
2018-02-01 14:32:12 +00:00
static void Task_RayChargesEnd(u8 taskId)
2018-02-01 10:17:07 +00:00
{
s16 *data = gTasks[taskId].data;
sub_81D8BB4();
if (!gPaletteFade.active)
{
SetVBlankCallback(NULL);
sub_81D6904();
DestroyTask(data[2]);
gTasks[taskId].func = Task_SetNextAnim;
}
}
2018-02-01 13:47:41 +00:00
2020-08-26 21:31:37 +01:00
static void InitChasesAwaySceneBgs(void)
2018-02-01 13:47:41 +00:00
{
ResetVramOamAndBgCntRegs();
ResetBgsAndClearDma3BusyFlags(0);
2020-08-26 21:31:37 +01:00
InitBgsFromTemplates(1, sBgTemplates_ChasesAway, ARRAY_COUNT(sBgTemplates_ChasesAway));
2018-02-01 13:47:41 +00:00
SetBgTilemapBuffer(0, sRayScene->tilemapBuffers[0]);
SetBgTilemapBuffer(1, sRayScene->tilemapBuffers[1]);
SetBgTilemapBuffer(2, sRayScene->tilemapBuffers[2]);
ResetAllBgsCoordinates();
2020-05-14 09:37:09 +01:00
ScheduleBgCopyTilemapToVram(0);
ScheduleBgCopyTilemapToVram(1);
ScheduleBgCopyTilemapToVram(2);
2018-02-01 13:47:41 +00:00
SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_OBJ_ON | DISPCNT_OBJ_1D_MAP | DISPCNT_WIN0_ON);
ShowBg(0);
ShowBg(1);
ShowBg(2);
SetGpuReg(REG_OFFSET_BLDCNT, 0);
}
2020-08-26 21:31:37 +01:00
static void LoadChasesAwaySceneGfx(void)
2018-02-01 13:47:41 +00:00
{
2020-05-14 09:37:09 +01:00
ResetTempTileDataBuffers();
2020-08-26 21:31:37 +01:00
DecompressAndCopyTileDataToVram(2, gRaySceneChasesAway_Ring_Gfx, 0, 0, 0);
DecompressAndCopyTileDataToVram(0, gRaySceneChasesAway_Bg_Gfx, 0, 0, 0);
while (FreeTempTileDataBuffersIfPossible())
;
LZDecompressWram(gRaySceneChasesAway_Ring_Tilemap, sRayScene->tilemapBuffers[1]);
LZDecompressWram(gRaySceneChasesAway_Bg_Tilemap, sRayScene->tilemapBuffers[0]);
LZDecompressWram(gRaySceneChasesAway_Ring_Map, sRayScene->tilemapBuffers[2]);
LoadCompressedPalette(gRaySceneChasesAway_Bg_Pal, 0, 0x60);
LoadCompressedSpriteSheet(&sSpriteSheet_ChasesAway_Groudon);
LoadCompressedSpriteSheet(&sSpriteSheet_ChasesAway_GroudonTail);
LoadCompressedSpriteSheet(&sSpriteSheet_ChasesAway_Kyogre);
LoadCompressedSpriteSheet(&sSpriteSheet_ChasesAway_Rayquaza);
LoadCompressedSpriteSheet(&sSpriteSheet_ChasesAway_RayquazaTail);
LoadCompressedSpriteSheet(&sSpriteSheet_ChasesAway_KyogreSplash);
LoadCompressedSpritePalette(&sSpritePal_ChasesAway_Groudon);
LoadCompressedSpritePalette(&sSpritePal_ChasesAway_Kyogre);
LoadCompressedSpritePalette(&sSpritePal_ChasesAway_Rayquaza);
LoadCompressedSpritePalette(&sSpritePal_ChasesAway_KyogreSplash);
2018-02-01 13:47:41 +00:00
}
2018-02-01 13:53:27 +00:00
static void Task_RayChasesAwayAnim(u8 taskId)
2018-02-01 13:47:41 +00:00
{
s16 *data = gTasks[taskId].data;
2020-08-26 21:31:37 +01:00
InitChasesAwaySceneBgs();
LoadChasesAwaySceneGfx();
2018-02-01 13:47:41 +00:00
sub_81D68C8();
ClearGpuRegBits(REG_OFFSET_DISPCNT, DISPCNT_BG2_ON);
2018-02-07 18:47:55 +00:00
SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT1_BG0 | BLDCNT_TGT2_BG1 | BLDCNT_EFFECT_BLEND);
2018-12-26 13:03:48 +00:00
SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(9, 14));
2018-02-01 13:47:41 +00:00
BlendPalettes(-1, 0x10, 0);
2018-02-07 18:47:55 +00:00
SetVBlankCallback(VBlankCB_RayquazaScene);
2018-02-01 13:47:41 +00:00
data[0] = 0;
data[1] = 0;
2018-02-01 22:39:53 +00:00
gTasks[taskId].func = Task_HandleRayChasesAway;
2018-02-01 13:47:41 +00:00
data[2] = CreateTask(sub_81D8FB0, 0);
gTasks[data[2]].data[0] = 0;
gTasks[data[2]].data[1] = 0;
gTasks[data[2]].data[2] = 0;
gTasks[data[2]].data[3] = 1;
gTasks[data[2]].data[4] = 1;
}
2018-02-01 22:39:53 +00:00
static void Task_HandleRayChasesAway(u8 taskId)
2018-02-01 13:47:41 +00:00
{
s16 *data = gTasks[taskId].data;
switch (data[0])
{
case 0:
if (data[1] == 8)
{
sub_81D90A8(taskId);
2019-04-04 22:05:46 +01:00
BeginNormalPaletteFade(0xFFFFFFFF, 0, 0x10, 0, RGB_BLACK);
2018-02-01 13:47:41 +00:00
data[1] = 0;
data[0]++;
}
else
{
data[1]++;
}
break;
case 1:
if (gSprites[data[5]].callback == sub_81D97E0)
{
if (data[1] == 64)
{
sub_81D94D4(taskId);
sub_81D93D8(taskId);
data[1] = 0;
data[0]++;
}
else
{
data[1]++;
}
}
break;
case 2:
if (data[1] == 448)
{
data[1] = 0;
data[0]++;
}
else
{
data[1]++;
if (data[1] % 144 == 0)
{
2020-08-26 21:31:37 +01:00
BlendPalettesGradually(0x0000FFFE, 0, 16, 0, RGB_WHITEALPHA, 0, 0);
BlendPalettesGradually(0xFFFF0000, 0, 16, 0, RGB_BLACK, 0, 1);
2018-02-01 13:47:41 +00:00
}
}
break;
case 3:
2019-04-04 22:05:46 +01:00
BeginNormalPaletteFade(0xFFFFFFFF, 4, 0, 0x10, RGB_BLACK);
2018-02-01 14:32:12 +00:00
gTasks[taskId].func = Task_RayChasesAwayEnd;
2018-02-01 13:47:41 +00:00
break;
}
}
static void sub_81D8FB0(u8 taskId)
{
s16 *data = gTasks[taskId].data;
if ((data[0] & 0xF) == 0)
{
SetGpuReg(REG_OFFSET_BLDALPHA, ((data[1] + 14) << 8 & 0x1F00) | ((data[2] + 9) & 0xF));
data[1] -= data[3];
data[2] += data[4];
if (data[1] == -3 || data[1] == 0)
data[3] *= -1;
if (data[2] == 3 || data[2] == 0)
data[4] *= -1;
}
data[0]++;
}
2018-02-01 14:32:12 +00:00
static void Task_RayChasesAwayEnd(u8 taskId)
2018-02-01 13:47:41 +00:00
{
s16 *data = gTasks[taskId].data;
if (!gPaletteFade.active)
{
StopMapMusic();
if (data[1] == 0)
{
SetVBlankCallback(NULL);
sub_81D6904();
ResetSpriteData();
FreeAllSpritePalettes();
DestroyTask(data[2]);
}
if (data[1] == 32)
{
data[1] = 0;
gTasks[taskId].func = Task_SetNextAnim;
}
else
{
data[1]++;
}
}
}
static void sub_81D90A8(u8 taskId)
{
s16 *taskData, *spriteData;
taskData = gTasks[taskId].data;
2020-08-26 21:31:37 +01:00
taskData[3] = CreateSprite(&sSpriteTemplate_ChasesAway_Groudon, 64, 120, 0);
2018-02-01 13:47:41 +00:00
spriteData = gSprites[taskData[3]].data;
2020-08-26 21:31:37 +01:00
spriteData[0] = CreateSprite(&sSpriteTemplate_ChasesAway_GroudonTail, 16, 130, 0);
2018-02-01 13:47:41 +00:00
gSprites[taskData[3]].oam.priority = 1;
gSprites[spriteData[0]].oam.priority = 1;
2020-08-26 21:31:37 +01:00
taskData[4] = CreateSprite(&sSpriteTemplate_ChasesAway_Kyogre, 160, 128, 1);
2018-02-01 13:47:41 +00:00
spriteData = gSprites[taskData[4]].data;
2020-08-26 21:31:37 +01:00
spriteData[0] = CreateSprite(&sSpriteTemplate_ChasesAway_Kyogre, 192, 128, 1);
spriteData[1] = CreateSprite(&sSpriteTemplate_ChasesAway_Kyogre, 224, 128, 1);
2018-02-01 13:47:41 +00:00
gSprites[taskData[4]].oam.priority = 1;
gSprites[spriteData[0]].oam.priority = 1;
gSprites[spriteData[1]].oam.priority = 1;
StartSpriteAnim(&gSprites[spriteData[0]], 1);
StartSpriteAnim(&gSprites[spriteData[1]], 2);
2020-08-26 21:31:37 +01:00
taskData[5] = CreateSprite(&sSpriteTemplate_ChasesAway_Rayquaza, 120, -65, 0);
2018-02-01 13:47:41 +00:00
spriteData = gSprites[taskData[5]].data;
2020-08-26 21:31:37 +01:00
spriteData[0] = CreateSprite(&sSpriteTemplate_ChasesAway_RayquazaTail, 120, -113, 0);
2018-02-01 13:47:41 +00:00
gSprites[taskData[5]].oam.priority = 1;
gSprites[spriteData[0]].oam.priority = 1;
}
static void sub_81D9274(u8 taskId)
{
s16 *taskData = gTasks[taskId].data;
gSprites[taskData[3]].callback = sub_81D9338;
gSprites[taskData[3]].data[4] = 0;
gSprites[taskData[3]].data[5] = 0;
gSprites[taskData[3]].data[6] = 4;
gSprites[taskData[3]].data[7] = 0;
gSprites[taskData[4]].callback = sub_81D9338;
gSprites[taskData[4]].data[4] = 0;
gSprites[taskData[4]].data[5] = 0;
gSprites[taskData[4]].data[6] = 4;
gSprites[taskData[4]].data[7] = 1;
}
static void sub_81D9338(struct Sprite *sprite)
{
if ((sprite->data[4] & 7) == 0)
{
if (sprite->data[7] == 0)
{
sprite->pos1.x -= sprite->data[6];
gSprites[sprite->data[0]].pos1.x -= sprite->data[6];
}
else
{
sprite->pos1.x += sprite->data[6];
gSprites[sprite->data[0]].pos1.x += sprite->data[6];
gSprites[sprite->data[1]].pos1.x += sprite->data[6];
}
sprite->data[5]++;
sprite->data[6] -= sprite->data[5];
if (sprite->data[5] == 3)
{
sprite->data[4] = 0;
sprite->data[5] = 0;
sprite->data[6] = 0;
sprite->callback = SpriteCallbackDummy;
return;
}
}
sprite->data[4]++;
}
static void sub_81D93D8(u8 taskId)
{
s16 *taskData = gTasks[taskId].data;
gSprites[taskData[3]].callback = sub_81D9420;
StartSpriteAnim(&gSprites[taskData[3]], 1);
}
static void sub_81D9420(struct Sprite *sprite)
{
switch (sprite->animCmdIndex)
{
case 0:
case 2:
if (sprite->animDelayCounter % 12 == 0)
{
sprite->pos1.x -= 2;
gSprites[sprite->data[0]].pos1.x -=2;
}
gSprites[sprite->data[0]].pos2.y = 0;
break;
case 1:
case 3:
gSprites[sprite->data[0]].pos2.y = -2;
if ((sprite->animDelayCounter & 15) == 0)
{
sprite->pos1.y++;
gSprites[sprite->data[0]].pos1.y++;
}
break;
}
}
static void sub_81D94D4(u8 taskId)
{
s16 *taskData, *spriteData;
taskData = gTasks[taskId].data;
spriteData = gSprites[taskData[4]].data;
gSprites[taskData[4]].callback = sub_81D9528;
gSprites[spriteData[0]].callback = sub_81D9528;
gSprites[spriteData[1]].callback = sub_81D9528;
}
static void sub_81D9528(struct Sprite *sprite)
{
if ((sprite->data[4] & 3) == 0)
{
if (sprite->pos2.x == 1)
sprite->pos2.x = -1;
else
sprite->pos2.x = 1;
}
if (sprite->data[5] == 128)
{
2020-08-26 21:31:37 +01:00
sprite->data[7] = CreateSprite(&sSpriteTemplate_ChasesAway_KyogreSplash, 152, 132, 0);
2018-02-01 13:47:41 +00:00
gSprites[sprite->data[7]].oam.priority = 1;
2020-08-26 21:31:37 +01:00
sprite->data[7] = CreateSprite(&sSpriteTemplate_ChasesAway_KyogreSplash, 224, 132, 0);
2018-02-01 13:47:41 +00:00
gSprites[sprite->data[7]].oam.priority = 1;
gSprites[sprite->data[7]].hFlip = 1;
sprite->data[5]++;
}
if (sprite->data[5] > 127)
{
if (sprite->pos2.y != 32)
{
sprite->data[6]++;
sprite->pos2.y = sprite->data[6] >> 4;
}
}
else
{
sprite->data[5]++;
}
if (sprite->data[4] % 64 == 0)
PlaySE(SE_W250);
sprite->data[4]++;
}
2020-08-26 21:31:37 +01:00
static void SpriteCB_ChasesAway_Rayquaza(struct Sprite *sprite)
2018-02-01 13:47:41 +00:00
{
s16 counter = sprite->data[7];
if (counter <= 64)
{
sprite->pos2.y += 2;
gSprites[sprite->data[0]].pos2.y += 2;
if (sprite->data[7] == 64)
{
sub_81D9868(sprite, 1, 0, -48);
sprite->data[4] = 5;
sprite->data[5] = -1;
gSprites[sprite->data[0]].data[4] = 3;
gSprites[sprite->data[0]].data[5] = 5;
}
}
else if (counter <= 111)
{
sub_81D97E0(sprite);
if (sprite->data[4] == 0)
PlaySE(SE_BT_START);
if (sprite->data[4] == -3)
sub_81D9868(sprite, 2, 48, 16);
}
else if (counter == 112)
{
gSprites[sprite->data[0]].data[4] = 7;
gSprites[sprite->data[0]].data[5] = 3;
sub_81D97E0(sprite);
}
else if (counter <= 327)
{
sub_81D97E0(sprite);
}
else if (counter == 328)
{
sub_81D97E0(sprite);
sub_81D9868(sprite, 3, 48, 16);
sprite->pos2.x = 1;
gSprites[sprite->data[0]].pos2.x = 1;
PlayCry1(SPECIES_RAYQUAZA, 0);
CreateTask(sub_81D98B4, 0);
}
else
{
switch (counter)
{
case 376:
sprite->pos2.x = 0;
gSprites[sprite->data[0]].pos2.x = 0;
sub_81D97E0(sprite);
sub_81D9868(sprite, 2, 48, 16);
sprite->callback = sub_81D97E0;
return;
case 352:
2018-02-01 22:39:53 +00:00
sub_81D9274(FindTaskIdByFunc(Task_HandleRayChasesAway));
2018-02-01 13:47:41 +00:00
break;
}
}
if (sprite->data[7] > 328 && (sprite->data[7] & 1) == 0)
{
sprite->pos2.x *= -1;
gSprites[sprite->data[0]].pos2.x = sprite->pos2.x;
}
sprite->data[7]++;
}
static void sub_81D97E0(struct Sprite *sprite)
{
struct Sprite *sprite2 = &gSprites[sprite->data[0]];
if (!(sprite->data[6] & sprite2->data[4]))
{
sprite->pos2.y += sprite->data[4];
gSprites[sprite->data[0]].pos2.y += sprite->data[4];
sprite->data[4] += sprite->data[5];
if (sprite->data[4] >= sprite2->data[5] || sprite->data[4] <= -sprite2->data[5])
{
if (sprite->data[4] > sprite2->data[5])
sprite->data[4] = sprite2->data[5];
else if (sprite->data[4] < -sprite2->data[5])
sprite->data[4] = -sprite2->data[5];
sprite->data[5] *= -1;
}
}
sprite->data[6]++;
}
static void sub_81D9868(struct Sprite *sprite, u8 animNum, s16 x, s16 y)
{
struct Sprite *sprite2 = &gSprites[sprite->data[0]];
sprite2->pos1.x = sprite->pos1.x + x;
sprite2->pos1.y = sprite->pos1.y + y;
sprite2->pos2.x = sprite->pos2.x;
sprite2->pos2.y = sprite->pos2.y;
StartSpriteAnim(sprite, animNum);
StartSpriteAnim(sprite2, animNum);
}
static void sub_81D98B4(u8 taskId)
{
s16 *data = gTasks[taskId].data;
switch (data[0])
{
case 0:
SetBgAffine(2, 0x4000, 0x4000, 0x78, 0x40, 0x100, 0x100, 0);
SetGpuRegBits(REG_OFFSET_DISPCNT, DISPCNT_BG2_ON);
data[4] = 16;
data[0]++;
break;
case 1:
if (data[5] == 8)
PlaySE(SE_JIDO_DOA);
if (data[2] == 2)
{
data[0]++;
}
else
{
data[1] += data[4];
data[5]++;
if (data[3] % 3 == 0 && data[4] != 4)
data[4] -= 2;
data[3]++;
SetBgAffine(2, 0x4000, 0x4000, 0x78, 0x40, 0x100 - data[1], 0x100 - data[1], 0);
if (data[1] > 255)
{
data[1] = 0;
data[3] = 0;
data[5] = 0;
data[4] = 16;
data[2]++;
}
}
break;
case 2:
ClearGpuRegBits(REG_OFFSET_DISPCNT, DISPCNT_BG2_ON);
DestroyTask(taskId);
break;
}
}