diff --git a/asm/macros/battle_script.inc b/asm/macros/battle_script.inc index 95b3a2303..cc89e0aae 100644 --- a/asm/macros/battle_script.inc +++ b/asm/macros/battle_script.inc @@ -1416,6 +1416,30 @@ .4byte \ptr .endm + .macro setabilitysimple battler ptr + various \battler VARIOUS_SET_SIMPLE_BEAM + .4byte \ptr + .endm + + .macro tryentrainment ptr + various BS_ATTACKER, VARIOUS_TRY_ENTRAINMENT + .4byte \ptr + .endm + + .macro setlastusedability battler + various \battler, VARIOUS_SET_LAST_USED_ABILITY + .endm + + .macro tryhealpulse battler ptr + various \battler, VARIOUS_TRY_HEAL_PULSE + .4byte \ptr + .endm + + .macro tryquash ptr + various BS_ATTACKER, VARIOUS_TRY_QUASH + .4byte \ptr + .endm + @ helpful macros .macro setstatchanger stat, stages, down setbyte sSTATCHANGER \stat | \stages << 4 | \down << 7 diff --git a/data/battle_scripts_1.s b/data/battle_scripts_1.s index fed31bb51..4f877d11a 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -274,6 +274,63 @@ gBattleScriptsForMoveEffects:: @ 82D86A8 .4byte BattleScript_EffectMetalBurst .4byte BattleScript_EffectLuckyChant .4byte BattleScript_EffectSuckerPunch + .4byte BattleScript_EffectSpecialDefenseDownHit2 + .4byte BattleScript_EffectSimpleBeam + .4byte BattleScript_EffectEntrainment + .4byte BattleScript_EffectHealPulse + .4byte BattleScript_EffectQuash + +BattleScript_EffectQuash: + attackcanceler + accuracycheck BattleScript_PrintMoveMissed, ACC_CURR_MOVE + attackstring + ppreduce + tryquash BattleScript_ButItFailed + attackanimation + waitanimation + printstring STRINGID_QUASHSUCCESS + waitmessage 0x40 + goto BattleScript_MoveEnd + +BattleScript_EffectHealPulse: + attackcanceler + attackstring + ppreduce + accuracycheck BattleScript_ButItFailed, NO_ACC_CALC_CHECK_LOCK_ON + jumpifsubstituteblocks BattleScript_ButItFailed + tryhealpulse BS_TARGET, BattleScript_AlreadyAtFullHp + attackanimation + waitanimation + healthbarupdate BS_TARGET + datahpupdate BS_TARGET + printstring STRINGID_PKMNREGAINEDHEALTH + waitmessage 0x40 + goto BattleScript_MoveEnd + +BattleScript_EffectEntrainment: + attackcanceler + accuracycheck BattleScript_PrintMoveMissed, ACC_CURR_MOVE + attackstring + ppreduce + tryentrainment BattleScript_ButItFailed + attackanimation + waitanimation + setlastusedability BS_TARGET + printstring STRINGID_PKMNACQUIREDABILITY + waitmessage 0x40 + goto BattleScript_MoveEnd + +BattleScript_EffectSimpleBeam: + attackcanceler + accuracycheck BattleScript_PrintMoveMissed, ACC_CURR_MOVE + attackstring + ppreduce + setabilitysimple BS_TARGET, BattleScript_ButItFailed + attackanimation + waitanimation + printstring STRINGID_PKMNACQUIREDSIMPLE + waitmessage 0x40 + goto BattleScript_MoveEnd BattleScript_EffectSuckerPunch: attackcanceler @@ -1547,6 +1604,10 @@ BattleScript_EffectSpecialAttackDownHit:: BattleScript_EffectSpecialDefenseDownHit:: setmoveeffect MOVE_EFFECT_SP_DEF_MINUS_1 goto BattleScript_EffectHit + +BattleScript_EffectSpecialDefenseDownHit2:: + setmoveeffect MOVE_EFFECT_SP_DEF_MINUS_2 + goto BattleScript_EffectHit BattleScript_EffectAccuracyDownHit:: setmoveeffect MOVE_EFFECT_ACC_MINUS_1 @@ -4044,6 +4105,21 @@ BattleScript_SpikesFree:: printstring STRINGID_PKMNBLEWAWAYSPIKES waitmessage 0x40 return + +BattleScript_ToxicSpikesFree:: + printstring STRINGID_PKMNBLEWAWAYTOXICSPIKES + waitmessage 0x40 + return + +BattleScript_StickyWebFree:: + printstring STRINGID_PKMNBLEWAWAYSTICKYWEB + waitmessage 0x40 + return + +BattleScript_StealthRockFree:: + printstring STRINGID_PKMNBLEWAWAYSTEALTHROCK + waitmessage 0x40 + return BattleScript_MonTookFutureAttack:: printstring STRINGID_PKMNTOOKATTACK diff --git a/include/battle_scripts.h b/include/battle_scripts.h index 274af5cae..f9333ca41 100644 --- a/include/battle_scripts.h +++ b/include/battle_scripts.h @@ -332,5 +332,8 @@ extern const u8 BattleScript_SelectingNotAllowedMoveGravityInPalace[]; extern const u8 BattleScript_SelectingNotAllowedMoveHealBlock[]; extern const u8 BattleScript_MoveUsedHealBlockPrevents[]; extern const u8 BattleScript_SelectingNotAllowedMoveHealBlockInPalace[]; +extern const u8 BattleScript_ToxicSpikesFree[]; +extern const u8 BattleScript_StickyWebFree[]; +extern const u8 BattleScript_StealthRockFree[]; #endif // GUARD_BATTLE_SCRIPTS_H diff --git a/include/constants/battle_move_effects.h b/include/constants/battle_move_effects.h index dab3b46be..c81d259f8 100644 --- a/include/constants/battle_move_effects.h +++ b/include/constants/battle_move_effects.h @@ -263,5 +263,10 @@ #define EFFECT_METAL_BURST 257 #define EFFECT_LUCKY_CHANT 258 #define EFFECT_SUCKER_PUNCH 259 +#define EFFECT_SPECIAL_DEFENSE_DOWN_HIT_2 260 +#define EFFECT_SIMPLE_BEAM 261 +#define EFFECT_ENTRAINMENT 262 +#define EFFECT_HEAL_PULSE 263 +#define EFFECT_QUASH 264 #endif // GUARD_CONSTANTS_BATTLE_MOVE_EFFECTS_H diff --git a/include/constants/battle_script_commands.h b/include/constants/battle_script_commands.h index e8706ed31..eef80d608 100644 --- a/include/constants/battle_script_commands.h +++ b/include/constants/battle_script_commands.h @@ -85,6 +85,11 @@ #define VARIOUS_PLAY_MOVE_ANIMATION 36 #define VARIOUS_SET_LUCKY_CHANT 37 #define VARIOUS_SUCKER_PUNCH_CHECK 38 +#define VARIOUS_SET_SIMPLE_BEAM 39 +#define VARIOUS_TRY_ENTRAINMENT 40 +#define VARIOUS_SET_LAST_USED_ABILITY 41 +#define VARIOUS_TRY_HEAL_PULSE 42 +#define VARIOUS_TRY_QUASH 43 // atk80, dmg manipulation #define ATK80_DMG_CHANGE_SIGN 0 diff --git a/include/constants/battle_string_ids.h b/include/constants/battle_string_ids.h index 63bbf599f..abab41bb8 100644 --- a/include/constants/battle_string_ids.h +++ b/include/constants/battle_string_ids.h @@ -491,6 +491,10 @@ #define STRINGID_HEALBLOCKPREVENTSUSAGE 488 #define STRINGID_NOTDONEYET 489 #define STRINGID_STICKYWEBUSED 490 +#define STRINGID_QUASHSUCCESS 491 +#define STRINGID_PKMNBLEWAWAYTOXICSPIKES 492 +#define STRINGID_PKMNBLEWAWAYSTICKYWEB 493 +#define STRINGID_PKMNBLEWAWAYSTEALTHROCK 494 #define BATTLESTRINGS_COUNT 506 diff --git a/include/data/battle_moves.h b/include/data/battle_moves.h index c7dcd5749..3db40d970 100644 --- a/include/data/battle_moves.h +++ b/include/data/battle_moves.h @@ -5896,7 +5896,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_GEN6] = .split = SPLIT_PHYSICAL, }, { // MOVE_ACID_SPRAY - .effect = EFFECT_PLACEHOLDER, // Needs a custom move effect + .effect = EFFECT_SPECIAL_DEFENSE_DOWN_HIT_2, .power = 40, .type = TYPE_POISON, .accuracy = 100, @@ -5920,7 +5920,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_GEN6] = .split = SPLIT_PHYSICAL, }, { // MOVE_SIMPLE_BEAM - .effect = EFFECT_PLACEHOLDER, // Needs a custom move effect + .effect = EFFECT_SIMPLE_BEAM, .power = 0, .type = TYPE_NORMAL, .accuracy = 100, @@ -5932,7 +5932,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_GEN6] = .split = SPLIT_STATUS, }, { // MOVE_ENTRAINMENT - .effect = EFFECT_PLACEHOLDER, // Needs a custom move effect + .effect = EFFECT_ENTRAINMENT, .power = 0, .type = TYPE_NORMAL, .accuracy = 100, @@ -6064,7 +6064,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_GEN6] = .split = SPLIT_STATUS, }, { // MOVE_HEAL_PULSE - .effect = EFFECT_PLACEHOLDER, // Needs a custom move effect (always bypasses accuracy checks) + .effect = EFFECT_HEAL_PULSE, .power = 0, .type = TYPE_PSYCHIC, .accuracy = 0, @@ -6136,7 +6136,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_GEN6] = .split = SPLIT_SPECIAL, }, { // MOVE_QUASH - .effect = EFFECT_PLACEHOLDER, // Needs a custom move effect + .effect = EFFECT_QUASH, .power = 0, .type = TYPE_DARK, .accuracy = 100, diff --git a/src/battle_message.c b/src/battle_message.c index ecaa88aad..c8207b0a8 100644 --- a/src/battle_message.c +++ b/src/battle_message.c @@ -629,6 +629,10 @@ static const u8 sText_PkmnMoveBouncedViaAbility[] = _("{B_ATK_NAME_WITH_PREFIX} static const u8 sText_ImposterTransform[] = _("{B_ATK_NAME_WITH_PREFIX} transformed into\n{B_DEF_NAME_WITH_PREFIX} using {B_LAST_ABILITY}!"); static const u8 sText_NotDoneYet[] = _("This move effect is not done yet!\p"); static const u8 sText_StickyWebUsed[] = _(""); +static const u8 sText_QuashSuccess[] = _(""); +static const u8 sText_PkmnBlewAwayToxicSpikes[] = _("{B_ATK_NAME_WITH_PREFIX} blew away\nTOXIC SPIKES!"); +static const u8 sText_PkmnBlewAwayStickyWeb[] = _("{B_ATK_NAME_WITH_PREFIX} blew away\nSTICKY WEB!"); +static const u8 sText_PkmnBlewAwayStealthRock[] = _("{B_ATK_NAME_WITH_PREFIX} blew away\nSTEALTH ROCK!"); // New selection strings, they must end with "\p". // Use {B_LAST_ITEM} and {B_CURRENT_MOVE}. @@ -1118,6 +1122,10 @@ const u8 *const gBattleStringsTable[BATTLESTRINGS_COUNT] = sText_HealBlockPreventsUsage, sText_NotDoneYet, sText_StickyWebUsed, + sText_QuashSuccess, + sText_PkmnBlewAwayToxicSpikes, + sText_PkmnBlewAwayStickyWeb, + sText_PkmnBlewAwayStealthRock, }; const u16 gMagicCoatBounceStringIds[] = diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 6a086fd56..bbb783d79 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -6061,7 +6061,7 @@ static bool32 HasAttackerFaintedTarget(void) static void atk76_various(void) { u8 side; - s32 i; + s32 i, j; u8 data[10]; if (gBattleControllerExecFlags) @@ -6330,6 +6330,106 @@ static void atk76_various(void) else gBattlescriptCurrInstr += 7; return; + case VARIOUS_SET_SIMPLE_BEAM: + switch (gBattleMons[gActiveBattler].ability) + { + case ABILITY_SIMPLE: + case ABILITY_TRUANT: + case ABILITY_STANCE_CHANGE: + case ABILITY_MULTITYPE: + gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); + break; + default: + gBattleMons[gActiveBattler].ability = ABILITY_SIMPLE; + gBattlescriptCurrInstr += 7; + break; + } + return; + case VARIOUS_TRY_ENTRAINMENT: + switch (gBattleMons[gBattlerTarget].ability) + { + case ABILITY_TRUANT: + case ABILITY_MULTITYPE: + case ABILITY_STANCE_CHANGE: + case ABILITY_SCHOOLING: + case ABILITY_COMATOSE: + case ABILITY_SHIELDS_DOWN: + case ABILITY_DISGUISE: + case ABILITY_RKS_SYSTEM: + case ABILITY_BATTLE_BOND: + gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); + return; + } + switch (gBattleMons[gBattlerAttacker].ability) + { + case ABILITY_TRACE: + case ABILITY_FORECAST: + case ABILITY_FLOWER_GIFT: + case ABILITY_ZEN_MODE: + case ABILITY_ILLUSION: + case ABILITY_IMPOSTER: + case ABILITY_POWER_OF_ALCHEMY: + case ABILITY_RECEIVER: + case ABILITY_DISGUISE: + case ABILITY_POWER_CONSTRUCT: + gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); + return; + } + if (gBattleMons[gBattlerTarget].ability == gBattleMons[gBattlerAttacker].ability) + { + gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); + } + else + { + gBattleMons[gBattlerTarget].ability = gBattleMons[gBattlerAttacker].ability; + gBattlescriptCurrInstr += 7; + } + return; + case VARIOUS_SET_LAST_USED_ABILITY: + gLastUsedAbility = gBattleMons[gActiveBattler].ability; + break; + case VARIOUS_TRY_HEAL_PULSE: + if (BATTLER_MAX_HP(gActiveBattler)) + { + gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); + } + else + { + if (GetBattlerAbility(gBattlerAttacker) == ABILITY_MEGA_LAUNCHER && gBattleMoves[gCurrentMove].flags & FLAG_MEGA_LAUNCHER_BOOST) + gBattleMoveDamage = -(gBattleMons[gActiveBattler].maxHP * 75 / 100); + else + gBattleMoveDamage = -(gBattleMons[gActiveBattler].maxHP / 2); + + if (gBattleMoveDamage == 0) + gBattleMoveDamage = -1; + gBattlescriptCurrInstr += 7; + } + return; + case VARIOUS_TRY_QUASH: + if (GetBattlerTurnOrderNum(gBattlerAttacker) > GetBattlerTurnOrderNum(gBattlerTarget)) + { + gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); + } + else + { + for (i = 0; i < gBattlersCount; i++) + data[i] = gBattlerByTurnOrder[i]; + for (i = 0; i < gBattlersCount; i++) + { + if (data[i] == gBattlerTarget) + { + for (j = i + 1; j < gBattlersCount; j++) + data[i++] = data[j]; + } + else + { + gBattlerByTurnOrder[i] = data[i]; + } + } + gBattlerByTurnOrder[gBattlersCount - 1] = gBattlerTarget; + gBattlescriptCurrInstr += 7; + } + return; } gBattlescriptCurrInstr += 3; @@ -8606,6 +8706,8 @@ static void atkBD_copyfoestats(void) // psych up static void atkBE_rapidspinfree(void) { + u8 atkSide = GetBattlerSide(gBattlerAttacker); + if (gBattleMons[gBattlerAttacker].status2 & STATUS2_WRAPPED) { gBattleScripting.battler = gBattlerTarget; @@ -8628,13 +8730,34 @@ static void atkBE_rapidspinfree(void) BattleScriptPushCursor(); gBattlescriptCurrInstr = BattleScript_LeechSeedFree; } - else if (gSideStatuses[GetBattlerSide(gBattlerAttacker)] & SIDE_STATUS_SPIKES) + else if (gSideStatuses[atkSide] & SIDE_STATUS_SPIKES) { - gSideStatuses[GetBattlerSide(gBattlerAttacker)] &= ~(SIDE_STATUS_SPIKES); - gSideTimers[GetBattlerSide(gBattlerAttacker)].spikesAmount = 0; + gSideStatuses[atkSide] &= ~(SIDE_STATUS_SPIKES); + gSideTimers[atkSide].spikesAmount = 0; BattleScriptPushCursor(); gBattlescriptCurrInstr = BattleScript_SpikesFree; } + else if (gSideStatuses[atkSide] & SIDE_STATUS_TOXIC_SPIKES) + { + gSideStatuses[atkSide] &= ~(SIDE_STATUS_TOXIC_SPIKES); + gSideTimers[atkSide].toxicSpikesAmount = 0; + BattleScriptPushCursor(); + gBattlescriptCurrInstr = BattleScript_ToxicSpikesFree; + } + else if (gSideStatuses[atkSide] & SIDE_STATUS_STICKY_WEB) + { + gSideStatuses[atkSide] &= ~(SIDE_STATUS_STICKY_WEB); + gSideTimers[atkSide].stickyWebAmount = 0; + BattleScriptPushCursor(); + gBattlescriptCurrInstr = BattleScript_StickyWebFree; + } + else if (gSideStatuses[atkSide] & SIDE_STATUS_STEALTH_ROCK) + { + gSideStatuses[atkSide] &= ~(SIDE_STATUS_STEALTH_ROCK); + gSideTimers[atkSide].stealthRockAmount = 0; + BattleScriptPushCursor(); + gBattlescriptCurrInstr = BattleScript_StealthRockFree; + } else { gBattlescriptCurrInstr++;