2017-10-03 03:51:22 +02:00
|
|
|
#include "global.h"
|
2018-05-10 10:02:33 +02:00
|
|
|
#include "decompress.h"
|
2018-10-17 02:11:44 +02:00
|
|
|
#include "event_object_movement.h"
|
2018-05-11 01:36:57 +02:00
|
|
|
#include "field_camera.h"
|
2018-11-13 15:19:04 +01:00
|
|
|
#include "field_control_avatar.h"
|
2018-10-17 02:11:44 +02:00
|
|
|
#include "field_effect.h"
|
2018-05-11 01:36:57 +02:00
|
|
|
#include "field_effect_helpers.h"
|
|
|
|
#include "field_player_avatar.h"
|
2018-12-08 22:05:11 +01:00
|
|
|
#include "field_screen_effect.h"
|
2018-05-10 10:02:33 +02:00
|
|
|
#include "field_weather.h"
|
2018-05-11 01:36:57 +02:00
|
|
|
#include "fieldmap.h"
|
2018-12-24 21:59:05 +01:00
|
|
|
#include "fldeff.h"
|
2018-05-11 01:36:57 +02:00
|
|
|
#include "gpu_regs.h"
|
|
|
|
#include "main.h"
|
2018-12-25 18:02:41 +01:00
|
|
|
#include "mirage_tower.h"
|
2018-05-11 01:36:57 +02:00
|
|
|
#include "menu.h"
|
|
|
|
#include "metatile_behavior.h"
|
|
|
|
#include "overworld.h"
|
2018-05-10 10:02:33 +02:00
|
|
|
#include "palette.h"
|
2018-05-11 01:36:57 +02:00
|
|
|
#include "party_menu.h"
|
2018-05-10 10:02:33 +02:00
|
|
|
#include "pokemon.h"
|
2018-05-11 01:36:57 +02:00
|
|
|
#include "script.h"
|
2018-05-10 10:02:33 +02:00
|
|
|
#include "sound.h"
|
|
|
|
#include "sprite.h"
|
|
|
|
#include "task.h"
|
2018-10-17 02:11:44 +02:00
|
|
|
#include "trainer_pokemon_sprites.h"
|
2018-05-11 01:36:57 +02:00
|
|
|
#include "trig.h"
|
|
|
|
#include "util.h"
|
2018-11-13 15:19:04 +01:00
|
|
|
#include "constants/field_effects.h"
|
2019-11-21 20:03:35 +01:00
|
|
|
#include "constants/event_object_movement.h"
|
2019-12-17 09:24:44 +01:00
|
|
|
#include "constants/metatile_behaviors.h"
|
2018-05-10 10:02:33 +02:00
|
|
|
#include "constants/rgb.h"
|
|
|
|
#include "constants/songs.h"
|
2017-10-03 03:51:22 +02:00
|
|
|
|
2018-05-11 01:36:57 +02:00
|
|
|
#define subsprite_table(ptr) {.subsprites = ptr, .subspriteCount = (sizeof ptr) / (sizeof(struct Subsprite))}
|
|
|
|
|
|
|
|
EWRAM_DATA s32 gFieldEffectArguments[8] = {0};
|
|
|
|
|
2017-10-03 03:51:22 +02:00
|
|
|
// Static type declarations
|
|
|
|
|
2018-11-13 15:19:04 +01:00
|
|
|
static void Task_PokecenterHeal(u8 taskId);
|
2020-06-24 22:27:00 +02:00
|
|
|
static void PokecenterHealEffect_Init(struct Task *);
|
|
|
|
static void PokecenterHealEffect_WaitForBallPlacement(struct Task *);
|
|
|
|
static void PokecenterHealEffect_WaitForBallFlashing(struct Task *);
|
|
|
|
static void PokecenterHealEffect_WaitForSoundAndEnd(struct Task *);
|
|
|
|
static u8 CreatePokecenterMonitorSprite(s16, s16);
|
|
|
|
static void SpriteCB_PokecenterMonitor(struct Sprite *);
|
2018-11-13 15:19:04 +01:00
|
|
|
|
|
|
|
static void Task_HallOfFameRecord(u8 taskId);
|
2020-06-24 22:27:00 +02:00
|
|
|
static void HallOfFameRecordEffect_Init(struct Task *);
|
|
|
|
static void HallOfFameRecordEffect_WaitForBallPlacement(struct Task *);
|
|
|
|
static void HallOfFameRecordEffect_WaitForBallFlashing(struct Task *);
|
|
|
|
static void HallOfFameRecordEffect_WaitForSoundAndEnd(struct Task *);
|
|
|
|
static void CreateHofMonitorSprite(s16, s16, s16, bool8);
|
|
|
|
static void SpriteCB_HallOfFameMonitor(struct Sprite *);
|
|
|
|
|
|
|
|
static u8 CreateGlowingPokeballsEffect(s16, s16, s16, bool16);
|
2018-11-13 15:19:04 +01:00
|
|
|
static void SpriteCB_PokeballGlowEffect(struct Sprite *);
|
2020-06-24 22:27:00 +02:00
|
|
|
static void PokeballGlowEffect_PlaceBalls(struct Sprite *);
|
|
|
|
static void PokeballGlowEffect_TryPlaySe(struct Sprite *);
|
|
|
|
static void PokeballGlowEffect_Flash1(struct Sprite *);
|
|
|
|
static void PokeballGlowEffect_Flash2(struct Sprite *);
|
|
|
|
static void PokeballGlowEffect_WaitAfterFlash(struct Sprite *);
|
|
|
|
static void PokeballGlowEffect_Dummy(struct Sprite *);
|
|
|
|
static void PokeballGlowEffect_WaitForSound(struct Sprite *);
|
|
|
|
static void PokeballGlowEffect_Idle(struct Sprite *);
|
|
|
|
static void SpriteCB_PokeballGlow(struct Sprite *);
|
2018-11-13 15:19:04 +01:00
|
|
|
|
2020-06-20 01:58:56 +02:00
|
|
|
static void FieldCallback_UseFly(void);
|
|
|
|
static void Task_UseFly(u8);
|
|
|
|
static void FieldCallback_FlyIntoMap(void);
|
|
|
|
static void Task_FlyIntoMap(u8);
|
2018-11-13 15:19:04 +01:00
|
|
|
|
2019-12-17 09:24:44 +01:00
|
|
|
static void Task_FallWarpFieldEffect(u8);
|
2020-06-24 22:27:00 +02:00
|
|
|
static bool8 FallWarpEffect_Init(struct Task *);
|
|
|
|
static bool8 FallWarpEffect_WaitWeather(struct Task *);
|
|
|
|
static bool8 FallWarpEffect_StartFall(struct Task *);
|
|
|
|
static bool8 FallWarpEffect_Fall(struct Task *);
|
|
|
|
static bool8 FallWarpEffect_Land(struct Task *);
|
|
|
|
static bool8 FallWarpEffect_CameraShake(struct Task *);
|
|
|
|
static bool8 FallWarpEffect_End(struct Task *);
|
2019-12-17 09:24:44 +01:00
|
|
|
|
2020-06-20 01:58:56 +02:00
|
|
|
static void Task_EscalatorWarpOut(u8);
|
2020-06-24 22:27:00 +02:00
|
|
|
static bool8 EscalatorWarpOut_Init(struct Task *);
|
|
|
|
static bool8 EscalatorWarpOut_WaitForPlayer(struct Task *);
|
|
|
|
static bool8 EscalatorWarpOut_Up_Ride(struct Task *);
|
|
|
|
static bool8 EscalatorWarpOut_Up_End(struct Task *);
|
|
|
|
static bool8 EscalatorWarpOut_Down_Ride(struct Task *);
|
|
|
|
static bool8 EscalatorWarpOut_Down_End(struct Task *);
|
|
|
|
static void RideUpEscalatorOut(struct Task *);
|
|
|
|
static void RideDownEscalatorOut(struct Task *);
|
|
|
|
static void FadeOutAtEndOfEscalator(void);
|
|
|
|
static void WarpAtEndOfEscalator(void);
|
2020-06-20 01:58:56 +02:00
|
|
|
|
|
|
|
static void FieldCallback_EscalatorWarpIn(void);
|
|
|
|
static void Task_EscalatorWarpIn(u8);
|
2020-06-24 22:27:00 +02:00
|
|
|
static bool8 EscalatorWarpIn_Init(struct Task *);
|
|
|
|
static bool8 EscalatorWarpIn_Down_Init(struct Task *);
|
|
|
|
static bool8 EscalatorWarpIn_Down_Ride(struct Task *);
|
|
|
|
static bool8 EscalatorWarpIn_Up_Init(struct Task *);
|
|
|
|
static bool8 EscalatorWarpIn_Up_Ride(struct Task *);
|
|
|
|
static bool8 EscalatorWarpIn_WaitForMovement(struct Task *);
|
|
|
|
static bool8 EscalatorWarpIn_End(struct Task *);
|
2020-06-20 01:58:56 +02:00
|
|
|
|
|
|
|
static void Task_UseWaterfall(u8);
|
2020-06-24 22:27:00 +02:00
|
|
|
static bool8 WaterfallFieldEffect_Init(struct Task *, struct ObjectEvent *);
|
|
|
|
static bool8 WaterfallFieldEffect_ShowMon(struct Task *, struct ObjectEvent *);
|
|
|
|
static bool8 WaterfallFieldEffect_WaitForShowMon(struct Task *, struct ObjectEvent *);
|
|
|
|
static bool8 WaterfallFieldEffect_RideUp(struct Task *, struct ObjectEvent *);
|
|
|
|
static bool8 WaterfallFieldEffect_ContinueRideOrEnd(struct Task *, struct ObjectEvent *);
|
2020-06-20 01:58:56 +02:00
|
|
|
|
|
|
|
static void Task_UseDive(u8);
|
2020-06-24 22:27:00 +02:00
|
|
|
static bool8 DiveFieldEffect_Init(struct Task *);
|
|
|
|
static bool8 DiveFieldEffect_ShowMon(struct Task *);
|
|
|
|
static bool8 DiveFieldEffect_TryWarp(struct Task *);
|
2018-11-13 15:19:04 +01:00
|
|
|
|
2019-12-17 09:24:44 +01:00
|
|
|
static void Task_LavaridgeGymB1FWarp(u8);
|
2020-06-24 22:27:00 +02:00
|
|
|
static bool8 LavaridgeGymB1FWarpEffect_Init(struct Task *, struct ObjectEvent *, struct Sprite *);
|
|
|
|
static bool8 LavaridgeGymB1FWarpEffect_CameraShake(struct Task *, struct ObjectEvent *, struct Sprite *);
|
|
|
|
static bool8 LavaridgeGymB1FWarpEffect_Launch(struct Task *, struct ObjectEvent *, struct Sprite *);
|
|
|
|
static bool8 LavaridgeGymB1FWarpEffect_Rise(struct Task *, struct ObjectEvent *, struct Sprite *);
|
|
|
|
static bool8 LavaridgeGymB1FWarpEffect_FadeOut(struct Task *, struct ObjectEvent *, struct Sprite *);
|
|
|
|
static bool8 LavaridgeGymB1FWarpEffect_Warp(struct Task *, struct ObjectEvent *, struct Sprite *);
|
2019-12-17 09:24:44 +01:00
|
|
|
|
|
|
|
static void FieldCB_LavaridgeGymB1FWarpExit(void);
|
|
|
|
static void Task_LavaridgeGymB1FWarpExit(u8);
|
2020-06-24 22:27:00 +02:00
|
|
|
static bool8 LavaridgeGymB1FWarpExitEffect_Init(struct Task *, struct ObjectEvent *, struct Sprite *);
|
|
|
|
static bool8 LavaridgeGymB1FWarpExitEffect_StartPopOut(struct Task *, struct ObjectEvent *, struct Sprite *);
|
|
|
|
static bool8 LavaridgeGymB1FWarpExitEffect_PopOut(struct Task *, struct ObjectEvent *, struct Sprite *);
|
|
|
|
static bool8 LavaridgeGymB1FWarpExitEffect_End(struct Task *, struct ObjectEvent *, struct Sprite *);
|
2019-12-17 09:24:44 +01:00
|
|
|
|
|
|
|
static void Task_LavaridgeGym1FWarp(u8);
|
2020-06-24 22:27:00 +02:00
|
|
|
static bool8 LavaridgeGym1FWarpEffect_Init(struct Task *, struct ObjectEvent *, struct Sprite *);
|
|
|
|
static bool8 LavaridgeGym1FWarpEffect_AshPuff(struct Task *, struct ObjectEvent *, struct Sprite *);
|
|
|
|
static bool8 LavaridgeGym1FWarpEffect_Disappear(struct Task *, struct ObjectEvent *, struct Sprite *);
|
|
|
|
static bool8 LavaridgeGym1FWarpEffect_FadeOut(struct Task *, struct ObjectEvent *, struct Sprite *);
|
|
|
|
static bool8 LavaridgeGym1FWarpEffect_Warp(struct Task *, struct ObjectEvent *, struct Sprite *);
|
2018-11-13 15:19:04 +01:00
|
|
|
|
2020-06-20 01:58:56 +02:00
|
|
|
static void Task_EscapeRopeWarpOut(u8);
|
2020-06-24 22:27:00 +02:00
|
|
|
static void EscapeRopeWarpOutEffect_Init(struct Task *);
|
|
|
|
static void EscapeRopeWarpOutEffect_Spin(struct Task *);
|
2020-06-20 01:58:56 +02:00
|
|
|
|
|
|
|
static void FieldCallback_EscapeRopeWarpIn(void);
|
|
|
|
static void Task_EscapeRopeWarpIn(u8);
|
2020-06-24 22:27:00 +02:00
|
|
|
static void EscapeRopeWarpInEffect_Init(struct Task *);
|
|
|
|
static void EscapeRopeWarpInEffect_Spin(struct Task *);
|
2020-06-20 01:58:56 +02:00
|
|
|
|
|
|
|
static void Task_TeleportWarpOut(u8);
|
2020-06-24 22:27:00 +02:00
|
|
|
static void TeleportWarpOutFieldEffect_Init(struct Task*);
|
|
|
|
static void TeleportWarpOutFieldEffect_SpinGround(struct Task*);
|
|
|
|
static void TeleportWarpOutFieldEffect_SpinExit(struct Task*);
|
|
|
|
static void TeleportWarpOutFieldEffect_End(struct Task*);
|
2020-06-20 01:58:56 +02:00
|
|
|
|
|
|
|
static void FieldCallback_TeleportWarpIn(void);
|
|
|
|
static void Task_TeleportWarpIn(u8);
|
2020-06-24 22:27:00 +02:00
|
|
|
static void TeleportWarpInFieldEffect_Init(struct Task *);
|
|
|
|
static void TeleportWarpInFieldEffect_SpinEnter(struct Task *);
|
|
|
|
static void TeleportWarpInFieldEffect_SpinGround(struct Task *);
|
2020-06-20 01:58:56 +02:00
|
|
|
|
|
|
|
static void Task_FieldMoveShowMonOutdoors(u8);
|
2020-06-24 22:27:00 +02:00
|
|
|
static void FieldMoveShowMonOutdoorsEffect_Init(struct Task *);
|
|
|
|
static void FieldMoveShowMonOutdoorsEffect_LoadGfx(struct Task *);
|
|
|
|
static void FieldMoveShowMonOutdoorsEffect_CreateBanner(struct Task *);
|
|
|
|
static void FieldMoveShowMonOutdoorsEffect_WaitForMon(struct Task *);
|
|
|
|
static void FieldMoveShowMonOutdoorsEffect_ShrinkBanner(struct Task *);
|
|
|
|
static void FieldMoveShowMonOutdoorsEffect_RestoreBg(struct Task *);
|
|
|
|
static void FieldMoveShowMonOutdoorsEffect_End(struct Task *);
|
2020-06-20 01:58:56 +02:00
|
|
|
static void VBlankCB_FieldMoveShowMonOutdoors(void);
|
2020-06-24 22:27:00 +02:00
|
|
|
static void LoadFieldMoveOutdoorStreaksTilemap(u16);
|
2018-11-13 15:19:04 +01:00
|
|
|
|
2020-06-20 01:58:56 +02:00
|
|
|
static void Task_FieldMoveShowMonIndoors(u8);
|
2020-06-24 22:27:00 +02:00
|
|
|
static void FieldMoveShowMonIndoorsEffect_Init(struct Task *);
|
|
|
|
static void FieldMoveShowMonIndoorsEffect_LoadGfx(struct Task *);
|
|
|
|
static void FieldMoveShowMonIndoorsEffect_SlideBannerOn(struct Task *);
|
|
|
|
static void FieldMoveShowMonIndoorsEffect_WaitForMon(struct Task *);
|
|
|
|
static void FieldMoveShowMonIndoorsEffect_RestoreBg(struct Task *);
|
|
|
|
static void FieldMoveShowMonIndoorsEffect_SlideBannerOff(struct Task *);
|
|
|
|
static void FieldMoveShowMonIndoorsEffect_End(struct Task *);
|
2020-06-20 01:58:56 +02:00
|
|
|
static void VBlankCB_FieldMoveShowMonIndoors(void);
|
2020-06-24 22:27:00 +02:00
|
|
|
static void AnimateIndoorShowMonBg(struct Task *);
|
|
|
|
static bool8 SlideIndoorBannerOnscreen(struct Task *);
|
|
|
|
static bool8 SlideIndoorBannerOffscreen(struct Task *);
|
2018-11-13 15:19:04 +01:00
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static u8 InitFieldMoveMonSprite(u32, u32, u32);
|
|
|
|
static void SpriteCB_FieldMoveMonSlideOnscreen(struct Sprite *);
|
|
|
|
static void SpriteCB_FieldMoveMonWaitAfterCry(struct Sprite *);
|
|
|
|
static void SpriteCB_FieldMoveMonSlideOffscreen(struct Sprite *);
|
2018-11-13 15:19:04 +01:00
|
|
|
|
2020-06-20 01:58:56 +02:00
|
|
|
static void Task_SurfFieldEffect(u8);
|
2020-06-24 22:27:00 +02:00
|
|
|
static void SurfFieldEffect_Init(struct Task *);
|
|
|
|
static void SurfFieldEffect_FieldMovePose(struct Task *);
|
|
|
|
static void SurfFieldEffect_ShowMon(struct Task *);
|
|
|
|
static void SurfFieldEffect_JumpOnSurfBlob(struct Task *);
|
|
|
|
static void SurfFieldEffect_End(struct Task *);
|
2020-06-20 01:58:56 +02:00
|
|
|
|
|
|
|
static void SpriteCB_NPCFlyOut(struct Sprite *);
|
|
|
|
|
|
|
|
static void Task_FlyOut(u8);
|
2020-06-24 22:27:00 +02:00
|
|
|
static void FlyOutFieldEffect_FieldMovePose(struct Task *);
|
|
|
|
static void FlyOutFieldEffect_ShowMon(struct Task *);
|
|
|
|
static void FlyOutFieldEffect_BirdLeaveBall(struct Task *);
|
|
|
|
static void FlyOutFieldEffect_WaitBirdLeave(struct Task *);
|
|
|
|
static void FlyOutFieldEffect_BirdSwoopDown(struct Task *);
|
|
|
|
static void FlyOutFieldEffect_JumpOnBird(struct Task *);
|
|
|
|
static void FlyOutFieldEffect_FlyOffWithBird(struct Task *);
|
|
|
|
static void FlyOutFieldEffect_WaitFlyOff(struct Task *);
|
|
|
|
static void FlyOutFieldEffect_End(struct Task *);
|
|
|
|
|
|
|
|
static u8 CreateFlyBirdSprite(void);
|
|
|
|
static u8 GetFlyBirdAnimCompleted(u8);
|
|
|
|
static void StartFlyBirdSwoopDown(u8);
|
|
|
|
static void SetFlyBirdPlayerSpriteId(u8, u8);
|
|
|
|
static void SpriteCB_FlyBirdLeaveBall(struct Sprite *);
|
|
|
|
static void SpriteCB_FlyBirdSwoopDown(struct Sprite *);
|
2018-11-13 15:19:04 +01:00
|
|
|
|
2020-06-20 01:58:56 +02:00
|
|
|
static void Task_FlyIn(u8);
|
2020-06-24 22:27:00 +02:00
|
|
|
static void FlyInFieldEffect_BirdSwoopDown(struct Task *);
|
|
|
|
static void FlyInFieldEffect_FlyInWithBird(struct Task *);
|
|
|
|
static void FlyInFieldEffect_JumpOffBird(struct Task *);
|
|
|
|
static void FlyInFieldEffect_FieldMovePose(struct Task *);
|
|
|
|
static void FlyInFieldEffect_BirdReturnToBall(struct Task *);
|
|
|
|
static void FlyInFieldEffect_WaitBirdReturn(struct Task *);
|
|
|
|
static void FlyInFieldEffect_End(struct Task *);
|
2020-06-20 01:58:56 +02:00
|
|
|
|
|
|
|
static void Task_DestroyDeoxysRock(u8 taskId);
|
2020-06-24 22:27:00 +02:00
|
|
|
static void DestroyDeoxysRockEffect_CameraShake(s16*, u8);
|
|
|
|
static void DestroyDeoxysRockEffect_RockFragments(s16*, u8);
|
|
|
|
static void DestroyDeoxysRockEffect_WaitAndEnd(s16*, u8);
|
|
|
|
static void CreateDeoxysRockFragments(struct Sprite*);
|
|
|
|
static void SpriteCB_DeoxysRockFragment(struct Sprite* sprite);
|
2018-11-13 15:19:04 +01:00
|
|
|
|
2020-06-20 01:58:56 +02:00
|
|
|
static void Task_MoveDeoxysRock(u8 taskId);
|
|
|
|
|
2017-10-03 03:51:22 +02:00
|
|
|
// Static RAM declarations
|
|
|
|
|
2019-06-26 22:23:00 +02:00
|
|
|
static u8 sActiveList[32];
|
2017-10-03 03:51:22 +02:00
|
|
|
|
2018-11-13 15:19:04 +01:00
|
|
|
// External declarations
|
2019-04-04 23:53:06 +02:00
|
|
|
extern struct CompressedSpritePalette gMonPaletteTable[]; // GF made a mistake and did not extern it as const.
|
|
|
|
extern const struct CompressedSpritePalette gTrainerFrontPicPaletteTable[];
|
|
|
|
extern const struct CompressedSpriteSheet gTrainerFrontPicTable[];
|
2018-05-10 10:02:33 +02:00
|
|
|
extern u8 *gFieldEffectScriptPointers[];
|
2018-11-13 15:19:04 +01:00
|
|
|
extern const struct SpriteTemplate *const gFieldEffectObjectTemplatePointers[];
|
2018-05-10 10:02:33 +02:00
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static const u32 sNewGameBirch_Gfx[] = INCBIN_U32("graphics/birch_speech/birch.4bpp");
|
|
|
|
static const u32 sUnusedBirchBeauty[] = INCBIN_U32("graphics/unused/intro_birch_beauty.4bpp");
|
|
|
|
static const u16 sNewGameBirch_Pal[16] = INCBIN_U16("graphics/birch_speech/birch.gbapal");
|
|
|
|
static const u32 sPokeballGlow_Gfx[] = INCBIN_U32("graphics/misc/pokeball_glow.4bpp");
|
2020-07-02 10:59:52 +02:00
|
|
|
static const u16 sPokeballGlow_Pal[16] = INCBIN_U16("graphics/field_effects/palettes/pokeball_glow.gbapal");
|
2020-06-24 22:27:00 +02:00
|
|
|
static const u32 sPokecenterMonitor0_Gfx[] = INCBIN_U32("graphics/misc/pokecenter_monitor/0.4bpp");
|
|
|
|
static const u32 sPokecenterMonitor1_Gfx[] = INCBIN_U32("graphics/misc/pokecenter_monitor/1.4bpp");
|
|
|
|
static const u32 sHofMonitorBig_Gfx[] = INCBIN_U32("graphics/misc/hof_monitor_big.4bpp");
|
|
|
|
static const u8 sHofMonitorSmall_Gfx[] = INCBIN_U8("graphics/misc/hof_monitor_small.4bpp");
|
2020-07-02 10:59:52 +02:00
|
|
|
static const u16 sHofMonitor_Pal[16] = INCBIN_U16("graphics/field_effects/palettes/hof_monitor.gbapal");
|
2018-05-11 01:36:57 +02:00
|
|
|
|
|
|
|
// Graphics for the lights streaking past your Pokemon when it uses a field move.
|
2020-06-24 22:27:00 +02:00
|
|
|
static const u32 sFieldMoveStreaksOutdoors_Gfx[] = INCBIN_U32("graphics/misc/field_move_streaks.4bpp");
|
|
|
|
static const u16 sFieldMoveStreaksOutdoors_Pal[16] = INCBIN_U16("graphics/misc/field_move_streaks.gbapal");
|
|
|
|
static const u16 sFieldMoveStreaksOutdoors_Tilemap[320] = INCBIN_U16("graphics/misc/field_move_streaks_map.bin");
|
|
|
|
|
|
|
|
// The following light streaks effect is used when the map is indoors
|
|
|
|
static const u32 sFieldMoveStreaksIndoors_Gfx[] = INCBIN_U32("graphics/misc/darkness_field_move_streaks.4bpp");
|
|
|
|
static const u16 sFieldMoveStreaksIndoors_Pal[16] = INCBIN_U16("graphics/misc/darkness_field_move_streaks.gbapal");
|
|
|
|
static const u16 sFieldMoveStreaksIndoors_Tilemap[320] = INCBIN_U16("graphics/misc/darkness_field_move_streaks_map.bin");
|
|
|
|
|
|
|
|
static const u16 sSpotlight_Pal[16] = INCBIN_U16("graphics/misc/spotlight.gbapal");
|
|
|
|
static const u8 sSpotlight_Gfx[] = INCBIN_U8("graphics/misc/spotlight.4bpp");
|
|
|
|
static const u8 sRockFragment_TopLeft[] = INCBIN_U8("graphics/misc/deoxys_rock_fragment_top_left.4bpp");
|
|
|
|
static const u8 sRockFragment_TopRight[] = INCBIN_U8("graphics/misc/deoxys_rock_fragment_top_right.4bpp");
|
|
|
|
static const u8 sRockFragment_BottomLeft[] = INCBIN_U8("graphics/misc/deoxys_rock_fragment_bottom_left.4bpp");
|
|
|
|
static const u8 sRockFragment_BottomRight[] = INCBIN_U8("graphics/misc/deoxys_rock_fragment_bottom_right.4bpp");
|
2018-05-11 01:36:57 +02:00
|
|
|
|
2019-03-11 08:12:15 +01:00
|
|
|
bool8 (*const gFieldEffectScriptFuncs[])(u8 **, u32 *) =
|
|
|
|
{
|
2018-05-11 01:36:57 +02:00
|
|
|
FieldEffectCmd_loadtiles,
|
|
|
|
FieldEffectCmd_loadfadedpal,
|
|
|
|
FieldEffectCmd_loadpal,
|
|
|
|
FieldEffectCmd_callnative,
|
|
|
|
FieldEffectCmd_end,
|
|
|
|
FieldEffectCmd_loadgfx_callnative,
|
|
|
|
FieldEffectCmd_loadtiles_callnative,
|
|
|
|
FieldEffectCmd_loadfadedpal_callnative,
|
|
|
|
};
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static const struct OamData sOam_64x64 =
|
2019-03-11 08:12:15 +01:00
|
|
|
{
|
2019-04-02 00:31:10 +02:00
|
|
|
.y = 0,
|
|
|
|
.affineMode = ST_OAM_AFFINE_OFF,
|
|
|
|
.objMode = ST_OAM_OBJ_NORMAL,
|
|
|
|
.bpp = ST_OAM_4BPP,
|
2019-03-11 08:12:15 +01:00
|
|
|
.shape = SPRITE_SHAPE(64x64),
|
2019-04-02 00:31:10 +02:00
|
|
|
.x = 0,
|
|
|
|
.size = SPRITE_SIZE(64x64),
|
|
|
|
.tileNum = 0,
|
|
|
|
.priority = 0,
|
|
|
|
.paletteNum = 0,
|
2019-03-11 08:12:15 +01:00
|
|
|
};
|
2018-05-11 01:36:57 +02:00
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static const struct OamData sOam_8x8 =
|
2019-03-11 08:12:15 +01:00
|
|
|
{
|
2019-04-02 00:31:10 +02:00
|
|
|
.y = 0,
|
|
|
|
.affineMode = ST_OAM_AFFINE_OFF,
|
|
|
|
.objMode = ST_OAM_OBJ_NORMAL,
|
|
|
|
.bpp = ST_OAM_4BPP,
|
2019-03-11 08:12:15 +01:00
|
|
|
.shape = SPRITE_SHAPE(8x8),
|
2019-04-02 00:31:10 +02:00
|
|
|
.x = 0,
|
|
|
|
.size = SPRITE_SIZE(8x8),
|
|
|
|
.tileNum = 0,
|
|
|
|
.priority = 0,
|
|
|
|
.paletteNum = 0,
|
2019-03-11 08:12:15 +01:00
|
|
|
};
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static const struct OamData sOam_16x16 =
|
2019-03-11 08:12:15 +01:00
|
|
|
{
|
2019-04-02 00:31:10 +02:00
|
|
|
.y = 0,
|
|
|
|
.affineMode = ST_OAM_AFFINE_OFF,
|
|
|
|
.objMode = ST_OAM_OBJ_NORMAL,
|
|
|
|
.bpp = ST_OAM_4BPP,
|
2019-03-11 08:12:15 +01:00
|
|
|
.shape = SPRITE_SHAPE(16x16),
|
2019-04-02 00:31:10 +02:00
|
|
|
.x = 0,
|
|
|
|
.size = SPRITE_SIZE(16x16),
|
|
|
|
.tileNum = 0,
|
|
|
|
.priority = 0,
|
|
|
|
.paletteNum = 0,
|
2019-03-11 08:12:15 +01:00
|
|
|
};
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static const struct SpriteFrameImage sPicTable_NewGameBirch[] =
|
2019-03-11 08:12:15 +01:00
|
|
|
{
|
2020-06-24 22:27:00 +02:00
|
|
|
obj_frame_tiles(sNewGameBirch_Gfx)
|
2018-05-11 01:36:57 +02:00
|
|
|
};
|
2017-10-03 03:51:22 +02:00
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static const struct SpritePalette sSpritePalette_NewGameBirch =
|
2019-03-11 08:12:15 +01:00
|
|
|
{
|
2020-06-24 22:27:00 +02:00
|
|
|
.data = sNewGameBirch_Pal,
|
2020-07-02 10:59:52 +02:00
|
|
|
.tag = 0x1006
|
2019-03-11 08:12:15 +01:00
|
|
|
};
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static const union AnimCmd sAnim_NewGameBirch[] =
|
2019-03-11 08:12:15 +01:00
|
|
|
{
|
2018-05-11 01:36:57 +02:00
|
|
|
ANIMCMD_FRAME(.imageValue = 0, .duration = 1),
|
|
|
|
ANIMCMD_END
|
|
|
|
};
|
2018-05-10 10:02:33 +02:00
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static const union AnimCmd *const sAnimTable_NewGameBirch[] =
|
2019-03-11 08:12:15 +01:00
|
|
|
{
|
2020-06-24 22:27:00 +02:00
|
|
|
sAnim_NewGameBirch
|
2018-05-11 01:36:57 +02:00
|
|
|
};
|
2018-05-10 10:02:33 +02:00
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static const struct SpriteTemplate sSpriteTemplate_NewGameBirch =
|
2019-03-11 08:12:15 +01:00
|
|
|
{
|
2021-09-14 19:14:14 +02:00
|
|
|
.tileTag = TAG_NONE,
|
2020-07-02 10:59:52 +02:00
|
|
|
.paletteTag = 0x1006,
|
2020-06-24 22:27:00 +02:00
|
|
|
.oam = &sOam_64x64,
|
|
|
|
.anims = sAnimTable_NewGameBirch,
|
|
|
|
.images = sPicTable_NewGameBirch,
|
2018-05-11 01:36:57 +02:00
|
|
|
.affineAnims = gDummySpriteAffineAnimTable,
|
|
|
|
.callback = SpriteCallbackDummy
|
|
|
|
};
|
|
|
|
|
2020-07-02 10:59:52 +02:00
|
|
|
const struct SpritePalette gSpritePalette_PokeballGlow =
|
2019-03-11 08:12:15 +01:00
|
|
|
{
|
2020-07-02 10:59:52 +02:00
|
|
|
.data = sPokeballGlow_Pal,
|
|
|
|
.tag = FLDEFF_PAL_TAG_POKEBALL_GLOW
|
2019-03-11 08:12:15 +01:00
|
|
|
};
|
|
|
|
|
2020-07-02 10:59:52 +02:00
|
|
|
const struct SpritePalette gSpritePalette_HofMonitor =
|
2019-03-11 08:12:15 +01:00
|
|
|
{
|
2020-07-02 10:59:52 +02:00
|
|
|
.data = sHofMonitor_Pal,
|
|
|
|
.tag = FLDEFF_PAL_TAG_HOF_MONITOR
|
2019-03-11 08:12:15 +01:00
|
|
|
};
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static const struct OamData sOam_32x16 =
|
2019-03-11 08:12:15 +01:00
|
|
|
{
|
2019-04-02 00:31:10 +02:00
|
|
|
.y = 0,
|
|
|
|
.affineMode = ST_OAM_AFFINE_OFF,
|
|
|
|
.objMode = ST_OAM_OBJ_NORMAL,
|
|
|
|
.bpp = ST_OAM_4BPP,
|
2019-03-11 08:12:15 +01:00
|
|
|
.shape = SPRITE_SHAPE(32x16),
|
2019-04-02 00:31:10 +02:00
|
|
|
.x = 0,
|
|
|
|
.size = SPRITE_SIZE(32x16),
|
|
|
|
.tileNum = 0,
|
|
|
|
.priority = 0,
|
|
|
|
.paletteNum = 0,
|
2018-05-11 01:36:57 +02:00
|
|
|
};
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static const struct SpriteFrameImage sPicTable_PokeballGlow[] =
|
2019-03-11 08:12:15 +01:00
|
|
|
{
|
2020-06-24 22:27:00 +02:00
|
|
|
obj_frame_tiles(sPokeballGlow_Gfx)
|
2018-05-11 01:36:57 +02:00
|
|
|
};
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static const struct SpriteFrameImage sPicTable_PokecenterMonitor[] =
|
2019-03-11 08:12:15 +01:00
|
|
|
{
|
2020-06-24 22:27:00 +02:00
|
|
|
obj_frame_tiles(sPokecenterMonitor0_Gfx),
|
|
|
|
obj_frame_tiles(sPokecenterMonitor1_Gfx)
|
2018-05-11 01:36:57 +02:00
|
|
|
};
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static const struct SpriteFrameImage sPicTable_HofMonitorBig[] =
|
2019-03-11 08:12:15 +01:00
|
|
|
{
|
2020-06-24 22:27:00 +02:00
|
|
|
obj_frame_tiles(sHofMonitorBig_Gfx)
|
2018-05-11 01:36:57 +02:00
|
|
|
};
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static const struct SpriteFrameImage sPicTable_HofMonitorSmall[] =
|
2019-03-11 08:12:15 +01:00
|
|
|
{
|
2020-06-24 22:27:00 +02:00
|
|
|
{.data = sHofMonitorSmall_Gfx, .size = 0x200} // the macro breaks down here
|
2018-05-11 01:36:57 +02:00
|
|
|
};
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static const struct Subsprite sSubsprites_PokecenterMonitor[] =
|
2019-03-11 08:12:15 +01:00
|
|
|
{
|
2019-12-05 03:00:45 +01:00
|
|
|
{
|
2021-08-25 00:59:32 +02:00
|
|
|
.x = -12,
|
|
|
|
.y = -8,
|
|
|
|
.shape = SPRITE_SHAPE(16x8),
|
2019-12-05 03:00:45 +01:00
|
|
|
.size = SPRITE_SIZE(16x8),
|
2021-08-25 00:59:32 +02:00
|
|
|
.tileOffset = 0,
|
2019-12-05 03:00:45 +01:00
|
|
|
.priority = 2
|
|
|
|
},
|
|
|
|
{
|
2021-08-25 00:59:32 +02:00
|
|
|
.x = 4,
|
2019-12-05 03:00:45 +01:00
|
|
|
.y = -8,
|
2021-08-25 00:59:32 +02:00
|
|
|
.shape = SPRITE_SHAPE(8x8),
|
|
|
|
.size = SPRITE_SIZE(8x8),
|
|
|
|
.tileOffset = 2,
|
|
|
|
.priority = 2
|
2019-12-05 03:00:45 +01:00
|
|
|
},
|
|
|
|
{
|
2021-08-25 00:59:32 +02:00
|
|
|
.x = -12,
|
|
|
|
.y = 0,
|
|
|
|
.shape = SPRITE_SHAPE(16x8),
|
2019-12-05 03:00:45 +01:00
|
|
|
.size = SPRITE_SIZE(16x8),
|
2021-08-25 00:59:32 +02:00
|
|
|
.tileOffset = 3,
|
2019-12-05 03:00:45 +01:00
|
|
|
.priority = 2
|
|
|
|
},
|
|
|
|
{
|
2021-08-25 00:59:32 +02:00
|
|
|
.x = 4,
|
|
|
|
.y = 0,
|
|
|
|
.shape = SPRITE_SHAPE(8x8),
|
|
|
|
.size = SPRITE_SIZE(8x8),
|
|
|
|
.tileOffset = 5,
|
2019-12-05 03:00:45 +01:00
|
|
|
.priority = 2
|
|
|
|
}
|
2018-05-11 01:36:57 +02:00
|
|
|
};
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static const struct SubspriteTable sSubspriteTable_PokecenterMonitor = subsprite_table(sSubsprites_PokecenterMonitor);
|
2018-05-11 01:36:57 +02:00
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static const struct Subsprite sSubsprites_HofMonitorBig[] =
|
2019-03-11 08:12:15 +01:00
|
|
|
{
|
2019-12-05 03:00:45 +01:00
|
|
|
{
|
2021-08-25 00:59:32 +02:00
|
|
|
.x = -32,
|
|
|
|
.y = -8,
|
|
|
|
.shape = SPRITE_SHAPE(32x8),
|
2019-12-05 03:00:45 +01:00
|
|
|
.size = SPRITE_SIZE(32x8),
|
2021-08-25 00:59:32 +02:00
|
|
|
.tileOffset = 0,
|
2019-12-05 03:00:45 +01:00
|
|
|
.priority = 2
|
|
|
|
},
|
|
|
|
{
|
2021-08-25 00:59:32 +02:00
|
|
|
.x = 0,
|
|
|
|
.y = -8,
|
|
|
|
.shape = SPRITE_SHAPE(32x8),
|
2019-12-05 03:00:45 +01:00
|
|
|
.size = SPRITE_SIZE(32x8),
|
2021-08-25 00:59:32 +02:00
|
|
|
.tileOffset = 4,
|
2019-12-05 03:00:45 +01:00
|
|
|
.priority = 2
|
|
|
|
},
|
|
|
|
{
|
2021-08-25 00:59:32 +02:00
|
|
|
.x = -32,
|
|
|
|
.y = 0,
|
|
|
|
.shape = SPRITE_SHAPE(32x8),
|
2019-12-05 03:00:45 +01:00
|
|
|
.size = SPRITE_SIZE(32x8),
|
2021-08-25 00:59:32 +02:00
|
|
|
.tileOffset = 8,
|
2019-12-05 03:00:45 +01:00
|
|
|
.priority = 2
|
|
|
|
},
|
|
|
|
{
|
2021-08-25 00:59:32 +02:00
|
|
|
.x = 0,
|
|
|
|
.y = 0,
|
|
|
|
.shape = SPRITE_SHAPE(32x8),
|
2019-12-05 03:00:45 +01:00
|
|
|
.size = SPRITE_SIZE(32x8),
|
2021-08-25 00:59:32 +02:00
|
|
|
.tileOffset = 12,
|
2019-12-05 03:00:45 +01:00
|
|
|
.priority = 2
|
|
|
|
}
|
2018-05-11 01:36:57 +02:00
|
|
|
};
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static const struct SubspriteTable sSubspriteTable_HofMonitorBig = subsprite_table(sSubsprites_HofMonitorBig);
|
2018-05-11 01:36:57 +02:00
|
|
|
|
2021-03-21 06:22:42 +01:00
|
|
|
const union AnimCmd sAnim_Static[] =
|
2019-03-11 08:12:15 +01:00
|
|
|
{
|
2018-05-11 01:36:57 +02:00
|
|
|
ANIMCMD_FRAME(.imageValue = 0, .duration = 1),
|
|
|
|
ANIMCMD_JUMP(0)
|
|
|
|
};
|
|
|
|
|
2021-03-21 06:22:42 +01:00
|
|
|
const union AnimCmd sAnim_Flicker[] =
|
2019-03-11 08:12:15 +01:00
|
|
|
{
|
2018-05-11 01:36:57 +02:00
|
|
|
ANIMCMD_FRAME(.imageValue = 0, .duration = 16),
|
|
|
|
ANIMCMD_FRAME(.imageValue = 1, .duration = 16),
|
|
|
|
ANIMCMD_FRAME(.imageValue = 0, .duration = 16),
|
|
|
|
ANIMCMD_FRAME(.imageValue = 1, .duration = 16),
|
|
|
|
ANIMCMD_FRAME(.imageValue = 0, .duration = 16),
|
|
|
|
ANIMCMD_FRAME(.imageValue = 1, .duration = 16),
|
|
|
|
ANIMCMD_FRAME(.imageValue = 0, .duration = 16),
|
|
|
|
ANIMCMD_FRAME(.imageValue = 1, .duration = 16),
|
|
|
|
ANIMCMD_END
|
|
|
|
};
|
|
|
|
|
2021-03-21 06:22:42 +01:00
|
|
|
// Flicker on and off, for the Pokéballs / monitors during the PokéCenter heal effect
|
|
|
|
const union AnimCmd *const sAnims_Flicker[] =
|
2019-03-11 08:12:15 +01:00
|
|
|
{
|
2021-03-21 06:22:42 +01:00
|
|
|
sAnim_Static,
|
|
|
|
sAnim_Flicker
|
2018-05-11 01:36:57 +02:00
|
|
|
};
|
|
|
|
|
2021-03-21 06:22:42 +01:00
|
|
|
static const union AnimCmd *const sAnims_HofMonitor[] =
|
2019-03-11 08:12:15 +01:00
|
|
|
{
|
2021-03-21 06:22:42 +01:00
|
|
|
sAnim_Static
|
2018-05-11 01:36:57 +02:00
|
|
|
};
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static const struct SpriteTemplate sSpriteTemplate_PokeballGlow =
|
2019-03-11 08:12:15 +01:00
|
|
|
{
|
2021-09-14 19:14:14 +02:00
|
|
|
.tileTag = TAG_NONE,
|
2020-07-02 10:59:52 +02:00
|
|
|
.paletteTag = FLDEFF_PAL_TAG_POKEBALL_GLOW,
|
2020-06-24 22:27:00 +02:00
|
|
|
.oam = &sOam_8x8,
|
2021-03-21 06:22:42 +01:00
|
|
|
.anims = sAnims_Flicker,
|
2020-06-24 22:27:00 +02:00
|
|
|
.images = sPicTable_PokeballGlow,
|
2018-05-10 10:02:33 +02:00
|
|
|
.affineAnims = gDummySpriteAffineAnimTable,
|
|
|
|
.callback = SpriteCB_PokeballGlow
|
2018-05-11 01:36:57 +02:00
|
|
|
};
|
2018-05-10 10:02:33 +02:00
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static const struct SpriteTemplate sSpriteTemplate_PokecenterMonitor =
|
2019-03-11 08:12:15 +01:00
|
|
|
{
|
2021-09-14 19:14:14 +02:00
|
|
|
.tileTag = TAG_NONE,
|
2020-07-02 10:59:52 +02:00
|
|
|
.paletteTag = FLDEFF_PAL_TAG_GENERAL_0,
|
2020-06-24 22:27:00 +02:00
|
|
|
.oam = &sOam_16x16,
|
2021-03-21 06:22:42 +01:00
|
|
|
.anims = sAnims_Flicker,
|
2020-06-24 22:27:00 +02:00
|
|
|
.images = sPicTable_PokecenterMonitor,
|
2018-05-10 10:02:33 +02:00
|
|
|
.affineAnims = gDummySpriteAffineAnimTable,
|
|
|
|
.callback = SpriteCB_PokecenterMonitor
|
2018-05-11 01:36:57 +02:00
|
|
|
};
|
2018-05-10 10:02:33 +02:00
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static const struct SpriteTemplate sSpriteTemplate_HofMonitorBig =
|
2019-03-11 08:12:15 +01:00
|
|
|
{
|
2021-09-14 19:14:14 +02:00
|
|
|
.tileTag = TAG_NONE,
|
2020-07-02 10:59:52 +02:00
|
|
|
.paletteTag = FLDEFF_PAL_TAG_HOF_MONITOR,
|
2020-06-24 22:27:00 +02:00
|
|
|
.oam = &sOam_16x16,
|
2021-03-21 06:22:42 +01:00
|
|
|
.anims = sAnims_HofMonitor,
|
2020-06-24 22:27:00 +02:00
|
|
|
.images = sPicTable_HofMonitorBig,
|
2018-05-10 10:02:33 +02:00
|
|
|
.affineAnims = gDummySpriteAffineAnimTable,
|
|
|
|
.callback = SpriteCB_HallOfFameMonitor
|
2018-05-11 01:36:57 +02:00
|
|
|
};
|
2018-05-10 10:02:33 +02:00
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static const struct SpriteTemplate sSpriteTemplate_HofMonitorSmall =
|
2019-03-11 08:12:15 +01:00
|
|
|
{
|
2021-09-14 19:14:14 +02:00
|
|
|
.tileTag = TAG_NONE,
|
2020-07-02 10:59:52 +02:00
|
|
|
.paletteTag = FLDEFF_PAL_TAG_HOF_MONITOR,
|
2020-06-24 22:27:00 +02:00
|
|
|
.oam = &sOam_32x16,
|
2021-03-21 06:22:42 +01:00
|
|
|
.anims = sAnims_HofMonitor,
|
2020-06-24 22:27:00 +02:00
|
|
|
.images = sPicTable_HofMonitorSmall,
|
2018-05-10 10:02:33 +02:00
|
|
|
.affineAnims = gDummySpriteAffineAnimTable,
|
|
|
|
.callback = SpriteCB_HallOfFameMonitor
|
2018-05-11 01:36:57 +02:00
|
|
|
};
|
2018-05-10 10:02:33 +02:00
|
|
|
|
2020-06-20 01:58:56 +02:00
|
|
|
void (*const sPokecenterHealEffectFuncs[])(struct Task *) =
|
2019-03-11 08:12:15 +01:00
|
|
|
{
|
2020-06-24 22:27:00 +02:00
|
|
|
PokecenterHealEffect_Init,
|
|
|
|
PokecenterHealEffect_WaitForBallPlacement,
|
|
|
|
PokecenterHealEffect_WaitForBallFlashing,
|
|
|
|
PokecenterHealEffect_WaitForSoundAndEnd
|
2018-05-11 01:36:57 +02:00
|
|
|
};
|
2018-05-10 10:02:33 +02:00
|
|
|
|
2020-06-20 01:58:56 +02:00
|
|
|
void (*const sHallOfFameRecordEffectFuncs[])(struct Task *) =
|
2019-03-11 08:12:15 +01:00
|
|
|
{
|
2020-06-24 22:27:00 +02:00
|
|
|
HallOfFameRecordEffect_Init,
|
|
|
|
HallOfFameRecordEffect_WaitForBallPlacement,
|
|
|
|
HallOfFameRecordEffect_WaitForBallFlashing,
|
|
|
|
HallOfFameRecordEffect_WaitForSoundAndEnd
|
2018-05-11 01:36:57 +02:00
|
|
|
};
|
2018-05-10 10:02:33 +02:00
|
|
|
|
2020-06-20 01:58:56 +02:00
|
|
|
void (*const sPokeballGlowEffectFuncs[])(struct Sprite *) =
|
2019-03-11 08:12:15 +01:00
|
|
|
{
|
2020-06-24 22:27:00 +02:00
|
|
|
PokeballGlowEffect_PlaceBalls,
|
|
|
|
PokeballGlowEffect_TryPlaySe,
|
|
|
|
PokeballGlowEffect_Flash1,
|
|
|
|
PokeballGlowEffect_Flash2,
|
|
|
|
PokeballGlowEffect_WaitAfterFlash,
|
|
|
|
PokeballGlowEffect_Dummy,
|
|
|
|
PokeballGlowEffect_WaitForSound,
|
|
|
|
PokeballGlowEffect_Idle
|
2018-05-11 01:36:57 +02:00
|
|
|
};
|
2018-05-10 10:02:33 +02:00
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static const struct Coords16 sPokeballCoordOffsets[PARTY_SIZE] =
|
2019-03-11 08:12:15 +01:00
|
|
|
{
|
2018-05-10 10:02:33 +02:00
|
|
|
{.x = 0, .y = 0},
|
|
|
|
{.x = 6, .y = 0},
|
|
|
|
{.x = 0, .y = 4},
|
|
|
|
{.x = 6, .y = 4},
|
|
|
|
{.x = 0, .y = 8},
|
|
|
|
{.x = 6, .y = 8}
|
2018-05-11 01:36:57 +02:00
|
|
|
};
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static const u8 sPokeballGlowReds[] = {16, 12, 8, 0};
|
|
|
|
static const u8 sPokeballGlowGreens[] = {16, 12, 8, 0};
|
|
|
|
static const u8 sPokeballGlowBlues[] = { 0, 0, 0, 0};
|
2018-05-11 01:36:57 +02:00
|
|
|
|
2019-12-17 09:24:44 +01:00
|
|
|
bool8 (*const sFallWarpFieldEffectFuncs[])(struct Task *) =
|
2019-03-11 08:12:15 +01:00
|
|
|
{
|
2020-06-24 22:27:00 +02:00
|
|
|
FallWarpEffect_Init,
|
|
|
|
FallWarpEffect_WaitWeather,
|
|
|
|
FallWarpEffect_StartFall,
|
|
|
|
FallWarpEffect_Fall,
|
|
|
|
FallWarpEffect_Land,
|
|
|
|
FallWarpEffect_CameraShake,
|
|
|
|
FallWarpEffect_End,
|
2018-05-11 01:36:57 +02:00
|
|
|
};
|
|
|
|
|
2020-06-20 01:58:56 +02:00
|
|
|
bool8 (*const sEscalatorWarpOutFieldEffectFuncs[])(struct Task *) =
|
2019-03-11 08:12:15 +01:00
|
|
|
{
|
2020-06-24 22:27:00 +02:00
|
|
|
EscalatorWarpOut_Init,
|
|
|
|
EscalatorWarpOut_WaitForPlayer,
|
|
|
|
EscalatorWarpOut_Up_Ride,
|
|
|
|
EscalatorWarpOut_Up_End,
|
|
|
|
EscalatorWarpOut_Down_Ride,
|
|
|
|
EscalatorWarpOut_Down_End,
|
2018-05-11 01:36:57 +02:00
|
|
|
};
|
|
|
|
|
2020-06-20 01:58:56 +02:00
|
|
|
bool8 (*const sEscalatorWarpInFieldEffectFuncs[])(struct Task *) =
|
2019-03-11 08:12:15 +01:00
|
|
|
{
|
2020-06-24 22:27:00 +02:00
|
|
|
EscalatorWarpIn_Init,
|
|
|
|
EscalatorWarpIn_Down_Init,
|
|
|
|
EscalatorWarpIn_Down_Ride,
|
|
|
|
EscalatorWarpIn_Up_Init,
|
|
|
|
EscalatorWarpIn_Up_Ride,
|
|
|
|
EscalatorWarpIn_WaitForMovement,
|
|
|
|
EscalatorWarpIn_End,
|
2018-05-11 01:36:57 +02:00
|
|
|
};
|
|
|
|
|
2020-06-20 01:58:56 +02:00
|
|
|
bool8 (*const sWaterfallFieldEffectFuncs[])(struct Task *, struct ObjectEvent *) =
|
2019-03-11 08:12:15 +01:00
|
|
|
{
|
2020-06-24 22:27:00 +02:00
|
|
|
WaterfallFieldEffect_Init,
|
|
|
|
WaterfallFieldEffect_ShowMon,
|
|
|
|
WaterfallFieldEffect_WaitForShowMon,
|
|
|
|
WaterfallFieldEffect_RideUp,
|
|
|
|
WaterfallFieldEffect_ContinueRideOrEnd,
|
2018-05-11 01:36:57 +02:00
|
|
|
};
|
|
|
|
|
2020-06-20 01:58:56 +02:00
|
|
|
bool8 (*const sDiveFieldEffectFuncs[])(struct Task *) =
|
2019-03-11 08:12:15 +01:00
|
|
|
{
|
2020-06-24 22:27:00 +02:00
|
|
|
DiveFieldEffect_Init,
|
|
|
|
DiveFieldEffect_ShowMon,
|
|
|
|
DiveFieldEffect_TryWarp,
|
2018-05-11 01:36:57 +02:00
|
|
|
};
|
|
|
|
|
2019-12-21 11:19:27 +01:00
|
|
|
bool8 (*const sLavaridgeGymB1FWarpEffectFuncs[])(struct Task *, struct ObjectEvent *, struct Sprite *) =
|
2019-03-11 08:12:15 +01:00
|
|
|
{
|
2020-06-24 22:27:00 +02:00
|
|
|
LavaridgeGymB1FWarpEffect_Init,
|
|
|
|
LavaridgeGymB1FWarpEffect_CameraShake,
|
|
|
|
LavaridgeGymB1FWarpEffect_Launch,
|
|
|
|
LavaridgeGymB1FWarpEffect_Rise,
|
|
|
|
LavaridgeGymB1FWarpEffect_FadeOut,
|
|
|
|
LavaridgeGymB1FWarpEffect_Warp,
|
2018-05-11 01:36:57 +02:00
|
|
|
};
|
|
|
|
|
2019-12-21 11:19:27 +01:00
|
|
|
bool8 (*const sLavaridgeGymB1FWarpExitEffectFuncs[])(struct Task *, struct ObjectEvent *, struct Sprite *) =
|
2019-03-11 08:12:15 +01:00
|
|
|
{
|
2020-06-24 22:27:00 +02:00
|
|
|
LavaridgeGymB1FWarpExitEffect_Init,
|
|
|
|
LavaridgeGymB1FWarpExitEffect_StartPopOut,
|
|
|
|
LavaridgeGymB1FWarpExitEffect_PopOut,
|
|
|
|
LavaridgeGymB1FWarpExitEffect_End,
|
2018-05-11 01:36:57 +02:00
|
|
|
};
|
|
|
|
|
2019-12-21 11:19:27 +01:00
|
|
|
bool8 (*const sLavaridgeGym1FWarpEffectFuncs[])(struct Task *, struct ObjectEvent *, struct Sprite *) =
|
2019-03-11 08:12:15 +01:00
|
|
|
{
|
2020-06-24 22:27:00 +02:00
|
|
|
LavaridgeGym1FWarpEffect_Init,
|
|
|
|
LavaridgeGym1FWarpEffect_AshPuff,
|
|
|
|
LavaridgeGym1FWarpEffect_Disappear,
|
|
|
|
LavaridgeGym1FWarpEffect_FadeOut,
|
|
|
|
LavaridgeGym1FWarpEffect_Warp,
|
2018-05-11 01:36:57 +02:00
|
|
|
};
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
void (*const sEscapeRopeWarpOutEffectFuncs[])(struct Task *) =
|
2019-03-11 08:12:15 +01:00
|
|
|
{
|
2020-06-24 22:27:00 +02:00
|
|
|
EscapeRopeWarpOutEffect_Init,
|
|
|
|
EscapeRopeWarpOutEffect_Spin,
|
2018-05-11 01:36:57 +02:00
|
|
|
};
|
2018-05-10 10:02:33 +02:00
|
|
|
|
|
|
|
u32 FieldEffectStart(u8 id)
|
|
|
|
{
|
|
|
|
u8 *script;
|
|
|
|
u32 val;
|
|
|
|
|
|
|
|
FieldEffectActiveListAdd(id);
|
|
|
|
|
|
|
|
script = gFieldEffectScriptPointers[id];
|
|
|
|
|
|
|
|
while (gFieldEffectScriptFuncs[*script](&script, &val))
|
|
|
|
;
|
|
|
|
|
|
|
|
return val;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool8 FieldEffectCmd_loadtiles(u8 **script, u32 *val)
|
|
|
|
{
|
|
|
|
(*script)++;
|
|
|
|
FieldEffectScript_LoadTiles(script);
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool8 FieldEffectCmd_loadfadedpal(u8 **script, u32 *val)
|
|
|
|
{
|
|
|
|
(*script)++;
|
|
|
|
FieldEffectScript_LoadFadedPalette(script);
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool8 FieldEffectCmd_loadpal(u8 **script, u32 *val)
|
|
|
|
{
|
|
|
|
(*script)++;
|
|
|
|
FieldEffectScript_LoadPalette(script);
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool8 FieldEffectCmd_callnative(u8 **script, u32 *val)
|
|
|
|
{
|
|
|
|
(*script)++;
|
|
|
|
FieldEffectScript_CallNative(script, val);
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool8 FieldEffectCmd_end(u8 **script, u32 *val)
|
|
|
|
{
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool8 FieldEffectCmd_loadgfx_callnative(u8 **script, u32 *val)
|
|
|
|
{
|
|
|
|
(*script)++;
|
|
|
|
FieldEffectScript_LoadTiles(script);
|
|
|
|
FieldEffectScript_LoadFadedPalette(script);
|
|
|
|
FieldEffectScript_CallNative(script, val);
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool8 FieldEffectCmd_loadtiles_callnative(u8 **script, u32 *val)
|
|
|
|
{
|
|
|
|
(*script)++;
|
|
|
|
FieldEffectScript_LoadTiles(script);
|
|
|
|
FieldEffectScript_CallNative(script, val);
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool8 FieldEffectCmd_loadfadedpal_callnative(u8 **script, u32 *val)
|
|
|
|
{
|
|
|
|
(*script)++;
|
|
|
|
FieldEffectScript_LoadFadedPalette(script);
|
|
|
|
FieldEffectScript_CallNative(script, val);
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
u32 FieldEffectScript_ReadWord(u8 **script)
|
|
|
|
{
|
|
|
|
return (*script)[0]
|
|
|
|
+ ((*script)[1] << 8)
|
|
|
|
+ ((*script)[2] << 16)
|
|
|
|
+ ((*script)[3] << 24);
|
|
|
|
}
|
|
|
|
|
|
|
|
void FieldEffectScript_LoadTiles(u8 **script)
|
|
|
|
{
|
|
|
|
struct SpriteSheet *sheet = (struct SpriteSheet *)FieldEffectScript_ReadWord(script);
|
2018-12-05 15:31:01 +01:00
|
|
|
if (GetSpriteTileStartByTag(sheet->tag) == 0xFFFF)
|
2018-05-10 10:02:33 +02:00
|
|
|
LoadSpriteSheet(sheet);
|
|
|
|
(*script) += 4;
|
|
|
|
}
|
|
|
|
|
|
|
|
void FieldEffectScript_LoadFadedPalette(u8 **script)
|
|
|
|
{
|
|
|
|
struct SpritePalette *palette = (struct SpritePalette *)FieldEffectScript_ReadWord(script);
|
|
|
|
LoadSpritePalette(palette);
|
|
|
|
UpdateSpritePaletteWithWeather(IndexOfSpritePaletteTag(palette->tag));
|
|
|
|
(*script) += 4;
|
|
|
|
}
|
|
|
|
|
|
|
|
void FieldEffectScript_LoadPalette(u8 **script)
|
|
|
|
{
|
|
|
|
struct SpritePalette *palette = (struct SpritePalette *)FieldEffectScript_ReadWord(script);
|
|
|
|
LoadSpritePalette(palette);
|
|
|
|
(*script) += 4;
|
|
|
|
}
|
|
|
|
|
|
|
|
void FieldEffectScript_CallNative(u8 **script, u32 *val)
|
|
|
|
{
|
|
|
|
u32 (*func)(void) = (u32 (*)(void))FieldEffectScript_ReadWord(script);
|
|
|
|
*val = func();
|
|
|
|
(*script) += 4;
|
|
|
|
}
|
|
|
|
|
|
|
|
void FieldEffectFreeGraphicsResources(struct Sprite *sprite)
|
|
|
|
{
|
|
|
|
u16 sheetTileStart = sprite->sheetTileStart;
|
|
|
|
u32 paletteNum = sprite->oam.paletteNum;
|
|
|
|
DestroySprite(sprite);
|
|
|
|
FieldEffectFreeTilesIfUnused(sheetTileStart);
|
|
|
|
FieldEffectFreePaletteIfUnused(paletteNum);
|
|
|
|
}
|
|
|
|
|
|
|
|
void FieldEffectStop(struct Sprite *sprite, u8 id)
|
|
|
|
{
|
|
|
|
FieldEffectFreeGraphicsResources(sprite);
|
|
|
|
FieldEffectActiveListRemove(id);
|
|
|
|
}
|
|
|
|
|
|
|
|
void FieldEffectFreeTilesIfUnused(u16 tileStart)
|
|
|
|
{
|
|
|
|
u8 i;
|
|
|
|
u16 tag = GetSpriteTileTagByTileStart(tileStart);
|
|
|
|
|
2021-09-14 19:14:14 +02:00
|
|
|
if (tag != TAG_NONE)
|
2018-05-10 10:02:33 +02:00
|
|
|
{
|
|
|
|
for (i = 0; i < MAX_SPRITES; i++)
|
|
|
|
if (gSprites[i].inUse && gSprites[i].usingSheet && tileStart == gSprites[i].sheetTileStart)
|
|
|
|
return;
|
|
|
|
FreeSpriteTilesByTag(tag);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void FieldEffectFreePaletteIfUnused(u8 paletteNum)
|
|
|
|
{
|
|
|
|
u8 i;
|
|
|
|
u16 tag = GetSpritePaletteTagByPaletteNum(paletteNum);
|
|
|
|
|
2021-09-14 19:14:14 +02:00
|
|
|
if (tag != TAG_NONE)
|
2018-05-10 10:02:33 +02:00
|
|
|
{
|
|
|
|
for (i = 0; i < MAX_SPRITES; i++)
|
|
|
|
if (gSprites[i].inUse && gSprites[i].oam.paletteNum == paletteNum)
|
|
|
|
return;
|
|
|
|
FreeSpritePaletteByTag(tag);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void FieldEffectActiveListClear(void)
|
|
|
|
{
|
|
|
|
u8 i;
|
|
|
|
for (i = 0; i < ARRAY_COUNT(sActiveList); i++)
|
|
|
|
sActiveList[i] = 0xFF;
|
|
|
|
}
|
|
|
|
|
|
|
|
void FieldEffectActiveListAdd(u8 id)
|
|
|
|
{
|
|
|
|
u8 i;
|
|
|
|
for (i = 0; i < ARRAY_COUNT(sActiveList); i++)
|
|
|
|
{
|
|
|
|
if (sActiveList[i] == 0xFF)
|
|
|
|
{
|
|
|
|
sActiveList[i] = id;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void FieldEffectActiveListRemove(u8 id)
|
|
|
|
{
|
|
|
|
u8 i;
|
|
|
|
for (i = 0; i < ARRAY_COUNT(sActiveList); i++)
|
|
|
|
{
|
|
|
|
if (sActiveList[i] == id)
|
|
|
|
{
|
|
|
|
sActiveList[i] = 0xFF;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool8 FieldEffectActiveListContains(u8 id)
|
|
|
|
{
|
|
|
|
u8 i;
|
|
|
|
for (i = 0; i < ARRAY_COUNT(sActiveList); i++)
|
|
|
|
if (sActiveList[i] == id)
|
|
|
|
return TRUE;
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
u8 CreateTrainerSprite(u8 trainerSpriteID, s16 x, s16 y, u8 subpriority, u8 *buffer)
|
|
|
|
{
|
|
|
|
struct SpriteTemplate spriteTemplate;
|
2018-12-17 23:00:08 +01:00
|
|
|
LoadCompressedSpritePaletteOverrideBuffer(&gTrainerFrontPicPaletteTable[trainerSpriteID], buffer);
|
|
|
|
LoadCompressedSpriteSheetOverrideBuffer(&gTrainerFrontPicTable[trainerSpriteID], buffer);
|
2018-05-10 10:02:33 +02:00
|
|
|
spriteTemplate.tileTag = gTrainerFrontPicTable[trainerSpriteID].tag;
|
|
|
|
spriteTemplate.paletteTag = gTrainerFrontPicPaletteTable[trainerSpriteID].tag;
|
2020-06-24 22:27:00 +02:00
|
|
|
spriteTemplate.oam = &sOam_64x64;
|
2018-05-10 10:02:33 +02:00
|
|
|
spriteTemplate.anims = gDummySpriteAnimTable;
|
|
|
|
spriteTemplate.images = NULL;
|
|
|
|
spriteTemplate.affineAnims = gDummySpriteAffineAnimTable;
|
|
|
|
spriteTemplate.callback = SpriteCallbackDummy;
|
|
|
|
return CreateSprite(&spriteTemplate, x, y, subpriority);
|
|
|
|
}
|
|
|
|
|
|
|
|
void LoadTrainerGfx_TrainerCard(u8 gender, u16 palOffset, u8 *dest)
|
|
|
|
{
|
|
|
|
LZDecompressVram(gTrainerFrontPicTable[gender].data, dest);
|
|
|
|
LoadCompressedPalette(gTrainerFrontPicPaletteTable[gender].data, palOffset, 0x20);
|
|
|
|
}
|
|
|
|
|
|
|
|
u8 AddNewGameBirchObject(s16 x, s16 y, u8 subpriority)
|
|
|
|
{
|
2020-06-24 22:27:00 +02:00
|
|
|
LoadSpritePalette(&sSpritePalette_NewGameBirch);
|
|
|
|
return CreateSprite(&sSpriteTemplate_NewGameBirch, x, y, subpriority);
|
2018-05-10 10:02:33 +02:00
|
|
|
}
|
|
|
|
|
2018-11-07 03:13:40 +01:00
|
|
|
u8 CreateMonSprite_PicBox(u16 species, s16 x, s16 y, u8 subpriority)
|
2018-05-10 10:02:33 +02:00
|
|
|
{
|
2018-11-25 20:16:41 +01:00
|
|
|
s32 spriteId = CreateMonPicSprite_HandleDeoxys(species, 0, 0x8000, 1, x, y, 0, gMonPaletteTable[species].tag);
|
2018-05-10 10:02:33 +02:00
|
|
|
PreservePaletteInWeather(IndexOfSpritePaletteTag(gMonPaletteTable[species].tag) + 0x10);
|
2018-12-05 15:31:01 +01:00
|
|
|
if (spriteId == 0xFFFF)
|
2018-11-07 03:13:40 +01:00
|
|
|
return MAX_SPRITES;
|
2018-11-25 20:16:41 +01:00
|
|
|
else
|
|
|
|
return spriteId;
|
2018-05-10 10:02:33 +02:00
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
u8 CreateMonSprite_FieldMove(u16 species, u32 otId, u32 personality, s16 x, s16 y, u8 subpriority)
|
2018-05-10 10:02:33 +02:00
|
|
|
{
|
2020-06-24 22:27:00 +02:00
|
|
|
const struct CompressedSpritePalette *spritePalette = GetMonSpritePalStructFromOtIdPersonality(species, otId, personality);
|
|
|
|
u16 spriteId = CreateMonPicSprite_HandleDeoxys(species, otId, personality, 1, x, y, 0, spritePalette->tag);
|
2018-05-10 10:02:33 +02:00
|
|
|
PreservePaletteInWeather(IndexOfSpritePaletteTag(spritePalette->tag) + 0x10);
|
2018-12-05 15:31:01 +01:00
|
|
|
if (spriteId == 0xFFFF)
|
2018-11-28 21:08:22 +01:00
|
|
|
return MAX_SPRITES;
|
2018-11-25 20:16:41 +01:00
|
|
|
else
|
|
|
|
return spriteId;
|
2018-05-10 10:02:33 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void FreeResourcesAndDestroySprite(struct Sprite *sprite, u8 spriteId)
|
|
|
|
{
|
|
|
|
ResetPreservedPalettesInWeather();
|
2019-12-05 03:00:45 +01:00
|
|
|
if (sprite->oam.affineMode != ST_OAM_AFFINE_OFF)
|
2018-05-10 10:02:33 +02:00
|
|
|
{
|
|
|
|
FreeOamMatrix(sprite->oam.matrixNum);
|
|
|
|
}
|
2018-08-19 01:06:10 +02:00
|
|
|
FreeAndDestroyMonPicSprite(spriteId);
|
2018-05-10 10:02:33 +02:00
|
|
|
}
|
|
|
|
|
2020-02-27 20:11:39 +01:00
|
|
|
// r, g, b are between 0 and 16
|
2018-05-10 10:02:33 +02:00
|
|
|
void MultiplyInvertedPaletteRGBComponents(u16 i, u8 r, u8 g, u8 b)
|
|
|
|
{
|
2021-01-19 18:15:12 +01:00
|
|
|
int curRed, curGreen, curBlue;
|
2021-01-19 18:59:36 +01:00
|
|
|
u16 color = gPlttBufferUnfaded[i];
|
2021-08-25 00:59:32 +02:00
|
|
|
|
2021-01-19 18:59:36 +01:00
|
|
|
curRed = (color & RGB_RED);
|
|
|
|
curGreen = (color & RGB_GREEN) >> 5;
|
|
|
|
curBlue = (color & RGB_BLUE) >> 10;
|
2021-08-25 00:59:32 +02:00
|
|
|
|
2021-01-19 18:15:12 +01:00
|
|
|
curRed += (((0x1F - curRed) * r) >> 4);
|
|
|
|
curGreen += (((0x1F - curGreen) * g) >> 4);
|
|
|
|
curBlue += (((0x1F - curBlue) * b) >> 4);
|
2021-08-25 00:59:32 +02:00
|
|
|
|
2021-01-19 18:59:36 +01:00
|
|
|
color = curRed;
|
|
|
|
color |= (curGreen << 5);
|
|
|
|
color |= (curBlue << 10);
|
2021-08-25 00:59:32 +02:00
|
|
|
|
2021-01-19 18:59:36 +01:00
|
|
|
gPlttBufferFaded[i] = color;
|
2018-05-10 10:02:33 +02:00
|
|
|
}
|
|
|
|
|
2020-02-27 20:11:39 +01:00
|
|
|
// r, g, b are between 0 and 16
|
2018-05-10 10:02:33 +02:00
|
|
|
void MultiplyPaletteRGBComponents(u16 i, u8 r, u8 g, u8 b)
|
|
|
|
{
|
2021-01-19 18:15:12 +01:00
|
|
|
int curRed, curGreen, curBlue;
|
2021-01-19 18:59:36 +01:00
|
|
|
u16 color = gPlttBufferUnfaded[i];
|
2021-08-25 00:59:32 +02:00
|
|
|
|
2021-01-19 18:59:36 +01:00
|
|
|
curRed = (color & RGB_RED);
|
|
|
|
curGreen = (color & RGB_GREEN) >> 5;
|
|
|
|
curBlue = (color & RGB_BLUE) >> 10;
|
2021-08-25 00:59:32 +02:00
|
|
|
|
2021-01-19 18:15:12 +01:00
|
|
|
curRed -= ((curRed * r) >> 4);
|
2018-05-10 10:02:33 +02:00
|
|
|
curGreen -= ((curGreen * g) >> 4);
|
2021-01-19 18:15:12 +01:00
|
|
|
curBlue -= ((curBlue * b) >> 4);
|
2021-08-25 00:59:32 +02:00
|
|
|
|
2021-01-19 18:59:36 +01:00
|
|
|
color = curRed;
|
2021-02-14 23:08:19 +01:00
|
|
|
color |= (curGreen << 5);
|
|
|
|
color |= (curBlue << 10);
|
2021-08-25 00:59:32 +02:00
|
|
|
|
2021-01-19 18:59:36 +01:00
|
|
|
gPlttBufferFaded[i] = color;
|
2018-05-10 10:02:33 +02:00
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
// Task data for Task_PokecenterHeal and Task_HallOfFameRecord
|
|
|
|
#define tState data[0]
|
|
|
|
#define tNumMons data[1]
|
|
|
|
#define tFirstBallX data[2]
|
|
|
|
#define tFirstBallY data[3]
|
|
|
|
#define tMonitorX data[4]
|
|
|
|
#define tMonitorY data[5]
|
|
|
|
#define tBallSpriteId data[6]
|
|
|
|
#define tMonitorSpriteId data[7]
|
|
|
|
#define tStartHofFlash data[15]
|
|
|
|
|
|
|
|
// Sprite data for SpriteCB_PokeballGlowEffect
|
|
|
|
#define sState data[0]
|
|
|
|
#define sTimer data[1]
|
|
|
|
#define sCounter data[2]
|
|
|
|
#define sPlayHealSe data[5]
|
|
|
|
#define sNumMons data[6]
|
|
|
|
#define sSpriteId data[7]
|
|
|
|
|
|
|
|
// Sprite data for SpriteCB_PokeballGlow
|
|
|
|
#define sEffectSpriteId data[0]
|
|
|
|
|
2018-05-10 10:02:33 +02:00
|
|
|
bool8 FldEff_PokecenterHeal(void)
|
|
|
|
{
|
|
|
|
u8 nPokemon;
|
|
|
|
struct Task *task;
|
|
|
|
|
|
|
|
nPokemon = CalculatePlayerPartyCount();
|
|
|
|
task = &gTasks[CreateTask(Task_PokecenterHeal, 0xff)];
|
2020-06-24 22:27:00 +02:00
|
|
|
task->tNumMons = nPokemon;
|
|
|
|
task->tFirstBallX = 93;
|
|
|
|
task->tFirstBallY = 36;
|
|
|
|
task->tMonitorX = 124;
|
|
|
|
task->tMonitorY = 24;
|
2018-05-10 10:02:33 +02:00
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2018-11-13 15:19:04 +01:00
|
|
|
static void Task_PokecenterHeal(u8 taskId)
|
2018-05-10 10:02:33 +02:00
|
|
|
{
|
|
|
|
struct Task *task;
|
|
|
|
task = &gTasks[taskId];
|
2020-06-24 22:27:00 +02:00
|
|
|
sPokecenterHealEffectFuncs[task->tState](task);
|
2018-05-10 10:02:33 +02:00
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static void PokecenterHealEffect_Init(struct Task *task)
|
2018-05-10 10:02:33 +02:00
|
|
|
{
|
2020-06-24 22:27:00 +02:00
|
|
|
task->tState++;
|
|
|
|
task->tBallSpriteId = CreateGlowingPokeballsEffect(task->tNumMons, task->tFirstBallX, task->tFirstBallY, TRUE);
|
|
|
|
task->tMonitorSpriteId = CreatePokecenterMonitorSprite(task->tMonitorX, task->tMonitorY);
|
2018-05-10 10:02:33 +02:00
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static void PokecenterHealEffect_WaitForBallPlacement(struct Task *task)
|
2018-05-10 10:02:33 +02:00
|
|
|
{
|
2020-06-24 22:27:00 +02:00
|
|
|
if (gSprites[task->tBallSpriteId].sState > 1)
|
2018-05-10 10:02:33 +02:00
|
|
|
{
|
2020-06-24 22:27:00 +02:00
|
|
|
gSprites[task->tMonitorSpriteId].sState++;
|
|
|
|
task->tState++;
|
2018-05-10 10:02:33 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static void PokecenterHealEffect_WaitForBallFlashing(struct Task *task)
|
2018-05-10 10:02:33 +02:00
|
|
|
{
|
2020-06-24 22:27:00 +02:00
|
|
|
if (gSprites[task->tBallSpriteId].sState > 4)
|
2018-05-10 10:02:33 +02:00
|
|
|
{
|
2020-06-24 22:27:00 +02:00
|
|
|
task->tState++;
|
2018-05-10 10:02:33 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static void PokecenterHealEffect_WaitForSoundAndEnd(struct Task *task)
|
2018-05-10 10:02:33 +02:00
|
|
|
{
|
2020-06-24 22:27:00 +02:00
|
|
|
if (gSprites[task->tBallSpriteId].sState > 6)
|
2018-05-10 10:02:33 +02:00
|
|
|
{
|
2020-06-24 22:27:00 +02:00
|
|
|
DestroySprite(&gSprites[task->tBallSpriteId]);
|
2018-05-10 10:02:33 +02:00
|
|
|
FieldEffectActiveListRemove(FLDEFF_POKECENTER_HEAL);
|
|
|
|
DestroyTask(FindTaskIdByFunc(Task_PokecenterHeal));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool8 FldEff_HallOfFameRecord(void)
|
|
|
|
{
|
|
|
|
u8 nPokemon;
|
|
|
|
struct Task *task;
|
|
|
|
|
|
|
|
nPokemon = CalculatePlayerPartyCount();
|
|
|
|
task = &gTasks[CreateTask(Task_HallOfFameRecord, 0xff)];
|
2020-06-24 22:27:00 +02:00
|
|
|
task->tNumMons = nPokemon;
|
|
|
|
task->tFirstBallX = 117;
|
|
|
|
task->tFirstBallY = 52;
|
2018-05-10 10:02:33 +02:00
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2018-11-13 15:19:04 +01:00
|
|
|
static void Task_HallOfFameRecord(u8 taskId)
|
2018-05-10 10:02:33 +02:00
|
|
|
{
|
|
|
|
struct Task *task;
|
|
|
|
task = &gTasks[taskId];
|
2020-06-24 22:27:00 +02:00
|
|
|
sHallOfFameRecordEffectFuncs[task->tState](task);
|
2018-05-10 10:02:33 +02:00
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static void HallOfFameRecordEffect_Init(struct Task *task)
|
2018-05-10 10:02:33 +02:00
|
|
|
{
|
|
|
|
u8 taskId;
|
2020-06-24 22:27:00 +02:00
|
|
|
task->tState++;
|
|
|
|
task->tBallSpriteId = CreateGlowingPokeballsEffect(task->tNumMons, task->tFirstBallX, task->tFirstBallY, FALSE);
|
2018-05-10 10:02:33 +02:00
|
|
|
taskId = FindTaskIdByFunc(Task_HallOfFameRecord);
|
2020-06-24 22:27:00 +02:00
|
|
|
CreateHofMonitorSprite(taskId, 120, 24, FALSE);
|
|
|
|
CreateHofMonitorSprite(taskId, 40, 8, TRUE);
|
|
|
|
CreateHofMonitorSprite(taskId, 72, 8, TRUE);
|
|
|
|
CreateHofMonitorSprite(taskId, 168, 8, TRUE);
|
|
|
|
CreateHofMonitorSprite(taskId, 200, 8, TRUE);
|
2018-05-10 10:02:33 +02:00
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static void HallOfFameRecordEffect_WaitForBallPlacement(struct Task *task)
|
2018-05-10 10:02:33 +02:00
|
|
|
{
|
2020-06-24 22:27:00 +02:00
|
|
|
if (gSprites[task->tBallSpriteId].sState > 1)
|
2018-05-10 10:02:33 +02:00
|
|
|
{
|
2020-06-24 22:27:00 +02:00
|
|
|
task->tStartHofFlash++;
|
|
|
|
task->tState++;
|
2018-05-10 10:02:33 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static void HallOfFameRecordEffect_WaitForBallFlashing(struct Task *task)
|
2018-05-10 10:02:33 +02:00
|
|
|
{
|
2020-06-24 22:27:00 +02:00
|
|
|
if (gSprites[task->tBallSpriteId].sState > 4)
|
2018-05-10 10:02:33 +02:00
|
|
|
{
|
2020-06-24 22:27:00 +02:00
|
|
|
task->tState++;
|
2018-05-10 10:02:33 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static void HallOfFameRecordEffect_WaitForSoundAndEnd(struct Task *task)
|
2018-05-10 10:02:33 +02:00
|
|
|
{
|
2020-06-24 22:27:00 +02:00
|
|
|
if (gSprites[task->tBallSpriteId].sState > 6)
|
2018-05-10 10:02:33 +02:00
|
|
|
{
|
2020-06-24 22:27:00 +02:00
|
|
|
DestroySprite(&gSprites[task->tBallSpriteId]);
|
2018-05-10 10:02:33 +02:00
|
|
|
FieldEffectActiveListRemove(FLDEFF_HALL_OF_FAME_RECORD);
|
|
|
|
DestroyTask(FindTaskIdByFunc(Task_HallOfFameRecord));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static u8 CreateGlowingPokeballsEffect(s16 numMons, s16 x, s16 y, bool16 playHealSe)
|
2018-05-10 10:02:33 +02:00
|
|
|
{
|
|
|
|
u8 spriteId;
|
|
|
|
struct Sprite *sprite;
|
|
|
|
spriteId = CreateInvisibleSprite(SpriteCB_PokeballGlowEffect);
|
|
|
|
sprite = &gSprites[spriteId];
|
2021-07-07 15:11:52 +02:00
|
|
|
sprite->x2 = x;
|
|
|
|
sprite->y2 = y;
|
2020-06-24 22:27:00 +02:00
|
|
|
sprite->sPlayHealSe = playHealSe;
|
|
|
|
sprite->sNumMons = numMons;
|
|
|
|
sprite->sSpriteId = spriteId;
|
2018-05-10 10:02:33 +02:00
|
|
|
return spriteId;
|
|
|
|
}
|
|
|
|
|
2018-11-13 15:19:04 +01:00
|
|
|
static void SpriteCB_PokeballGlowEffect(struct Sprite *sprite)
|
2018-05-10 10:02:33 +02:00
|
|
|
{
|
2020-06-24 22:27:00 +02:00
|
|
|
sPokeballGlowEffectFuncs[sprite->sState](sprite);
|
2018-05-10 10:02:33 +02:00
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static void PokeballGlowEffect_PlaceBalls(struct Sprite *sprite)
|
2018-05-10 10:02:33 +02:00
|
|
|
{
|
2020-06-24 22:27:00 +02:00
|
|
|
u8 spriteId;
|
|
|
|
if (sprite->sTimer == 0 || (--sprite->sTimer) == 0)
|
|
|
|
{
|
|
|
|
sprite->sTimer = 25;
|
2021-07-07 15:11:52 +02:00
|
|
|
spriteId = CreateSpriteAtEnd(&sSpriteTemplate_PokeballGlow, sPokeballCoordOffsets[sprite->sCounter].x + sprite->x2, sPokeballCoordOffsets[sprite->sCounter].y + sprite->y2, 0);
|
2020-06-24 22:27:00 +02:00
|
|
|
gSprites[spriteId].oam.priority = 2;
|
|
|
|
gSprites[spriteId].sEffectSpriteId = sprite->sSpriteId;
|
|
|
|
sprite->sCounter++;
|
|
|
|
sprite->sNumMons--;
|
2020-08-21 00:02:00 +02:00
|
|
|
PlaySE(SE_BALL);
|
2018-05-10 10:02:33 +02:00
|
|
|
}
|
2020-06-24 22:27:00 +02:00
|
|
|
if (sprite->sNumMons == 0)
|
2018-05-10 10:02:33 +02:00
|
|
|
{
|
2020-06-24 22:27:00 +02:00
|
|
|
sprite->sTimer = 32;
|
|
|
|
sprite->sState++;
|
2018-05-10 10:02:33 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static void PokeballGlowEffect_TryPlaySe(struct Sprite *sprite)
|
2018-05-10 10:02:33 +02:00
|
|
|
{
|
2020-06-24 22:27:00 +02:00
|
|
|
if ((--sprite->sTimer) == 0)
|
2018-05-10 10:02:33 +02:00
|
|
|
{
|
2020-06-24 22:27:00 +02:00
|
|
|
sprite->sState++;
|
|
|
|
sprite->sTimer = 8;
|
|
|
|
sprite->sCounter = 0;
|
2018-05-10 10:02:33 +02:00
|
|
|
sprite->data[3] = 0;
|
2020-06-24 22:27:00 +02:00
|
|
|
if (sprite->sPlayHealSe)
|
2018-05-10 10:02:33 +02:00
|
|
|
{
|
2020-08-21 00:02:00 +02:00
|
|
|
PlayFanfare(MUS_HEAL);
|
2018-05-10 10:02:33 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static void PokeballGlowEffect_Flash1(struct Sprite *sprite)
|
2018-05-10 10:02:33 +02:00
|
|
|
{
|
|
|
|
u8 phase;
|
2020-06-24 22:27:00 +02:00
|
|
|
if ((--sprite->sTimer) == 0)
|
2018-05-10 10:02:33 +02:00
|
|
|
{
|
2020-06-24 22:27:00 +02:00
|
|
|
sprite->sTimer = 8;
|
|
|
|
sprite->sCounter++;
|
|
|
|
sprite->sCounter &= 3;
|
|
|
|
|
|
|
|
if (sprite->sCounter == 0)
|
2018-05-10 10:02:33 +02:00
|
|
|
sprite->data[3]++;
|
|
|
|
}
|
2020-06-24 22:27:00 +02:00
|
|
|
phase = (sprite->sCounter + 3) & 3;
|
2020-07-02 10:59:52 +02:00
|
|
|
MultiplyInvertedPaletteRGBComponents((IndexOfSpritePaletteTag(FLDEFF_PAL_TAG_POKEBALL_GLOW) << 4) + 0x108, sPokeballGlowReds[phase], sPokeballGlowGreens[phase], sPokeballGlowBlues[phase]);
|
2020-06-24 22:27:00 +02:00
|
|
|
phase = (sprite->sCounter + 2) & 3;
|
2020-07-02 10:59:52 +02:00
|
|
|
MultiplyInvertedPaletteRGBComponents((IndexOfSpritePaletteTag(FLDEFF_PAL_TAG_POKEBALL_GLOW) << 4) + 0x106, sPokeballGlowReds[phase], sPokeballGlowGreens[phase], sPokeballGlowBlues[phase]);
|
2020-06-24 22:27:00 +02:00
|
|
|
phase = (sprite->sCounter + 1) & 3;
|
2020-07-02 10:59:52 +02:00
|
|
|
MultiplyInvertedPaletteRGBComponents((IndexOfSpritePaletteTag(FLDEFF_PAL_TAG_POKEBALL_GLOW) << 4) + 0x102, sPokeballGlowReds[phase], sPokeballGlowGreens[phase], sPokeballGlowBlues[phase]);
|
2020-06-24 22:27:00 +02:00
|
|
|
phase = sprite->sCounter;
|
2020-07-02 10:59:52 +02:00
|
|
|
MultiplyInvertedPaletteRGBComponents((IndexOfSpritePaletteTag(FLDEFF_PAL_TAG_POKEBALL_GLOW) << 4) + 0x105, sPokeballGlowReds[phase], sPokeballGlowGreens[phase], sPokeballGlowBlues[phase]);
|
|
|
|
MultiplyInvertedPaletteRGBComponents((IndexOfSpritePaletteTag(FLDEFF_PAL_TAG_POKEBALL_GLOW) << 4) + 0x103, sPokeballGlowReds[phase], sPokeballGlowGreens[phase], sPokeballGlowBlues[phase]);
|
2018-05-10 10:02:33 +02:00
|
|
|
if (sprite->data[3] > 2)
|
|
|
|
{
|
2020-06-24 22:27:00 +02:00
|
|
|
sprite->sState++;
|
|
|
|
sprite->sTimer = 8;
|
|
|
|
sprite->sCounter = 0;
|
2018-05-10 10:02:33 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static void PokeballGlowEffect_Flash2(struct Sprite *sprite)
|
2018-05-10 10:02:33 +02:00
|
|
|
{
|
|
|
|
u8 phase;
|
2020-06-24 22:27:00 +02:00
|
|
|
if ((--sprite->sTimer) == 0)
|
2018-05-10 10:02:33 +02:00
|
|
|
{
|
2020-06-24 22:27:00 +02:00
|
|
|
sprite->sTimer = 8;
|
|
|
|
sprite->sCounter++;
|
|
|
|
sprite->sCounter &= 3;
|
|
|
|
if (sprite->sCounter == 3)
|
2018-05-10 10:02:33 +02:00
|
|
|
{
|
2020-06-24 22:27:00 +02:00
|
|
|
sprite->sState++;
|
|
|
|
sprite->sTimer = 30;
|
2018-05-10 10:02:33 +02:00
|
|
|
}
|
|
|
|
}
|
2020-06-24 22:27:00 +02:00
|
|
|
phase = sprite->sCounter;
|
2020-07-02 10:59:52 +02:00
|
|
|
MultiplyInvertedPaletteRGBComponents((IndexOfSpritePaletteTag(FLDEFF_PAL_TAG_POKEBALL_GLOW) << 4) + 0x108, sPokeballGlowReds[phase], sPokeballGlowGreens[phase], sPokeballGlowBlues[phase]);
|
|
|
|
MultiplyInvertedPaletteRGBComponents((IndexOfSpritePaletteTag(FLDEFF_PAL_TAG_POKEBALL_GLOW) << 4) + 0x106, sPokeballGlowReds[phase], sPokeballGlowGreens[phase], sPokeballGlowBlues[phase]);
|
|
|
|
MultiplyInvertedPaletteRGBComponents((IndexOfSpritePaletteTag(FLDEFF_PAL_TAG_POKEBALL_GLOW) << 4) + 0x102, sPokeballGlowReds[phase], sPokeballGlowGreens[phase], sPokeballGlowBlues[phase]);
|
|
|
|
MultiplyInvertedPaletteRGBComponents((IndexOfSpritePaletteTag(FLDEFF_PAL_TAG_POKEBALL_GLOW) << 4) + 0x105, sPokeballGlowReds[phase], sPokeballGlowGreens[phase], sPokeballGlowBlues[phase]);
|
|
|
|
MultiplyInvertedPaletteRGBComponents((IndexOfSpritePaletteTag(FLDEFF_PAL_TAG_POKEBALL_GLOW) << 4) + 0x103, sPokeballGlowReds[phase], sPokeballGlowGreens[phase], sPokeballGlowBlues[phase]);
|
2018-05-10 10:02:33 +02:00
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static void PokeballGlowEffect_WaitAfterFlash(struct Sprite *sprite)
|
2018-05-10 10:02:33 +02:00
|
|
|
{
|
2020-06-24 22:27:00 +02:00
|
|
|
if ((--sprite->sTimer) == 0)
|
2018-05-10 10:02:33 +02:00
|
|
|
{
|
2020-06-24 22:27:00 +02:00
|
|
|
sprite->sState++;
|
2018-05-10 10:02:33 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static void PokeballGlowEffect_Dummy(struct Sprite *sprite)
|
2018-05-10 10:02:33 +02:00
|
|
|
{
|
2020-06-24 22:27:00 +02:00
|
|
|
sprite->sState++;
|
2018-05-10 10:02:33 +02:00
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static void PokeballGlowEffect_WaitForSound(struct Sprite *sprite)
|
2018-05-10 10:02:33 +02:00
|
|
|
{
|
2020-06-24 22:27:00 +02:00
|
|
|
if (sprite->sPlayHealSe == FALSE || IsFanfareTaskInactive())
|
2018-05-10 10:02:33 +02:00
|
|
|
{
|
2020-06-24 22:27:00 +02:00
|
|
|
sprite->sState++;
|
2018-05-10 10:02:33 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static void PokeballGlowEffect_Idle(struct Sprite *sprite)
|
2018-05-10 10:02:33 +02:00
|
|
|
{
|
2020-06-24 22:27:00 +02:00
|
|
|
// Idle until destroyed
|
2018-05-10 10:02:33 +02:00
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static void SpriteCB_PokeballGlow(struct Sprite *sprite)
|
2018-05-10 10:02:33 +02:00
|
|
|
{
|
2020-06-24 22:27:00 +02:00
|
|
|
if (gSprites[sprite->sEffectSpriteId].sState > 4)
|
2018-05-10 10:02:33 +02:00
|
|
|
{
|
|
|
|
FieldEffectFreeGraphicsResources(sprite);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static u8 CreatePokecenterMonitorSprite(s16 x, s16 y)
|
2018-05-10 10:02:33 +02:00
|
|
|
{
|
2020-06-24 22:27:00 +02:00
|
|
|
u8 spriteId;
|
2018-05-10 10:02:33 +02:00
|
|
|
struct Sprite *sprite;
|
2020-06-24 22:27:00 +02:00
|
|
|
spriteId = CreateSpriteAtEnd(&sSpriteTemplate_PokecenterMonitor, x, y, 0);
|
|
|
|
sprite = &gSprites[spriteId];
|
2018-05-10 10:02:33 +02:00
|
|
|
sprite->oam.priority = 2;
|
2018-09-10 17:25:58 +02:00
|
|
|
sprite->invisible = TRUE;
|
2020-06-24 22:27:00 +02:00
|
|
|
SetSubspriteTables(sprite, &sSubspriteTable_PokecenterMonitor);
|
|
|
|
return spriteId;
|
2018-05-10 10:02:33 +02:00
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static void SpriteCB_PokecenterMonitor(struct Sprite *sprite)
|
2018-05-10 10:02:33 +02:00
|
|
|
{
|
|
|
|
if (sprite->data[0] != 0)
|
|
|
|
{
|
|
|
|
sprite->data[0] = 0;
|
2018-09-10 17:25:58 +02:00
|
|
|
sprite->invisible = FALSE;
|
2018-05-10 10:02:33 +02:00
|
|
|
StartSpriteAnim(sprite, 1);
|
|
|
|
}
|
|
|
|
if (sprite->animEnded)
|
|
|
|
{
|
|
|
|
FieldEffectFreeGraphicsResources(sprite);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static void CreateHofMonitorSprite(s16 taskId, s16 x, s16 y, bool8 isSmallMonitor)
|
2018-05-10 10:02:33 +02:00
|
|
|
{
|
2020-06-24 22:27:00 +02:00
|
|
|
u8 spriteId;
|
|
|
|
if (!isSmallMonitor)
|
2018-05-10 10:02:33 +02:00
|
|
|
{
|
2020-06-24 22:27:00 +02:00
|
|
|
spriteId = CreateSpriteAtEnd(&sSpriteTemplate_HofMonitorBig, x, y, 0);
|
|
|
|
SetSubspriteTables(&gSprites[spriteId], &sSubspriteTable_HofMonitorBig);
|
2018-05-10 10:02:33 +02:00
|
|
|
} else
|
|
|
|
{
|
2020-06-24 22:27:00 +02:00
|
|
|
spriteId = CreateSpriteAtEnd(&sSpriteTemplate_HofMonitorSmall, x, y, 0);
|
2018-05-10 10:02:33 +02:00
|
|
|
}
|
2020-06-24 22:27:00 +02:00
|
|
|
gSprites[spriteId].invisible = TRUE;
|
|
|
|
gSprites[spriteId].data[0] = taskId;
|
2018-05-10 10:02:33 +02:00
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static void SpriteCB_HallOfFameMonitor(struct Sprite *sprite)
|
2018-05-10 10:02:33 +02:00
|
|
|
{
|
2020-06-24 22:27:00 +02:00
|
|
|
if (gTasks[sprite->data[0]].tStartHofFlash)
|
2018-05-10 10:02:33 +02:00
|
|
|
{
|
|
|
|
if (sprite->data[1] == 0 || (--sprite->data[1]) == 0)
|
|
|
|
{
|
|
|
|
sprite->data[1] = 16;
|
|
|
|
sprite->invisible ^= 1;
|
|
|
|
}
|
|
|
|
sprite->data[2]++;
|
|
|
|
}
|
|
|
|
if (sprite->data[2] > 127)
|
|
|
|
{
|
|
|
|
FieldEffectFreeGraphicsResources(sprite);
|
|
|
|
}
|
|
|
|
}
|
2018-05-11 01:36:57 +02:00
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
#undef tState
|
|
|
|
#undef tNumMons
|
|
|
|
#undef tFirstBallX
|
|
|
|
#undef tFirstBallY
|
|
|
|
#undef tMonitorX
|
|
|
|
#undef tMonitorY
|
|
|
|
#undef tBallSpriteId
|
|
|
|
#undef tMonitorSpriteId
|
|
|
|
#undef tStartHofFlash
|
|
|
|
#undef sState
|
|
|
|
#undef sTimer
|
|
|
|
#undef sCounter
|
|
|
|
#undef sPlayHealSe
|
|
|
|
#undef sNumMons
|
|
|
|
#undef sSpriteId
|
|
|
|
#undef sEffectSpriteId
|
2018-05-11 01:36:57 +02:00
|
|
|
|
2019-10-18 01:22:03 +02:00
|
|
|
void ReturnToFieldFromFlyMapSelect(void)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
|
|
|
SetMainCallback2(CB2_ReturnToField);
|
2020-06-20 01:58:56 +02:00
|
|
|
gFieldCallback = FieldCallback_UseFly;
|
2018-05-11 01:36:57 +02:00
|
|
|
}
|
|
|
|
|
2020-06-20 01:58:56 +02:00
|
|
|
static void FieldCallback_UseFly(void)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2019-12-17 09:24:44 +01:00
|
|
|
FadeInFromBlack();
|
2020-06-20 01:58:56 +02:00
|
|
|
CreateTask(Task_UseFly, 0);
|
2018-05-11 01:36:57 +02:00
|
|
|
ScriptContext2_Enable();
|
2019-11-21 04:55:44 +01:00
|
|
|
FreezeObjectEvents();
|
2018-05-11 01:36:57 +02:00
|
|
|
gFieldCallback = NULL;
|
|
|
|
}
|
|
|
|
|
2020-06-20 01:58:56 +02:00
|
|
|
static void Task_UseFly(u8 taskId)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
|
|
|
struct Task *task;
|
|
|
|
task = &gTasks[taskId];
|
|
|
|
if (!task->data[0])
|
|
|
|
{
|
|
|
|
if (!IsWeatherNotFadingIn())
|
|
|
|
return;
|
2020-06-24 22:27:00 +02:00
|
|
|
|
2018-05-11 01:36:57 +02:00
|
|
|
gFieldEffectArguments[0] = GetCursorSelectionMonId();
|
2020-06-20 01:58:56 +02:00
|
|
|
if ((int)gFieldEffectArguments[0] > PARTY_SIZE - 1)
|
2018-05-11 01:36:57 +02:00
|
|
|
gFieldEffectArguments[0] = 0;
|
2020-06-24 22:27:00 +02:00
|
|
|
|
2018-05-11 01:36:57 +02:00
|
|
|
FieldEffectStart(FLDEFF_USE_FLY);
|
|
|
|
task->data[0]++;
|
|
|
|
}
|
|
|
|
if (!FieldEffectActiveListContains(FLDEFF_USE_FLY))
|
|
|
|
{
|
|
|
|
Overworld_ResetStateAfterFly();
|
2018-09-05 00:31:37 +02:00
|
|
|
WarpIntoMap();
|
2018-05-11 01:36:57 +02:00
|
|
|
SetMainCallback2(CB2_LoadMap);
|
2020-06-20 01:58:56 +02:00
|
|
|
gFieldCallback = FieldCallback_FlyIntoMap;
|
2018-05-11 01:36:57 +02:00
|
|
|
DestroyTask(taskId);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-20 01:58:56 +02:00
|
|
|
static void FieldCallback_FlyIntoMap(void)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
|
|
|
Overworld_PlaySpecialMapMusic();
|
2019-12-17 09:24:44 +01:00
|
|
|
FadeInFromBlack();
|
2020-06-20 01:58:56 +02:00
|
|
|
CreateTask(Task_FlyIntoMap, 0);
|
2019-11-21 04:55:44 +01:00
|
|
|
gObjectEvents[gPlayerAvatar.objectEventId].invisible = TRUE;
|
2020-06-20 01:58:56 +02:00
|
|
|
if (gPlayerAvatar.flags & PLAYER_AVATAR_FLAG_SURFING)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2019-11-21 04:55:44 +01:00
|
|
|
ObjectEventTurn(&gObjectEvents[gPlayerAvatar.objectEventId], DIR_WEST);
|
2018-05-11 01:36:57 +02:00
|
|
|
}
|
|
|
|
ScriptContext2_Enable();
|
2019-11-21 04:55:44 +01:00
|
|
|
FreezeObjectEvents();
|
2018-05-11 01:36:57 +02:00
|
|
|
gFieldCallback = NULL;
|
|
|
|
}
|
|
|
|
|
2020-06-20 01:58:56 +02:00
|
|
|
static void Task_FlyIntoMap(u8 taskId)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
|
|
|
struct Task *task;
|
|
|
|
task = &gTasks[taskId];
|
|
|
|
if (task->data[0] == 0)
|
|
|
|
{
|
|
|
|
if (gPaletteFade.active)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
FieldEffectStart(FLDEFF_FLY_IN);
|
|
|
|
task->data[0]++;
|
|
|
|
}
|
|
|
|
if (!FieldEffectActiveListContains(FLDEFF_FLY_IN))
|
|
|
|
{
|
|
|
|
ScriptContext2_Disable();
|
2019-11-21 04:55:44 +01:00
|
|
|
UnfreezeObjectEvents();
|
2018-05-11 01:36:57 +02:00
|
|
|
DestroyTask(taskId);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
#define tState data[0]
|
|
|
|
#define tFallOffset data[1]
|
|
|
|
#define tTotalFall data[2]
|
|
|
|
#define tSetTrigger data[3]
|
|
|
|
#define tSubsprMode data[4]
|
|
|
|
|
|
|
|
#define tVertShake data[1] // re-used
|
|
|
|
#define tNumShakes data[2]
|
|
|
|
|
2019-12-17 09:24:44 +01:00
|
|
|
void FieldCB_FallWarpExit(void)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
|
|
|
Overworld_PlaySpecialMapMusic();
|
2019-12-17 09:24:44 +01:00
|
|
|
WarpFadeInScreen();
|
2018-05-11 01:36:57 +02:00
|
|
|
ScriptContext2_Enable();
|
2019-11-21 04:55:44 +01:00
|
|
|
FreezeObjectEvents();
|
2019-12-17 09:24:44 +01:00
|
|
|
CreateTask(Task_FallWarpFieldEffect, 0);
|
2018-05-11 01:36:57 +02:00
|
|
|
gFieldCallback = NULL;
|
|
|
|
}
|
|
|
|
|
2019-12-17 09:24:44 +01:00
|
|
|
static void Task_FallWarpFieldEffect(u8 taskId)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
|
|
|
struct Task *task;
|
|
|
|
task = &gTasks[taskId];
|
2020-06-24 22:27:00 +02:00
|
|
|
while (sFallWarpFieldEffectFuncs[task->tState](task));
|
2018-05-11 01:36:57 +02:00
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static bool8 FallWarpEffect_Init(struct Task *task)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2019-11-21 04:55:44 +01:00
|
|
|
struct ObjectEvent *playerObject;
|
2018-05-11 01:36:57 +02:00
|
|
|
struct Sprite *playerSprite;
|
2019-11-21 04:55:44 +01:00
|
|
|
playerObject = &gObjectEvents[gPlayerAvatar.objectEventId];
|
2018-05-11 01:36:57 +02:00
|
|
|
playerSprite = &gSprites[gPlayerAvatar.spriteId];
|
|
|
|
CameraObjectReset2();
|
2019-11-21 04:55:44 +01:00
|
|
|
gObjectEvents[gPlayerAvatar.objectEventId].invisible = TRUE;
|
2018-05-11 01:36:57 +02:00
|
|
|
gPlayerAvatar.preventStep = TRUE;
|
2019-11-21 04:55:44 +01:00
|
|
|
ObjectEventSetHeldMovement(playerObject, GetFaceDirectionMovementAction(GetPlayerFacingDirection()));
|
2020-06-24 22:27:00 +02:00
|
|
|
task->tSubsprMode = playerSprite->subspriteMode;
|
2018-06-11 16:19:17 +02:00
|
|
|
playerObject->fixedPriority = 1;
|
2018-05-11 01:36:57 +02:00
|
|
|
playerSprite->oam.priority = 1;
|
2019-12-05 03:00:45 +01:00
|
|
|
playerSprite->subspriteMode = SUBSPRITES_IGNORE_PRIORITY;
|
2020-06-24 22:27:00 +02:00
|
|
|
task->tState++;
|
2018-05-11 01:36:57 +02:00
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static bool8 FallWarpEffect_WaitWeather(struct Task *task)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
|
|
|
if (IsWeatherNotFadingIn())
|
2020-06-24 22:27:00 +02:00
|
|
|
task->tState++;
|
|
|
|
|
2018-05-11 01:36:57 +02:00
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static bool8 FallWarpEffect_StartFall(struct Task *task)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
|
|
|
struct Sprite *sprite;
|
|
|
|
s16 centerToCornerVecY;
|
|
|
|
sprite = &gSprites[gPlayerAvatar.spriteId];
|
|
|
|
centerToCornerVecY = -(sprite->centerToCornerVecY << 1);
|
2021-07-07 15:11:52 +02:00
|
|
|
sprite->y2 = -(sprite->y + sprite->centerToCornerVecY + gSpriteCoordOffsetY + centerToCornerVecY);
|
2020-06-24 22:27:00 +02:00
|
|
|
task->tFallOffset = 1;
|
|
|
|
task->tTotalFall = 0;
|
2019-11-21 04:55:44 +01:00
|
|
|
gObjectEvents[gPlayerAvatar.objectEventId].invisible = FALSE;
|
2020-08-21 00:02:00 +02:00
|
|
|
PlaySE(SE_FALL);
|
2020-06-24 22:27:00 +02:00
|
|
|
task->tState++;
|
2018-05-11 01:36:57 +02:00
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static bool8 FallWarpEffect_Fall(struct Task *task)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2019-11-21 04:55:44 +01:00
|
|
|
struct ObjectEvent *objectEvent;
|
2018-05-11 01:36:57 +02:00
|
|
|
struct Sprite *sprite;
|
|
|
|
|
2019-11-21 04:55:44 +01:00
|
|
|
objectEvent = &gObjectEvents[gPlayerAvatar.objectEventId];
|
2018-05-11 01:36:57 +02:00
|
|
|
sprite = &gSprites[gPlayerAvatar.spriteId];
|
2021-07-07 15:11:52 +02:00
|
|
|
sprite->y2 += task->tFallOffset;
|
2020-06-24 22:27:00 +02:00
|
|
|
if (task->tFallOffset < 8)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2020-06-24 22:27:00 +02:00
|
|
|
task->tTotalFall += task->tFallOffset;
|
|
|
|
|
|
|
|
if (task->tTotalFall & 0xf)
|
|
|
|
task->tFallOffset <<= 1;
|
2018-05-11 01:36:57 +02:00
|
|
|
}
|
2021-07-07 15:11:52 +02:00
|
|
|
if (task->tSetTrigger == FALSE && sprite->y2 >= -16)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2020-06-24 22:27:00 +02:00
|
|
|
task->tSetTrigger++;
|
2019-11-21 04:55:44 +01:00
|
|
|
objectEvent->fixedPriority = 0;
|
2020-06-24 22:27:00 +02:00
|
|
|
sprite->subspriteMode = task->tSubsprMode;
|
2019-11-21 04:55:44 +01:00
|
|
|
objectEvent->triggerGroundEffectsOnMove = 1;
|
2018-05-11 01:36:57 +02:00
|
|
|
}
|
2021-07-07 15:11:52 +02:00
|
|
|
if (sprite->y2 >= 0)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2020-08-21 00:02:00 +02:00
|
|
|
PlaySE(SE_M_STRENGTH);
|
2019-11-21 04:55:44 +01:00
|
|
|
objectEvent->triggerGroundEffectsOnStop = 1;
|
|
|
|
objectEvent->landingJump = 1;
|
2021-07-07 15:11:52 +02:00
|
|
|
sprite->y2 = 0;
|
2020-06-24 22:27:00 +02:00
|
|
|
task->tState++;
|
2018-05-11 01:36:57 +02:00
|
|
|
}
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static bool8 FallWarpEffect_Land(struct Task *task)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2020-06-24 22:27:00 +02:00
|
|
|
task->tState++;
|
|
|
|
task->tVertShake = 4;
|
|
|
|
task->tNumShakes = 0;
|
2018-05-11 01:36:57 +02:00
|
|
|
SetCameraPanningCallback(NULL);
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static bool8 FallWarpEffect_CameraShake(struct Task *task)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2020-06-24 22:27:00 +02:00
|
|
|
SetCameraPanning(0, task->tVertShake);
|
|
|
|
task->tVertShake = -task->tVertShake;
|
|
|
|
task->tNumShakes++;
|
|
|
|
|
|
|
|
if ((task->tNumShakes & 3) == 0)
|
|
|
|
task->tVertShake >>= 1;
|
|
|
|
|
|
|
|
if (task->tVertShake == 0)
|
|
|
|
task->tState++;
|
|
|
|
|
2018-05-11 01:36:57 +02:00
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static bool8 FallWarpEffect_End(struct Task *task)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
|
|
|
gPlayerAvatar.preventStep = FALSE;
|
|
|
|
ScriptContext2_Disable();
|
|
|
|
CameraObjectReset1();
|
2019-11-21 04:55:44 +01:00
|
|
|
UnfreezeObjectEvents();
|
2018-05-11 01:36:57 +02:00
|
|
|
InstallCameraPanAheadCallback();
|
2019-12-17 09:24:44 +01:00
|
|
|
DestroyTask(FindTaskIdByFunc(Task_FallWarpFieldEffect));
|
2018-05-11 01:36:57 +02:00
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
#undef tState
|
|
|
|
#undef tFallOffset
|
|
|
|
#undef tTotalFall
|
|
|
|
#undef tSetTrigger
|
|
|
|
#undef tSubsprMode
|
|
|
|
#undef tVertShake
|
|
|
|
#undef tNumShakes
|
|
|
|
|
|
|
|
#define tState data[0]
|
|
|
|
#define tGoingUp data[1]
|
|
|
|
|
2019-12-17 09:24:44 +01:00
|
|
|
void StartEscalatorWarp(u8 metatileBehavior, u8 priority)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
|
|
|
u8 taskId;
|
2020-06-20 01:58:56 +02:00
|
|
|
taskId = CreateTask(Task_EscalatorWarpOut, priority);
|
2020-06-24 22:27:00 +02:00
|
|
|
gTasks[taskId].tGoingUp = FALSE;
|
2019-12-17 09:24:44 +01:00
|
|
|
if (metatileBehavior == MB_UP_ESCALATOR)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2020-06-24 22:27:00 +02:00
|
|
|
gTasks[taskId].tGoingUp = TRUE;
|
2018-05-11 01:36:57 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-20 01:58:56 +02:00
|
|
|
static void Task_EscalatorWarpOut(u8 taskId)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
|
|
|
struct Task *task;
|
|
|
|
task = &gTasks[taskId];
|
2020-06-24 22:27:00 +02:00
|
|
|
while (sEscalatorWarpOutFieldEffectFuncs[task->tState](task));
|
2018-05-11 01:36:57 +02:00
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static bool8 EscalatorWarpOut_Init(struct Task *task)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2019-11-21 04:55:44 +01:00
|
|
|
FreezeObjectEvents();
|
2018-05-11 01:36:57 +02:00
|
|
|
CameraObjectReset2();
|
2020-06-24 22:27:00 +02:00
|
|
|
StartEscalator(task->tGoingUp);
|
|
|
|
task->tState++;
|
2018-05-11 01:36:57 +02:00
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static bool8 EscalatorWarpOut_WaitForPlayer(struct Task *task)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2019-11-21 04:55:44 +01:00
|
|
|
struct ObjectEvent *objectEvent;
|
|
|
|
objectEvent = &gObjectEvents[gPlayerAvatar.objectEventId];
|
|
|
|
if (!ObjectEventIsMovementOverridden(objectEvent) || ObjectEventClearHeldMovementIfFinished(objectEvent))
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2019-11-21 04:55:44 +01:00
|
|
|
ObjectEventSetHeldMovement(objectEvent, GetFaceDirectionMovementAction(GetPlayerFacingDirection()));
|
2020-06-24 22:27:00 +02:00
|
|
|
task->tState++;
|
2018-05-11 01:36:57 +02:00
|
|
|
task->data[2] = 0;
|
|
|
|
task->data[3] = 0;
|
2020-06-24 22:27:00 +02:00
|
|
|
if ((u8)task->tGoingUp == FALSE)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2020-06-24 22:27:00 +02:00
|
|
|
task->tState = 4; // jump to EscalatorWarpOut_Down_Ride
|
2018-05-11 01:36:57 +02:00
|
|
|
}
|
2020-08-21 00:02:00 +02:00
|
|
|
PlaySE(SE_ESCALATOR);
|
2018-05-11 01:36:57 +02:00
|
|
|
}
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static bool8 EscalatorWarpOut_Up_Ride(struct Task *task)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2020-06-24 22:27:00 +02:00
|
|
|
RideUpEscalatorOut(task);
|
2018-05-11 01:36:57 +02:00
|
|
|
if (task->data[2] > 3)
|
|
|
|
{
|
2020-06-24 22:27:00 +02:00
|
|
|
FadeOutAtEndOfEscalator();
|
|
|
|
task->tState++;
|
2018-05-11 01:36:57 +02:00
|
|
|
}
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static bool8 EscalatorWarpOut_Up_End(struct Task *task)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2020-06-24 22:27:00 +02:00
|
|
|
RideUpEscalatorOut(task);
|
|
|
|
WarpAtEndOfEscalator();
|
2018-05-11 01:36:57 +02:00
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static bool8 EscalatorWarpOut_Down_Ride(struct Task *task)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2020-06-24 22:27:00 +02:00
|
|
|
RideDownEscalatorOut(task);
|
2018-05-11 01:36:57 +02:00
|
|
|
if (task->data[2] > 3)
|
|
|
|
{
|
2020-06-24 22:27:00 +02:00
|
|
|
FadeOutAtEndOfEscalator();
|
|
|
|
task->tState++;
|
2018-05-11 01:36:57 +02:00
|
|
|
}
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static bool8 EscalatorWarpOut_Down_End(struct Task *task)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2020-06-24 22:27:00 +02:00
|
|
|
RideDownEscalatorOut(task);
|
|
|
|
WarpAtEndOfEscalator();
|
2018-05-11 01:36:57 +02:00
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static void RideUpEscalatorOut(struct Task *task)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
|
|
|
struct Sprite *sprite;
|
|
|
|
sprite = &gSprites[gPlayerAvatar.spriteId];
|
2021-07-07 15:11:52 +02:00
|
|
|
sprite->x2 = Cos(0x84, task->data[2]);
|
|
|
|
sprite->y2 = Sin(0x94, task->data[2]);
|
2018-05-11 01:36:57 +02:00
|
|
|
task->data[3]++;
|
|
|
|
if (task->data[3] & 1)
|
|
|
|
{
|
|
|
|
task->data[2]++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static void RideDownEscalatorOut(struct Task *task)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
|
|
|
struct Sprite *sprite;
|
|
|
|
sprite = &gSprites[gPlayerAvatar.spriteId];
|
2021-07-07 15:11:52 +02:00
|
|
|
sprite->x2 = Cos(0x7c, task->data[2]);
|
|
|
|
sprite->y2 = Sin(0x76, task->data[2]);
|
2018-05-11 01:36:57 +02:00
|
|
|
task->data[3]++;
|
|
|
|
if (task->data[3] & 1)
|
|
|
|
{
|
|
|
|
task->data[2]++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static void FadeOutAtEndOfEscalator(void)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2018-12-08 21:42:36 +01:00
|
|
|
TryFadeOutOldMapMusic();
|
2019-12-17 09:24:44 +01:00
|
|
|
WarpFadeOutScreen();
|
2018-05-11 01:36:57 +02:00
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static void WarpAtEndOfEscalator(void)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2018-09-05 00:31:37 +02:00
|
|
|
if (!gPaletteFade.active && BGMusicStopped() == TRUE)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2020-06-20 01:58:56 +02:00
|
|
|
StopEscalator();
|
2018-09-05 00:31:37 +02:00
|
|
|
WarpIntoMap();
|
2020-06-20 01:58:56 +02:00
|
|
|
gFieldCallback = FieldCallback_EscalatorWarpIn;
|
2018-05-11 01:36:57 +02:00
|
|
|
SetMainCallback2(CB2_LoadMap);
|
2020-06-20 01:58:56 +02:00
|
|
|
DestroyTask(FindTaskIdByFunc(Task_EscalatorWarpOut));
|
2018-05-11 01:36:57 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
#undef tState
|
|
|
|
#undef tGoingUp
|
|
|
|
|
2020-06-20 01:58:56 +02:00
|
|
|
static void FieldCallback_EscalatorWarpIn(void)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
|
|
|
Overworld_PlaySpecialMapMusic();
|
2019-12-17 09:24:44 +01:00
|
|
|
WarpFadeInScreen();
|
2018-05-11 01:36:57 +02:00
|
|
|
ScriptContext2_Enable();
|
2020-06-20 01:58:56 +02:00
|
|
|
CreateTask(Task_EscalatorWarpIn, 0);
|
2018-05-11 01:36:57 +02:00
|
|
|
gFieldCallback = NULL;
|
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
#define tState data[0]
|
|
|
|
|
2020-06-20 01:58:56 +02:00
|
|
|
static void Task_EscalatorWarpIn(u8 taskId)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
|
|
|
struct Task *task;
|
|
|
|
task = &gTasks[taskId];
|
2020-06-24 22:27:00 +02:00
|
|
|
while (sEscalatorWarpInFieldEffectFuncs[task->tState](task));
|
2018-05-11 01:36:57 +02:00
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static bool8 EscalatorWarpIn_Init(struct Task *task)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2019-11-21 04:55:44 +01:00
|
|
|
struct ObjectEvent *objectEvent;
|
2018-05-11 01:36:57 +02:00
|
|
|
s16 x;
|
|
|
|
s16 y;
|
|
|
|
u8 behavior;
|
|
|
|
CameraObjectReset2();
|
2019-11-21 04:55:44 +01:00
|
|
|
objectEvent = &gObjectEvents[gPlayerAvatar.objectEventId];
|
|
|
|
ObjectEventSetHeldMovement(objectEvent, GetFaceDirectionMovementAction(DIR_EAST));
|
2018-05-11 01:36:57 +02:00
|
|
|
PlayerGetDestCoords(&x, &y);
|
|
|
|
behavior = MapGridGetMetatileBehaviorAt(x, y);
|
2020-06-24 22:27:00 +02:00
|
|
|
task->tState++;
|
2018-05-11 01:36:57 +02:00
|
|
|
task->data[1] = 16;
|
2020-06-24 22:27:00 +02:00
|
|
|
|
2020-06-20 01:58:56 +02:00
|
|
|
if (behavior == MB_DOWN_ESCALATOR)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2020-06-24 22:27:00 +02:00
|
|
|
// If dest is down escalator tile, player is riding up
|
2020-06-20 01:58:56 +02:00
|
|
|
behavior = TRUE;
|
2020-06-24 22:27:00 +02:00
|
|
|
task->tState = 3; // jump to EscalatorWarpIn_Up_Init
|
2021-08-25 00:59:32 +02:00
|
|
|
}
|
2020-06-24 22:27:00 +02:00
|
|
|
else // MB_UP_ESCALATOR
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2020-06-24 22:27:00 +02:00
|
|
|
// If dest is up escalator tile, player is riding down
|
2020-06-20 01:58:56 +02:00
|
|
|
behavior = FALSE;
|
2018-05-11 01:36:57 +02:00
|
|
|
}
|
2020-06-20 01:58:56 +02:00
|
|
|
StartEscalator(behavior);
|
2018-05-11 01:36:57 +02:00
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static bool8 EscalatorWarpIn_Down_Init(struct Task *task)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
|
|
|
struct Sprite *sprite;
|
|
|
|
sprite = &gSprites[gPlayerAvatar.spriteId];
|
2021-07-07 15:11:52 +02:00
|
|
|
sprite->x2 = Cos(0x84, task->data[1]);
|
|
|
|
sprite->y2 = Sin(0x94, task->data[1]);
|
2020-06-24 22:27:00 +02:00
|
|
|
task->tState++;
|
2018-05-11 01:36:57 +02:00
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static bool8 EscalatorWarpIn_Down_Ride(struct Task *task)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
|
|
|
struct Sprite *sprite;
|
|
|
|
sprite = &gSprites[gPlayerAvatar.spriteId];
|
2021-07-07 15:11:52 +02:00
|
|
|
sprite->x2 = Cos(0x84, task->data[1]);
|
|
|
|
sprite->y2 = Sin(0x94, task->data[1]);
|
2018-05-11 01:36:57 +02:00
|
|
|
task->data[2]++;
|
|
|
|
if (task->data[2] & 1)
|
|
|
|
{
|
|
|
|
task->data[1]--;
|
|
|
|
}
|
|
|
|
if (task->data[1] == 0)
|
|
|
|
{
|
2021-07-07 15:11:52 +02:00
|
|
|
sprite->x2 = 0;
|
|
|
|
sprite->y2 = 0;
|
2020-06-24 22:27:00 +02:00
|
|
|
task->tState = 5;
|
2018-05-11 01:36:57 +02:00
|
|
|
}
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static bool8 EscalatorWarpIn_Up_Init(struct Task *task)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
|
|
|
struct Sprite *sprite;
|
|
|
|
sprite = &gSprites[gPlayerAvatar.spriteId];
|
2021-07-07 15:11:52 +02:00
|
|
|
sprite->x2 = Cos(0x7c, task->data[1]);
|
|
|
|
sprite->y2 = Sin(0x76, task->data[1]);
|
2020-06-24 22:27:00 +02:00
|
|
|
task->tState++;
|
2018-05-11 01:36:57 +02:00
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static bool8 EscalatorWarpIn_Up_Ride(struct Task *task)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
|
|
|
struct Sprite *sprite;
|
|
|
|
sprite = &gSprites[gPlayerAvatar.spriteId];
|
2021-07-07 15:11:52 +02:00
|
|
|
sprite->x2 = Cos(0x7c, task->data[1]);
|
|
|
|
sprite->y2 = Sin(0x76, task->data[1]);
|
2018-05-11 01:36:57 +02:00
|
|
|
task->data[2]++;
|
|
|
|
if (task->data[2] & 1)
|
|
|
|
{
|
|
|
|
task->data[1]--;
|
|
|
|
}
|
|
|
|
if (task->data[1] == 0)
|
|
|
|
{
|
2021-07-07 15:11:52 +02:00
|
|
|
sprite->x2 = 0;
|
|
|
|
sprite->y2 = 0;
|
2020-06-24 22:27:00 +02:00
|
|
|
task->tState++;
|
2018-05-11 01:36:57 +02:00
|
|
|
}
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static bool8 EscalatorWarpIn_WaitForMovement(struct Task *task)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2020-06-20 01:58:56 +02:00
|
|
|
if (IsEscalatorMoving())
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
|
|
|
return FALSE;
|
|
|
|
}
|
2020-06-20 01:58:56 +02:00
|
|
|
StopEscalator();
|
2020-06-24 22:27:00 +02:00
|
|
|
task->tState++;
|
2018-05-11 01:36:57 +02:00
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static bool8 EscalatorWarpIn_End(struct Task *task)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2019-11-21 04:55:44 +01:00
|
|
|
struct ObjectEvent *objectEvent;
|
|
|
|
objectEvent = &gObjectEvents[gPlayerAvatar.objectEventId];
|
|
|
|
if (ObjectEventClearHeldMovementIfFinished(objectEvent))
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
|
|
|
CameraObjectReset1();
|
|
|
|
ScriptContext2_Disable();
|
2019-11-21 04:55:44 +01:00
|
|
|
ObjectEventSetHeldMovement(objectEvent, GetWalkNormalMovementAction(DIR_EAST));
|
2020-06-20 01:58:56 +02:00
|
|
|
DestroyTask(FindTaskIdByFunc(Task_EscalatorWarpIn));
|
2018-05-11 01:36:57 +02:00
|
|
|
}
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
#undef tState
|
|
|
|
|
|
|
|
#define tState data[0]
|
|
|
|
#define tMonId data[1]
|
|
|
|
|
2018-05-11 01:36:57 +02:00
|
|
|
bool8 FldEff_UseWaterfall(void)
|
|
|
|
{
|
|
|
|
u8 taskId;
|
2020-06-20 01:58:56 +02:00
|
|
|
taskId = CreateTask(Task_UseWaterfall, 0xff);
|
2020-06-24 22:27:00 +02:00
|
|
|
gTasks[taskId].tMonId = gFieldEffectArguments[0];
|
2020-06-20 01:58:56 +02:00
|
|
|
Task_UseWaterfall(taskId);
|
2018-05-11 01:36:57 +02:00
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2020-06-20 01:58:56 +02:00
|
|
|
static void Task_UseWaterfall(u8 taskId)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2020-06-24 22:27:00 +02:00
|
|
|
while (sWaterfallFieldEffectFuncs[gTasks[taskId].tState](&gTasks[taskId], &gObjectEvents[gPlayerAvatar.objectEventId]));
|
2018-05-11 01:36:57 +02:00
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static bool8 WaterfallFieldEffect_Init(struct Task *task, struct ObjectEvent *objectEvent)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
|
|
|
ScriptContext2_Enable();
|
|
|
|
gPlayerAvatar.preventStep = TRUE;
|
2020-06-24 22:27:00 +02:00
|
|
|
task->tState++;
|
2018-05-11 01:36:57 +02:00
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static bool8 WaterfallFieldEffect_ShowMon(struct Task *task, struct ObjectEvent *objectEvent)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
|
|
|
ScriptContext2_Enable();
|
2019-11-21 04:55:44 +01:00
|
|
|
if (!ObjectEventIsMovementOverridden(objectEvent))
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2019-11-21 04:55:44 +01:00
|
|
|
ObjectEventClearHeldMovementIfFinished(objectEvent);
|
2020-06-24 22:27:00 +02:00
|
|
|
gFieldEffectArguments[0] = task->tMonId;
|
2018-05-11 01:36:57 +02:00
|
|
|
FieldEffectStart(FLDEFF_FIELD_MOVE_SHOW_MON_INIT);
|
2020-06-24 22:27:00 +02:00
|
|
|
task->tState++;
|
2018-05-11 01:36:57 +02:00
|
|
|
}
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static bool8 WaterfallFieldEffect_WaitForShowMon(struct Task *task, struct ObjectEvent *objectEvent)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
|
|
|
if (FieldEffectActiveListContains(FLDEFF_FIELD_MOVE_SHOW_MON))
|
|
|
|
{
|
|
|
|
return FALSE;
|
|
|
|
}
|
2020-06-24 22:27:00 +02:00
|
|
|
task->tState++;
|
2018-05-11 01:36:57 +02:00
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static bool8 WaterfallFieldEffect_RideUp(struct Task *task, struct ObjectEvent *objectEvent)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2019-11-21 04:55:44 +01:00
|
|
|
ObjectEventSetHeldMovement(objectEvent, GetWalkSlowMovementAction(DIR_NORTH));
|
2020-06-24 22:27:00 +02:00
|
|
|
task->tState++;
|
2018-05-11 01:36:57 +02:00
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static bool8 WaterfallFieldEffect_ContinueRideOrEnd(struct Task *task, struct ObjectEvent *objectEvent)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2019-11-21 04:55:44 +01:00
|
|
|
if (!ObjectEventClearHeldMovementIfFinished(objectEvent))
|
2018-05-11 01:36:57 +02:00
|
|
|
return FALSE;
|
2020-06-24 22:27:00 +02:00
|
|
|
|
2019-11-21 04:55:44 +01:00
|
|
|
if (MetatileBehavior_IsWaterfall(objectEvent->currentMetatileBehavior))
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2020-06-24 22:27:00 +02:00
|
|
|
// Still ascending waterfall, back to WaterfallFieldEffect_RideUp
|
|
|
|
task->tState = 3;
|
2018-05-11 01:36:57 +02:00
|
|
|
return TRUE;
|
|
|
|
}
|
2020-06-24 22:27:00 +02:00
|
|
|
|
2018-05-11 01:36:57 +02:00
|
|
|
ScriptContext2_Disable();
|
|
|
|
gPlayerAvatar.preventStep = FALSE;
|
2020-06-20 01:58:56 +02:00
|
|
|
DestroyTask(FindTaskIdByFunc(Task_UseWaterfall));
|
2018-05-11 01:36:57 +02:00
|
|
|
FieldEffectActiveListRemove(FLDEFF_USE_WATERFALL);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
#undef tState
|
|
|
|
#undef tMonId
|
|
|
|
|
2018-05-11 01:36:57 +02:00
|
|
|
bool8 FldEff_UseDive(void)
|
|
|
|
{
|
|
|
|
u8 taskId;
|
2020-06-20 01:58:56 +02:00
|
|
|
taskId = CreateTask(Task_UseDive, 0xff);
|
2018-05-11 01:36:57 +02:00
|
|
|
gTasks[taskId].data[15] = gFieldEffectArguments[0];
|
|
|
|
gTasks[taskId].data[14] = gFieldEffectArguments[1];
|
2020-06-20 01:58:56 +02:00
|
|
|
Task_UseDive(taskId);
|
2018-05-11 01:36:57 +02:00
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2020-06-20 01:58:56 +02:00
|
|
|
void Task_UseDive(u8 taskId)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2020-06-20 01:58:56 +02:00
|
|
|
while (sDiveFieldEffectFuncs[gTasks[taskId].data[0]](&gTasks[taskId]));
|
2018-05-11 01:36:57 +02:00
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static bool8 DiveFieldEffect_Init(struct Task *task)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
|
|
|
gPlayerAvatar.preventStep = TRUE;
|
|
|
|
task->data[0]++;
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static bool8 DiveFieldEffect_ShowMon(struct Task *task)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
|
|
|
ScriptContext2_Enable();
|
|
|
|
gFieldEffectArguments[0] = task->data[15];
|
|
|
|
FieldEffectStart(FLDEFF_FIELD_MOVE_SHOW_MON_INIT);
|
|
|
|
task->data[0]++;
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static bool8 DiveFieldEffect_TryWarp(struct Task *task)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
|
|
|
struct MapPosition mapPosition;
|
|
|
|
PlayerGetDestCoords(&mapPosition.x, &mapPosition.y);
|
2020-06-24 22:27:00 +02:00
|
|
|
|
|
|
|
// Wait for show mon first
|
2018-05-11 01:36:57 +02:00
|
|
|
if (!FieldEffectActiveListContains(FLDEFF_FIELD_MOVE_SHOW_MON))
|
|
|
|
{
|
2020-06-20 01:58:56 +02:00
|
|
|
TryDoDiveWarp(&mapPosition, gObjectEvents[gPlayerAvatar.objectEventId].currentMetatileBehavior);
|
|
|
|
DestroyTask(FindTaskIdByFunc(Task_UseDive));
|
2018-05-11 01:36:57 +02:00
|
|
|
FieldEffectActiveListRemove(FLDEFF_USE_DIVE);
|
|
|
|
}
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2019-12-17 09:24:44 +01:00
|
|
|
void StartLavaridgeGymB1FWarp(u8 priority)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2019-12-17 09:24:44 +01:00
|
|
|
CreateTask(Task_LavaridgeGymB1FWarp, priority);
|
2018-05-11 01:36:57 +02:00
|
|
|
}
|
|
|
|
|
2019-12-17 09:24:44 +01:00
|
|
|
static void Task_LavaridgeGymB1FWarp(u8 taskId)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2019-12-21 11:19:27 +01:00
|
|
|
while (sLavaridgeGymB1FWarpEffectFuncs[gTasks[taskId].data[0]](&gTasks[taskId], &gObjectEvents[gPlayerAvatar.objectEventId], &gSprites[gPlayerAvatar.spriteId]));
|
2018-05-11 01:36:57 +02:00
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static bool8 LavaridgeGymB1FWarpEffect_Init(struct Task *task, struct ObjectEvent *objectEvent, struct Sprite *sprite)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2019-11-21 04:55:44 +01:00
|
|
|
FreezeObjectEvents();
|
2018-05-11 01:36:57 +02:00
|
|
|
CameraObjectReset2();
|
|
|
|
SetCameraPanningCallback(NULL);
|
|
|
|
gPlayerAvatar.preventStep = TRUE;
|
2019-11-21 04:55:44 +01:00
|
|
|
objectEvent->fixedPriority = 1;
|
2018-05-11 01:36:57 +02:00
|
|
|
task->data[1] = 1;
|
|
|
|
task->data[0]++;
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static bool8 LavaridgeGymB1FWarpEffect_CameraShake(struct Task *task, struct ObjectEvent *objectEvent, struct Sprite *sprite)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
|
|
|
SetCameraPanning(0, task->data[1]);
|
|
|
|
task->data[1] = -task->data[1];
|
|
|
|
task->data[2]++;
|
|
|
|
if (task->data[2] > 7)
|
|
|
|
{
|
|
|
|
task->data[2] = 0;
|
|
|
|
task->data[0]++;
|
|
|
|
}
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static bool8 LavaridgeGymB1FWarpEffect_Launch(struct Task *task, struct ObjectEvent *objectEvent, struct Sprite *sprite)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2021-07-07 15:11:52 +02:00
|
|
|
sprite->y2 = 0;
|
2018-05-11 01:36:57 +02:00
|
|
|
task->data[3] = 1;
|
2019-11-21 04:55:44 +01:00
|
|
|
gFieldEffectArguments[0] = objectEvent->currentCoords.x;
|
|
|
|
gFieldEffectArguments[1] = objectEvent->currentCoords.y;
|
2018-05-11 01:36:57 +02:00
|
|
|
gFieldEffectArguments[2] = sprite->subpriority - 1;
|
|
|
|
gFieldEffectArguments[3] = sprite->oam.priority;
|
2020-06-24 22:27:00 +02:00
|
|
|
FieldEffectStart(FLDEFF_ASH_LAUNCH);
|
2020-08-21 00:02:00 +02:00
|
|
|
PlaySE(SE_M_EXPLOSION);
|
2018-05-11 01:36:57 +02:00
|
|
|
task->data[0]++;
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static bool8 LavaridgeGymB1FWarpEffect_Rise(struct Task *task, struct ObjectEvent *objectEvent, struct Sprite *sprite)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
|
|
|
s16 centerToCornerVecY;
|
|
|
|
SetCameraPanning(0, task->data[1]);
|
|
|
|
if (task->data[1] = -task->data[1], ++task->data[2] <= 17)
|
|
|
|
{
|
|
|
|
if (!(task->data[2] & 1) && (task->data[1] <= 3))
|
|
|
|
{
|
|
|
|
task->data[1] <<= 1;
|
|
|
|
}
|
|
|
|
} else if (!(task->data[2] & 4) && (task->data[1] > 0))
|
|
|
|
{
|
|
|
|
task->data[1] >>= 1;
|
|
|
|
}
|
|
|
|
if (task->data[2] > 6)
|
|
|
|
{
|
|
|
|
centerToCornerVecY = -(sprite->centerToCornerVecY << 1);
|
2021-07-07 15:11:52 +02:00
|
|
|
if (sprite->y2 > -(sprite->y + sprite->centerToCornerVecY + gSpriteCoordOffsetY + centerToCornerVecY))
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2021-07-07 15:11:52 +02:00
|
|
|
sprite->y2 -= task->data[3];
|
2018-05-11 01:36:57 +02:00
|
|
|
if (task->data[3] <= 7)
|
|
|
|
{
|
|
|
|
task->data[3]++;
|
|
|
|
}
|
|
|
|
} else
|
|
|
|
{
|
|
|
|
task->data[4] = 1;
|
|
|
|
}
|
|
|
|
}
|
2021-07-07 15:11:52 +02:00
|
|
|
if (task->data[5] == 0 && sprite->y2 < -0x10)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
|
|
|
task->data[5]++;
|
2019-11-21 04:55:44 +01:00
|
|
|
objectEvent->fixedPriority = 1;
|
2018-05-11 01:36:57 +02:00
|
|
|
sprite->oam.priority = 1;
|
2019-12-05 03:00:45 +01:00
|
|
|
sprite->subspriteMode = SUBSPRITES_IGNORE_PRIORITY;
|
2018-05-11 01:36:57 +02:00
|
|
|
}
|
|
|
|
if (task->data[1] == 0 && task->data[4] != 0)
|
|
|
|
{
|
|
|
|
task->data[0]++;
|
|
|
|
}
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static bool8 LavaridgeGymB1FWarpEffect_FadeOut(struct Task *task, struct ObjectEvent *objectEvent, struct Sprite *sprite)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2018-12-08 21:42:36 +01:00
|
|
|
TryFadeOutOldMapMusic();
|
2019-12-17 09:24:44 +01:00
|
|
|
WarpFadeOutScreen();
|
2018-05-11 01:36:57 +02:00
|
|
|
task->data[0]++;
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static bool8 LavaridgeGymB1FWarpEffect_Warp(struct Task *task, struct ObjectEvent *objectEvent, struct Sprite *sprite)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2018-09-05 00:31:37 +02:00
|
|
|
if (!gPaletteFade.active && BGMusicStopped() == TRUE)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2018-09-05 00:31:37 +02:00
|
|
|
WarpIntoMap();
|
2019-12-17 09:24:44 +01:00
|
|
|
gFieldCallback = FieldCB_LavaridgeGymB1FWarpExit;
|
2018-05-11 01:36:57 +02:00
|
|
|
SetMainCallback2(CB2_LoadMap);
|
2019-12-17 09:24:44 +01:00
|
|
|
DestroyTask(FindTaskIdByFunc(Task_LavaridgeGymB1FWarp));
|
2018-05-11 01:36:57 +02:00
|
|
|
}
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2019-12-17 09:24:44 +01:00
|
|
|
static void FieldCB_LavaridgeGymB1FWarpExit(void)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
|
|
|
Overworld_PlaySpecialMapMusic();
|
2019-12-17 09:24:44 +01:00
|
|
|
WarpFadeInScreen();
|
2018-05-11 01:36:57 +02:00
|
|
|
ScriptContext2_Enable();
|
|
|
|
gFieldCallback = NULL;
|
2019-12-17 09:24:44 +01:00
|
|
|
CreateTask(Task_LavaridgeGymB1FWarpExit, 0);
|
2018-05-11 01:36:57 +02:00
|
|
|
}
|
|
|
|
|
2019-12-17 09:24:44 +01:00
|
|
|
static void Task_LavaridgeGymB1FWarpExit(u8 taskId)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2019-12-21 11:19:27 +01:00
|
|
|
while (sLavaridgeGymB1FWarpExitEffectFuncs[gTasks[taskId].data[0]](&gTasks[taskId], &gObjectEvents[gPlayerAvatar.objectEventId], &gSprites[gPlayerAvatar.spriteId]));
|
2018-05-11 01:36:57 +02:00
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static bool8 LavaridgeGymB1FWarpExitEffect_Init(struct Task *task, struct ObjectEvent *objectEvent, struct Sprite *sprite)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
|
|
|
CameraObjectReset2();
|
2019-11-21 04:55:44 +01:00
|
|
|
FreezeObjectEvents();
|
2018-05-11 01:36:57 +02:00
|
|
|
gPlayerAvatar.preventStep = TRUE;
|
2019-11-21 04:55:44 +01:00
|
|
|
objectEvent->invisible = TRUE;
|
2018-05-11 01:36:57 +02:00
|
|
|
task->data[0]++;
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static bool8 LavaridgeGymB1FWarpExitEffect_StartPopOut(struct Task *task, struct ObjectEvent *objectEvent, struct Sprite *sprite)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
|
|
|
if (IsWeatherNotFadingIn())
|
|
|
|
{
|
2019-11-21 04:55:44 +01:00
|
|
|
gFieldEffectArguments[0] = objectEvent->currentCoords.x;
|
|
|
|
gFieldEffectArguments[1] = objectEvent->currentCoords.y;
|
2018-05-11 01:36:57 +02:00
|
|
|
gFieldEffectArguments[2] = sprite->subpriority - 1;
|
|
|
|
gFieldEffectArguments[3] = sprite->oam.priority;
|
2020-06-24 22:27:00 +02:00
|
|
|
task->data[1] = FieldEffectStart(FLDEFF_ASH_PUFF);
|
2018-05-11 01:36:57 +02:00
|
|
|
task->data[0]++;
|
|
|
|
}
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static bool8 LavaridgeGymB1FWarpExitEffect_PopOut(struct Task *task, struct ObjectEvent *objectEvent, struct Sprite *sprite)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
|
|
|
sprite = &gSprites[task->data[1]];
|
|
|
|
if (sprite->animCmdIndex > 1)
|
|
|
|
{
|
|
|
|
task->data[0]++;
|
2019-11-21 04:55:44 +01:00
|
|
|
objectEvent->invisible = FALSE;
|
2018-05-11 01:36:57 +02:00
|
|
|
CameraObjectReset1();
|
2020-08-21 00:02:00 +02:00
|
|
|
PlaySE(SE_M_DIG);
|
2019-11-21 04:55:44 +01:00
|
|
|
ObjectEventSetHeldMovement(objectEvent, GetJumpMovementAction(DIR_EAST));
|
2018-05-11 01:36:57 +02:00
|
|
|
}
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static bool8 LavaridgeGymB1FWarpExitEffect_End(struct Task *task, struct ObjectEvent *objectEvent, struct Sprite *sprite)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2019-11-21 04:55:44 +01:00
|
|
|
if (ObjectEventClearHeldMovementIfFinished(objectEvent))
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
|
|
|
gPlayerAvatar.preventStep = FALSE;
|
|
|
|
ScriptContext2_Disable();
|
2019-11-21 04:55:44 +01:00
|
|
|
UnfreezeObjectEvents();
|
2019-12-17 09:24:44 +01:00
|
|
|
DestroyTask(FindTaskIdByFunc(Task_LavaridgeGymB1FWarpExit));
|
2018-05-11 01:36:57 +02:00
|
|
|
}
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
// For the ash effect when jumping off the Lavaridge Gym B1F warp tiles
|
|
|
|
u8 FldEff_AshLaunch(void)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
|
|
|
u8 spriteId;
|
2020-06-01 16:23:12 +02:00
|
|
|
SetSpritePosToOffsetMapCoords((s16 *)&gFieldEffectArguments[0], (s16 *)&gFieldEffectArguments[1], 8, 8);
|
2020-06-24 22:27:00 +02:00
|
|
|
spriteId = CreateSpriteAtEnd(gFieldEffectObjectTemplatePointers[FLDEFFOBJ_ASH_LAUNCH], gFieldEffectArguments[0], gFieldEffectArguments[1], gFieldEffectArguments[2]);
|
2018-05-11 01:36:57 +02:00
|
|
|
gSprites[spriteId].oam.priority = gFieldEffectArguments[3];
|
2020-06-20 01:58:56 +02:00
|
|
|
gSprites[spriteId].coordOffsetEnabled = TRUE;
|
2018-05-11 01:36:57 +02:00
|
|
|
return spriteId;
|
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
void SpriteCB_AshLaunch(struct Sprite *sprite)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
|
|
|
if (sprite->animEnded)
|
2020-06-24 22:27:00 +02:00
|
|
|
FieldEffectStop(sprite, FLDEFF_ASH_LAUNCH);
|
2018-05-11 01:36:57 +02:00
|
|
|
}
|
|
|
|
|
2019-12-17 09:24:44 +01:00
|
|
|
void StartLavaridgeGym1FWarp(u8 priority)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2019-12-17 09:24:44 +01:00
|
|
|
CreateTask(Task_LavaridgeGym1FWarp, priority);
|
2018-05-11 01:36:57 +02:00
|
|
|
}
|
|
|
|
|
2019-12-17 09:24:44 +01:00
|
|
|
static void Task_LavaridgeGym1FWarp(u8 taskId)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2019-12-21 11:19:27 +01:00
|
|
|
while(sLavaridgeGym1FWarpEffectFuncs[gTasks[taskId].data[0]](&gTasks[taskId], &gObjectEvents[gPlayerAvatar.objectEventId], &gSprites[gPlayerAvatar.spriteId]));
|
2018-05-11 01:36:57 +02:00
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static bool8 LavaridgeGym1FWarpEffect_Init(struct Task *task, struct ObjectEvent *objectEvent, struct Sprite *sprite)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2019-11-21 04:55:44 +01:00
|
|
|
FreezeObjectEvents();
|
2018-05-11 01:36:57 +02:00
|
|
|
CameraObjectReset2();
|
|
|
|
gPlayerAvatar.preventStep = TRUE;
|
2019-11-21 04:55:44 +01:00
|
|
|
objectEvent->fixedPriority = 1;
|
2018-05-11 01:36:57 +02:00
|
|
|
task->data[0]++;
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static bool8 LavaridgeGym1FWarpEffect_AshPuff(struct Task *task, struct ObjectEvent *objectEvent, struct Sprite *sprite)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2019-11-21 04:55:44 +01:00
|
|
|
if (ObjectEventClearHeldMovementIfFinished(objectEvent))
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
|
|
|
if (task->data[1] > 3)
|
|
|
|
{
|
2019-11-21 04:55:44 +01:00
|
|
|
gFieldEffectArguments[0] = objectEvent->currentCoords.x;
|
|
|
|
gFieldEffectArguments[1] = objectEvent->currentCoords.y;
|
2018-05-11 01:36:57 +02:00
|
|
|
gFieldEffectArguments[2] = sprite->subpriority - 1;
|
|
|
|
gFieldEffectArguments[3] = sprite->oam.priority;
|
2020-06-24 22:27:00 +02:00
|
|
|
task->data[1] = FieldEffectStart(FLDEFF_ASH_PUFF);
|
2018-05-11 01:36:57 +02:00
|
|
|
task->data[0]++;
|
|
|
|
} else
|
|
|
|
{
|
|
|
|
task->data[1]++;
|
2019-11-21 04:55:44 +01:00
|
|
|
ObjectEventSetHeldMovement(objectEvent, GetWalkInPlaceFastestMovementAction(objectEvent->facingDirection));
|
2020-08-21 00:02:00 +02:00
|
|
|
PlaySE(SE_LAVARIDGE_FALL_WARP);
|
2018-05-11 01:36:57 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static bool8 LavaridgeGym1FWarpEffect_Disappear(struct Task *task, struct ObjectEvent *objectEvent, struct Sprite *sprite)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
|
|
|
if (gSprites[task->data[1]].animCmdIndex == 2)
|
|
|
|
{
|
2019-11-21 04:55:44 +01:00
|
|
|
objectEvent->invisible = TRUE;
|
2018-05-11 01:36:57 +02:00
|
|
|
task->data[0]++;
|
|
|
|
}
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static bool8 LavaridgeGym1FWarpEffect_FadeOut(struct Task *task, struct ObjectEvent *objectEvent, struct Sprite *sprite)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2020-06-24 22:27:00 +02:00
|
|
|
if (!FieldEffectActiveListContains(FLDEFF_ASH_PUFF))
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2018-12-08 21:42:36 +01:00
|
|
|
TryFadeOutOldMapMusic();
|
2019-12-17 09:24:44 +01:00
|
|
|
WarpFadeOutScreen();
|
2018-05-11 01:36:57 +02:00
|
|
|
task->data[0]++;
|
|
|
|
}
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static bool8 LavaridgeGym1FWarpEffect_Warp(struct Task *task, struct ObjectEvent *objectEvent, struct Sprite *sprite)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2018-09-05 00:31:37 +02:00
|
|
|
if (!gPaletteFade.active && BGMusicStopped() == TRUE)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2018-09-05 00:31:37 +02:00
|
|
|
WarpIntoMap();
|
2019-12-17 09:24:44 +01:00
|
|
|
gFieldCallback = FieldCB_FallWarpExit;
|
2018-05-11 01:36:57 +02:00
|
|
|
SetMainCallback2(CB2_LoadMap);
|
2019-12-17 09:24:44 +01:00
|
|
|
DestroyTask(FindTaskIdByFunc(Task_LavaridgeGym1FWarp));
|
2018-05-11 01:36:57 +02:00
|
|
|
}
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
// For the ash effect when a trainer pops out of ash, or when the player enters/exits a warp in Lavaridge Gym 1F
|
|
|
|
u8 FldEff_AshPuff(void)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
|
|
|
u8 spriteId;
|
2020-06-01 16:23:12 +02:00
|
|
|
SetSpritePosToOffsetMapCoords((s16 *)&gFieldEffectArguments[0], (s16 *)&gFieldEffectArguments[1], 8, 8);
|
2020-06-24 22:27:00 +02:00
|
|
|
spriteId = CreateSpriteAtEnd(gFieldEffectObjectTemplatePointers[FLDEFFOBJ_ASH_PUFF], gFieldEffectArguments[0], gFieldEffectArguments[1], gFieldEffectArguments[2]);
|
2018-05-11 01:36:57 +02:00
|
|
|
gSprites[spriteId].oam.priority = gFieldEffectArguments[3];
|
2020-06-20 01:58:56 +02:00
|
|
|
gSprites[spriteId].coordOffsetEnabled = TRUE;
|
2018-05-11 01:36:57 +02:00
|
|
|
return spriteId;
|
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
void SpriteCB_AshPuff(struct Sprite *sprite)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
|
|
|
if (sprite->animEnded)
|
2020-06-24 22:27:00 +02:00
|
|
|
FieldEffectStop(sprite, FLDEFF_ASH_PUFF);
|
2018-05-11 01:36:57 +02:00
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
#define tState data[0]
|
|
|
|
#define tSpinDelay data[1]
|
|
|
|
#define tNumTurns data[2]
|
|
|
|
#define tTimer data[14]
|
|
|
|
#define tStartDir data[15]
|
|
|
|
|
2018-10-17 02:11:44 +02:00
|
|
|
void StartEscapeRopeFieldEffect(void)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
|
|
|
ScriptContext2_Enable();
|
2019-11-21 04:55:44 +01:00
|
|
|
FreezeObjectEvents();
|
2020-06-29 17:41:09 +02:00
|
|
|
CreateTask(Task_EscapeRopeWarpOut, 80);
|
2018-05-11 01:36:57 +02:00
|
|
|
}
|
|
|
|
|
2020-06-20 01:58:56 +02:00
|
|
|
static void Task_EscapeRopeWarpOut(u8 taskId)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2020-06-24 22:27:00 +02:00
|
|
|
sEscapeRopeWarpOutEffectFuncs[gTasks[taskId].tState](&gTasks[taskId]);
|
2018-05-11 01:36:57 +02:00
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static void EscapeRopeWarpOutEffect_Init(struct Task *task)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2020-06-24 22:27:00 +02:00
|
|
|
task->tState++;
|
|
|
|
task->tTimer = 64;
|
|
|
|
task->tStartDir = GetPlayerFacingDirection();
|
2018-05-11 01:36:57 +02:00
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static void EscapeRopeWarpOutEffect_Spin(struct Task *task)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2019-11-21 04:55:44 +01:00
|
|
|
struct ObjectEvent *objectEvent;
|
2018-10-17 02:11:44 +02:00
|
|
|
u8 spinDirections[5] = {DIR_SOUTH, DIR_WEST, DIR_EAST, DIR_NORTH, DIR_SOUTH};
|
2020-06-24 22:27:00 +02:00
|
|
|
if (task->tTimer != 0 && (--task->tTimer) == 0)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2018-12-08 21:42:36 +01:00
|
|
|
TryFadeOutOldMapMusic();
|
2019-12-17 09:24:44 +01:00
|
|
|
WarpFadeOutScreen();
|
2018-05-11 01:36:57 +02:00
|
|
|
}
|
2019-11-21 04:55:44 +01:00
|
|
|
objectEvent = &gObjectEvents[gPlayerAvatar.objectEventId];
|
|
|
|
if (!ObjectEventIsMovementOverridden(objectEvent) || ObjectEventClearHeldMovementIfFinished(objectEvent))
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2020-06-24 22:27:00 +02:00
|
|
|
if (task->tTimer == 0 && !gPaletteFade.active && BGMusicStopped() == TRUE)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2020-06-24 22:27:00 +02:00
|
|
|
SetObjectEventDirection(objectEvent, task->tStartDir);
|
2018-12-27 23:30:47 +01:00
|
|
|
SetWarpDestinationToEscapeWarp();
|
2018-09-05 00:31:37 +02:00
|
|
|
WarpIntoMap();
|
2020-06-20 01:58:56 +02:00
|
|
|
gFieldCallback = FieldCallback_EscapeRopeWarpIn;
|
2018-05-11 01:36:57 +02:00
|
|
|
SetMainCallback2(CB2_LoadMap);
|
2020-06-20 01:58:56 +02:00
|
|
|
DestroyTask(FindTaskIdByFunc(Task_EscapeRopeWarpOut));
|
2021-08-25 00:59:32 +02:00
|
|
|
}
|
2020-06-24 22:27:00 +02:00
|
|
|
else if (task->tSpinDelay == 0 || (--task->tSpinDelay) == 0)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2019-11-21 04:55:44 +01:00
|
|
|
ObjectEventSetHeldMovement(objectEvent, GetFaceDirectionMovementAction(spinDirections[objectEvent->facingDirection]));
|
2020-06-24 22:27:00 +02:00
|
|
|
if (task->tNumTurns < 12)
|
|
|
|
task->tNumTurns++;
|
|
|
|
task->tSpinDelay = 8 >> (task->tNumTurns >> 2);
|
2018-05-11 01:36:57 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
void (*const sEscapeRopeWarpInEffectFuncs[])(struct Task *) = {
|
|
|
|
EscapeRopeWarpInEffect_Init,
|
|
|
|
EscapeRopeWarpInEffect_Spin
|
2018-05-11 01:36:57 +02:00
|
|
|
};
|
|
|
|
|
2020-06-20 01:58:56 +02:00
|
|
|
static void FieldCallback_EscapeRopeWarpIn(void)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
|
|
|
Overworld_PlaySpecialMapMusic();
|
2019-12-17 09:24:44 +01:00
|
|
|
WarpFadeInScreen();
|
2018-05-11 01:36:57 +02:00
|
|
|
ScriptContext2_Enable();
|
2019-11-21 04:55:44 +01:00
|
|
|
FreezeObjectEvents();
|
2018-05-11 01:36:57 +02:00
|
|
|
gFieldCallback = NULL;
|
2019-11-21 04:55:44 +01:00
|
|
|
gObjectEvents[gPlayerAvatar.objectEventId].invisible = TRUE;
|
2020-06-20 01:58:56 +02:00
|
|
|
CreateTask(Task_EscapeRopeWarpIn, 0);
|
2018-05-11 01:36:57 +02:00
|
|
|
}
|
|
|
|
|
2020-06-20 01:58:56 +02:00
|
|
|
static void Task_EscapeRopeWarpIn(u8 taskId)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2020-06-24 22:27:00 +02:00
|
|
|
sEscapeRopeWarpInEffectFuncs[gTasks[taskId].tState](&gTasks[taskId]);
|
2018-05-11 01:36:57 +02:00
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static void EscapeRopeWarpInEffect_Init(struct Task *task)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
|
|
|
if (IsWeatherNotFadingIn())
|
|
|
|
{
|
2020-06-24 22:27:00 +02:00
|
|
|
task->tState++;
|
|
|
|
task->tStartDir = GetPlayerFacingDirection();
|
2018-05-11 01:36:57 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static void EscapeRopeWarpInEffect_Spin(struct Task *task)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2020-06-20 01:58:56 +02:00
|
|
|
u8 spinDirections[5] = {DIR_SOUTH, DIR_WEST, DIR_EAST, DIR_NORTH, DIR_SOUTH};
|
2019-11-21 04:55:44 +01:00
|
|
|
struct ObjectEvent *objectEvent = &gObjectEvents[gPlayerAvatar.objectEventId];
|
2020-06-24 22:27:00 +02:00
|
|
|
if (task->tSpinDelay == 0 || (--task->tSpinDelay) == 0)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2019-11-21 04:55:44 +01:00
|
|
|
if (ObjectEventIsMovementOverridden(objectEvent) && !ObjectEventClearHeldMovementIfFinished(objectEvent))
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
2020-06-24 22:27:00 +02:00
|
|
|
if (task->tNumTurns >= 32 && task->tStartDir == GetPlayerFacingDirection())
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2019-11-21 04:55:44 +01:00
|
|
|
objectEvent->invisible = FALSE;
|
2018-05-11 01:36:57 +02:00
|
|
|
ScriptContext2_Disable();
|
2019-11-21 04:55:44 +01:00
|
|
|
UnfreezeObjectEvents();
|
2020-06-20 01:58:56 +02:00
|
|
|
DestroyTask(FindTaskIdByFunc(Task_EscapeRopeWarpIn));
|
2018-05-11 01:36:57 +02:00
|
|
|
return;
|
|
|
|
}
|
2019-11-21 04:55:44 +01:00
|
|
|
ObjectEventSetHeldMovement(objectEvent, GetFaceDirectionMovementAction(spinDirections[objectEvent->facingDirection]));
|
2020-06-24 22:27:00 +02:00
|
|
|
if (task->tNumTurns < 32)
|
|
|
|
task->tNumTurns++;
|
|
|
|
task->tSpinDelay = task->tNumTurns >> 2;
|
2018-05-11 01:36:57 +02:00
|
|
|
}
|
2019-11-21 04:55:44 +01:00
|
|
|
objectEvent->invisible ^= 1;
|
2018-05-11 01:36:57 +02:00
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
#undef tState
|
|
|
|
#undef tSpinDelay
|
|
|
|
#undef tNumTurns
|
|
|
|
#undef tTimer
|
|
|
|
#undef tStartDir
|
|
|
|
|
|
|
|
#define tState data[0]
|
|
|
|
|
2020-06-20 01:58:56 +02:00
|
|
|
void FldEff_TeleportWarpOut(void)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2020-06-20 01:58:56 +02:00
|
|
|
CreateTask(Task_TeleportWarpOut, 0);
|
2018-05-11 01:36:57 +02:00
|
|
|
}
|
|
|
|
|
2020-06-20 01:58:56 +02:00
|
|
|
static void (*const sTeleportWarpOutFieldEffectFuncs[])(struct Task *) = {
|
2020-06-24 22:27:00 +02:00
|
|
|
TeleportWarpOutFieldEffect_Init,
|
|
|
|
TeleportWarpOutFieldEffect_SpinGround,
|
|
|
|
TeleportWarpOutFieldEffect_SpinExit,
|
|
|
|
TeleportWarpOutFieldEffect_End
|
2018-05-11 01:36:57 +02:00
|
|
|
};
|
|
|
|
|
2020-06-20 01:58:56 +02:00
|
|
|
static void Task_TeleportWarpOut(u8 taskId)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2020-06-24 22:27:00 +02:00
|
|
|
sTeleportWarpOutFieldEffectFuncs[gTasks[taskId].tState](&gTasks[taskId]);
|
2018-05-11 01:36:57 +02:00
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static void TeleportWarpOutFieldEffect_Init(struct Task *task)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
|
|
|
ScriptContext2_Enable();
|
2019-11-21 04:55:44 +01:00
|
|
|
FreezeObjectEvents();
|
2018-05-11 01:36:57 +02:00
|
|
|
CameraObjectReset2();
|
2018-06-14 00:51:26 +02:00
|
|
|
task->data[15] = GetPlayerFacingDirection();
|
2020-06-24 22:27:00 +02:00
|
|
|
task->tState++;
|
2018-05-11 01:36:57 +02:00
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static void TeleportWarpOutFieldEffect_SpinGround(struct Task *task)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
|
|
|
u8 spinDirections[5] = {DIR_SOUTH, DIR_WEST, DIR_EAST, DIR_NORTH, DIR_SOUTH};
|
2019-11-21 04:55:44 +01:00
|
|
|
struct ObjectEvent *objectEvent = &gObjectEvents[gPlayerAvatar.objectEventId];
|
2018-05-11 01:36:57 +02:00
|
|
|
if (task->data[1] == 0 || (--task->data[1]) == 0)
|
|
|
|
{
|
2019-11-21 04:55:44 +01:00
|
|
|
ObjectEventTurn(objectEvent, spinDirections[objectEvent->facingDirection]);
|
2018-05-11 01:36:57 +02:00
|
|
|
task->data[1] = 8;
|
|
|
|
task->data[2]++;
|
|
|
|
}
|
2019-11-21 04:55:44 +01:00
|
|
|
if (task->data[2] > 7 && task->data[15] == objectEvent->facingDirection)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2020-06-24 22:27:00 +02:00
|
|
|
task->tState++;
|
2018-05-11 01:36:57 +02:00
|
|
|
task->data[1] = 4;
|
|
|
|
task->data[2] = 8;
|
|
|
|
task->data[3] = 1;
|
2020-08-21 00:02:00 +02:00
|
|
|
PlaySE(SE_WARP_IN);
|
2018-05-11 01:36:57 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static void TeleportWarpOutFieldEffect_SpinExit(struct Task *task)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
|
|
|
u8 spinDirections[5] = {DIR_SOUTH, DIR_WEST, DIR_EAST, DIR_NORTH, DIR_SOUTH};
|
2019-11-21 04:55:44 +01:00
|
|
|
struct ObjectEvent *objectEvent = &gObjectEvents[gPlayerAvatar.objectEventId];
|
2018-05-11 01:36:57 +02:00
|
|
|
struct Sprite *sprite = &gSprites[gPlayerAvatar.spriteId];
|
|
|
|
if ((--task->data[1]) <= 0)
|
|
|
|
{
|
|
|
|
task->data[1] = 4;
|
2019-11-21 04:55:44 +01:00
|
|
|
ObjectEventTurn(objectEvent, spinDirections[objectEvent->facingDirection]);
|
2018-05-11 01:36:57 +02:00
|
|
|
}
|
2021-07-07 15:11:52 +02:00
|
|
|
sprite->y -= task->data[3];
|
2018-05-11 01:36:57 +02:00
|
|
|
task->data[4] += task->data[3];
|
|
|
|
if ((--task->data[2]) <= 0 && (task->data[2] = 4, task->data[3] < 8))
|
|
|
|
{
|
|
|
|
task->data[3] <<= 1;
|
|
|
|
}
|
2019-12-05 03:00:45 +01:00
|
|
|
if (task->data[4] > 8 && (sprite->oam.priority = 1, sprite->subspriteMode != SUBSPRITES_OFF))
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2019-12-05 03:00:45 +01:00
|
|
|
sprite->subspriteMode = SUBSPRITES_IGNORE_PRIORITY;
|
2018-05-11 01:36:57 +02:00
|
|
|
}
|
|
|
|
if (task->data[4] >= 0xa8)
|
|
|
|
{
|
2020-06-24 22:27:00 +02:00
|
|
|
task->tState++;
|
2018-12-08 21:42:36 +01:00
|
|
|
TryFadeOutOldMapMusic();
|
2019-12-17 09:24:44 +01:00
|
|
|
WarpFadeOutScreen();
|
2018-05-11 01:36:57 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static void TeleportWarpOutFieldEffect_End(struct Task *task)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
|
|
|
if (!gPaletteFade.active)
|
|
|
|
{
|
|
|
|
if (task->data[5] == FALSE)
|
|
|
|
{
|
2018-12-25 18:02:41 +01:00
|
|
|
ClearMirageTowerPulseBlendEffect();
|
2018-05-11 01:36:57 +02:00
|
|
|
task->data[5] = TRUE;
|
|
|
|
}
|
|
|
|
|
2018-09-05 00:31:37 +02:00
|
|
|
if (BGMusicStopped() == TRUE)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2018-12-27 23:30:47 +01:00
|
|
|
SetWarpDestinationToLastHealLocation();
|
2018-09-05 00:31:37 +02:00
|
|
|
WarpIntoMap();
|
2018-05-11 01:36:57 +02:00
|
|
|
SetMainCallback2(CB2_LoadMap);
|
2020-06-20 01:58:56 +02:00
|
|
|
gFieldCallback = FieldCallback_TeleportWarpIn;
|
|
|
|
DestroyTask(FindTaskIdByFunc(Task_TeleportWarpOut));
|
2018-05-11 01:36:57 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-20 01:58:56 +02:00
|
|
|
static void FieldCallback_TeleportWarpIn(void)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
|
|
|
Overworld_PlaySpecialMapMusic();
|
2019-12-17 09:24:44 +01:00
|
|
|
WarpFadeInScreen();
|
2018-05-11 01:36:57 +02:00
|
|
|
ScriptContext2_Enable();
|
2019-11-21 04:55:44 +01:00
|
|
|
FreezeObjectEvents();
|
2018-05-11 01:36:57 +02:00
|
|
|
gFieldCallback = NULL;
|
2019-11-21 04:55:44 +01:00
|
|
|
gObjectEvents[gPlayerAvatar.objectEventId].invisible = TRUE;
|
2018-05-11 01:36:57 +02:00
|
|
|
CameraObjectReset2();
|
2020-06-20 01:58:56 +02:00
|
|
|
CreateTask(Task_TeleportWarpIn, 0);
|
2018-05-11 01:36:57 +02:00
|
|
|
}
|
|
|
|
|
2020-06-20 01:58:56 +02:00
|
|
|
void (*const sTeleportWarpInFieldEffectFuncs[])(struct Task *) = {
|
2020-06-24 22:27:00 +02:00
|
|
|
TeleportWarpInFieldEffect_Init,
|
|
|
|
TeleportWarpInFieldEffect_SpinEnter,
|
|
|
|
TeleportWarpInFieldEffect_SpinGround
|
2018-05-11 01:36:57 +02:00
|
|
|
};
|
|
|
|
|
2020-06-20 01:58:56 +02:00
|
|
|
static void Task_TeleportWarpIn(u8 taskId)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2020-06-20 01:58:56 +02:00
|
|
|
sTeleportWarpInFieldEffectFuncs[gTasks[taskId].data[0]](&gTasks[taskId]);
|
2018-05-11 01:36:57 +02:00
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static void TeleportWarpInFieldEffect_Init(struct Task *task)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
|
|
|
struct Sprite *sprite;
|
|
|
|
s16 centerToCornerVecY;
|
|
|
|
if (IsWeatherNotFadingIn())
|
|
|
|
{
|
|
|
|
sprite = &gSprites[gPlayerAvatar.spriteId];
|
|
|
|
centerToCornerVecY = -(sprite->centerToCornerVecY << 1);
|
2021-07-07 15:11:52 +02:00
|
|
|
sprite->y2 = -(sprite->y + sprite->centerToCornerVecY + gSpriteCoordOffsetY + centerToCornerVecY);
|
2019-11-21 04:55:44 +01:00
|
|
|
gObjectEvents[gPlayerAvatar.objectEventId].invisible = FALSE;
|
2018-05-11 01:36:57 +02:00
|
|
|
task->data[0]++;
|
|
|
|
task->data[1] = 8;
|
|
|
|
task->data[2] = 1;
|
|
|
|
task->data[14] = sprite->subspriteMode;
|
2018-06-14 00:51:26 +02:00
|
|
|
task->data[15] = GetPlayerFacingDirection();
|
2020-08-21 00:02:00 +02:00
|
|
|
PlaySE(SE_WARP_IN);
|
2018-05-11 01:36:57 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static void TeleportWarpInFieldEffect_SpinEnter(struct Task *task)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2020-06-20 01:58:56 +02:00
|
|
|
u8 spinDirections[5] = {DIR_SOUTH, DIR_WEST, DIR_EAST, DIR_NORTH, DIR_SOUTH};
|
2019-11-21 04:55:44 +01:00
|
|
|
struct ObjectEvent *objectEvent = &gObjectEvents[gPlayerAvatar.objectEventId];
|
2018-05-11 01:36:57 +02:00
|
|
|
struct Sprite *sprite = &gSprites[gPlayerAvatar.spriteId];
|
2021-07-07 15:11:52 +02:00
|
|
|
if ((sprite->y2 += task->data[1]) >= -8)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
|
|
|
if (task->data[13] == 0)
|
|
|
|
{
|
|
|
|
task->data[13]++;
|
2019-11-21 04:55:44 +01:00
|
|
|
objectEvent->triggerGroundEffectsOnMove = 1;
|
2018-05-11 01:36:57 +02:00
|
|
|
sprite->subspriteMode = task->data[14];
|
|
|
|
}
|
|
|
|
} else
|
|
|
|
{
|
|
|
|
sprite->oam.priority = 1;
|
2019-12-05 03:00:45 +01:00
|
|
|
if (sprite->subspriteMode != SUBSPRITES_OFF)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2019-12-05 03:00:45 +01:00
|
|
|
sprite->subspriteMode = SUBSPRITES_IGNORE_PRIORITY;
|
2018-05-11 01:36:57 +02:00
|
|
|
}
|
|
|
|
}
|
2021-07-07 15:11:52 +02:00
|
|
|
if (sprite->y2 >= -0x30 && task->data[1] > 1 && !(sprite->y2 & 1))
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
|
|
|
task->data[1]--;
|
|
|
|
}
|
|
|
|
if ((--task->data[2]) == 0)
|
|
|
|
{
|
|
|
|
task->data[2] = 4;
|
2019-11-21 04:55:44 +01:00
|
|
|
ObjectEventTurn(objectEvent, spinDirections[objectEvent->facingDirection]);
|
2018-05-11 01:36:57 +02:00
|
|
|
}
|
2021-07-07 15:11:52 +02:00
|
|
|
if (sprite->y2 >= 0)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2021-07-07 15:11:52 +02:00
|
|
|
sprite->y2 = 0;
|
2018-05-11 01:36:57 +02:00
|
|
|
task->data[0]++;
|
|
|
|
task->data[1] = 1;
|
|
|
|
task->data[2] = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static void TeleportWarpInFieldEffect_SpinGround(struct Task *task)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2020-06-20 01:58:56 +02:00
|
|
|
u8 spinDirections[5] = {DIR_SOUTH, DIR_WEST, DIR_EAST, DIR_NORTH, DIR_SOUTH};
|
2019-11-21 04:55:44 +01:00
|
|
|
struct ObjectEvent *objectEvent = &gObjectEvents[gPlayerAvatar.objectEventId];
|
2018-05-11 01:36:57 +02:00
|
|
|
if ((--task->data[1]) == 0)
|
|
|
|
{
|
2019-11-21 04:55:44 +01:00
|
|
|
ObjectEventTurn(objectEvent, spinDirections[objectEvent->facingDirection]);
|
2018-05-11 01:36:57 +02:00
|
|
|
task->data[1] = 8;
|
2019-11-21 04:55:44 +01:00
|
|
|
if ((++task->data[2]) > 4 && task->data[14] == objectEvent->facingDirection)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
|
|
|
ScriptContext2_Disable();
|
|
|
|
CameraObjectReset1();
|
2019-11-21 04:55:44 +01:00
|
|
|
UnfreezeObjectEvents();
|
2020-06-20 01:58:56 +02:00
|
|
|
DestroyTask(FindTaskIdByFunc(Task_TeleportWarpIn));
|
2018-05-11 01:36:57 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
// Task data for Task_FieldMoveShowMonOutDoors
|
|
|
|
#define tState data[0]
|
|
|
|
#define tWinHoriz data[1]
|
|
|
|
#define tWinVert data[2]
|
|
|
|
#define tWinIn data[3]
|
|
|
|
#define tWinOut data[4]
|
|
|
|
#define tBgHoriz data[5]
|
|
|
|
#define tBgVert data[6]
|
|
|
|
#define tMonSpriteId data[15]
|
|
|
|
|
|
|
|
// Sprite data for field move mon sprite
|
|
|
|
#define sSpecies data[0]
|
|
|
|
#define sOnscreenTimer data[1]
|
|
|
|
#define sSlidOffscreen data[7]
|
|
|
|
|
|
|
|
// There are two variants (outdoor/indoor) of the "show mon for a field move" effect
|
|
|
|
// Outdoor has a black background with thick white streaks and appears from the right by stretching vertically and horizontally
|
|
|
|
// Indoor has blue background with thin white streaks and appears from the left by stretching horizontally
|
|
|
|
// For both the background streaks move to the right, and the mon sprite enters from the right and exits left
|
2018-05-11 01:36:57 +02:00
|
|
|
bool8 FldEff_FieldMoveShowMon(void)
|
|
|
|
{
|
|
|
|
u8 taskId;
|
2019-03-01 07:49:11 +01:00
|
|
|
if (IsMapTypeOutdoors(GetCurrentMapType()) == TRUE)
|
2020-06-20 01:58:56 +02:00
|
|
|
taskId = CreateTask(Task_FieldMoveShowMonOutdoors, 0xff);
|
2020-06-24 22:27:00 +02:00
|
|
|
else
|
2020-06-20 01:58:56 +02:00
|
|
|
taskId = CreateTask(Task_FieldMoveShowMonIndoors, 0xff);
|
2020-06-24 22:27:00 +02:00
|
|
|
|
|
|
|
gTasks[taskId].tMonSpriteId = InitFieldMoveMonSprite(gFieldEffectArguments[0], gFieldEffectArguments[1], gFieldEffectArguments[2]);
|
2018-05-11 01:36:57 +02:00
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2021-11-07 19:54:44 +01:00
|
|
|
#define SHOW_MON_CRY_NO_DUCKING (1 << 31)
|
|
|
|
|
2018-05-11 01:36:57 +02:00
|
|
|
bool8 FldEff_FieldMoveShowMonInit(void)
|
|
|
|
{
|
|
|
|
struct Pokemon *pokemon;
|
2021-11-07 19:54:44 +01:00
|
|
|
bool32 noDucking = gFieldEffectArguments[0] & SHOW_MON_CRY_NO_DUCKING;
|
2018-05-11 01:36:57 +02:00
|
|
|
pokemon = &gPlayerParty[(u8)gFieldEffectArguments[0]];
|
|
|
|
gFieldEffectArguments[0] = GetMonData(pokemon, MON_DATA_SPECIES);
|
|
|
|
gFieldEffectArguments[1] = GetMonData(pokemon, MON_DATA_OT_ID);
|
|
|
|
gFieldEffectArguments[2] = GetMonData(pokemon, MON_DATA_PERSONALITY);
|
2021-11-07 19:54:44 +01:00
|
|
|
gFieldEffectArguments[0] |= noDucking;
|
2018-05-11 01:36:57 +02:00
|
|
|
FieldEffectStart(FLDEFF_FIELD_MOVE_SHOW_MON);
|
|
|
|
FieldEffectActiveListRemove(FLDEFF_FIELD_MOVE_SHOW_MON_INIT);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2020-06-20 01:58:56 +02:00
|
|
|
void (*const sFieldMoveShowMonOutdoorsEffectFuncs[])(struct Task *) = {
|
2020-06-24 22:27:00 +02:00
|
|
|
FieldMoveShowMonOutdoorsEffect_Init,
|
|
|
|
FieldMoveShowMonOutdoorsEffect_LoadGfx,
|
|
|
|
FieldMoveShowMonOutdoorsEffect_CreateBanner,
|
|
|
|
FieldMoveShowMonOutdoorsEffect_WaitForMon,
|
|
|
|
FieldMoveShowMonOutdoorsEffect_ShrinkBanner,
|
|
|
|
FieldMoveShowMonOutdoorsEffect_RestoreBg,
|
|
|
|
FieldMoveShowMonOutdoorsEffect_End,
|
2018-05-11 01:36:57 +02:00
|
|
|
};
|
|
|
|
|
2020-06-20 01:58:56 +02:00
|
|
|
static void Task_FieldMoveShowMonOutdoors(u8 taskId)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2020-06-24 22:27:00 +02:00
|
|
|
sFieldMoveShowMonOutdoorsEffectFuncs[gTasks[taskId].tState](&gTasks[taskId]);
|
2018-05-11 01:36:57 +02:00
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static void FieldMoveShowMonOutdoorsEffect_Init(struct Task *task)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
|
|
|
task->data[11] = REG_WININ;
|
|
|
|
task->data[12] = REG_WINOUT;
|
Undo PokeCodec's PRs
This commit undoes most of PokeCodec's PRs after the debate in chat. Some
harmless or completely superseded PRs have been left alone, as there is not
much benefit in attempting to undo them.
Reverts #1104, #1108, #1115, #1118, #1119, #1124, #1126, #1127, #1132, #1136,
#1137, #1139, #1140, #1144, #1148, #1149, #1150, #1153, #1155, #1177, #1179,
#1180, #1181, #1182 and #1183.
2020-09-13 09:22:50 +02:00
|
|
|
StoreWordInTwoHalfwords(&task->data[13], (u32)gMain.vblankCallback);
|
2020-06-29 17:41:09 +02:00
|
|
|
task->tWinHoriz = WIN_RANGE(DISPLAY_WIDTH, DISPLAY_WIDTH + 1);
|
|
|
|
task->tWinVert = WIN_RANGE(DISPLAY_HEIGHT / 2, DISPLAY_HEIGHT / 2 + 1);
|
2020-06-24 22:27:00 +02:00
|
|
|
task->tWinIn = WININ_WIN0_BG_ALL | WININ_WIN0_OBJ | WININ_WIN0_CLR;
|
|
|
|
task->tWinOut = WINOUT_WIN01_BG1 | WINOUT_WIN01_BG2 | WINOUT_WIN01_BG3 | WINOUT_WIN01_OBJ | WINOUT_WIN01_CLR;
|
|
|
|
SetGpuReg(REG_OFFSET_WIN0H, task->tWinHoriz);
|
|
|
|
SetGpuReg(REG_OFFSET_WIN0V, task->tWinVert);
|
|
|
|
SetGpuReg(REG_OFFSET_WININ, task->tWinIn);
|
|
|
|
SetGpuReg(REG_OFFSET_WINOUT, task->tWinOut);
|
2020-06-20 01:58:56 +02:00
|
|
|
SetVBlankCallback(VBlankCB_FieldMoveShowMonOutdoors);
|
2020-06-24 22:27:00 +02:00
|
|
|
task->tState++;
|
2018-05-11 01:36:57 +02:00
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static void FieldMoveShowMonOutdoorsEffect_LoadGfx(struct Task *task)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2018-11-30 23:16:15 +01:00
|
|
|
u16 offset = ((REG_BG0CNT >> 2) << 14);
|
|
|
|
u16 delta = ((REG_BG0CNT >> 8) << 11);
|
2020-06-24 22:27:00 +02:00
|
|
|
CpuCopy16(sFieldMoveStreaksOutdoors_Gfx, (void *)(VRAM + offset), 0x200);
|
2018-05-11 01:36:57 +02:00
|
|
|
CpuFill32(0, (void *)(VRAM + delta), 0x800);
|
2020-06-24 22:27:00 +02:00
|
|
|
LoadPalette(sFieldMoveStreaksOutdoors_Pal, 0xf0, 0x20);
|
|
|
|
LoadFieldMoveOutdoorStreaksTilemap(delta);
|
|
|
|
task->tState++;
|
2018-05-11 01:36:57 +02:00
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static void FieldMoveShowMonOutdoorsEffect_CreateBanner(struct Task *task)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2020-06-24 22:27:00 +02:00
|
|
|
s16 horiz;
|
|
|
|
s16 vertHi;
|
|
|
|
s16 vertLo;
|
|
|
|
task->tBgHoriz -= 16;
|
|
|
|
horiz = ((u16)task->tWinHoriz >> 8);
|
|
|
|
vertHi = ((u16)task->tWinVert >> 8);
|
|
|
|
vertLo = ((u16)task->tWinVert & 0xff);
|
|
|
|
horiz -= 16;
|
|
|
|
vertHi -= 2;
|
|
|
|
vertLo += 2;
|
|
|
|
|
|
|
|
if (horiz < 0)
|
|
|
|
horiz = 0;
|
|
|
|
|
2020-06-29 17:41:09 +02:00
|
|
|
if (vertHi < DISPLAY_HEIGHT / 4)
|
|
|
|
vertHi = DISPLAY_HEIGHT / 4;
|
2020-06-24 22:27:00 +02:00
|
|
|
|
2020-06-29 17:41:09 +02:00
|
|
|
if (vertLo > DISPLAY_WIDTH / 2)
|
|
|
|
vertLo = DISPLAY_WIDTH / 2;
|
2020-06-24 22:27:00 +02:00
|
|
|
|
|
|
|
task->tWinHoriz = (horiz << 8) | (task->tWinHoriz & 0xff);
|
|
|
|
task->tWinVert = (vertHi << 8) | vertLo;
|
2020-06-29 17:41:09 +02:00
|
|
|
if (horiz == 0 && vertHi == DISPLAY_HEIGHT / 4 && vertLo == DISPLAY_WIDTH / 2)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2020-06-24 22:27:00 +02:00
|
|
|
gSprites[task->tMonSpriteId].callback = SpriteCB_FieldMoveMonSlideOnscreen;
|
|
|
|
task->tState++;
|
2018-05-11 01:36:57 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static void FieldMoveShowMonOutdoorsEffect_WaitForMon(struct Task *task)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2020-06-24 22:27:00 +02:00
|
|
|
task->tBgHoriz -= 16;
|
|
|
|
|
|
|
|
if (gSprites[task->tMonSpriteId].sSlidOffscreen)
|
|
|
|
task->tState++;
|
2018-05-11 01:36:57 +02:00
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static void FieldMoveShowMonOutdoorsEffect_ShrinkBanner(struct Task *task)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2020-06-24 22:27:00 +02:00
|
|
|
s16 vertHi;
|
|
|
|
s16 vertLo;
|
|
|
|
task->tBgHoriz -= 16;
|
|
|
|
vertHi = (task->tWinVert >> 8);
|
|
|
|
vertLo = (task->tWinVert & 0xFF);
|
|
|
|
vertHi += 6;
|
|
|
|
vertLo -= 6;
|
|
|
|
|
2020-06-29 17:41:09 +02:00
|
|
|
if (vertHi > DISPLAY_HEIGHT / 2)
|
|
|
|
vertHi = DISPLAY_HEIGHT / 2;
|
2020-06-24 22:27:00 +02:00
|
|
|
|
2020-06-29 17:41:09 +02:00
|
|
|
if (vertLo < DISPLAY_HEIGHT / 2 + 1)
|
|
|
|
vertLo = DISPLAY_HEIGHT / 2 + 1;
|
2020-06-24 22:27:00 +02:00
|
|
|
|
|
|
|
task->tWinVert = (vertHi << 8) | vertLo;
|
|
|
|
|
2020-06-29 17:41:09 +02:00
|
|
|
if (vertHi == DISPLAY_HEIGHT / 2 && vertLo == DISPLAY_HEIGHT / 2 + 1)
|
2020-06-24 22:27:00 +02:00
|
|
|
task->tState++;
|
2018-05-11 01:36:57 +02:00
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static void FieldMoveShowMonOutdoorsEffect_RestoreBg(struct Task *task)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2018-11-30 23:16:15 +01:00
|
|
|
u16 bg0cnt = (REG_BG0CNT >> 8) << 11;
|
2018-05-11 01:36:57 +02:00
|
|
|
CpuFill32(0, (void *)VRAM + bg0cnt, 0x800);
|
2020-06-29 17:41:09 +02:00
|
|
|
task->tWinHoriz = DISPLAY_WIDTH + 1;
|
|
|
|
task->tWinVert = DISPLAY_HEIGHT + 1;
|
2020-06-24 22:27:00 +02:00
|
|
|
task->tWinIn = task->data[11];
|
|
|
|
task->tWinOut = task->data[12];
|
|
|
|
task->tState++;
|
2018-05-11 01:36:57 +02:00
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static void FieldMoveShowMonOutdoorsEffect_End(struct Task *task)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
|
|
|
IntrCallback callback;
|
|
|
|
LoadWordFromTwoHalfwords((u16 *)&task->data[13], (u32 *)&callback);
|
|
|
|
SetVBlankCallback(callback);
|
2020-06-20 01:58:56 +02:00
|
|
|
InitTextBoxGfxAndPrinters();
|
2020-06-24 22:27:00 +02:00
|
|
|
FreeResourcesAndDestroySprite(&gSprites[task->tMonSpriteId], task->tMonSpriteId);
|
2018-05-11 01:36:57 +02:00
|
|
|
FieldEffectActiveListRemove(FLDEFF_FIELD_MOVE_SHOW_MON);
|
2020-06-20 01:58:56 +02:00
|
|
|
DestroyTask(FindTaskIdByFunc(Task_FieldMoveShowMonOutdoors));
|
2018-05-11 01:36:57 +02:00
|
|
|
}
|
|
|
|
|
2020-06-20 01:58:56 +02:00
|
|
|
static void VBlankCB_FieldMoveShowMonOutdoors(void)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
|
|
|
IntrCallback callback;
|
2020-06-20 01:58:56 +02:00
|
|
|
struct Task *task = &gTasks[FindTaskIdByFunc(Task_FieldMoveShowMonOutdoors)];
|
2018-05-11 01:36:57 +02:00
|
|
|
LoadWordFromTwoHalfwords((u16 *)&task->data[13], (u32 *)&callback);
|
|
|
|
callback();
|
2020-06-24 22:27:00 +02:00
|
|
|
SetGpuReg(REG_OFFSET_WIN0H, task->tWinHoriz);
|
|
|
|
SetGpuReg(REG_OFFSET_WIN0V, task->tWinVert);
|
|
|
|
SetGpuReg(REG_OFFSET_WININ, task->tWinIn);
|
|
|
|
SetGpuReg(REG_OFFSET_WINOUT, task->tWinOut);
|
|
|
|
SetGpuReg(REG_OFFSET_BG0HOFS, task->tBgHoriz);
|
|
|
|
SetGpuReg(REG_OFFSET_BG0VOFS, task->tBgVert);
|
2018-05-11 01:36:57 +02:00
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static void LoadFieldMoveOutdoorStreaksTilemap(u16 offs)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
|
|
|
u16 i;
|
|
|
|
u16 *dest;
|
2020-06-24 22:27:00 +02:00
|
|
|
dest = (u16 *)(VRAM + ARRAY_COUNT(sFieldMoveStreaksOutdoors_Tilemap) + offs);
|
|
|
|
for (i = 0; i < ARRAY_COUNT(sFieldMoveStreaksOutdoors_Tilemap); i++, dest++)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2020-06-24 22:27:00 +02:00
|
|
|
*dest = sFieldMoveStreaksOutdoors_Tilemap[i] | 0xF000;
|
2018-05-11 01:36:57 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
#undef tState
|
|
|
|
#undef tWinHoriz
|
|
|
|
#undef tWinVert
|
|
|
|
#undef tWinIn
|
|
|
|
#undef tWinOut
|
|
|
|
#undef tBgHoriz
|
|
|
|
#undef tBgVert
|
|
|
|
#undef tMonSpriteId
|
|
|
|
|
|
|
|
// Task data for Task_FieldMoveShowMonIndoors
|
|
|
|
#define tState data[0]
|
|
|
|
#define tBgHoriz data[1]
|
|
|
|
#define tBgVert data[2]
|
|
|
|
#define tBgOffsetIdx data[3]
|
|
|
|
#define tBgOffset data[4]
|
|
|
|
#define tMonSpriteId data[15]
|
|
|
|
|
2020-06-20 01:58:56 +02:00
|
|
|
void (*const sFieldMoveShowMonIndoorsEffectFuncs[])(struct Task *) = {
|
2020-06-24 22:27:00 +02:00
|
|
|
FieldMoveShowMonIndoorsEffect_Init,
|
|
|
|
FieldMoveShowMonIndoorsEffect_LoadGfx,
|
|
|
|
FieldMoveShowMonIndoorsEffect_SlideBannerOn,
|
|
|
|
FieldMoveShowMonIndoorsEffect_WaitForMon,
|
|
|
|
FieldMoveShowMonIndoorsEffect_RestoreBg,
|
|
|
|
FieldMoveShowMonIndoorsEffect_SlideBannerOff,
|
|
|
|
FieldMoveShowMonIndoorsEffect_End,
|
2018-05-11 01:36:57 +02:00
|
|
|
};
|
|
|
|
|
2020-06-20 01:58:56 +02:00
|
|
|
static void Task_FieldMoveShowMonIndoors(u8 taskId)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2020-06-24 22:27:00 +02:00
|
|
|
sFieldMoveShowMonIndoorsEffectFuncs[gTasks[taskId].tState](&gTasks[taskId]);
|
2018-05-11 01:36:57 +02:00
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static void FieldMoveShowMonIndoorsEffect_Init(struct Task *task)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2020-06-24 22:27:00 +02:00
|
|
|
SetGpuReg(REG_OFFSET_BG0HOFS, task->tBgHoriz);
|
|
|
|
SetGpuReg(REG_OFFSET_BG0VOFS, task->tBgVert);
|
2018-05-11 01:36:57 +02:00
|
|
|
StoreWordInTwoHalfwords((u16 *)&task->data[13], (u32)gMain.vblankCallback);
|
2020-06-20 01:58:56 +02:00
|
|
|
SetVBlankCallback(VBlankCB_FieldMoveShowMonIndoors);
|
2020-06-24 22:27:00 +02:00
|
|
|
task->tState++;
|
2018-05-11 01:36:57 +02:00
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static void FieldMoveShowMonIndoorsEffect_LoadGfx(struct Task *task)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
|
|
|
u16 offset;
|
|
|
|
u16 delta;
|
|
|
|
offset = ((REG_BG0CNT >> 2) << 14);
|
|
|
|
delta = ((REG_BG0CNT >> 8) << 11);
|
|
|
|
task->data[12] = delta;
|
2020-06-24 22:27:00 +02:00
|
|
|
CpuCopy16(sFieldMoveStreaksIndoors_Gfx, (void *)(VRAM + offset), 0x80);
|
2018-05-11 01:36:57 +02:00
|
|
|
CpuFill32(0, (void *)(VRAM + delta), 0x800);
|
2020-06-24 22:27:00 +02:00
|
|
|
LoadPalette(sFieldMoveStreaksIndoors_Pal, 0xf0, 0x20);
|
|
|
|
task->tState++;
|
2018-05-11 01:36:57 +02:00
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static void FieldMoveShowMonIndoorsEffect_SlideBannerOn(struct Task *task)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2020-06-24 22:27:00 +02:00
|
|
|
if (SlideIndoorBannerOnscreen(task))
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2020-06-29 17:41:09 +02:00
|
|
|
SetGpuReg(REG_OFFSET_WIN1H, WIN_RANGE(0, DISPLAY_WIDTH));
|
|
|
|
SetGpuReg(REG_OFFSET_WIN1V, WIN_RANGE(DISPLAY_HEIGHT / 4, DISPLAY_HEIGHT - DISPLAY_HEIGHT / 4));
|
2020-06-24 22:27:00 +02:00
|
|
|
gSprites[task->tMonSpriteId].callback = SpriteCB_FieldMoveMonSlideOnscreen;
|
|
|
|
task->tState++;
|
2018-05-11 01:36:57 +02:00
|
|
|
}
|
2020-06-24 22:27:00 +02:00
|
|
|
AnimateIndoorShowMonBg(task);
|
2018-05-11 01:36:57 +02:00
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static void FieldMoveShowMonIndoorsEffect_WaitForMon(struct Task *task)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2020-06-24 22:27:00 +02:00
|
|
|
AnimateIndoorShowMonBg(task);
|
|
|
|
if (gSprites[task->tMonSpriteId].sSlidOffscreen)
|
|
|
|
task->tState++;
|
2018-05-11 01:36:57 +02:00
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static void FieldMoveShowMonIndoorsEffect_RestoreBg(struct Task *task)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2020-06-24 22:27:00 +02:00
|
|
|
AnimateIndoorShowMonBg(task);
|
|
|
|
task->tBgOffsetIdx = task->tBgHoriz & 7;
|
|
|
|
task->tBgOffset = 0;
|
2020-06-29 17:41:09 +02:00
|
|
|
SetGpuReg(REG_OFFSET_WIN1H, WIN_RANGE(0xFF, 0xFF));
|
|
|
|
SetGpuReg(REG_OFFSET_WIN1V, WIN_RANGE(0xFF, 0xFF));
|
2020-06-24 22:27:00 +02:00
|
|
|
task->tState++;
|
2018-05-11 01:36:57 +02:00
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static void FieldMoveShowMonIndoorsEffect_SlideBannerOff(struct Task *task)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2020-06-24 22:27:00 +02:00
|
|
|
AnimateIndoorShowMonBg(task);
|
|
|
|
if (SlideIndoorBannerOffscreen(task))
|
|
|
|
task->tState++;
|
2018-05-11 01:36:57 +02:00
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static void FieldMoveShowMonIndoorsEffect_End(struct Task *task)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
|
|
|
IntrCallback intrCallback;
|
|
|
|
u16 bg0cnt;
|
|
|
|
bg0cnt = (REG_BG0CNT >> 8) << 11;
|
|
|
|
CpuFill32(0, (void *)VRAM + bg0cnt, 0x800);
|
|
|
|
LoadWordFromTwoHalfwords((u16 *)&task->data[13], (u32 *)&intrCallback);
|
|
|
|
SetVBlankCallback(intrCallback);
|
2020-06-20 01:58:56 +02:00
|
|
|
InitTextBoxGfxAndPrinters();
|
2020-06-24 22:27:00 +02:00
|
|
|
FreeResourcesAndDestroySprite(&gSprites[task->tMonSpriteId], task->tMonSpriteId);
|
2018-05-11 01:36:57 +02:00
|
|
|
FieldEffectActiveListRemove(FLDEFF_FIELD_MOVE_SHOW_MON);
|
2020-06-20 01:58:56 +02:00
|
|
|
DestroyTask(FindTaskIdByFunc(Task_FieldMoveShowMonIndoors));
|
2018-05-11 01:36:57 +02:00
|
|
|
}
|
|
|
|
|
2020-06-20 01:58:56 +02:00
|
|
|
static void VBlankCB_FieldMoveShowMonIndoors(void)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
|
|
|
IntrCallback intrCallback;
|
|
|
|
struct Task *task;
|
2020-06-20 01:58:56 +02:00
|
|
|
task = &gTasks[FindTaskIdByFunc(Task_FieldMoveShowMonIndoors)];
|
2018-05-11 01:36:57 +02:00
|
|
|
LoadWordFromTwoHalfwords((u16 *)&task->data[13], (u32 *)&intrCallback);
|
|
|
|
intrCallback();
|
2020-06-24 22:27:00 +02:00
|
|
|
SetGpuReg(REG_OFFSET_BG0HOFS, task->tBgHoriz);
|
|
|
|
SetGpuReg(REG_OFFSET_BG0VOFS, task->tBgVert);
|
2018-05-11 01:36:57 +02:00
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static void AnimateIndoorShowMonBg(struct Task *task)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2020-06-24 22:27:00 +02:00
|
|
|
task->tBgHoriz -= 16;
|
|
|
|
task->tBgOffsetIdx += 16;
|
2018-05-11 01:36:57 +02:00
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static bool8 SlideIndoorBannerOnscreen(struct Task *task)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
|
|
|
u16 i;
|
|
|
|
u16 srcOffs;
|
|
|
|
u16 dstOffs;
|
|
|
|
u16 *dest;
|
2020-06-24 22:27:00 +02:00
|
|
|
|
|
|
|
if (task->tBgOffset >= 32)
|
2018-05-11 01:36:57 +02:00
|
|
|
return TRUE;
|
2020-06-24 22:27:00 +02:00
|
|
|
|
|
|
|
dstOffs = (task->tBgOffsetIdx >> 3) & 0x1f;
|
|
|
|
if (dstOffs >= task->tBgOffset)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
|
|
|
dstOffs = (32 - dstOffs) & 0x1f;
|
2020-06-24 22:27:00 +02:00
|
|
|
srcOffs = (32 - task->tBgOffset) & 0x1f;
|
2018-05-11 01:36:57 +02:00
|
|
|
dest = (u16 *)(VRAM + 0x140 + (u16)task->data[12]);
|
2018-11-30 23:16:15 +01:00
|
|
|
for (i = 0; i < 10; i++)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2020-06-24 22:27:00 +02:00
|
|
|
dest[dstOffs + i * 32] = sFieldMoveStreaksIndoors_Tilemap[srcOffs + i * 32];
|
2018-11-30 23:16:15 +01:00
|
|
|
dest[dstOffs + i * 32] |= 0xf000;
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
dest[((dstOffs + 1) & 0x1f) + i * 32] = sFieldMoveStreaksIndoors_Tilemap[((srcOffs + 1) & 0x1f) + i * 32] | 0xf000;
|
2018-11-30 23:16:15 +01:00
|
|
|
dest[((dstOffs + 1) & 0x1f) + i * 32] |= 0xf000;
|
2018-05-11 01:36:57 +02:00
|
|
|
}
|
2020-06-24 22:27:00 +02:00
|
|
|
task->tBgOffset += 2;
|
2018-05-11 01:36:57 +02:00
|
|
|
}
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static bool8 SlideIndoorBannerOffscreen(struct Task *task)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
|
|
|
u16 i;
|
|
|
|
u16 dstOffs;
|
|
|
|
u16 *dest;
|
2020-06-24 22:27:00 +02:00
|
|
|
|
|
|
|
if (task->tBgOffset >= 32)
|
2018-05-11 01:36:57 +02:00
|
|
|
return TRUE;
|
2020-06-24 22:27:00 +02:00
|
|
|
|
|
|
|
dstOffs = task->tBgOffsetIdx >> 3;
|
|
|
|
if (dstOffs >= task->tBgOffset)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2020-06-24 22:27:00 +02:00
|
|
|
dstOffs = (task->tBgHoriz >> 3) & 0x1f;
|
2018-05-11 01:36:57 +02:00
|
|
|
dest = (u16 *)(VRAM + 0x140 + (u16)task->data[12]);
|
2018-11-30 23:16:15 +01:00
|
|
|
for (i = 0; i < 10; i++)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
|
|
|
dest[dstOffs + i * 32] = 0xf000;
|
|
|
|
dest[((dstOffs + 1) & 0x1f) + i * 32] = 0xf000;
|
|
|
|
}
|
2020-06-24 22:27:00 +02:00
|
|
|
task->tBgOffset += 2;
|
2018-05-11 01:36:57 +02:00
|
|
|
}
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
#undef tState
|
|
|
|
#undef tBgHoriz
|
|
|
|
#undef tBgVert
|
|
|
|
#undef tBgOffsetIdx
|
|
|
|
#undef tBgOffset
|
|
|
|
#undef tMonSpriteId
|
|
|
|
|
|
|
|
static u8 InitFieldMoveMonSprite(u32 species, u32 otId, u32 personality)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2021-11-07 19:54:44 +01:00
|
|
|
bool16 noDucking;
|
2018-05-11 01:36:57 +02:00
|
|
|
u8 monSprite;
|
|
|
|
struct Sprite *sprite;
|
2021-11-07 19:54:44 +01:00
|
|
|
noDucking = (species & SHOW_MON_CRY_NO_DUCKING) >> 16;
|
|
|
|
species &= ~SHOW_MON_CRY_NO_DUCKING;
|
2020-06-29 17:41:09 +02:00
|
|
|
monSprite = CreateMonSprite_FieldMove(species, otId, personality, 320, 80, 0);
|
2018-05-11 01:36:57 +02:00
|
|
|
sprite = &gSprites[monSprite];
|
|
|
|
sprite->callback = SpriteCallbackDummy;
|
|
|
|
sprite->oam.priority = 0;
|
2020-06-24 22:27:00 +02:00
|
|
|
sprite->sSpecies = species;
|
2021-11-07 19:54:44 +01:00
|
|
|
sprite->data[6] = noDucking;
|
2018-05-11 01:36:57 +02:00
|
|
|
return monSprite;
|
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static void SpriteCB_FieldMoveMonSlideOnscreen(struct Sprite *sprite)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2021-07-07 15:11:52 +02:00
|
|
|
if ((sprite->x -= 20) <= DISPLAY_WIDTH / 2)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2021-07-07 15:11:52 +02:00
|
|
|
sprite->x = DISPLAY_WIDTH / 2;
|
2020-06-24 22:27:00 +02:00
|
|
|
sprite->sOnscreenTimer = 30;
|
|
|
|
sprite->callback = SpriteCB_FieldMoveMonWaitAfterCry;
|
2018-05-11 01:36:57 +02:00
|
|
|
if (sprite->data[6])
|
2021-11-07 19:54:44 +01:00
|
|
|
PlayCry_NormalNoDucking(sprite->sSpecies, 0, CRY_VOLUME_RS, CRY_PRIORITY_NORMAL);
|
2018-11-30 23:16:15 +01:00
|
|
|
else
|
2021-11-07 19:54:44 +01:00
|
|
|
PlayCry_Normal(sprite->sSpecies, 0);
|
2018-05-11 01:36:57 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static void SpriteCB_FieldMoveMonWaitAfterCry(struct Sprite *sprite)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2020-06-24 22:27:00 +02:00
|
|
|
if ((--sprite->sOnscreenTimer) == 0)
|
|
|
|
sprite->callback = SpriteCB_FieldMoveMonSlideOffscreen;
|
2018-05-11 01:36:57 +02:00
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static void SpriteCB_FieldMoveMonSlideOffscreen(struct Sprite *sprite)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2021-07-07 15:11:52 +02:00
|
|
|
if (sprite->x < -64)
|
2020-06-24 22:27:00 +02:00
|
|
|
sprite->sSlidOffscreen = TRUE;
|
2018-11-30 23:16:15 +01:00
|
|
|
else
|
2021-07-07 15:11:52 +02:00
|
|
|
sprite->x -= 20;
|
2018-05-11 01:36:57 +02:00
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
#undef tState
|
|
|
|
#undef tMonSpriteId
|
|
|
|
#undef sSpecies
|
|
|
|
#undef sSlidOffscreen
|
|
|
|
#undef sOnscreenTimer
|
|
|
|
|
|
|
|
#define tState data[0]
|
|
|
|
#define tDestX data[1]
|
|
|
|
#define tDestY data[2]
|
|
|
|
#define tMonId data[15]
|
|
|
|
|
2018-05-11 01:36:57 +02:00
|
|
|
u8 FldEff_UseSurf(void)
|
|
|
|
{
|
2020-06-20 01:58:56 +02:00
|
|
|
u8 taskId = CreateTask(Task_SurfFieldEffect, 0xff);
|
2020-06-24 22:27:00 +02:00
|
|
|
gTasks[taskId].tMonId = gFieldEffectArguments[0];
|
2018-05-11 01:36:57 +02:00
|
|
|
Overworld_ClearSavedMusic();
|
2020-08-21 00:02:00 +02:00
|
|
|
Overworld_ChangeMusicTo(MUS_SURF);
|
2018-05-11 01:36:57 +02:00
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2020-06-20 01:58:56 +02:00
|
|
|
void (*const sSurfFieldEffectFuncs[])(struct Task *) = {
|
2020-06-24 22:27:00 +02:00
|
|
|
SurfFieldEffect_Init,
|
|
|
|
SurfFieldEffect_FieldMovePose,
|
|
|
|
SurfFieldEffect_ShowMon,
|
|
|
|
SurfFieldEffect_JumpOnSurfBlob,
|
|
|
|
SurfFieldEffect_End,
|
2018-05-11 01:36:57 +02:00
|
|
|
};
|
|
|
|
|
2020-06-20 01:58:56 +02:00
|
|
|
static void Task_SurfFieldEffect(u8 taskId)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2020-06-24 22:27:00 +02:00
|
|
|
sSurfFieldEffectFuncs[gTasks[taskId].tState](&gTasks[taskId]);
|
2018-05-11 01:36:57 +02:00
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static void SurfFieldEffect_Init(struct Task *task)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
|
|
|
ScriptContext2_Enable();
|
2019-11-21 04:55:44 +01:00
|
|
|
FreezeObjectEvents();
|
2018-05-11 01:36:57 +02:00
|
|
|
gPlayerAvatar.preventStep = TRUE;
|
2020-06-20 01:58:56 +02:00
|
|
|
SetPlayerAvatarStateMask(PLAYER_AVATAR_FLAG_SURFING);
|
2020-06-24 22:27:00 +02:00
|
|
|
PlayerGetDestCoords(&task->tDestX, &task->tDestY);
|
|
|
|
MoveCoords(gObjectEvents[gPlayerAvatar.objectEventId].movementDirection, &task->tDestX, &task->tDestY);
|
|
|
|
task->tState++;
|
2018-05-11 01:36:57 +02:00
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static void SurfFieldEffect_FieldMovePose(struct Task *task)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2019-11-21 04:55:44 +01:00
|
|
|
struct ObjectEvent *objectEvent;
|
|
|
|
objectEvent = &gObjectEvents[gPlayerAvatar.objectEventId];
|
|
|
|
if (!ObjectEventIsMovementOverridden(objectEvent) || ObjectEventClearHeldMovementIfFinished(objectEvent))
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2020-06-20 01:58:56 +02:00
|
|
|
SetPlayerAvatarFieldMove();
|
2019-11-21 04:55:44 +01:00
|
|
|
ObjectEventSetHeldMovement(objectEvent, MOVEMENT_ACTION_START_ANIM_IN_DIRECTION);
|
2020-06-24 22:27:00 +02:00
|
|
|
task->tState++;
|
2018-05-11 01:36:57 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static void SurfFieldEffect_ShowMon(struct Task *task)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2019-11-21 04:55:44 +01:00
|
|
|
struct ObjectEvent *objectEvent;
|
|
|
|
objectEvent = &gObjectEvents[gPlayerAvatar.objectEventId];
|
|
|
|
if (ObjectEventCheckHeldMovementStatus(objectEvent))
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2021-11-07 19:54:44 +01:00
|
|
|
gFieldEffectArguments[0] = task->tMonId | SHOW_MON_CRY_NO_DUCKING;
|
2018-05-11 01:36:57 +02:00
|
|
|
FieldEffectStart(FLDEFF_FIELD_MOVE_SHOW_MON_INIT);
|
2020-06-24 22:27:00 +02:00
|
|
|
task->tState++;
|
2018-05-11 01:36:57 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static void SurfFieldEffect_JumpOnSurfBlob(struct Task *task)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2019-11-21 04:55:44 +01:00
|
|
|
struct ObjectEvent *objectEvent;
|
2018-05-11 01:36:57 +02:00
|
|
|
if (!FieldEffectActiveListContains(FLDEFF_FIELD_MOVE_SHOW_MON))
|
|
|
|
{
|
2019-11-21 04:55:44 +01:00
|
|
|
objectEvent = &gObjectEvents[gPlayerAvatar.objectEventId];
|
2020-06-20 01:58:56 +02:00
|
|
|
ObjectEventSetGraphicsId(objectEvent, GetPlayerAvatarGraphicsIdByStateId(PLAYER_AVATAR_STATE_SURFING));
|
2019-11-21 04:55:44 +01:00
|
|
|
ObjectEventClearHeldMovementIfFinished(objectEvent);
|
|
|
|
ObjectEventSetHeldMovement(objectEvent, GetJumpSpecialMovementAction(objectEvent->movementDirection));
|
2020-06-24 22:27:00 +02:00
|
|
|
gFieldEffectArguments[0] = task->tDestX;
|
|
|
|
gFieldEffectArguments[1] = task->tDestY;
|
2019-11-21 04:55:44 +01:00
|
|
|
gFieldEffectArguments[2] = gPlayerAvatar.objectEventId;
|
|
|
|
objectEvent->fieldEffectSpriteId = FieldEffectStart(FLDEFF_SURF_BLOB);
|
2020-06-24 22:27:00 +02:00
|
|
|
task->tState++;
|
2018-05-11 01:36:57 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static void SurfFieldEffect_End(struct Task *task)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2019-11-21 04:55:44 +01:00
|
|
|
struct ObjectEvent *objectEvent;
|
|
|
|
objectEvent = &gObjectEvents[gPlayerAvatar.objectEventId];
|
|
|
|
if (ObjectEventClearHeldMovementIfFinished(objectEvent))
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
|
|
|
gPlayerAvatar.preventStep = FALSE;
|
2021-10-26 19:27:20 +02:00
|
|
|
gPlayerAvatar.flags &= ~PLAYER_AVATAR_FLAG_CONTROLLABLE;
|
2019-11-21 04:55:44 +01:00
|
|
|
ObjectEventSetHeldMovement(objectEvent, GetFaceDirectionMovementAction(objectEvent->movementDirection));
|
2021-04-05 16:32:33 +02:00
|
|
|
SetSurfBlob_BobState(objectEvent->fieldEffectSpriteId, BOB_PLAYER_AND_MON);
|
2019-11-21 04:55:44 +01:00
|
|
|
UnfreezeObjectEvents();
|
2018-05-11 01:36:57 +02:00
|
|
|
ScriptContext2_Disable();
|
|
|
|
FieldEffectActiveListRemove(FLDEFF_USE_SURF);
|
2020-06-20 01:58:56 +02:00
|
|
|
DestroyTask(FindTaskIdByFunc(Task_SurfFieldEffect));
|
2018-05-11 01:36:57 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
#undef tState
|
|
|
|
#undef tDestX
|
|
|
|
#undef tDestY
|
|
|
|
#undef tMonId
|
|
|
|
|
|
|
|
u8 FldEff_RayquazaSpotlight(void)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2018-11-30 23:16:15 +01:00
|
|
|
u8 i, j, k;
|
2020-06-24 22:27:00 +02:00
|
|
|
u8 spriteId = CreateSprite(gFieldEffectObjectTemplatePointers[FLDEFFOBJ_RAYQUAZA], 120, -24, 1);
|
2018-11-30 23:16:15 +01:00
|
|
|
struct Sprite *sprite = &gSprites[spriteId];
|
|
|
|
|
2018-05-11 01:36:57 +02:00
|
|
|
sprite->oam.priority = 1;
|
|
|
|
sprite->oam.paletteNum = 4;
|
|
|
|
sprite->data[0] = 0;
|
|
|
|
sprite->data[1] = 0;
|
|
|
|
sprite->data[2] = 0;
|
|
|
|
sprite->data[3] = -1;
|
2021-07-07 15:11:52 +02:00
|
|
|
sprite->data[4] = sprite->y;
|
2018-05-11 01:36:57 +02:00
|
|
|
sprite->data[5] = 0;
|
|
|
|
SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT1_BG0 | BLDCNT_EFFECT_BLEND | BLDCNT_TGT2_BG1 | BLDCNT_TGT2_BG2 | BLDCNT_TGT2_BG3 | BLDCNT_TGT2_OBJ | BLDCNT_TGT2_BD);
|
|
|
|
SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(14, 14));
|
2018-11-30 23:16:15 +01:00
|
|
|
SetGpuReg(REG_OFFSET_WININ, WININ_WIN0_BG_ALL | WININ_WIN0_OBJ | WININ_WIN0_CLR | WININ_WIN1_BG_ALL | WININ_WIN1_OBJ | WININ_WIN1_CLR);
|
2020-06-24 22:27:00 +02:00
|
|
|
LoadPalette(sSpotlight_Pal, 0xC0, sizeof(sSpotlight_Pal));
|
2018-05-11 01:36:57 +02:00
|
|
|
SetGpuReg(REG_OFFSET_BG0VOFS, 120);
|
|
|
|
for (i = 3; i < 15; i++)
|
|
|
|
{
|
|
|
|
for (j = 12; j < 18; j++)
|
|
|
|
{
|
2019-02-17 06:25:48 +01:00
|
|
|
((u16*)(BG_SCREEN_ADDR(31)))[i * 32 + j] = 0xBFF4 + i * 6 + j + 1;
|
2018-05-11 01:36:57 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
for (k = 0; k < 90; k++)
|
|
|
|
{
|
2018-11-30 23:16:15 +01:00
|
|
|
for (i = 0; i < 8; i++)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2020-06-24 22:27:00 +02:00
|
|
|
*(u16*)(BG_CHAR_ADDR(2) + (k + 1) * 32 + i * 4) = (sSpotlight_Gfx[k * 32 + i * 4 + 1] << 8) + sSpotlight_Gfx[k * 32 + i * 4];
|
|
|
|
*(u16*)(BG_CHAR_ADDR(2) + (k + 1) * 32 + i * 4 + 2) = (sSpotlight_Gfx[k * 32 + i * 4 + 3] << 8) + sSpotlight_Gfx[k * 32 + i * 4 + 2];
|
2018-05-11 01:36:57 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return spriteId;
|
|
|
|
}
|
|
|
|
|
|
|
|
u8 FldEff_NPCFlyOut(void)
|
|
|
|
{
|
2020-06-20 01:58:56 +02:00
|
|
|
u8 spriteId = CreateSprite(gFieldEffectObjectTemplatePointers[FLDEFFOBJ_BIRD], 0x78, 0, 1);
|
2018-11-30 23:16:15 +01:00
|
|
|
struct Sprite *sprite = &gSprites[spriteId];
|
|
|
|
|
2018-05-11 01:36:57 +02:00
|
|
|
sprite->oam.paletteNum = 0;
|
|
|
|
sprite->oam.priority = 1;
|
2020-06-20 01:58:56 +02:00
|
|
|
sprite->callback = SpriteCB_NPCFlyOut;
|
2018-05-11 01:36:57 +02:00
|
|
|
sprite->data[1] = gFieldEffectArguments[0];
|
2020-08-21 00:02:00 +02:00
|
|
|
PlaySE(SE_M_FLY);
|
2018-05-11 01:36:57 +02:00
|
|
|
return spriteId;
|
|
|
|
}
|
|
|
|
|
2020-06-20 01:58:56 +02:00
|
|
|
static void SpriteCB_NPCFlyOut(struct Sprite *sprite)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
|
|
|
struct Sprite *npcSprite;
|
2018-11-30 23:16:15 +01:00
|
|
|
|
2021-07-07 15:11:52 +02:00
|
|
|
sprite->x2 = Cos(sprite->data[2], 0x8c);
|
|
|
|
sprite->y2 = Sin(sprite->data[2], 0x48);
|
2018-05-11 01:36:57 +02:00
|
|
|
sprite->data[2] = (sprite->data[2] + 4) & 0xff;
|
|
|
|
if (sprite->data[0])
|
|
|
|
{
|
|
|
|
npcSprite = &gSprites[sprite->data[1]];
|
2020-06-20 01:58:56 +02:00
|
|
|
npcSprite->coordOffsetEnabled = FALSE;
|
2021-07-07 15:11:52 +02:00
|
|
|
npcSprite->x = sprite->x + sprite->x2;
|
|
|
|
npcSprite->y = sprite->y + sprite->y2 - 8;
|
|
|
|
npcSprite->x2 = 0;
|
|
|
|
npcSprite->y2 = 0;
|
2018-05-11 01:36:57 +02:00
|
|
|
}
|
2020-06-24 22:27:00 +02:00
|
|
|
|
2018-05-11 01:36:57 +02:00
|
|
|
if (sprite->data[2] >= 0x80)
|
|
|
|
FieldEffectStop(sprite, FLDEFF_NPCFLY_OUT);
|
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
// Task data for Task_FlyOut/FlyIn
|
|
|
|
#define tState data[0]
|
|
|
|
#define tMonId data[1]
|
|
|
|
#define tBirdSpriteId data[1] //re-used
|
|
|
|
#define tTimer data[2]
|
|
|
|
#define tAvatarFlags data[15]
|
|
|
|
|
|
|
|
// Sprite data for the fly bird
|
|
|
|
#define sPlayerSpriteId data[6]
|
|
|
|
#define sAnimCompleted data[7]
|
2020-06-20 01:58:56 +02:00
|
|
|
|
2018-05-11 01:36:57 +02:00
|
|
|
u8 FldEff_UseFly(void)
|
|
|
|
{
|
2020-06-20 01:58:56 +02:00
|
|
|
u8 taskId = CreateTask(Task_FlyOut, 254);
|
2020-06-24 22:27:00 +02:00
|
|
|
gTasks[taskId].tMonId = gFieldEffectArguments[0];
|
2018-05-11 01:36:57 +02:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2020-06-20 01:58:56 +02:00
|
|
|
void (*const sFlyOutFieldEffectFuncs[])(struct Task *) = {
|
2020-06-24 22:27:00 +02:00
|
|
|
FlyOutFieldEffect_FieldMovePose,
|
|
|
|
FlyOutFieldEffect_ShowMon,
|
|
|
|
FlyOutFieldEffect_BirdLeaveBall,
|
|
|
|
FlyOutFieldEffect_WaitBirdLeave,
|
|
|
|
FlyOutFieldEffect_BirdSwoopDown,
|
|
|
|
FlyOutFieldEffect_JumpOnBird,
|
|
|
|
FlyOutFieldEffect_FlyOffWithBird,
|
|
|
|
FlyOutFieldEffect_WaitFlyOff,
|
|
|
|
FlyOutFieldEffect_End,
|
2018-05-11 01:36:57 +02:00
|
|
|
};
|
|
|
|
|
2020-06-20 01:58:56 +02:00
|
|
|
static void Task_FlyOut(u8 taskId)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2020-06-24 22:27:00 +02:00
|
|
|
sFlyOutFieldEffectFuncs[gTasks[taskId].tState](&gTasks[taskId]);
|
2018-05-11 01:36:57 +02:00
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static void FlyOutFieldEffect_FieldMovePose(struct Task *task)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2019-11-21 04:55:44 +01:00
|
|
|
struct ObjectEvent *objectEvent = &gObjectEvents[gPlayerAvatar.objectEventId];
|
|
|
|
if (!ObjectEventIsMovementOverridden(objectEvent) || ObjectEventClearHeldMovementIfFinished(objectEvent))
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2020-06-20 01:58:56 +02:00
|
|
|
task->tAvatarFlags = gPlayerAvatar.flags;
|
2018-05-11 01:36:57 +02:00
|
|
|
gPlayerAvatar.preventStep = TRUE;
|
2020-06-20 01:58:56 +02:00
|
|
|
SetPlayerAvatarStateMask(PLAYER_AVATAR_FLAG_ON_FOOT);
|
|
|
|
SetPlayerAvatarFieldMove();
|
2019-11-21 04:55:44 +01:00
|
|
|
ObjectEventSetHeldMovement(objectEvent, MOVEMENT_ACTION_START_ANIM_IN_DIRECTION);
|
2020-06-24 22:27:00 +02:00
|
|
|
task->tState++;
|
2018-05-11 01:36:57 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static void FlyOutFieldEffect_ShowMon(struct Task *task)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2019-11-21 04:55:44 +01:00
|
|
|
struct ObjectEvent *objectEvent = &gObjectEvents[gPlayerAvatar.objectEventId];
|
|
|
|
if (ObjectEventClearHeldMovementIfFinished(objectEvent))
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2020-06-24 22:27:00 +02:00
|
|
|
task->tState++;
|
|
|
|
gFieldEffectArguments[0] = task->tMonId;
|
2018-05-11 01:36:57 +02:00
|
|
|
FieldEffectStart(FLDEFF_FIELD_MOVE_SHOW_MON_INIT);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static void FlyOutFieldEffect_BirdLeaveBall(struct Task *task)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
|
|
|
if (!FieldEffectActiveListContains(FLDEFF_FIELD_MOVE_SHOW_MON))
|
|
|
|
{
|
2019-11-21 04:55:44 +01:00
|
|
|
struct ObjectEvent *objectEvent = &gObjectEvents[gPlayerAvatar.objectEventId];
|
2020-06-20 01:58:56 +02:00
|
|
|
if (task->tAvatarFlags & PLAYER_AVATAR_FLAG_SURFING)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2021-04-05 16:32:33 +02:00
|
|
|
SetSurfBlob_BobState(objectEvent->fieldEffectSpriteId, BOB_JUST_MON);
|
|
|
|
SetSurfBlob_DontSyncAnim(objectEvent->fieldEffectSpriteId, FALSE);
|
2018-05-11 01:36:57 +02:00
|
|
|
}
|
2020-06-24 22:27:00 +02:00
|
|
|
task->tBirdSpriteId = CreateFlyBirdSprite(); // Does "leave ball" animation by default
|
|
|
|
task->tState++;
|
2018-05-11 01:36:57 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static void FlyOutFieldEffect_WaitBirdLeave(struct Task *task)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2020-06-24 22:27:00 +02:00
|
|
|
if (GetFlyBirdAnimCompleted(task->tBirdSpriteId))
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2020-06-24 22:27:00 +02:00
|
|
|
task->tState++;
|
|
|
|
task->tTimer = 16;
|
2018-05-11 01:36:57 +02:00
|
|
|
SetPlayerAvatarTransitionFlags(PLAYER_AVATAR_FLAG_ON_FOOT);
|
2019-11-21 04:55:44 +01:00
|
|
|
ObjectEventSetHeldMovement(&gObjectEvents[gPlayerAvatar.objectEventId], MOVEMENT_ACTION_FACE_LEFT);
|
2018-05-11 01:36:57 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static void FlyOutFieldEffect_BirdSwoopDown(struct Task *task)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2019-11-21 04:55:44 +01:00
|
|
|
struct ObjectEvent *objectEvent = &gObjectEvents[gPlayerAvatar.objectEventId];
|
2020-06-24 22:27:00 +02:00
|
|
|
if ((task->tTimer == 0 || (--task->tTimer) == 0) && ObjectEventClearHeldMovementIfFinished(objectEvent))
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2020-06-24 22:27:00 +02:00
|
|
|
task->tState++;
|
2020-08-21 00:02:00 +02:00
|
|
|
PlaySE(SE_M_FLY);
|
2020-06-24 22:27:00 +02:00
|
|
|
StartFlyBirdSwoopDown(task->tBirdSpriteId);
|
2018-05-11 01:36:57 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static void FlyOutFieldEffect_JumpOnBird(struct Task *task)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2020-06-24 22:27:00 +02:00
|
|
|
if ((++task->tTimer) >= 8)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2019-11-21 04:55:44 +01:00
|
|
|
struct ObjectEvent *objectEvent = &gObjectEvents[gPlayerAvatar.objectEventId];
|
2020-06-20 01:58:56 +02:00
|
|
|
ObjectEventSetGraphicsId(objectEvent, GetPlayerAvatarGraphicsIdByStateId(PLAYER_AVATAR_STATE_SURFING));
|
2021-10-29 19:37:49 +02:00
|
|
|
StartSpriteAnim(&gSprites[objectEvent->spriteId], ANIM_GET_ON_OFF_POKEMON_WEST);
|
2020-06-20 01:58:56 +02:00
|
|
|
objectEvent->inanimate = TRUE;
|
2019-11-21 04:55:44 +01:00
|
|
|
ObjectEventSetHeldMovement(objectEvent, MOVEMENT_ACTION_JUMP_IN_PLACE_LEFT);
|
2020-06-20 01:58:56 +02:00
|
|
|
if (task->tAvatarFlags & PLAYER_AVATAR_FLAG_SURFING)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2019-11-21 04:55:44 +01:00
|
|
|
DestroySprite(&gSprites[objectEvent->fieldEffectSpriteId]);
|
2018-05-11 01:36:57 +02:00
|
|
|
}
|
2020-06-24 22:27:00 +02:00
|
|
|
task->tState++;
|
|
|
|
task->tTimer = 0;
|
2018-05-11 01:36:57 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static void FlyOutFieldEffect_FlyOffWithBird(struct Task *task)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2020-06-24 22:27:00 +02:00
|
|
|
if ((++task->tTimer) >= 10)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2019-11-21 04:55:44 +01:00
|
|
|
struct ObjectEvent *objectEvent = &gObjectEvents[gPlayerAvatar.objectEventId];
|
|
|
|
ObjectEventClearHeldMovementIfActive(objectEvent);
|
2020-06-20 01:58:56 +02:00
|
|
|
objectEvent->inanimate = FALSE;
|
|
|
|
objectEvent->hasShadow = FALSE;
|
2020-06-24 22:27:00 +02:00
|
|
|
SetFlyBirdPlayerSpriteId(task->tBirdSpriteId, objectEvent->spriteId);
|
2018-05-11 01:36:57 +02:00
|
|
|
CameraObjectReset2();
|
2020-06-24 22:27:00 +02:00
|
|
|
task->tState++;
|
2018-05-11 01:36:57 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static void FlyOutFieldEffect_WaitFlyOff(struct Task *task)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2020-06-24 22:27:00 +02:00
|
|
|
if (GetFlyBirdAnimCompleted(task->tBirdSpriteId))
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2019-12-17 09:24:44 +01:00
|
|
|
WarpFadeOutScreen();
|
2020-06-24 22:27:00 +02:00
|
|
|
task->tState++;
|
2018-05-11 01:36:57 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static void FlyOutFieldEffect_End(struct Task *task)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
|
|
|
if (!gPaletteFade.active)
|
|
|
|
{
|
|
|
|
FieldEffectActiveListRemove(FLDEFF_USE_FLY);
|
2020-06-20 01:58:56 +02:00
|
|
|
DestroyTask(FindTaskIdByFunc(Task_FlyOut));
|
2018-05-11 01:36:57 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static u8 CreateFlyBirdSprite(void)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
|
|
|
u8 spriteId;
|
|
|
|
struct Sprite *sprite;
|
2020-06-20 01:58:56 +02:00
|
|
|
spriteId = CreateSprite(gFieldEffectObjectTemplatePointers[FLDEFFOBJ_BIRD], 0xff, 0xb4, 0x1);
|
2018-05-11 01:36:57 +02:00
|
|
|
sprite = &gSprites[spriteId];
|
|
|
|
sprite->oam.paletteNum = 0;
|
|
|
|
sprite->oam.priority = 1;
|
2020-06-24 22:27:00 +02:00
|
|
|
sprite->callback = SpriteCB_FlyBirdLeaveBall;
|
2018-05-11 01:36:57 +02:00
|
|
|
return spriteId;
|
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static u8 GetFlyBirdAnimCompleted(u8 spriteId)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2020-06-24 22:27:00 +02:00
|
|
|
return gSprites[spriteId].sAnimCompleted;
|
2018-05-11 01:36:57 +02:00
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static void StartFlyBirdSwoopDown(u8 spriteId)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
|
|
|
struct Sprite *sprite;
|
|
|
|
sprite = &gSprites[spriteId];
|
2020-06-24 22:27:00 +02:00
|
|
|
sprite->callback = SpriteCB_FlyBirdSwoopDown;
|
2021-07-07 15:11:52 +02:00
|
|
|
sprite->x = DISPLAY_WIDTH / 2;
|
|
|
|
sprite->y = 0;
|
|
|
|
sprite->x2 = 0;
|
|
|
|
sprite->y2 = 0;
|
2018-05-11 01:36:57 +02:00
|
|
|
memset(&sprite->data[0], 0, 8 * sizeof(u16) /* zero all data cells */);
|
2020-06-24 22:27:00 +02:00
|
|
|
sprite->sPlayerSpriteId = MAX_SPRITES;
|
2018-05-11 01:36:57 +02:00
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static void SetFlyBirdPlayerSpriteId(u8 birdSpriteId, u8 playerSpriteId)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2020-06-24 22:27:00 +02:00
|
|
|
gSprites[birdSpriteId].sPlayerSpriteId = playerSpriteId;
|
2018-05-11 01:36:57 +02:00
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static const union AffineAnimCmd sAffineAnim_FlyBirdLeaveBall[] = {
|
2018-05-11 01:36:57 +02:00
|
|
|
AFFINEANIMCMD_FRAME(8, 8, -30, 0),
|
|
|
|
AFFINEANIMCMD_FRAME(28, 28, 0, 30),
|
|
|
|
AFFINEANIMCMD_END
|
|
|
|
};
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static const union AffineAnimCmd sAffineAnim_FlyBirdReturnToBall[] = {
|
2018-05-11 01:36:57 +02:00
|
|
|
AFFINEANIMCMD_FRAME(256, 256, 64, 0),
|
|
|
|
AFFINEANIMCMD_FRAME(-10, -10, 0, 22),
|
|
|
|
AFFINEANIMCMD_END
|
|
|
|
};
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static const union AffineAnimCmd *const sAffineAnims_FlyBird[] = {
|
|
|
|
sAffineAnim_FlyBirdLeaveBall,
|
|
|
|
sAffineAnim_FlyBirdReturnToBall
|
2018-05-11 01:36:57 +02:00
|
|
|
};
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static void SpriteCB_FlyBirdLeaveBall(struct Sprite *sprite)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2020-06-24 22:27:00 +02:00
|
|
|
if (sprite->sAnimCompleted == FALSE)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
|
|
|
if (sprite->data[0] == 0)
|
|
|
|
{
|
2019-12-05 03:00:45 +01:00
|
|
|
sprite->oam.affineMode = ST_OAM_AFFINE_DOUBLE;
|
2020-06-24 22:27:00 +02:00
|
|
|
sprite->affineAnims = sAffineAnims_FlyBird;
|
2018-05-11 01:36:57 +02:00
|
|
|
InitSpriteAffineAnim(sprite);
|
|
|
|
StartSpriteAffineAnim(sprite, 0);
|
2021-07-07 15:11:52 +02:00
|
|
|
sprite->x = 0x76;
|
|
|
|
sprite->y = -0x30;
|
2018-05-11 01:36:57 +02:00
|
|
|
sprite->data[0]++;
|
|
|
|
sprite->data[1] = 0x40;
|
|
|
|
sprite->data[2] = 0x100;
|
|
|
|
}
|
|
|
|
sprite->data[1] += (sprite->data[2] >> 8);
|
2021-07-07 15:11:52 +02:00
|
|
|
sprite->x2 = Cos(sprite->data[1], 0x78);
|
|
|
|
sprite->y2 = Sin(sprite->data[1], 0x78);
|
2018-05-11 01:36:57 +02:00
|
|
|
if (sprite->data[2] < 0x800)
|
|
|
|
{
|
|
|
|
sprite->data[2] += 0x60;
|
|
|
|
}
|
|
|
|
if (sprite->data[1] > 0x81)
|
|
|
|
{
|
2020-06-24 22:27:00 +02:00
|
|
|
sprite->sAnimCompleted++;
|
2019-12-05 03:00:45 +01:00
|
|
|
sprite->oam.affineMode = ST_OAM_AFFINE_OFF;
|
2018-05-11 01:36:57 +02:00
|
|
|
FreeOamMatrix(sprite->oam.matrixNum);
|
2019-12-05 03:00:45 +01:00
|
|
|
CalcCenterToCornerVec(sprite, sprite->oam.shape, sprite->oam.size, ST_OAM_AFFINE_OFF);
|
2018-05-11 01:36:57 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static void SpriteCB_FlyBirdSwoopDown(struct Sprite *sprite)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2021-07-07 15:11:52 +02:00
|
|
|
sprite->x2 = Cos(sprite->data[2], 0x8c);
|
|
|
|
sprite->y2 = Sin(sprite->data[2], 0x48);
|
2018-05-11 01:36:57 +02:00
|
|
|
sprite->data[2] = (sprite->data[2] + 4) & 0xff;
|
2020-06-24 22:27:00 +02:00
|
|
|
if (sprite->sPlayerSpriteId != MAX_SPRITES)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2020-06-24 22:27:00 +02:00
|
|
|
struct Sprite *sprite1 = &gSprites[sprite->sPlayerSpriteId];
|
2020-06-20 01:58:56 +02:00
|
|
|
sprite1->coordOffsetEnabled = FALSE;
|
2021-07-07 15:11:52 +02:00
|
|
|
sprite1->x = sprite->x + sprite->x2;
|
|
|
|
sprite1->y = sprite->y + sprite->y2 - 8;
|
|
|
|
sprite1->x2 = 0;
|
|
|
|
sprite1->y2 = 0;
|
2018-05-11 01:36:57 +02:00
|
|
|
}
|
|
|
|
if (sprite->data[2] >= 0x80)
|
|
|
|
{
|
2020-06-24 22:27:00 +02:00
|
|
|
sprite->sAnimCompleted = TRUE;
|
2018-05-11 01:36:57 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static void SpriteCB_FlyBirdReturnToBall(struct Sprite *sprite)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2020-06-24 22:27:00 +02:00
|
|
|
if (sprite->sAnimCompleted == FALSE)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
|
|
|
if (sprite->data[0] == 0)
|
|
|
|
{
|
2019-12-05 03:00:45 +01:00
|
|
|
sprite->oam.affineMode = ST_OAM_AFFINE_DOUBLE;
|
2020-06-24 22:27:00 +02:00
|
|
|
sprite->affineAnims = sAffineAnims_FlyBird;
|
2018-05-11 01:36:57 +02:00
|
|
|
InitSpriteAffineAnim(sprite);
|
|
|
|
StartSpriteAffineAnim(sprite, 1);
|
2021-07-07 15:11:52 +02:00
|
|
|
sprite->x = 0x5e;
|
|
|
|
sprite->y = -0x20;
|
2018-05-11 01:36:57 +02:00
|
|
|
sprite->data[0]++;
|
|
|
|
sprite->data[1] = 0xf0;
|
|
|
|
sprite->data[2] = 0x800;
|
|
|
|
sprite->data[4] = 0x80;
|
|
|
|
}
|
|
|
|
sprite->data[1] += sprite->data[2] >> 8;
|
|
|
|
sprite->data[3] += sprite->data[2] >> 8;
|
|
|
|
sprite->data[1] &= 0xff;
|
2021-07-07 15:11:52 +02:00
|
|
|
sprite->x2 = Cos(sprite->data[1], 0x20);
|
|
|
|
sprite->y2 = Sin(sprite->data[1], 0x78);
|
2018-05-11 01:36:57 +02:00
|
|
|
if (sprite->data[2] > 0x100)
|
|
|
|
{
|
|
|
|
sprite->data[2] -= sprite->data[4];
|
|
|
|
}
|
|
|
|
if (sprite->data[4] < 0x100)
|
|
|
|
{
|
|
|
|
sprite->data[4] += 24;
|
|
|
|
}
|
|
|
|
if (sprite->data[2] < 0x100)
|
|
|
|
{
|
|
|
|
sprite->data[2] = 0x100;
|
|
|
|
}
|
|
|
|
if (sprite->data[3] >= 60)
|
|
|
|
{
|
2020-06-24 22:27:00 +02:00
|
|
|
sprite->sAnimCompleted++;
|
2019-12-05 03:00:45 +01:00
|
|
|
sprite->oam.affineMode = ST_OAM_AFFINE_OFF;
|
2018-05-11 01:36:57 +02:00
|
|
|
FreeOamMatrix(sprite->oam.matrixNum);
|
2018-09-10 17:25:58 +02:00
|
|
|
sprite->invisible = TRUE;
|
2018-05-11 01:36:57 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static void StartFlyBirdReturnToBall(u8 spriteId)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2020-06-24 22:27:00 +02:00
|
|
|
StartFlyBirdSwoopDown(spriteId); // Set up is the same, but overrwrites the callback below
|
|
|
|
gSprites[spriteId].callback = SpriteCB_FlyBirdReturnToBall;
|
2018-05-11 01:36:57 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
u8 FldEff_FlyIn(void)
|
|
|
|
{
|
2020-06-24 22:27:00 +02:00
|
|
|
CreateTask(Task_FlyIn, 254);
|
2018-05-11 01:36:57 +02:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2020-06-20 01:58:56 +02:00
|
|
|
void (*const sFlyInFieldEffectFuncs[])(struct Task *) = {
|
2020-06-24 22:27:00 +02:00
|
|
|
FlyInFieldEffect_BirdSwoopDown,
|
|
|
|
FlyInFieldEffect_FlyInWithBird,
|
|
|
|
FlyInFieldEffect_JumpOffBird,
|
|
|
|
FlyInFieldEffect_FieldMovePose,
|
|
|
|
FlyInFieldEffect_BirdReturnToBall,
|
|
|
|
FlyInFieldEffect_WaitBirdReturn,
|
|
|
|
FlyInFieldEffect_End,
|
2018-05-11 01:36:57 +02:00
|
|
|
};
|
|
|
|
|
2020-06-20 01:58:56 +02:00
|
|
|
static void Task_FlyIn(u8 taskId)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2020-06-24 22:27:00 +02:00
|
|
|
sFlyInFieldEffectFuncs[gTasks[taskId].tState](&gTasks[taskId]);
|
2018-05-11 01:36:57 +02:00
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static void FlyInFieldEffect_BirdSwoopDown(struct Task *task)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2019-11-21 04:55:44 +01:00
|
|
|
struct ObjectEvent *objectEvent;
|
|
|
|
objectEvent = &gObjectEvents[gPlayerAvatar.objectEventId];
|
|
|
|
if (!ObjectEventIsMovementOverridden(objectEvent) || ObjectEventClearHeldMovementIfFinished(objectEvent))
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2020-06-24 22:27:00 +02:00
|
|
|
task->tState++;
|
|
|
|
task->tTimer = 17;
|
2020-06-20 01:58:56 +02:00
|
|
|
task->tAvatarFlags = gPlayerAvatar.flags;
|
2018-05-11 01:36:57 +02:00
|
|
|
gPlayerAvatar.preventStep = TRUE;
|
2020-06-20 01:58:56 +02:00
|
|
|
SetPlayerAvatarStateMask(PLAYER_AVATAR_FLAG_ON_FOOT);
|
|
|
|
if (task->tAvatarFlags & PLAYER_AVATAR_FLAG_SURFING)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2021-04-05 16:32:33 +02:00
|
|
|
SetSurfBlob_BobState(objectEvent->fieldEffectSpriteId, BOB_NONE);
|
2018-05-11 01:36:57 +02:00
|
|
|
}
|
2020-06-20 01:58:56 +02:00
|
|
|
ObjectEventSetGraphicsId(objectEvent, GetPlayerAvatarGraphicsIdByStateId(PLAYER_AVATAR_STATE_SURFING));
|
2018-05-11 01:36:57 +02:00
|
|
|
CameraObjectReset2();
|
2019-11-21 04:55:44 +01:00
|
|
|
ObjectEventTurn(objectEvent, DIR_WEST);
|
2021-10-29 19:37:49 +02:00
|
|
|
StartSpriteAnim(&gSprites[objectEvent->spriteId], ANIM_GET_ON_OFF_POKEMON_WEST);
|
2019-11-21 04:55:44 +01:00
|
|
|
objectEvent->invisible = FALSE;
|
2020-06-24 22:27:00 +02:00
|
|
|
task->tBirdSpriteId = CreateFlyBirdSprite();
|
|
|
|
StartFlyBirdSwoopDown(task->tBirdSpriteId);
|
|
|
|
SetFlyBirdPlayerSpriteId(task->tBirdSpriteId, objectEvent->spriteId);
|
2018-05-11 01:36:57 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static void FlyInFieldEffect_FlyInWithBird(struct Task *task)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2019-11-21 04:55:44 +01:00
|
|
|
struct ObjectEvent *objectEvent;
|
2018-05-11 01:36:57 +02:00
|
|
|
struct Sprite *sprite;
|
2020-06-24 22:27:00 +02:00
|
|
|
if (task->tTimer == 0 || (--task->tTimer) == 0)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2019-11-21 04:55:44 +01:00
|
|
|
objectEvent = &gObjectEvents[gPlayerAvatar.objectEventId];
|
|
|
|
sprite = &gSprites[objectEvent->spriteId];
|
2020-06-24 22:27:00 +02:00
|
|
|
SetFlyBirdPlayerSpriteId(task->tBirdSpriteId, MAX_SPRITES);
|
2021-07-07 15:11:52 +02:00
|
|
|
sprite->x += sprite->x2;
|
|
|
|
sprite->y += sprite->y2;
|
|
|
|
sprite->x2 = 0;
|
|
|
|
sprite->y2 = 0;
|
2020-06-24 22:27:00 +02:00
|
|
|
task->tState++;
|
|
|
|
task->tTimer = 0;
|
2018-05-11 01:36:57 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static void FlyInFieldEffect_JumpOffBird(struct Task *task)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2020-06-20 01:58:56 +02:00
|
|
|
s16 sYPositions[18] = {
|
2018-05-11 01:36:57 +02:00
|
|
|
-2,
|
|
|
|
-4,
|
|
|
|
-5,
|
|
|
|
-6,
|
|
|
|
-7,
|
|
|
|
-8,
|
|
|
|
-8,
|
|
|
|
-8,
|
|
|
|
-7,
|
|
|
|
-7,
|
|
|
|
-6,
|
|
|
|
-5,
|
|
|
|
-3,
|
|
|
|
-2,
|
|
|
|
0,
|
|
|
|
2,
|
|
|
|
4,
|
|
|
|
8
|
|
|
|
};
|
|
|
|
struct Sprite *sprite = &gSprites[gPlayerAvatar.spriteId];
|
2021-07-07 15:11:52 +02:00
|
|
|
sprite->y2 = sYPositions[task->tTimer];
|
2020-06-24 22:27:00 +02:00
|
|
|
|
|
|
|
if ((++task->tTimer) >= (int)ARRAY_COUNT(sYPositions))
|
|
|
|
task->tState++;
|
2018-05-11 01:36:57 +02:00
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static void FlyInFieldEffect_FieldMovePose(struct Task *task)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2019-11-21 04:55:44 +01:00
|
|
|
struct ObjectEvent *objectEvent;
|
2018-05-11 01:36:57 +02:00
|
|
|
struct Sprite *sprite;
|
2020-06-24 22:27:00 +02:00
|
|
|
if (GetFlyBirdAnimCompleted(task->tBirdSpriteId))
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2019-11-21 04:55:44 +01:00
|
|
|
objectEvent = &gObjectEvents[gPlayerAvatar.objectEventId];
|
|
|
|
sprite = &gSprites[objectEvent->spriteId];
|
2020-06-20 01:58:56 +02:00
|
|
|
objectEvent->inanimate = FALSE;
|
2019-11-21 04:55:44 +01:00
|
|
|
MoveObjectEventToMapCoords(objectEvent, objectEvent->currentCoords.x, objectEvent->currentCoords.y);
|
2021-07-07 15:11:52 +02:00
|
|
|
sprite->x2 = 0;
|
|
|
|
sprite->y2 = 0;
|
2020-06-20 01:58:56 +02:00
|
|
|
sprite->coordOffsetEnabled = TRUE;
|
|
|
|
SetPlayerAvatarFieldMove();
|
2019-11-21 04:55:44 +01:00
|
|
|
ObjectEventSetHeldMovement(objectEvent, MOVEMENT_ACTION_START_ANIM_IN_DIRECTION);
|
2020-06-24 22:27:00 +02:00
|
|
|
task->tState++;
|
2018-05-11 01:36:57 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static void FlyInFieldEffect_BirdReturnToBall(struct Task *task)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2019-11-21 04:55:44 +01:00
|
|
|
if (ObjectEventClearHeldMovementIfFinished(&gObjectEvents[gPlayerAvatar.objectEventId]))
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2020-06-24 22:27:00 +02:00
|
|
|
task->tState++;
|
|
|
|
StartFlyBirdReturnToBall(task->tBirdSpriteId);
|
2018-05-11 01:36:57 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static void FlyInFieldEffect_WaitBirdReturn(struct Task *task)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2020-06-24 22:27:00 +02:00
|
|
|
if (GetFlyBirdAnimCompleted(task->tBirdSpriteId))
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2020-06-24 22:27:00 +02:00
|
|
|
DestroySprite(&gSprites[task->tBirdSpriteId]);
|
|
|
|
task->tState++;
|
|
|
|
task->data[1] = 16;
|
2018-05-11 01:36:57 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static void FlyInFieldEffect_End(struct Task *task)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
|
|
|
u8 state;
|
2019-11-21 04:55:44 +01:00
|
|
|
struct ObjectEvent *objectEvent;
|
2018-05-11 01:36:57 +02:00
|
|
|
if ((--task->data[1]) == 0)
|
|
|
|
{
|
2019-11-21 04:55:44 +01:00
|
|
|
objectEvent = &gObjectEvents[gPlayerAvatar.objectEventId];
|
2020-06-20 01:58:56 +02:00
|
|
|
state = PLAYER_AVATAR_STATE_NORMAL;
|
|
|
|
if (task->tAvatarFlags & PLAYER_AVATAR_FLAG_SURFING)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2020-06-20 01:58:56 +02:00
|
|
|
state = PLAYER_AVATAR_STATE_SURFING;
|
2021-04-05 16:32:33 +02:00
|
|
|
SetSurfBlob_BobState(objectEvent->fieldEffectSpriteId, BOB_PLAYER_AND_MON);
|
2018-05-11 01:36:57 +02:00
|
|
|
}
|
2019-11-21 04:55:44 +01:00
|
|
|
ObjectEventSetGraphicsId(objectEvent, GetPlayerAvatarGraphicsIdByStateId(state));
|
|
|
|
ObjectEventTurn(objectEvent, DIR_SOUTH);
|
2020-06-20 01:58:56 +02:00
|
|
|
gPlayerAvatar.flags = task->tAvatarFlags;
|
2018-05-11 01:36:57 +02:00
|
|
|
gPlayerAvatar.preventStep = FALSE;
|
|
|
|
FieldEffectActiveListRemove(FLDEFF_FLY_IN);
|
2020-06-20 01:58:56 +02:00
|
|
|
DestroyTask(FindTaskIdByFunc(Task_FlyIn));
|
2018-05-11 01:36:57 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
#undef tState
|
|
|
|
#undef tMonId
|
|
|
|
#undef tBirdSpriteId
|
|
|
|
#undef tTimer
|
|
|
|
#undef tAvatarFlags
|
|
|
|
#undef sPlayerSpriteId
|
|
|
|
#undef sAnimCompleted
|
|
|
|
|
|
|
|
#define tState data[1]
|
|
|
|
#define tObjectEventId data[2]
|
|
|
|
#define tTimer data[3]
|
|
|
|
#define tCameraTaskId data[5]
|
|
|
|
#define tLocalId data[6]
|
|
|
|
#define tMapNum data[7]
|
|
|
|
#define tMapGroup data[8]
|
|
|
|
|
2020-06-20 01:58:56 +02:00
|
|
|
bool8 FldEff_DestroyDeoxysRock(void)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
|
|
|
u8 taskId;
|
2020-06-24 22:27:00 +02:00
|
|
|
u8 objectEventId;
|
|
|
|
if (!TryGetObjectEventIdByLocalIdAndMap(gFieldEffectArguments[0], gFieldEffectArguments[1], gFieldEffectArguments[2], &objectEventId))
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2020-06-24 22:27:00 +02:00
|
|
|
taskId = CreateTask(Task_DestroyDeoxysRock, 80);
|
|
|
|
gTasks[taskId].tObjectEventId = objectEventId;
|
|
|
|
gTasks[taskId].tLocalId = gFieldEffectArguments[0];
|
|
|
|
gTasks[taskId].tMapNum = gFieldEffectArguments[1];
|
|
|
|
gTasks[taskId].tMapGroup = gFieldEffectArguments[2];
|
2018-05-11 01:36:57 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2020-06-20 01:58:56 +02:00
|
|
|
FieldEffectActiveListRemove(FLDEFF_DESTROY_DEOXYS_ROCK);
|
2018-05-11 01:36:57 +02:00
|
|
|
}
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
#define tShakeDelay data[0]
|
|
|
|
#define tShakeUp data[1]
|
|
|
|
#define tShake data[5]
|
|
|
|
#define tEndDelay data[6]
|
|
|
|
#define tEnding data[7]
|
|
|
|
|
|
|
|
static void Task_DeoxysRockCameraShake(u8 taskId)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
|
|
|
s16 *data = gTasks[taskId].data;
|
2020-06-24 22:27:00 +02:00
|
|
|
if (tEnding)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2020-06-24 22:27:00 +02:00
|
|
|
if (++tEndDelay > 20)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2020-06-24 22:27:00 +02:00
|
|
|
tEndDelay = 0;
|
|
|
|
if (tShake != 0)
|
|
|
|
tShake--;
|
2018-05-11 01:36:57 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2020-06-24 22:27:00 +02:00
|
|
|
tShake = 4;
|
2018-05-11 01:36:57 +02:00
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
if (++tShakeDelay > 1)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2020-06-24 22:27:00 +02:00
|
|
|
tShakeDelay = 0;
|
|
|
|
|
|
|
|
if (++tShakeUp & 1)
|
|
|
|
SetCameraPanning(0, -tShake);
|
2018-05-11 01:36:57 +02:00
|
|
|
else
|
2020-06-24 22:27:00 +02:00
|
|
|
SetCameraPanning(0, tShake);
|
2018-05-11 01:36:57 +02:00
|
|
|
}
|
|
|
|
UpdateCameraPanning();
|
2020-06-24 22:27:00 +02:00
|
|
|
if (tShake == 0)
|
2018-05-11 01:36:57 +02:00
|
|
|
DestroyTask(taskId);
|
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static void StartEndingDeoxysRockCameraShake(u8 taskId)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2020-06-24 22:27:00 +02:00
|
|
|
gTasks[taskId].tEnding = TRUE;
|
2018-05-11 01:36:57 +02:00
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
#undef tShakeDelay
|
|
|
|
#undef tShakeUp
|
|
|
|
#undef tShake
|
|
|
|
#undef tEndDelay
|
|
|
|
#undef tEnding
|
|
|
|
|
|
|
|
void (*const sDestroyDeoxysRockEffectFuncs[])(s16*, u8) = {
|
|
|
|
DestroyDeoxysRockEffect_CameraShake,
|
|
|
|
DestroyDeoxysRockEffect_RockFragments,
|
|
|
|
DestroyDeoxysRockEffect_WaitAndEnd,
|
2018-05-11 01:36:57 +02:00
|
|
|
};
|
|
|
|
|
2020-06-20 01:58:56 +02:00
|
|
|
static void Task_DestroyDeoxysRock(u8 taskId)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
|
|
|
s16 *data = gTasks[taskId].data;
|
|
|
|
InstallCameraPanAheadCallback();
|
|
|
|
SetCameraPanningCallback(0);
|
2020-06-24 22:27:00 +02:00
|
|
|
sDestroyDeoxysRockEffectFuncs[tState](data, taskId);
|
2018-05-11 01:36:57 +02:00
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static void DestroyDeoxysRockEffect_CameraShake(s16* data, u8 taskId)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2020-06-24 22:27:00 +02:00
|
|
|
u8 newTaskId = CreateTask(Task_DeoxysRockCameraShake, 90);
|
2020-08-21 00:02:00 +02:00
|
|
|
PlaySE(SE_THUNDER2);
|
2020-06-24 22:27:00 +02:00
|
|
|
tCameraTaskId = newTaskId;
|
|
|
|
tState++;
|
2018-05-11 01:36:57 +02:00
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static void DestroyDeoxysRockEffect_RockFragments(s16* data, u8 taskId)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2020-06-24 22:27:00 +02:00
|
|
|
if (++tTimer > 120)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2020-06-24 22:27:00 +02:00
|
|
|
struct Sprite *sprite = &gSprites[gObjectEvents[tObjectEventId].spriteId];
|
|
|
|
gObjectEvents[tObjectEventId].invisible = TRUE;
|
2021-02-24 17:01:02 +01:00
|
|
|
BlendPalettes(PALETTES_BG, 0x10, RGB_WHITE);
|
|
|
|
BeginNormalPaletteFade(PALETTES_BG, 0, 0x10, 0, RGB_WHITE);
|
2020-06-24 22:27:00 +02:00
|
|
|
CreateDeoxysRockFragments(sprite);
|
2020-08-21 00:02:00 +02:00
|
|
|
PlaySE(SE_THUNDER);
|
2020-06-24 22:27:00 +02:00
|
|
|
StartEndingDeoxysRockCameraShake(tCameraTaskId);
|
|
|
|
tTimer = 0;
|
|
|
|
tState++;
|
2018-05-11 01:36:57 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static void DestroyDeoxysRockEffect_WaitAndEnd(s16* data, u8 taskId)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2020-06-24 22:27:00 +02:00
|
|
|
if (!gPaletteFade.active && !FuncIsActiveTask(Task_DeoxysRockCameraShake))
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
|
|
|
InstallCameraPanAheadCallback();
|
2020-06-24 22:27:00 +02:00
|
|
|
RemoveObjectEventByLocalIdAndMap(tLocalId, tMapNum, tMapGroup);
|
2020-06-20 01:58:56 +02:00
|
|
|
FieldEffectActiveListRemove(FLDEFF_DESTROY_DEOXYS_ROCK);
|
2018-05-11 01:36:57 +02:00
|
|
|
DestroyTask(taskId);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
#undef tState
|
|
|
|
#undef tObjectEventId
|
|
|
|
#undef tTimer
|
|
|
|
#undef tCameraTaskId
|
|
|
|
#undef tLocalId
|
|
|
|
#undef tMapNum
|
|
|
|
#undef tMapGroup
|
|
|
|
|
|
|
|
static const struct SpriteFrameImage sImages_DeoxysRockFragment[] = {
|
|
|
|
obj_frame_tiles(sRockFragment_TopLeft),
|
|
|
|
obj_frame_tiles(sRockFragment_TopRight),
|
|
|
|
obj_frame_tiles(sRockFragment_BottomLeft),
|
|
|
|
obj_frame_tiles(sRockFragment_BottomRight),
|
2018-05-11 01:36:57 +02:00
|
|
|
};
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static const union AnimCmd sAnim_RockFragment_TopLeft[] = {
|
2018-05-11 01:36:57 +02:00
|
|
|
ANIMCMD_FRAME(.imageValue = 0),
|
|
|
|
ANIMCMD_END
|
|
|
|
};
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static const union AnimCmd sAnim_RockFragment_TopRight[] = {
|
2018-05-11 01:36:57 +02:00
|
|
|
ANIMCMD_FRAME(.imageValue = 1),
|
|
|
|
ANIMCMD_END
|
|
|
|
};
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static const union AnimCmd sAnim_RockFragment_BottomLeft[] = {
|
2018-05-11 01:36:57 +02:00
|
|
|
ANIMCMD_FRAME(.imageValue = 2),
|
|
|
|
ANIMCMD_END
|
|
|
|
};
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static const union AnimCmd sAnim_RockFragment_BottomRight[] = {
|
2018-05-11 01:36:57 +02:00
|
|
|
ANIMCMD_FRAME(.imageValue = 3),
|
|
|
|
ANIMCMD_END
|
|
|
|
};
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static const union AnimCmd *const sAnims_DeoxysRockFragment[] = {
|
|
|
|
sAnim_RockFragment_TopLeft,
|
|
|
|
sAnim_RockFragment_TopRight,
|
|
|
|
sAnim_RockFragment_BottomLeft,
|
|
|
|
sAnim_RockFragment_BottomRight,
|
2018-05-11 01:36:57 +02:00
|
|
|
};
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static const struct SpriteTemplate sSpriteTemplate_DeoxysRockFragment = {
|
2021-09-14 19:14:14 +02:00
|
|
|
.tileTag = TAG_NONE,
|
2018-05-11 01:36:57 +02:00
|
|
|
.paletteTag = 4378,
|
2020-06-24 22:27:00 +02:00
|
|
|
.oam = &sOam_8x8,
|
|
|
|
.anims = sAnims_DeoxysRockFragment,
|
|
|
|
.images = sImages_DeoxysRockFragment,
|
2018-05-11 01:36:57 +02:00
|
|
|
.affineAnims = gDummySpriteAffineAnimTable,
|
2020-06-24 22:27:00 +02:00
|
|
|
.callback = SpriteCB_DeoxysRockFragment
|
2018-05-11 01:36:57 +02:00
|
|
|
};
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static void CreateDeoxysRockFragments(struct Sprite* sprite)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
|
|
|
int i;
|
2021-07-07 15:11:52 +02:00
|
|
|
int xPos = (s16)gTotalCameraPixelOffsetX + sprite->x + sprite->x2;
|
|
|
|
int yPos = (s16)gTotalCameraPixelOffsetY + sprite->y + sprite->y2 - 4;
|
2018-05-11 01:36:57 +02:00
|
|
|
|
|
|
|
for (i = 0; i < 4; i++)
|
|
|
|
{
|
2020-06-24 22:27:00 +02:00
|
|
|
u8 spriteId = CreateSprite(&sSpriteTemplate_DeoxysRockFragment, xPos, yPos, 0);
|
2018-11-28 21:08:22 +01:00
|
|
|
if (spriteId != MAX_SPRITES)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
|
|
|
StartSpriteAnim(&gSprites[spriteId], i);
|
|
|
|
gSprites[spriteId].data[0] = i;
|
|
|
|
gSprites[spriteId].oam.paletteNum = sprite->oam.paletteNum;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-24 22:27:00 +02:00
|
|
|
static void SpriteCB_DeoxysRockFragment(struct Sprite* sprite)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2020-06-24 22:27:00 +02:00
|
|
|
// 1 case for each fragment, fly off in 4 different directions
|
2018-05-11 01:36:57 +02:00
|
|
|
switch (sprite->data[0])
|
|
|
|
{
|
2018-11-28 21:08:22 +01:00
|
|
|
case 0:
|
2021-07-07 15:11:52 +02:00
|
|
|
sprite->x -= 16;
|
|
|
|
sprite->y -= 12;
|
2018-11-28 21:08:22 +01:00
|
|
|
break;
|
|
|
|
case 1:
|
2021-07-07 15:11:52 +02:00
|
|
|
sprite->x += 16;
|
|
|
|
sprite->y -= 12;
|
2018-11-28 21:08:22 +01:00
|
|
|
break;
|
|
|
|
case 2:
|
2021-07-07 15:11:52 +02:00
|
|
|
sprite->x -= 16;
|
|
|
|
sprite->y += 12;
|
2018-11-28 21:08:22 +01:00
|
|
|
break;
|
|
|
|
case 3:
|
2021-07-07 15:11:52 +02:00
|
|
|
sprite->x += 16;
|
|
|
|
sprite->y += 12;
|
2018-11-28 21:08:22 +01:00
|
|
|
break;
|
2018-05-11 01:36:57 +02:00
|
|
|
}
|
2021-07-07 15:11:52 +02:00
|
|
|
if ((u16)(sprite->x + 4) > DISPLAY_WIDTH + 8 || sprite->y < -4 || sprite->y > DISPLAY_HEIGHT + 4)
|
2018-05-11 01:36:57 +02:00
|
|
|
DestroySprite(sprite);
|
|
|
|
}
|
|
|
|
|
2020-06-20 01:58:56 +02:00
|
|
|
bool8 FldEff_MoveDeoxysRock(struct Sprite* sprite)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2019-11-21 04:55:44 +01:00
|
|
|
u8 objectEventIdBuffer;
|
|
|
|
if (!TryGetObjectEventIdByLocalIdAndMap(gFieldEffectArguments[0], gFieldEffectArguments[1], gFieldEffectArguments[2], &objectEventIdBuffer))
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
2019-11-21 04:55:44 +01:00
|
|
|
struct ObjectEvent *object;
|
2018-05-11 01:36:57 +02:00
|
|
|
int xPos, yPos;
|
|
|
|
u8 taskId;
|
2019-11-21 04:55:44 +01:00
|
|
|
object = &gObjectEvents[objectEventIdBuffer];
|
2021-10-09 18:12:18 +02:00
|
|
|
xPos = object->currentCoords.x - MAP_OFFSET;
|
|
|
|
yPos = object->currentCoords.y - MAP_OFFSET;
|
2018-05-11 01:36:57 +02:00
|
|
|
xPos = (gFieldEffectArguments[3] - xPos) * 16;
|
|
|
|
yPos = (gFieldEffectArguments[4] - yPos) * 16;
|
2021-10-09 18:12:18 +02:00
|
|
|
ShiftObjectEventCoords(object, gFieldEffectArguments[3] + MAP_OFFSET, gFieldEffectArguments[4] + MAP_OFFSET);
|
2020-07-02 06:17:14 +02:00
|
|
|
taskId = CreateTask(Task_MoveDeoxysRock, 80);
|
2018-05-11 01:36:57 +02:00
|
|
|
gTasks[taskId].data[1] = object->spriteId;
|
2021-07-07 15:11:52 +02:00
|
|
|
gTasks[taskId].data[2] = gSprites[object->spriteId].x + xPos;
|
|
|
|
gTasks[taskId].data[3] = gSprites[object->spriteId].y + yPos;
|
2018-05-11 01:36:57 +02:00
|
|
|
gTasks[taskId].data[8] = gFieldEffectArguments[5];
|
2019-11-21 04:55:44 +01:00
|
|
|
gTasks[taskId].data[9] = objectEventIdBuffer;
|
2018-05-11 01:36:57 +02:00
|
|
|
}
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2020-06-20 01:58:56 +02:00
|
|
|
static void Task_MoveDeoxysRock(u8 taskId)
|
2018-05-11 01:36:57 +02:00
|
|
|
{
|
|
|
|
s16 *data = gTasks[taskId].data;
|
|
|
|
struct Sprite *sprite = &gSprites[data[1]];
|
|
|
|
switch (data[0])
|
|
|
|
{
|
|
|
|
case 0:
|
2021-07-07 15:11:52 +02:00
|
|
|
data[4] = sprite->x << 4;
|
|
|
|
data[5] = sprite->y << 4;
|
2021-03-19 23:17:43 +01:00
|
|
|
data[6] = SAFE_DIV(data[2] * 16 - data[4], data[8]);
|
|
|
|
data[7] = SAFE_DIV(data[3] * 16 - data[5], data[8]);
|
2018-05-11 01:36:57 +02:00
|
|
|
data[0]++;
|
|
|
|
case 1:
|
|
|
|
if (data[8] != 0)
|
|
|
|
{
|
|
|
|
data[8]--;
|
|
|
|
data[4] += data[6];
|
|
|
|
data[5] += data[7];
|
2021-07-07 15:11:52 +02:00
|
|
|
sprite->x = data[4] >> 4;
|
|
|
|
sprite->y = data[5] >> 4;
|
2018-05-11 01:36:57 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2019-11-21 04:55:44 +01:00
|
|
|
struct ObjectEvent *object = &gObjectEvents[data[9]];
|
2021-07-07 15:11:52 +02:00
|
|
|
sprite->x = data[2];
|
|
|
|
sprite->y = data[3];
|
2019-11-21 04:55:44 +01:00
|
|
|
ShiftStillObjectEventCoords(object);
|
2018-06-11 16:19:17 +02:00
|
|
|
object->triggerGroundEffectsOnStop = TRUE;
|
2020-06-20 01:58:56 +02:00
|
|
|
FieldEffectActiveListRemove(FLDEFF_MOVE_DEOXYS_ROCK);
|
2018-05-11 01:36:57 +02:00
|
|
|
DestroyTask(taskId);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2019-04-02 00:31:10 +02:00
|
|
|
|