Fix fusion pokemon aquiring illegal movesets (#7896)

This commit is contained in:
FosterProgramming 2025-10-09 15:26:26 +02:00 committed by GitHub
parent 5b5b813c1d
commit 41751451f6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 151 additions and 20 deletions

View File

@ -631,6 +631,13 @@ struct FormChange
u16 param3;
};
enum FusionExtraMoveHandling
{
FORGET_EXTRA_MOVES,
SWAP_EXTRA_MOVES_KYUREM_WHITE,
SWAP_EXTRA_MOVES_KYUREM_BLACK
};
struct Fusion
{
u16 fusionStorageIndex;
@ -639,11 +646,22 @@ struct Fusion
u16 targetSpecies2;
u16 fusingIntoMon;
u16 fusionMove;
u16 unfuseForgetMove;
enum FusionExtraMoveHandling extraMoveHandling;
};
extern const struct Fusion *const gFusionTablePointers[NUM_SPECIES];
#if P_FUSION_FORMS
#if P_FAMILY_KYUREM
#if P_FAMILY_RESHIRAM
extern const u16 gKyurenWhiteSwapMoveTable[][2];
#endif //P_FAMILY_RESHIRAM
#if P_FAMILY_ZEKROM
extern const u16 gKyurenBlackSwapMoveTable[][2];
#endif //P_FAMILY_ZEKROM
#endif //P_FAMILY_KYUREM
#endif //P_FUSION_FORMS
#define NUM_UNOWN_FORMS 28
#define GET_UNOWN_LETTER(personality) (( \

View File

@ -34,3 +34,22 @@ const struct Fusion *const gFusionTablePointers[NUM_SPECIES] =
#endif //P_FAMILY_CALYREX
#endif //P_FUSION_FORMS
};
#if P_FUSION_FORMS
#if P_FAMILY_KYUREM
#if P_FAMILY_RESHIRAM
const u16 gKyurenWhiteSwapMoveTable[][2] =
{
{MOVE_SCARY_FACE, MOVE_FUSION_FLARE},
{MOVE_GLACIATE, MOVE_ICE_BURN},
};
#endif //P_FAMILY_RESHIRAM
#if P_FAMILY_ZEKROM
const u16 gKyurenBlackSwapMoveTable[][2] =
{
{MOVE_SCARY_FACE, MOVE_FUSION_BOLT},
{MOVE_GLACIATE, MOVE_FREEZE_SHOCK},
};
#endif //P_FAMILY_ZEKROM
#endif //P_FAMILY_KYUREM
#endif //P_FUSION_FORMS

View File

@ -755,8 +755,8 @@ static const struct FormChange sLandorusFormChangeTable[] = {
#if P_FAMILY_KYUREM
static const struct Fusion sKyuremFusionTable[] = {
{0, ITEM_DNA_SPLICERS, SPECIES_KYUREM, SPECIES_RESHIRAM, SPECIES_KYUREM_WHITE},
{0, ITEM_DNA_SPLICERS, SPECIES_KYUREM, SPECIES_ZEKROM, SPECIES_KYUREM_BLACK},
{0, ITEM_DNA_SPLICERS, SPECIES_KYUREM, SPECIES_RESHIRAM, SPECIES_KYUREM_WHITE, MOVE_NONE, SWAP_EXTRA_MOVES_KYUREM_WHITE},
{0, ITEM_DNA_SPLICERS, SPECIES_KYUREM, SPECIES_ZEKROM, SPECIES_KYUREM_BLACK, MOVE_NONE, SWAP_EXTRA_MOVES_KYUREM_BLACK},
{FUSION_TERMINATOR},
};
#endif //P_FAMILY_KYUREM
@ -998,8 +998,8 @@ static const struct FormChange sMimikyuTotemFormChangeTable[] = {
#if P_FAMILY_NECROZMA
static const struct Fusion sNecrozmaFusionTable[] = {
{1, ITEM_N_SOLARIZER, SPECIES_NECROZMA, SPECIES_SOLGALEO, SPECIES_NECROZMA_DUSK_MANE, MOVE_SUNSTEEL_STRIKE, MOVE_CONFUSION},
{2, ITEM_N_LUNARIZER, SPECIES_NECROZMA, SPECIES_LUNALA, SPECIES_NECROZMA_DAWN_WINGS, MOVE_MOONGEIST_BEAM, MOVE_CONFUSION},
{1, ITEM_N_SOLARIZER, SPECIES_NECROZMA, SPECIES_SOLGALEO, SPECIES_NECROZMA_DUSK_MANE, MOVE_SUNSTEEL_STRIKE, FORGET_EXTRA_MOVES},
{2, ITEM_N_LUNARIZER, SPECIES_NECROZMA, SPECIES_LUNALA, SPECIES_NECROZMA_DAWN_WINGS, MOVE_MOONGEIST_BEAM, FORGET_EXTRA_MOVES},
{FUSION_TERMINATOR},
};
@ -1266,8 +1266,8 @@ static const struct FormChange sUrshifuRapidStrikeFormChangeTable[] = {
#if P_FAMILY_CALYREX
static const struct Fusion sCalyrexFusionTable[] = {
{3, ITEM_REINS_OF_UNITY, SPECIES_CALYREX, SPECIES_GLASTRIER, SPECIES_CALYREX_ICE, MOVE_GLACIAL_LANCE, MOVE_CONFUSION},
{3, ITEM_REINS_OF_UNITY, SPECIES_CALYREX, SPECIES_SPECTRIER, SPECIES_CALYREX_SHADOW, MOVE_ASTRAL_BARRAGE, MOVE_CONFUSION},
{3, ITEM_REINS_OF_UNITY, SPECIES_CALYREX, SPECIES_GLASTRIER, SPECIES_CALYREX_ICE, MOVE_GLACIAL_LANCE, FORGET_EXTRA_MOVES},
{3, ITEM_REINS_OF_UNITY, SPECIES_CALYREX, SPECIES_SPECTRIER, SPECIES_CALYREX_SHADOW, MOVE_ASTRAL_BARRAGE, FORGET_EXTRA_MOVES},
{FUSION_TERMINATOR},
};
#endif //P_FAMILY_CALYREX

View File

@ -6113,13 +6113,14 @@ void ItemUseCB_EvolutionStone(u8 taskId, TaskFunc task)
#define tAnimWait data[2]
#define tNextFunc 3
#define fusionType data[7]
#define firstFusion data[8]
#define firstFusionSlot data[9]
#define fusionResult data[10]
#define secondFusionSlot data[11]
#define unfuseSecondMon data[12]
#define moveToLearn data[13]
#define fusionType data[6]
#define firstFusion data[7]
#define firstFusionSlot data[8]
#define fusionResult data[9]
#define secondFusionSlot data[10]
#define unfuseSecondMon data[11]
#define moveToLearn data[12]
#define tExtraMoveHandling data[13]
#define forgetMove data[14]
#define storageIndex data[15]
@ -6254,6 +6255,75 @@ static void RestoreFusionMon(struct Pokemon *mon)
}
}
static void DeleteInvalidFusionMoves(struct Pokemon *mon, u32 species)
{
for (u32 i = 0; i < MAX_MON_MOVES; i++)
{
u32 move = GetMonData(mon, MON_DATA_MOVE1 + i);
bool32 toDelete = TRUE;
const struct LevelUpMove *learnset = GetSpeciesLevelUpLearnset(species);
for (u32 j = 0; learnset[j].move != LEVEL_UP_MOVE_END;j++)
{
if (learnset[j].move == move)
{
toDelete = FALSE;
break;
}
}
if (!toDelete)
continue;
const u16 *learnset2 = GetSpeciesTeachableLearnset(species);
for (u32 j = 0; learnset2[j] != MOVE_UNAVAILABLE;j++)
{
if (learnset2[j] == move)
{
toDelete = FALSE;
break;
}
}
if (!toDelete)
continue;
const u16 *learnset3 = GetSpeciesEggMoves(species);
for (u32 j = 0; learnset3[j] != MOVE_UNAVAILABLE;j++)
{
if (learnset3[j] == move)
{
toDelete = FALSE;
break;
}
}
if (toDelete)
DeleteMove(mon, move);
}
}
static void SwapFusionMonMoves(struct Pokemon *mon, const u16 moveTable[][2], u32 mode)
{
u32 oldMoveIndex, newMoveIndex;
if (mode == FUSE_MON)
{
oldMoveIndex = 0;
newMoveIndex = 1;
}
else //mode == UNFUSE_MON
{
oldMoveIndex = 1;
newMoveIndex = 0;
}
for (u32 i = 0; i < MAX_MON_MOVES; i++)
{
u32 move = GetMonData(mon, MON_DATA_MOVE1 + i);
for (u32 j = 0; j < 2; j++)
{
if (move == moveTable[j][oldMoveIndex])
{
SetMonData(mon, MON_DATA_MOVE1 + i, &moveTable[j][newMoveIndex]);
SetMonData(mon, MON_DATA_PP1 + i, &gMovesInfo[moveTable[j][newMoveIndex]].pp);
}
}
}
}
static void Task_TryItemUseFusionChange(u8 taskId)
{
struct Pokemon *mon = &gPlayerParty[gTasks[taskId].firstFusionSlot];
@ -6345,15 +6415,38 @@ static void Task_TryItemUseFusionChange(u8 taskId)
case 6:
if (!IsPartyMenuTextPrinterActive())
{
if (gTasks[taskId].moveToLearn != 0)
if (gTasks[taskId].fusionType == FUSE_MON)
{
if (gTasks[taskId].fusionType == FUSE_MON)
#if P_FAMILY_KYUREM
#if P_FAMILY_RESHIRAM
if (gTasks[taskId].tExtraMoveHandling == SWAP_EXTRA_MOVES_KYUREM_WHITE)
SwapFusionMonMoves(mon, gKyurenWhiteSwapMoveTable, FUSE_MON);
#endif //P_FAMILY_RESHIRAM
#if P_FAMILY_ZEKROM
if (gTasks[taskId].tExtraMoveHandling == SWAP_EXTRA_MOVES_KYUREM_BLACK)
SwapFusionMonMoves(mon, gKyurenBlackSwapMoveTable, FUSE_MON);
#endif //P_FAMILY_ZEKROM
#endif //P_FAMILY_KYUREM
if (gTasks[taskId].moveToLearn != 0)
FormChangeTeachMove(taskId, gTasks[taskId].moveToLearn, gTasks[taskId].firstFusionSlot);
else
}
else //(gTasks[taskId].fusionType == UNFUSE_MON)
{
#if P_FAMILY_KYUREM
#if P_FAMILY_RESHIRAM
if (gTasks[taskId].tExtraMoveHandling == SWAP_EXTRA_MOVES_KYUREM_WHITE)
SwapFusionMonMoves(mon, gKyurenWhiteSwapMoveTable, UNFUSE_MON);
#endif //P_FAMILY_RESHIRAM
#if P_FAMILY_ZEKROM
if (gTasks[taskId].tExtraMoveHandling == SWAP_EXTRA_MOVES_KYUREM_BLACK)
SwapFusionMonMoves(mon, gKyurenBlackSwapMoveTable, UNFUSE_MON);
#endif //P_FAMILY_ZEKROM
#endif //P_FAMILY_KYUREM
if ( gTasks[taskId].tExtraMoveHandling == FORGET_EXTRA_MOVES)
{
DeleteMove(mon, gTasks[taskId].forgetMove);
DeleteInvalidFusionMoves(mon, gTasks[taskId].fusionResult);
if (!DoesMonHaveAnyMoves(mon))
FormChangeTeachMove(taskId, gTasks[taskId].moveToLearn, gTasks[taskId].firstFusionSlot);
FormChangeTeachMove(taskId, MOVE_CONFUSION, gTasks[taskId].firstFusionSlot);
}
}
gTasks[taskId].tState++;
@ -6400,7 +6493,7 @@ void ItemUseCB_Fusion(u8 taskId, TaskFunc taskFunc)
task->storageIndex = itemFusion[i].fusionStorageIndex;
task->fusionResult = itemFusion[i].targetSpecies1;
task->unfuseSecondMon = itemFusion[i].targetSpecies2;
task->moveToLearn = itemFusion[i].unfuseForgetMove;
task->tExtraMoveHandling = itemFusion[i].extraMoveHandling;
task->forgetMove = itemFusion[i].fusionMove;
TryItemUseFusionChange(taskId, taskFunc);
return;
@ -6440,6 +6533,7 @@ void ItemUseCB_Fusion(u8 taskId, TaskFunc taskFunc)
task->fusionResult = itemFusion[i].fusingIntoMon;
task->secondFusionSlot = gPartyMenu.slotId;
task->moveToLearn = itemFusion[i].fusionMove;
task->tExtraMoveHandling = itemFusion[i].extraMoveHandling;
// Start Fusion
TryItemUseFusionChange(taskId, taskFunc);
return;