diff --git a/asm/macros/event.inc b/asm/macros/event.inc index b15bf8deb3..e081819217 100644 --- a/asm/macros/event.inc +++ b/asm/macros/event.inc @@ -2313,6 +2313,11 @@ callnative ScriptSetDoubleBattleFlag, requests_effects=1 .endm + @ Stop using the ORAS dowsing machine. + .macro stoporasdowsing + callnative EndORASDowsing + .endm + @ ============================ @ @ FAKE RTC MACROS @ Will only function if OW_USE_FAKE_RTC is true. If it has any additional requirements, it will be listed accordingly. diff --git a/data/field_effect_scripts.s b/data/field_effect_scripts.s index 34678bb293..ce71a102fd 100644 --- a/data/field_effect_scripts.s +++ b/data/field_effect_scripts.s @@ -83,6 +83,7 @@ gFieldEffectScriptPointers:: .4byte gFieldEffectScript_Defog @ FLDEFF_DEFOG .4byte gFieldEffectScript_UseRockClimb @ FLDEFF_USE_ROCK_CLIMB .4byte gFieldEffectScript_RockClimbDust @ FLDEFF_ROCK_CLIMB_DUST + .4byte gFieldEffectScript_ORASDowse @ FLDEFF_ORAS_DOWSE gFieldEffectScript_ExclamationMarkIcon1:: field_eff_callnative FldEff_ExclamationMarkIcon @@ -386,6 +387,7 @@ gFieldEffectScript_CaveDust:: gFieldEffectScript_Defog:: field_eff_callnative FldEff_Defog field_eff_end + gFieldEffectScript_UseRockClimb:: @ 82DBC3F field_eff_callnative FldEff_UseRockClimb field_eff_end @@ -394,3 +396,7 @@ gFieldEffectScript_RockClimbDust:: @ 82DBB28 field_eff_loadfadedpal_callnative gSpritePalette_BigDust, FldEff_RockClimbDust field_eff_end +gFieldEffectScript_ORASDowse:: + field_eff_callnative FldEff_ORASDowsing + field_eff_end + diff --git a/data/scripts/obtain_item.inc b/data/scripts/obtain_item.inc index 599961c821..3eb7f4f0d4 100644 --- a/data/scripts/obtain_item.inc +++ b/data/scripts/obtain_item.inc @@ -205,6 +205,7 @@ EventScript_FoundHiddenItem:: end EventScript_PutHiddenItemInPocket:: + callnative Script_ClearDowsingColor delay 10 showitemdescription waitmessage @@ -215,6 +216,7 @@ EventScript_PutHiddenItemInPocket:: hideitemdescription special TryPutTreasureInvestigatorsOnAir special SetHiddenItemFlag + callnative Script_UpdateDowseState releaseall end diff --git a/graphics/field_effects/palettes/oras_dowsing.pal b/graphics/field_effects/palettes/oras_dowsing.pal new file mode 100644 index 0000000000..d3446e3971 --- /dev/null +++ b/graphics/field_effects/palettes/oras_dowsing.pal @@ -0,0 +1,19 @@ +JASC-PAL +0100 +16 +115 197 164 +0 0 0 +255 255 255 +255 255 255 +255 255 255 +255 255 255 +255 255 255 +255 255 255 +255 255 255 +255 255 255 +255 255 255 +255 255 255 +255 255 255 +255 255 255 +255 255 255 +255 0 255 diff --git a/graphics/field_effects/pics/oras_dowsing_brendan.png b/graphics/field_effects/pics/oras_dowsing_brendan.png new file mode 100644 index 0000000000..fd83519819 Binary files /dev/null and b/graphics/field_effects/pics/oras_dowsing_brendan.png differ diff --git a/graphics/field_effects/pics/oras_dowsing_may.png b/graphics/field_effects/pics/oras_dowsing_may.png new file mode 100644 index 0000000000..6a4eb08f02 Binary files /dev/null and b/graphics/field_effects/pics/oras_dowsing_may.png differ diff --git a/include/config/item.h b/include/config/item.h index 6792f8979f..1195aafd63 100644 --- a/include/config/item.h +++ b/include/config/item.h @@ -38,4 +38,15 @@ // Vs. Seeker #define I_VS_SEEKER_CHARGING 0 // If this flag is assigned, the Vs Seeker functionality will be enabled. When the player has the Vs. Seeker, Match Call rematch functions will stop working. +// ORAS Dowsing Machine +#define I_ORAS_DOWSING_FLAG 0 // Replace 0 with an unused flag to enable the Dowsing Machine mechanic from ORAS. +#define I_ORAS_DOWSING_SOUNDS TRUE // If TRUE, the Dowsing Machine will make sounds based on how far away the hidden item is. +#define I_ORAS_DOWSING_COLOR_PAL 15 // The color within the palette that will change based on proximity to the item. +// Color values for the ORAS dowsing distances/anims +#define I_ORAS_DOWSING_COLOR_NONE RGB_GRAY +#define I_ORAS_DOWSING_COLOR_SLOW RGB2GBA(56, 120, 255) +#define I_ORAS_DOWSING_COLOR_NORMAL RGB2GBA(24, 216, 24) +#define I_ORAS_DOWSING_COLOR_FAST RGB2GBA(255, 255, 40) +#define I_ORAS_DOWSING_COLOR_FASTER RGB_RED + #endif // GUARD_CONFIG_ITEM_H diff --git a/include/constants/field_effects.h b/include/constants/field_effects.h index e38b25cac7..71978fc64f 100644 --- a/include/constants/field_effects.h +++ b/include/constants/field_effects.h @@ -79,6 +79,7 @@ #define FLDEFF_DEFOG 74 #define FLDEFF_USE_ROCK_CLIMB 75 #define FLDEFF_ROCK_CLIMB_DUST 76 +#define FLDEFF_ORAS_DOWSE 77 #define FLDEFFOBJ_SHADOW_S 0 #define FLDEFFOBJ_SHADOW_M 1 @@ -123,6 +124,8 @@ #define FLDEFFOBJ_CAVE_DUST 40 #define FLDEFFOBJ_ROCK_CLIMB_BLOB 41 #define FLDEFFOBJ_ROCK_CLIMB_DUST 42 +#define FLDEFFOBJ_ORAS_DOWSE_BRENDAN 43 +#define FLDEFFOBJ_ORAS_DOWSE_MAY 44 #define FLDEFF_PAL_TAG_CUT_GRASS 0x1000 #define FLDEFF_PAL_TAG_SECRET_POWER_TREE 0x1003 @@ -138,6 +141,7 @@ #define FLDEFF_PAL_TAG_UNKNOWN 0x1011 #define FLDEFF_PAL_TAG_CAVE_DUST 0x1012 #define FLDEFF_PAL_TAG_DUST_CLOUD 0x1013 +#define FLDEFF_PAL_TAG_ORAS_DOWSE 0x1014 #define FLDEFF_PAL_TAG_FIELD_MOVE_MON 0x8400 // tile tags, for field effects that may have many copies on screen at once diff --git a/include/item_use.h b/include/item_use.h index ad8018d67d..ccb0f4f3df 100644 --- a/include/item_use.h +++ b/include/item_use.h @@ -49,6 +49,8 @@ void Task_ItemUse_CloseMessageBoxAndReturnToField_VsSeeker(u8 taskId); void DisplayDadsAdviceCannotUseItemMessage(u8 taskId, bool8 isUsingRegisteredKeyItemOnField); void ItemUseOutOfBattle_PokeFlute(u8 taskId); void ItemUseOutOfBattle_TownMap(u8 taskId); +bool8 ItemfinderCheckForHiddenItems(const struct MapEvents *, u8); +u8 GetDirectionToHiddenItem(s16, s16); enum { BALL_THROW_UNABLE_TWO_MONS, diff --git a/include/oras_dowse.h b/include/oras_dowse.h new file mode 100644 index 0000000000..8b490cf6c7 --- /dev/null +++ b/include/oras_dowse.h @@ -0,0 +1,39 @@ +#ifndef GUARD_ORAS_DOWSE_H +#define GUARD_ORAS_DOWSE_H + +// States for ORAS Dowsing +enum +{ + ORASD_WIGGLE_NONE, + ORASD_WIGGLE_SLOW, + ORASD_WIGGLE_NORMAL, + ORASD_WIGGLE_FAST, + ORASD_WIGGLE_FASTER +}; + +#define ANIM_ORAS_DOWSE_WIGGLE_SOUTH_SLOW (ANIM_STD_FACE_EAST + 1) +#define ANIM_ORAS_DOWSE_WIGGLE_NORTH_SLOW (ANIM_STD_FACE_EAST + 2) +#define ANIM_ORAS_DOWSE_WIGGLE_WEST_SLOW (ANIM_STD_FACE_EAST + 3) +#define ANIM_ORAS_DOWSE_WIGGLE_EAST_SLOW (ANIM_STD_FACE_EAST + 4) +#define ANIM_ORAS_DOWSE_WIGGLE_SOUTH (ANIM_STD_FACE_EAST + 5) +#define ANIM_ORAS_DOWSE_WIGGLE_NORTH (ANIM_STD_FACE_EAST + 6) +#define ANIM_ORAS_DOWSE_WIGGLE_WEST (ANIM_STD_FACE_EAST + 7) +#define ANIM_ORAS_DOWSE_WIGGLE_EAST (ANIM_STD_FACE_EAST + 8) +#define ANIM_ORAS_DOWSE_WIGGLE_SOUTH_FAST (ANIM_STD_FACE_EAST + 9) +#define ANIM_ORAS_DOWSE_WIGGLE_NORTH_FAST (ANIM_STD_FACE_EAST + 10) +#define ANIM_ORAS_DOWSE_WIGGLE_WEST_FAST (ANIM_STD_FACE_EAST + 11) +#define ANIM_ORAS_DOWSE_WIGGLE_EAST_FAST (ANIM_STD_FACE_EAST + 12) +#define ANIM_ORAS_DOWSE_WIGGLE_SOUTH_FASTER (ANIM_STD_FACE_EAST + 13) +#define ANIM_ORAS_DOWSE_WIGGLE_NORTH_FASTER (ANIM_STD_FACE_EAST + 14) +#define ANIM_ORAS_DOWSE_WIGGLE_WEST_FASTER (ANIM_STD_FACE_EAST + 15) +#define ANIM_ORAS_DOWSE_WIGGLE_EAST_FASTER (ANIM_STD_FACE_EAST + 16) + +extern const u16 gFieldEffectPal_ORASDowsing[]; + +void Task_UseORASDowsingMachine(u8 taskId); +void ResumeORASDowseFieldEffect(void); +void UpdateDowseState(struct Sprite *sprite); +void UpdateDowsingAnimDirection(struct Sprite *sprite, struct ObjectEvent *playerObj); +void EndORASDowsing(void); + +#endif // GUARD_ORAS_DOWSE_H diff --git a/spritesheet_rules.mk b/spritesheet_rules.mk index ef5da9c091..e817a65893 100644 --- a/spritesheet_rules.mk +++ b/spritesheet_rules.mk @@ -693,6 +693,12 @@ $(FLDEFFGFXDIR)/surf_blob.4bpp: %.4bpp: %.png $(FLDEFFGFXDIR)/rock_climb_blob.4bpp: %.4bpp: %.png $(GFX) $< $@ -mwidth 4 -mheight 4 +$(FLDEFFGFXDIR)/oras_dowsing_brendan.4bpp: %.4bpp: %.png + $(GFX) $< $@ -mwidth 2 -mheight 4 + +$(FLDEFFGFXDIR)/oras_dowsing_may.4bpp: %.4bpp: %.png + $(GFX) $< $@ -mwidth 2 -mheight 4 + $(FLDEFFGFXDIR)/tall_grass.4bpp: %.4bpp: %.png $(GFX) $< $@ -mwidth 2 -mheight 2 diff --git a/src/bike.c b/src/bike.c index 50ed705da3..3f4181f129 100644 --- a/src/bike.c +++ b/src/bike.c @@ -5,6 +5,7 @@ #include "fieldmap.h" #include "field_specials.h" #include "metatile_behavior.h" +#include "oras_dowse.h" #include "overworld.h" #include "sound.h" #include "constants/songs.h" @@ -1003,6 +1004,7 @@ void GetOnOffBike(u8 transitionFlags) } else { + EndORASDowsing(); SetPlayerAvatarTransitionFlags(transitionFlags); Overworld_SetSavedMusic(MUS_CYCLING); Overworld_ChangeMusicTo(MUS_CYCLING); diff --git a/src/data/field_effects/field_effect_object_template_pointers.h b/src/data/field_effects/field_effect_object_template_pointers.h index 281c664f03..369b5821a9 100755 --- a/src/data/field_effects/field_effect_object_template_pointers.h +++ b/src/data/field_effects/field_effect_object_template_pointers.h @@ -42,6 +42,8 @@ extern const struct SpriteTemplate gFieldEffectObjectTemplate_SpotTracks; extern const struct SpriteTemplate gFieldEffectObjectTemplate_CaveDust; extern const struct SpriteTemplate gFieldEffectObjectTemplate_RockClimbBlob; extern const struct SpriteTemplate gFieldEffectObjectTemplate_RockClimbDust; +extern const struct SpriteTemplate gFieldEffectObjectTemplate_ORASDowsingBrendan; +extern const struct SpriteTemplate gFieldEffectObjectTemplate_ORASDowsingMay; const struct SpriteTemplate *const gFieldEffectObjectTemplatePointers[] = { [FLDEFFOBJ_SHADOW_S] = &gFieldEffectObjectTemplate_ShadowSmall, @@ -87,4 +89,6 @@ const struct SpriteTemplate *const gFieldEffectObjectTemplatePointers[] = { [FLDEFFOBJ_CAVE_DUST] = &gFieldEffectObjectTemplate_CaveDust, [FLDEFFOBJ_ROCK_CLIMB_BLOB] = &gFieldEffectObjectTemplate_RockClimbBlob, [FLDEFFOBJ_ROCK_CLIMB_DUST] = &gFieldEffectObjectTemplate_RockClimbDust, + [FLDEFFOBJ_ORAS_DOWSE_BRENDAN] = &gFieldEffectObjectTemplate_ORASDowsingBrendan, + [FLDEFFOBJ_ORAS_DOWSE_MAY] = &gFieldEffectObjectTemplate_ORASDowsingMay, }; diff --git a/src/field_effect.c b/src/field_effect.c index 45b4d61d17..174c071ae4 100644 --- a/src/field_effect.c +++ b/src/field_effect.c @@ -19,6 +19,7 @@ #include "mirage_tower.h" #include "menu.h" #include "metatile_behavior.h" +#include "oras_dowse.h" #include "overworld.h" #include "palette.h" #include "party_menu.h" @@ -1679,6 +1680,7 @@ void StartEscalatorWarp(u8 metatileBehavior, u8 priority) { gTasks[taskId].tGoingUp = TRUE; } + EndORASDowsing(); } static void Task_EscalatorWarpOut(u8 taskId) @@ -2065,6 +2067,7 @@ static bool8 DiveFieldEffect_TryWarp(struct Task *task) void StartLavaridgeGymB1FWarp(u8 priority) { + EndORASDowsing(); CreateTask(Task_LavaridgeGymB1FWarp, priority); } @@ -2273,6 +2276,7 @@ void SpriteCB_AshLaunch(struct Sprite *sprite) void StartLavaridgeGym1FWarp(u8 priority) { + EndORASDowsing(); CreateTask(Task_LavaridgeGym1FWarp, priority); } @@ -2395,6 +2399,7 @@ void StartEscapeRopeFieldEffect(void) LockPlayerFieldControls(); FreezeObjectEvents(); HideFollowerForFieldEffect(); // hide follower before warping + EndORASDowsing(); CreateTask(Task_EscapeRopeWarpOut, 80); } @@ -2589,6 +2594,7 @@ static void TeleportWarpOutFieldEffect_Init(struct Task *task) LockPlayerFieldControls(); FreezeObjectEvents(); CameraObjectFreeze(); + EndORASDowsing(); task->data[15] = GetPlayerFacingDirection(); task->tState++; } diff --git a/src/field_effect_helpers.c b/src/field_effect_helpers.c index 2e9e1a8510..3623437a4d 100755 --- a/src/field_effect_helpers.c +++ b/src/field_effect_helpers.c @@ -1903,4 +1903,3 @@ static void UpdateGrassFieldEffectSubpriority(struct Sprite *sprite, u8 elevatio } } } - diff --git a/src/field_player_avatar.c b/src/field_player_avatar.c index 386d917355..89fb3a2bb8 100644 --- a/src/field_player_avatar.c +++ b/src/field_player_avatar.c @@ -12,6 +12,7 @@ #include "follower_npc.h" #include "menu.h" #include "metatile_behavior.h" +#include "oras_dowse.h" #include "overworld.h" #include "party_menu.h" #include "random.h" @@ -363,6 +364,8 @@ void PlayerStep(u8 direction, u16 newKeys, u16 heldKeys) } } +#define sCounter data[3] + static bool8 TryInterruptObjectEventSpecialAnim(struct ObjectEvent *playerObjEvent, u8 direction) { if (ObjectEventIsMovementOverridden(playerObjEvent) @@ -371,6 +374,8 @@ static bool8 TryInterruptObjectEventSpecialAnim(struct ObjectEvent *playerObjEve u8 heldMovementActionId = ObjectEventGetHeldMovementActionId(playerObjEvent); if (heldMovementActionId > MOVEMENT_ACTION_WALK_FAST_RIGHT && heldMovementActionId < MOVEMENT_ACTION_WALK_IN_PLACE_NORMAL_DOWN) { + struct ObjectEvent *playerObj = &gObjectEvents[gPlayerAvatar.objectEventId]; + if (direction == DIR_NONE) { return TRUE; @@ -378,12 +383,21 @@ static bool8 TryInterruptObjectEventSpecialAnim(struct ObjectEvent *playerObjEve if (playerObjEvent->movementDirection != direction) { + if (I_ORAS_DOWSING_FLAG != 0 && FlagGet(I_ORAS_DOWSING_FLAG)) + gSprites[playerObj->fieldEffectSpriteId].sCounter = 0; + ObjectEventClearHeldMovement(playerObjEvent); return FALSE; } if (CheckForPlayerAvatarStaticCollision(direction) == COLLISION_NONE) { + if (I_ORAS_DOWSING_FLAG != 0 && FlagGet(I_ORAS_DOWSING_FLAG)) + { + gSprites[playerObj->fieldEffectSpriteId].sCounter = 0; + gSprites[playerObj->fieldEffectSpriteId].y2 = 0; + } + ObjectEventClearHeldMovement(playerObjEvent); return FALSE; } @@ -395,6 +409,8 @@ static bool8 TryInterruptObjectEventSpecialAnim(struct ObjectEvent *playerObjEve return FALSE; } +#undef sCounter + static void npc_clear_strange_bits(struct ObjectEvent *objEvent) { objEvent->inanimate = FALSE; @@ -824,8 +840,12 @@ static void PlayerNotOnBikeMoving(u8 direction, u16 heldKeys) return; } - if (!(gPlayerAvatar.flags & PLAYER_AVATAR_FLAG_UNDERWATER) && (heldKeys & B_BUTTON) && FlagGet(FLAG_SYS_B_DASH) - && IsRunningDisallowed(gObjectEvents[gPlayerAvatar.objectEventId].currentMetatileBehavior) == 0 && !FollowerNPCComingThroughDoor()) + if (!(gPlayerAvatar.flags & PLAYER_AVATAR_FLAG_UNDERWATER) + && (heldKeys & B_BUTTON) + && FlagGet(FLAG_SYS_B_DASH) + && IsRunningDisallowed(gObjectEvents[gPlayerAvatar.objectEventId].currentMetatileBehavior) == 0 + && !FollowerNPCComingThroughDoor() + && (I_ORAS_DOWSING_FLAG == 0 || (I_ORAS_DOWSING_FLAG != 0 && !FlagGet(I_ORAS_DOWSING_FLAG)))) { if (ObjectMovingOnRockStairs(&gObjectEvents[gPlayerAvatar.objectEventId], direction)) PlayerRunSlow(direction); @@ -1626,12 +1646,14 @@ void SetPlayerInvisibility(bool8 invisible) void SetPlayerAvatarFieldMove(void) { + EndORASDowsing(); ObjectEventSetGraphicsId(&gObjectEvents[gPlayerAvatar.objectEventId], GetPlayerAvatarGraphicsIdByStateId(PLAYER_AVATAR_STATE_FIELD_MOVE)); StartSpriteAnim(&gSprites[gPlayerAvatar.spriteId], ANIM_FIELD_MOVE); } void SetPlayerAvatarFishing(u8 direction) { + EndORASDowsing(); ObjectEventSetGraphicsId(&gObjectEvents[gPlayerAvatar.objectEventId], GetPlayerAvatarGraphicsIdByStateId(PLAYER_AVATAR_STATE_FISHING)); StartSpriteAnim(&gSprites[gPlayerAvatar.spriteId], GetFishingDirectionAnimNum(direction)); } @@ -1645,6 +1667,7 @@ void PlayerUseAcroBikeOnBumpySlope(u8 direction) void SetPlayerAvatarWatering(u8 direction) { + EndORASDowsing(); ObjectEventSetGraphicsId(&gObjectEvents[gPlayerAvatar.objectEventId], GetPlayerAvatarGraphicsIdByStateId(PLAYER_AVATAR_STATE_WATERING)); StartSpriteAnim(&gSprites[gPlayerAvatar.spriteId], GetFaceDirectionAnimNum(direction)); } diff --git a/src/field_screen_effect.c b/src/field_screen_effect.c index 74d2008ac9..2a3a5993d8 100644 --- a/src/field_screen_effect.c +++ b/src/field_screen_effect.c @@ -24,6 +24,7 @@ #include "mirage_tower.h" #include "metatile_behavior.h" #include "palette.h" +#include "oras_dowse.h" #include "overworld.h" #include "scanline_effect.h" #include "script.h" @@ -684,6 +685,7 @@ void Task_WarpAndLoadMap(u8 taskId) case 0: FreezeObjectEvents(); LockPlayerFieldControls(); + EndORASDowsing(); task->tState++; break; case 1: @@ -745,6 +747,7 @@ void Task_DoDoorWarp(u8 taskId) ObjectEventSetHeldMovement(followerObject, MOVEMENT_ACTION_ENTER_POKEBALL); } task->tDoorTask = FieldAnimateDoorOpen(*x, *y - 1); + EndORASDowsing(); task->tState = DOORWARP_START_WALK_UP; break; case DOORWARP_START_WALK_UP: diff --git a/src/item_use.c b/src/item_use.c index 1b91dd76da..aa34f7b1ec 100644 --- a/src/item_use.c +++ b/src/item_use.c @@ -29,6 +29,7 @@ #include "menu.h" #include "menu_helpers.h" #include "metatile_behavior.h" +#include "oras_dowse.h" #include "overworld.h" #include "palette.h" #include "party_menu.h" @@ -55,8 +56,6 @@ static void Task_UseItemfinder(u8); static void Task_CloseItemfinderMessage(u8); static void Task_HiddenItemNearby(u8); static void Task_StandingOnHiddenItem(u8); -static bool8 ItemfinderCheckForHiddenItems(const struct MapEvents *, u8); -static u8 GetDirectionToHiddenItem(s16, s16); static void PlayerFaceHiddenItem(u8); static void CheckForHiddenItemsInMapConnection(u8); static void Task_OpenRegisteredPokeblockCase(u8); @@ -368,10 +367,20 @@ void ItemUseOutOfBattle_Itemfinder(u8 var) static void ItemUseOnFieldCB_Itemfinder(u8 taskId) { - if (ItemfinderCheckForHiddenItems(gMapHeader.events, taskId) == TRUE) - gTasks[taskId].func = Task_UseItemfinder; + if (I_ORAS_DOWSING_FLAG != 0) + { + if (!TestPlayerAvatarFlags(PLAYER_AVATAR_FLAG_SURFING) && !TestPlayerAvatarFlags(PLAYER_AVATAR_FLAG_UNDERWATER)) + gTasks[taskId].func = Task_UseORASDowsingMachine; + else + DisplayItemMessageOnField(taskId, gText_DadsAdvice, Task_CloseItemfinderMessage); + } else - DisplayItemMessageOnField(taskId, sText_ItemFinderNothing, Task_CloseItemfinderMessage); + { + if (ItemfinderCheckForHiddenItems(gMapHeader.events, taskId) == TRUE) + gTasks[taskId].func = Task_UseItemfinder; + else + DisplayItemMessageOnField(taskId, sText_ItemFinderNothing, Task_CloseItemfinderMessage); + } } // Define itemfinder task data @@ -427,12 +436,15 @@ static void Task_CloseItemfinderMessage(u8 taskId) DestroyTask(taskId); } -static bool8 ItemfinderCheckForHiddenItems(const struct MapEvents *events, u8 taskId) +bool8 ItemfinderCheckForHiddenItems(const struct MapEvents *events, u8 taskId) { int itemX, itemY; s16 playerX, playerY, i, distanceX, distanceY; PlayerGetDestCoords(&playerX, &playerY); - gTasks[taskId].tItemFound = FALSE; + if (I_ORAS_DOWSING_FLAG != 0) + gSprites[gObjectEvents[gPlayerAvatar.objectEventId].fieldEffectSpriteId].tItemFound = FALSE; + else + gTasks[taskId].tItemFound = FALSE; for (i = 0; i < events->bgEventCount; i++) { @@ -452,7 +464,7 @@ static bool8 ItemfinderCheckForHiddenItems(const struct MapEvents *events, u8 ta } CheckForHiddenItemsInMapConnection(taskId); - if (gTasks[taskId].tItemFound == TRUE) + if (gTasks[taskId].tItemFound == TRUE || gSprites[gObjectEvents[gPlayerAvatar.objectEventId].fieldEffectSpriteId].tItemFound) return TRUE; else return FALSE; @@ -551,6 +563,8 @@ static void SetDistanceOfClosestHiddenItem(u8 taskId, s16 itemDistanceX, s16 ite { s16 *data = gTasks[taskId].data; s16 oldItemAbsX, oldItemAbsY, newItemAbsX, newItemAbsY; + if (I_ORAS_DOWSING_FLAG != 0) + data = gSprites[gObjectEvents[gPlayerAvatar.objectEventId].fieldEffectSpriteId].data; if (tItemFound == FALSE) { @@ -607,7 +621,7 @@ static void SetDistanceOfClosestHiddenItem(u8 taskId, s16 itemDistanceX, s16 ite } } -static u8 GetDirectionToHiddenItem(s16 itemDistanceX, s16 itemDistanceY) +u8 GetDirectionToHiddenItem(s16 itemDistanceX, s16 itemDistanceY) { s16 absX, absY; diff --git a/src/oras_dowse.c b/src/oras_dowse.c new file mode 100644 index 0000000000..237c456187 --- /dev/null +++ b/src/oras_dowse.c @@ -0,0 +1,562 @@ +#include "global.h" +#include "oras_dowse.h" +#include "bike.h" +#include "event_data.h" +#include "event_object_lock.h" +#include "event_object_movement.h" +#include "field_effect.h" +#include "field_effect_helpers.h" +#include "field_player_avatar.h" +#include "fldeff.h" +#include "item_use.h" +#include "palette.h" +#include "script.h" +#include "sound.h" +#include "task.h" +#include "constants/field_effects.h" +#include "constants/songs.h" +#include "constants/rgb.h" + +static void StartORASDowseFieldEffect(void); +static void UpdateORASDowsingFieldEffect(struct Sprite *sprite); +static void ChangeDowsingColor(u8 direction, struct Sprite *sprite); +static void ClearDowsingColor(struct Sprite *sprite); +static void PlayDowseSound(u32 dowseState); + +const u32 gFieldEffectObjectPic_ORASDowsingBrendan[] = INCBIN_U32("graphics/field_effects/pics/oras_dowsing_brendan.4bpp"); +const u32 gFieldEffectObjectPic_ORASDowsingMay[] = INCBIN_U32("graphics/field_effects/pics/oras_dowsing_may.4bpp"); +const u16 gFieldEffectPal_ORASDowsing[] = INCBIN_U16("graphics/field_effects/palettes/oras_dowsing.gbapal"); + +static const struct SpriteFrameImage sPicTable_ORASDowsingBrendan[] = { + overworld_ascending_frames(gFieldEffectObjectPic_ORASDowsingBrendan, 2, 4), +}; + +static const struct SpriteFrameImage sPicTable_ORASDowsingMay[] = { + overworld_ascending_frames(gFieldEffectObjectPic_ORASDowsingMay, 2, 4), +}; + +static const union AnimCmd sAnim_FaceSouth[] = +{ + ANIMCMD_FRAME(0, 16), + ANIMCMD_JUMP(0), +}; + +static const union AnimCmd sAnim_FaceNorth[] = +{ + ANIMCMD_FRAME(1, 16), + ANIMCMD_JUMP(0), +}; + +static const union AnimCmd sAnim_FaceWest[] = +{ + ANIMCMD_FRAME(2, 16), + ANIMCMD_JUMP(0), +}; + +static const union AnimCmd sAnim_FaceEast[] = +{ + ANIMCMD_FRAME(2, 16, .hFlip = TRUE), + ANIMCMD_JUMP(0), +}; + +static const union AnimCmd sAnim_ORASDowseWiggleSouthSlow[] = +{ + ANIMCMD_FRAME(0, 32), + ANIMCMD_FRAME(0, 32), + ANIMCMD_FRAME(4, 32), + ANIMCMD_FRAME(4, 32), + ANIMCMD_JUMP(0), +}; + +static const union AnimCmd sAnim_ORASDowseWiggleNorthSlow[] = +{ + ANIMCMD_FRAME(1, 32), + ANIMCMD_FRAME(1, 32), + ANIMCMD_FRAME(6, 32), + ANIMCMD_FRAME(6, 32), + ANIMCMD_JUMP(0), +}; + +static const union AnimCmd sAnim_ORASDowseWiggleWestSlow[] = +{ + ANIMCMD_FRAME(2, 32), + ANIMCMD_FRAME(2, 32), + ANIMCMD_FRAME(8, 32), + ANIMCMD_FRAME(8, 32), + ANIMCMD_JUMP(0), +}; + +static const union AnimCmd sAnim_ORASDowseWiggleEastSlow[] = +{ + ANIMCMD_FRAME(2, 32, .hFlip = TRUE), + ANIMCMD_FRAME(2, 32, .hFlip = TRUE), + ANIMCMD_FRAME(8, 32, .hFlip = TRUE), + ANIMCMD_FRAME(8, 32, .hFlip = TRUE), + ANIMCMD_JUMP(0), +}; + +static const union AnimCmd sAnim_ORASDowseWiggleSouth[] = +{ + ANIMCMD_FRAME(0, 32), + ANIMCMD_FRAME(3, 32), + ANIMCMD_FRAME(0, 32), + ANIMCMD_FRAME(4, 32), + ANIMCMD_JUMP(0), +}; + +static const union AnimCmd sAnim_ORASDowseWiggleNorth[] = +{ + ANIMCMD_FRAME(1, 32), + ANIMCMD_FRAME(5, 32), + ANIMCMD_FRAME(1, 32), + ANIMCMD_FRAME(6, 32), + ANIMCMD_JUMP(0), +}; + +static const union AnimCmd sAnim_ORASDowseWiggleWest[] = +{ + ANIMCMD_FRAME(2, 32), + ANIMCMD_FRAME(7, 32), + ANIMCMD_FRAME(2, 32), + ANIMCMD_FRAME(8, 32), + ANIMCMD_JUMP(0), +}; + +static const union AnimCmd sAnim_ORASDowseWiggleEast[] = +{ + ANIMCMD_FRAME(2, 32, .hFlip = TRUE), + ANIMCMD_FRAME(7, 32, .hFlip = TRUE), + ANIMCMD_FRAME(2, 32, .hFlip = TRUE), + ANIMCMD_FRAME(8, 32, .hFlip = TRUE), + ANIMCMD_JUMP(0), +}; + +static const union AnimCmd sAnim_ORASDowseWiggleSouthFast[] = +{ + ANIMCMD_FRAME(0, 16), + ANIMCMD_FRAME(3, 16), + ANIMCMD_FRAME(0, 16), + ANIMCMD_FRAME(4, 16), + ANIMCMD_JUMP(0), +}; + +static const union AnimCmd sAnim_ORASDowseWiggleNorthFast[] = +{ + ANIMCMD_FRAME(1, 16), + ANIMCMD_FRAME(5, 16), + ANIMCMD_FRAME(1, 16), + ANIMCMD_FRAME(6, 16), + ANIMCMD_JUMP(0), +}; + +static const union AnimCmd sAnim_ORASDowseWiggleWestFast[] = +{ + ANIMCMD_FRAME(2, 16), + ANIMCMD_FRAME(7, 16), + ANIMCMD_FRAME(2, 16), + ANIMCMD_FRAME(8, 16), + ANIMCMD_JUMP(0), +}; + +static const union AnimCmd sAnim_ORASDowseWiggleEastFast[] = +{ + ANIMCMD_FRAME(2, 16, .hFlip = TRUE), + ANIMCMD_FRAME(7, 16, .hFlip = TRUE), + ANIMCMD_FRAME(2, 16, .hFlip = TRUE), + ANIMCMD_FRAME(8, 16, .hFlip = TRUE), + ANIMCMD_JUMP(0), +}; + +static const union AnimCmd sAnim_ORASDowseWiggleSouthFaster[] = +{ + ANIMCMD_FRAME(0, 8), + ANIMCMD_FRAME(3, 8), + ANIMCMD_FRAME(0, 8), + ANIMCMD_FRAME(4, 8), + ANIMCMD_JUMP(0), +}; + +static const union AnimCmd sAnim_ORASDowseWiggleNorthFaster[] = +{ + ANIMCMD_FRAME(1, 8), + ANIMCMD_FRAME(5, 8), + ANIMCMD_FRAME(1, 8), + ANIMCMD_FRAME(6, 8), + ANIMCMD_JUMP(0), +}; + +static const union AnimCmd sAnim_ORASDowseWiggleWestFaster[] = +{ + ANIMCMD_FRAME(2, 8), + ANIMCMD_FRAME(7, 8), + ANIMCMD_FRAME(2, 8), + ANIMCMD_FRAME(8, 8), + ANIMCMD_JUMP(0), +}; + +static const union AnimCmd sAnim_ORASDowseWiggleEastFaster[] = +{ + ANIMCMD_FRAME(2, 8, .hFlip = TRUE), + ANIMCMD_FRAME(7, 8, .hFlip = TRUE), + ANIMCMD_FRAME(2, 8, .hFlip = TRUE), + ANIMCMD_FRAME(8, 8, .hFlip = TRUE), + ANIMCMD_JUMP(0), +}; + +static const union AnimCmd *const sAnimTable_ORASDowsing[] = +{ + [ANIM_STD_FACE_SOUTH] = sAnim_FaceSouth, + [ANIM_STD_FACE_NORTH] = sAnim_FaceNorth, + [ANIM_STD_FACE_WEST] = sAnim_FaceWest, + [ANIM_STD_FACE_EAST] = sAnim_FaceEast, + [ANIM_ORAS_DOWSE_WIGGLE_SOUTH_SLOW] = sAnim_ORASDowseWiggleSouthSlow, + [ANIM_ORAS_DOWSE_WIGGLE_NORTH_SLOW] = sAnim_ORASDowseWiggleNorthSlow, + [ANIM_ORAS_DOWSE_WIGGLE_WEST_SLOW] = sAnim_ORASDowseWiggleWestSlow, + [ANIM_ORAS_DOWSE_WIGGLE_EAST_SLOW] = sAnim_ORASDowseWiggleEastSlow, + [ANIM_ORAS_DOWSE_WIGGLE_SOUTH] = sAnim_ORASDowseWiggleSouth, + [ANIM_ORAS_DOWSE_WIGGLE_NORTH] = sAnim_ORASDowseWiggleNorth, + [ANIM_ORAS_DOWSE_WIGGLE_WEST] = sAnim_ORASDowseWiggleWest, + [ANIM_ORAS_DOWSE_WIGGLE_EAST] = sAnim_ORASDowseWiggleEast, + [ANIM_ORAS_DOWSE_WIGGLE_SOUTH_FAST] = sAnim_ORASDowseWiggleSouthFast, + [ANIM_ORAS_DOWSE_WIGGLE_NORTH_FAST] = sAnim_ORASDowseWiggleNorthFast, + [ANIM_ORAS_DOWSE_WIGGLE_WEST_FAST] = sAnim_ORASDowseWiggleWestFast, + [ANIM_ORAS_DOWSE_WIGGLE_EAST_FAST] = sAnim_ORASDowseWiggleEastFast, + [ANIM_ORAS_DOWSE_WIGGLE_SOUTH_FASTER] = sAnim_ORASDowseWiggleSouthFaster, + [ANIM_ORAS_DOWSE_WIGGLE_NORTH_FASTER] = sAnim_ORASDowseWiggleNorthFaster, + [ANIM_ORAS_DOWSE_WIGGLE_WEST_FASTER] = sAnim_ORASDowseWiggleWestFaster, + [ANIM_ORAS_DOWSE_WIGGLE_EAST_FASTER] = sAnim_ORASDowseWiggleEastFaster, +}; + +static const struct OamData gObjectEventOam_ORASDowse = { + .shape = SPRITE_SHAPE(16x32), + .size = SPRITE_SIZE(16x32), + .priority = 2 +}; + +const struct SpriteTemplate gFieldEffectObjectTemplate_ORASDowsingBrendan = { + .tileTag = TAG_NONE, + .paletteTag = FLDEFF_PAL_TAG_ORAS_DOWSE, + .oam = &gObjectEventOam_ORASDowse, + .anims = sAnimTable_ORASDowsing, + .images = sPicTable_ORASDowsingBrendan, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = UpdateORASDowsingFieldEffect, +}; + +const struct SpriteTemplate gFieldEffectObjectTemplate_ORASDowsingMay = { + .tileTag = TAG_NONE, + .paletteTag = FLDEFF_PAL_TAG_ORAS_DOWSE, + .oam = &gObjectEventOam_ORASDowse, + .anims = sAnimTable_ORASDowsing, + .images = sPicTable_ORASDowsingMay, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = UpdateORASDowsingFieldEffect, +}; + +void Task_UseORASDowsingMachine(u8 taskId) +{ + if (FlagGet(I_ORAS_DOWSING_FLAG)) + { + EndORASDowsing(); + } + else + { + if (TestPlayerAvatarFlags(PLAYER_AVATAR_FLAG_BIKE)) + GetOnOffBike(0); + + StartORASDowseFieldEffect(); + } + ScriptUnfreezeObjectEvents(); + UnlockPlayerFieldControls(); + DestroyTask(taskId); +} + +static void StartORASDowseFieldEffect(void) +{ + struct ObjectEvent *playerObj = &gObjectEvents[gPlayerAvatar.objectEventId]; + + gFieldEffectArguments[0] = playerObj->currentCoords.x; + gFieldEffectArguments[1] = playerObj->currentCoords.y; + FieldEffectStart(FLDEFF_ORAS_DOWSE); +} + +void ResumeORASDowseFieldEffect(void) +{ + if (I_ORAS_DOWSING_FLAG != 0 && FlagGet(I_ORAS_DOWSING_FLAG)) + StartORASDowseFieldEffect(); +} + +static const struct SpritePalette gSpritePalette_ORASDowsing = {gFieldEffectPal_ORASDowsing, FLDEFF_PAL_TAG_ORAS_DOWSE}; + +// Sprite data for ORAS Dowsing Machine +#define tItemDistanceX data[0] +#define tItemDistanceY data[1] +#define sItemFound data[2] +#define sCounter data[3] +#define sSoundTimer data[4] +#define sDowseState data[5] +#define sPrevDowseState data[6] +#define sMoveActive data[7] + +#define fPlayerX gFieldEffectArguments[0] +#define fPlayerY gFieldEffectArguments[1] + +// Create the ORAS Dowsing Machine sprite. +u32 FldEff_ORASDowsing(void) +{ + struct ObjectEvent *playerObj = &gObjectEvents[gPlayerAvatar.objectEventId]; + u32 spriteId; + u32 palNum; + + FlagSet(I_ORAS_DOWSING_FLAG); + SetSpritePosToOffsetMapCoords((s16 *)&fPlayerX, (s16 *)&fPlayerY, 8, 0); + if (gPlayerAvatar.gender == MALE) + spriteId = CreateSpriteAtEnd(gFieldEffectObjectTemplatePointers[FLDEFFOBJ_ORAS_DOWSE_BRENDAN], fPlayerX, fPlayerY, 1); + else + spriteId = CreateSpriteAtEnd(gFieldEffectObjectTemplatePointers[FLDEFFOBJ_ORAS_DOWSE_MAY], fPlayerX, fPlayerY, 1); + + if (spriteId != MAX_SPRITES) + { + struct Sprite *sprite = &gSprites[spriteId]; + sprite->coordOffsetEnabled = TRUE; + palNum = LoadSpritePalette(&gSpritePalette_ORASDowsing); + if (palNum != 0xFF) + sprite->oam.paletteNum = palNum; + else + sprite->oam.paletteNum = LoadPlayerObjectEventPalette(gSaveBlock2Ptr->playerGender); + + playerObj->fieldEffectSpriteId = spriteId; + sprite->sDowseState = ORASD_WIGGLE_NONE; + UpdateDowseState(sprite); + } + FieldEffectActiveListRemove(FLDEFF_ORAS_DOWSE); + return spriteId; +} + +// Callback for ORAS Dowsing Machine sprite. +static void UpdateORASDowsingFieldEffect(struct Sprite *sprite) +{ + struct ObjectEvent *playerObj = &gObjectEvents[gPlayerAvatar.objectEventId]; + struct Sprite *playerSprite = &gSprites[playerObj->spriteId]; + + if (!FlagGet(I_ORAS_DOWSING_FLAG)) + { + DestroySpriteAndFreeResources(sprite); + return; + } + + sprite->x = playerSprite->x; + sprite->y = playerSprite->y; + sprite->x2 = playerSprite->x2; + sprite->y2 = playerSprite->y2; + + if (playerSprite->anims[playerSprite->animNum][playerSprite->animCmdIndex].frame.imageValue > 2) + sprite->y2++; + + if (playerObj->previousMovementDirection != playerObj->movementDirection) + UpdateDowsingAnimDirection(sprite, playerObj); + + if (playerObj->movementActionId != MOVEMENT_ACTION_NONE) + { + if (playerObj->heldMovementFinished == FALSE) + { + if (sprite->sCounter == 0) + { + sprite->sMoveActive = TRUE; + sprite->sCounter++; + } + } + else if (playerObj->heldMovementFinished == TRUE && sprite->sMoveActive) + { + sprite->sMoveActive = FALSE; + sprite->sCounter = 0; + UpdateDowseState(sprite); + } + } + + if (I_ORAS_DOWSING_SOUNDS && sprite->sDowseState == ORASD_WIGGLE_FASTER && playerObj->heldMovementFinished != FALSE) + { + if (++sprite->sSoundTimer == 70) + { + PlaySE(SE_ITEMFINDER); + sprite->sSoundTimer = 0; + } + } + sprite->oam.priority = playerSprite->oam.priority; +} + +static const u8 sClockwiseDirections[] = {DIR_NORTH, DIR_EAST, DIR_SOUTH, DIR_WEST}; + +void UpdateDowseState(struct Sprite *sprite) +{ + struct ObjectEvent *playerObj = &gObjectEvents[gPlayerAvatar.objectEventId]; + + sprite->tItemDistanceX = 0; + sprite->tItemDistanceY = 0; + sprite->sPrevDowseState = sprite->sDowseState; + if (ItemfinderCheckForHiddenItems(gMapHeader.events, TASK_NONE) == TRUE) + { + s8 distX = sprite->tItemDistanceX; + s8 distY = sprite->tItemDistanceY; + u8 directionToItem = CARDINAL_DIRECTION_COUNT; + u8 playerDirToItem = GetDirectionToHiddenItem(distX, distY); + if (playerDirToItem != DIR_NONE) + directionToItem = sClockwiseDirections[GetDirectionToHiddenItem(distX, distY) - 1]; + + if (distX < 0) + distX *= -1; + + if (distY < 0) + distY *= -1; + + // If the player is facing the item's direction. + if (directionToItem == playerObj->movementDirection) + { + ChangeDowsingColor(directionToItem, sprite); + } + // If x and y distances are equal, make sure item can bee seen from both facing directions. + else if (distX == distY && distX != 0) + { + if ((directionToItem == DIR_NORTH || directionToItem == DIR_SOUTH) && sprite->tItemDistanceX > 0 && playerObj->movementDirection == DIR_EAST) + ChangeDowsingColor(DIR_EAST, sprite); + else if ((directionToItem == DIR_NORTH || directionToItem == DIR_SOUTH) && sprite->tItemDistanceX < 0 && playerObj->movementDirection == DIR_WEST) + ChangeDowsingColor(DIR_WEST, sprite); + else + ClearDowsingColor(sprite); + } + else + { + ClearDowsingColor(sprite); + } + } + else + { + ClearDowsingColor(sprite); + } + UpdateDowsingAnimDirection(sprite, playerObj); +} + +static void ChangeDowsingColor(u8 direction, struct Sprite *sprite) +{ + s16 distance; + u16 color = I_ORAS_DOWSING_COLOR_NONE; + + if (direction == DIR_NORTH || direction == DIR_SOUTH) + distance = sprite->tItemDistanceY; + else + distance = sprite->tItemDistanceX; + + // Absolute value. + if (distance < 0) + distance *= -1; + + switch (distance) + { + case 1: + if (sprite->tItemDistanceX == 0 || sprite->tItemDistanceY == 0) + { + color = I_ORAS_DOWSING_COLOR_FASTER; + sprite->sDowseState = ORASD_WIGGLE_FASTER; + break; + } + case 2: + color = I_ORAS_DOWSING_COLOR_FAST; + sprite->sDowseState = ORASD_WIGGLE_FAST; + break; + case 3: + case 4: + color = I_ORAS_DOWSING_COLOR_NORMAL; + sprite->sDowseState = ORASD_WIGGLE_NORMAL; + break; + case 5: + case 6: + case 7: + color = I_ORAS_DOWSING_COLOR_SLOW; + sprite->sDowseState = ORASD_WIGGLE_SLOW; + break; + } + + if (I_ORAS_DOWSING_SOUNDS && sprite->sDowseState != sprite->sPrevDowseState) + { + sprite->sSoundTimer = 0; + PlayDowseSound(sprite->sDowseState); + } + + FillPalette(color, (OBJ_PLTT_ID(IndexOfSpritePaletteTag(FLDEFF_PAL_TAG_ORAS_DOWSE)) + I_ORAS_DOWSING_COLOR_PAL), PLTT_SIZEOF(1)); + UpdateSpritePaletteWithTime(IndexOfSpritePaletteTag(FLDEFF_PAL_TAG_ORAS_DOWSE)); +} + +static void ClearDowsingColor(struct Sprite *sprite) +{ + sprite->sDowseState = ORASD_WIGGLE_NONE; + FillPalette(I_ORAS_DOWSING_COLOR_NONE, (OBJ_PLTT_ID(IndexOfSpritePaletteTag(FLDEFF_PAL_TAG_ORAS_DOWSE)) + I_ORAS_DOWSING_COLOR_PAL), PLTT_SIZEOF(1)); + UpdateSpritePaletteWithTime(IndexOfSpritePaletteTag(FLDEFF_PAL_TAG_ORAS_DOWSE)); +} + +static void PlayDowseSound(u32 dowseState) +{ + switch (dowseState) + { + case ORASD_WIGGLE_SLOW: + PlaySE(SE_CONTEST_ICON_CLEAR); + return; + case ORASD_WIGGLE_NORMAL: + PlaySE(SE_PIN); + return; + case ORASD_WIGGLE_FAST: + PlaySE(SE_SUCCESS); + return; + case ORASD_WIGGLE_FASTER: + PlaySE(SE_ITEMFINDER); + return; + } +} + +void UpdateDowsingAnimDirection(struct Sprite *sprite, struct ObjectEvent *playerObj) +{ + u32 anim = (playerObj->facingDirection - 1); + + switch (sprite->sDowseState) + { + case ORASD_WIGGLE_SLOW: + anim += 4; + break; + case ORASD_WIGGLE_NORMAL: + anim += 8; + break; + case ORASD_WIGGLE_FAST: + anim += 12; + break; + case ORASD_WIGGLE_FASTER: + anim += 16; + break; + } + + // Don't completely restart anim if wiggling didn't stop. + if (sprite->sPrevDowseState != ORASD_WIGGLE_NONE && sprite->sDowseState != ORASD_WIGGLE_NONE) + SetAndStartSpriteAnim(sprite, anim, sprite->animCmdIndex); + else + StartSpriteAnimIfDifferent(sprite, anim); +} + +void EndORASDowsing(void) +{ + if (I_ORAS_DOWSING_FLAG != 0 && FlagGet(I_ORAS_DOWSING_FLAG)) + FlagClear(I_ORAS_DOWSING_FLAG); +} + +void Script_ClearDowsingColor(void) +{ + if (I_ORAS_DOWSING_FLAG != 0 && FlagGet(I_ORAS_DOWSING_FLAG)) + { + struct Sprite *sprite = &gSprites[gObjectEvents[gPlayerAvatar.objectEventId].fieldEffectSpriteId]; + ClearDowsingColor(sprite); + UpdateDowsingAnimDirection(sprite, &gObjectEvents[gPlayerAvatar.objectEventId]); + } +} + +void Script_UpdateDowseState(void) +{ + if (I_ORAS_DOWSING_FLAG != 0 && FlagGet(I_ORAS_DOWSING_FLAG)) + UpdateDowseState(&gSprites[gObjectEvents[gPlayerAvatar.objectEventId].fieldEffectSpriteId]); +} diff --git a/src/overworld.c b/src/overworld.c index a3f2e6f007..1d87ca44fc 100644 --- a/src/overworld.c +++ b/src/overworld.c @@ -43,6 +43,7 @@ #include "mirage_tower.h" #include "money.h" #include "new_game.h" +#include "oras_dowse.h" #include "palette.h" #include "play_time.h" #include "random.h" @@ -2240,6 +2241,7 @@ static bool32 ReturnToFieldLocal(u8 *state) InitViewGraphics(); TryLoadTrainerHillEReaderPalette(); FollowerNPC_BindToSurfBlobOnReloadScreen(); + ResumeORASDowseFieldEffect(); (*state)++; break; case 2: