Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes Synchronize's OW effect and adds configs #3480

Merged
merged 9 commits into from
Oct 29, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion include/config/battle.h
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,6 @@
#define B_SHADOW_TAG_ESCAPE GEN_LATEST // In Gen4+, if both sides have a Pokémon with Shadow Tag, all battlers can escape. Before, neither side could escape this situation.
#define B_MOODY_ACC_EVASION GEN_LATEST // In Gen8, Moody CANNOT raise Accuracy and Evasion anymore.
#define B_FLASH_FIRE_FROZEN GEN_LATEST // In Gen5+, Flash Fire can trigger even when frozen, when it couldn't before.
#define B_SYNCHRONIZE_NATURE GEN_LATEST // In Gen8, if a Pokémon with Synchronize is leading the party, it's 100% guaranteed that wild Pokémon will have the same Nature, as opposed to 50% previously. In Gen9, it has no out-of-battle effect.
#define B_SYNCHRONIZE_TOXIC GEN_LATEST // In Gen5+, if a Pokémon with Synchronize is badly poisoned, the opponent will also become badly poisoned. Previously, the opponent would become regular poisoned.
#define B_UPDATED_INTIMIDATE GEN_LATEST // In Gen8, Intimidate doesn't work on opponents with the Inner Focus, Scrappy, Own Tempo or Oblivious abilities. It also activates Rattled.
#define B_OBLIVIOUS_TAUNT GEN_LATEST // In Gen6+, Pokémon with Oblivious can't be taunted.
Expand Down
14 changes: 14 additions & 0 deletions include/config/overworld.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,20 @@
// PC settings
#define OW_PC_PRESS_B GEN_LATEST // In Gen4, pressing B when holding a Pokémon is equivalent to placing it. In Gen3, it gives the "You're holding a Pokémon!" error.

// Out-of-battle Ability effects
#define OW_SYNCHRONIZE_NATURE GEN_LATEST // In Gen8, if a Pokémon with Synchronize is leading the party, it's 100% guaranteed that wild Pokémon will have the same Nature, as opposed to 50% previously. Stationary Pokémon are excluded in Gen3. In Gen6, all No Eggs Discovered gift Pokémon will have the same Nature, while in Gen7 all gift Pokémon will, regardless of Egg Group - In Gen 8, no gift Pokémon are affected. In Gen9, this ability has no out-of-battle effect.
#define OW_COMPOUND_EYES GEN_LATEST // Prior to Gen9, if a Pokémon with Compound Eyes is leading the party, the wild held item rate is increased to 60%/20%.
#define OW_SUPER_LUCK GEN_LATEST // In Gen8, if a Pokémon with Super Luck is leading the party, the wild held item rate is increased to 60%/20%.
#define OW_CUTE_CHARM GEN_LATEST // Prior to Gen9, if a Pokémon with Cute Charm is leading the party, wild encounters have a 66.7% chance to be forced to be of the opposite gender.
#define OW_ILLUMINATE GEN_LATEST // Prior to Gen9, if a Pokémon with Illuminate is leading the party, the wild encounter rate is doubled.
#define OW_INFILTRATOR GEN_LATEST // In Gen8, if a Pokémon with Infiltrator is leading the party, the wild encounter rate is halved.
#define OW_HARVEST GEN_LATEST // In Gen8, if a Pokémon with Harvest is leading the party, there is a 50% chance to encounter a Grass-type Pokémon.
#define OW_LIGHTNING_ROD GEN_LATEST // In Gen8, if a Pokémon with Lightning Rod is leading the party, there is a 50% chance to encounter an Electric-type Pokémon.
#define OW_STORM_DRAIN GEN_LATEST // In Gen8, if a Pokémon with Storm Drain is leading the party, there is a 50% chance to encounter a Water-type Pokémon.
#define OW_FLASH_FIRE GEN_LATEST // In Gen8, if a Pokémon with Flash Fire is leading the party, there is a 50% chance to encounter a Fire-type Pokémon.
#define OW_MAGNET_PULL GEN_LATEST // Prior to Gen9, if a Pokémon with Magnet Pull is leading the party, there is a 50% chance to encounter a Steel-type Pokémon.
#define OW_STATIC GEN_LATEST // Prior to Gen9, if a Pokémon with Static is leading the party, there is a 50% chance to encounter an Electric-type Pokémon.

// Overworld flags
// To use the following features in scripting, replace the 0s with the flag ID you're assigning it to.
// Eg: Replace with FLAG_UNUSED_0x264 so you can use that flag to toggle the feature.
Expand Down
1 change: 1 addition & 0 deletions include/wild_encounter.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ extern bool8 gIsFishingEncounter;
extern bool8 gIsSurfingEncounter;

void DisableWildEncounters(bool8 disabled);
u8 PickWildMonNature(void);
bool8 StandardWildEncounter(u16 currMetaTileBehavior, u16 previousMetaTileBehavior);
bool8 SweetScentWildEncounter(void);
bool8 DoesCurrentMapHaveFishingMons(void);
Expand Down
26 changes: 15 additions & 11 deletions src/pokemon.c
Original file line number Diff line number Diff line change
Expand Up @@ -8070,29 +8070,33 @@ static s32 GetWildMonTableIdInAlteringCave(u16 species)
return 0;
}

static inline bool32 CanFirstMonBoostHeldItemRarity(void)
{
if (GetMonData(&gPlayerParty[0], MON_DATA_SANITY_IS_EGG))
return FALSE;
else if ((OW_COMPOUND_EYES < GEN_9) && GetMonAbility(&gPlayerParty[0]) == ABILITY_COMPOUND_EYES)
return TRUE;
else if ((OW_SUPER_LUCK == GEN_8) && GetMonAbility(&gPlayerParty[0]) == ABILITY_SUPER_LUCK)
return TRUE;
return FALSE;
}

void SetWildMonHeldItem(void)
{
if (!(gBattleTypeFlags & (BATTLE_TYPE_LEGENDARY | BATTLE_TYPE_TRAINER | BATTLE_TYPE_PYRAMID | BATTLE_TYPE_PIKE)))
{
u16 rnd;
u16 species;
u16 chanceNoItem = 45;
u16 chanceNotRare = 95;
u16 count = (WILD_DOUBLE_BATTLE) ? 2 : 1;
u16 i;

if (!GetMonData(&gPlayerParty[0], MON_DATA_SANITY_IS_EGG, 0)
&& (GetMonAbility(&gPlayerParty[0]) == ABILITY_COMPOUND_EYES
|| GetMonAbility(&gPlayerParty[0]) == ABILITY_SUPER_LUCK))
{
chanceNoItem = 20;
chanceNotRare = 80;
}
bool32 itemHeldBoost = CanFirstMonBoostHeldItemRarity();
u16 chanceNoItem = itemHeldBoost ? 20 : 45;
u16 chanceNotRare = itemHeldBoost ? 80 : 95;

for (i = 0; i < count; i++)
{
if (GetMonData(&gEnemyParty[i], MON_DATA_HELD_ITEM, NULL) != ITEM_NONE)
continue; // prevent ovewriting previously set item
continue; // prevent overwriting previously set item

rnd = Random() % 100;
species = GetMonData(&gEnemyParty[i], MON_DATA_SPECIES, 0);
Expand Down
22 changes: 18 additions & 4 deletions src/script_pokemon_util.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include "sprite.h"
#include "string_util.h"
#include "tv.h"
#include "wild_encounter.h"
#include "constants/items.h"
#include "constants/battle_frontier.h"

Expand Down Expand Up @@ -66,7 +67,11 @@ u8 ScriptGiveMon(u16 species, u8 level, u16 item, u32 unused1, u32 unused2, u8 u
struct Pokemon mon;
u16 targetSpecies;

CreateMon(&mon, species, level, USE_RANDOM_IVS, FALSE, 0, OT_ID_PLAYER_ID, 0);
if (OW_SYNCHRONIZE_NATURE >= GEN_6 && (gSpeciesInfo[species].eggGroups[0] == EGG_GROUP_UNDISCOVERED || OW_SYNCHRONIZE_NATURE == GEN_7))
CreateMonWithNature(&mon, species, level, USE_RANDOM_IVS, PickWildMonNature());
else
CreateMon(&mon, species, level, USE_RANDOM_IVS, FALSE, 0, OT_ID_PLAYER_ID, 0);

heldItem[0] = item;
heldItem[1] = item >> 8;
SetMonData(&mon, MON_DATA_HELD_ITEM, heldItem);
Expand Down Expand Up @@ -149,7 +154,10 @@ void CreateScriptedWildMon(u16 species, u8 level, u16 item)
u8 heldItem[2];

ZeroEnemyPartyMons();
CreateMon(&gEnemyParty[0], species, level, USE_RANDOM_IVS, 0, 0, OT_ID_PLAYER_ID, 0);
if (OW_SYNCHRONIZE_NATURE > GEN_3)
CreateMonWithNature(&gEnemyParty[0], species, level, USE_RANDOM_IVS, PickWildMonNature());
else
CreateMon(&gEnemyParty[0], species, level, USE_RANDOM_IVS, 0, 0, OT_ID_PLAYER_ID, 0);
if (item)
{
heldItem[0] = item;
Expand All @@ -164,15 +172,21 @@ void CreateScriptedDoubleWildMon(u16 species1, u8 level1, u16 item1, u16 species

ZeroEnemyPartyMons();

CreateMon(&gEnemyParty[0], species1, level1, 32, 0, 0, OT_ID_PLAYER_ID, 0);
if (OW_SYNCHRONIZE_NATURE > GEN_3)
CreateMonWithNature(&gEnemyParty[0], species1, level1, 32, PickWildMonNature());
else
CreateMon(&gEnemyParty[0], species1, level1, 32, 0, 0, OT_ID_PLAYER_ID, 0);
if (item1)
{
heldItem1[0] = item1;
heldItem1[1] = item1 >> 8;
SetMonData(&gEnemyParty[0], MON_DATA_HELD_ITEM, heldItem1);
}

CreateMon(&gEnemyParty[1], species2, level2, 32, 0, 0, OT_ID_PLAYER_ID, 0);
if (OW_SYNCHRONIZE_NATURE > GEN_3)
CreateMonWithNature(&gEnemyParty[1], species2, level2, 32, PickWildMonNature());
else
CreateMon(&gEnemyParty[1], species2, level2, 32, 0, 0, OT_ID_PLAYER_ID, 0);
if (item2)
{
heldItem2[0] = item2;
Expand Down
41 changes: 20 additions & 21 deletions src/wild_encounter.c
Original file line number Diff line number Diff line change
Expand Up @@ -383,7 +383,7 @@ static u16 GetCurrentMapWildMonHeaderId(void)
return HEADER_NONE;
}

static u8 PickWildMonNature(void)
u8 PickWildMonNature(void)
{
u8 i;
u8 j;
Expand Down Expand Up @@ -415,15 +415,14 @@ static u8 PickWildMonNature(void)
}
}
}
#if B_SYNCHRONIZE_NATURE < GEN_9
// check synchronize for a pokemon with the same ability
if (!GetMonData(&gPlayerParty[0], MON_DATA_SANITY_IS_EGG)
if (OW_SYNCHRONIZE_NATURE < GEN_9
&& !GetMonData(&gPlayerParty[0], MON_DATA_SANITY_IS_EGG)
&& GetMonAbility(&gPlayerParty[0]) == ABILITY_SYNCHRONIZE
&& (B_SYNCHRONIZE_NATURE >= GEN_8 || Random() % 2 == 0))
&& (OW_SYNCHRONIZE_NATURE == GEN_8 || Random() % 2 == 0))
{
return GetMonData(&gPlayerParty[0], MON_DATA_PERSONALITY) % NUM_NATURES;
}
#endif

// random nature
return Random() % NUM_NATURES;
Expand All @@ -434,7 +433,7 @@ static void CreateWildMon(u16 species, u8 level)
bool32 checkCuteCharm;

ZeroEnemyPartyMons();
checkCuteCharm = TRUE;
checkCuteCharm = OW_CUTE_CHARM < GEN_9;

switch (gSpeciesInfo[species].genderRatio)
{
Expand Down Expand Up @@ -480,33 +479,33 @@ static bool8 TryGenerateWildMon(const struct WildPokemonInfo *wildMonInfo, u8 ar
switch (area)
{
case WILD_AREA_LAND:
if (TRY_GET_ABILITY_INFLUENCED_WILD_MON_INDEX(wildMonInfo->wildPokemon, TYPE_STEEL, ABILITY_MAGNET_PULL, &wildMonIndex, LAND_WILD_COUNT))
if (OW_MAGNET_PULL < GEN_9 && TRY_GET_ABILITY_INFLUENCED_WILD_MON_INDEX(wildMonInfo->wildPokemon, TYPE_STEEL, ABILITY_MAGNET_PULL, &wildMonIndex, LAND_WILD_COUNT))
break;
if (TRY_GET_ABILITY_INFLUENCED_WILD_MON_INDEX(wildMonInfo->wildPokemon, TYPE_ELECTRIC, ABILITY_STATIC, &wildMonIndex, LAND_WILD_COUNT))
if (OW_STATIC < GEN_9 && TRY_GET_ABILITY_INFLUENCED_WILD_MON_INDEX(wildMonInfo->wildPokemon, TYPE_ELECTRIC, ABILITY_STATIC, &wildMonIndex, LAND_WILD_COUNT))
break;
if (TRY_GET_ABILITY_INFLUENCED_WILD_MON_INDEX(wildMonInfo->wildPokemon, TYPE_ELECTRIC, ABILITY_LIGHTNING_ROD, &wildMonIndex, LAND_WILD_COUNT))
if (OW_LIGHTNING_ROD == GEN_8 && TRY_GET_ABILITY_INFLUENCED_WILD_MON_INDEX(wildMonInfo->wildPokemon, TYPE_ELECTRIC, ABILITY_LIGHTNING_ROD, &wildMonIndex, LAND_WILD_COUNT))
break;
if (TRY_GET_ABILITY_INFLUENCED_WILD_MON_INDEX(wildMonInfo->wildPokemon, TYPE_FIRE, ABILITY_FLASH_FIRE, &wildMonIndex, LAND_WILD_COUNT))
if (OW_FLASH_FIRE == GEN_8 && TRY_GET_ABILITY_INFLUENCED_WILD_MON_INDEX(wildMonInfo->wildPokemon, TYPE_FIRE, ABILITY_FLASH_FIRE, &wildMonIndex, LAND_WILD_COUNT))
break;
if (TRY_GET_ABILITY_INFLUENCED_WILD_MON_INDEX(wildMonInfo->wildPokemon, TYPE_GRASS, ABILITY_HARVEST, &wildMonIndex, LAND_WILD_COUNT))
if (OW_HARVEST == GEN_8 && TRY_GET_ABILITY_INFLUENCED_WILD_MON_INDEX(wildMonInfo->wildPokemon, TYPE_GRASS, ABILITY_HARVEST, &wildMonIndex, LAND_WILD_COUNT))
break;
if (TRY_GET_ABILITY_INFLUENCED_WILD_MON_INDEX(wildMonInfo->wildPokemon, TYPE_WATER, ABILITY_STORM_DRAIN, &wildMonIndex, LAND_WILD_COUNT))
if (OW_STORM_DRAIN == GEN_8 && TRY_GET_ABILITY_INFLUENCED_WILD_MON_INDEX(wildMonInfo->wildPokemon, TYPE_WATER, ABILITY_STORM_DRAIN, &wildMonIndex, LAND_WILD_COUNT))
break;

wildMonIndex = ChooseWildMonIndex_Land();
break;
case WILD_AREA_WATER:
if (TRY_GET_ABILITY_INFLUENCED_WILD_MON_INDEX(wildMonInfo->wildPokemon, TYPE_STEEL, ABILITY_MAGNET_PULL, &wildMonIndex, WATER_WILD_COUNT))
if (OW_MAGNET_PULL < GEN_9 && TRY_GET_ABILITY_INFLUENCED_WILD_MON_INDEX(wildMonInfo->wildPokemon, TYPE_STEEL, ABILITY_MAGNET_PULL, &wildMonIndex, WATER_WILD_COUNT))
break;
if (TRY_GET_ABILITY_INFLUENCED_WILD_MON_INDEX(wildMonInfo->wildPokemon, TYPE_ELECTRIC, ABILITY_STATIC, &wildMonIndex, WATER_WILD_COUNT))
if (OW_STATIC < GEN_9 && TRY_GET_ABILITY_INFLUENCED_WILD_MON_INDEX(wildMonInfo->wildPokemon, TYPE_ELECTRIC, ABILITY_STATIC, &wildMonIndex, WATER_WILD_COUNT))
break;
if (TRY_GET_ABILITY_INFLUENCED_WILD_MON_INDEX(wildMonInfo->wildPokemon, TYPE_ELECTRIC, ABILITY_LIGHTNING_ROD, &wildMonIndex, WATER_WILD_COUNT))
if (OW_LIGHTNING_ROD == GEN_8 && TRY_GET_ABILITY_INFLUENCED_WILD_MON_INDEX(wildMonInfo->wildPokemon, TYPE_ELECTRIC, ABILITY_LIGHTNING_ROD, &wildMonIndex, WATER_WILD_COUNT))
break;
if (TRY_GET_ABILITY_INFLUENCED_WILD_MON_INDEX(wildMonInfo->wildPokemon, TYPE_FIRE, ABILITY_FLASH_FIRE, &wildMonIndex, WATER_WILD_COUNT))
if (OW_FLASH_FIRE == GEN_8 && TRY_GET_ABILITY_INFLUENCED_WILD_MON_INDEX(wildMonInfo->wildPokemon, TYPE_FIRE, ABILITY_FLASH_FIRE, &wildMonIndex, WATER_WILD_COUNT))
break;
if (TRY_GET_ABILITY_INFLUENCED_WILD_MON_INDEX(wildMonInfo->wildPokemon, TYPE_GRASS, ABILITY_HARVEST, &wildMonIndex, WATER_WILD_COUNT))
if (OW_HARVEST == GEN_8 && TRY_GET_ABILITY_INFLUENCED_WILD_MON_INDEX(wildMonInfo->wildPokemon, TYPE_GRASS, ABILITY_HARVEST, &wildMonIndex, WATER_WILD_COUNT))
break;
if (TRY_GET_ABILITY_INFLUENCED_WILD_MON_INDEX(wildMonInfo->wildPokemon, TYPE_WATER, ABILITY_STORM_DRAIN, &wildMonIndex, WATER_WILD_COUNT))
if (OW_STORM_DRAIN == GEN_8 && TRY_GET_ABILITY_INFLUENCED_WILD_MON_INDEX(wildMonInfo->wildPokemon, TYPE_WATER, ABILITY_STORM_DRAIN, &wildMonIndex, WATER_WILD_COUNT))
break;

wildMonIndex = ChooseWildMonIndex_WaterRock();
Expand Down Expand Up @@ -587,7 +586,7 @@ static bool8 WildEncounterCheck(u32 encounterRate, bool8 ignoreAbility)
encounterRate = encounterRate * 3 / 4;
else if (ability == ABILITY_STENCH)
encounterRate /= 2;
else if (ability == ABILITY_ILLUMINATE)
else if (ability == ABILITY_ILLUMINATE && OW_ILLUMINATE < GEN_9)
encounterRate *= 2;
else if (ability == ABILITY_WHITE_SMOKE)
encounterRate /= 2;
Expand All @@ -599,10 +598,10 @@ static bool8 WildEncounterCheck(u32 encounterRate, bool8 ignoreAbility)
encounterRate /= 2;
else if (ability == ABILITY_QUICK_FEET)
encounterRate /= 2;
else if (ability == ABILITY_INFILTRATOR)
else if (ability == ABILITY_INFILTRATOR && OW_INFILTRATOR == GEN_8)
encounterRate /= 2;
else if (ability == ABILITY_NO_GUARD)
encounterRate = encounterRate * 3 / 2;
encounterRate *= 2;
}
if (encounterRate > MAX_ENCOUNTER_RATE)
encounterRate = MAX_ENCOUNTER_RATE;
Expand Down
Loading