Some constants in wild_encounter.c, document Feebas spot generation
This commit is contained in:
parent
ff01eb951b
commit
b01213b8bc
1 changed files with 80 additions and 57 deletions
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue