Refactor move Synchronise (#7271)
This commit is contained in:
parent
0422a013c4
commit
7ae97ab6e9
@ -2461,6 +2461,11 @@
|
||||
.byte \battler
|
||||
.endm
|
||||
|
||||
.macro trysynchronoise jumpInstr:req
|
||||
callnative BS_TrySynchronoise
|
||||
.4byte \jumpInstr
|
||||
.endm
|
||||
|
||||
.macro setallytonexttarget jumpInstr:req
|
||||
jumpifbyte CMP_GREATER_THAN, gBattlerTarget, 0x1, 1f
|
||||
addbyte gBattlerTarget, 0x2
|
||||
|
||||
@ -1622,42 +1622,20 @@ BattleScript_EffectPsychoShiftCanWork:
|
||||
BattleScript_EffectSynchronoise::
|
||||
attackcanceler
|
||||
attackstring
|
||||
pause B_WAIT_TIME_MED
|
||||
ppreduce
|
||||
selectfirstvalidtarget
|
||||
BattleScript_SynchronoiseLoop:
|
||||
movevaluescleanup
|
||||
jumpifcantusesynchronoise BattleScript_SynchronoiseNoEffect
|
||||
accuracycheck BattleScript_SynchronoiseMissed, ACC_CURR_MOVE
|
||||
critcalc
|
||||
damagecalc
|
||||
adjustdamage
|
||||
attackanimation
|
||||
waitanimation
|
||||
effectivenesssound
|
||||
hitanimation BS_TARGET
|
||||
waitstate
|
||||
healthbarupdate BS_TARGET
|
||||
datahpupdate BS_TARGET
|
||||
critmessage
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
resultmessage
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
trysynchronoise BattleScript_MoveEnd
|
||||
accuracycheck BattleScript_ButItFailed, ACC_CURR_MOVE
|
||||
goto BattleScript_HitFromCritCalc
|
||||
|
||||
BattleScript_ItDoesntAffectFoe::
|
||||
savetarget
|
||||
copybyte gBattlerTarget, sBATTLER
|
||||
printstring STRINGID_ITDOESNTAFFECT
|
||||
waitmessage B_WAIT_TIME_SHORT
|
||||
flushtextbox
|
||||
tryfaintmon BS_TARGET
|
||||
BattleScript_SynchronoiseMoveTargetEnd:
|
||||
moveendto MOVEEND_NEXT_TARGET
|
||||
jumpifnexttargetvalid BattleScript_SynchronoiseLoop
|
||||
end
|
||||
BattleScript_SynchronoiseMissed:
|
||||
pause B_WAIT_TIME_SHORT
|
||||
resultmessage
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
goto BattleScript_SynchronoiseMoveTargetEnd
|
||||
BattleScript_SynchronoiseNoEffect:
|
||||
pause B_WAIT_TIME_SHORT
|
||||
printstring STRINGID_NOEFFECTONTARGET
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
goto BattleScript_SynchronoiseMoveTargetEnd
|
||||
restoretarget
|
||||
return
|
||||
|
||||
BattleScript_MoveEffectSmackDown::
|
||||
printstring STRINGID_FELLSTRAIGHTDOWN
|
||||
|
||||
@ -526,7 +526,6 @@ extern const u8 BattleScript_TeraShellDistortingTypeMatchups[];
|
||||
extern const u8 BattleScript_TeraFormChange[];
|
||||
extern const u8 BattleScript_SleepClausePreventsEnd[];
|
||||
extern const u8 BattleScript_PowerConstruct[];
|
||||
|
||||
extern const u8 BattleScript_AbilityProtectsDoesntAffect[];
|
||||
extern const u8 BattleScript_ImmunityProtected[];
|
||||
extern const u8 BattleScript_SafeguardProtected[];
|
||||
@ -538,6 +537,7 @@ extern const u8 BattleScript_AlreadyPoisoned[];
|
||||
extern const u8 BattleScript_AlreadyParalyzed[];
|
||||
extern const u8 BattleScript_AlreadyBurned[];
|
||||
extern const u8 BattleScript_PrintAbilityMadeIneffective[];
|
||||
extern const u8 BattleScript_ItDoesntAffectFoe[];
|
||||
|
||||
// zmoves
|
||||
extern const u8 BattleScript_ZMoveActivateDamaging[];
|
||||
|
||||
@ -345,6 +345,7 @@ enum TypeSideHazard
|
||||
#define MOVE_RESULT_FOE_HUNG_ON (1 << 7)
|
||||
#define MOVE_RESULT_STURDIED (1 << 8)
|
||||
#define MOVE_RESULT_FOE_ENDURED_AFFECTION (1 << 9)
|
||||
#define MOVE_RESULT_SYNCHRONOISE_AFFECTED (1 << 10)
|
||||
#define MOVE_RESULT_NO_EFFECT (MOVE_RESULT_MISSED | MOVE_RESULT_DOESNT_AFFECT_FOE | MOVE_RESULT_FAILED)
|
||||
|
||||
enum BattleWeather
|
||||
|
||||
@ -1242,22 +1242,24 @@ static void Cmd_attackcanceler(void)
|
||||
|
||||
|
||||
u32 abilityDef = GetBattlerAbility(gBattlerTarget);
|
||||
if (CanAbilityBlockMove(gBattlerAttacker,
|
||||
gBattlerTarget,
|
||||
GetBattlerAbility(gBattlerAttacker),
|
||||
abilityDef,
|
||||
gCurrentMove,
|
||||
ABILITY_RUN_SCRIPT))
|
||||
if (CanAbilityBlockMove(
|
||||
gBattlerAttacker,
|
||||
gBattlerTarget,
|
||||
GetBattlerAbility(gBattlerAttacker),
|
||||
abilityDef,
|
||||
gCurrentMove,
|
||||
ABILITY_RUN_SCRIPT))
|
||||
return;
|
||||
|
||||
if (GetMoveNonVolatileStatus(gCurrentMove) == MOVE_EFFECT_PARALYSIS)
|
||||
{
|
||||
if (CanAbilityAbsorbMove(gBattlerAttacker,
|
||||
gBattlerTarget,
|
||||
abilityDef,
|
||||
gCurrentMove,
|
||||
GetBattleMoveType(gCurrentMove),
|
||||
ABILITY_RUN_SCRIPT))
|
||||
if (CanAbilityAbsorbMove(
|
||||
gBattlerAttacker,
|
||||
gBattlerTarget,
|
||||
abilityDef,
|
||||
gCurrentMove,
|
||||
GetBattleMoveType(gCurrentMove),
|
||||
ABILITY_RUN_SCRIPT))
|
||||
return;
|
||||
}
|
||||
|
||||
@ -2418,6 +2420,7 @@ static bool32 ProcessPreAttackAnimationFuncs(void)
|
||||
if (IsDoubleSpreadMove())
|
||||
{
|
||||
u32 moveTarget = GetBattlerMoveTargetType(gBattlerAttacker, gCurrentMove);
|
||||
|
||||
if (!gBattleStruct->printedStrongWindsWeakenedAttack)
|
||||
{
|
||||
for (u32 battlerDef = 0; battlerDef < gBattlersCount; battlerDef++)
|
||||
@ -5957,9 +5960,10 @@ static u32 GetNextTarget(u32 moveTarget, bool32 excludeCurrent)
|
||||
u32 battler;
|
||||
for (battler = 0; battler < MAX_BATTLERS_COUNT; battler++)
|
||||
{
|
||||
if (battler != gBattlerAttacker
|
||||
&& !(excludeCurrent && battler == gBattlerTarget)
|
||||
&& IsBattlerAlive(battler)
|
||||
if (battler == gBattlerAttacker || !IsBattlerAlive(battler))
|
||||
continue;
|
||||
|
||||
if (!(excludeCurrent && battler == gBattlerTarget)
|
||||
&& !gBattleStruct->battlerState[gBattlerAttacker].targetsDone[battler]
|
||||
&& (!IsBattlerAlly(battler, gBattlerAttacker) || moveTarget == MOVE_TARGET_FOES_AND_ALLY))
|
||||
break;
|
||||
@ -6665,8 +6669,9 @@ static void Cmd_moveend(void)
|
||||
MoveValuesCleanUp();
|
||||
gBattleScripting.moveEffect = gBattleScripting.savedMoveEffect;
|
||||
|
||||
if (moveEffect == EFFECT_EXPLOSION || moveEffect == EFFECT_MISTY_EXPLOSION)
|
||||
BattleScriptPush(gBattleMoveEffects[EFFECT_HIT].battleScript); // Edge case for Explosion not changing targets
|
||||
if (moveEffect == EFFECT_EXPLOSION || moveEffect == EFFECT_MISTY_EXPLOSION // Edge case for Explosion not changing targets
|
||||
|| moveEffect == EFFECT_SYNCHRONOISE) // So we don't go back to the Synchronoise script
|
||||
BattleScriptPush(gBattleMoveEffects[EFFECT_HIT].battleScript);
|
||||
else
|
||||
BattleScriptPush(GetMoveBattleScript(gCurrentMove));
|
||||
gBattlescriptCurrInstr = BattleScript_FlushMessageBox;
|
||||
@ -17907,7 +17912,6 @@ void BS_JumpIfSleepClause(void)
|
||||
void BS_FickleBeamDamageCalculation(void)
|
||||
{
|
||||
NATIVE_ARGS();
|
||||
gBattleStruct->fickleBeamBoosted = FALSE;
|
||||
|
||||
if (RandomPercentage(RNG_FICKLE_BEAM, 30))
|
||||
{
|
||||
@ -18671,3 +18675,36 @@ void BS_TryActivateAbilityShield(void)
|
||||
BattleScriptCall(BattleScript_AbilityShieldProtects);
|
||||
}
|
||||
}
|
||||
|
||||
void BS_TrySynchronoise(void)
|
||||
{
|
||||
NATIVE_ARGS(const u8 *jumpInstr);
|
||||
bool32 atleastOneSharedType = FALSE;
|
||||
|
||||
for (u32 battlerDef = 0; battlerDef < gBattlersCount; battlerDef++)
|
||||
{
|
||||
if (gBattleStruct->moveResultFlags[battlerDef] & MOVE_RESULT_SYNCHRONOISE_AFFECTED
|
||||
|| gBattlerAttacker == battlerDef
|
||||
|| !IsBattlerAlive(battlerDef))
|
||||
continue;
|
||||
|
||||
if (DoBattlersShareType(gBattlerAttacker, battlerDef))
|
||||
{
|
||||
atleastOneSharedType = TRUE;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!DoBattlersShareType(gBattlerAttacker, battlerDef))
|
||||
{
|
||||
gBattleScripting.battler = battlerDef;
|
||||
gBattleStruct->moveResultFlags[battlerDef] |= MOVE_RESULT_NO_EFFECT | MOVE_RESULT_SYNCHRONOISE_AFFECTED;
|
||||
BattleScriptCall(BattleScript_ItDoesntAffectFoe);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (atleastOneSharedType)
|
||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||
else
|
||||
gBattlescriptCurrInstr = cmd->jumpInstr;
|
||||
}
|
||||
|
||||
@ -2513,6 +2513,7 @@ static enum MoveCanceller CancellerMultiTargetMoves(void)
|
||||
|
||||
if (gBattlerAttacker == battlerDef
|
||||
|| !IsBattlerAlive(battlerDef)
|
||||
|| (GetMoveEffect(gCurrentMove) == EFFECT_SYNCHRONOISE && !DoBattlersShareType(gBattlerAttacker, battlerDef))
|
||||
|| (moveTarget == MOVE_TARGET_BOTH && gBattlerAttacker == BATTLE_PARTNER(battlerDef))
|
||||
|| IsBattlerProtected(gBattlerAttacker, battlerDef, gCurrentMove)) // Missing Invulnerable check
|
||||
{
|
||||
|
||||
@ -385,7 +385,7 @@ SINGLE_BATTLE_TEST("(TERA) Synchronoise uses a Terastallized Pokemon's Tera Type
|
||||
} SCENE {
|
||||
// turn 1
|
||||
MESSAGE("The opposing Wobbuffet used Synchronoise!");
|
||||
MESSAGE("It won't have any effect on Wobbuffet!");
|
||||
MESSAGE("It doesn't affect Wobbuffet…");
|
||||
// turn 2
|
||||
MESSAGE("The opposing Wobbuffet used Synchronoise!");
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_SYNCHRONOISE, opponent);
|
||||
|
||||
@ -1,4 +1,74 @@
|
||||
#include "global.h"
|
||||
#include "test/battle.h"
|
||||
|
||||
DOUBLE_BATTLE_TEST("Synchronoise hits all Pokemon that share a type with the attacker")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(playerLeft, MOVE_SYNCHRONOISE); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_SYNCHRONOISE, playerLeft);
|
||||
HP_BAR(opponentLeft);
|
||||
HP_BAR(playerRight);
|
||||
HP_BAR(opponentRight);
|
||||
}
|
||||
}
|
||||
|
||||
DOUBLE_BATTLE_TEST("Synchronoise will fail if there is no corresponding typing on the field")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
PLAYER(SPECIES_BULBASAUR);
|
||||
OPPONENT(SPECIES_BULBASAUR);
|
||||
OPPONENT(SPECIES_BULBASAUR);
|
||||
} WHEN {
|
||||
TURN { MOVE(playerLeft, MOVE_SYNCHRONOISE); }
|
||||
} SCENE {
|
||||
NOT ANIMATION(ANIM_TYPE_MOVE, MOVE_SYNCHRONOISE, playerLeft);
|
||||
MESSAGE("Wobbuffet used Synchronoise!");
|
||||
MESSAGE("It doesn't affect the opposing Bulbasaur…");
|
||||
MESSAGE("It doesn't affect Bulbasaur…");
|
||||
MESSAGE("It doesn't affect the opposing Bulbasaur…");
|
||||
NOT MESSAGE("But it failed!");
|
||||
}
|
||||
}
|
||||
|
||||
DOUBLE_BATTLE_TEST("Synchronoise will hit if there is at least one target")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
PLAYER(SPECIES_BULBASAUR);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_BULBASAUR);
|
||||
} WHEN {
|
||||
TURN { MOVE(playerLeft, MOVE_SYNCHRONOISE); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_SYNCHRONOISE, playerLeft);
|
||||
HP_BAR(opponentLeft);
|
||||
NONE_OF {
|
||||
HP_BAR(playerRight);
|
||||
HP_BAR(opponentRight);
|
||||
MESSAGE("But it failed!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DOUBLE_BATTLE_TEST("Synchronoise will fail if the corresponding typing mon protects")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
PLAYER(SPECIES_BULBASAUR);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_BULBASAUR);
|
||||
} WHEN {
|
||||
TURN { MOVE(opponentLeft, MOVE_PROTECT); MOVE(playerLeft, MOVE_SYNCHRONOISE); }
|
||||
} SCENE {
|
||||
NOT ANIMATION(ANIM_TYPE_MOVE, MOVE_SYNCHRONOISE, playerLeft);
|
||||
}
|
||||
}
|
||||
|
||||
TO_DO_BATTLE_TEST("TODO: Write Synchronoise (Move Effect) test titles")
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user