#include "global.h" #include "field_player_avatar.h" #include "bike.h" #include "event_data.h" #include "field_effect.h" #include "field_effect_helpers.h" #include "field_ground_effect.h" #include "field_map_obj.h" #include "field_map_obj_helpers.h" #include "fieldmap.h" #include "main.h" #include "map_object_constants.h" #include "menu.h" #include "metatile_behavior.h" #include "party_menu.h" #include "rng.h" #include "overworld.h" #include "rotating_gate.h" #include "script.h" #include "songs.h" #include "sound.h" #include "strings2.h" #include "task.h" #include "tv.h" #include "wild_encounter.h" EWRAM_DATA struct PlayerAvatar gPlayerAvatar = {0}; //Functions static bool8 sub_8058854(struct MapObject *, u8); static void npc_clear_strange_bits(struct MapObject *a); static void MovePlayerAvatarUsingKeypadInput(u8 a, u16 b, u16 c); static void PlayerAllowForcedMovementIfMovingSameDirection(void); static u8 TryDoMetatileBehaviorForcedMovement(void); static u8 GetForcedMovementByMetatileBehavior(void); static void MovePlayerNotOnBike(u8 a, u16 b); static u8 CheckMovementInputNotOnBike(u8 a); static u8 CheckForPlayerAvatarCollision(u8 a); static u8 sub_8058EF0(s16 a, s16 b, u8 c); static bool8 ShouldJumpLedge(s16 a, s16 b, u8 c); static u8 sub_8058F6C(s16 a, s16 b, u8 c); static void check_acro_bike_metatile(int unused1, int unused2, u8 c, u8 *d); static void DoPlayerAvatarTransition(void); static bool8 player_is_anim_in_certain_ranges(void); static bool8 sub_80592A4(void); static bool8 PlayerIsAnimActive(void); static bool8 PlayerCheckIfAnimFinishedOrInactive(void); static void PlayerNotOnBikeCollide(u8 a); static void PlayCollisionSoundIfNotFacingWarp(u8 a); static void sub_8059D60(struct MapObject *a); static void StartStrengthAnim(u8 a, u8 b); static void sub_8059F94(void); static void sub_805A06C(void); static bool8 (*const gUnknown_0830FB58[])(u8) = { MetatileBehavior_IsTrickHouseSlipperyFloor, MetatileBehavior_IsIce_2, MetatileBehavior_IsWalkSouth, MetatileBehavior_IsWalkNorth, MetatileBehavior_IsWalkWest, MetatileBehavior_IsWalkEast, MetatileBehavior_IsSouthwardCurrent, MetatileBehavior_IsNorthwardCurrent, MetatileBehavior_IsWestwardCurrent, MetatileBehavior_IsEastwardCurrent, MetatileBehavior_IsSlideSouth, MetatileBehavior_IsSlideNorth, MetatileBehavior_IsSlideWest, MetatileBehavior_IsSlideEast, MetatileBehavior_IsWaterfall, MetatileBehavior_0xBB, MetatileBehavior_0xBC, MetatileBehavior_IsMuddySlope, }; static u8 (*const gUnknown_0830FBA0[])(void) = { ForcedMovement_None, ForcedMovement_Slip, ForcedMovement_Slip, sub_8058AAC, sub_8058AC4, sub_8058ADC, sub_8058AF4, sub_8058B0C, sub_8058B24, sub_8058B3C, sub_8058B54, ForcedMovement_SlideSouth, ForcedMovement_SlideNorth, ForcedMovement_SlideWest, ForcedMovement_SlideEast, sub_8058B0C, sub_8058C04, sub_8058C10, ForcedMovement_MuddySlope, }; static void (*const gUnknown_0830FBEC[])(u8, u16) = { PlayerNotOnBikeNotMoving, PlayerNotOnBikeTurningInPlace, sub_8058D0C, }; static bool8 (*const gUnknown_0830FBF8[])(u8) = { MetatileBehavior_IsBumpySlope, MetatileBehavior_IsIsolatedVerticalRail, MetatileBehavior_IsIsolatedHorizontalRail, MetatileBehavior_IsVerticalRail, MetatileBehavior_IsHorizontalRail, }; static const u8 gUnknown_0830FC0C[] = {9, 10, 11, 12, 13}; static void (*const gUnknown_0830FC14[])(struct MapObject *) = { PlayerAvatarTransition_Normal, PlayerAvatarTransition_MachBike, PlayerAvatarTransition_AcroBike, PlayerAvatarTransition_Surfing, PlayerAvatarTransition_Underwater, sub_80591F4, nullsub_49, nullsub_49, }; static bool8 (*const gUnknown_0830FC34[])(u8) = { MetatileBehavior_IsSouthArrowWarp, MetatileBehavior_IsNorthArrowWarp, MetatileBehavior_IsWestArrowWarp, MetatileBehavior_IsEastArrowWarp, }; static const u8 sRivalAvatarGfxIds[][2] = { {MAP_OBJ_GFX_RIVAL_BRENDAN_NORMAL, MAP_OBJ_GFX_RIVAL_MAY_NORMAL}, {MAP_OBJ_GFX_RIVAL_BRENDAN_MACH_BIKE, MAP_OBJ_GFX_RIVAL_MAY_MACH_BIKE}, {MAP_OBJ_GFX_RIVAL_BRENDAN_ACRO_BIKE, MAP_OBJ_GFX_RIVAL_MAY_ACRO_BIKE}, {MAP_OBJ_GFX_RIVAL_BRENDAN_SURFING, MAP_OBJ_GFX_RIVAL_MAY_SURFING}, {MAP_OBJ_GFX_BRENDAN_UNDERWATER, MAP_OBJ_GFX_MAY_UNDERWATER}, {MAP_OBJ_GFX_RIVAL_BRENDAN_FIELD_MOVE, MAP_OBJ_GFX_RIVAL_MAY_FIELD_MOVE}, {MAP_OBJ_GFX_BRENDAN_FISHING, MAP_OBJ_GFX_MAY_FISHING}, {MAP_OBJ_GFX_BRENDAN_WATERING, MAP_OBJ_GFX_MAY_WATERING}, }; static const u8 sPlayerAvatarGfxIds[][2] = { {MAP_OBJ_GFX_BRENDAN_NORMAL, MAP_OBJ_GFX_MAY_NORMAL}, {MAP_OBJ_GFX_BRENDAN_MACH_BIKE, MAP_OBJ_GFX_MAY_MACH_BIKE}, {MAP_OBJ_GFX_BRENDAN_ACRO_BIKE, MAP_OBJ_GFX_MAY_ACRO_BIKE}, {MAP_OBJ_GFX_BRENDAN_SURFING, MAP_OBJ_GFX_MAY_SURFING}, {MAP_OBJ_GFX_BRENDAN_UNDERWATER, MAP_OBJ_GFX_MAY_UNDERWATER}, {MAP_OBJ_GFX_BRENDAN_FIELD_MOVE, MAP_OBJ_GFX_MAY_FIELD_MOVE}, {MAP_OBJ_GFX_BRENDAN_FISHING, MAP_OBJ_GFX_MAY_FISHING}, {MAP_OBJ_GFX_BRENDAN_WATERING, MAP_OBJ_GFX_MAY_WATERING}, }; static const u8 gUnknown_0830FC64[2][5][2] = { //male { {MAP_OBJ_GFX_BRENDAN_NORMAL, 1}, {MAP_OBJ_GFX_BRENDAN_MACH_BIKE, 2}, {MAP_OBJ_GFX_BRENDAN_ACRO_BIKE, 4}, {MAP_OBJ_GFX_BRENDAN_SURFING, 8}, {MAP_OBJ_GFX_BRENDAN_UNDERWATER, 16}, }, //female { {MAP_OBJ_GFX_MAY_NORMAL, 1}, {MAP_OBJ_GFX_MAY_MACH_BIKE, 2}, {MAP_OBJ_GFX_MAY_ACRO_BIKE, 4}, {MAP_OBJ_GFX_MAY_SURFING, 8}, {MAP_OBJ_GFX_MAY_UNDERWATER, 16}, } }; static bool8 (*const gUnknown_0830FC78[])(u8) = //Duplicate of gUnknown_0830FC34 { MetatileBehavior_IsSouthArrowWarp, MetatileBehavior_IsNorthArrowWarp, MetatileBehavior_IsWestArrowWarp, MetatileBehavior_IsEastArrowWarp, }; static u8 (*const gUnknown_0830FC88[])(struct Task *, struct MapObject *, struct MapObject *) = { sub_8059E84, sub_8059EA4, sub_8059F40, }; static u8 (*const gUnknown_0830FC94[])(struct Task *, struct MapObject *) = { sub_805A000, }; static u8 (*const gUnknown_0830FC98[])(struct Task *, struct MapObject *) = { sub_805A0D8, sub_805A100, sub_805A178, sub_805A1B8, }; fieldmap_object_null_cb(sub_80587B4, sub_80587D8); void player_step(u8 direction, u16 newKeys, u16 heldKeys) { struct MapObject *playerMapObj = &gMapObjects[gPlayerAvatar.mapObjectId]; sub_8059D60(playerMapObj); if (gPlayerAvatar.unk6 == 0) { sub_80E5B38(newKeys, heldKeys); if (!sub_8058854(playerMapObj, direction)) { npc_clear_strange_bits(playerMapObj); DoPlayerAvatarTransition(); if (TryDoMetatileBehaviorForcedMovement() == 0) { MovePlayerAvatarUsingKeypadInput(direction, newKeys, heldKeys); PlayerAllowForcedMovementIfMovingSameDirection(); } } } } static bool8 sub_8058854(struct MapObject *playerMapObj, u8 direction) { if (FieldObjectIsSpecialAnimOrDirectionSequenceAnimActive(playerMapObj) && !FieldObjectClearAnimIfSpecialAnimFinished(playerMapObj)) { u8 specialAnim = FieldObjectGetSpecialAnim(playerMapObj); if (specialAnim > 24 && specialAnim < 29 && direction != DIR_NONE && playerMapObj->placeholder18 != direction) { FieldObjectClearAnim(playerMapObj); return FALSE; } else { return TRUE; } } return FALSE; } static void npc_clear_strange_bits(struct MapObject *a) { a->mapobj_bit_12 = 0; a->mapobj_bit_10 = 0; a->mapobj_bit_9 = 0; gPlayerAvatar.flags &= ~PLAYER_AVATAR_FLAG_DASH; } static void MovePlayerAvatarUsingKeypadInput(u8 direction, u16 newKeys, u16 heldKeys) { if ((gPlayerAvatar.flags & PLAYER_AVATAR_FLAG_MACH_BIKE) || (gPlayerAvatar.flags & PLAYER_AVATAR_FLAG_ACRO_BIKE)) MovePlayerOnBike(direction, newKeys, heldKeys); else MovePlayerNotOnBike(direction, heldKeys); } static void PlayerAllowForcedMovementIfMovingSameDirection(void) { if (gPlayerAvatar.running2 == 2) gPlayerAvatar.flags &= ~PLAYER_AVATAR_FLAG_5; } static u8 TryDoMetatileBehaviorForcedMovement(void) { return gUnknown_0830FBA0[GetForcedMovementByMetatileBehavior()](); } static u8 GetForcedMovementByMetatileBehavior(void) { u8 i; if (!(gPlayerAvatar.flags & PLAYER_AVATAR_FLAG_5)) { u8 r5 = gMapObjects[gPlayerAvatar.mapObjectId].mapobj_unk_1E; for (i = 0; i < 18; i++) { if (gUnknown_0830FB58[i](r5)) return i + 1; } } return 0; } u8 ForcedMovement_None(void) { if (gPlayerAvatar.flags & PLAYER_AVATAR_FLAG_6) { struct MapObject *playerMapObj = &gMapObjects[gPlayerAvatar.mapObjectId]; playerMapObj->mapobj_bit_9 = 0; playerMapObj->mapobj_bit_11 = 1; FieldObjectSetDirection(playerMapObj, playerMapObj->mapobj_unk_18); gPlayerAvatar.flags &= ~PLAYER_AVATAR_FLAG_6; } return 0; } static u8 DoForcedMovement(u8 direction, void (*b)(u8)) { struct PlayerAvatar *playerAvatar = &gPlayerAvatar; u8 collisionType = CheckForPlayerAvatarCollision(direction); playerAvatar->flags |= PLAYER_AVATAR_FLAG_6; if (collisionType != 0) { ForcedMovement_None(); if (collisionType <= 4) { return 0; } else { if (collisionType == COLLISION_LEDGE_JUMP) PlayerJumpLedge(direction); playerAvatar->flags |= PLAYER_AVATAR_FLAG_6; playerAvatar->running2 = 2; return 1; } } else { playerAvatar->running2 = 2; b(direction); return 1; } } static u8 DoForcedMovementInCurrentDirection(void (*a)(u8)) { struct MapObject *playerMapObj = &gMapObjects[gPlayerAvatar.mapObjectId]; playerMapObj->mapobj_bit_10 = 1; return DoForcedMovement(playerMapObj->placeholder18, a); } u8 ForcedMovement_Slip(void) { return DoForcedMovementInCurrentDirection(sub_80593C4); } u8 sub_8058AAC(void) { return DoForcedMovement(1, PlayerGoSpeed0); } u8 sub_8058AC4(void) { return DoForcedMovement(2, PlayerGoSpeed0); } u8 sub_8058ADC(void) { return DoForcedMovement(3, PlayerGoSpeed0); } u8 sub_8058AF4(void) { return DoForcedMovement(4, PlayerGoSpeed0); } u8 sub_8058B0C(void) { return DoForcedMovement(1, npc_use_some_d2s); } u8 sub_8058B24(void) { return DoForcedMovement(2, npc_use_some_d2s); } u8 sub_8058B3C(void) { return DoForcedMovement(3, npc_use_some_d2s); } u8 sub_8058B54(void) { return DoForcedMovement(4, npc_use_some_d2s); } static u8 ForcedMovement_Slide(u8 direction, void (*b)(u8)) { struct MapObject *playerMapObj = &gMapObjects[gPlayerAvatar.mapObjectId]; playerMapObj->mapobj_bit_10 = 1; playerMapObj->mapobj_bit_9 = 1; return DoForcedMovement(direction, b); } u8 ForcedMovement_SlideSouth(void) { return ForcedMovement_Slide(1, sub_80593C4); } u8 ForcedMovement_SlideNorth(void) { return ForcedMovement_Slide(2, sub_80593C4); } u8 ForcedMovement_SlideWest(void) { return ForcedMovement_Slide(3, sub_80593C4); } u8 ForcedMovement_SlideEast(void) { return ForcedMovement_Slide(4, sub_80593C4); } u8 sub_8058C04(void) { sub_8059F94(); return 1; } u8 sub_8058C10(void) { sub_805A06C(); return 1; } u8 ForcedMovement_MuddySlope(void) { struct MapObject *playerMapObj = &gMapObjects[gPlayerAvatar.mapObjectId]; if (playerMapObj->placeholder18 != 2 || GetPlayerSpeed() <= 3) { sub_80E6010(0); playerMapObj->mapobj_bit_9 = 1; return DoForcedMovement(1, sub_80593C4); } else { return 0; } } static void MovePlayerNotOnBike(u8 direction, u16 heldKeys) { gUnknown_0830FBEC[CheckMovementInputNotOnBike(direction)](direction, heldKeys); } static u8 CheckMovementInputNotOnBike(u8 direction) { if (direction == DIR_NONE) { gPlayerAvatar.running2 = 0; return 0; } else if (direction != player_get_direction_upper_nybble() && gPlayerAvatar.running2 != 2) { gPlayerAvatar.running2 = 1; return 1; } else { gPlayerAvatar.running2 = 2; return 2; } } void PlayerNotOnBikeNotMoving(u8 direction, u16 heldKeys) { PlayerFaceDirection(player_get_direction_lower_nybble()); } void PlayerNotOnBikeTurningInPlace(u8 direction, u16 heldKeys) { PlayerTurnInPlace(direction); } void sub_8058D0C(u8 direction, u16 heldKeys) { u8 r1 = CheckForPlayerAvatarCollision(direction); switch (r1) { case 6: PlayerJumpLedge(direction); return; default: if (r1 > 8 || r1 < 5) PlayerNotOnBikeCollide(direction); return; case 0: if (gPlayerAvatar.flags & PLAYER_AVATAR_FLAG_SURFING) { sub_80593C4(direction); return; } if (!(gPlayerAvatar.flags & PLAYER_AVATAR_FLAG_4) && (heldKeys & B_BUTTON) && FlagGet(SYS_B_DASH) && IsRunningDisallowed(gMapObjects[gPlayerAvatar.mapObjectId].mapobj_unk_1E) == 0) { sub_805940C(direction); gPlayerAvatar.flags |= PLAYER_AVATAR_FLAG_DASH; } else { PlayerGoSpeed0(direction); } } } static u8 CheckForPlayerAvatarCollision(u8 direction) { s16 x, y; struct MapObject *playerMapObj = &gMapObjects[gPlayerAvatar.mapObjectId]; x = playerMapObj->coords2.x; y = playerMapObj->coords2.y; MoveCoords(direction, &x, &y); return CheckForFieldObjectCollision(playerMapObj, x, y, direction, MapGridGetMetatileBehaviorAt(x, y)); } u8 CheckForFieldObjectCollision(struct MapObject *a, s16 x, s16 y, u8 direction, u8 e) { u8 collision; collision = npc_block_way(a, x, y, direction); if (collision == 3 && sub_8058EF0(x, y, direction)) return 5; if (ShouldJumpLedge(x, y, direction)) { IncrementGameStat(0x2B); return COLLISION_LEDGE_JUMP; } if (collision == 4 && sub_8058F6C(x, y, direction)) return 7; if (collision == 0) { if (CheckForRotatingGatePuzzleCollision(direction, x, y)) return 8; check_acro_bike_metatile(x, y, e, &collision); } return collision; } static u8 sub_8058EF0(s16 a, s16 b, u8 c) { if ((gPlayerAvatar.flags & PLAYER_AVATAR_FLAG_SURFING) && MapGridGetZCoordAt(a, b) == 3 && GetFieldObjectIdByXYZ(a, b, 3) == 16) { sub_805A20C(c); return 1; } else { return 0; } } static bool8 ShouldJumpLedge(s16 a, s16 b, u8 c) { if (GetLedgeJumpDirection(a, b, c) != 0) return 1; else return 0; } static u8 sub_8058F6C(s16 a, s16 b, u8 c) { if (FlagGet(SYS_USE_STRENGTH)) { u8 mapObjectId = GetFieldObjectIdByXY(a, b); if (mapObjectId != 16) { if (gMapObjects[mapObjectId].graphicsId == 0x57) { a = gMapObjects[mapObjectId].coords2.x; b = gMapObjects[mapObjectId].coords2.y; MoveCoords(c, &a, &b); if (npc_block_way(&gMapObjects[mapObjectId], a, b, c) == 0 && MetatileBehavior_IsNonAnimDoor(MapGridGetMetatileBehaviorAt(a, b)) == 0) { StartStrengthAnim(mapObjectId, c); return 1; } } } } return 0; } static void check_acro_bike_metatile(int unused1, int unused2, u8 c, u8 *d) { u8 i; for (i = 0; i < 5; i++) { if (gUnknown_0830FBF8[i](c)) { *d = gUnknown_0830FC0C[i]; return; } } } void SetPlayerAvatarTransitionFlags(u16 a) { gPlayerAvatar.bike |= a; DoPlayerAvatarTransition(); } static void DoPlayerAvatarTransition(void) { u8 i; u32 flags = gPlayerAvatar.bike; if (flags != 0) { for (i = 0; i < 8; i++, flags >>= 1) { #ifdef NONMATCHING if (flags & 1) { gUnknown_0830FC14[i](&gMapObjects[gPlayerAvatar.mapObjectId]); } #else if (flags & 1) { register void (*const *funcs)(struct MapObject *) asm("r0") = gUnknown_0830FC14; funcs[i](&gMapObjects[gPlayerAvatar.mapObjectId]); } #endif } gPlayerAvatar.bike = 0; } } void nullsub_49(struct MapObject *a) { } void PlayerAvatarTransition_Normal(struct MapObject *a) { sub_805B980(a, GetPlayerAvatarGraphicsIdByStateId(0)); FieldObjectTurn(a, a->placeholder18); SetPlayerAvatarStateMask(1); } void PlayerAvatarTransition_MachBike(struct MapObject *a) { sub_805B980(a, GetPlayerAvatarGraphicsIdByStateId(1)); FieldObjectTurn(a, a->placeholder18); SetPlayerAvatarStateMask(2); BikeClearState(0, 0); } void PlayerAvatarTransition_AcroBike(struct MapObject *a) { sub_805B980(a, GetPlayerAvatarGraphicsIdByStateId(2)); FieldObjectTurn(a, a->placeholder18); SetPlayerAvatarStateMask(4); BikeClearState(0, 0); sub_80E6084(); } void PlayerAvatarTransition_Surfing(struct MapObject *a) { u8 unk; sub_805B980(a, GetPlayerAvatarGraphicsIdByStateId(3)); FieldObjectTurn(a, a->placeholder18); SetPlayerAvatarStateMask(8); gFieldEffectArguments[0] = a->coords2.x; gFieldEffectArguments[1] = a->coords2.y; gFieldEffectArguments[2] = gPlayerAvatar.mapObjectId; unk = FieldEffectStart(FLDEFF_SURF_BLOB); a->mapobj_unk_1A = unk; sub_8127ED0(unk, 1); } void PlayerAvatarTransition_Underwater(struct MapObject *a) { sub_805B980(a, GetPlayerAvatarGraphicsIdByStateId(4)); FieldObjectTurn(a, a->placeholder18); SetPlayerAvatarStateMask(16); a->mapobj_unk_1A = sub_8128124(a->spriteId); } void sub_80591F4(struct MapObject *a) { gPlayerAvatar.flags |= PLAYER_AVATAR_FLAG_5; } void sub_8059204(void) { gPlayerAvatar.running1 = 0; if (PlayerIsAnimActive()) { if (!PlayerCheckIfAnimFinishedOrInactive()) { if (!player_is_anim_in_certain_ranges()) gPlayerAvatar.running1 = 1; } else { if (!sub_80592A4()) gPlayerAvatar.running1 = 2; } } } static bool8 player_is_anim_in_certain_ranges(void) { u8 unk = gMapObjects[gPlayerAvatar.mapObjectId].mapobj_unk_1C; if (unk < 4 || (unk >= 16 && unk < 0x15) || (unk >= 25 && unk < 41) || (unk >= 98 && unk < 110) || (unk >= 122 && unk < 126)) return TRUE; else return FALSE; } static bool8 sub_80592A4(void) { if (player_is_anim_in_certain_ranges() && gPlayerAvatar.running2 != 1) return TRUE; else return FALSE; } static bool8 PlayerIsAnimActive(void) { return FieldObjectIsSpecialAnimOrDirectionSequenceAnimActive(&gMapObjects[gPlayerAvatar.mapObjectId]); } static bool8 PlayerCheckIfAnimFinishedOrInactive(void) { return FieldObjectCheckIfSpecialAnimFinishedOrInactive(&gMapObjects[gPlayerAvatar.mapObjectId]); } static void player_set_x22(u8 a) { gMapObjects[gPlayerAvatar.mapObjectId].animId = a; } u8 player_get_x22(void) { return gMapObjects[gPlayerAvatar.mapObjectId].animId; } static void sub_8059348(u8 a) { FieldObjectForceSetSpecialAnim(&gMapObjects[gPlayerAvatar.mapObjectId], a); } void PlayerSetAnimId(u8 animId, u8 b) { if (!PlayerIsAnimActive()) { player_set_x22(b); FieldObjectSetSpecialAnim(&gMapObjects[gPlayerAvatar.mapObjectId], animId); } } void PlayerGoSpeed0(u8 a) { PlayerSetAnimId(GetGoSpeed0AnimId(a), 2); } void sub_80593C4(u8 a) { PlayerSetAnimId(sub_8060744(a), 2); } void npc_use_some_d2s(u8 a) { PlayerSetAnimId(d2s_08064034(a), 2); } void sub_80593F4(u8 a) { PlayerSetAnimId(sub_806079C(a), 2); } void sub_805940C(u8 a) { PlayerSetAnimId(sub_80607F4(a), 2); } void PlayerOnBikeCollide(u8 a) { PlayCollisionSoundIfNotFacingWarp(a); PlayerSetAnimId(GetStepInPlaceDelay16AnimId(a), 2); } static void PlayerNotOnBikeCollide(u8 a) { PlayCollisionSoundIfNotFacingWarp(a); PlayerSetAnimId(GetStepInPlaceDelay32AnimId(a), 2); } void PlayerFaceDirection(u8 direction) { PlayerSetAnimId(GetFaceDirectionAnimId(direction), 1); } void PlayerTurnInPlace(u8 direction) { PlayerSetAnimId(GetStepInPlaceDelay8AnimId(direction), 1); } void PlayerJumpLedge(u8 direction) { PlaySE(SE_DANSA); PlayerSetAnimId(GetJumpLedgeAnimId(direction), 8); } void sub_80594C0(void) { if (gPlayerAvatar.running1 == 2 || gPlayerAvatar.running1 == 0) { if (player_should_look_direction_be_enforced_upon_movement()) sub_8059348(GetFaceDirectionAnimId(gMapObjects[gPlayerAvatar.mapObjectId].mapobj_unk_18)); } } void sub_8059504(u8 a) { PlayerSetAnimId(sub_80609D8(a), 1); } //normal to wheelie void PlayerStartWheelie(u8 a) { PlayerSetAnimId(sub_8060A04(a), 1); } void sub_8059534(u8 a) { PlayerSetAnimId(sub_8060A30(a), 1); } void sub_805954C(u8 a) { PlaySE(SE_JITE_PYOKO); PlayerSetAnimId(sub_8060A5C(a), 1); } void sub_8059570(u8 a) { PlaySE(SE_JITE_PYOKO); PlayerSetAnimId(sub_8060A88(a), 2); } void sub_8059594(u8 a) { PlaySE(SE_JITE_PYOKO); PlayerSetAnimId(sub_8060AB4(a), 8); } void sub_80595B8(u8 direction) { PlaySE(SE_JITE_PYOKO); PlayerSetAnimId(sub_8060878(direction), 1); } void sub_80595DC(u8 direction) { PlaySE(SE_WALL_HIT); PlayerSetAnimId(sub_8060AE0(direction), 2); } void sub_8059600(u8 a) { PlayerSetAnimId(sub_8060B0C(a), 2); } void sub_8059618(u8 a) { PlayerSetAnimId(sub_8060B38(a), 2); } void sub_8059630(u8 a) { PlayerSetAnimId(sub_8060B64(a), 2); } static void PlayCollisionSoundIfNotFacingWarp(u8 a) { s16 x, y; u8 unk = gMapObjects[gPlayerAvatar.mapObjectId].mapobj_unk_1E; if (!gUnknown_0830FC34[a - 1](unk)) { if (a == 2) { PlayerGetDestCoords(&x, &y); MoveCoords(2, &x, &y); if (MetatileBehavior_IsWarpDoor(MapGridGetMetatileBehaviorAt(x, y))) return; } PlaySE(SE_WALL_HIT); } } void GetXYCoordsOneStepInFrontOfPlayer(s16 *x, s16 *y) { *x = gMapObjects[gPlayerAvatar.mapObjectId].coords2.x; *y = gMapObjects[gPlayerAvatar.mapObjectId].coords2.y; MoveCoords(player_get_direction_lower_nybble(), x, y); } void PlayerGetDestCoords(s16 *x, s16 *y) { *x = gMapObjects[gPlayerAvatar.mapObjectId].coords2.x; *y = gMapObjects[gPlayerAvatar.mapObjectId].coords2.y; } u8 player_get_direction_lower_nybble(void) { return gMapObjects[gPlayerAvatar.mapObjectId].mapobj_unk_18; } u8 player_get_direction_upper_nybble(void) { return gMapObjects[gPlayerAvatar.mapObjectId].placeholder18; } u8 PlayerGetZCoord(void) { return gMapObjects[gPlayerAvatar.mapObjectId].elevation; } void unref_sub_8059790(s16 a, s16 b) { sub_805C058(&gMapObjects[gPlayerAvatar.mapObjectId], a, b); } u8 TestPlayerAvatarFlags(u8 a) { return gPlayerAvatar.flags & a; } u8 sub_80597D0(void) { return gPlayerAvatar.flags; } u8 GetPlayerAvatarObjectId(void) { return gPlayerAvatar.spriteId; } void sub_80597E8(void) { ForcedMovement_None(); } void sub_80597F4(void) { struct MapObject *playerMapObj = &gMapObjects[gPlayerAvatar.mapObjectId]; npc_clear_strange_bits(playerMapObj); FieldObjectSetDirection(playerMapObj, playerMapObj->mapobj_unk_18); if (TestPlayerAvatarFlags(PLAYER_AVATAR_FLAG_MACH_BIKE | PLAYER_AVATAR_FLAG_ACRO_BIKE)) { sub_80E6084(); sub_80E6010(0); } } u8 GetRivalAvatarGraphicsIdByStateIdAndGender(u8 state, u8 gender) { return sRivalAvatarGfxIds[state][gender]; } static u8 GetPlayerAvatarGraphicsIdByStateIdAndGender(u8 state, u8 gender) { return sPlayerAvatarGfxIds[state][gender]; } u8 GetPlayerAvatarGraphicsIdByStateId(u8 state) { return GetPlayerAvatarGraphicsIdByStateIdAndGender(state, gPlayerAvatar.gender); } u8 unref_GetRivalAvatarGenderByGraphcsId(u8 gfxId) { switch (gfxId) { case MAP_OBJ_GFX_RIVAL_MAY_NORMAL: case MAP_OBJ_GFX_RIVAL_MAY_MACH_BIKE: case MAP_OBJ_GFX_RIVAL_MAY_ACRO_BIKE: case MAP_OBJ_GFX_RIVAL_MAY_SURFING: case MAP_OBJ_GFX_RIVAL_MAY_FIELD_MOVE: case MAP_OBJ_GFX_MAY_UNDERWATER: case MAP_OBJ_GFX_MAY_FISHING: case MAP_OBJ_GFX_MAY_WATERING: return FEMALE; default: return MALE; } } u8 GetPlayerAvatarGenderByGraphicsId(u8 gfxId) { switch (gfxId) { case MAP_OBJ_GFX_MAY_NORMAL: case MAP_OBJ_GFX_MAY_MACH_BIKE: case MAP_OBJ_GFX_MAY_ACRO_BIKE: case MAP_OBJ_GFX_MAY_SURFING: case MAP_OBJ_GFX_MAY_FIELD_MOVE: case MAP_OBJ_GFX_MAY_UNDERWATER: case MAP_OBJ_GFX_MAY_FISHING: case MAP_OBJ_GFX_MAY_WATERING: return FEMALE; default: return MALE; } } bool8 PartyHasMonWithSurf(void) { u8 i; if (!TestPlayerAvatarFlags(PLAYER_AVATAR_FLAG_SURFING)) { for (i = 0; i < 6; i++) { if (GetMonData(&gPlayerParty[i], MON_DATA_SPECIES) == 0) break; if (pokemon_has_move(&gPlayerParty[i], 0x39)) return TRUE; } } return FALSE; } bool8 IsPlayerSurfingNorth(void) { if (player_get_direction_upper_nybble() == DIR_NORTH && TestPlayerAvatarFlags(PLAYER_AVATAR_FLAG_SURFING)) return TRUE; else return FALSE; } bool8 IsPlayerFacingSurfableFishableWater(void) { struct MapObject *playerMapObj = &gMapObjects[gPlayerAvatar.mapObjectId]; s16 x = playerMapObj->coords2.x; s16 y = playerMapObj->coords2.y; MoveCoords(playerMapObj->mapobj_unk_18, &x, &y); if (npc_block_way(playerMapObj, x, y, playerMapObj->mapobj_unk_18) == 3 && PlayerGetZCoord() == 3 && MetatileBehavior_IsSurfableFishableWater(MapGridGetMetatileBehaviorAt(x, y))) return TRUE; else return FALSE; } void ClearPlayerAvatarInfo(void) { //TODO: 0x24 should be the size of gPlayerAvatar memset(&gPlayerAvatar, 0, sizeof(struct PlayerAvatar)); } void SetPlayerAvatarStateMask(u8 a) { gPlayerAvatar.flags &= 0xE0; gPlayerAvatar.flags |= a; } static u8 GetPlayerAvatarStateTransitionByGraphicsId(u8 a, u8 gender) { u8 i; for (i = 0; i < 5; i++) { if (gUnknown_0830FC64[gender][i][0] == a) return gUnknown_0830FC64[gender][i][1]; } return 1; } u8 GetPlayerAvatarGraphicsIdByCurrentState(void) { u8 i; u8 r5 = gPlayerAvatar.flags; for (i = 0; i < 5; i++) { if (gUnknown_0830FC64[gPlayerAvatar.gender][i][1] & r5) return gUnknown_0830FC64[gPlayerAvatar.gender][i][0]; } return 0; } void SetPlayerAvatarExtraStateTransition(u8 a, u8 b) { u8 unk = GetPlayerAvatarStateTransitionByGraphicsId(a, gPlayerAvatar.gender); gPlayerAvatar.bike |= unk | b; DoPlayerAvatarTransition(); } void InitPlayerAvatar(s16 x, s16 y, u8 direction, u8 gender) { struct MapObjectTemplate playerMapObjTemplate; u8 mapObjectId; struct MapObject *mapObject; playerMapObjTemplate.localId = 0xFF; playerMapObjTemplate.graphicsId = GetPlayerAvatarGraphicsIdByStateIdAndGender(0, gender); playerMapObjTemplate.x = x - 7; playerMapObjTemplate.y = y - 7; playerMapObjTemplate.elevation = 0; playerMapObjTemplate.movementType = 11; playerMapObjTemplate.unkA_0 = 0; playerMapObjTemplate.unkA_4 = 0; playerMapObjTemplate.unkC = 0; playerMapObjTemplate.unkE = 0; playerMapObjTemplate.script = NULL; playerMapObjTemplate.flagId = 0; mapObjectId = SpawnSpecialFieldObject(&playerMapObjTemplate); mapObject = &gMapObjects[mapObjectId]; mapObject->mapobj_bit_16 = 1; mapObject->mapobj_unk_1B = sub_8126B54(); FieldObjectTurn(mapObject, direction); ClearPlayerAvatarInfo(); gPlayerAvatar.running2 = 0; gPlayerAvatar.running1 = 0; gPlayerAvatar.mapObjectId = mapObjectId; gPlayerAvatar.spriteId = mapObject->spriteId; gPlayerAvatar.gender = gender; SetPlayerAvatarStateMask(0x21); } void sub_8059B88(u8 a) { gMapObjects[gPlayerAvatar.mapObjectId].mapobj_bit_13 = a; if (TestPlayerAvatarFlags(PLAYER_AVATAR_FLAG_SURFING)) gSprites[gMapObjects[gPlayerAvatar.mapObjectId].mapobj_unk_1A].invisible = a; } void sub_8059BF4(void) { sub_805B980(&gMapObjects[gPlayerAvatar.mapObjectId], GetPlayerAvatarGraphicsIdByStateId(5)); StartSpriteAnim(&gSprites[gPlayerAvatar.spriteId], 0); } void sub_8059C3C(u8 a) { sub_805B980(&gMapObjects[gPlayerAvatar.mapObjectId], GetPlayerAvatarGraphicsIdByStateId(6)); StartSpriteAnim(&gSprites[gPlayerAvatar.spriteId], sub_805FDE8(a)); } void sub_8059C94(u8 a) { sub_805B980(&gMapObjects[gPlayerAvatar.mapObjectId], GetPlayerAvatarGraphicsIdByStateId(2)); StartSpriteAnim(&gSprites[gPlayerAvatar.spriteId], sub_805FD98(a)); SeekSpriteAnim(&gSprites[gPlayerAvatar.spriteId], 1); } void sub_8059D08(u8 a) { sub_805B980(&gMapObjects[gPlayerAvatar.mapObjectId], GetPlayerAvatarGraphicsIdByStateId(7)); StartSpriteAnim(&gSprites[gPlayerAvatar.spriteId], FieldObjectDirectionToImageAnimId(a)); } static void sub_8059D60(struct MapObject *a) { s16 x; s16 y; u8 r6; u8 r8 = a->mapobj_unk_1E; for (x = 0, r6 = 1; x < 4; x++, r6++) { if (gUnknown_0830FC78[x](r8) && r6 == a->placeholder18) { x = a->coords2.x; y = a->coords2.y; MoveCoords(r6, &x, &y); sub_8126BC4(a->mapobj_unk_1B, r6, x, y); return; } } objid_set_invisible(a->mapobj_unk_1B); } /* Strength */ static void sub_8059E2C(u8 taskId); static void StartStrengthAnim(u8 a, u8 b) { u8 taskId = CreateTask(sub_8059E2C, 0xFF); gTasks[taskId].data[1] = a; gTasks[taskId].data[2] = b; sub_8059E2C(taskId); } static void sub_8059E2C(u8 taskId) { while (gUnknown_0830FC88[gTasks[taskId].data[0]](&gTasks[taskId], &gMapObjects[gPlayerAvatar.mapObjectId], &gMapObjects[gTasks[taskId].data[1]])) ; } u8 sub_8059E84(struct Task *task, struct MapObject *b, struct MapObject *c) { ScriptContext2_Enable(); gPlayerAvatar.unk6 = 1; task->data[0]++; return 0; } u8 sub_8059EA4(struct Task *task, struct MapObject *b, struct MapObject *c) { if (!FieldObjectIsSpecialAnimOrDirectionSequenceAnimActive(b) && !FieldObjectIsSpecialAnimOrDirectionSequenceAnimActive(c)) { FieldObjectClearAnimIfSpecialAnimFinished(b); FieldObjectClearAnimIfSpecialAnimFinished(c); FieldObjectSetSpecialAnim(b, GetStepInPlaceDelay16AnimId((u8)task->data[2])); FieldObjectSetSpecialAnim(c, GetSimpleGoAnimId((u8)task->data[2])); gFieldEffectArguments[0] = c->coords2.x; gFieldEffectArguments[1] = c->coords2.y; gFieldEffectArguments[2] = c->elevation; gFieldEffectArguments[3] = gSprites[c->spriteId].oam.priority; FieldEffectStart(FLDEFF_DUST); PlaySE(SE_W070); task->data[0]++; } return 0; } u8 sub_8059F40(struct Task *task, struct MapObject *b, struct MapObject *c) { if (FieldObjectCheckIfSpecialAnimFinishedOrInactive(b) && FieldObjectCheckIfSpecialAnimFinishedOrInactive(c)) { FieldObjectClearAnimIfSpecialAnimFinished(b); FieldObjectClearAnimIfSpecialAnimFinished(c); gPlayerAvatar.unk6 = 0; ScriptContext2_Disable(); DestroyTask(FindTaskIdByFunc(sub_8059E2C)); } return 0; } /* Some field effect */ static void sub_8059FB4(u8 taskId); static void sub_8059F94(void) { u8 taskId = CreateTask(sub_8059FB4, 0xFF); sub_8059FB4(taskId); } static void sub_8059FB4(u8 taskId) { while (gUnknown_0830FC94[gTasks[taskId].data[0]](&gTasks[taskId], &gMapObjects[gPlayerAvatar.mapObjectId])) ; } u8 sub_805A000(struct Task *task, struct MapObject *mapObject) { gPlayerAvatar.unk6 = 1; if (FieldObjectClearAnimIfSpecialAnimFinished(mapObject)) { PlaySE(SE_DANSA); FieldObjectSetSpecialAnim(mapObject, sub_806084C(mapObject->mapobj_unk_18)); task->data[1]++; if (task->data[1] > 1) { gPlayerAvatar.unk6 = 0; gPlayerAvatar.bike |= 0x20; DestroyTask(FindTaskIdByFunc(sub_8059FB4)); } } return 0; } /* Some field effect */ static void sub_805A08C(u8 taskId); static void sub_805A06C(void) { u8 taskId = CreateTask(sub_805A08C, 0xFF); sub_805A08C(taskId); } static void sub_805A08C(u8 taskId) { while (gUnknown_0830FC98[gTasks[taskId].data[0]](&gTasks[taskId], &gMapObjects[gPlayerAvatar.mapObjectId])) ; } u8 sub_805A0D8(struct Task *task, struct MapObject *mapObject) { task->data[0]++; task->data[1] = mapObject->placeholder18; gPlayerAvatar.unk6 = 1; ScriptContext2_Enable(); PlaySE(SE_TK_WARPIN); return 1; } u8 sub_805A100(struct Task *task, struct MapObject *mapObject) { u8 directions[] = {DIR_WEST, DIR_EAST, DIR_NORTH, DIR_SOUTH}; if (FieldObjectClearAnimIfSpecialAnimFinished(mapObject)) { u8 direction; FieldObjectSetSpecialAnim(mapObject, GetFaceDirectionAnimId(direction = directions[mapObject->placeholder18 - 1])); if (direction == (u8)task->data[1]) task->data[2]++; task->data[0]++; if (task->data[2] > 3 && direction == GetOppositeDirection(task->data[1])) task->data[0]++; } return 0; } u8 sub_805A178(struct Task *task, struct MapObject *mapObject) { const u8 arr[] = {16, 16, 17, 18, 19}; if (FieldObjectClearAnimIfSpecialAnimFinished(mapObject)) { FieldObjectSetSpecialAnim(mapObject, arr[task->data[2]]); task->data[0] = 1; } return 0; } u8 sub_805A1B8(struct Task *task, struct MapObject *mapObject) { if (FieldObjectClearAnimIfSpecialAnimFinished(mapObject)) { FieldObjectSetSpecialAnim(mapObject, GetSimpleGoAnimId(GetOppositeDirection(task->data[1]))); ScriptContext2_Disable(); gPlayerAvatar.unk6 = 0; DestroyTask(FindTaskIdByFunc(sub_805A08C)); } return 0; } /* Some Field effect */ static void taskFF_0805D1D4(u8 taskId); static void sub_805A2D0(u8 taskId); void sub_805A20C(u8 a) { u8 taskId; ScriptContext2_Enable(); sav1_reset_battle_music_maybe(); sub_8053F84(); gPlayerAvatar.flags &= ~PLAYER_AVATAR_FLAG_SURFING; gPlayerAvatar.flags |= PLAYER_AVATAR_FLAG_ON_FOOT; gPlayerAvatar.unk6 = 1; taskId = CreateTask(taskFF_0805D1D4, 0xFF); gTasks[taskId].data[0] = a; taskFF_0805D1D4(taskId); } static void taskFF_0805D1D4(u8 taskId) { struct MapObject *playerMapObj = &gMapObjects[gPlayerAvatar.mapObjectId]; if (FieldObjectIsSpecialAnimOrDirectionSequenceAnimActive(playerMapObj)) { if (!FieldObjectClearAnimIfSpecialAnimFinished(playerMapObj)) return; } sub_8127ED0(playerMapObj->mapobj_unk_1A, 2); FieldObjectSetSpecialAnim(playerMapObj, sub_80608D0((u8)gTasks[taskId].data[0])); gTasks[taskId].func = sub_805A2D0; } static void sub_805A2D0(u8 taskId) { struct MapObject *playerMapObj = &gMapObjects[gPlayerAvatar.mapObjectId]; if (FieldObjectClearAnimIfSpecialAnimFinished(playerMapObj)) { sub_805B980(playerMapObj, GetPlayerAvatarGraphicsIdByStateId(0)); FieldObjectSetSpecialAnim(playerMapObj, GetFaceDirectionAnimId(playerMapObj->mapobj_unk_18)); gPlayerAvatar.unk6 = 0; ScriptContext2_Disable(); DestroySprite(&gSprites[playerMapObj->mapobj_unk_1A]); DestroyTask(taskId); } } /* Fishing */ static u8 (*const sFishingStateFuncs[])(struct Task *) = { Fishing1, Fishing2, Fishing3, Fishing4, Fishing5, Fishing6, Fishing7, Fishing8, Fishing9, Fishing10, Fishing11, Fishing12, Fishing13, Fishing14, Fishing15, Fishing16, }; static void Task_Fishing(u8 taskId); static void sub_805A954(void); #define tStep data[0] #define tFrameCounter data[1] #define tNumDots data[2] #define tDotsRequired data[3] #define tRoundsPlayed data[12] #define tMinRoundsRequired data[13] #define tPlayerGfxId data[14] #define tFishingRod data[15] #define FISHING_START_ROUND 3 #define FISHING_GOT_BITE 6 #define FISHING_ON_HOOK 9 #define FISHING_NO_BITE 11 #define FISHING_GOT_AWAY 12 #define FISHING_SHOW_RESULT 13 void StartFishing(u8 rod) { u8 taskId = CreateTask(Task_Fishing, 0xFF); gTasks[taskId].tFishingRod = rod; Task_Fishing(taskId); } static void Task_Fishing(u8 taskId) { while (sFishingStateFuncs[gTasks[taskId].tStep](&gTasks[taskId])) ; } u8 Fishing1(struct Task *task) { ScriptContext2_Enable(); gPlayerAvatar.unk6 = 1; task->tStep++; return 0; } u8 Fishing2(struct Task *task) { struct MapObject *playerMapObj; const s16 arr1[] = {1, 1, 1}; const s16 arr2[] = {1, 3, 6}; task->tRoundsPlayed = 0; task->tMinRoundsRequired = arr1[task->tFishingRod] + (Random() % arr2[task->tFishingRod]); task->tPlayerGfxId = gMapObjects[gPlayerAvatar.mapObjectId].graphicsId; playerMapObj = &gMapObjects[gPlayerAvatar.mapObjectId]; FieldObjectClearAnimIfSpecialAnimActive(playerMapObj); playerMapObj->mapobj_bit_11 = 1; sub_8059C3C(playerMapObj->mapobj_unk_18); task->tStep++; return 0; } u8 Fishing3(struct Task *task) { sub_805A954(); // Wait one second before starting dot game task->tFrameCounter++; if (task->tFrameCounter >= 60) task->tStep++; return 0; } u8 Fishing4(struct Task *task) { u32 randVal; MenuDisplayMessageBox(); task->tStep++; task->tFrameCounter = 0; task->tNumDots = 0; randVal = Random(); randVal %= 10; task->tDotsRequired = randVal + 1; if (task->tRoundsPlayed == 0) task->tDotsRequired = randVal + 4; if (task->tDotsRequired >= 10) task->tDotsRequired = 10; return 1; } // Play a round of the dot game u8 Fishing5(struct Task *task) { const u8 dot[] = _("ยท"); sub_805A954(); task->tFrameCounter++; if (gMain.newKeys & A_BUTTON) { task->tStep = FISHING_NO_BITE; if (task->tRoundsPlayed != 0) task->tStep = FISHING_GOT_AWAY; return 1; } else { if (task->tFrameCounter >= 20) { task->tFrameCounter = 0; if (task->tNumDots >= task->tDotsRequired) { task->tStep++; if (task->tRoundsPlayed != 0) task->tStep++; task->tRoundsPlayed++; } else { MenuPrint(dot, task->tNumDots + 4, 15); task->tNumDots++; } } return 0; } } // Determine if fish bites u8 Fishing6(struct Task *task) { sub_805A954(); task->tStep++; if (!DoesCurrentMapHaveFishingMons() || (Random() & 1)) task->tStep = FISHING_NO_BITE; else StartSpriteAnim(&gSprites[gPlayerAvatar.spriteId], sub_805FE08(player_get_direction_lower_nybble())); return 1; } // Oh! A Bite! u8 Fishing7(struct Task *task) { sub_805A954(); MenuPrint(gOtherText_OhABite, 4, 17); task->tStep++; task->tFrameCounter = 0; return 0; } // We have a bite. Now, wait for the player to press A, or the timer to expire. u8 Fishing8(struct Task *task) { const s16 reelTimeouts[3] = {36, 33, 30}; sub_805A954(); task->tFrameCounter++; if (task->tFrameCounter >= reelTimeouts[task->tFishingRod]) task->tStep = FISHING_GOT_AWAY; else if (gMain.newKeys & A_BUTTON) task->tStep++; return 0; } // Determine if we're going to play the dot game again u8 Fishing9(struct Task *task) { const s16 arr[][2] = { {0, 0}, {40, 10}, {70, 30} }; sub_805A954(); task->tStep++; if (task->tRoundsPlayed < task->tMinRoundsRequired) { task->tStep = FISHING_START_ROUND; } else if (task->tRoundsPlayed < 2) { // probability of having to play another round s16 probability = Random() % 100; if (arr[task->tFishingRod][task->tRoundsPlayed] > probability) task->tStep = FISHING_START_ROUND; } return 0; } u8 Fishing10(struct Task *task) { sub_805A954(); MenuPrintMessageDefaultCoords(gOtherText_PokeOnHook); MenuDisplayMessageBox(); task->tStep++; task->tFrameCounter = 0; return 0; } u8 Fishing11(struct Task *task) { if (task->tFrameCounter == 0) sub_805A954(); if (task->tFrameCounter == 0) { if (MenuUpdateWindowText()) { struct MapObject *playerMapObj = &gMapObjects[gPlayerAvatar.mapObjectId]; sub_805B980(playerMapObj, task->tPlayerGfxId); FieldObjectTurn(playerMapObj, playerMapObj->placeholder18); if (gPlayerAvatar.flags & PLAYER_AVATAR_FLAG_SURFING) sub_8127F28(gMapObjects[gPlayerAvatar.mapObjectId].mapobj_unk_1A, 0, 0); gSprites[gPlayerAvatar.spriteId].pos2.x = 0; gSprites[gPlayerAvatar.spriteId].pos2.y = 0; MenuZeroFillScreen(); task->tFrameCounter++; return 0; } } if (task->tFrameCounter != 0) { gPlayerAvatar.unk6 = 0; ScriptContext2_Disable(); FishingWildEncounter(task->tFishingRod); sub_80BE97C(1); DestroyTask(FindTaskIdByFunc(Task_Fishing)); } return 0; } // Not even a nibble u8 Fishing12(struct Task *task) { sub_805A954(); StartSpriteAnim(&gSprites[gPlayerAvatar.spriteId], sub_805FDF8(player_get_direction_lower_nybble())); MenuPrintMessageDefaultCoords(gOtherText_NotEvenANibble); task->tStep = FISHING_SHOW_RESULT; return 1; } // It got away u8 Fishing13(struct Task *task) { sub_805A954(); StartSpriteAnim(&gSprites[gPlayerAvatar.spriteId], sub_805FDF8(player_get_direction_lower_nybble())); MenuPrintMessageDefaultCoords(gOtherText_ItGotAway); task->tStep++; return 1; } // Display the message u8 Fishing14(struct Task *task) { sub_805A954(); MenuDisplayMessageBox(); task->tStep++; return 0; } u8 Fishing15(struct Task *task) { sub_805A954(); if (gSprites[gPlayerAvatar.spriteId].animEnded) { struct MapObject *playerMapObj = &gMapObjects[gPlayerAvatar.mapObjectId]; sub_805B980(playerMapObj, task->tPlayerGfxId); FieldObjectTurn(playerMapObj, playerMapObj->placeholder18); if (gPlayerAvatar.flags & PLAYER_AVATAR_FLAG_SURFING) sub_8127F28(gMapObjects[gPlayerAvatar.mapObjectId].mapobj_unk_1A, 0, 0); gSprites[gPlayerAvatar.spriteId].pos2.x = 0; gSprites[gPlayerAvatar.spriteId].pos2.y = 0; task->tStep++; } return 0; } u8 Fishing16(struct Task *task) { if (MenuUpdateWindowText()) { gPlayerAvatar.unk6 = 0; ScriptContext2_Disable(); UnfreezeMapObjects(); MenuZeroFillScreen(); sub_80BE97C(0); DestroyTask(FindTaskIdByFunc(Task_Fishing)); } return 0; } #undef tStep #undef tFrameCounter #undef tFishingRod static void sub_805A954(void) { struct Sprite *playerSprite = &gSprites[gPlayerAvatar.spriteId]; u8 animCmdIndex; u8 animType; AnimateSprite(playerSprite); playerSprite->pos2.x = 0; playerSprite->pos2.y = 0; animCmdIndex = playerSprite->animCmdIndex; if (playerSprite->anims[playerSprite->animNum][animCmdIndex].type == -1) { animCmdIndex--; } else { playerSprite->animDelayCounter++; if (playerSprite->anims[playerSprite->animNum][animCmdIndex].type == -1) animCmdIndex--; } animType = playerSprite->anims[playerSprite->animNum][animCmdIndex].type; if (animType == 1 || animType == 2 || animType == 3) { playerSprite->pos2.x = 8; if (player_get_direction_lower_nybble() == 3) playerSprite->pos2.x = -8; } if (animType == 5) playerSprite->pos2.y = -8; if (animType == 10 || animType == 11) playerSprite->pos2.y = 8; if (gPlayerAvatar.flags & PLAYER_AVATAR_FLAG_SURFING) sub_8127F28(gMapObjects[gPlayerAvatar.mapObjectId].mapobj_unk_1A, 1, playerSprite->pos2.y); }