From 1e6bb4f47cdf5ae978e17d1297f889d44f1d5502 Mon Sep 17 00:00:00 2001 From: FosterProgramming Date: Fri, 22 Aug 2025 20:23:18 +0200 Subject: [PATCH] Fix overlap between spin evolution and script evolution (#7593) --- asm/macros/event.inc | 2 +- include/constants/pokemon.h | 1 + src/pokemon.c | 49 ++++++++++++++++++++++++++++++++++++- 3 files changed, 50 insertions(+), 2 deletions(-) diff --git a/asm/macros/event.inc b/asm/macros/event.inc index 3bc6516097..da6d64edd4 100644 --- a/asm/macros/event.inc +++ b/asm/macros/event.inc @@ -2175,7 +2175,7 @@ setvar VAR_0x8000, \evoMethod setvar VAR_0x8001, \canStopEvo setvar VAR_0x8002, \tryMultiple - special TrySpecialOverworldEvo + special TrySpecialScriptEvolution .endm .macro ai_vs_ai_battle trainer1:req, trainer2:req diff --git a/include/constants/pokemon.h b/include/constants/pokemon.h index af01007cd2..20cff8a30f 100644 --- a/include/constants/pokemon.h +++ b/include/constants/pokemon.h @@ -322,6 +322,7 @@ enum EvolutionMode { EVO_MODE_ITEM_CHECK, // If an Everstone is being held, still want to show that the stone *could* be used on that Pokémon to evolve EVO_MODE_BATTLE_SPECIAL, EVO_MODE_OVERWORLD_SPECIAL, + EVO_MODE_SCRIPT_TRIGGER, EVO_MODE_BATTLE_ONLY, // This mode is only used in battles to support Tandemaus' unique requirement }; diff --git a/src/pokemon.c b/src/pokemon.c index 62abadca7c..b76683254e 100644 --- a/src/pokemon.c +++ b/src/pokemon.c @@ -4896,7 +4896,6 @@ u32 GetEvolutionTargetSpecies(struct Pokemon *mon, enum EvolutionMode mode, u16 switch (evolutions[i].method) { - case EVO_SCRIPT_TRIGGER: case EVO_SPIN: if (gSpecialVar_0x8000 == evolutions[i].param) conditionsMet = TRUE; @@ -4914,6 +4913,23 @@ u32 GetEvolutionTargetSpecies(struct Pokemon *mon, enum EvolutionMode mode, u16 } } break; + case EVO_MODE_SCRIPT_TRIGGER: + for (i = 0; evolutions[i].method != EVOLUTIONS_END; i++) + { + if (SanitizeSpeciesId(evolutions[i].targetSpecies) == SPECIES_NONE) + continue; + if (evolutions[i].method != EVO_SCRIPT_TRIGGER) + continue; + if (DoesMonMeetAdditionalConditions(mon, evolutions[i].params, NULL, PARTY_SIZE, canStopEvo, evoState)) + { + // All checks passed, so stop checking the rest of the evolutions. + // This is different from vanilla where the loop continues. + // If you have overlapping evolutions, put the ones you want to happen first on top of the list. + targetSpecies = evolutions[i].targetSpecies; + break; + } + } + break; } // Pikachu, Meowth, Eevee and Duraludon cannot evolve if they have the @@ -6760,6 +6776,37 @@ void RemoveIVIndexFromList(u8 *ivs, u8 selectedIv) } // Attempts to perform non-level/item related overworld evolutions; called by tryspecialevo command. +void TryScriptEvolution(void) +{ + u8 i; + bool32 canStopEvo = gSpecialVar_0x8001; + u16 tryMultiple = gSpecialVar_0x8002; + + for (i = 0; i < PARTY_SIZE; i++) + { + u32 targetSpecies = GetEvolutionTargetSpecies(&gPlayerParty[i], EVO_MODE_SCRIPT_TRIGGER, 0, NULL, &canStopEvo, CHECK_EVO); + + if (targetSpecies != SPECIES_NONE && !(sTriedEvolving & (1u << i))) + { + GetEvolutionTargetSpecies(&gPlayerParty[i], EVO_MODE_SCRIPT_TRIGGER, 0, NULL, &canStopEvo, DO_EVO); + sTriedEvolving |= 1u << i; + if(gMain.callback2 == TryScriptEvolution) // This fixes small graphics glitches. + EvolutionScene(&gPlayerParty[i], targetSpecies, canStopEvo, i); + else + BeginEvolutionScene(&gPlayerParty[i], targetSpecies, canStopEvo, i); + + if (tryMultiple) + gCB2_AfterEvolution = TryScriptEvolution; + else + gCB2_AfterEvolution = CB2_ReturnToField; + return; + } + } + + sTriedEvolving = 0; + SetMainCallback2(CB2_ReturnToField); +} + void TrySpecialOverworldEvo(void) { u8 i;