Rocky Helmet before Knock Off

This commit is contained in:
DizzyEggg 2020-06-25 16:15:11 +02:00
parent f252cd8003
commit 548a43f8d9
5 changed files with 76 additions and 48 deletions

View File

@ -1751,6 +1751,11 @@
various \battler, VARIOUS_SET_LAST_USED_ITEM
.endm
.macro jumpifabsent battler:req, ptr:req
various \battler, VARIOUS_JUMP_IF_ABSENT
.4byte \ptr
.endm
@ helpful macros
.macro setstatchanger stat:req, stages:req, down:req
setbyte sSTATCHANGER \stat | \stages << 3 | \down << 7

View File

@ -7100,8 +7100,11 @@ BattleScript_RoughSkinActivates::
return
BattleScript_RockyHelmetActivates::
@ don't play the animation for a fainted mon
jumpifabsent BS_TARGET, BattleScript_RockyHelmetActivatesDmg
playanimation BS_TARGET, B_ANIM_HELD_ITEM_EFFECT, NULL
waitanimation
BattleScript_RockyHelmetActivatesDmg:
call BattleScript_HurtAttacker
return

View File

@ -547,6 +547,7 @@ struct BattleStruct
u8 friskedBattler; // Frisk needs to identify 2 battlers in double battles.
bool8 friskedAbility; // If identifies two mons, show the ability pop-up only once.
u8 sameMoveTurns[MAX_BATTLERS_COUNT]; // For Metronome, number of times the same moves has been SUCCESFULLY used.
u16 moveEffect2; // For Knock Off
};
#define GET_MOVE_TYPE(move, typeArg) \

View File

@ -161,6 +161,7 @@
#define VARIOUS_INFATUATE_WITH_BATTLER 98
#define VARIOUS_SET_LAST_USED_ITEM 99
#define VARIOUS_PARALYZE_TYPE_IMMUNITY 100
#define VARIOUS_JUMP_IF_ABSENT 101
// Cmd_manipulatedamage
#define DMG_CHANGE_SIGN 0
@ -200,16 +201,17 @@
#define MOVEEND_ATTACKER_VISIBLE 11
#define MOVEEND_TARGET_VISIBLE 12
#define MOVEEND_ITEM_EFFECTS_TARGET 13
#define MOVEEND_ITEM_EFFECTS_ALL 14
#define MOVEEND_KINGSROCK_SHELLBELL 15
#define MOVEEND_SUBSTITUTE 16
#define MOVEEND_UPDATE_LAST_MOVES 17
#define MOVEEND_MIRROR_MOVE 18
#define MOVEEND_NEXT_TARGET 19
#define MOVEEND_LIFE_ORB 20
#define MOVEEND_DANCER 21
#define MOVEEND_CLEAR_BITS 22
#define MOVEEND_COUNT 23
#define MOVEEND_MOVE_EFFECTS2 14
#define MOVEEND_ITEM_EFFECTS_ALL 15
#define MOVEEND_KINGSROCK_SHELLBELL 16
#define MOVEEND_SUBSTITUTE 17
#define MOVEEND_UPDATE_LAST_MOVES 18
#define MOVEEND_MIRROR_MOVE 19
#define MOVEEND_NEXT_TARGET 20
#define MOVEEND_LIFE_ORB 21
#define MOVEEND_DANCER 22
#define MOVEEND_CLEAR_BITS 23
#define MOVEEND_COUNT 24
// stat flags for Cmd_playstatchangeanimation
#define BIT_HP 0x1

View File

@ -2179,6 +2179,14 @@ void SetMoveEffect(bool32 primary, u32 certain)
bool32 statusChanged = FALSE;
bool32 noSunCanFreeze = TRUE;
switch (gBattleScripting.moveEffect) // Set move effects which happen later on
{
case MOVE_EFFECT_KNOCK_OFF:
gBattleStruct->moveEffect2 = gBattleScripting.moveEffect;
gBattlescriptCurrInstr++;
return;
}
if (gBattleScripting.moveEffect & MOVE_EFFECT_AFFECTS_USER)
{
gEffectBattler = gBattlerAttacker; // battlerId that effects get applied on
@ -2861,43 +2869,6 @@ void SetMoveEffect(bool32 primary, u32 certain)
gBattleMons[gEffectBattler].status2 |= (((Random() & 1) + 2) << 0xA);
}
break;
case MOVE_EFFECT_KNOCK_OFF:
if (!CanBattlerGetOrLoseItem(gEffectBattler, gBattleMons[gEffectBattler].item))
{
gBattlescriptCurrInstr++;
}
else if (GetBattlerAbility(gEffectBattler) == ABILITY_STICKY_HOLD)
{
if (gBattleMons[gEffectBattler].item == 0)
{
gBattlescriptCurrInstr++;
}
else
{
gLastUsedAbility = ABILITY_STICKY_HOLD;
gBattlescriptCurrInstr = BattleScript_StickyHoldActivates;
RecordAbilityBattle(gEffectBattler, ABILITY_STICKY_HOLD);
}
}
else if (gBattleMons[gEffectBattler].item)
{
side = GetBattlerSide(gEffectBattler);
gLastUsedItem = gBattleMons[gEffectBattler].item;
gBattleMons[gEffectBattler].item = 0;
gWishFutureKnock.knockedOffMons[side] |= gBitTable[gBattlerPartyIndexes[gEffectBattler]];
CheckSetUnburden(gEffectBattler);
BattleScriptPush(gBattlescriptCurrInstr + 1);
gBattlescriptCurrInstr = BattleScript_KnockedOff;
gBattleStruct->choicedMove[gEffectBattler] = 0;
}
else
{
gBattlescriptCurrInstr++;
}
break;
case MOVE_EFFECT_SP_ATK_TWO_DOWN: // Overheat
BattleScriptPush(gBattlescriptCurrInstr + 1);
gBattlescriptCurrInstr = BattleScript_SAtkDown2;
@ -4437,6 +4408,36 @@ static void Cmd_playstatchangeanimation(void)
}
}
static bool32 TryKnockOffBattleScript(u32 battlerDef)
{
if (gBattleMons[battlerDef].item != 0
&& CanBattlerGetOrLoseItem(battlerDef, gBattleMons[battlerDef].item)
&& !NoAliveMonsForEitherParty())
{
if (GetBattlerAbility(battlerDef) == ABILITY_STICKY_HOLD && IsBattlerAlive(battlerDef))
{
gBattlerAbility = battlerDef;
BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_StickyHoldActivates;
}
else
{
u32 side = GetBattlerSide(battlerDef);
gLastUsedItem = gBattleMons[battlerDef].item;
gBattleMons[battlerDef].item = 0;
gBattleStruct->choicedMove[battlerDef] = 0;
gWishFutureKnock.knockedOffMons[side] |= gBitTable[gBattlerPartyIndexes[battlerDef]];
CheckSetUnburden(battlerDef);
BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_KnockedOff;
}
return TRUE;
}
return FALSE;
}
static void Cmd_moveend(void)
{
s32 i;
@ -4594,6 +4595,16 @@ static void Cmd_moveend(void)
effect = TRUE;
gBattleScripting.moveendState++;
break;
case MOVEEND_MOVE_EFFECTS2: // For effects which should happen after target items, for example Knock Off after damage from Rocky Helmet.
switch (gBattleStruct->moveEffect2)
{
case MOVE_EFFECT_KNOCK_OFF:
effect = TryKnockOffBattleScript(gBattlerTarget);
break;
}
gBattleStruct->moveEffect2 = 0;
gBattleScripting.moveendState++;
break;
case MOVEEND_ITEM_EFFECTS_ALL: // item effects for all battlers
if (ItemBattleEffects(ITEMEFFECT_MOVE_END, 0, FALSE))
effect = TRUE;
@ -6841,6 +6852,12 @@ static void Cmd_various(void)
else
gBattlescriptCurrInstr += 7;
return;
case VARIOUS_JUMP_IF_ABSENT:
if (!IsBattlerAlive(gActiveBattler))
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3);
else
gBattlescriptCurrInstr += 7;
return;
case VARIOUS_JUMP_IF_SHIELDS_DOWN_PROTECTED:
if (IsShieldsDownProtected(gActiveBattler))
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3);
@ -9595,7 +9612,7 @@ static void Cmd_disablelastusedattack(void)
gDisableStructs[gBattlerTarget].disableTimer = (Random() & 3) + 2;
else if (B_DISABLE_TURNS == GEN_4)
gDisableStructs[gBattlerTarget].disableTimer = (Random() & 3) + 4;
else
else
gDisableStructs[gBattlerTarget].disableTimer = 4;
gDisableStructs[gBattlerTarget].disableTimerStartValue = gDisableStructs[gBattlerTarget].disableTimer; // used to save the random amount of turns?
gBattlescriptCurrInstr += 5;