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
|
various \battler, VARIOUS_CHECK_IF_GRASSY_TERRAIN_HEALS
|
||||||
.4byte \ptr
|
.4byte \ptr
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
|
.macro jumpifroarfails ptr:req
|
||||||
|
various BS_ATTACKER, VARIOUS_JUMP_IF_ROAR_FAILS
|
||||||
|
.4byte \ptr
|
||||||
|
.endm
|
||||||
|
|
||||||
@ helpful macros
|
@ helpful macros
|
||||||
.macro setstatchanger stat:req, stages:req, down:req
|
.macro setstatchanger stat:req, stages:req, down:req
|
||||||
|
@ -2123,6 +2123,7 @@ BattleScript_EffectRoar::
|
|||||||
attackcanceler
|
attackcanceler
|
||||||
attackstring
|
attackstring
|
||||||
ppreduce
|
ppreduce
|
||||||
|
jumpifroarfails BattleScript_ButItFailed
|
||||||
jumpifability BS_TARGET, ABILITY_SUCTION_CUPS, BattleScript_AbilityPreventsPhasingOut
|
jumpifability BS_TARGET, ABILITY_SUCTION_CUPS, BattleScript_AbilityPreventsPhasingOut
|
||||||
jumpifstatus3 BS_TARGET, STATUS3_ROOTED, BattleScript_PrintMonIsRooted
|
jumpifstatus3 BS_TARGET, STATUS3_ROOTED, BattleScript_PrintMonIsRooted
|
||||||
accuracycheck BattleScript_ButItFailed, NO_ACC_CALC_CHECK_LOCK_ON
|
accuracycheck BattleScript_ButItFailed, NO_ACC_CALC_CHECK_LOCK_ON
|
||||||
@ -4967,18 +4968,9 @@ BattleScript_BideNoEnergyToAttack::
|
|||||||
printstring STRINGID_PKMNUNLEASHEDENERGY
|
printstring STRINGID_PKMNUNLEASHEDENERGY
|
||||||
waitmessage 0x40
|
waitmessage 0x40
|
||||||
goto BattleScript_ButItFailed
|
goto BattleScript_ButItFailed
|
||||||
|
|
||||||
BattleScript_SuccessForceOut::
|
BattleScript_RoarSuccessSwitch::
|
||||||
attackanimation
|
call BattleScript_RoarSuccessRet
|
||||||
waitanimation
|
|
||||||
switchoutabilities BS_TARGET
|
|
||||||
returntoball BS_TARGET
|
|
||||||
waitstate
|
|
||||||
jumpifbattletype BATTLE_TYPE_TRAINER, BattleScript_TrainerBattleForceOut
|
|
||||||
setoutcomeonteleport BS_ATTACKER
|
|
||||||
finishaction
|
|
||||||
|
|
||||||
BattleScript_TrainerBattleForceOut::
|
|
||||||
getswitchedmondata BS_TARGET
|
getswitchedmondata BS_TARGET
|
||||||
switchindataupdate BS_TARGET
|
switchindataupdate BS_TARGET
|
||||||
switchinanim BS_TARGET, FALSE
|
switchinanim BS_TARGET, FALSE
|
||||||
@ -4986,6 +4978,19 @@ BattleScript_TrainerBattleForceOut::
|
|||||||
printstring STRINGID_PKMNWASDRAGGEDOUT
|
printstring STRINGID_PKMNWASDRAGGEDOUT
|
||||||
switchineffects BS_TARGET
|
switchineffects BS_TARGET
|
||||||
goto BattleScript_MoveEnd
|
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::
|
BattleScript_MistProtected::
|
||||||
pause 0x20
|
pause 0x20
|
||||||
|
@ -53,7 +53,8 @@ extern const u8 BattleScript_LeechSeedTurnDrain[];
|
|||||||
extern const u8 BattleScript_BideStoringEnergy[];
|
extern const u8 BattleScript_BideStoringEnergy[];
|
||||||
extern const u8 BattleScript_BideAttack[];
|
extern const u8 BattleScript_BideAttack[];
|
||||||
extern const u8 BattleScript_BideNoEnergyToAttack[];
|
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_MistProtected[];
|
||||||
extern const u8 BattleScript_RageIsBuilding[];
|
extern const u8 BattleScript_RageIsBuilding[];
|
||||||
extern const u8 BattleScript_MoveUsedIsDisabled[];
|
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 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);
|
u8 GetBattlerForBattleScript(u8 caseId);
|
||||||
void PressurePPLose(u8 target, u8 attacker, u16 move);
|
void PressurePPLose(u8 target, u8 attacker, u16 move);
|
||||||
void PressurePPLoseOnUsingPerishSong(u8 attacker);
|
void PressurePPLoseOnUsingPerishSong(u8 attacker);
|
||||||
|
@ -138,6 +138,7 @@
|
|||||||
#define VARIOUS_SPECTRAL_THIEF 75
|
#define VARIOUS_SPECTRAL_THIEF 75
|
||||||
#define VARIOUS_GRAVITY_ON_AIRBORNE_MONS 76
|
#define VARIOUS_GRAVITY_ON_AIRBORNE_MONS 76
|
||||||
#define VARIOUS_CHECK_IF_GRASSY_TERRAIN_HEALS 77
|
#define VARIOUS_CHECK_IF_GRASSY_TERRAIN_HEALS 77
|
||||||
|
#define VARIOUS_JUMP_IF_ROAR_FAILS 78
|
||||||
|
|
||||||
// atk80, dmg manipulation
|
// atk80, dmg manipulation
|
||||||
#define ATK80_DMG_CHANGE_SIGN 0
|
#define ATK80_DMG_CHANGE_SIGN 0
|
||||||
|
@ -6368,6 +6368,21 @@ static void atk76_various(void)
|
|||||||
|
|
||||||
switch (gBattlescriptCurrInstr[2])
|
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:
|
case VARIOUS_CHECK_IF_GRASSY_TERRAIN_HEALS:
|
||||||
if ((gStatuses3[gActiveBattler] & (STATUS3_SEMI_INVULNERABLE))
|
if ((gStatuses3[gActiveBattler] & (STATUS3_SEMI_INVULNERABLE))
|
||||||
|| BATTLER_MAX_HP(gActiveBattler)
|
|| BATTLER_MAX_HP(gActiveBattler)
|
||||||
@ -8027,27 +8042,6 @@ static void atk8E_initmultihitstring(void)
|
|||||||
gBattlescriptCurrInstr++;
|
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)
|
static void atk8F_forcerandomswitch(void)
|
||||||
{
|
{
|
||||||
s32 i;
|
s32 i;
|
||||||
@ -8060,14 +8054,26 @@ static void atk8F_forcerandomswitch(void)
|
|||||||
s32 validMons = 0;
|
s32 validMons = 0;
|
||||||
s32 minNeeded = 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)
|
if (GetBattlerSide(gBattlerTarget) == B_SIDE_PLAYER)
|
||||||
party = gPlayerParty;
|
party = gPlayerParty;
|
||||||
else
|
else
|
||||||
party = gEnemyParty;
|
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;
|
firstMonId = 0;
|
||||||
lastMonId = 6;
|
lastMonId = 6;
|
||||||
@ -8175,19 +8181,20 @@ static void atk8F_forcerandomswitch(void)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (TryDoForceSwitchOut())
|
*(gBattleStruct->field_58 + gBattlerTarget) = gBattlerPartyIndexes[gBattlerTarget];
|
||||||
|
gBattlescriptCurrInstr = BattleScript_RoarSuccessSwitch;
|
||||||
|
|
||||||
|
do
|
||||||
{
|
{
|
||||||
do
|
i = Random() % monsCount;
|
||||||
{
|
i += firstMonId;
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
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;
|
*(gBattleStruct->monToSwitchIntoId + gBattlerTarget) = i;
|
||||||
|
|
||||||
if (!IsMultiBattle())
|
if (!IsMultiBattle())
|
||||||
@ -8208,7 +8215,11 @@ static void atk8F_forcerandomswitch(void)
|
|||||||
}
|
}
|
||||||
else
|
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