summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGriffinR <griffin.g.richards@gmail.com>2021-10-09 14:18:05 -0400
committerGriffinR <griffin.g.richards@gmail.com>2021-10-09 15:23:59 -0400
commitb01213b8bc0e4f82a0ab7505b4fe7db2e2d0ddf2 (patch)
treeab52a03e8b4ad5d3d88da6e970c35b0d80641738 /src
parentff01eb951b89afe141cbe81a9c2524df17bd63d3 (diff)
Some constants in wild_encounter.c, document Feebas spot generation
Diffstat (limited to 'src')
-rw-r--r--src/wild_encounter.c137
1 files changed, 80 insertions, 57 deletions
diff --git a/src/wild_encounter.c b/src/wild_encounter.c
index 32316c119..5d7425762 100644
--- a/src/wild_encounter.c
+++ b/src/wild_encounter.c
@@ -25,9 +25,27 @@
extern const u8 EventScript_RepelWoreOff[];
-#define NUM_FEEBAS_SPOTS 6
+#define MAX_ENCOUNTER_RATE 2880
+
+#define NUM_FEEBAS_SPOTS 6
+
+// Number of accessible fishing spots in each section of Route 119
+// Each section is an area of the route between the y coordinates in sRoute119WaterTileData
+#define NUM_FISHING_SPOTS_1 131
+#define NUM_FISHING_SPOTS_2 167
+#define NUM_FISHING_SPOTS_3 149
+#define NUM_FISHING_SPOTS (NUM_FISHING_SPOTS_1 + NUM_FISHING_SPOTS_2 + NUM_FISHING_SPOTS_3)
+
+enum {
+ WILD_AREA_LAND,
+ WILD_AREA_WATER,
+ WILD_AREA_ROCKS,
+ WILD_AREA_FISHING,
+};
+
+#define WILD_CHECK_REPEL (1 << 0)
+#define WILD_CHECK_KEEN_EYE (1 << 1)
-// this file's functions
static u16 FeebasRandom(void);
static void FeebasSeedRng(u16 seed);
static bool8 IsWildLevelAllowedByRepel(u8 level);
@@ -36,60 +54,64 @@ static void ApplyCleanseTagEncounterRateMod(u32 *encRate);
static bool8 TryGetAbilityInfluencedWildMonIndex(const struct WildPokemon *wildMon, u8 type, u8 ability, u8 *monIndex);
static bool8 IsAbilityAllowingEncounter(u8 level);
-// EWRAM vars
EWRAM_DATA static u8 sWildEncountersDisabled = 0;
EWRAM_DATA static u32 sFeebasRngValue = 0;
#include "data/wild_encounters.h"
-//Special Feebas-related data.
-const struct WildPokemon gWildFeebasRoute119Data = {20, 25, SPECIES_FEEBAS};
+static const struct WildPokemon sWildFeebas = {20, 25, SPECIES_FEEBAS};
-const u16 gRoute119WaterTileData[] =
+static const u16 sRoute119WaterTileData[] =
{
- 0, 0x2D, 0,
- 0x2E, 0x5B, 0x83,
- 0x5C, 0x8B, 0x12A,
+//yMin, yMax, numSpots in previous sections
+ 0, 45, 0,
+ 46, 91, NUM_FISHING_SPOTS_1,
+ 92, 139, NUM_FISHING_SPOTS_1 + NUM_FISHING_SPOTS_2,
};
-// code
void DisableWildEncounters(bool8 disabled)
{
sWildEncountersDisabled = disabled;
}
-static u16 GetRoute119WaterTileNum(s16 x, s16 y, u8 section)
+// Each fishing spot on Route 119 is given a number between 1 and NUM_FISHING_SPOTS inclusive.
+// The number is determined by counting the valid fishing spots left to right top to bottom.
+// The map is divided into three sections, with each section having a pre-counted number of
+// fishing spots to start from to avoid counting a large number of spots at the bottom of the map.
+// Note that a spot is considered valid if it is surfable and not a waterfall. To exclude all
+// of the inaccessible water metatiles (so that they can't be selected as a Feebas spot) they
+// use a different metatile that isn't actually surfable because it has MB_NORMAL instead.
+// This function is given the coordinates and section of a fishing spot and returns which number it is.
+static u16 GetFeebasFishingSpotId(s16 targetX, s16 targetY, u8 section)
{
- u16 xCur;
- u16 yCur;
- u16 yMin = gRoute119WaterTileData[section * 3 + 0];
- u16 yMax = gRoute119WaterTileData[section * 3 + 1];
- u16 tileNum = gRoute119WaterTileData[section * 3 + 2];
+ u16 x, y;
+ u16 yMin = sRoute119WaterTileData[section * 3 + 0];
+ u16 yMax = sRoute119WaterTileData[section * 3 + 1];
+ u16 spotId = sRoute119WaterTileData[section * 3 + 2];
- for (yCur = yMin; yCur <= yMax; yCur++)
+ for (y = yMin; y <= yMax; y++)
{
- for (xCur = 0; xCur < gMapHeader.mapLayout->width; xCur++)
+ for (x = 0; x < gMapHeader.mapLayout->width; x++)
{
- u8 tileBehaviorId = MapGridGetMetatileBehaviorAt(xCur + MAP_OFFSET, yCur + MAP_OFFSET);
- if (MetatileBehavior_IsSurfableAndNotWaterfall(tileBehaviorId) == TRUE)
+ u8 behavior = MapGridGetMetatileBehaviorAt(x + MAP_OFFSET, y + MAP_OFFSET);
+ if (MetatileBehavior_IsSurfableAndNotWaterfall(behavior) == TRUE)
{
- tileNum++;
- if (x == xCur && y == yCur)
- return tileNum;
+ spotId++;
+ if (targetX == x && targetY == y)
+ return spotId;
}
}
}
- return tileNum + 1;
+ return spotId + 1;
}
static bool8 CheckFeebas(void)
{
u8 i;
u16 feebasSpots[NUM_FEEBAS_SPOTS];
- s16 x;
- s16 y;
+ s16 x, y;
u8 route119Section = 0;
- u16 waterTileNum;
+ u16 spotId;
if (gSaveBlock1Ptr->location.mapGroup == MAP_GROUP(ROUTE119)
&& gSaveBlock1Ptr->location.mapNum == MAP_NUM(ROUTE119))
@@ -98,29 +120,42 @@ static bool8 CheckFeebas(void)
x -= MAP_OFFSET;
y -= MAP_OFFSET;
- if (y >= gRoute119WaterTileData[3 * 0 + 0] && y <= gRoute119WaterTileData[3 * 0 + 1])
+ // Get which third of the map the player is in
+ if (y >= sRoute119WaterTileData[3 * 0 + 0] && y <= sRoute119WaterTileData[3 * 0 + 1])
route119Section = 0;
- if (y >= gRoute119WaterTileData[3 * 1 + 0] && y <= gRoute119WaterTileData[3 * 1 + 1])
+ if (y >= sRoute119WaterTileData[3 * 1 + 0] && y <= sRoute119WaterTileData[3 * 1 + 1])
route119Section = 1;
- if (y >= gRoute119WaterTileData[3 * 2 + 0] && y <= gRoute119WaterTileData[3 * 2 + 1])
+ if (y >= sRoute119WaterTileData[3 * 2 + 0] && y <= sRoute119WaterTileData[3 * 2 + 1])
route119Section = 2;
- if (Random() % 100 > 49) // 50% chance of encountering Feebas
+ // 50% chance of encountering Feebas (assuming this is a Feebas spot)
+ if (Random() % 100 > 49)
return FALSE;
FeebasSeedRng(gSaveBlock1Ptr->dewfordTrends[0].rand);
+
+ // Assign each Feebas spot to a random fishing spot.
+ // Randomness is fixed depending on the seed above.
for (i = 0; i != NUM_FEEBAS_SPOTS;)
{
- feebasSpots[i] = FeebasRandom() % 447;
+ feebasSpots[i] = FeebasRandom() % NUM_FISHING_SPOTS;
if (feebasSpots[i] == 0)
- feebasSpots[i] = 447;
+ feebasSpots[i] = NUM_FISHING_SPOTS;
+
+ // < 1 below is a pointless check, it will never be TRUE.
+ // >= 4 to skip fishing spots 1-3, because these are inaccessible
+ // spots at the top of the map, at (9,7), (7,13), and (15,16).
+ // The first accessible fishing spot is spot 4 at (18,18).
if (feebasSpots[i] < 1 || feebasSpots[i] >= 4)
i++;
}
- waterTileNum = GetRoute119WaterTileNum(x, y, route119Section);
+
+ // Check which fishing spot the player is at, and see if
+ // it matches any of the Feebas spots.
+ spotId = GetFeebasFishingSpotId(x, y, route119Section);
for (i = 0; i < NUM_FEEBAS_SPOTS; i++)
{
- if (waterTileNum == feebasSpots[i])
+ if (spotId == feebasSpots[i])
return TRUE;
}
}
@@ -256,7 +291,6 @@ static u8 ChooseWildMonLevel(const struct WildPokemon *wildPokemon)
rand--;
}
}
-
return min + rand;
}
@@ -365,24 +399,13 @@ static void CreateWildMon(u16 species, u8 level)
else
gender = MON_FEMALE;
- CreateMonWithGenderNatureLetter(&gEnemyParty[0], species, level, 32, gender, PickWildMonNature(), 0);
+ CreateMonWithGenderNatureLetter(&gEnemyParty[0], species, level, USE_RANDOM_IVS, gender, PickWildMonNature(), 0);
return;
}
- CreateMonWithNature(&gEnemyParty[0], species, level, 32, PickWildMonNature());
+ CreateMonWithNature(&gEnemyParty[0], species, level, USE_RANDOM_IVS, PickWildMonNature());
}
-enum
-{
- WILD_AREA_LAND,
- WILD_AREA_WATER,
- WILD_AREA_ROCKS,
- WILD_AREA_FISHING,
-};
-
-#define WILD_CHECK_REPEL 0x1
-#define WILD_CHECK_KEEN_EYE 0x2
-
static bool8 TryGenerateWildMon(const struct WildPokemonInfo *wildMonInfo, u8 area, u8 flags)
{
u8 wildMonIndex = 0;
@@ -436,7 +459,7 @@ static bool8 SetUpMassOutbreakEncounter(u8 flags)
return FALSE;
CreateWildMon(gSaveBlock1Ptr->outbreakPokemonSpecies, gSaveBlock1Ptr->outbreakPokemonLevel);
- for (i = 0; i < 4; i++)
+ for (i = 0; i < MAX_MON_MOVES; i++)
SetMonMoveSlot(&gEnemyParty[0], gSaveBlock1Ptr->outbreakPokemonMoves[i], i);
return TRUE;
@@ -444,7 +467,7 @@ static bool8 SetUpMassOutbreakEncounter(u8 flags)
static bool8 DoMassOutbreakEncounterTest(void)
{
- if (gSaveBlock1Ptr->outbreakPokemonSpecies != 0
+ if (gSaveBlock1Ptr->outbreakPokemonSpecies != SPECIES_NONE
&& gSaveBlock1Ptr->location.mapNum == gSaveBlock1Ptr->outbreakLocationMapNum
&& gSaveBlock1Ptr->location.mapGroup == gSaveBlock1Ptr->outbreakLocationMapGroup)
{
@@ -456,7 +479,7 @@ static bool8 DoMassOutbreakEncounterTest(void)
static bool8 DoWildEncounterRateDiceRoll(u16 encounterRate)
{
- if (Random() % 2880 < encounterRate)
+ if (Random() % MAX_ENCOUNTER_RATE < encounterRate)
return TRUE;
else
return FALSE;
@@ -486,8 +509,8 @@ static bool8 DoWildEncounterRateTest(u32 encounterRate, bool8 ignoreAbility)
else if (ability == ABILITY_SAND_VEIL && gSaveBlock1Ptr->weather == WEATHER_SANDSTORM)
encounterRate /= 2;
}
- if (encounterRate > 2880)
- encounterRate = 2880;
+ if (encounterRate > MAX_ENCOUNTER_RATE)
+ encounterRate = MAX_ENCOUNTER_RATE;
return DoWildEncounterRateDiceRoll(encounterRate);
}
@@ -639,7 +662,7 @@ void RockSmashWildEncounter(void)
gSpecialVar_Result = FALSE;
}
else if (DoWildEncounterRateTest(wildPokemonInfo->encounterRate, 1) == TRUE
- && TryGenerateWildMon(wildPokemonInfo, 2, WILD_CHECK_REPEL | WILD_CHECK_KEEN_EYE) == TRUE)
+ && TryGenerateWildMon(wildPokemonInfo, WILD_AREA_ROCKS, WILD_CHECK_REPEL | WILD_CHECK_KEEN_EYE) == TRUE)
{
BattleSetup_StartWildBattle();
gSpecialVar_Result = TRUE;
@@ -744,9 +767,9 @@ void FishingWildEncounter(u8 rod)
if (CheckFeebas() == TRUE)
{
- u8 level = ChooseWildMonLevel(&gWildFeebasRoute119Data);
+ u8 level = ChooseWildMonLevel(&sWildFeebas);
- species = gWildFeebasRoute119Data.species;
+ species = sWildFeebas.species;
CreateWildMon(species, level);
}
else