Fishing Enhancements (#4343)

* Implemented chain fishing

* Added configs

* I_FISHING_MINIGAME implemented

* Refactored Check For Bite

* CLeaned up version of metatile checks

* Removed debug script

* Added helper functinons

* Cleaned up CalculateFishingProximityOdds

* Added new constatnts for cardinal direction and axis

* Updated with constants

* Reordered functions

* Cleaned up some functions

* Moved constants

* Created UpdateChainFishingSpeciesAndStreak
When 3 sides are blocked, every cast will get a mon

* Created DoesFishingMinigameAllowCancel

* Removed fishing chain check

* Fixed bug where streak was not incremented correctly
Fixed bug where Land was not properly counted
Fixed bug where streak was always being read as maxed

* Updated variable and function names

* Updated variable and function names

* Moved UpdateChainFishingSpeciesAndStreak to happen before shiny rolls occur

* Removed debug statements

* Applied feedback from https://github.com/rh-hideout/pokeemerald-expansion/pull/4343\#discussion_r1551278416

* Fixed default item config and changed gChainFishingDexNavStreak and sLastFishingSpecies to only use EWRAM when features are enabled

* Update include/config/item.h

Include feedback from https://github.com/rh-hideout/pokeemerald-expansion/pull/4343#discussion_r1567145660

Co-authored-by: Bassoonian <iasperbassoonian@gmail.com>

* Changed Dexnav to DexNav per https://github.com/rh-hideout/pokeemerald-expansion/pull/4343\#discussion_r1567145660

---------

Co-authored-by: Bassoonian <iasperbassoonian@gmail.com>
This commit is contained in:
psf 2024-04-16 13:53:50 -07:00 committed by GitHub
parent 0d95354a82
commit fcf90ab52d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 377 additions and 48 deletions

View File

@ -36,4 +36,9 @@
// 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.
//Fishing
#define I_FISHING_CHAIN FALSE // Introduced in XY, hooking the same Pokémon repeatedly will increase the odds of that mon being shiny. NOTE: This implementation is an approximation of the actual feature, as XY have not been throughoutly documented or datamined.
#define I_FISHING_MINIGAME GEN_3 // Each generation uses a variation of reeling in Pokémon once they have been hooked.
#define I_FISHING_PROXIMITY FALSE // Introduced in XY, fishing away from other people in enclosed areas will increase the chances of a Pokémon being hooked. NOTE: This implementation is an approximation of the actual feature, as XY have not been throughoutly documented or datamined.
#endif // GUARD_CONFIG_ITEM_H

View File

@ -155,6 +155,11 @@
#define DIR_SOUTHEAST 6
#define DIR_NORTHWEST 7
#define DIR_NORTHEAST 8
#define CARDINAL_DIRECTION_COUNT DIR_SOUTHWEST
#define AXIS_X 0
#define AXIS_Y 1
#define AXIS_COUNT 2
#define CONNECTION_INVALID -1
#define CONNECTION_NONE 0

View File

@ -8,4 +8,6 @@
#define NUM_ALTERING_CAVE_TABLES 9
#define FISHING_CHAIN_LENGTH_MAX 20
#endif // GUARD_CONSTANTS_WILD_ENCOUNTER_H

View File

@ -29,6 +29,7 @@ struct WildPokemonHeader
extern const struct WildPokemonHeader gWildMonHeaders[];
extern bool8 gIsFishingEncounter;
extern bool8 gIsSurfingEncounter;
extern u8 gChainFishingDexNavStreak;
void DisableWildEncounters(bool8 disabled);
u8 PickWildMonNature(void);
@ -41,5 +42,8 @@ u16 GetLocalWaterMon(void);
bool8 UpdateRepelCounter(void);
bool8 TryDoDoubleWildBattle(void);
bool8 StandardWildEncounter_Debug(void);
void ResetChainFishingDexNavStreak(void);
bool32 IsCurrentEncounterFishing(void);
u32 CalculateChainFishingShinyRolls(void);
#endif // GUARD_WILD_ENCOUNTER_H

View File

@ -129,7 +129,9 @@ static u8 Fishing_InitDots(struct Task *);
static u8 Fishing_ShowDots(struct Task *);
static u8 Fishing_CheckForBite(struct Task *);
static u8 Fishing_GotBite(struct Task *);
static u8 Fishing_ChangeMinigame(struct Task *);
static u8 Fishing_WaitForA(struct Task *);
static u8 Fishing_APressNoMinigame(struct Task *);
static u8 Fishing_CheckMoreDots(struct Task *);
static u8 Fishing_MonOnHook(struct Task *);
static u8 Fishing_StartEncounter(struct Task *);
@ -139,6 +141,18 @@ static u8 Fishing_NoMon(struct Task *);
static u8 Fishing_PutRodAway(struct Task *);
static u8 Fishing_EndNoMon(struct Task *);
static void AlignFishingAnimationFrames(void);
static bool32 DoesFishingMinigameAllowCancel(void);
static bool32 Fishing_DoesFirstMonInPartyHaveSuctionCupsOrStickyHold(void);
static bool32 Fishing_RollForBite(bool32);
static u32 CalculateFishingBiteOdds(bool32);
static u32 CalculateFishingProximityBoost(u32 odds);
static void GetCoordinatesAroundBobber(s16[], s16[][AXIS_COUNT], u32);
static u32 CountQualifyingTiles(s16[][AXIS_COUNT], s16 player[], u8 facingDirection, struct ObjectEvent *objectEvent, bool32 isTileLand[]);
static bool32 CheckTileQualification(s16 tile[], s16 player[], u32 facingDirection, struct ObjectEvent* objectEvent, bool32 isTileLand[], u32 direction);
static u32 CountLandTiles(bool32 isTileLand[]);
static bool32 IsPlayerHere(s16, s16, s16, s16);
static bool32 IsMetatileBlocking(s16, s16, u32);
static bool32 IsMetatileLand(s16, s16, u32);
static u8 TrySpinPlayerForWarp(struct ObjectEvent *, s16 *);
@ -1682,32 +1696,52 @@ static void Task_WaitStopSurfing(u8 taskId)
#define tPlayerGfxId data[14]
#define tFishingRod data[15]
// Some states are jumped to directly, labeled below
#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
#define FISHING_PROXIMITY_BOOST 4
#define FISHING_STICKY_BOOST 36
#define FISHING_DEFAULT_ODDS 50
enum
{
FISHING_INIT,
FISHING_GET_ROD_OUT,
FISHING_WAIT_BEFORE_DOTS,
FISHING_START_ROUND,
FISHING_SHOW_DOTS,
FISHING_CHECK_FOR_BITE,
FISHING_GOT_BITE,
FISHING_CHANGE_MINIGAME,
FISHING_WAIT_FOR_A,
FISHING_A_PRESS_NO_MINIGAME,
FISHING_CHECK_MORE_DOTS,
FISHING_ON_HOOK,
FISHING_START_ENCOUNTER,
FISHING_NO_BITE,
FISHING_GOT_AWAY,
FISHING_SHOW_RESULT,
FISHING_PUT_ROD_AWAY,
FISHING_END_NO_MON,
};
static bool8 (*const sFishingStateFuncs[])(struct Task *) =
{
Fishing_Init,
Fishing_GetRodOut,
Fishing_WaitBeforeDots,
Fishing_InitDots, // FISHING_START_ROUND
Fishing_ShowDots,
Fishing_CheckForBite,
Fishing_GotBite, // FISHING_GOT_BITE
Fishing_WaitForA,
Fishing_CheckMoreDots,
Fishing_MonOnHook, // FISHING_ON_HOOK
Fishing_StartEncounter,
Fishing_NotEvenNibble, // FISHING_NO_BITE
Fishing_GotAway, // FISHING_GOT_AWAY
Fishing_NoMon, // FISHING_SHOW_RESULT
Fishing_PutRodAway,
Fishing_EndNoMon,
Fishing_Init, // FISHING_INIT,
Fishing_GetRodOut, // FISHING_GET_ROD_OUT,
Fishing_WaitBeforeDots, // FISHING_WAIT_BEFORE_DOTS,
Fishing_InitDots, // FISHING_START_ROUND,
Fishing_ShowDots, // FISHING_SHOW_DOTS,
Fishing_CheckForBite, // FISHING_CHECK_FOR_BITE,
Fishing_GotBite, // FISHING_GOT_BITE,
Fishing_ChangeMinigame, // FISHING_CHANGE_MINIGAME,
Fishing_WaitForA, // FISHING_WAIT_FOR_A,
Fishing_APressNoMinigame, // FISHING_A_PRESS_NO_MINIGAME,
Fishing_CheckMoreDots, // FISHING_CHECK_MORE_DOTS,
Fishing_MonOnHook, // FISHING_ON_HOOK,
Fishing_StartEncounter, // FISHING_START_ENCOUNTER,
Fishing_NotEvenNibble, // FISHING_NO_BITE,
Fishing_GotAway, // FISHING_GOT_AWAY,
Fishing_NoMon, // FISHING_SHOW_RESULT,
Fishing_PutRodAway, // FISHING_PUT_ROD_AWAY,
Fishing_EndNoMon, // FISHING_END_NO_MON,
};
void StartFishing(u8 rod)
@ -1794,6 +1828,9 @@ static bool8 Fishing_ShowDots(struct Task *task)
task->tFrameCounter++;
if (JOY_NEW(A_BUTTON))
{
if (!DoesFishingMinigameAllowCancel())
return FALSE;
task->tStep = FISHING_NO_BITE;
if (task->tRoundsPlayed != 0)
task->tStep = FISHING_GOT_AWAY;
@ -1823,7 +1860,7 @@ static bool8 Fishing_ShowDots(struct Task *task)
static bool8 Fishing_CheckForBite(struct Task *task)
{
bool8 bite;
bool32 bite, firstMonHasSuctionOrSticky;
AlignFishingAnimationFrames();
task->tStep++;
@ -1832,30 +1869,23 @@ static bool8 Fishing_CheckForBite(struct Task *task)
if (!DoesCurrentMapHaveFishingMons())
{
task->tStep = FISHING_NO_BITE;
return TRUE;
}
else
{
if (!GetMonData(&gPlayerParty[0], MON_DATA_SANITY_IS_EGG))
{
u16 ability = GetMonAbility(&gPlayerParty[0]);
if (ability == ABILITY_SUCTION_CUPS || ability == ABILITY_STICKY_HOLD)
{
if (Random() % 100 > 14)
bite = TRUE;
}
}
if (!bite)
{
if (Random() & 1)
task->tStep = FISHING_NO_BITE;
else
bite = TRUE;
}
firstMonHasSuctionOrSticky = Fishing_DoesFirstMonInPartyHaveSuctionCupsOrStickyHold();
if(firstMonHasSuctionOrSticky)
bite = Fishing_RollForBite(firstMonHasSuctionOrSticky);
if (!bite)
bite = Fishing_RollForBite(FALSE);
if (!bite)
task->tStep = FISHING_NO_BITE;
if (bite)
StartSpriteAnim(&gSprites[gPlayerAvatar.spriteId], GetFishingBiteDirectionAnimNum(GetPlayerFacingDirection()));
if (bite == TRUE)
StartSpriteAnim(&gSprites[gPlayerAvatar.spriteId], GetFishingBiteDirectionAnimNum(GetPlayerFacingDirection()));
}
return TRUE;
}
@ -1868,6 +1898,22 @@ static bool8 Fishing_GotBite(struct Task *task)
return FALSE;
}
static u8 Fishing_ChangeMinigame(struct Task *task)
{
switch (I_FISHING_MINIGAME)
{
case GEN_1:
case GEN_2:
task->tStep = FISHING_A_PRESS_NO_MINIGAME;
break;
case GEN_3:
default:
task->tStep = FISHING_WAIT_FOR_A;
break;
}
return TRUE;
}
// We have a bite. Now, wait for the player to press A, or the timer to expire.
static bool8 Fishing_WaitForA(struct Task *task)
{
@ -1886,6 +1932,14 @@ static bool8 Fishing_WaitForA(struct Task *task)
return FALSE;
}
static bool8 Fishing_APressNoMinigame(struct Task *task)
{
AlignFishingAnimationFrames();
if (JOY_NEW(A_BUTTON))
task->tStep = FISHING_ON_HOOK;
return FALSE;
}
// Determine if we're going to play the dot game again
static bool8 Fishing_CheckMoreDots(struct Task *task)
{
@ -1961,6 +2015,7 @@ static bool8 Fishing_StartEncounter(struct Task *task)
static bool8 Fishing_NotEvenNibble(struct Task *task)
{
ResetChainFishingDexNavStreak();
AlignFishingAnimationFrames();
StartSpriteAnim(&gSprites[gPlayerAvatar.spriteId], GetFishingNoCatchDirectionAnimNum(GetPlayerFacingDirection()));
FillWindowPixelBuffer(0, PIXEL_FILL(1));
@ -1971,6 +2026,7 @@ static bool8 Fishing_NotEvenNibble(struct Task *task)
static bool8 Fishing_GotAway(struct Task *task)
{
ResetChainFishingDexNavStreak();
AlignFishingAnimationFrames();
StartSpriteAnim(&gSprites[gPlayerAvatar.spriteId], GetFishingNoCatchDirectionAnimNum(GetPlayerFacingDirection()));
FillWindowPixelBuffer(0, PIXEL_FILL(1));
@ -2019,6 +2075,168 @@ static bool8 Fishing_EndNoMon(struct Task *task)
return FALSE;
}
static bool32 DoesFishingMinigameAllowCancel(void)
{
switch(I_FISHING_MINIGAME)
{
case GEN_1:
case GEN_2:
return FALSE;
case GEN_3:
default:
return TRUE;
}
}
static bool32 Fishing_DoesFirstMonInPartyHaveSuctionCupsOrStickyHold(void)
{
u32 ability;
if (GetMonData(&gPlayerParty[0], MON_DATA_SANITY_IS_EGG))
return FALSE;
ability = GetMonAbility(&gPlayerParty[0]);
return (ability == ABILITY_SUCTION_CUPS || ability == ABILITY_STICKY_HOLD);
}
static bool32 Fishing_RollForBite(bool32 isStickyHold)
{
return ((Random() % 100) > CalculateFishingBiteOdds(isStickyHold));
}
static u32 CalculateFishingBiteOdds(bool32 isStickyHold)
{
u32 odds = FISHING_DEFAULT_ODDS;
if (isStickyHold)
odds -= FISHING_STICKY_BOOST;
odds -= CalculateFishingProximityBoost(odds);
return odds;
}
static u32 CalculateFishingProximityBoost(u32 odds)
{
s16 player[AXIS_COUNT], bobber[AXIS_COUNT];
s16 surroundingTile[CARDINAL_DIRECTION_COUNT][AXIS_COUNT] = {{0, 0}};
bool32 isTileLand[CARDINAL_DIRECTION_COUNT] = {FALSE};
u32 facingDirection, numQualifyingTile = 0;
struct ObjectEvent *objectEvent;
if (!I_FISHING_PROXIMITY)
return 0;
objectEvent = &gObjectEvents[gPlayerAvatar.objectEventId];
player[AXIS_X] = objectEvent->currentCoords.x;
player[AXIS_Y] = objectEvent->currentCoords.y;
bobber[AXIS_X] = objectEvent->currentCoords.x;
bobber[AXIS_Y] = objectEvent->currentCoords.y;
facingDirection = GetPlayerFacingDirection();
MoveCoords(facingDirection, &bobber[AXIS_X], &bobber[AXIS_Y]);
GetCoordinatesAroundBobber(bobber, surroundingTile, facingDirection);
numQualifyingTile = CountQualifyingTiles(surroundingTile, player, facingDirection, objectEvent, isTileLand);
numQualifyingTile += CountLandTiles(isTileLand);
return (numQualifyingTile == 3) ? odds : (numQualifyingTile * FISHING_PROXIMITY_BOOST);
}
static void GetCoordinatesAroundBobber(s16 bobber[], s16 surroundingTile[][AXIS_COUNT], u32 facingDirection)
{
u32 direction;
for (direction = DIR_SOUTH; direction < CARDINAL_DIRECTION_COUNT; direction++)
{
surroundingTile[direction][AXIS_X] = bobber[AXIS_X];
surroundingTile[direction][AXIS_Y] = bobber[AXIS_Y];
MoveCoords(direction, &surroundingTile[direction][AXIS_X], &surroundingTile[direction][AXIS_Y]);
}
}
static u32 CountQualifyingTiles(s16 surroundingTile[][AXIS_COUNT], s16 player[], u8 facingDirection, struct ObjectEvent *objectEvent, bool32 isTileLand[])
{
u32 numQualifyingTile = 0;
s16 tile[AXIS_COUNT];
u8 direction = DIR_SOUTH;
for (direction = DIR_SOUTH; direction < CARDINAL_DIRECTION_COUNT; direction++)
{
tile[AXIS_X] = surroundingTile[direction][AXIS_X];
tile[AXIS_Y] = surroundingTile[direction][AXIS_Y];
if (!CheckTileQualification(tile, player, facingDirection, objectEvent, isTileLand, direction))
continue;
numQualifyingTile++;
}
return numQualifyingTile;
}
static bool32 CheckTileQualification(s16 tile[], s16 player[], u32 facingDirection, struct ObjectEvent* objectEvent, bool32 isTileLand[], u32 direction)
{
u32 collison = GetCollisionAtCoords(objectEvent, tile[AXIS_X], tile[AXIS_Y], facingDirection);
if (IsPlayerHere(tile[AXIS_X], tile[AXIS_Y], player[AXIS_X], player[AXIS_Y]))
return FALSE;
else if (IsMetatileBlocking(tile[AXIS_X], tile[AXIS_Y], collison))
return TRUE;
else if (MetatileBehavior_IsSurfableFishableWater(MapGridGetMetatileBehaviorAt(tile[AXIS_X], tile[AXIS_Y])))
return FALSE;
else if (IsMetatileLand(tile[AXIS_X], tile[AXIS_Y], collison))
isTileLand[direction] = TRUE;
return FALSE;
}
static u32 CountLandTiles(bool32 isTileLand[])
{
u32 direction, numQualifyingTile = 0;
for (direction = DIR_SOUTH; direction < CARDINAL_DIRECTION_COUNT; direction++)
if (isTileLand[direction])
numQualifyingTile++;
return (numQualifyingTile < 2) ? 0 : numQualifyingTile;
}
static bool32 IsPlayerHere(s16 x, s16 y, s16 playerX, s16 playerY)
{
return ((x == playerX) && (y == playerY));
}
static bool32 IsMetatileBlocking(s16 x, s16 y, u32 collison)
{
switch(collison)
{
case COLLISION_NONE:
case COLLISION_STOP_SURFING:
case COLLISION_ELEVATION_MISMATCH:
return FALSE;
default:
return TRUE;
case COLLISION_OBJECT_EVENT:
return (gObjectEvents[GetObjectEventIdByXY(x,y)].inanimate);
}
return TRUE;
}
static bool32 IsMetatileLand(s16 x, s16 y, u32 collison)
{
switch(collison)
{
case COLLISION_NONE:
case COLLISION_STOP_SURFING:
case COLLISION_ELEVATION_MISMATCH:
return TRUE;
default:
return FALSE;
}
}
#undef tStep
#undef tFrameCounter
#undef tFishingRod

View File

@ -16,6 +16,7 @@
#include "tv.h"
#include "constants/rgb.h"
#include "constants/metatile_behaviors.h"
#include "wild_encounter.h"
struct ConnectionFlags
{
@ -66,6 +67,7 @@ const struct MapHeader *const GetMapHeaderFromConnection(const struct MapConnect
void InitMap(void)
{
ResetChainFishingDexNavStreak();
InitMapLayoutData(&gMapHeader);
SetOccupiedSecretBaseEntranceMetatiles(gMapHeader.events);
RunOnLoadMapScript();

View File

@ -56,6 +56,7 @@
#include "constants/trainers.h"
#include "constants/union_room.h"
#include "constants/weather.h"
#include "wild_encounter.h"
#define FRIENDSHIP_EVO_THRESHOLD ((P_FRIENDSHIP_EVO_THRESHOLD >= GEN_9) ? 160 : 220)
@ -891,6 +892,8 @@ void CreateBoxMon(struct BoxPokemon *boxMon, u16 species, u8 level, u8 fixedIV,
totalRerolls += I_SHINY_CHARM_ADDITIONAL_ROLLS;
if (LURE_STEP_COUNT != 0)
totalRerolls += 1;
if (IsCurrentEncounterFishing())
totalRerolls += CalculateChainFishingShinyRolls();
while (GET_SHINY_VALUE(value, personality) >= SHINY_ODDS && totalRerolls > 0)
{

View File

@ -51,6 +51,15 @@ enum {
static u16 FeebasRandom(void);
static void FeebasSeedRng(u16 seed);
static u32 GetLastFishingSpecies(void);
static bool32 DoesSpeciesMatchLastFishingSpecies(u32 species);
static u32 GetCurrentChainFishingDexNavStreak(void);
static bool32 IsChainFishingStreakAtMax(void);
static void IncrementChainFishingDexNavStreak(void);
static void SetEncounterFishing(void);
static void SetLastFishingSpecies(u32 species);
static void HandleChainFishingStreak(u32 species);
static void UpdateChainFishingSpeciesAndStreak(u32 species);
static bool8 IsWildLevelAllowedByRepel(u8 level);
static void ApplyFluteEncounterRateMod(u32 *encRate);
static void ApplyCleanseTagEncounterRateMod(u32 *encRate);
@ -67,6 +76,11 @@ EWRAM_DATA static u32 sFeebasRngValue = 0;
EWRAM_DATA bool8 gIsFishingEncounter = 0;
EWRAM_DATA bool8 gIsSurfingEncounter = 0;
#ifdef I_FISHING_CHAIN
EWRAM_DATA u8 gChainFishingDexNavStreak = 0;
EWRAM_DATA static u16 sLastFishingSpecies = 0;
#endif
#include "data/wild_encounters.h"
static const struct WildPokemon sWildFeebas = {20, 25, SPECIES_FEEBAS};
@ -514,10 +528,12 @@ static bool8 TryGenerateWildMon(const struct WildPokemonInfo *wildMonInfo, u8 ar
static u16 GenerateFishingWildMon(const struct WildPokemonInfo *wildMonInfo, u8 rod)
{
u8 wildMonIndex = ChooseWildMonIndex_Fishing(rod);
u8 wildMonSpecies = wildMonInfo->wildPokemon[wildMonIndex].species;
u8 level = ChooseWildMonLevel(wildMonInfo->wildPokemon, wildMonIndex, WILD_AREA_FISHING);
CreateWildMon(wildMonInfo->wildPokemon[wildMonIndex].species, level);
return wildMonInfo->wildPokemon[wildMonIndex].species;
UpdateChainFishingSpeciesAndStreak(wildMonSpecies);
CreateWildMon(wildMonSpecies, level);
return wildMonSpecies;
}
static bool8 SetUpMassOutbreakEncounter(u8 flags)
@ -864,10 +880,84 @@ bool8 DoesCurrentMapHaveFishingMons(void)
return FALSE;
}
static u32 GetLastFishingSpecies(void)
{
return sLastFishingSpecies;
}
static bool32 DoesSpeciesMatchLastFishingSpecies(u32 species)
{
return (species == GetLastFishingSpecies());
}
static u32 GetCurrentChainFishingDexNavStreak(void)
{
return gChainFishingDexNavStreak;
}
static bool32 IsChainFishingStreakAtMax(void)
{
return (GetCurrentChainFishingDexNavStreak() >= FISHING_CHAIN_LENGTH_MAX);
}
static void IncrementChainFishingDexNavStreak(void)
{
gChainFishingDexNavStreak++;
}
void ResetChainFishingDexNavStreak(void)
{
gChainFishingDexNavStreak = 0;
}
bool32 IsCurrentEncounterFishing(void)
{
return gIsFishingEncounter;
}
static void SetEncounterFishing(void)
{
gIsFishingEncounter = TRUE;
}
u32 CalculateChainFishingShinyRolls(void)
{
return (1 + (2 * GetCurrentChainFishingDexNavStreak()));
}
static void SetLastFishingSpecies(u32 species)
{
sLastFishingSpecies = species;
}
static void HandleChainFishingStreak(u32 species)
{
if (!DoesSpeciesMatchLastFishingSpecies(species))
{
ResetChainFishingDexNavStreak();
return;
}
if (IsChainFishingStreakAtMax())
return;
IncrementChainFishingDexNavStreak();
}
static void UpdateChainFishingSpeciesAndStreak(u32 species)
{
if (!I_FISHING_CHAIN)
return;
HandleChainFishingStreak(species);
SetLastFishingSpecies(species);
}
void FishingWildEncounter(u8 rod)
{
u16 species;
SetEncounterFishing();
if (CheckFeebas() == TRUE)
{
u8 level = ChooseWildMonLevel(&sWildFeebas, 0, WILD_AREA_FISHING);
@ -879,9 +969,9 @@ void FishingWildEncounter(u8 rod)
{
species = GenerateFishingWildMon(gWildMonHeaders[GetCurrentMapWildMonHeaderId()].fishingMonsInfo, rod);
}
IncrementGameStat(GAME_STAT_FISHING_ENCOUNTERS);
SetPokemonAnglerSpecies(species);
gIsFishingEncounter = TRUE;
BattleSetup_StartWildBattle();
}