wild encounter file is decompiled

This commit is contained in:
DizzyEggg 2017-11-17 22:28:55 +01:00
parent a2a17bba92
commit 6b075ae0ff
10 changed files with 221 additions and 531 deletions

View File

@ -1246,7 +1246,7 @@ sub_809C8DC: @ 809C8DC
lsrs r0, 24
cmp r0, 0x1
beq _0809C92E
bl sub_80B5870
bl UpdateRepelCounter
lsls r0, 24
lsrs r0, 24
cmp r0, 0x1

View File

@ -4640,7 +4640,7 @@ _0808CD58:
ldrh r0, [r5, 0x26]
lsls r0, 24
lsrs r0, 24
bl sub_80B5734
bl FishingWildEncounter
movs r0, 0x1
bl sub_80ED950
ldr r0, =Task_Fish

View File

@ -2675,12 +2675,12 @@ sub_8085B2C: @ 8085B2C
ldr r1, =gUnknown_02032306
movs r0, 0x1
strb r0, [r1]
bl sub_80B582C
bl GetLocalWaterMon
b _08085B62
.pool
_08085B5C:
ldr r0, =gUnknown_02032306
bl wild_pokemon_rand_for_map
bl GetLocalWildMon
_08085B62:
ldr r1, =gUnknown_02032304
strh r0, [r1]

View File

@ -6,512 +6,4 @@
.text
thumb_func_start sub_80B5734
sub_80B5734: @ 80B5734
push {r4,r5,lr}
lsls r0, 24
lsrs r5, r0, 24
bl CheckFeebas
lsls r0, 24
lsrs r0, 24
cmp r0, 0x1
bne _080B5764
ldr r4, =gUnknown_08553A78
adds r0, r4, 0
bl ChooseWildMonLevel
adds r1, r0, 0
lsls r1, 24
lsrs r1, 24
ldrh r4, [r4, 0x2]
adds r0, r4, 0
bl CreateWildMon
b _080B5784
.pool
_080B5764:
ldr r4, =gWildMonHeaders
bl GetCurrentMapWildMonHeaderId
lsls r0, 16
lsrs r0, 16
lsls r1, r0, 2
adds r1, r0
lsls r1, 2
adds r4, 0x10
adds r1, r4
ldr r0, [r1]
adds r1, r5, 0
bl GenerateFishingWildMon
lsls r0, 16
lsrs r4, r0, 16
_080B5784:
movs r0, 0xC
bl IncrementGameStat
adds r0, r4, 0
bl sub_80EDA3C
bl BattleSetup_StartWildBattle
pop {r4,r5}
pop {r0}
bx r0
.pool
thumb_func_end sub_80B5734
thumb_func_start wild_pokemon_rand_for_map
wild_pokemon_rand_for_map: @ 80B57A0
push {r4-r6,lr}
adds r6, r0, 0
movs r0, 0
strb r0, [r6]
bl GetCurrentMapWildMonHeaderId
lsls r0, 16
lsrs r3, r0, 16
ldr r0, =0x0000ffff
cmp r3, r0
beq _080B57D2
ldr r2, =gWildMonHeaders
lsls r1, r3, 2
adds r1, r3
lsls r1, 2
adds r0, r2, 0x4
adds r0, r1, r0
ldr r5, [r0]
adds r2, 0x8
adds r1, r2
ldr r4, [r1]
cmp r5, 0
bne _080B57E0
cmp r4, 0
bne _080B57E6
_080B57D2:
movs r0, 0
b _080B5826
.pool
_080B57E0:
cmp r4, 0
bne _080B57F4
b _080B5818
_080B57E6:
movs r0, 0x1
strb r0, [r6]
bl ChooseWildMonIndex_WaterRock
lsls r0, 24
ldr r1, [r4, 0x4]
b _080B5820
_080B57F4:
bl Random
lsls r0, 16
lsrs r0, 16
movs r1, 0x64
bl __umodsi3
lsls r0, 16
lsrs r0, 16
cmp r0, 0x4F
bls _080B5818
movs r0, 0x1
strb r0, [r6]
bl ChooseWildMonIndex_WaterRock
lsls r0, 24
ldr r1, [r4, 0x4]
b _080B5820
_080B5818:
bl ChooseWildMonIndex_Land
lsls r0, 24
ldr r1, [r5, 0x4]
_080B5820:
lsrs r0, 22
adds r0, r1
ldrh r0, [r0, 0x2]
_080B5826:
pop {r4-r6}
pop {r1}
bx r1
thumb_func_end wild_pokemon_rand_for_map
thumb_func_start sub_80B582C
sub_80B582C: @ 80B582C
push {r4,lr}
bl GetCurrentMapWildMonHeaderId
lsls r0, 16
lsrs r2, r0, 16
ldr r0, =0x0000ffff
cmp r2, r0
beq _080B5868
ldr r1, =gWildMonHeaders
lsls r0, r2, 2
adds r0, r2
lsls r0, 2
adds r1, 0x8
adds r0, r1
ldr r4, [r0]
cmp r4, 0
beq _080B5868
bl ChooseWildMonIndex_WaterRock
lsls r0, 24
ldr r1, [r4, 0x4]
lsrs r0, 22
adds r0, r1
ldrh r0, [r0, 0x2]
b _080B586A
.pool
_080B5868:
movs r0, 0
_080B586A:
pop {r4}
pop {r1}
bx r1
thumb_func_end sub_80B582C
thumb_func_start sub_80B5870
sub_80B5870: @ 80B5870
push {r4,r5,lr}
bl InBattlePike
lsls r0, 24
cmp r0, 0
bne _080B58C4
bl InBattlePyramid
lsls r0, 24
cmp r0, 0
bne _080B58C4
bl InUnionRoom
cmp r0, 0x1
beq _080B58C4
ldr r5, =0x00004021
adds r0, r5, 0
bl VarGet
lsls r0, 16
lsrs r0, 16
cmp r0, 0
beq _080B58C4
subs r4, r0, 0x1
lsls r4, 16
lsrs r4, 16
adds r0, r5, 0
adds r1, r4, 0
bl VarSet
cmp r4, 0
bne _080B58C4
ldr r0, =EventScript_RepelWoreOff
bl ScriptContext1_SetupScript
movs r0, 0x1
b _080B58C6
.pool
_080B58C4:
movs r0, 0
_080B58C6:
pop {r4,r5}
pop {r1}
bx r1
thumb_func_end sub_80B5870
thumb_func_start IsWildLevelAllowedByRepel
IsWildLevelAllowedByRepel: @ 80B58CC
push {r4-r6,lr}
lsls r0, 24
lsrs r6, r0, 24
ldr r0, =0x00004021
bl VarGet
lsls r0, 16
cmp r0, 0
beq _080B5912
movs r5, 0
_080B58E0:
movs r0, 0x64
adds r1, r5, 0
muls r1, r0
ldr r0, =gPlayerParty
adds r4, r1, r0
adds r0, r4, 0
movs r1, 0x39
bl GetMonData
cmp r0, 0
beq _080B5920
adds r0, r4, 0
movs r1, 0x2D
bl GetMonData
cmp r0, 0
bne _080B5920
adds r0, r4, 0
movs r1, 0x38
bl GetMonData
lsls r0, 24
lsrs r0, 24
cmp r6, r0
bcc _080B592A
_080B5912:
movs r0, 0x1
b _080B592C
.pool
_080B5920:
adds r0, r5, 0x1
lsls r0, 24
lsrs r5, r0, 24
cmp r5, 0x5
bls _080B58E0
_080B592A:
movs r0, 0
_080B592C:
pop {r4-r6}
pop {r1}
bx r1
thumb_func_end IsWildLevelAllowedByRepel
thumb_func_start IsAbilityAllowingEncounter
@ _BOOL1 IsAbilityAllowingEncounter(u8 wildMonLevel)
IsAbilityAllowingEncounter: @ 80B5934
push {r4,r5,lr}
lsls r0, 24
lsrs r5, r0, 24
ldr r4, =gPlayerParty
adds r0, r4, 0
movs r1, 0x6
bl GetMonData
cmp r0, 0
bne _080B5988
adds r0, r4, 0
bl GetMonAbility
lsls r0, 24
lsrs r0, 24
cmp r0, 0x33
beq _080B595A
cmp r0, 0x16
bne _080B5988
_080B595A:
adds r0, r4, 0
movs r1, 0x38
bl GetMonData
lsls r0, 24
lsrs r0, 24
cmp r0, 0x5
bls _080B5988
subs r0, 0x5
cmp r5, r0
bgt _080B5988
bl Random
lsls r0, 16
lsrs r0, 16
movs r1, 0x1
ands r0, r1
cmp r0, 0
bne _080B5988
movs r0, 0
b _080B598A
.pool
_080B5988:
movs r0, 0x1
_080B598A:
pop {r4,r5}
pop {r1}
bx r1
thumb_func_end IsAbilityAllowingEncounter
thumb_func_start TryGetRandomWildMonIndexByType
@ _BOOL1 TryGetRandomWildMonIndexByType(WildMonEntry *mons, u8 type, u8 numMons, u8 *monIndex)
TryGetRandomWildMonIndexByType: @ 80B5990
push {r4-r7,lr}
mov r7, r10
mov r6, r9
mov r5, r8
push {r5-r7}
sub sp, 0x4
mov r7, sp
mov r12, r0
mov r8, r3
lsls r1, 24
lsrs r1, 24
str r1, [r7]
lsls r2, 24
lsrs r2, 24
mov r9, sp
adds r0, r2, 0x3
lsrs r0, 2
lsls r0, 2
mov r1, sp
subs r1, r0
mov sp, r1
mov r5, sp
movs r3, 0
cmp r3, r2
bcs _080B59D2
movs r1, 0
_080B59C4:
adds r0, r5, r3
strb r1, [r0]
adds r0, r3, 0x1
lsls r0, 24
lsrs r3, r0, 24
cmp r3, r2
bcc _080B59C4
_080B59D2:
movs r4, 0
movs r3, 0
cmp r4, r2
bcs _080B5A12
ldr r6, =gBaseStats
mov r10, r6
_080B59DE:
lsls r0, r3, 2
add r0, r12
ldrh r1, [r0, 0x2]
lsls r0, r1, 3
subs r0, r1
lsls r0, 2
mov r6, r10
adds r1, r0, r6
ldrb r0, [r1, 0x6]
ldr r6, [r7]
cmp r0, r6
beq _080B59FC
ldrb r0, [r1, 0x7]
cmp r0, r6
bne _080B5A08
_080B59FC:
adds r1, r4, 0
adds r0, r1, 0x1
lsls r0, 24
lsrs r4, r0, 24
adds r1, r5, r1
strb r3, [r1]
_080B5A08:
adds r0, r3, 0x1
lsls r0, 24
lsrs r3, r0, 24
cmp r3, r2
bcc _080B59DE
_080B5A12:
cmp r4, 0
beq _080B5A1A
cmp r4, r2
bne _080B5A24
_080B5A1A:
movs r0, 0
b _080B5A3C
.pool
_080B5A24:
bl Random
lsls r0, 16
lsrs r0, 16
adds r1, r4, 0
bl __modsi3
adds r0, r5, r0
ldrb r0, [r0]
mov r1, r8
strb r0, [r1]
movs r0, 0x1
_080B5A3C:
mov sp, r9
add sp, 0x4
pop {r3-r5}
mov r8, r3
mov r9, r4
mov r10, r5
pop {r4-r7}
pop {r1}
bx r1
thumb_func_end TryGetRandomWildMonIndexByType
thumb_func_start TryGetAbilityInfluencedWildMonIndex
@ _BOOL1 TryGetAbilityInfluencedWildMonIndex(WildMonEntry *mons, u8 type, u8 abilityId, u8 *monIndex)
TryGetAbilityInfluencedWildMonIndex: @ 80B5A50
push {r4-r7,lr}
mov r7, r8
push {r7}
adds r7, r0, 0
mov r8, r3
lsls r1, 24
lsrs r6, r1, 24
lsls r2, 24
lsrs r5, r2, 24
ldr r4, =gPlayerParty
adds r0, r4, 0
movs r1, 0x6
bl GetMonData
cmp r0, 0
bne _080B5AA4
adds r0, r4, 0
bl GetMonAbility
lsls r0, 24
lsrs r0, 24
cmp r0, r5
bne _080B5AA4
bl Random
lsls r0, 16
lsrs r0, 16
movs r1, 0x1
ands r0, r1
cmp r0, 0
bne _080B5AA4
adds r0, r7, 0
adds r1, r6, 0
movs r2, 0xC
mov r3, r8
bl TryGetRandomWildMonIndexByType
lsls r0, 24
lsrs r0, 24
b _080B5AA6
.pool
_080B5AA4:
movs r0, 0
_080B5AA6:
pop {r3}
mov r8, r3
pop {r4-r7}
pop {r1}
bx r1
thumb_func_end TryGetAbilityInfluencedWildMonIndex
thumb_func_start ApplyFluteEncounterRateMod
@ void ApplyFluteEncounterRateMod(u32 *val)
ApplyFluteEncounterRateMod: @ 80B5AB0
push {r4,lr}
adds r4, r0, 0
ldr r0, =0x000008ad
bl FlagGet
lsls r0, 24
lsrs r0, 24
cmp r0, 0x1
bne _080B5AD0
ldr r0, [r4]
lsrs r1, r0, 1
adds r0, r1
b _080B5AE2
.pool
_080B5AD0:
ldr r0, =0x000008ae
bl FlagGet
lsls r0, 24
lsrs r0, 24
cmp r0, 0x1
bne _080B5AE4
ldr r0, [r4]
lsrs r0, 1
_080B5AE2:
str r0, [r4]
_080B5AE4:
pop {r4}
pop {r0}
bx r0
.pool
thumb_func_end ApplyFluteEncounterRateMod
thumb_func_start ApplyCleanseTagEncounterRateMod
ApplyCleanseTagEncounterRateMod: @ 80B5AF0
push {r4,lr}
adds r4, r0, 0
ldr r0, =gPlayerParty
movs r1, 0xC
bl GetMonData
cmp r0, 0xBE
bne _080B5B0C
ldr r0, [r4]
lsls r0, 1
movs r1, 0x3
bl __udivsi3
str r0, [r4]
_080B5B0C:
pop {r4}
pop {r0}
bx r0
.pool
thumb_func_end ApplyCleanseTagEncounterRateMod
.align 2, 0 @ Don't pad with nop.

View File

@ -15,7 +15,7 @@ gBattlePyramidWildMonHeaders:: @ 8553894
gBattlePikeWildMonHeaders:: @ 8553A14
.incbin "baserom.gba", 0x553a14, 0x64
gUnknown_08553A78:: @ 8553A78
gWildFeebasRoute119Data:: @ 8553A78
.incbin "baserom.gba", 0x553a78, 0x4
gRoute119WaterTileData:: @ 8553A7C

View File

@ -217,10 +217,10 @@ struct SaveBlock2
/*0xCA9*/ u8 field_CA9_f : 1; // 0x80
/*0xCAA*/ u16 field_CAA[4];
/*0xCB2*/ u16 battlePyramidWildHeaderId;
/*0xCB4*/ u8 field_CB4[88];
/*0xCB4*/ u8 field_CB4[82];
/*0xD06*/ u8 field_D06;
/*0xD07*/ u8 field_D07;
/*0xd08*/ u8 filler_D08[0x112];
/*0xD08*/ u8 filler_D08[0x112];
/*0xE1A*/ u16 battlePyramidFloor; // possibly?
/*0xE1C*/ u8 field_E1C[16];
/*0xE2C*/ struct PyramidBag pyramidBag;
@ -587,12 +587,11 @@ struct SaveBlock1
/*0x2E25*/ u8 unk2E25[3]; // possibly padding?
/*0x2E28*/ OldMan oldMan;
/*0x2e64*/ struct EasyChatPair easyChatPairs[5]; //Dewford trend [0] and some other stuff
/*0x2e8c*/ u8 filler_2E8C[0x4];
/*0x2e90*/ struct ContestWinner contestWinners[13]; // 0 - 5 used in contest hall, 6 - 7 unused?, 8 - 12 museum
/*0x3030*/ struct DaycareData daycare;
/*0x3150*/ struct LinkBattleRecord linkBattleRecords[5];
/*0x31A0*/ u8 unk_31A0;
/*0x31A1*/ u8 filler_31A1[3];
/*0x31A1*/ u8 filler_31A1[7];
/*0x31A8*/ u8 giftRibbons[52];
/*0x31DC*/ struct Roamer roamer;
/*0x31F8*/ struct EnigmaBerry enigmaBerry;

View File

@ -179,6 +179,7 @@ void LinkVSync(void);
void Timer3Intr(void);
void SerialCB(void);
u8 GetLinkPlayerCount(void);
bool32 InUnionRoom(void);
void sub_800E0E8(void);
bool8 sub_800A520(void);

View File

@ -13,5 +13,6 @@ void sub_80EE184(void);
void sub_80EEA70(void);
void sub_80F14F8(TVShow *shows);
size_t sub_80EF370(int value);
void SetPokemonAnglerSpecies(u16 species);
#endif //GUARD_TV_H

View File

@ -1883,7 +1883,7 @@ void PutFishingAdviceShowOnTheAir(void)
}
}
void sub_80EDA3C(u16 species)
void SetPokemonAnglerSpecies(u16 species)
{
sPokemonAnglerSpecies = species;
}

View File

@ -13,28 +13,43 @@
#include "pokeblock.h"
#include "battle_setup.h"
#include "roamer.h"
#include "game_stat.h"
#include "tv.h"
#include "link.h"
#include "script.h"
#include "items.h"
EWRAM_DATA u8 sWildEncountersDisabled = 0;
EWRAM_DATA u32 sFeebasRngValue = 0;
extern const u8 EventScript_RepelWoreOff[];
#define NUM_FEEBAS_SPOTS 6
#define NUM_FEEBAS_SPOTS 6
#define LAND_WILD_COUNT 12
#define WATER_WILD_COUNT 5
#define ROCK_WILD_COUNT 5
#define FISH_WILD_COUNT 10
extern const u16 gRoute119WaterTileData[];
extern const struct WildPokemonHeader gBattlePikeWildMonHeaders[];
extern const struct WildPokemonHeader gBattlePyramidWildMonHeaders[];
extern const struct WildPokemon gWildFeebasRoute119Data;
extern u8 GetBattlePikeWildMonHeaderId(void);
extern bool32 TryGenerateBattlePikeWildMon(bool8 checkKeenEyeIntimidate);
extern void GenerateBattlePyramidWildMon(void);
extern bool8 InBattlePike(void);
extern bool8 InBattlePyramid(void);
// this file's functions
u16 FeebasRandom(void);
void FeebasSeedRng(u16 seed);
bool8 IsWildLevelAllowedByRepel(u8 level);
void ApplyFluteEncounterRateMod(u32 *encRate);
void ApplyCleanseTagEncounterRateMod(u32 *encRate);
bool8 TryGetAbilityInfluencedWildMonIndex(const struct WildPokemon *wildMon, u8 type, u8 ability, u8 *monIndex);
bool8 IsAbilityAllowingEncounter(u8 level);
static u16 FeebasRandom(void);
static void FeebasSeedRng(u16 seed);
static bool8 IsWildLevelAllowedByRepel(u8 level);
static void ApplyFluteEncounterRateMod(u32 *encRate);
static void ApplyCleanseTagEncounterRateMod(u32 *encRate);
static bool8 TryGetAbilityInfluencedWildMonIndex(const struct WildPokemon *wildMon, u8 type, u8 ability, u8 *monIndex);
static bool8 IsAbilityAllowingEncounter(u8 level);
EWRAM_DATA u8 sWildEncountersDisabled = 0;
EWRAM_DATA u32 sFeebasRngValue = 0;
void DisableWildEncounters(bool8 disabled)
{
@ -118,13 +133,13 @@ bool8 CheckFeebas(void)
return FALSE;
}
u16 FeebasRandom(void)
static u16 FeebasRandom(void)
{
sFeebasRngValue = 12345 + 0x41C64E6D * sFeebasRngValue;
return sFeebasRngValue >> 16;
}
void FeebasSeedRng(u16 seed)
static void FeebasSeedRng(u16 seed)
{
sFeebasRngValue = seed;
}
@ -418,7 +433,7 @@ bool8 TryGenerateWildMon(const struct WildPokemonInfo *wildMonInfo, u8 area, u8
return TRUE;
}
u16 GenerateFishingWildMon(struct WildPokemonInfo *wildMonInfo, u8 rod)
u16 GenerateFishingWildMon(const struct WildPokemonInfo *wildMonInfo, u8 rod)
{
u8 wildMonIndex = ChooseWildMonIndex_Fishing(rod);
u8 level = ChooseWildMonLevel(&wildMonInfo->wildPokemon[wildMonIndex]);
@ -736,3 +751,185 @@ bool8 DoesCurrentMapHaveFishingMons(void)
else
return FALSE;
}
void FishingWildEncounter(u8 rod)
{
u16 species;
if (CheckFeebas() == TRUE)
{
u8 level = ChooseWildMonLevel(&gWildFeebasRoute119Data);
species = gWildFeebasRoute119Data.species;
CreateWildMon(species, level);
}
else
{
species = GenerateFishingWildMon(gWildMonHeaders[GetCurrentMapWildMonHeaderId()].fishingMonsInfo, rod);
}
IncrementGameStat(GAME_STAT_FISHING_CAPTURES);
SetPokemonAnglerSpecies(species);
BattleSetup_StartWildBattle();
}
u16 GetLocalWildMon(bool8 *isWaterMon)
{
u16 headerId;
const struct WildPokemonInfo *landMonsInfo;
const struct WildPokemonInfo *waterMonsInfo;
*isWaterMon = FALSE;
headerId = GetCurrentMapWildMonHeaderId();
if (headerId == 0xFFFF)
return SPECIES_NONE;
landMonsInfo = gWildMonHeaders[headerId].landMonsInfo;
waterMonsInfo = gWildMonHeaders[headerId].waterMonsInfo;
// Neither
if (landMonsInfo == NULL && waterMonsInfo == NULL)
return SPECIES_NONE;
// Land Pokemon
if (landMonsInfo != NULL && waterMonsInfo == NULL)
return landMonsInfo->wildPokemon[ChooseWildMonIndex_Land()].species;
// Water Pokemon
if (landMonsInfo == NULL && waterMonsInfo != NULL)
{
*isWaterMon = TRUE;
return waterMonsInfo->wildPokemon[ChooseWildMonIndex_WaterRock()].species;
}
// Either land or water Pokemon
if ((Random() % 100) < 80)
{
return landMonsInfo->wildPokemon[ChooseWildMonIndex_Land()].species;
}
else
{
*isWaterMon = TRUE;
return waterMonsInfo->wildPokemon[ChooseWildMonIndex_WaterRock()].species;
}
}
u16 GetLocalWaterMon(void)
{
u16 headerId = GetCurrentMapWildMonHeaderId();
if (headerId != 0xFFFF)
{
const struct WildPokemonInfo *waterMonsInfo = gWildMonHeaders[headerId].waterMonsInfo;
if (waterMonsInfo)
return waterMonsInfo->wildPokemon[ChooseWildMonIndex_WaterRock()].species;
}
return SPECIES_NONE;
}
bool8 UpdateRepelCounter(void)
{
u16 steps;
if (InBattlePike() || InBattlePyramid())
return FALSE;
if (InUnionRoom() == TRUE)
return FALSE;
steps = VarGet(VAR_REPEL_STEP_COUNT);
if (steps != 0)
{
steps--;
VarSet(VAR_REPEL_STEP_COUNT, steps);
if (steps == 0)
{
ScriptContext1_SetupScript(EventScript_RepelWoreOff);
return TRUE;
}
}
return FALSE;
}
static bool8 IsWildLevelAllowedByRepel(u8 wildLevel)
{
u8 i;
if (!VarGet(VAR_REPEL_STEP_COUNT))
return TRUE;
for (i = 0; i < PARTY_SIZE; i++)
{
if (GetMonData(&gPlayerParty[i], MON_DATA_HP) && !GetMonData(&gPlayerParty[i], MON_DATA_IS_EGG))
{
u8 ourLevel = GetMonData(&gPlayerParty[i], MON_DATA_LEVEL);
if (wildLevel < ourLevel)
return FALSE;
else
return TRUE;
}
}
return FALSE;
}
static bool8 IsAbilityAllowingEncounter(u8 level)
{
u8 ability;
if (GetMonData(&gPlayerParty[0], MON_DATA_SANITY_BIT3))
return TRUE;
ability = GetMonAbility(&gPlayerParty[0]);
if (ability == ABILITY_KEEN_EYE || ability == ABILITY_INTIMIDATE)
{
u8 playerMonLevel = GetMonData(&gPlayerParty[0], MON_DATA_LEVEL);
if (playerMonLevel > 5 && level <= playerMonLevel - 5 && !(Random() % 2))
return FALSE;
}
return TRUE;
}
static bool8 TryGetRandomWildMonIndexByType(const struct WildPokemon *wildMon, u8 type, u8 numMon, u8 *monIndex)
{
u8 validIndexes[numMon]; // variable length array, an interesting feature
u8 i, validMonCount;
for (i = 0; i < numMon; i++)
validIndexes[i] = 0;
for (validMonCount = 0, i = 0; i < numMon; i++)
{
if (gBaseStats[wildMon[i].species].type1 == type || gBaseStats[wildMon[i].species].type2 == type)
validIndexes[validMonCount++] = i;
}
if (validMonCount == 0 || validMonCount == numMon)
return FALSE;
*monIndex = validIndexes[Random() % validMonCount];
return TRUE;
}
static bool8 TryGetAbilityInfluencedWildMonIndex(const struct WildPokemon *wildMon, u8 type, u8 ability, u8 *monIndex)
{
if (GetMonData(&gPlayerParty[0], MON_DATA_SANITY_BIT3))
return FALSE;
if (GetMonAbility(&gPlayerParty[0]) != ability)
return FALSE;
if (Random() % 2 != 0)
return FALSE;
return TryGetRandomWildMonIndexByType(wildMon, type, LAND_WILD_COUNT, monIndex);
}
static void ApplyFluteEncounterRateMod(u32 *encRate)
{
if (FlagGet(FLAG_SYS_ENC_UP_ITEM) == TRUE)
*encRate += *encRate / 2;
else if (FlagGet(FLAG_SYS_ENC_DOWN_ITEM) == TRUE)
*encRate = *encRate / 2;
}
static void ApplyCleanseTagEncounterRateMod(u32 *encRate)
{
if (GetMonData(&gPlayerParty[0], MON_DATA_HELD_ITEM) == ITEM_CLEANSE_TAG)
*encRate = *encRate * 2 / 3;
}