Grudge, Destiny Bond and FaintBattler refactor (#8072)
Co-authored-by: Bassoonian <iasperbassoonian@gmail.com>
This commit is contained in:
parent
ff557e3d0c
commit
1c1a98ee45
@ -936,7 +936,7 @@
|
||||
.4byte \failInstr
|
||||
.endm
|
||||
|
||||
.macro trysetdestinybondtohappen
|
||||
.macro unused_0xab
|
||||
.byte 0xab
|
||||
.endm
|
||||
|
||||
@ -1617,14 +1617,6 @@
|
||||
.4byte \failInstr
|
||||
.endm
|
||||
|
||||
.macro tryupdaterecoiltracker
|
||||
callnative BS_TryUpdateRecoilTracker
|
||||
.endm
|
||||
|
||||
.macro tryupdateleaderscresttracker
|
||||
callnative BS_TryUpdateLeadersCrestTracker
|
||||
.endm
|
||||
|
||||
.macro trytidyup clear:req, jumpInstr:req
|
||||
callnative BS_TryTidyUp
|
||||
.byte \clear
|
||||
|
||||
@ -2306,6 +2306,7 @@ BattleScript_EffectMiracleEye::
|
||||
accuracycheck BattleScript_MoveMissedPause, ACC_CURR_MOVE
|
||||
setvolatile BS_TARGET, VOLATILE_MIRACLE_EYE
|
||||
goto BattleScript_IdentifiedFoe
|
||||
|
||||
BattleScript_EffectGravity::
|
||||
call BattleScript_EffectGravityInternal
|
||||
goto BattleScript_MoveEnd
|
||||
@ -2838,7 +2839,6 @@ BattleScript_EffectOHKO::
|
||||
typecalc
|
||||
jumpifmovehadnoeffect BattleScript_HitFromAtkAnimation
|
||||
tryKO BattleScript_KOFail
|
||||
trysetdestinybondtohappen
|
||||
goto BattleScript_HitFromAtkAnimation
|
||||
BattleScript_KOFail::
|
||||
pause B_WAIT_TIME_LONG
|
||||
@ -2853,6 +2853,7 @@ BattleScript_RecoilIfMiss::
|
||||
healthbarupdate BS_ATTACKER, PASSIVE_HP_UPDATE
|
||||
datahpupdate BS_ATTACKER, PASSIVE_HP_UPDATE
|
||||
tryfaintmon BS_ATTACKER
|
||||
BattleScript_RecoilEnd:
|
||||
return
|
||||
|
||||
BattleScript_EffectMist::
|
||||
@ -4393,40 +4394,23 @@ BattleScript_EffectCamouflage::
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
goto BattleScript_MoveEnd
|
||||
|
||||
BattleScript_FaintAttacker::
|
||||
tryillusionoff BS_ATTACKER
|
||||
BattleScript_FaintBattler::
|
||||
tryillusionoff BS_SCRIPTING
|
||||
tryactivategulpmissile
|
||||
playfaintcry BS_ATTACKER
|
||||
playfaintcry BS_SCRIPTING
|
||||
pause B_WAIT_TIME_LONG
|
||||
dofaintanimation BS_ATTACKER
|
||||
printstring STRINGID_ATTACKERFAINTED
|
||||
cleareffectsonfaint BS_ATTACKER
|
||||
dofaintanimation BS_SCRIPTING
|
||||
printstring STRINGID_BATTLERFAINTED
|
||||
cleareffectsonfaint BS_SCRIPTING
|
||||
trytoclearprimalweather
|
||||
tryrevertweatherform
|
||||
flushtextbox
|
||||
waitanimation
|
||||
tryactivatesoulheart
|
||||
tryactivatereceiver BS_ATTACKER
|
||||
trytrainerslidemsgfirstoff BS_ATTACKER
|
||||
tryactivatereceiver BS_SCRIPTING
|
||||
trytrainerslidemsgfirstoff BS_SCRIPTING
|
||||
return
|
||||
|
||||
BattleScript_FaintTarget::
|
||||
tryillusionoff BS_TARGET
|
||||
tryactivategulpmissile
|
||||
tryupdateleaderscresttracker
|
||||
playfaintcry BS_TARGET
|
||||
pause B_WAIT_TIME_LONG
|
||||
dofaintanimation BS_TARGET
|
||||
printstring STRINGID_TARGETFAINTED
|
||||
cleareffectsonfaint BS_TARGET
|
||||
trytoclearprimalweather
|
||||
tryrevertweatherform
|
||||
flushtextbox
|
||||
waitanimation
|
||||
tryactivatesoulheart
|
||||
tryactivatereceiver BS_TARGET
|
||||
trytrainerslidemsgfirstoff BS_TARGET
|
||||
return
|
||||
|
||||
BattleScript_GiveExp::
|
||||
setbyte sGIVEEXP_STATE, 0
|
||||
@ -6391,17 +6375,11 @@ BattleScript_MoveEffectConfusion::
|
||||
return
|
||||
|
||||
BattleScript_MoveEffectRecoil::
|
||||
jumpifmove MOVE_STRUGGLE, BattleScript_DoRecoil
|
||||
jumpifability BS_ATTACKER, ABILITY_ROCK_HEAD, BattleScript_RecoilEnd
|
||||
jumpifability BS_ATTACKER, ABILITY_MAGIC_GUARD, BattleScript_RecoilEnd
|
||||
BattleScript_DoRecoil::
|
||||
healthbarupdate BS_ATTACKER, PASSIVE_HP_UPDATE
|
||||
datahpupdate BS_ATTACKER, PASSIVE_HP_UPDATE
|
||||
printstring STRINGID_PKMNHITWITHRECOIL
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
tryupdaterecoiltracker
|
||||
tryfaintmon BS_ATTACKER
|
||||
BattleScript_RecoilEnd::
|
||||
return
|
||||
|
||||
BattleScript_ItemSteal::
|
||||
|
||||
@ -777,11 +777,12 @@ struct BattleStruct
|
||||
u8 numHazards[NUM_BATTLE_SIDES];
|
||||
u8 hazardsCounter:4; // Counter for applying hazard on switch in
|
||||
enum SubmoveState submoveAnnouncement:2;
|
||||
u8 padding3:2;
|
||||
u8 tryDestinyBond:1;
|
||||
u8 tryGrudge:1;
|
||||
u16 flingItem;
|
||||
u8 incrementEchoedVoice:1;
|
||||
u8 echoedVoiceCounter:3;
|
||||
u8 padding4:4;
|
||||
u8 padding3:4;
|
||||
};
|
||||
|
||||
struct AiBattleData
|
||||
|
||||
@ -22,8 +22,7 @@ extern const u8 BattleScript_StatDown[];
|
||||
extern const u8 BattleScript_AlreadyAtFullHp[];
|
||||
extern const u8 BattleScript_PresentHealTarget[];
|
||||
extern const u8 BattleScript_MoveUsedMustRecharge[];
|
||||
extern const u8 BattleScript_FaintAttacker[];
|
||||
extern const u8 BattleScript_FaintTarget[];
|
||||
extern const u8 BattleScript_FaintBattler[];
|
||||
extern const u8 BattleScript_GiveExp[];
|
||||
extern const u8 BattleScript_HandleFaintedMon[];
|
||||
extern const u8 BattleScript_LocalTrainerBattleWon[];
|
||||
|
||||
@ -264,7 +264,7 @@ enum SemiInvulnerableExclusion
|
||||
#define HITMARKER_UNUSED_21 (1 << 21)
|
||||
#define HITMARKER_PLAYER_FAINTED (1 << 22)
|
||||
#define HITMARKER_UNUSED_23 (1 << 23)
|
||||
#define HITMARKER_GRUDGE (1 << 24)
|
||||
#define HITMARKER_UNUSED_24 (1 << 24)
|
||||
#define HITMARKER_OBEYS (1 << 25)
|
||||
#define HITMARKER_UNUSED_26 (1 << 26)
|
||||
#define HITMARKER_UNUSED_27 (1 << 27)
|
||||
|
||||
@ -130,6 +130,8 @@ enum MoveEndEffects
|
||||
{
|
||||
MOVEEND_SET_VALUES,
|
||||
MOVEEND_PROTECT_LIKE_EFFECT,
|
||||
MOVEEND_GRUDGE,
|
||||
MOVEEND_DESTINY_BOND,
|
||||
MOVEEND_ABSORB,
|
||||
MOVEEND_RAGE,
|
||||
MOVEEND_SYNCHRONIZE_TARGET,
|
||||
|
||||
@ -28,8 +28,7 @@ enum StringID
|
||||
STRINGID_STATSWONTINCREASE2,
|
||||
STRINGID_AVOIDEDDAMAGE,
|
||||
STRINGID_ITDOESNTAFFECT,
|
||||
STRINGID_ATTACKERFAINTED,
|
||||
STRINGID_TARGETFAINTED,
|
||||
STRINGID_BATTLERFAINTED,
|
||||
STRINGID_PLAYERGOTMONEY,
|
||||
STRINGID_PLAYERWHITEOUT,
|
||||
STRINGID_PLAYERWHITEOUT2_WILD,
|
||||
|
||||
@ -2250,7 +2250,7 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
|
||||
case EFFECT_DESTINY_BOND:
|
||||
if (DoesDestinyBondFail(battlerAtk))
|
||||
ADJUST_SCORE(-10);
|
||||
if (gBattleMons[battlerDef].volatiles.destinyBond)
|
||||
if (gBattleMons[battlerAtk].volatiles.destinyBond)
|
||||
ADJUST_SCORE(-10);
|
||||
else if (GetActiveGimmick(battlerDef) == GIMMICK_DYNAMAX)
|
||||
ADJUST_SCORE(-10);
|
||||
|
||||
@ -1540,7 +1540,6 @@ static bool32 (*const sEndTurnEffectHandlers[])(u32 battler) =
|
||||
u32 DoEndTurnEffects(void)
|
||||
{
|
||||
u32 battler = MAX_BATTLERS_COUNT;
|
||||
gHitMarker |= HITMARKER_GRUDGE;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
@ -1555,10 +1554,7 @@ u32 DoEndTurnEffects(void)
|
||||
|
||||
// Jump out if possible after endTurnEventsCounter was increased in the above code block
|
||||
if (gBattleStruct->endTurnEventsCounter == ENDTURN_COUNT)
|
||||
{
|
||||
gHitMarker &= ~HITMARKER_GRUDGE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
battler = gBattlerAttacker = gBattlerByTurnOrder[gBattleStruct->turnEffectsBattlerId];
|
||||
|
||||
|
||||
@ -549,7 +549,7 @@ static void CB2_InitBattleInternal(void)
|
||||
gReservedSpritePaletteCount = MAX_BATTLERS_COUNT;
|
||||
SetVBlankCallback(VBlankCB_Battle);
|
||||
SetUpBattleVarsAndBirchZigzagoon();
|
||||
|
||||
|
||||
if ((IsMultibattleTest() && gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER)
|
||||
|| (gBattleTypeFlags & BATTLE_TYPE_MULTI && gBattleTypeFlags & BATTLE_TYPE_BATTLE_TOWER)
|
||||
|| (gBattleTypeFlags & BATTLE_TYPE_MULTI && gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER))
|
||||
@ -5164,6 +5164,8 @@ static void TurnValuesCleanUp(bool8 var0)
|
||||
gSideTimers[B_SIDE_OPPONENT].followmeTimer = 0;
|
||||
|
||||
gBattleStruct->pledgeMove = FALSE; // combined pledge move may not have been used due to a canceller
|
||||
gBattleStruct->tryDestinyBond = FALSE;
|
||||
gBattleStruct->tryGrudge = FALSE;
|
||||
ClearPursuitValues();
|
||||
ClearDamageCalcResults();
|
||||
}
|
||||
|
||||
@ -188,8 +188,7 @@ const u8 *const gBattleStringsTable[STRINGID_COUNT] =
|
||||
[STRINGID_STATSWONTINCREASE2] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX}'s stats won't go any higher!"),
|
||||
[STRINGID_AVOIDEDDAMAGE] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX} avoided damage with {B_DEF_ABILITY}!"), //not in gen 5+, ability popup
|
||||
[STRINGID_ITDOESNTAFFECT] = COMPOUND_STRING("It doesn't affect {B_DEF_NAME_WITH_PREFIX2}…"),
|
||||
[STRINGID_ATTACKERFAINTED] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} fainted!\p"),
|
||||
[STRINGID_TARGETFAINTED] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX} fainted!\p"),
|
||||
[STRINGID_BATTLERFAINTED] = COMPOUND_STRING("{B_SCR_NAME_WITH_PREFIX} fainted!\p"),
|
||||
[STRINGID_PLAYERGOTMONEY] = COMPOUND_STRING("You got ¥{B_BUFF1} for winning!\p"),
|
||||
[STRINGID_PLAYERWHITEOUT] = COMPOUND_STRING("You have no more Pokémon that can fight!\p"),
|
||||
[STRINGID_PLAYERWHITEOUT2_WILD] = COMPOUND_STRING("You panicked and dropped ¥{B_BUFF1}…"),
|
||||
|
||||
@ -310,7 +310,6 @@ enum GiveCaughtMonStates
|
||||
|
||||
#define TAG_LVLUP_BANNER_MON_ICON 55130
|
||||
|
||||
static void TrySetDestinyBondToHappen(void);
|
||||
static u32 ChangeStatBuffs(u32 battler, s8 statValue, enum Stat statId, union StatChangeFlags flags, u32 stats, const u8 *BS_ptr);
|
||||
static bool32 IsMonGettingExpSentOut(void);
|
||||
static void InitLevelUpBanner(void);
|
||||
@ -509,7 +508,7 @@ static void Cmd_setalwayshitflag(void);
|
||||
static void Cmd_copymovepermanently(void);
|
||||
static void Cmd_unused_0xA9(void);
|
||||
static void Cmd_unused_AA(void);
|
||||
static void Cmd_trysetdestinybondtohappen(void);
|
||||
static void Cmd_unused_0xab(void);
|
||||
static void Cmd_settailwind(void);
|
||||
static void Cmd_tryspiteppreduce(void);
|
||||
static void Cmd_healpartystatus(void);
|
||||
@ -768,7 +767,7 @@ void (*const gBattleScriptingCommandsTable[])(void) =
|
||||
Cmd_copymovepermanently, //0xA8
|
||||
Cmd_unused_0xA9, //0xA9
|
||||
Cmd_unused_AA, //0xAA
|
||||
Cmd_trysetdestinybondtohappen, //0xAB
|
||||
Cmd_unused_0xab, //0xAB
|
||||
Cmd_settailwind, //0xAC
|
||||
Cmd_tryspiteppreduce, //0xAD
|
||||
Cmd_healpartystatus, //0xAE
|
||||
@ -1317,8 +1316,6 @@ static void JumpIfMoveFailed(u32 adder, u32 move, u32 moveType, const u8 *failIn
|
||||
}
|
||||
else
|
||||
{
|
||||
TrySetDestinyBondToHappen();
|
||||
|
||||
if (CanAbilityAbsorbMove(gBattlerAttacker,
|
||||
gBattlerTarget,
|
||||
GetBattlerAbility(gBattlerTarget),
|
||||
@ -3323,6 +3320,7 @@ void SetMoveEffect(u32 battler, u32 effectBattler, bool32 primary, bool32 certai
|
||||
if (GetBattlerAbility(gEffectBattler) == ABILITY_PARENTAL_BOND)
|
||||
recoil *= 2;
|
||||
SetPassiveDamageAmount(gEffectBattler, recoil);
|
||||
TryUpdateEvolutionTracker(IF_RECOIL_DAMAGE_GE, gBattleStruct->passiveHpUpdate[gBattlerAttacker], MOVE_NONE);
|
||||
BattleScriptPush(gBattlescriptCurrInstr + 1);
|
||||
gBattlescriptCurrInstr = BattleScript_MoveEffectRecoil;
|
||||
break;
|
||||
@ -4175,7 +4173,7 @@ static void Cmd_clearvolatile(void)
|
||||
static void Cmd_tryfaintmon(void)
|
||||
{
|
||||
CMD_ARGS(u8 battler, bool8 isSpikes, const u8 *instr);
|
||||
u32 battler, destinyBondBattler;
|
||||
u32 battler;
|
||||
const u8 *faintScript;
|
||||
|
||||
battler = GetBattlerForBattleScript(cmd->battler);
|
||||
@ -4202,16 +4200,12 @@ static void Cmd_tryfaintmon(void)
|
||||
gBattlescriptCurrInstr = BattleScript_NeutralizingGasExits;
|
||||
return;
|
||||
}
|
||||
|
||||
if (cmd->battler == BS_ATTACKER)
|
||||
{
|
||||
destinyBondBattler = gBattlerTarget;
|
||||
faintScript = BattleScript_FaintAttacker;
|
||||
}
|
||||
else
|
||||
{
|
||||
destinyBondBattler = gBattlerAttacker;
|
||||
faintScript = BattleScript_FaintTarget;
|
||||
}
|
||||
TryUpdateEvolutionTracker(IF_DEFEAT_X_WITH_ITEMS, 1, MOVE_NONE);
|
||||
|
||||
gBattleScripting.battler = battler;
|
||||
faintScript = BattleScript_FaintBattler;
|
||||
if (!(gAbsentBattlerFlags & (1u << battler))
|
||||
&& !IsBattlerAlive(battler))
|
||||
{
|
||||
@ -4233,30 +4227,11 @@ static void Cmd_tryfaintmon(void)
|
||||
gBattleResults.lastOpponentSpecies = GetMonData(GetBattlerMon(battler), MON_DATA_SPECIES, NULL);
|
||||
gSideTimers[B_SIDE_OPPONENT].retaliateTimer = 2;
|
||||
}
|
||||
if ((gHitMarker & HITMARKER_DESTINYBOND) && IsBattlerAlive(gBattlerAttacker)
|
||||
&& !(GetActiveGimmick(gBattlerAttacker) == GIMMICK_DYNAMAX))
|
||||
{
|
||||
gHitMarker &= ~HITMARKER_DESTINYBOND;
|
||||
BattleScriptPush(gBattlescriptCurrInstr);
|
||||
gBattleStruct->passiveHpUpdate[destinyBondBattler] = gBattleMons[destinyBondBattler].hp;
|
||||
gBattlescriptCurrInstr = BattleScript_DestinyBondTakesLife;
|
||||
}
|
||||
if (gBattleMons[gBattlerTarget].volatiles.grudge
|
||||
&& !(gHitMarker & HITMARKER_GRUDGE)
|
||||
&& !IsBattlerAlly(gBattlerAttacker, gBattlerTarget)
|
||||
&& IsBattlerAlive(gBattlerAttacker)
|
||||
&& gCurrentMove != MOVE_STRUGGLE)
|
||||
{
|
||||
u8 moveIndex = gBattleStruct->chosenMovePositions[gBattlerAttacker];
|
||||
|
||||
gBattleMons[gBattlerAttacker].pp[moveIndex] = 0;
|
||||
BattleScriptPush(gBattlescriptCurrInstr);
|
||||
gBattlescriptCurrInstr = BattleScript_GrudgeTakesPp;
|
||||
BtlController_EmitSetMonData(gBattlerAttacker, B_COMM_TO_CONTROLLER, moveIndex + REQUEST_PPMOVE1_BATTLE, 0, sizeof(gBattleMons[gBattlerAttacker].pp[moveIndex]), &gBattleMons[gBattlerAttacker].pp[moveIndex]);
|
||||
MarkBattlerForControllerExec(gBattlerAttacker);
|
||||
|
||||
PREPARE_MOVE_BUFFER(gBattleTextBuff1, gBattleMons[gBattlerAttacker].moves[moveIndex])
|
||||
}
|
||||
if (gBattleMons[gBattlerTarget].volatiles.destinyBond)
|
||||
gBattleStruct->tryDestinyBond = TRUE;
|
||||
if (gBattleMons[gBattlerTarget].volatiles.grudge)
|
||||
gBattleStruct->tryGrudge = TRUE;
|
||||
|
||||
TryDeactivateSleepClause(GetBattlerSide(battler), gBattlerPartyIndexes[battler]);
|
||||
}
|
||||
@ -4957,8 +4932,6 @@ static void MoveValuesCleanUp(void)
|
||||
gBattleScripting.moveEffect = MOVE_EFFECT_NONE;
|
||||
gBattleStruct->synchronizeMoveEffect = MOVE_EFFECT_NONE;
|
||||
gBattleCommunication[MISS_TYPE] = 0;
|
||||
if (!gMultiHitCounter)
|
||||
gHitMarker &= ~HITMARKER_DESTINYBOND;
|
||||
}
|
||||
|
||||
static void Cmd_movevaluescleanup(void)
|
||||
@ -5819,7 +5792,13 @@ static bool32 HandleMoveEndMoveBlock(u32 moveEffect)
|
||||
case EFFECT_RECOIL:
|
||||
if (IsBattlerTurnDamaged(gBattlerTarget) && IsBattlerAlive(gBattlerAttacker))
|
||||
{
|
||||
enum Ability ability = GetBattlerAbility(gBattlerAttacker);
|
||||
if (IsAbilityAndRecord(gBattlerAttacker, ability, ABILITY_ROCK_HEAD)
|
||||
|| IsAbilityAndRecord(gBattlerAttacker, ability, ABILITY_MAGIC_GUARD))
|
||||
break;
|
||||
|
||||
SetPassiveDamageAmount(gBattlerAttacker, gBattleScripting.savedDmg * max(1, GetMoveRecoil(gCurrentMove)) / 100);
|
||||
TryUpdateEvolutionTracker(IF_RECOIL_DAMAGE_GE, gBattleStruct->passiveHpUpdate[gBattlerAttacker], MOVE_NONE);
|
||||
BattleScriptCall(BattleScript_MoveEffectRecoil);
|
||||
effect = TRUE;
|
||||
}
|
||||
@ -5836,10 +5815,11 @@ static bool32 HandleMoveEndMoveBlock(u32 moveEffect)
|
||||
case EFFECT_MAX_HP_50_RECOIL:
|
||||
if (IsBattlerAlive(gBattlerAttacker)
|
||||
&& !(gBattleStruct->moveResultFlags[gBattlerTarget] & MOVE_RESULT_FAILED)
|
||||
&& GetBattlerAbility(gBattlerAttacker) != ABILITY_MAGIC_GUARD)
|
||||
&& !IsAbilityAndRecord(gBattlerAttacker, GetBattlerAbility(gBattlerAttacker), ABILITY_MAGIC_GUARD))
|
||||
{
|
||||
s32 recoil = (GetNonDynamaxMaxHP(gBattlerAttacker) + 1) / 2; // Half of Max HP Rounded UP
|
||||
SetPassiveDamageAmount(gBattlerAttacker, recoil);
|
||||
TryUpdateEvolutionTracker(IF_RECOIL_DAMAGE_GE, gBattleStruct->passiveHpUpdate[gBattlerAttacker], MOVE_NONE);
|
||||
BattleScriptCall(BattleScript_MaxHp50Recoil);
|
||||
effect = TRUE;
|
||||
}
|
||||
@ -5847,8 +5827,14 @@ static bool32 HandleMoveEndMoveBlock(u32 moveEffect)
|
||||
case EFFECT_CHLOROBLAST:
|
||||
if (IsBattlerTurnDamaged(gBattlerTarget) && IsBattlerAlive(gBattlerAttacker))
|
||||
{
|
||||
enum Ability ability = GetBattlerAbility(gBattlerAttacker);
|
||||
if (IsAbilityAndRecord(gBattlerAttacker, ability, ABILITY_ROCK_HEAD)
|
||||
|| IsAbilityAndRecord(gBattlerAttacker, ability, ABILITY_MAGIC_GUARD))
|
||||
break;
|
||||
|
||||
s32 recoil = (GetNonDynamaxMaxHP(gBattlerAttacker) + 1) / 2; // Half of Max HP Rounded UP
|
||||
SetPassiveDamageAmount(gBattlerAttacker, recoil);
|
||||
TryUpdateEvolutionTracker(IF_RECOIL_DAMAGE_GE, gBattleStruct->passiveHpUpdate[gBattlerAttacker], MOVE_NONE);
|
||||
BattleScriptCall(BattleScript_MoveEffectRecoil);
|
||||
effect = TRUE;
|
||||
}
|
||||
@ -6044,6 +6030,43 @@ static void Cmd_moveend(void)
|
||||
}
|
||||
gBattleScripting.moveendState++;
|
||||
break;
|
||||
|
||||
case MOVEEND_GRUDGE:
|
||||
if (gBattleStruct->tryGrudge
|
||||
&& IsBattlerTurnDamaged(gBattlerTarget)
|
||||
&& !IsBattlerAlive(gBattlerTarget)
|
||||
&& IsBattlerAlive(gBattlerAttacker)
|
||||
&& !IsBattlerAlly(gBattlerAttacker, gBattlerTarget)
|
||||
&& !IsZMove(gCurrentMove)
|
||||
&& gCurrentMove != MOVE_STRUGGLE)
|
||||
{
|
||||
u32 moveIndex = gBattleStruct->chosenMovePositions[gBattlerAttacker];
|
||||
|
||||
gBattleStruct->tryGrudge = FALSE;
|
||||
gBattleMons[gBattlerAttacker].pp[moveIndex] = 0;
|
||||
BattleScriptCall(BattleScript_GrudgeTakesPp);
|
||||
BtlController_EmitSetMonData(gBattlerAttacker, B_COMM_TO_CONTROLLER, moveIndex + REQUEST_PPMOVE1_BATTLE, 0, sizeof(gBattleMons[gBattlerAttacker].pp[moveIndex]), &gBattleMons[gBattlerAttacker].pp[moveIndex]);
|
||||
MarkBattlerForControllerExec(gBattlerAttacker);
|
||||
PREPARE_MOVE_BUFFER(gBattleTextBuff1, gBattleMons[gBattlerAttacker].moves[moveIndex])
|
||||
}
|
||||
gBattleScripting.moveendState++;
|
||||
break;
|
||||
|
||||
case MOVEEND_DESTINY_BOND:
|
||||
if (gBattleStruct->tryDestinyBond
|
||||
&& IsBattlerTurnDamaged(gBattlerTarget)
|
||||
&& !IsBattlerAlive(gBattlerTarget)
|
||||
&& IsBattlerAlive(gBattlerAttacker)
|
||||
&& !(GetActiveGimmick(gBattlerAttacker) == GIMMICK_DYNAMAX)
|
||||
&& !IsBattlerAlly(gBattlerAttacker, gBattlerTarget))
|
||||
{
|
||||
gBattleStruct->tryDestinyBond = FALSE;
|
||||
gBattleStruct->passiveHpUpdate[gBattlerAttacker] = gBattleMons[gBattlerAttacker].hp;
|
||||
BattleScriptCall(BattleScript_DestinyBondTakesLife);
|
||||
effect = TRUE;
|
||||
}
|
||||
gBattleScripting.moveendState++;
|
||||
break;
|
||||
case MOVEEND_ABSORB:
|
||||
if (gHitMarker & HITMARKER_UNABLE_TO_USE_MOVE
|
||||
|| !IsBattlerTurnDamaged(gBattlerTarget))
|
||||
@ -7705,8 +7728,6 @@ static void UpdateSentMonFlags(u32 battler)
|
||||
|
||||
static void SetDmgHazardsBattlescript(u8 battler, u8 multistringId)
|
||||
{
|
||||
gBattleMons[battler].volatiles.destinyBond = 0;
|
||||
gHitMarker &= ~HITMARKER_DESTINYBOND;
|
||||
gBattleScripting.battler = battler;
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = multistringId;
|
||||
|
||||
@ -11596,22 +11617,8 @@ static void Cmd_unused_AA(void)
|
||||
{
|
||||
}
|
||||
|
||||
static void TrySetDestinyBondToHappen(void)
|
||||
static void Cmd_unused_0xab(void)
|
||||
{
|
||||
if (gBattleMons[gBattlerTarget].volatiles.destinyBond
|
||||
&& !IsBattlerAlly(gBattlerAttacker, gBattlerTarget)
|
||||
&& !(gHitMarker & HITMARKER_GRUDGE))
|
||||
{
|
||||
gHitMarker |= HITMARKER_DESTINYBOND;
|
||||
}
|
||||
}
|
||||
|
||||
static void Cmd_trysetdestinybondtohappen(void)
|
||||
{
|
||||
CMD_ARGS();
|
||||
|
||||
TrySetDestinyBondToHappen();
|
||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||
}
|
||||
|
||||
static void Cmd_settailwind(void)
|
||||
@ -15475,20 +15482,6 @@ static void TryUpdateEvolutionTracker(u32 evolutionCondition, u32 upAmount, u16
|
||||
}
|
||||
}
|
||||
|
||||
void BS_TryUpdateRecoilTracker(void)
|
||||
{
|
||||
NATIVE_ARGS();
|
||||
TryUpdateEvolutionTracker(IF_RECOIL_DAMAGE_GE, gBattleStruct->moveDamage[gBattlerAttacker], MOVE_NONE);
|
||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||
}
|
||||
|
||||
void BS_TryUpdateLeadersCrestTracker(void)
|
||||
{
|
||||
NATIVE_ARGS();
|
||||
TryUpdateEvolutionTracker(IF_DEFEAT_X_WITH_ITEMS, 1, MOVE_NONE);
|
||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||
}
|
||||
|
||||
void BS_TryTidyUp(void)
|
||||
{
|
||||
NATIVE_ARGS(u8 clear, const u8 *jumpInstr);
|
||||
|
||||
@ -14,7 +14,7 @@
|
||||
static bool8 IsNotSpecialBattleString(enum StringID stringId);
|
||||
static void AddMovePoints(u8 caseId, u16 arg1, u8 arg2, u8 arg3);
|
||||
static void TrySetBattleSeminarShow(void);
|
||||
static void AddPointsOnFainting(bool8 targetFainted);
|
||||
static void AddPointsOnFainting(void);
|
||||
static void AddPointsBasedOnWeather(u16 weatherFlags, u16 move, u8 moveSlot);
|
||||
static bool8 ShouldCalculateDamage(u16 move, s32 *dmg, u16 *powerOverride);
|
||||
|
||||
@ -124,12 +124,23 @@ static const u16 *const sPointsArray[] =
|
||||
// even if current Pokémon does not have corresponding move
|
||||
static const u16 sSpecialBattleStrings[] =
|
||||
{
|
||||
STRINGID_PKMNPERISHCOUNTFELL, STRINGID_PKMNWISHCAMETRUE, STRINGID_PKMNLOSTPPGRUDGE,
|
||||
STRINGID_PKMNTOOKFOE, STRINGID_PKMNABSORBEDNUTRIENTS, STRINGID_PKMNANCHOREDITSELF,
|
||||
STRINGID_PKMNAFFLICTEDBYCURSE, STRINGID_PKMNSAPPEDBYLEECHSEED, STRINGID_PKMNLOCKEDINNIGHTMARE,
|
||||
STRINGID_PKMNHURTBY, STRINGID_PKMNHURTBYBURN, STRINGID_PKMNHURTBYPOISON,
|
||||
STRINGID_PKMNHURTBYSPIKES, STRINGID_ATTACKERFAINTED, STRINGID_TARGETFAINTED,
|
||||
STRINGID_PKMNHITWITHRECOIL, STRINGID_PKMNCRASHED, TABLE_END
|
||||
STRINGID_PKMNPERISHCOUNTFELL,
|
||||
STRINGID_PKMNWISHCAMETRUE,
|
||||
STRINGID_PKMNLOSTPPGRUDGE,
|
||||
STRINGID_PKMNTOOKFOE,
|
||||
STRINGID_PKMNABSORBEDNUTRIENTS,
|
||||
STRINGID_PKMNANCHOREDITSELF,
|
||||
STRINGID_PKMNAFFLICTEDBYCURSE,
|
||||
STRINGID_PKMNSAPPEDBYLEECHSEED,
|
||||
STRINGID_PKMNLOCKEDINNIGHTMARE,
|
||||
STRINGID_PKMNHURTBY,
|
||||
STRINGID_PKMNHURTBYBURN,
|
||||
STRINGID_PKMNHURTBYPOISON,
|
||||
STRINGID_PKMNHURTBYSPIKES,
|
||||
STRINGID_BATTLERFAINTED,
|
||||
STRINGID_PKMNHITWITHRECOIL,
|
||||
STRINGID_PKMNCRASHED,
|
||||
TABLE_END
|
||||
};
|
||||
|
||||
// code
|
||||
@ -139,7 +150,7 @@ void BattleTv_SetDataBasedOnString(enum StringID stringId)
|
||||
u32 atkSide, defSide, effSide, scriptingSide;
|
||||
struct Pokemon *atkMon, *defMon;
|
||||
u8 moveSlot;
|
||||
u32 atkFlank, defFlank, effFlank;
|
||||
u32 atkFlank, defFlank, effFlank, flank;
|
||||
u8 *perishCount;
|
||||
u16 *statStringId, *finishedMoveId;
|
||||
|
||||
@ -452,8 +463,6 @@ void BattleTv_SetDataBasedOnString(enum StringID stringId)
|
||||
tvPtr->pos[atkSide][atkFlank].mudSportMonId = gBattlerPartyIndexes[gBattlerAttacker] + 1;
|
||||
tvPtr->pos[atkSide][atkFlank].mudSportMoveSlot = moveSlot;
|
||||
break;
|
||||
case STRINGID_ATTACKERFAINTED:
|
||||
AddPointsOnFainting(FALSE);
|
||||
case STRINGID_RETURNMON:
|
||||
if (tvPtr->pos[atkSide][atkFlank].waterSportMonId != 0)
|
||||
{
|
||||
@ -466,17 +475,22 @@ void BattleTv_SetDataBasedOnString(enum StringID stringId)
|
||||
tvPtr->pos[atkSide][atkFlank].mudSportMoveSlot = 0;
|
||||
}
|
||||
break;
|
||||
case STRINGID_TARGETFAINTED:
|
||||
AddPointsOnFainting(TRUE);
|
||||
if (tvPtr->pos[atkSide][defFlank].waterSportMonId != 0)
|
||||
case STRINGID_BATTLERFAINTED:
|
||||
AddPointsOnFainting();
|
||||
if (gBattlerAttacker == gBattleScripting.battler)
|
||||
flank = atkFlank;
|
||||
else
|
||||
flank = defFlank;
|
||||
|
||||
if (tvPtr->pos[atkSide][flank].waterSportMonId != 0)
|
||||
{
|
||||
tvPtr->pos[atkSide][defFlank].waterSportMonId = 0;
|
||||
tvPtr->pos[atkSide][defFlank].waterSportMoveSlot = 0;
|
||||
tvPtr->pos[atkSide][flank].waterSportMonId = 0;
|
||||
tvPtr->pos[atkSide][flank].waterSportMoveSlot = 0;
|
||||
}
|
||||
if (tvPtr->pos[atkSide][defFlank].mudSportMonId != 0)
|
||||
if (tvPtr->pos[atkSide][flank].mudSportMonId != 0)
|
||||
{
|
||||
tvPtr->pos[atkSide][defFlank].mudSportMonId = 0;
|
||||
tvPtr->pos[atkSide][defFlank].mudSportMoveSlot = 0;
|
||||
tvPtr->pos[atkSide][flank].mudSportMonId = 0;
|
||||
tvPtr->pos[atkSide][flank].mudSportMoveSlot = 0;
|
||||
}
|
||||
break;
|
||||
case STRINGID_PKMNRAISEDDEF:
|
||||
@ -1064,7 +1078,7 @@ static void AddMovePoints(u8 caseId, u16 arg1, u8 arg2, u8 arg3)
|
||||
}
|
||||
}
|
||||
|
||||
static void AddPointsOnFainting(bool8 targetFainted)
|
||||
static void AddPointsOnFainting(void)
|
||||
{
|
||||
struct BattleTv *tvPtr = &gBattleStruct->tv;
|
||||
u32 atkSide = GetBattlerSide(gBattlerAttacker);
|
||||
@ -1187,7 +1201,7 @@ static void AddPointsOnFainting(bool8 targetFainted)
|
||||
}
|
||||
break;
|
||||
case FNT_RECOIL:
|
||||
if (targetFainted == TRUE)
|
||||
if (gBattlerAttacker == gBattleScripting.battler)
|
||||
{
|
||||
AddMovePoints(PTS_FAINT_SET_UP, 0, atkSide,
|
||||
(gBattlerPartyIndexes[gBattlerAttacker]) * 4 + tvPtr->side[atkSide].usedMoveSlot);
|
||||
|
||||
@ -912,8 +912,7 @@ void HandleAction_NothingIsFainted(void)
|
||||
gCurrentTurnActionNumber++;
|
||||
gCurrentActionFuncId = gActionsByTurnOrder[gCurrentTurnActionNumber];
|
||||
gBattleStruct->synchronizeMoveEffect = MOVE_EFFECT_NONE;
|
||||
gHitMarker &= ~(HITMARKER_DESTINYBOND
|
||||
| HITMARKER_ATTACKSTRING_PRINTED
|
||||
gHitMarker &= ~(HITMARKER_ATTACKSTRING_PRINTED
|
||||
| HITMARKER_STATUS_ABILITY_EFFECT
|
||||
| HITMARKER_OBEYS);
|
||||
}
|
||||
@ -926,8 +925,7 @@ void HandleAction_ActionFinished(void)
|
||||
gCurrentTurnActionNumber++;
|
||||
gCurrentActionFuncId = gActionsByTurnOrder[gCurrentTurnActionNumber];
|
||||
memset(&gSpecialStatuses, 0, sizeof(gSpecialStatuses));
|
||||
gHitMarker &= ~(HITMARKER_DESTINYBOND
|
||||
| HITMARKER_ATTACKSTRING_PRINTED
|
||||
gHitMarker &= ~(HITMARKER_ATTACKSTRING_PRINTED
|
||||
| HITMARKER_STATUS_ABILITY_EFFECT
|
||||
| HITMARKER_OBEYS);
|
||||
|
||||
@ -1786,8 +1784,6 @@ void TryToRevertMimicryAndFlags(void)
|
||||
|
||||
bool32 BattleArenaTurnEnd(void)
|
||||
{
|
||||
gHitMarker |= HITMARKER_GRUDGE;
|
||||
|
||||
if ((gBattleTypeFlags & BATTLE_TYPE_ARENA)
|
||||
&& gBattleStruct->arenaTurnCounter == 2
|
||||
&& IsBattlerAlive(B_POSITION_PLAYER_LEFT) && IsBattlerAlive(B_POSITION_OPPONENT_LEFT))
|
||||
@ -1799,9 +1795,6 @@ bool32 BattleArenaTurnEnd(void)
|
||||
BattleScriptExecute(BattleScript_ArenaDoJudgment);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gHitMarker &= ~HITMARKER_GRUDGE;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
@ -239,8 +239,8 @@ SINGLE_BATTLE_TEST("Dynamax: Dynamaxed Pokemon are affected by Grudge")
|
||||
} SCENE {
|
||||
MESSAGE("The opposing Wobbuffet used Grudge!");
|
||||
MESSAGE("Wobbuffet used Max Strike!");
|
||||
MESSAGE("Wobbuffet's Scratch lost all its PP due to the grudge!");
|
||||
MESSAGE("The opposing Wobbuffet fainted!");
|
||||
MESSAGE("Wobbuffet's Scratch lost all its PP due to the grudge!");
|
||||
}
|
||||
}
|
||||
|
||||
@ -860,7 +860,7 @@ SINGLE_BATTLE_TEST("Dynamax: Max Hailstorm sets up hail")
|
||||
MESSAGE("It started to hail!");
|
||||
MESSAGE("The opposing Wobbuffet used Celebrate!");
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HAIL_CONTINUES);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -10,12 +10,18 @@ SINGLE_BATTLE_TEST("Destiny Bond faints the opposing mon if it fainted from the
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET) { HP(1); }
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_DESTINY_BOND); MOVE(opponent, MOVE_SCRATCH); }
|
||||
TURN {
|
||||
MOVE(player, MOVE_DESTINY_BOND);
|
||||
MOVE(opponent, MOVE_SCRATCH);
|
||||
SEND_OUT(player, 1);
|
||||
}
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_DESTINY_BOND, player);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_SCRATCH, opponent);
|
||||
MESSAGE("Wobbuffet fainted!");
|
||||
MESSAGE("Wobbuffet took its attacker down with it!");
|
||||
MESSAGE("The opposing Wobbuffet fainted!");
|
||||
}
|
||||
|
||||
@ -2,3 +2,52 @@
|
||||
#include "test/battle.h"
|
||||
|
||||
TO_DO_BATTLE_TEST("TODO: Write Grudge (Move Effect) test titles")
|
||||
|
||||
SINGLE_BATTLE_TEST("Grudge depletes all pp of the move that fainted the target")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET) { HP(1); }
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WOBBUFFET) { Moves(MOVE_CELEBRATE, MOVE_SCRATCH, MOVE_POUND, MOVE_SURF); };
|
||||
} WHEN {
|
||||
TURN {
|
||||
MOVE(player, MOVE_GRUDGE);
|
||||
MOVE(opponent, MOVE_SCRATCH);
|
||||
SEND_OUT(player, 1);
|
||||
}
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_GRUDGE, player);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_SCRATCH, opponent);
|
||||
MESSAGE("Wobbuffet fainted!");
|
||||
} THEN {
|
||||
EXPECT_GT(opponent->pp[0], 0);
|
||||
EXPECT_EQ(opponent->pp[1], 0);
|
||||
EXPECT_GT(opponent->pp[2], 0);
|
||||
EXPECT_GT(opponent->pp[3], 0);
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Grudge does not depletes pp of a z-move")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET) { HP(1); }
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WOBBUFFET) { Item(ITEM_NORMALIUM_Z); Moves(MOVE_CELEBRATE, MOVE_SCRATCH, MOVE_POUND, MOVE_SURF); };
|
||||
} WHEN {
|
||||
TURN {
|
||||
MOVE(player, MOVE_GRUDGE);
|
||||
MOVE(opponent, MOVE_SCRATCH, gimmick: GIMMICK_Z_MOVE);
|
||||
SEND_OUT(player, 1);
|
||||
}
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_GRUDGE, player);
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_ZMOVE_ACTIVATE, opponent);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_BREAKNECK_BLITZ, opponent);
|
||||
MESSAGE("Wobbuffet fainted!");
|
||||
} THEN {
|
||||
EXPECT_GT(opponent->pp[0], 0);
|
||||
EXPECT_GT(opponent->pp[1], 0);
|
||||
EXPECT_GT(opponent->pp[2], 0);
|
||||
EXPECT_GT(opponent->pp[3], 0);
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user