diff options
author | PikalaxALT <pikalaxalt@gmail.com> | 2019-10-31 14:31:21 -0400 |
---|---|---|
committer | PikalaxALT <pikalaxalt@gmail.com> | 2019-10-31 14:31:21 -0400 |
commit | b07b36c6d29fbfdb8e75e343870ae8e87e9308bd (patch) | |
tree | e8ef1407b372bf70259df84575ba9c7816d259f7 /src | |
parent | dc8c03d13fa1972c02fbe32f6f3143f3f36a7355 (diff) |
wild_encounter through sub_8082C98
Diffstat (limited to 'src')
-rw-r--r-- | src/wild_encounter.c | 301 |
1 files changed, 301 insertions, 0 deletions
diff --git a/src/wild_encounter.c b/src/wild_encounter.c new file mode 100644 index 000000000..d6d115348 --- /dev/null +++ b/src/wild_encounter.c @@ -0,0 +1,301 @@ +#include "global.h" +#include "random.h" +#include "wild_encounter.h" +#include "event_data.h" +#include "field_player_avatar.h" +#include "constants/species.h" +#include "constants/maps.h" +#include "constants/vars.h" +#include "constants/abilities.h" + +struct UnkStruct_20386D0 +{ + u8 filler_0[6]; + u16 unk_6; + u8 unk_8; + u8 unk_9; +}; + +EWRAM_DATA struct UnkStruct_20386D0 gUnknown_20386D0 = {}; +EWRAM_DATA bool8 gUnknown_20386DC = FALSE; + +extern const u8 gUnknown_83CA71C[][12]; + +bool8 UnlockedTanobyOrAreNotInTanoby(void); +u32 GenerateUnownPersonalityByLetter(u8 letter); +bool8 sub_808310C(u8 level); +u16 sub_808322C(void); +void ApplyFluteEncounterRateMod(u32 *rate); +void ApplyCleanseTagEncounterRateMod(u32 *rate); + +void sub_8082740(bool8 state) +{ + gUnknown_20386DC = state; +} + +u8 ChooseWildMonIndex_Land(void) +{ + u8 pct = Random() % 100; + if (pct < 20) + return 0; + if (pct >= 20 && pct < 40) + return 1; + if (pct >= 40 && pct < 50) + return 2; + if (pct >= 50 && pct < 60) + return 3; + if (pct >= 60 && pct < 70) + return 4; + if (pct >= 70 && pct < 80) + return 5; + if (pct >= 80 && pct < 85) + return 6; + if (pct >= 85 && pct < 90) + return 7; + if (pct >= 90 && pct < 94) + return 8; + if (pct >= 94 && pct < 98) + return 9; + if (pct == 98) + return 10; + return 11; +} + +u8 ChooseWildMonIndex_WaterRock(void) +{ + u8 pct = Random() % 100; + if (pct < 60) + return 0; + if (pct >= 60 && pct < 90) + return 1; + if (pct >= 90 && pct < 95) + return 2; + if (pct >= 95 && pct < 99) + return 3; + return 4; +} + +u8 ChooseWildMonIndex_Fishing(u8 rod) +{ + u8 slot = 0; + u8 pct = Random() % 100; + switch (rod) + { + case 0: // old + if (pct < 70) + slot = 0; + else + slot = 1; + break; + case 1: + if (pct < 60) + slot = 2; + if (pct >= 60 && pct < 80) + slot = 3; + if (pct >= 80 && pct < 100) + slot = 4; + break; + case 2: + if (pct < 40) + slot = 5; + if (pct >= 40 && pct < 80) + slot = 6; + if (pct >= 80 && pct < 95) + slot = 7; + if (pct >= 95 && pct < 99) + slot = 8; + if (pct == 99) + slot = 9; + break; + } + return slot; +} + +u8 ChooseWildMonLevel(const struct WildPokemon * info) +{ + u8 lo; + u8 hi; + u8 mod; + u8 res; + if (info->maxLevel >= info->minLevel) + { + lo = info->minLevel; + hi = info->maxLevel; + } + else + { + lo = info->maxLevel; + hi = info->minLevel; + } + mod = hi - lo + 1; + res = Random() % mod; + return lo + res; +} + +u16 sub_8082934(void) +{ + u16 i; + + for (i = 0; ; i++) + { + const struct WildPokemonHeader *wildHeader = &gWildMonHeaders[i]; + if (wildHeader->mapGroup == 0xFF) + break; + + if (gWildMonHeaders[i].mapGroup == gSaveBlock1Ptr->location.mapGroup && + gWildMonHeaders[i].mapNum == gSaveBlock1Ptr->location.mapNum) + { + if (gSaveBlock1Ptr->location.mapGroup == MAP_GROUP(SIX_ISLAND_ALTERING_CAVE) && + gSaveBlock1Ptr->location.mapNum == MAP_NUM(SIX_ISLAND_ALTERING_CAVE)) + { + u16 alteringCaveId = VarGet(VAR_ALTERING_CAVE_WILD_SET); + if (alteringCaveId > 8) + alteringCaveId = 0; + + i += alteringCaveId; + } + + if (!UnlockedTanobyOrAreNotInTanoby()) + break; + return i; + } + } + + return -1; +} + +bool8 UnlockedTanobyOrAreNotInTanoby(void) +{ + if (FlagGet(FLAG_SYS_UNLOCKED_TANOBY_RUINS)) + return TRUE; + if (gSaveBlock1Ptr->location.mapGroup != MAP_GROUP(SEVEN_ISLAND_TANOBY_RUINS_DILFORD_CHAMBER)) + return TRUE; + if (!(gSaveBlock1Ptr->location.mapNum == MAP_NUM(SEVEN_ISLAND_TANOBY_RUINS_MONEAN_CHAMBER) + || gSaveBlock1Ptr->location.mapNum == MAP_NUM(SEVEN_ISLAND_TANOBY_RUINS_LIPTOO_CHAMBER) + || gSaveBlock1Ptr->location.mapNum == MAP_NUM(SEVEN_ISLAND_TANOBY_RUINS_WEEPTH_CHAMBER) + || gSaveBlock1Ptr->location.mapNum == MAP_NUM(SEVEN_ISLAND_TANOBY_RUINS_DILFORD_CHAMBER) + || gSaveBlock1Ptr->location.mapNum == MAP_NUM(SEVEN_ISLAND_TANOBY_RUINS_SCUFIB_CHAMBER) + || gSaveBlock1Ptr->location.mapNum == MAP_NUM(SEVEN_ISLAND_TANOBY_RUINS_RIXY_CHAMBER) + || gSaveBlock1Ptr->location.mapNum == MAP_NUM(SEVEN_ISLAND_TANOBY_RUINS_VIAPOIS_CHAMBER) + )) + return TRUE; + return FALSE; +} + +void GenerateWildMon(u16 species, u8 level, u8 slot) +{ + u32 personality; + s8 chamber; + ZeroEnemyPartyMons(); + if (species != SPECIES_UNOWN) + { + CreateMonWithNature(&gEnemyParty[0], species, level, 32, Random() % 25); + } + else + { + chamber = gSaveBlock1Ptr->location.mapNum - MAP_NUM(SEVEN_ISLAND_TANOBY_RUINS_MONEAN_CHAMBER); + personality = GenerateUnownPersonalityByLetter(gUnknown_83CA71C[chamber][slot]); + CreateMon(&gEnemyParty[0], species, level, 32, TRUE, personality, FALSE, 0); + } +} + +u32 GenerateUnownPersonalityByLetter(u8 letter) +{ + u32 personality; + do + { + personality = (Random() << 16) | Random(); + } while (GetUnownLetterByPersonalityLoByte(personality) != letter); + return personality; +} + +u8 GetUnownLetterByPersonalityLoByte(u32 personality) +{ + return (((personality & 0x3000000) >> 18) | ((personality & 0x30000) >> 12) | ((personality & 0x300) >> 6) | (personality & 0x3)) % 0x1C; +} + +bool8 sub_8082AEC(const struct WildPokemonInfo * info, u8 tableIdx, u8 a2) +{ + u8 slot = 0; + u8 level; + switch (tableIdx) + { + case 0: + slot = ChooseWildMonIndex_Land(); + break; + case 1: + slot = ChooseWildMonIndex_WaterRock(); + break; + case 2: + slot = ChooseWildMonIndex_WaterRock(); + break; + } + level = ChooseWildMonLevel(&info->wildPokemon[slot]); + if (a2 == 1 && !sub_808310C(level)) + { + return FALSE; + } + GenerateWildMon(info->wildPokemon[slot].species, level, slot); + return TRUE; +} + +u16 sub_8082B64(const struct WildPokemonInfo * info, u8 rod) +{ + u8 slot = ChooseWildMonIndex_Fishing(rod); + u8 level = ChooseWildMonLevel(&info->wildPokemon[slot]); + GenerateWildMon(info->wildPokemon[slot].species, level, slot); + return info->wildPokemon[slot].species; +} + +bool8 DoWildEncounterRateDiceRoll(u16 a0) +{ + if (sub_808322C() % 1600 < a0) + return TRUE; + return FALSE; +} + +bool8 sub_8082BCC(u32 encounterRate, bool8 ignoreAbility) +{ + encounterRate *= 16; + if (TestPlayerAvatarFlags(PLAYER_AVATAR_FLAG_MACH_BIKE | PLAYER_AVATAR_FLAG_ACRO_BIKE)) + encounterRate = encounterRate * 80 / 100; + encounterRate += gUnknown_20386D0.unk_6 * 16 / 200; + ApplyFluteEncounterRateMod(&encounterRate); + ApplyCleanseTagEncounterRateMod(&encounterRate); + if (!ignoreAbility) + { + switch (gUnknown_20386D0.unk_9) + { + case 1: + encounterRate /= 2; + break; + case 2: + encounterRate *= 2; + break; + } + } + if (encounterRate > 1600) + encounterRate = 1600; + return DoWildEncounterRateDiceRoll(encounterRate); +} + +u8 sub_8082C58(void) +{ + gUnknown_20386D0.unk_9 = 0; + if (!GetMonData(&gPlayerParty[0], MON_DATA_SANITY_IS_EGG)) + { + u8 ability = GetMonAbility(&gPlayerParty[0]); + if (ability == ABILITY_STENCH) + gUnknown_20386D0.unk_9 = 1; + else if (ability == ABILITY_ILLUMINATE) + gUnknown_20386D0.unk_9 = 2; + } + return gUnknown_20386D0.unk_9; +} + +bool8 sub_8082C98(void) +{ + if ((Random() % 100) >= 60) + return FALSE; + return TRUE; +} |