mirror of
https://github.com/Ninjdai1/pokeemerald.git
synced 2024-12-27 20:24:18 +01:00
Proper Roar handling in double battles
This commit is contained in:
parent
fddb5159b4
commit
7a8f524bc5
@ -1597,6 +1597,11 @@
|
||||
various \battler, VARIOUS_CHECK_IF_GRASSY_TERRAIN_HEALS
|
||||
.4byte \ptr
|
||||
.endm
|
||||
|
||||
.macro jumpifroarfails ptr:req
|
||||
various BS_ATTACKER, VARIOUS_JUMP_IF_ROAR_FAILS
|
||||
.4byte \ptr
|
||||
.endm
|
||||
|
||||
@ helpful macros
|
||||
.macro setstatchanger stat:req, stages:req, down:req
|
||||
|
@ -2123,6 +2123,7 @@ BattleScript_EffectRoar::
|
||||
attackcanceler
|
||||
attackstring
|
||||
ppreduce
|
||||
jumpifroarfails BattleScript_ButItFailed
|
||||
jumpifability BS_TARGET, ABILITY_SUCTION_CUPS, BattleScript_AbilityPreventsPhasingOut
|
||||
jumpifstatus3 BS_TARGET, STATUS3_ROOTED, BattleScript_PrintMonIsRooted
|
||||
accuracycheck BattleScript_ButItFailed, NO_ACC_CALC_CHECK_LOCK_ON
|
||||
@ -4967,18 +4968,9 @@ BattleScript_BideNoEnergyToAttack::
|
||||
printstring STRINGID_PKMNUNLEASHEDENERGY
|
||||
waitmessage 0x40
|
||||
goto BattleScript_ButItFailed
|
||||
|
||||
BattleScript_SuccessForceOut::
|
||||
attackanimation
|
||||
waitanimation
|
||||
switchoutabilities BS_TARGET
|
||||
returntoball BS_TARGET
|
||||
waitstate
|
||||
jumpifbattletype BATTLE_TYPE_TRAINER, BattleScript_TrainerBattleForceOut
|
||||
setoutcomeonteleport BS_ATTACKER
|
||||
finishaction
|
||||
|
||||
BattleScript_TrainerBattleForceOut::
|
||||
|
||||
BattleScript_RoarSuccessSwitch::
|
||||
call BattleScript_RoarSuccessRet
|
||||
getswitchedmondata BS_TARGET
|
||||
switchindataupdate BS_TARGET
|
||||
switchinanim BS_TARGET, FALSE
|
||||
@ -4986,6 +4978,19 @@ BattleScript_TrainerBattleForceOut::
|
||||
printstring STRINGID_PKMNWASDRAGGEDOUT
|
||||
switchineffects BS_TARGET
|
||||
goto BattleScript_MoveEnd
|
||||
|
||||
BattleScript_RoarSuccessEndBattle::
|
||||
call BattleScript_RoarSuccessRet
|
||||
setoutcomeonteleport BS_ATTACKER
|
||||
finishaction
|
||||
|
||||
BattleScript_RoarSuccessRet:
|
||||
attackanimation
|
||||
waitanimation
|
||||
switchoutabilities BS_TARGET
|
||||
returntoball BS_TARGET
|
||||
waitstate
|
||||
return
|
||||
|
||||
BattleScript_MistProtected::
|
||||
pause 0x20
|
||||
|
@ -53,7 +53,8 @@ extern const u8 BattleScript_LeechSeedTurnDrain[];
|
||||
extern const u8 BattleScript_BideStoringEnergy[];
|
||||
extern const u8 BattleScript_BideAttack[];
|
||||
extern const u8 BattleScript_BideNoEnergyToAttack[];
|
||||
extern const u8 BattleScript_SuccessForceOut[];
|
||||
extern const u8 BattleScript_RoarSuccessSwitch[];
|
||||
extern const u8 BattleScript_RoarSuccessEndBattle[];
|
||||
extern const u8 BattleScript_MistProtected[];
|
||||
extern const u8 BattleScript_RageIsBuilding[];
|
||||
extern const u8 BattleScript_MoveUsedIsDisabled[];
|
||||
|
@ -38,6 +38,8 @@
|
||||
|
||||
#define WEATHER_HAS_EFFECT ((!ABILITY_ON_FIELD(ABILITY_CLOUD_NINE) && !ABILITY_ON_FIELD(ABILITY_AIR_LOCK)))
|
||||
|
||||
#define IS_WHOLE_SIDE_ALIVE(battler)((IsBattlerAlive(battler) && IsBattlerAlive(BATTLE_PARTNER(battler))))
|
||||
|
||||
u8 GetBattlerForBattleScript(u8 caseId);
|
||||
void PressurePPLose(u8 target, u8 attacker, u16 move);
|
||||
void PressurePPLoseOnUsingPerishSong(u8 attacker);
|
||||
|
@ -138,6 +138,7 @@
|
||||
#define VARIOUS_SPECTRAL_THIEF 75
|
||||
#define VARIOUS_GRAVITY_ON_AIRBORNE_MONS 76
|
||||
#define VARIOUS_CHECK_IF_GRASSY_TERRAIN_HEALS 77
|
||||
#define VARIOUS_JUMP_IF_ROAR_FAILS 78
|
||||
|
||||
// atk80, dmg manipulation
|
||||
#define ATK80_DMG_CHANGE_SIGN 0
|
||||
|
@ -6368,6 +6368,21 @@ static void atk76_various(void)
|
||||
|
||||
switch (gBattlescriptCurrInstr[2])
|
||||
{
|
||||
// Roar will fail in a double wild battle when used by the player against one of the two alive wild mons.
|
||||
// Also when an opposing wild mon uses it againt its partner.
|
||||
case VARIOUS_JUMP_IF_ROAR_FAILS:
|
||||
if (WILD_DOUBLE_BATTLE
|
||||
&& GetBattlerSide(gBattlerAttacker) == B_SIDE_PLAYER
|
||||
&& GetBattlerSide(gBattlerTarget) == B_SIDE_OPPONENT
|
||||
&& IS_WHOLE_SIDE_ALIVE(gBattlerTarget))
|
||||
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3);
|
||||
else if (WILD_DOUBLE_BATTLE
|
||||
&& GetBattlerSide(gBattlerAttacker) == B_SIDE_OPPONENT
|
||||
&& GetBattlerSide(gBattlerTarget) == B_SIDE_OPPONENT)
|
||||
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3);
|
||||
else
|
||||
gBattlescriptCurrInstr += 7;
|
||||
return;
|
||||
case VARIOUS_CHECK_IF_GRASSY_TERRAIN_HEALS:
|
||||
if ((gStatuses3[gActiveBattler] & (STATUS3_SEMI_INVULNERABLE))
|
||||
|| BATTLER_MAX_HP(gActiveBattler)
|
||||
@ -8027,27 +8042,6 @@ static void atk8E_initmultihitstring(void)
|
||||
gBattlescriptCurrInstr++;
|
||||
}
|
||||
|
||||
static bool8 TryDoForceSwitchOut(void)
|
||||
{
|
||||
if (gBattleMons[gBattlerAttacker].level >= gBattleMons[gBattlerTarget].level)
|
||||
{
|
||||
*(gBattleStruct->field_58 + gBattlerTarget) = gBattlerPartyIndexes[gBattlerTarget];
|
||||
}
|
||||
else
|
||||
{
|
||||
u16 random = Random() & 0xFF;
|
||||
if ((u32)((random * (gBattleMons[gBattlerAttacker].level + gBattleMons[gBattlerTarget].level) >> 8) + 1) <= (gBattleMons[gBattlerTarget].level / 4))
|
||||
{
|
||||
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
|
||||
return FALSE;
|
||||
}
|
||||
*(gBattleStruct->field_58 + gBattlerTarget) = gBattlerPartyIndexes[gBattlerTarget];
|
||||
}
|
||||
|
||||
gBattlescriptCurrInstr = BattleScript_SuccessForceOut;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void atk8F_forcerandomswitch(void)
|
||||
{
|
||||
s32 i;
|
||||
@ -8060,14 +8054,26 @@ static void atk8F_forcerandomswitch(void)
|
||||
s32 validMons = 0;
|
||||
s32 minNeeded = 0;
|
||||
|
||||
if ((gBattleTypeFlags & BATTLE_TYPE_TRAINER))
|
||||
// Swapping pokemon happens in:
|
||||
// trainer battles
|
||||
// wild double battles when an opposing pokemon uses it against one of the two alive player mons
|
||||
// wild double battle when a player pokemon uses it against its partner
|
||||
if ((gBattleTypeFlags & BATTLE_TYPE_TRAINER)
|
||||
|| (WILD_DOUBLE_BATTLE
|
||||
&& GetBattlerSide(gBattlerAttacker) == B_SIDE_OPPONENT
|
||||
&& GetBattlerSide(gBattlerTarget) == B_SIDE_PLAYER
|
||||
&& IS_WHOLE_SIDE_ALIVE(gBattlerTarget))
|
||||
|| (WILD_DOUBLE_BATTLE
|
||||
&& GetBattlerSide(gBattlerAttacker) == B_SIDE_PLAYER
|
||||
&& GetBattlerSide(gBattlerTarget) == B_SIDE_PLAYER)
|
||||
)
|
||||
{
|
||||
if (GetBattlerSide(gBattlerTarget) == B_SIDE_PLAYER)
|
||||
party = gPlayerParty;
|
||||
else
|
||||
party = gEnemyParty;
|
||||
|
||||
if (BATTLE_TWO_VS_ONE_OPPONENT && (gBattlerTarget & BIT_SIDE) == B_SIDE_OPPONENT)
|
||||
if (BATTLE_TWO_VS_ONE_OPPONENT && GetBattlerSide(gBattlerTarget) == B_SIDE_OPPONENT)
|
||||
{
|
||||
firstMonId = 0;
|
||||
lastMonId = 6;
|
||||
@ -8175,19 +8181,20 @@ static void atk8F_forcerandomswitch(void)
|
||||
}
|
||||
else
|
||||
{
|
||||
if (TryDoForceSwitchOut())
|
||||
*(gBattleStruct->field_58 + gBattlerTarget) = gBattlerPartyIndexes[gBattlerTarget];
|
||||
gBattlescriptCurrInstr = BattleScript_RoarSuccessSwitch;
|
||||
|
||||
do
|
||||
{
|
||||
do
|
||||
{
|
||||
i = Random() % monsCount;
|
||||
i += firstMonId;
|
||||
}
|
||||
while (i == battler2PartyId
|
||||
|| i == battler1PartyId
|
||||
|| GetMonData(&party[i], MON_DATA_SPECIES) == SPECIES_NONE
|
||||
|| GetMonData(&party[i], MON_DATA_IS_EGG) == TRUE
|
||||
|| GetMonData(&party[i], MON_DATA_HP) == 0);
|
||||
i = Random() % monsCount;
|
||||
i += firstMonId;
|
||||
}
|
||||
while (i == battler2PartyId
|
||||
|| i == battler1PartyId
|
||||
|| GetMonData(&party[i], MON_DATA_SPECIES) == SPECIES_NONE
|
||||
|| GetMonData(&party[i], MON_DATA_IS_EGG) == TRUE
|
||||
|| GetMonData(&party[i], MON_DATA_HP) == 0);
|
||||
|
||||
*(gBattleStruct->monToSwitchIntoId + gBattlerTarget) = i;
|
||||
|
||||
if (!IsMultiBattle())
|
||||
@ -8208,7 +8215,11 @@ static void atk8F_forcerandomswitch(void)
|
||||
}
|
||||
else
|
||||
{
|
||||
TryDoForceSwitchOut();
|
||||
// In normal wild doubles, Roar will always fail if the user's level is less than the target's.
|
||||
if (gBattleMons[gBattlerAttacker].level >= gBattleMons[gBattlerTarget].level)
|
||||
gBattlescriptCurrInstr = BattleScript_RoarSuccessEndBattle;
|
||||
else
|
||||
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user