Form changes layout and Stance Change Aegi

This commit is contained in:
DizzyEggg 2019-12-31 19:11:53 +01:00
parent b15f0b3bb3
commit 39e3b0b740
11 changed files with 139 additions and 15 deletions

View File

@ -1531,6 +1531,11 @@
.byte \case
.endm
.macro handleformchange battler:req, case:req
various \battler, VARIOUS_HANDLE_FORM_CHANGE
.byte \case
.endm
.macro jumpifcantuselastresort battler:req, ptr:req
various \battler, VARIOUS_TRY_LAST_RESORT
.4byte \ptr

View File

@ -683,6 +683,7 @@ gBattleAnims_General::
.4byte General_TerrainElectric
.4byte General_TerrainPsychic
.4byte General_IllusionOff
.4byte General_FormChange
.align 2
gBattleAnims_Special::
@ -14763,6 +14764,13 @@ General_IllusionOff:
waitforvisualfinish
clearmonbg ANIM_TARGET
end
General_FormChange:
monbg ANIM_ATTACKER
createvisualtask AnimTask_TransformMon, 2, 0, 1
waitforvisualfinish
clearmonbg ANIM_ATTACKER
end
General_MegaEvolution:
loadspritegfx ANIM_TAG_MEGA_STONE

View File

@ -5881,6 +5881,18 @@ BattleScript_MegaEvolution::
printstring STRINGID_MEGAEVOEVOLVED
waitmessage 0x40
end2
BattleScript_StanceChangeActivates::
pause 0x5
call BattleScript_AbilityPopUp
printstring STRINGID_EMPTYSTRING3
waitmessage 0x1
handleformchange BS_ATTACKER, 0
handleformchange BS_ATTACKER, 1
playanimation BS_ATTACKER, B_ANIM_FORM_CHANGE, NULL
waitanimation
handleformchange BS_ATTACKER, 2
return
BattleScript_IllusionOff::
spriteignore0hp TRUE

View File

@ -328,5 +328,6 @@ extern const u8 BattleScript_MoveEffectBugBite[];
extern const u8 BattleScript_IllusionOff[];
extern const u8 BattleScript_DancerActivates[];
extern const u8 BattleScript_AftermathDmg[];
extern const u8 BattleScript_StanceChangeActivates[];
#endif // GUARD_BATTLE_SCRIPTS_H

View File

@ -103,7 +103,8 @@ u16 GetTypeModifier(u8 atkType, u8 defType);
s32 GetStealthHazardDamage(u8 hazardType, u8 battlerId);
u16 GetMegaEvolutionSpecies(u16 preEvoSpecies, u16 heldItemId);
bool32 CanMegaEvolve(u8 battlerId);
void UndoMegaEvolution(u8 monId);
void UndoMegaEvolution(u32 monId);
void UndoFormChange(u32 monId, u32 side);
bool32 DoBattlersShareType(u32 battler1, u32 battler2);
bool32 CanBattlerGetOrLoseItem(u8 battlerId, u16 itemId);
struct Pokemon *GetIllusionMonPtr(u32 battlerId);

View File

@ -407,6 +407,7 @@
#define B_ANIM_TERRAIN_ELECTRIC 0x1A
#define B_ANIM_TERRAIN_PSYCHIC 0x1B
#define B_ANIM_ILLUSION_OFF 0x1C
#define B_ANIM_FORM_CHANGE 0x1D
// special animations table
#define B_ANIM_LVL_UP 0x0

View File

@ -9,6 +9,8 @@
#define SPECIES_ARCEUS 0
#define SPECIES_SILVALLY 0
#define SPECIES_GENESECT 0
#define SPECIES_AEGISLASH 0
#define SPECIES_AEGISLASH_BLADE 10000
// Items with peculiar battle effects. Remove them if they're properly placed in constant/items.h
#define ITEM_GRISEOUS_ORB 0
@ -50,6 +52,7 @@
#define B_SOUND_SUBSTITUTE GEN_6 // Starting from gen6 sound moves bypass Substitute.
#define B_EXP_CATCH GEN_6 // Starting from gen6, pokemon get experience from catching.
#define B_ABILITY_POP_UP GEN_6 // Starting from gen5, the pokemon abilities are displayed in a pop-up, when they activate in battle.
#define B_STANCE_CHANGE_FAIL GEN_7 // In Gen7, Aegislash's form change does not happen, if the pokemon cannot use a move, because of confusion, paralysis, etc. In gen6, the form change occurs despite not being able to move.
#define B_FAST_INTRO TRUE // If set to TRUE, battle intro texts print at the same time as animation of a pokemon, as opposing to waiting for the animation to end.

View File

@ -145,6 +145,7 @@
#define VARIOUS_UPDATE_NICK 82
#define VARIOUS_TRY_ILLUSION_OFF 83
#define VARIOUS_SET_SPRITEIGNORE0HP 84
#define VARIOUS_HANDLE_FORM_CHANGE 85
// Cmd_manipulatedmg
#define DMG_CHANGE_SIGN 0

View File

@ -3154,6 +3154,7 @@ void FaintClearSetData(void)
ClearBattlerMoveHistory(gActiveBattler);
ClearBattlerAbilityHistory(gActiveBattler);
UndoFormChange(gBattlerPartyIndexes[gActiveBattler], GET_BATTLER_SIDE(gActiveBattler));
if (GetBattlerSide(gActiveBattler) == B_SIDE_PLAYER)
UndoMegaEvolution(gBattlerPartyIndexes[gActiveBattler]);
}
@ -4864,7 +4865,10 @@ static void HandleEndTurn_FinishBattle(void)
BeginFastPaletteFade(3);
FadeOutMapMusic(5);
for (i = 0; i < PARTY_SIZE; i++)
{
UndoMegaEvolution(i);
UndoFormChange(i, B_SIDE_PLAYER);
}
gBattleMainFunc = FreeResetData_ReturnToOvOrDoEvolutions;
gCB2_AfterEvolution = BattleMainCB2;
}
@ -5360,6 +5364,8 @@ static void HandleAction_Switch(void)
if (gBattleResults.playerSwitchesCounter < 255)
gBattleResults.playerSwitchesCounter++;
UndoFormChange(gBattlerPartyIndexes[gBattlerAttacker], GetBattlerSide(gBattlerAttacker));
}
static void HandleAction_UseItem(void)

View File

@ -970,6 +970,32 @@ static bool32 NoTargetPresent(u32 move)
return FALSE;
}
static bool32 TryAegiFormChange(void)
{
if (GetBattlerAbility(gBattlerAttacker) != ABILITY_STANCE_CHANGE)
return FALSE;
switch (gBattleMons[gBattlerAttacker].species)
{
default:
return FALSE;
case SPECIES_AEGISLASH: // Shield -> Blade
if (gBattleMoves[gCurrentMove].power == 0)
return FALSE;
gBattleMons[gBattlerAttacker].species = SPECIES_AEGISLASH_BLADE;
break;
case SPECIES_AEGISLASH_BLADE: // Blade -> Shield
if (gCurrentMove != MOVE_KING_S_SHIELD)
return FALSE;
gBattleMons[gBattlerAttacker].species = SPECIES_AEGISLASH;
break;
}
BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_StanceChangeActivates;
return TRUE;
}
static void Cmd_attackcanceler(void)
{
s32 i, moveType;
@ -985,6 +1011,10 @@ static void Cmd_attackcanceler(void)
gBattlescriptCurrInstr = BattleScript_MoveEnd;
return;
}
#if (B_STANCE_CHANGE_FAIL <= GEN_6)
if (TryAegiFormChange())
return;
#endif
if (AtkCanceller_UnableToUseMove())
return;
@ -1014,6 +1044,10 @@ static void Cmd_attackcanceler(void)
gMoveResultFlags |= MOVE_RESULT_MISSED;
return;
}
#if (B_STANCE_CHANGE_FAIL >= GEN_7)
if (TryAegiFormChange())
return;
#endif
gHitMarker &= ~(HITMARKER_x800000);
if (!(gHitMarker & HITMARKER_OBEYS) && !(gBattleMons[gBattlerAttacker].status2 & STATUS2_MULTIPLETURNS))
@ -4141,6 +4175,7 @@ static void Cmd_playanimation(void)
|| gBattlescriptCurrInstr[2] == B_ANIM_SNATCH_MOVE
|| gBattlescriptCurrInstr[2] == B_ANIM_MEGA_EVOLUTION
|| gBattlescriptCurrInstr[2] == B_ANIM_ILLUSION_OFF
|| gBattlescriptCurrInstr[2] == B_ANIM_FORM_CHANGE
|| gBattlescriptCurrInstr[2] == B_ANIM_SUBSTITUTE_FADE)
{
BtlController_EmitBattleAnimation(0, gBattlescriptCurrInstr[2], *argumentPtr);
@ -4186,6 +4221,7 @@ static void Cmd_playanimation2(void) // animation Id is stored in the first poin
|| *animationIdPtr == B_ANIM_SNATCH_MOVE
|| *animationIdPtr == B_ANIM_MEGA_EVOLUTION
|| *animationIdPtr == B_ANIM_ILLUSION_OFF
|| *animationIdPtr == B_ANIM_FORM_CHANGE
|| *animationIdPtr == B_ANIM_SUBSTITUTE_FADE)
{
BtlController_EmitBattleAnimation(0, *animationIdPtr, *argumentPtr);
@ -6676,6 +6712,22 @@ u32 IsLeafGuardProtected(u32 battler)
return 0;
}
static void RecalcBattlerStats(u32 battler, struct Pokemon *mon)
{
CalculateMonStats(mon);
gBattleMons[battler].level = GetMonData(mon, MON_DATA_LEVEL);
gBattleMons[battler].hp = GetMonData(mon, MON_DATA_HP);
gBattleMons[battler].maxHP = GetMonData(mon, MON_DATA_MAX_HP);
gBattleMons[battler].attack = GetMonData(mon, MON_DATA_ATK);
gBattleMons[battler].defense = GetMonData(mon, MON_DATA_DEF);
gBattleMons[battler].speed = GetMonData(mon, MON_DATA_SPEED);
gBattleMons[battler].spAttack = GetMonData(mon, MON_DATA_SPATK);
gBattleMons[battler].spDefense = GetMonData(mon, MON_DATA_SPDEF);
gBattleMons[battler].ability = GetMonAbility(mon);
gBattleMons[battler].type1 = gBaseStats[gBattleMons[battler].species].type1;
gBattleMons[battler].type2 = gBaseStats[gBattleMons[battler].species].type2;
}
static void Cmd_various(void)
{
struct Pokemon *mon;
@ -7297,19 +7349,7 @@ static void Cmd_various(void)
// Change stats.
else if (gBattlescriptCurrInstr[3] == 1)
{
CalculateMonStats(mon);
gBattleMons[gActiveBattler].level = GetMonData(mon, MON_DATA_LEVEL);
gBattleMons[gActiveBattler].hp = GetMonData(mon, MON_DATA_HP);
gBattleMons[gActiveBattler].maxHP = GetMonData(mon, MON_DATA_MAX_HP);
gBattleMons[gActiveBattler].attack = GetMonData(mon, MON_DATA_ATK);
gBattleMons[gActiveBattler].defense = GetMonData(mon, MON_DATA_DEF);
gBattleMons[gActiveBattler].speed = GetMonData(mon, MON_DATA_SPEED);
gBattleMons[gActiveBattler].spAttack = GetMonData(mon, MON_DATA_SPATK);
gBattleMons[gActiveBattler].spDefense = GetMonData(mon, MON_DATA_SPDEF);
gBattleMons[gActiveBattler].ability = GetMonAbility(mon);
gBattleMons[gActiveBattler].type1 = gBaseStats[gBattleMons[gActiveBattler].species].type1;
gBattleMons[gActiveBattler].type2 = gBaseStats[gBattleMons[gActiveBattler].species].type2;
RecalcBattlerStats(gActiveBattler, mon);
gBattleStruct->mega.alreadyEvolved[GetBattlerPosition(gActiveBattler)] = TRUE;
gBattleStruct->mega.evolvedPartyIds[GetBattlerSide(gActiveBattler)] |= gBitTable[gBattlerPartyIndexes[gActiveBattler]];
}
@ -7321,6 +7361,31 @@ static void Cmd_various(void)
}
gBattlescriptCurrInstr += 4;
return;
case VARIOUS_HANDLE_FORM_CHANGE:
if (GetBattlerSide(gActiveBattler) == B_SIDE_OPPONENT)
mon = &gEnemyParty[gBattlerPartyIndexes[gActiveBattler]];
else
mon = &gPlayerParty[gBattlerPartyIndexes[gActiveBattler]];
// Change species.
if (gBattlescriptCurrInstr[3] == 0)
{
PREPARE_SPECIES_BUFFER(gBattleTextBuff1, gBattleMons[gActiveBattler].species);
BtlController_EmitSetMonData(0, REQUEST_SPECIES_BATTLE, gBitTable[gBattlerPartyIndexes[gActiveBattler]], 2, &gBattleMons[gActiveBattler].species);
MarkBattlerForControllerExec(gActiveBattler);
}
// Change stats.
else if (gBattlescriptCurrInstr[3] == 1)
{
RecalcBattlerStats(gActiveBattler, mon);
}
// Update healthbox.
else
{
UpdateHealthboxAttribute(gHealthboxSpriteIds[gActiveBattler], mon, HEALTHBOX_ALL);
}
gBattlescriptCurrInstr += 4;
return;
case VARIOUS_TRY_LAST_RESORT:
if (CanUseLastResort(gActiveBattler))
gBattlescriptCurrInstr += 7;

View File

@ -6276,7 +6276,7 @@ bool32 CanMegaEvolve(u8 battlerId)
return TRUE;
}
void UndoMegaEvolution(u8 monId)
void UndoMegaEvolution(u32 monId)
{
if (gBattleStruct->mega.evolvedPartyIds[B_SIDE_PLAYER] & gBitTable[monId])
{
@ -6286,6 +6286,27 @@ void UndoMegaEvolution(u8 monId)
}
}
void UndoFormChange(u32 monId, u32 side)
{
u32 i, currSpecies;
struct Pokemon *party = (side == B_SIDE_PLAYER) ? gPlayerParty : gEnemyParty;
static const u16 species[][2] = // changed form id, default form id
{
{SPECIES_AEGISLASH_BLADE, SPECIES_AEGISLASH},
};
currSpecies = GetMonData(&party[monId], MON_DATA_SPECIES, NULL);
for (i = 0; i < ARRAY_COUNT(species); i++)
{
if (currSpecies == species[i][0])
{
SetMonData(&party[monId], MON_DATA_SPECIES, &species[i][1]);
CalculateMonStats(&party[monId]);
break;
}
}
}
bool32 DoBattlersShareType(u32 battler1, u32 battler2)
{
s32 i;