diff options
-rw-r--r-- | asm/field_control_avatar.s | 2 | ||||
-rw-r--r-- | asm/field_player_avatar.s | 2 | ||||
-rw-r--r-- | asm/rom4.s | 4 | ||||
-rw-r--r-- | asm/wild_encounter.s | 508 | ||||
-rw-r--r-- | data/wild_encounter.s | 2 | ||||
-rw-r--r-- | include/global.h | 7 | ||||
-rw-r--r-- | include/link.h | 1 | ||||
-rw-r--r-- | include/tv.h | 1 | ||||
-rw-r--r-- | src/tv.c | 2 | ||||
-rw-r--r-- | src/wild_encounter.c | 223 |
10 files changed, 221 insertions, 531 deletions
diff --git a/asm/field_control_avatar.s b/asm/field_control_avatar.s index a6d3c93ea..57415ca36 100644 --- a/asm/field_control_avatar.s +++ b/asm/field_control_avatar.s @@ -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 diff --git a/asm/field_player_avatar.s b/asm/field_player_avatar.s index 28c90d23d..ae405f127 100644 --- a/asm/field_player_avatar.s +++ b/asm/field_player_avatar.s @@ -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 diff --git a/asm/rom4.s b/asm/rom4.s index 3f59c2807..8b7dec1ae 100644 --- a/asm/rom4.s +++ b/asm/rom4.s @@ -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] diff --git a/asm/wild_encounter.s b/asm/wild_encounter.s index d8f02ae83..da4dca0ed 100644 --- a/asm/wild_encounter.s +++ b/asm/wild_encounter.s @@ -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. diff --git a/data/wild_encounter.s b/data/wild_encounter.s index d45acf415..e221c2f99 100644 --- a/data/wild_encounter.s +++ b/data/wild_encounter.s @@ -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 diff --git a/include/global.h b/include/global.h index 490ebe64e..c05d6a309 100644 --- a/include/global.h +++ b/include/global.h @@ -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; diff --git a/include/link.h b/include/link.h index 7a6563144..ddd809ebe 100644 --- a/include/link.h +++ b/include/link.h @@ -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); diff --git a/include/tv.h b/include/tv.h index 43f36d69f..3f48af569 100644 --- a/include/tv.h +++ b/include/tv.h @@ -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 @@ -1883,7 +1883,7 @@ void PutFishingAdviceShowOnTheAir(void) } } -void sub_80EDA3C(u16 species) +void SetPokemonAnglerSpecies(u16 species) { sPokemonAnglerSpecies = species; } diff --git a/src/wild_encounter.c b/src/wild_encounter.c index 6238f6aab..d92f9daf3 100644 --- a/src/wild_encounter.c +++ b/src/wild_encounter.c @@ -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; +} |