mirror of
https://github.com/Ninjdai1/pokeemerald.git
synced 2024-12-26 03:34:15 +01:00
start decompiling wild encounter
This commit is contained in:
parent
a98c6bf210
commit
b37d8c0821
@ -704,7 +704,7 @@ sub_817A1C4: @ 817A1C4
|
||||
lsls r0, 24
|
||||
lsrs r0, 24
|
||||
adds r1, r4, 0
|
||||
bl sub_8136FE4
|
||||
bl PokeblockGetGain
|
||||
ldr r6, =gUnknown_0203BC9E
|
||||
strh r0, [r6]
|
||||
ldr r1, =gStringVar1
|
||||
|
10
asm/rom6.s
10
asm/rom6.s
@ -2779,7 +2779,7 @@ sub_8136C8C: @ 8136C8C
|
||||
adds r2, r6
|
||||
ldr r1, [r5]
|
||||
adds r1, r2
|
||||
bl sub_8136FE4
|
||||
bl PokeblockGetGain
|
||||
adds r4, r0, 0
|
||||
lsls r4, 16
|
||||
lsrs r4, 16
|
||||
@ -3177,8 +3177,8 @@ _08136FDE:
|
||||
bx r1
|
||||
thumb_func_end sub_8136F9C
|
||||
|
||||
thumb_func_start sub_8136FE4
|
||||
sub_8136FE4: @ 8136FE4
|
||||
thumb_func_start PokeblockGetGain
|
||||
PokeblockGetGain: @ 8136FE4
|
||||
push {r4-r7,lr}
|
||||
mov r7, r9
|
||||
mov r6, r8
|
||||
@ -3227,7 +3227,7 @@ _0813702A:
|
||||
pop {r1}
|
||||
bx r1
|
||||
.pool
|
||||
thumb_func_end sub_8136FE4
|
||||
thumb_func_end PokeblockGetGain
|
||||
|
||||
thumb_func_start sub_8137044
|
||||
sub_8137044: @ 8137044
|
||||
@ -3261,7 +3261,7 @@ _08137074:
|
||||
ldr r0, =gUnknown_085B2720
|
||||
adds r1, r0
|
||||
adds r0, r5, 0
|
||||
bl sub_8136FE4
|
||||
bl PokeblockGetGain
|
||||
lsls r0, 16
|
||||
cmp r0, 0
|
||||
ble _081370A0
|
||||
|
1325
asm/wild_encounter.s
1325
asm/wild_encounter.s
File diff suppressed because it is too large
Load Diff
@ -18,5 +18,5 @@ gUnknown_08553A14:: @ 8553A14
|
||||
gUnknown_08553A78:: @ 8553A78
|
||||
.incbin "baserom.gba", 0x553a78, 0x4
|
||||
|
||||
gUnknown_08553A7C:: @ 8553A7C
|
||||
gRoute119WaterTileData:: @ 8553A7C
|
||||
.incbin "baserom.gba", 0x553a7c, 0x14
|
||||
|
@ -579,7 +579,7 @@ struct SaveBlock1
|
||||
/*0x2BB0*/ u16 unk2BB0[6];
|
||||
/*0x2BBC*/ u16 unk2BBC[6];
|
||||
/*0x2BC8*/ u16 unk2BC8[6];
|
||||
/*0x2BD4*/ u16 unk2BD4[3];
|
||||
/*0x2BD4*/ u16 unk2BD4[6];
|
||||
/*0x2BE0*/ struct MailStruct mail[16];
|
||||
/*0x2E20*/ u8 additionalPhrases[5]; // bitfield for 33 additional phrases in easy chat system
|
||||
/*0x2E25*/ u8 unk2E25[3]; // possibly padding?
|
||||
|
@ -23,6 +23,7 @@ enum
|
||||
};
|
||||
|
||||
void ClearPokeblocks(void);
|
||||
s16 PokeblockGetGain(u8, const struct Pokeblock *);
|
||||
|
||||
/*
|
||||
void sub_810B96C(void);
|
||||
@ -32,7 +33,6 @@ s16 GetPokeblockData(const struct Pokeblock *, u8);
|
||||
u8 sub_810C9E8(struct Pokeblock *);
|
||||
void sub_810BA7C(u8);
|
||||
bool8 PokeblockClearIfExists(u8);
|
||||
s16 PokeblockGetGain(u8, const struct Pokeblock *);
|
||||
u8 sub_810CB68(u8, u8*);
|
||||
void PokeblockCopyName(struct Pokeblock *pokeblock, u8 *dest);
|
||||
void CB2_PreparePokeblockFeedScene(void);
|
||||
|
@ -30,6 +30,7 @@
|
||||
#define VAR_RESET_RTC_ENABLE 0x402C
|
||||
|
||||
#define VAR_0x4037 0x4037
|
||||
#define VAR_ALTERING_CAVE_WILD_SET 0x403E
|
||||
#define VAR_DAYS 0x4040
|
||||
|
||||
#define VAR_DEPT_STORE_FLOOR 0x4043
|
||||
|
39
include/wild_encounter.h
Normal file
39
include/wild_encounter.h
Normal file
@ -0,0 +1,39 @@
|
||||
#ifndef GUARD_WILD_ENCOUNTER_H
|
||||
#define GUARD_WILD_ENCOUNTER_H
|
||||
|
||||
struct WildPokemon
|
||||
{
|
||||
u8 minLevel;
|
||||
u8 maxLevel;
|
||||
u16 species;
|
||||
};
|
||||
|
||||
struct WildPokemonInfo
|
||||
{
|
||||
u8 encounterRate;
|
||||
const struct WildPokemon *wildPokemon;
|
||||
};
|
||||
|
||||
struct WildPokemonHeader
|
||||
{
|
||||
u8 mapGroup;
|
||||
u8 mapNum;
|
||||
const struct WildPokemonInfo *landMonsInfo;
|
||||
const struct WildPokemonInfo *waterMonsInfo;
|
||||
const struct WildPokemonInfo *rockSmashMonsInfo;
|
||||
const struct WildPokemonInfo *fishingMonsInfo;
|
||||
};
|
||||
|
||||
extern const struct WildPokemonHeader gWildMonHeaders[];
|
||||
|
||||
void DisableWildEncounters(bool8 disabled);
|
||||
bool8 StandardWildEncounter(u16 a, u16 b);
|
||||
void ScrSpecial_RockSmashWildEncounter(void);
|
||||
bool8 SweetScentWildEncounter(void);
|
||||
bool8 DoesCurrentMapHaveFishingMons(void);
|
||||
void FishingWildEncounter(u8 rod);
|
||||
u16 GetLocalWildMon(bool8 *isWaterMon);
|
||||
u16 GetLocalWaterMon(void);
|
||||
bool8 UpdateRepelCounter(void);
|
||||
|
||||
#endif // GUARD_WILD_ENCOUNTER_H
|
@ -124,6 +124,7 @@ SECTIONS {
|
||||
asm/battle_setup.o(.text);
|
||||
asm/cable_club.o(.text);
|
||||
asm/trainer_see.o(.text);
|
||||
src/wild_encounter.o(.text);
|
||||
asm/wild_encounter.o(.text);
|
||||
asm/field_effect.o(.text);
|
||||
asm/unknown_task.o(.text);
|
||||
|
483
src/wild_encounter.c
Normal file
483
src/wild_encounter.c
Normal file
@ -0,0 +1,483 @@
|
||||
#include "global.h"
|
||||
#include "wild_encounter.h"
|
||||
#include "pokemon.h"
|
||||
#include "species.h"
|
||||
#include "metatile_behavior.h"
|
||||
#include "fieldmap.h"
|
||||
#include "rng.h"
|
||||
#include "map_constants.h"
|
||||
#include "field_player_avatar.h"
|
||||
#include "abilities.h"
|
||||
#include "event_data.h"
|
||||
#include "safari_zone.h"
|
||||
#include "pokeblock.h"
|
||||
|
||||
EWRAM_DATA u8 sWildEncountersDisabled = 0;
|
||||
EWRAM_DATA u32 sFeebasRngValue = 0;
|
||||
|
||||
#define NUM_FEEBAS_SPOTS 6
|
||||
|
||||
extern const u16 gRoute119WaterTileData[];
|
||||
|
||||
// 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);
|
||||
|
||||
void DisableWildEncounters(bool8 disabled)
|
||||
{
|
||||
sWildEncountersDisabled = disabled;
|
||||
}
|
||||
|
||||
u16 GetRoute119WaterTileNum(s16 x, s16 y, u8 section)
|
||||
{
|
||||
u16 xCur;
|
||||
u16 yCur;
|
||||
u16 yMin = gRoute119WaterTileData[section * 3 + 0];
|
||||
u16 yMax = gRoute119WaterTileData[section * 3 + 1];
|
||||
u16 tileNum = gRoute119WaterTileData[section * 3 + 2];
|
||||
|
||||
for (yCur = yMin; yCur <= yMax; yCur++)
|
||||
{
|
||||
for (xCur = 0; xCur < gMapHeader.mapData->width; xCur++)
|
||||
{
|
||||
u8 tileBehaviorId = MapGridGetMetatileBehaviorAt(xCur + 7, yCur + 7);
|
||||
if (MetatileBehavior_IsSurfableAndNotWaterfall(tileBehaviorId) == TRUE)
|
||||
{
|
||||
tileNum++;
|
||||
if (x == xCur && y == yCur)
|
||||
return tileNum;
|
||||
}
|
||||
}
|
||||
}
|
||||
return tileNum + 1;
|
||||
}
|
||||
|
||||
bool8 CheckFeebas(void)
|
||||
{
|
||||
u8 i;
|
||||
u16 feebasSpots[NUM_FEEBAS_SPOTS];
|
||||
s16 x;
|
||||
s16 y;
|
||||
u8 route119section = 0;
|
||||
u16 waterTileNum;
|
||||
|
||||
if (gSaveBlock1Ptr->location.mapGroup == MAP_GROUP_ROUTE119
|
||||
&& gSaveBlock1Ptr->location.mapNum == MAP_ID_ROUTE119)
|
||||
{
|
||||
GetXYCoordsOneStepInFrontOfPlayer(&x, &y);
|
||||
x -= 7;
|
||||
y -= 7;
|
||||
|
||||
#ifdef NONMATCHING
|
||||
if (y >= gRoute119WaterTileData[3 * 1 + 0] && y <= gRoute119WaterTileData[3 * 1 + 1])
|
||||
route119section = 1;
|
||||
if (y >= gRoute119WaterTileData[3 * 2 + 0] && y <= gRoute119WaterTileData[3 * 2 + 1])
|
||||
route119section = 2;
|
||||
#else
|
||||
{
|
||||
register const u16 *arr asm("r0");
|
||||
if (y >= (arr = gRoute119WaterTileData)[3 * 1 + 0] && y <= arr[3 * 1 + 1])
|
||||
route119section = 1;
|
||||
if (y >= arr[3 * 2 + 0] && y <= arr[3 * 2 + 1])
|
||||
route119section = 2;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (Random() % 100 > 49) // 50% chance of encountering Feebas
|
||||
return FALSE;
|
||||
|
||||
FeebasSeedRng(gSaveBlock1Ptr->easyChatPairs[0].unk2);
|
||||
for (i = 0; i != NUM_FEEBAS_SPOTS;)
|
||||
{
|
||||
feebasSpots[i] = FeebasRandom() % 447;
|
||||
if (feebasSpots[i] == 0)
|
||||
feebasSpots[i] = 447;
|
||||
if (feebasSpots[i] < 1 || feebasSpots[i] >= 4)
|
||||
i++;
|
||||
}
|
||||
waterTileNum = GetRoute119WaterTileNum(x, y, route119section);
|
||||
for (i = 0; i < NUM_FEEBAS_SPOTS; i++)
|
||||
{
|
||||
if (waterTileNum == feebasSpots[i])
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
u16 FeebasRandom(void)
|
||||
{
|
||||
sFeebasRngValue = 12345 + 0x41C64E6D * sFeebasRngValue;
|
||||
return sFeebasRngValue >> 16;
|
||||
}
|
||||
|
||||
void FeebasSeedRng(u16 seed)
|
||||
{
|
||||
sFeebasRngValue = seed;
|
||||
}
|
||||
|
||||
u8 ChooseWildMonIndex_Land(void)
|
||||
{
|
||||
u8 rand = Random() % 100;
|
||||
|
||||
if (rand < 20) // 20% chance
|
||||
return 0;
|
||||
if (rand >= 20 && rand < 40) // 20% chance
|
||||
return 1;
|
||||
if (rand >= 40 && rand < 50) // 10% chance
|
||||
return 2;
|
||||
if (rand >= 50 && rand < 60) // 10% chance
|
||||
return 3;
|
||||
if (rand >= 60 && rand < 70) // 10% chance
|
||||
return 4;
|
||||
if (rand >= 70 && rand < 80) // 10% chance
|
||||
return 5;
|
||||
if (rand >= 80 && rand < 85) // 5% chance
|
||||
return 6;
|
||||
if (rand >= 85 && rand < 90) // 5% chance
|
||||
return 7;
|
||||
if (rand >= 90 && rand < 94) // 4% chance
|
||||
return 8;
|
||||
if (rand >= 94 && rand < 98) // 4% chance
|
||||
return 9;
|
||||
if (rand == 98) // 1% chance
|
||||
return 10;
|
||||
else // 1% chance
|
||||
return 11;
|
||||
}
|
||||
|
||||
u8 ChooseWildMonIndex_WaterRock(void)
|
||||
{
|
||||
u8 rand = Random() % 100;
|
||||
|
||||
if (rand < 60) // 60% chance
|
||||
return 0;
|
||||
if (rand >= 60 && rand < 90) // 30% chance
|
||||
return 1;
|
||||
if (rand >= 90 && rand < 95) // 5% chance
|
||||
return 2;
|
||||
if (rand >= 95 && rand < 99) // 4% chance
|
||||
return 3;
|
||||
else // 1% chance
|
||||
return 4;
|
||||
}
|
||||
|
||||
enum
|
||||
{
|
||||
OLD_ROD,
|
||||
GOOD_ROD,
|
||||
SUPER_ROD
|
||||
};
|
||||
|
||||
u8 ChooseWildMonIndex_Fishing(u8 rod)
|
||||
{
|
||||
u8 wildMonIndex = 0;
|
||||
u8 rand = Random() % 100;
|
||||
|
||||
switch (rod)
|
||||
{
|
||||
case OLD_ROD:
|
||||
if (rand < 70) // 70% chance
|
||||
wildMonIndex = 0;
|
||||
else // 30% chance
|
||||
wildMonIndex = 1;
|
||||
break;
|
||||
case GOOD_ROD:
|
||||
if (rand < 60) // 60% chance
|
||||
wildMonIndex = 2;
|
||||
if (rand >= 60 && rand < 80) // 20% chance
|
||||
wildMonIndex = 3;
|
||||
if (rand >= 80 && rand < 100) // 20% chance
|
||||
wildMonIndex = 4;
|
||||
break;
|
||||
case SUPER_ROD:
|
||||
if (rand < 40) // 40% chance
|
||||
wildMonIndex = 5;
|
||||
if (rand >= 40 && rand < 80) // 40% chance
|
||||
wildMonIndex = 6;
|
||||
if (rand >= 80 && rand < 95) // 15% chance
|
||||
wildMonIndex = 7;
|
||||
if (rand >= 95 && rand < 99) // 4% chance
|
||||
wildMonIndex = 8;
|
||||
if (rand == 99) // 1% chance
|
||||
wildMonIndex = 9;
|
||||
break;
|
||||
}
|
||||
return wildMonIndex;
|
||||
}
|
||||
|
||||
u8 ChooseWildMonLevel(const struct WildPokemon *wildPokemon)
|
||||
{
|
||||
u8 min;
|
||||
u8 max;
|
||||
u8 range;
|
||||
u8 rand;
|
||||
|
||||
// Make sure minimum level is less than maximum level
|
||||
if (wildPokemon->maxLevel >= wildPokemon->minLevel)
|
||||
{
|
||||
min = wildPokemon->minLevel;
|
||||
max = wildPokemon->maxLevel;
|
||||
}
|
||||
else
|
||||
{
|
||||
min = wildPokemon->maxLevel;
|
||||
max = wildPokemon->minLevel;
|
||||
}
|
||||
range = max - min + 1;
|
||||
rand = Random() % range;
|
||||
|
||||
// check ability for max level mon
|
||||
if (!GetMonData(&gPlayerParty[0], MON_DATA_SANITY_BIT3))
|
||||
{
|
||||
u8 ability = GetMonAbility(&gPlayerParty[0]);
|
||||
if (ability == ABILITY_HUSTLE || ability == ABILITY_VITAL_SPIRIT || ability == ABILITY_PRESSURE)
|
||||
{
|
||||
if (Random() % 2 == 0)
|
||||
return max;
|
||||
|
||||
if (rand != 0)
|
||||
rand--;
|
||||
}
|
||||
}
|
||||
|
||||
return min + rand;
|
||||
}
|
||||
|
||||
u16 GetCurrentMapWildMonHeaderId(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_ALTERING_CAVE &&
|
||||
gSaveBlock1Ptr->location.mapNum == MAP_ID_ALTERING_CAVE)
|
||||
{
|
||||
u16 alteringCaveId = VarGet(VAR_ALTERING_CAVE_WILD_SET);
|
||||
if (alteringCaveId > 8)
|
||||
alteringCaveId = 0;
|
||||
|
||||
i += alteringCaveId;
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
u8 PickWildMonNature(void)
|
||||
{
|
||||
u8 i;
|
||||
u8 j;
|
||||
struct Pokeblock *safariPokeblock;
|
||||
u8 natures[25];
|
||||
|
||||
if (GetSafariZoneFlag() == TRUE && Random() % 100 < 80)
|
||||
{
|
||||
safariPokeblock = SafariZoneGetActivePokeblock();
|
||||
if (safariPokeblock != NULL)
|
||||
{
|
||||
for (i = 0; i < 25; i++)
|
||||
natures[i] = i;
|
||||
for (i = 0; i < 24; i++)
|
||||
{
|
||||
for (j = i + 1; j < 25; j++)
|
||||
{
|
||||
if (Random() & 1)
|
||||
{
|
||||
u8 temp = natures[i];
|
||||
|
||||
natures[i] = natures[j];
|
||||
natures[j] = temp;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (i = 0; i < 25; i++)
|
||||
{
|
||||
if (PokeblockGetGain(natures[i], safariPokeblock) > 0)
|
||||
return natures[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
// check synchronize for a pokemon with the same ability
|
||||
if (!GetMonData(&gPlayerParty[0], MON_DATA_SANITY_BIT3)
|
||||
&& GetMonAbility(&gPlayerParty[0]) == ABILITY_SYNCHRONIZE
|
||||
&& Random() % 2 == 0)
|
||||
{
|
||||
return GetMonData(&gPlayerParty[0], MON_DATA_PERSONALITY) % 25;
|
||||
}
|
||||
|
||||
// random nature
|
||||
return Random() % 25;
|
||||
}
|
||||
|
||||
void CreateWildMon(u16 species, u8 level)
|
||||
{
|
||||
bool32 checkCuteCharm;
|
||||
|
||||
ZeroEnemyPartyMons();
|
||||
checkCuteCharm = TRUE;
|
||||
|
||||
switch (gBaseStats[species].genderRatio)
|
||||
{
|
||||
case MON_MALE:
|
||||
case MON_FEMALE:
|
||||
case MON_GENDERLESS:
|
||||
checkCuteCharm = FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
if (checkCuteCharm
|
||||
&& !GetMonData(&gPlayerParty[0], MON_DATA_SANITY_BIT3)
|
||||
&& GetMonAbility(&gPlayerParty[0]) == ABILITY_CUTE_CHARM
|
||||
&& Random() % 3 != 0)
|
||||
{
|
||||
u16 leadingMonSpecies = GetMonData(&gPlayerParty[0], MON_DATA_SPECIES);
|
||||
u32 leadingMonPersonality = GetMonData(&gPlayerParty[0], MON_DATA_PERSONALITY);
|
||||
u8 gender = GetGenderFromSpeciesAndPersonality(leadingMonSpecies, leadingMonPersonality);
|
||||
|
||||
// misses mon is genderless check, although no genderless mon can have cute charm as ability
|
||||
if (gender == MON_FEMALE)
|
||||
gender = MON_MALE;
|
||||
else
|
||||
gender = MON_FEMALE;
|
||||
|
||||
CreateMonWithGenderNatureLetter(&gEnemyParty[0], species, level, 32, gender, PickWildMonNature(), 0);
|
||||
return;
|
||||
}
|
||||
|
||||
CreateMonWithNature(&gEnemyParty[0], species, level, 32, 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
|
||||
|
||||
bool8 TryGenerateWildMon(struct WildPokemonInfo *wildMonInfo, u8 area, u8 flags)
|
||||
{
|
||||
u8 wildMonIndex = 0;
|
||||
u8 level;
|
||||
|
||||
switch (area)
|
||||
{
|
||||
case WILD_AREA_LAND:
|
||||
if (TryGetAbilityInfluencedWildMonIndex(wildMonInfo->wildPokemon, TYPE_STEEL, ABILITY_MAGNET_PULL, &wildMonIndex))
|
||||
break;
|
||||
if (TryGetAbilityInfluencedWildMonIndex(wildMonInfo->wildPokemon, TYPE_ELECTRIC, ABILITY_STATIC, &wildMonIndex))
|
||||
break;
|
||||
|
||||
wildMonIndex = ChooseWildMonIndex_Land();
|
||||
break;
|
||||
case WILD_AREA_WATER:
|
||||
if (TryGetAbilityInfluencedWildMonIndex(wildMonInfo->wildPokemon, TYPE_ELECTRIC, ABILITY_STATIC, &wildMonIndex))
|
||||
break;
|
||||
|
||||
wildMonIndex = ChooseWildMonIndex_WaterRock();
|
||||
break;
|
||||
case WILD_AREA_ROCKS:
|
||||
wildMonIndex = ChooseWildMonIndex_WaterRock();
|
||||
break;
|
||||
}
|
||||
|
||||
level = ChooseWildMonLevel(&wildMonInfo->wildPokemon[wildMonIndex]);
|
||||
if (flags & WILD_CHECK_REPEL && !IsWildLevelAllowedByRepel(level))
|
||||
return FALSE;
|
||||
if (gMapHeader.mapDataId != 0x166 && flags & WILD_CHECK_KEEN_EYE && !IsAbilityAllowingEncounter(level))
|
||||
return FALSE;
|
||||
|
||||
CreateWildMon(wildMonInfo->wildPokemon[wildMonIndex].species, level);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
u16 GenerateFishingWildMon(struct WildPokemonInfo *wildMonInfo, u8 rod)
|
||||
{
|
||||
u8 wildMonIndex = ChooseWildMonIndex_Fishing(rod);
|
||||
u8 level = ChooseWildMonLevel(&wildMonInfo->wildPokemon[wildMonIndex]);
|
||||
|
||||
CreateWildMon(wildMonInfo->wildPokemon[wildMonIndex].species, level);
|
||||
return wildMonInfo->wildPokemon[wildMonIndex].species;
|
||||
}
|
||||
|
||||
bool8 SetUpMassOutbreakEncounter(u8 flags)
|
||||
{
|
||||
u16 i;
|
||||
|
||||
if (flags & WILD_CHECK_REPEL && !IsWildLevelAllowedByRepel(gSaveBlock1Ptr->outbreakPokemonLevel))
|
||||
return FALSE;
|
||||
|
||||
CreateWildMon(gSaveBlock1Ptr->outbreakPokemonSpecies, gSaveBlock1Ptr->outbreakPokemonLevel);
|
||||
for (i = 0; i < 4; i++)
|
||||
SetMonMoveSlot(&gEnemyParty[0], gSaveBlock1Ptr->outbreakPokemonMoves[i], i);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool8 DoMassOutbreakEncounterTest(void)
|
||||
{
|
||||
if (gSaveBlock1Ptr->outbreakPokemonSpecies != 0
|
||||
&& gSaveBlock1Ptr->location.mapNum == gSaveBlock1Ptr->outbreakLocationMapNum
|
||||
&& gSaveBlock1Ptr->location.mapGroup == gSaveBlock1Ptr->outbreakLocationMapGroup)
|
||||
{
|
||||
if (Random() % 100 < gSaveBlock1Ptr->outbreakPokemonProbability)
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
bool8 DoWildEncounterRateDiceRoll(u16 encounterRate)
|
||||
{
|
||||
if (Random() % 2880 < encounterRate)
|
||||
return TRUE;
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
bool8 DoWildEncounterRateTest(u32 encounterRate, bool8 ignoreAbility)
|
||||
{
|
||||
encounterRate *= 16;
|
||||
if (TestPlayerAvatarFlags(PLAYER_AVATAR_FLAG_MACH_BIKE | PLAYER_AVATAR_FLAG_ACRO_BIKE))
|
||||
encounterRate = encounterRate * 80 / 100;
|
||||
ApplyFluteEncounterRateMod(&encounterRate);
|
||||
ApplyCleanseTagEncounterRateMod(&encounterRate);
|
||||
if (!ignoreAbility && !GetMonData(&gPlayerParty[0], MON_DATA_SANITY_BIT3))
|
||||
{
|
||||
u32 ability = GetMonAbility(&gPlayerParty[0]);
|
||||
|
||||
if (ability == ABILITY_STENCH && gMapHeader.mapDataId == 0x169)
|
||||
encounterRate = encounterRate * 3 / 4;
|
||||
else if (ability == ABILITY_STENCH)
|
||||
encounterRate /= 2;
|
||||
else if (ability == ABILITY_ILLUMINATE)
|
||||
encounterRate *= 2;
|
||||
else if (ability == ABILITY_WHITE_SMOKE)
|
||||
encounterRate /= 2;
|
||||
else if (ability == ABILITY_ARENA_TRAP)
|
||||
encounterRate *= 2;
|
||||
else if (ability == ABILITY_SAND_VEIL && gSaveBlock1Ptr->weather == 8)
|
||||
encounterRate /= 2;
|
||||
}
|
||||
if (encounterRate > 2880)
|
||||
encounterRate = 2880;
|
||||
return DoWildEncounterRateDiceRoll(encounterRate);
|
||||
}
|
@ -789,11 +789,7 @@ gUnknown_02038BF9: @ 2038BF9
|
||||
gUnknown_02038BFC: @ 2038BFC
|
||||
.space 0x4
|
||||
|
||||
gUnknown_02038C00: @ 2038C00
|
||||
.space 0x4
|
||||
|
||||
gUnknown_02038C04: @ 2038C04
|
||||
.space 0x4
|
||||
.include "src/wild_encounter.o"
|
||||
|
||||
gFieldEffectArguments: @ 2038C08
|
||||
.space 0x20
|
||||
|
Loading…
Reference in New Issue
Block a user