-Removed the pointless param1 setting in sXerneasFormChangeTable
-Updated the descriptions of Behemoth Blade and Behemoth Bash
-Added a new parameter to the struct FormChange
-Allowed FORM_BATTLE_BEGIN and FORM_BATTLE_END to replace a move through a new function called "TryToSetBattleFormChangeMoves".
-Added missing calls to "CalculateMonStats".
-Renamed BoxPokemon pointer in GetFormChangeTargetSpeciesBoxMon for consistency's sake
-Optimized check inside UndoFormChange (even though the plan is to get rid of that func entirely.)

Special thanks to Blecoutre who fixed my TryToSetBattleFormChangeMoves function. It just wasn't working correctly at all.
This commit is contained in:
LOuroboros 2022-09-01 14:57:58 -03:00
parent df88317a98
commit bb290d5ab0
6 changed files with 83 additions and 31 deletions

View File

@ -366,11 +366,13 @@ struct Evolution
u16 targetSpecies;
};
struct FormChange {
struct FormChange
{
u16 method;
u16 targetSpecies;
u16 param1;
u16 param2;
u16 param3;
};
#define NUM_UNOWN_FORMS 28
@ -559,5 +561,6 @@ u16 GetFormChangeTargetSpecies(struct Pokemon *mon, u16 method, u32 arg);
u16 GetFormChangeTargetSpeciesBoxMon(struct BoxPokemon *mon, u16 method, u32 arg);
u16 MonTryLearningNewMoveEvolution(struct Pokemon *mon, bool8 firstMove);
bool32 ShouldShowFemaleDifferences(u16 species, u32 personality);
void TryToSetBattleFormChangeMoves(struct Pokemon *mon);
#endif // GUARD_POKEMON_H

View File

@ -578,11 +578,19 @@ static void CB2_InitBattleInternal(void)
// Player's side
targetSpecies = GetFormChangeTargetSpecies(&gPlayerParty[i], FORM_BATTLE_BEGIN, 0);
if (targetSpecies != SPECIES_NONE)
{
SetMonData(&gPlayerParty[i], MON_DATA_SPECIES, &targetSpecies);
CalculateMonStats(&gPlayerParty[i]);
TryToSetBattleFormChangeMoves(&gPlayerParty[i]);
}
// Opponent's side
targetSpecies = GetFormChangeTargetSpecies(&gEnemyParty[i], FORM_BATTLE_BEGIN, 0);
if (targetSpecies != SPECIES_NONE)
{
SetMonData(&gEnemyParty[i], MON_DATA_SPECIES, &targetSpecies);
CalculateMonStats(&gEnemyParty[i]);
TryToSetBattleFormChangeMoves(&gEnemyParty[i]);
}
}
gBattleCommunication[MULTIUSE_STATE] = 0;

View File

@ -9624,17 +9624,12 @@ void UndoFormChange(u32 monId, u32 side, bool32 isSwitchingOut)
}
if (!isSwitchingOut)
{
// Apply party-wide end-of-battle form changes
for (i = 0; i < PARTY_SIZE; i++)
targetSpecies = GetFormChangeTargetSpecies(&party[monId], FORM_BATTLE_END, 0);
if (targetSpecies != SPECIES_NONE)
{
// Player's side
targetSpecies = GetFormChangeTargetSpecies(&gPlayerParty[i], FORM_BATTLE_END, 0);
if (targetSpecies != SPECIES_NONE)
SetMonData(&gPlayerParty[i], MON_DATA_SPECIES, &targetSpecies);
// Opponent's side
targetSpecies = GetFormChangeTargetSpecies(&gEnemyParty[i], FORM_BATTLE_END, 0);
if (targetSpecies != SPECIES_NONE)
SetMonData(&gEnemyParty[i], MON_DATA_SPECIES, &targetSpecies);
SetMonData(&party[monId], MON_DATA_SPECIES, &targetSpecies);
CalculateMonStats(&party[monId]);
TryToSetBattleFormChangeMoves(&party[monId]);
}
}
}

View File

@ -37,10 +37,14 @@ FORM_ITEM_USE_TIME:
FORM_BATTLE_BEGIN:
Form change activates when the Pokémon is sent out at the beginning of a battle
param1 = item to hold, optional
param2 = a move that will be replaced, optional
param3 = a new move to replace it with, optional
FORM_BATTLE_END:
Form change activates at the end of a battle
param1 = item to hold, optional
param2 = a move that will be replaced, optional
param3 = a new move to replace it with, optional
*/
// FORM_MOVE param2 Arguments
@ -194,20 +198,20 @@ static const struct FormChange sSilvallyFormChangeTable[] = {
#endif
static const struct FormChange sXerneasFormChangeTable[] = {
{FORM_BATTLE_BEGIN, SPECIES_XERNEAS_ACTIVE, ITEM_NONE},
{FORM_BATTLE_END, SPECIES_XERNEAS, ITEM_NONE},
{FORM_BATTLE_BEGIN, SPECIES_XERNEAS_ACTIVE},
{FORM_BATTLE_END, SPECIES_XERNEAS, },
{FORM_CHANGE_END},
};
static const struct FormChange sZacianFormChangeTable[] = {
{FORM_BATTLE_BEGIN, SPECIES_ZACIAN_CROWNED_SWORD, ITEM_RUSTED_SWORD},
{FORM_BATTLE_END, SPECIES_ZACIAN, ITEM_RUSTED_SWORD},
{FORM_BATTLE_BEGIN, SPECIES_ZACIAN_CROWNED_SWORD, ITEM_RUSTED_SWORD, MOVE_IRON_HEAD, MOVE_BEHEMOTH_BLADE},
{FORM_BATTLE_END, SPECIES_ZACIAN, ITEM_RUSTED_SWORD, MOVE_BEHEMOTH_BLADE, MOVE_IRON_HEAD},
{FORM_CHANGE_END},
};
static const struct FormChange sZamazentaFormChangeTable[] = {
{FORM_BATTLE_BEGIN, SPECIES_ZAMAZENTA_CROWNED_SHIELD, ITEM_RUSTED_SHIELD},
{FORM_BATTLE_END, SPECIES_ZAMAZENTA, ITEM_RUSTED_SHIELD},
{FORM_BATTLE_BEGIN, SPECIES_ZAMAZENTA_CROWNED_SHIELD, ITEM_RUSTED_SHIELD, MOVE_IRON_HEAD, MOVE_BEHEMOTH_BASH},
{FORM_BATTLE_END, SPECIES_ZAMAZENTA, ITEM_RUSTED_SHIELD, MOVE_BEHEMOTH_BASH, MOVE_IRON_HEAD},
{FORM_CHANGE_END},
};

View File

@ -2791,12 +2791,12 @@ static const u8 sPyroBallDescription[] = _(
"target. It may cause a burn.");
static const u8 sBehemothBladeDescription[] = _(
"Strikes as a sword. It deals\n"
"2x damage to Dynamaxed foes.");
"Strikes as a sword. Deals 2x\n"
"damage to Dynamaxed foes.");
static const u8 sBehemothBashDescription[] = _(
"Attacks as a shield. Deals\n"
"2x damage to Dynamaxed foes.");
"Attacks as a shield. Deals 2x\n"
"damage to Dynamaxed foes.");
static const u8 sAuraWheelDescription[] = _(
"Raises Speed to attack. The\n"

View File

@ -8243,19 +8243,19 @@ u16 GetFormChangeTargetSpecies(struct Pokemon *mon, u16 method, u32 arg)
}
// Returns SPECIES_NONE if no form change is possible
u16 GetFormChangeTargetSpeciesBoxMon(struct BoxPokemon *mon, u16 method, u32 arg)
u16 GetFormChangeTargetSpeciesBoxMon(struct BoxPokemon *boxMon, u16 method, u32 arg)
{
u32 i;
u32 i, j;
u16 targetSpecies = SPECIES_NONE;
u16 species = GetBoxMonData(mon, MON_DATA_SPECIES, NULL);
u16 species = GetBoxMonData(boxMon, MON_DATA_SPECIES, NULL);
const struct FormChange *formChanges = gFormChangeTablePointers[species];
u16 heldItem;
u32 ability;
if (formChanges != NULL)
{
heldItem = GetBoxMonData(mon, MON_DATA_HELD_ITEM, NULL);
ability = GetAbilityBySpecies(species, GetBoxMonData(mon, MON_DATA_ABILITY_NUM, NULL));
heldItem = GetBoxMonData(boxMon, MON_DATA_HELD_ITEM, NULL);
ability = GetAbilityBySpecies(species, GetBoxMonData(boxMon, MON_DATA_ABILITY_NUM, NULL));
for (i = 0; formChanges[i].method != FORM_CHANGE_END; i++)
{
@ -8264,8 +8264,6 @@ u16 GetFormChangeTargetSpeciesBoxMon(struct BoxPokemon *mon, u16 method, u32 arg
switch (method)
{
case FORM_ITEM_HOLD:
case FORM_BATTLE_BEGIN:
case FORM_BATTLE_END:
if (heldItem == formChanges[i].param1 || formChanges[i].param1 == ITEM_NONE)
targetSpecies = formChanges[i].targetSpecies;
break;
@ -8274,7 +8272,7 @@ u16 GetFormChangeTargetSpeciesBoxMon(struct BoxPokemon *mon, u16 method, u32 arg
targetSpecies = formChanges[i].targetSpecies;
break;
case FORM_MOVE:
if (BoxMonKnowsMove(mon, formChanges[i].param1) != formChanges[i].param2)
if (BoxMonKnowsMove(boxMon, formChanges[i].param1) != formChanges[i].param2)
targetSpecies = formChanges[i].targetSpecies;
break;
case FORM_ITEM_HOLD_ABILITY:
@ -8299,6 +8297,10 @@ u16 GetFormChangeTargetSpeciesBoxMon(struct BoxPokemon *mon, u16 method, u32 arg
}
}
break;
case FORM_BATTLE_BEGIN:
case FORM_BATTLE_END:
if (heldItem == formChanges[i].param1 || formChanges[i].param1 == ITEM_NONE)
targetSpecies = formChanges[i].targetSpecies;
}
}
}
@ -8358,7 +8360,7 @@ void TrySpecialOverworldEvo(void)
u8 i;
u8 evoMethod = gSpecialVar_0x8000;
u16 canStopEvo = gSpecialVar_0x8001;
u16 tryMultiple = gSpecialVar_0x8002;
u16 tryMultiple = gSpecialVar_0x8002;
for (i = 0; i < PARTY_SIZE; i++)
{
@ -8375,7 +8377,7 @@ void TrySpecialOverworldEvo(void)
else
gCB2_AfterEvolution = CB2_ReturnToField;
return;
}
}
}
sTriedEvolving = 0;
@ -8386,3 +8388,43 @@ bool32 ShouldShowFemaleDifferences(u16 species, u32 personality)
{
return (gBaseStats[species].flags & FLAG_GENDER_DIFFERENCE) && GetGenderFromSpeciesAndPersonality(species, personality) == MON_FEMALE;
}
void TryToSetBattleFormChangeMoves(struct Pokemon *mon)
{
int i, j;
u16 species = GetMonData(mon, MON_DATA_SPECIES, NULL);
const struct FormChange *formChanges = gFormChangeTablePointers[species];
u8 ppBonuses = GetMonData(mon, MON_DATA_PP_BONUSES, NULL);
if (formChanges == NULL)
return;
for (i = 0; formChanges[i].method != FORM_CHANGE_END; i++)
{
if ((formChanges[i].method == FORM_BATTLE_BEGIN || formChanges[i].method == FORM_BATTLE_END)
&& formChanges[i].param2 && formChanges[i].param3 && formChanges[i].targetSpecies == species)
{
u16 originalMove = formChanges[i].param2;
u16 newMove = formChanges[i].param3;
for (j = 0; j < MAX_MON_MOVES; j++)
{
u16 currMove = GetMonData(mon, MON_DATA_MOVE1 + j, NULL);
u8 totalPp = gBattleMoves[currMove].pp; // Get current move's max PP
u8 currPp = GetMonData(mon, MON_DATA_PP1 + j, NULL); // Get current move's remaining PP
u8 diffPp = totalPp - currPp; // Current move's PP difference
u8 finalPp = gBattleMoves[newMove].pp - diffPp; // Apply the PP difference to the new move
if (currMove == originalMove)
{
if (finalPp > gBattleMoves[newMove].pp)
finalPp = 0;
SetMonMoveSlot(mon, newMove, j);
SetMonData(mon, MON_DATA_PP1 + j, &finalPp);
}
}
SetMonData(mon, MON_DATA_PP_BONUSES, &ppBonuses);
break;
}
}
}