pokeemerald/src/fldeff_rocksmash.c

167 lines
5.4 KiB
C
Raw Normal View History

2018-04-10 08:47:29 +02:00
#include "global.h"
#include "braille_puzzles.h"
#include "event_data.h"
2018-10-17 02:11:44 +02:00
#include "event_object_movement.h"
2018-04-10 08:47:29 +02:00
#include "event_scripts.h"
#include "field_effect.h"
#include "field_player_avatar.h"
2018-12-24 21:59:05 +01:00
#include "fldeff.h"
2018-04-10 08:47:29 +02:00
#include "item_use.h"
#include "overworld.h"
2018-10-17 02:11:44 +02:00
#include "party_menu.h"
2018-04-10 08:47:29 +02:00
#include "script.h"
#include "sound.h"
#include "sprite.h"
#include "task.h"
2019-11-21 20:03:35 +01:00
#include "constants/event_object_movement.h"
2018-10-17 02:11:44 +02:00
#include "constants/event_objects.h"
2018-11-13 15:19:04 +01:00
#include "constants/field_effects.h"
2018-07-13 05:39:38 +02:00
#include "constants/map_types.h"
2018-10-17 02:11:44 +02:00
#include "constants/songs.h"
2018-04-10 08:47:29 +02:00
2020-06-29 17:41:09 +02:00
static void Task_DoFieldMove_Init(u8 taskId);
static void Task_DoFieldMove_ShowMonAfterPose(u8 taskId);
static void Task_DoFieldMove_WaitForMon(u8 taskId);
static void Task_DoFieldMove_RunFunc(u8 taskId);
static void FieldCallback_RockSmash(void);
2020-06-29 17:41:09 +02:00
static void FieldMove_RockSmash(void);
2018-04-10 08:47:29 +02:00
2018-10-17 02:11:44 +02:00
bool8 CheckObjectGraphicsInFrontOfPlayer(u8 graphicsId)
2018-04-10 08:47:29 +02:00
{
u8 objEventId;
2018-04-10 08:47:29 +02:00
2018-06-16 00:45:48 +02:00
GetXYCoordsOneStepInFrontOfPlayer(&gPlayerFacingPosition.x, &gPlayerFacingPosition.y);
2022-01-21 18:48:19 +01:00
gPlayerFacingPosition.elevation = PlayerGetElevation();
objEventId = GetObjectEventIdByPosition(gPlayerFacingPosition.x, gPlayerFacingPosition.y, gPlayerFacingPosition.elevation);
if (gObjectEvents[objEventId].graphicsId != graphicsId)
2018-04-10 08:47:29 +02:00
{
return FALSE;
}
else
{
gSpecialVar_LastTalked = gObjectEvents[objEventId].localId;
2018-04-10 08:47:29 +02:00
return TRUE;
}
}
u8 CreateFieldMoveTask(void)
2018-04-10 08:47:29 +02:00
{
2018-06-16 00:45:48 +02:00
GetXYCoordsOneStepInFrontOfPlayer(&gPlayerFacingPosition.x, &gPlayerFacingPosition.y);
2020-06-29 17:41:09 +02:00
return CreateTask(Task_DoFieldMove_Init, 8);
2018-04-10 08:47:29 +02:00
}
2020-06-29 17:41:09 +02:00
static void Task_DoFieldMove_Init(u8 taskId)
2018-04-10 08:47:29 +02:00
{
u8 objEventId;
2018-04-10 08:47:29 +02:00
ScriptContext2_Enable();
gPlayerAvatar.preventStep = TRUE;
objEventId = gPlayerAvatar.objectEventId;
if (!ObjectEventIsMovementOverridden(&gObjectEvents[objEventId])
|| ObjectEventClearHeldMovementIfFinished(&gObjectEvents[objEventId]))
2018-04-10 08:47:29 +02:00
{
if (gMapHeader.mapType == MAP_TYPE_UNDERWATER)
{
2020-06-29 17:41:09 +02:00
// Skip field move pose underwater
2018-04-10 08:47:29 +02:00
FieldEffectStart(FLDEFF_FIELD_MOVE_SHOW_MON_INIT);
2020-06-29 17:41:09 +02:00
gTasks[taskId].func = Task_DoFieldMove_WaitForMon;
2018-04-10 08:47:29 +02:00
}
else
{
2020-06-29 17:41:09 +02:00
// Do field move pose
SetPlayerAvatarFieldMove();
ObjectEventSetHeldMovement(&gObjectEvents[objEventId], MOVEMENT_ACTION_START_ANIM_IN_DIRECTION);
2020-06-29 17:41:09 +02:00
gTasks[taskId].func = Task_DoFieldMove_ShowMonAfterPose;
2018-04-10 08:47:29 +02:00
}
}
}
2020-06-29 17:41:09 +02:00
static void Task_DoFieldMove_ShowMonAfterPose(u8 taskId)
2018-04-10 08:47:29 +02:00
{
if (ObjectEventCheckHeldMovementStatus(&gObjectEvents[gPlayerAvatar.objectEventId]) == TRUE)
2018-04-10 08:47:29 +02:00
{
FieldEffectStart(FLDEFF_FIELD_MOVE_SHOW_MON_INIT);
2020-06-29 17:41:09 +02:00
gTasks[taskId].func = Task_DoFieldMove_WaitForMon;
2018-04-10 08:47:29 +02:00
}
}
2020-06-29 17:41:09 +02:00
static void Task_DoFieldMove_WaitForMon(u8 taskId)
2018-04-10 08:47:29 +02:00
{
2018-10-17 02:11:44 +02:00
if (!FieldEffectActiveListContains(FLDEFF_FIELD_MOVE_SHOW_MON))
2018-04-10 08:47:29 +02:00
{
gFieldEffectArguments[1] = GetPlayerFacingDirection();
if (gFieldEffectArguments[1] == DIR_SOUTH)
2018-04-10 08:47:29 +02:00
gFieldEffectArguments[2] = 0;
if (gFieldEffectArguments[1] == DIR_NORTH)
2018-04-10 08:47:29 +02:00
gFieldEffectArguments[2] = 1;
if (gFieldEffectArguments[1] == DIR_WEST)
2018-04-10 08:47:29 +02:00
gFieldEffectArguments[2] = 2;
if (gFieldEffectArguments[1] == DIR_EAST)
2018-04-10 08:47:29 +02:00
gFieldEffectArguments[2] = 3;
ObjectEventSetGraphicsId(&gObjectEvents[gPlayerAvatar.objectEventId], GetPlayerAvatarGraphicsIdByCurrentState());
2018-04-10 08:47:29 +02:00
StartSpriteAnim(&gSprites[gPlayerAvatar.spriteId], gFieldEffectArguments[2]);
FieldEffectActiveListRemove(FLDEFF_FIELD_MOVE_SHOW_MON);
2020-06-29 17:41:09 +02:00
gTasks[taskId].func = Task_DoFieldMove_RunFunc;
2018-04-10 08:47:29 +02:00
}
}
2020-06-29 17:41:09 +02:00
static void Task_DoFieldMove_RunFunc(u8 taskId)
2018-04-10 08:47:29 +02:00
{
2020-06-29 17:41:09 +02:00
// The function for the field move to do is stored in halves across data[8] and data[9]
void (*fieldMoveFunc)(void) = (void (*)(void))(((u16)gTasks[taskId].data[8] << 16) | (u16)gTasks[taskId].data[9]);
2018-04-10 08:47:29 +02:00
2020-06-29 17:41:09 +02:00
fieldMoveFunc();
2018-04-10 08:47:29 +02:00
gPlayerAvatar.preventStep = FALSE;
DestroyTask(taskId);
}
2020-06-29 17:41:09 +02:00
// Called when Rock Smash is used from the party menu
// For interacting with a smashable rock in the field, see EventScript_RockSmash
2018-04-10 08:47:29 +02:00
bool8 SetUpFieldMove_RockSmash(void)
{
// In Ruby and Sapphire, Regirock's tomb is opened by using Strength. In Emerald,
// it is opened by using Rock Smash.
if (ShouldDoBrailleRegirockEffect())
2018-04-10 08:47:29 +02:00
{
gSpecialVar_Result = GetCursorSelectionMonId();
2018-06-16 00:45:48 +02:00
gFieldCallback2 = FieldCallback_PrepareFadeInFromMenu;
gPostMenuFieldCallback = SetUpPuzzleEffectRegirock;
2018-04-10 08:47:29 +02:00
return TRUE;
}
else if (CheckObjectGraphicsInFrontOfPlayer(OBJ_EVENT_GFX_BREAKABLE_ROCK) == TRUE)
2018-04-10 08:47:29 +02:00
{
2018-06-16 00:45:48 +02:00
gFieldCallback2 = FieldCallback_PrepareFadeInFromMenu;
gPostMenuFieldCallback = FieldCallback_RockSmash;
2018-04-10 08:47:29 +02:00
return TRUE;
}
else
{
return FALSE;
}
}
static void FieldCallback_RockSmash(void)
2018-04-10 08:47:29 +02:00
{
gFieldEffectArguments[0] = GetCursorSelectionMonId();
2020-07-02 10:59:52 +02:00
ScriptContext1_SetupScript(EventScript_UseRockSmash);
2018-04-10 08:47:29 +02:00
}
bool8 FldEff_UseRockSmash(void)
{
u8 taskId = CreateFieldMoveTask();
2018-04-10 08:47:29 +02:00
2020-06-29 17:41:09 +02:00
gTasks[taskId].data[8] = (u32)FieldMove_RockSmash >> 16;
gTasks[taskId].data[9] = (u32)FieldMove_RockSmash;
2018-04-10 08:47:29 +02:00
IncrementGameStat(GAME_STAT_USED_ROCK_SMASH);
return FALSE;
}
2020-06-29 17:41:09 +02:00
// The actual rock smashing is handled by EventScript_SmashRock, so this function does very little
static void FieldMove_RockSmash(void)
2018-04-10 08:47:29 +02:00
{
2020-08-21 00:02:00 +02:00
PlaySE(SE_M_ROCK_THROW);
2018-04-10 08:47:29 +02:00
FieldEffectActiveListRemove(FLDEFF_USE_ROCK_SMASH);
EnableBothScriptContexts();
}