fixed Gigantamax and level bugs + lots of clean-up and debug removal

This commit is contained in:
AgustinGDLV 2023-03-25 15:33:50 -07:00
parent a383fab75a
commit fff0f78c89
11 changed files with 75 additions and 38 deletions

View file

@ -532,7 +532,7 @@ struct DynamaxData
u8 splits[MAX_BATTLERS_COUNT];
u16 baseMove[MAX_BATTLERS_COUNT]; // base move of Max Move
u16 lastUsedBaseMove;
u16 beforeLevelHP;
u16 levelUpHP;
};
struct StolenItem

View file

@ -1,7 +1,7 @@
#ifndef GUARD_BATTLE_DYNAMAX_H
#define GUARD_BATTLE_DYNAMAX_H
#define DYNAMAX_TURNS 3
#define DYNAMAX_TURNS_COUNT 3
enum MaxMoveEffect
{
@ -58,6 +58,7 @@ enum MaxMoveEffect
bool32 IsDynamaxed(u16 battlerId);
bool32 CanDynamax(u16 battlerId);
bool32 IsGigantamaxed(u16 battlerId);
void ApplyDynamaxHPMultiplier(u16 battlerId, struct Pokemon* mon);
void PrepareBattlerForDynamax(u16 battlerId);
u16 GetNonDynamaxHP(u16 battlerId);

View file

@ -6,7 +6,7 @@
// still has them in the ROM. This is because the developers forgot
// to define NDEBUG before release, however this has been changed as
// Ruby's actual debug build does not use the AGBPrint features.
// #define NDEBUG
#define NDEBUG
// To enable printf debugging, comment out "#define NDEBUG". This allows
// the various AGBPrint functions to be used. (See include/gba/isagbprint.h).

View file

@ -183,7 +183,7 @@
#define B_LAST_USED_BALL_BUTTON R_BUTTON // If last used ball is implemented, this button (or button combo) will trigger throwing the last used ball.
// Other settings
#define B_DOUBLE_WILD_CHANCE 100 // % chance of encountering two Pokémon in a Wild Encounter.
#define B_DOUBLE_WILD_CHANCE 0 // % chance of encountering two Pokémon in a Wild Encounter.
#define B_MULTI_BATTLE_WHITEOUT GEN_LATEST // In Gen4+, multi battles end when the Player and also their Partner don't have any more Pokémon to fight.
#define B_EVOLUTION_AFTER_WHITEOUT GEN_LATEST // In Gen6+, Pokemon that qualify for evolution after battle will evolve even if the player loses.
#define B_WILD_NATURAL_ENEMIES TRUE // If set to TRUE, certain wild mon species will attack other species when partnered in double wild battles (eg. Zangoose vs Seviper)

View file

@ -5,7 +5,7 @@
#define DEBUG_OVERWORLD_MENU TRUE // Enables an overworld debug menu to change flags, variables, giving pokemon and more, accessed by holding R and pressing START while in the overworld by default.
#define DEBUG_OVERWORLD_HELD_KEYS (R_BUTTON) // The keys required to be held to open the debug menu.
#define DEBUG_OVERWORLD_TRIGGER_EVENT pressedStartButton // The event that opens the menu when holding the key(s) defined in DEBUG_OVERWORLD_HELD_KEYS.
#define DEBUG_OVERWORLD_IN_MENU TRUE // Replaces the overworld debug menu button combination with a start menu entry (above Pokédex).
#define DEBUG_OVERWORLD_IN_MENU FALSE // Replaces the overworld debug menu button combination with a start menu entry (above Pokédex).
// Battle Debug Menu
#define DEBUG_BATTLE_MENU TRUE // If set to TRUE, enables a debug menu to use in battles by pressing the Select button.

View file

@ -1418,14 +1418,15 @@ static void Task_GiveExpToMon(u8 taskId)
u8 savedActiveBattler;
SetMonData(mon, MON_DATA_EXP, &nextLvlExp);
gBattleStruct->dynamax.beforeLevelHP = GetMonData(mon, MON_DATA_HP) + gBattleScripting.levelUpHP;
gBattleStruct->dynamax.levelUpHP = GetMonData(mon, MON_DATA_HP) \
+ UQ_4_12_TO_INT((gBattleScripting.levelUpHP * UQ_4_12(1.5)) + UQ_4_12_ROUND);
CalculateMonStats(mon);
// Prevent Dynamaxed HP from being reset upon level-up.
if (IsDynamaxed(battlerId))
// Reapply Dynamax HP multiplier after stats are recalculated.
if (IsDynamaxed(battlerId) && monId == gBattlerPartyIndexes[battlerId])
{
ApplyDynamaxHPMultiplier(battlerId, mon);
gBattleMons[battlerId].hp = gBattleStruct->dynamax.beforeLevelHP;
gBattleMons[battlerId].hp = gBattleStruct->dynamax.levelUpHP;
SetMonData(mon, MON_DATA_HP, &gBattleMons[battlerId].hp);
}
@ -1507,7 +1508,18 @@ static void Task_GiveExpWithExpBar(u8 taskId)
u8 savedActiveBattler;
SetMonData(&gPlayerParty[monId], MON_DATA_EXP, &expOnNextLvl);
gBattleStruct->dynamax.levelUpHP = GetMonData(&gPlayerParty[monId], MON_DATA_HP) \
+ UQ_4_12_TO_INT((gBattleScripting.levelUpHP * UQ_4_12(1.5)) + UQ_4_12_ROUND);
CalculateMonStats(&gPlayerParty[monId]);
// Reapply Dynamax HP multiplier after stats are recalculated.
if (IsDynamaxed(battlerId) && monId == gBattlerPartyIndexes[battlerId])
{
ApplyDynamaxHPMultiplier(battlerId, &gPlayerParty[monId]);
gBattleMons[battlerId].hp = gBattleStruct->dynamax.levelUpHP;
SetMonData(&gPlayerParty[monId], MON_DATA_HP, &gBattleMons[battlerId].hp);
}
gainedExp -= expOnNextLvl - currExp;
savedActiveBattler = gActiveBattler;
gActiveBattler = battlerId;

View file

@ -332,14 +332,15 @@ static void Task_GiveExpToMon(u8 taskId)
u8 savedActiveBank;
SetMonData(mon, MON_DATA_EXP, &nextLvlExp);
gBattleStruct->dynamax.beforeLevelHP = GetMonData(mon, MON_DATA_HP);
gBattleStruct->dynamax.levelUpHP = GetMonData(mon, MON_DATA_HP);
CalculateMonStats(mon);
// Prevent Dynamaxed HP from being reset upon level-up.
// Reapply Dynamax HP multiplier after stats are recalculated.
if (IsDynamaxed(battlerId))
{
ApplyDynamaxHPMultiplier(battlerId, mon);
gBattleMons[battlerId].hp = gBattleStruct->dynamax.beforeLevelHP;
gBattleMons[battlerId].hp = gBattleStruct->dynamax.levelUpHP \
+ UQ_4_12_TO_INT(gBattleScripting.levelUpHP * UQ_4_12(1.5) + UQ_4_12_ROUND);
SetMonData(mon, MON_DATA_HP, &gBattleMons[battlerId].hp);
}
@ -421,7 +422,18 @@ static void Task_GiveExpWithExpBar(u8 taskId)
u8 savedActiveBank;
SetMonData(&gPlayerParty[monId], MON_DATA_EXP, &expOnNextLvl);
gBattleStruct->dynamax.levelUpHP = GetMonData(&gPlayerParty[monId], MON_DATA_HP) \
+ UQ_4_12_TO_INT((gBattleScripting.levelUpHP * UQ_4_12(1.5)) + UQ_4_12_ROUND);
CalculateMonStats(&gPlayerParty[monId]);
// Reapply Dynamax HP multiplier after stats are recalculated.
if (IsDynamaxed(battlerId) && monId == gBattlerPartyIndexes[battlerId])
{
ApplyDynamaxHPMultiplier(battlerId, &gPlayerParty[monId]);
gBattleMons[battlerId].hp = gBattleStruct->dynamax.levelUpHP;
SetMonData(&gPlayerParty[monId], MON_DATA_HP, &gBattleMons[battlerId].hp);
}
gainedExp -= expOnNextLvl - currExp;
savedActiveBank = gActiveBattler;
gActiveBattler = battlerId;

View file

@ -115,13 +115,7 @@ bool32 CanDynamax(u16 battlerId)
#if B_FLAG_DYNAMAX_BATTLE != 0
if (!FlagGet(B_FLAG_DYNAMAX_BATTLE))
#endif
// return FALSE;
// Check if Dynamax battle flag is set. This needs to be defined in include/config/battle.h
#if B_FLAG_DYNAMAX_BATTLE != 0
if (!FlagGet(B_FLAG_DYNAMAX_BATTLE))
#endif
// return FALSE;
return FALSE;
// Check if Player has a Dynamax Band.
@ -153,6 +147,15 @@ bool32 CanDynamax(u16 battlerId)
return TRUE;
}
// Returns whether a battler is transformed into a Gigantamax form.
bool32 IsGigantamaxed(u16 battlerId) {
// TODO: Incorporate Gigantamax factor.
if (gBattleMons[battlerId].species >= (SPECIES_VENUSAUR_GMAX)
&& gBattleMons[battlerId].species <= (SPECIES_URSHIFU_RAPID_STRIKE_STYLE_GMAX))
return TRUE;
return FALSE;
}
// Applies the HP Multiplier for Dynamaxed Pokemon and Raid Bosses.
void ApplyDynamaxHPMultiplier(u16 battlerId, struct Pokemon* mon)
{
@ -161,7 +164,7 @@ void ApplyDynamaxHPMultiplier(u16 battlerId, struct Pokemon* mon)
else
{
u16 mult = UQ_4_12(1.5); // placeholder
u16 hp = UQ_4_12_TO_INT((gBattleMons[battlerId].hp * mult) + UQ_4_12_ROUND);
u16 hp = UQ_4_12_TO_INT((GetMonData(mon, MON_DATA_HP) * mult) + UQ_4_12_ROUND);
u16 maxHP = UQ_4_12_TO_INT((GetMonData(mon, MON_DATA_MAX_HP) * mult) + UQ_4_12_ROUND);
SetMonData(mon, MON_DATA_HP, &hp);
SetMonData(mon, MON_DATA_MAX_HP, &maxHP);
@ -202,7 +205,7 @@ void PrepareBattlerForDynamax(u16 battlerId)
gBattleStruct->dynamax.alreadyDynamaxed[side] = TRUE;
gBattleStruct->dynamax.dynamaxed[battlerId] = TRUE;
gBattleStruct->dynamax.dynamaxTurns[battlerId] = DYNAMAX_TURNS;
gBattleStruct->dynamax.dynamaxTurns[battlerId] = DYNAMAX_TURNS_COUNT;
// Substitute is removed upon Dynamaxing.
gBattleMons[battlerId].status2 &= ~STATUS2_SUBSTITUTE;
@ -220,18 +223,24 @@ void PrepareBattlerForDynamax(u16 battlerId)
void UndoDynamax(u16 battlerId)
{
u8 side = GetBattlerSide(battlerId);
// Revert HP and try form reversion if battler is Dynamaxed.
u8 monId = gBattlerPartyIndexes[battlerId];
// Revert HP if battler is still Dynamaxed.
if (IsDynamaxed(battlerId))
{
struct Pokemon *party = (side == B_SIDE_PLAYER) ? gPlayerParty : gEnemyParty;
struct Pokemon *mon = (side == B_SIDE_PLAYER) ? &gPlayerParty[monId] : &gEnemyParty[monId];
u16 mult = UQ_4_12(1.0/1.5); // placeholder
u16 hp = UQ_4_12_TO_INT((gBattleMons[battlerId].hp * mult + 1) + UQ_4_12_ROUND); // round up
SetMonData(&party[gBattlerPartyIndexes[battlerId]], MON_DATA_HP, &hp);
TryBattleFormChange(battlerId, FORM_CHANGE_BATTLE_SWITCH);
gBattleMons[battlerId].hp = UQ_4_12_TO_INT((GetMonData(mon, MON_DATA_HP) * mult + 1) + UQ_4_12_ROUND); // round up
SetMonData(mon, MON_DATA_HP, &gBattleMons[battlerId].hp);
}
// Makes sure there are no Dynamax flags set, including on switch / faint.
gBattleStruct->dynamax.dynamaxed[battlerId] = FALSE;
gBattleStruct->dynamax.dynamaxTurns[battlerId] = 0;
// Undo form change if needed.
if (IsGigantamaxed(battlerId))
TryBattleFormChange(battlerId, FORM_CHANGE_END_BATTLE);
}
// Weight-based moves (and some other moves in Raids) are blocked by Dynamax.
@ -258,16 +267,19 @@ bool32 ShouldUseMaxMove(u16 battlerId, u16 baseMove)
static u16 GetTypeBasedMaxMove(u16 battlerId, u16 type)
{
u32 species;
if (GetBattlerSide(battlerId) == B_SIDE_PLAYER)
species = GetMonData(&gPlayerParty[gBattlerPartyIndexes[battlerId]], MON_DATA_SPECIES, NULL);
else
species = GetMonData(&gEnemyParty[gBattlerPartyIndexes[battlerId]], MON_DATA_SPECIES, NULL);
// Gigantamax check
u16 species = gBattleMons[battlerId].species;
u16 targetSpecies = GetBattleFormChangeTargetSpecies(battlerId, FORM_CHANGE_BATTLE_GIGANTAMAX);
if (species >= (SPECIES_VENUSAUR_GMAX)
&& sGMaxMoveTable[species - (SPECIES_VENUSAUR_GMAX)].moveType == type)
{
return sGMaxMoveTable[species - (SPECIES_VENUSAUR_GMAX)].gmaxMove;
}
else if (targetSpecies != SPECIES_NONE
&& sGMaxMoveTable[targetSpecies - (SPECIES_VENUSAUR_GMAX)].moveType == type)
{
return sGMaxMoveTable[targetSpecies - (SPECIES_VENUSAUR_GMAX)].gmaxMove;
}
// regular Max Move
else

View file

@ -11348,7 +11348,8 @@ static void Cmd_various(void)
mon = &gPlayerParty[gBattlerPartyIndexes[battler]];
else
mon = &gEnemyParty[gBattlerPartyIndexes[battler]];
RecalcBattlerStats(battler, mon);
if (!IsGigantamaxed(battler)) // RecalcBattlerStats will get called on form change.
RecalcBattlerStats(battler, mon);
UpdateHealthboxAttribute(gHealthboxSpriteIds[battler], mon, HEALTHBOX_ALL);
break;
}

View file

@ -10220,8 +10220,7 @@ u16 GetBattleFormChangeTargetSpecies(u8 battlerId, u16 method)
break;
case FORM_CHANGE_BATTLE_GIGANTAMAX:
// TODO: check Gigantamax factor
if (IsDynamaxed(battlerId))
targetSpecies = formChanges[i].targetSpecies;
targetSpecies = formChanges[i].targetSpecies;
break;
case FORM_CHANGE_BATTLE_TURN_END:
if (formChanges[i].param1 == GetBattlerAbility(battlerId))
@ -10246,7 +10245,7 @@ bool32 CanBattlerFormChange(u8 battlerId, u16 method)
else if (IsBattlerPrimalReverted(battlerId) && (method == FORM_CHANGE_END_BATTLE))
return TRUE;
// Gigantamaxed Pokemon should revert upon fainting, switching, or ending the battle.
else if (IsDynamaxed(battlerId) && (method == FORM_CHANGE_FAINT || method == FORM_CHANGE_BATTLE_SWITCH || method == FORM_CHANGE_END_BATTLE))
else if (IsGigantamaxed(battlerId) && (method == FORM_CHANGE_FAINT || method == FORM_CHANGE_BATTLE_SWITCH || method == FORM_CHANGE_END_BATTLE))
return TRUE;
return DoesSpeciesHaveFormChangeMethod(gBattleMons[battlerId].species, method);
}
@ -10289,7 +10288,7 @@ bool32 TryBattleFormChange(u8 battlerId, u16 method)
restoreSpecies = TRUE;
// Gigantamax Pokemon have their forms reverted after fainting, switching, or ending the battle.
else if (IsDynamaxed(battlerId) && (method == FORM_CHANGE_FAINT || method == FORM_CHANGE_BATTLE_SWITCH || method == FORM_CHANGE_END_BATTLE))
else if (IsGigantamaxed(battlerId) && (method == FORM_CHANGE_FAINT || method == FORM_CHANGE_BATTLE_SWITCH || method == FORM_CHANGE_END_BATTLE))
restoreSpecies = TRUE;
if (restoreSpecies)

View file

@ -39,7 +39,7 @@ SINGLE_BATTLE_TEST("(DYNAMAX) Dynamax expires after three turns")
TURN { MOVE(player, MOVE_TACKLE); } // 3rd max move
} SCENE {
int i;
for (i = 0; i < DYNAMAX_TURNS; ++i) {
for (i = 0; i < DYNAMAX_TURNS_COUNT; ++i) {
MESSAGE("Wobbuffet used Max Strike!");
MESSAGE("Foe Wobbuffet used Celebrate!");
}