From 1c95c36338addcaccb218f8444284dd715d7f966 Mon Sep 17 00:00:00 2001 From: DizzyEggg Date: Thu, 26 Jul 2018 20:36:16 +0200 Subject: [PATCH] Healing Wish and Lunar Dance --- asm/macros/battle_script.inc | 20 +++++++++ data/battle_scripts_1.s | 51 ++++++++++++++++++++-- include/constants/battle_move_effects.h | 2 +- include/constants/battle_script_commands.h | 4 ++ include/constants/battle_string_ids.h | 5 ++- include/data/battle_moves.h | 4 +- src/battle_controller_opponent.c | 7 +++ src/battle_message.c | 11 +++++ src/battle_script_commands.c | 37 ++++++++++++++-- 9 files changed, 131 insertions(+), 10 deletions(-) diff --git a/asm/macros/battle_script.inc b/asm/macros/battle_script.inc index bd6a2ac7e..9bc4b0687 100644 --- a/asm/macros/battle_script.inc +++ b/asm/macros/battle_script.inc @@ -1373,6 +1373,18 @@ various BS_TARGET, VARIOUS_RESTORE_TARGET .endm + .macro instanthpdrop battler + various \battler, VARIOUS_INSTANT_HP_DROP + .endm + + .macro clearstatus battler + various \battler, VARIOUS_CLEAR_STATUS + .endm + + .macro restorepp battler + various \battler, VARIOUS_RESTORE_PP + .endm + @ helpful macros .macro setstatchanger stat, stages, down setbyte sSTATCHANGER \stat | \stages << 4 | \down << 7 @@ -1430,6 +1442,10 @@ jumpifhalfword CMP_NOT_EQUAL, gCurrentMove, \move, \jumpptr .endm + .macro jumpifnotchosenmove move, jumpptr + jumpifhalfword CMP_NOT_EQUAL, gChosenMove, \move, \jumpptr + .endm + .macro jumpifstatus3 bank, status, jumpptr jumpifstatus3condition \bank, \status, 0x0, \jumpptr .endm @@ -1453,3 +1469,7 @@ .macro dmg_1_8_targethp manipulatedamage ATK80_1_8_TARGET_HP .endm + + .macro dmgtomaxattackerhp + manipulatedamage ATK80_FULL_ATTACKER_HP + .endm diff --git a/data/battle_scripts_1.s b/data/battle_scripts_1.s index 0d20dd5ed..5ec5c41a5 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -124,7 +124,7 @@ gBattleScriptsForMoveEffects:: @ 82D86A8 .4byte BattleScript_EffectNightmare .4byte BattleScript_EffectMinimize .4byte BattleScript_EffectCurse - .4byte BattleScript_EffectUnused6e + .4byte BattleScript_EffectHealingWish .4byte BattleScript_EffectProtect .4byte BattleScript_EffectSpikes .4byte BattleScript_EffectForesight @@ -271,6 +271,52 @@ gBattleScriptsForMoveEffects:: @ 82D86A8 .4byte BattleScript_EffectPowerSplit .4byte BattleScript_EffectGuardSplit +BattleScript_EffectHealingWish: + attackcanceler + attackstring + ppreduce + attackanimation + waitanimation + instanthpdrop BS_ATTACKER + setatkhptozero + tryfaintmon BS_ATTACKER, FALSE, NULL + jumpifcantswitch ATK4F_DONT_CHECK_STATUSES | BS_ATTACKER, BattleScript_EffectHealingWishEnd + openpartyscreen 0x1, BattleScript_EffectHealingWishEnd + switchoutabilities BS_ATTACKER + waitstate + switchhandleorder BS_ATTACKER, 0x2 + returnatktoball + getswitchedmondata BS_ATTACKER + switchindataupdate BS_ATTACKER + hpthresholds BS_ATTACKER + printstring STRINGID_SWITCHINMON + switchinanim BS_ATTACKER, TRUE + waitstate + setbyte cMULTISTRING_CHOOSER 0 + jumpifnotchosenmove MOVE_LUNAR_DANCE BattleScript_EffectHealingWishNewMon + setbyte cMULTISTRING_CHOOSER 1 + restorepp BS_ATTACKER +BattleScript_EffectHealingWishNewMon: + printfromtable gHealingWishStringIds + waitmessage 0x40 + playanimation BS_ATTACKER, B_ANIM_WISH_HEAL, NULL + waitanimation + dmgtomaxattackerhp + manipulatedamage ATK80_DMG_CHANGE_SIGN + healthbarupdate BS_ATTACKER + datahpupdate BS_ATTACKER + clearstatus BS_ATTACKER + waitstate + updatestatusicon BS_ATTACKER + waitstate + printstring STRINGID_HEALINGWISHHEALED + waitmessage 0x40 + switchineffects BS_ATTACKER +BattleScript_EffectHealingWishEnd: + setbyte sMOVEEND_STATE, 0x0 + moveend 0x0, 0x0 + end + BattleScript_EffectWorrySeed: attackcanceler accuracycheck BattleScript_PrintMoveMissed, ACC_CURR_MOVE @@ -543,7 +589,6 @@ BattleScript_EffectVitalThrow: BattleScript_EffectUnused60: BattleScript_EffectFalseSwipe: BattleScript_EffectAlwaysCrit: -BattleScript_EffectUnused6e: BattleScript_EffectPursuit: BattleScript_EffectUnused8d: BattleScript_EffectPlaceholder209: @@ -2073,7 +2118,7 @@ BattleScript_EffectBatonPass:: jumpifcantswitch ATK4F_DONT_CHECK_STATUSES | BS_ATTACKER, BattleScript_ButItFailed attackanimation waitanimation - openpartyscreen 0x1, BattleScript_ButItFailed + openpartyscreen BS_ATTACKER, BattleScript_ButItFailed switchoutabilities BS_ATTACKER waitstate switchhandleorder BS_ATTACKER, 0x2 diff --git a/include/constants/battle_move_effects.h b/include/constants/battle_move_effects.h index 0924d6576..e5f2a678e 100644 --- a/include/constants/battle_move_effects.h +++ b/include/constants/battle_move_effects.h @@ -111,7 +111,7 @@ #define EFFECT_NIGHTMARE 107 #define EFFECT_MINIMIZE 108 #define EFFECT_CURSE 109 -#define EFFECT_UNUSED_6E 110 +#define EFFECT_HEALING_WISH 110 #define EFFECT_PROTECT 111 #define EFFECT_SPIKES 112 #define EFFECT_FORESIGHT 113 diff --git a/include/constants/battle_script_commands.h b/include/constants/battle_script_commands.h index 2e73bd808..fdce1e686 100644 --- a/include/constants/battle_script_commands.h +++ b/include/constants/battle_script_commands.h @@ -76,12 +76,16 @@ #define VARIOUS_SWITCHIN_ABILITIES 28 #define VARIOUS_SAVE_TARGET 29 #define VARIOUS_RESTORE_TARGET 30 +#define VARIOUS_INSTANT_HP_DROP 31 +#define VARIOUS_CLEAR_STATUS 32 +#define VARIOUS_RESTORE_PP 33 // atk80, dmg manipulation #define ATK80_DMG_CHANGE_SIGN 0 #define ATK80_DMG_HALF_BY_TWO_NOT_MORE_THAN_HALF_MAX_HP 1 #define ATK80_DMG_DOUBLED 2 #define ATK80_1_8_TARGET_HP 3 +#define ATK80_FULL_ATTACKER_HP 4 // atk4F, a flag used for the jumpifcantswitch command #define ATK4F_DONT_CHECK_STATUSES 0x80 diff --git a/include/constants/battle_string_ids.h b/include/constants/battle_string_ids.h index 3ba5c7b4d..42c5c0566 100644 --- a/include/constants/battle_string_ids.h +++ b/include/constants/battle_string_ids.h @@ -477,7 +477,10 @@ #define STRINGID_TOXICSPIKESABSORBED 474 #define STRINGID_TOXICSPIKESPOISONED 475 #define STRINGID_STICKYWEBSWITCHIN 476 +#define STRINGID_HEALINGWISHCAMETRUE 477 +#define STRINGID_HEALINGWISHHEALED 478 +#define STRINGID_LUNARDANCECAMETRUE 479 -#define BATTLESTRINGS_COUNT 467 +#define BATTLESTRINGS_COUNT 490 #endif // GUARD_CONSTANTS_BATTLE_STRING_IDS_H diff --git a/include/data/battle_moves.h b/include/data/battle_moves.h index 3d33820c7..30583abb0 100644 --- a/include/data/battle_moves.h +++ b/include/data/battle_moves.h @@ -4336,7 +4336,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_GEN6] = .split = SPLIT_PHYSICAL, }, { // MOVE_HEALING_WISH - .effect = EFFECT_PLACEHOLDER_209, + .effect = EFFECT_HEALING_WISH, .power = 0, .type = TYPE_PSYCHIC, .accuracy = 0, @@ -5536,7 +5536,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_GEN6] = .split = SPLIT_SPECIAL, }, { // MOVE_LUNAR_DANCE - .effect = EFFECT_PLACEHOLDER_209, + .effect = EFFECT_HEALING_WISH, .power = 0, .type = TYPE_PSYCHIC, .accuracy = 0, diff --git a/src/battle_controller_opponent.c b/src/battle_controller_opponent.c index 1eaa9da18..940f1b77a 100644 --- a/src/battle_controller_opponent.c +++ b/src/battle_controller_opponent.c @@ -101,6 +101,7 @@ static void OpponentHandleBattleAnimation(void); static void OpponentHandleLinkStandbyMsg(void); static void OpponentHandleResetActionMoveSelection(void); static void OpponentHandleCmd55(void); +static void OpponentHandleDebugMenu(void); static void nullsub_91(void); static void OpponentBufferRunCommand(void); @@ -173,6 +174,7 @@ static void (*const sOpponentBufferCommands[CONTROLLER_CMDS_COUNT])(void) = OpponentHandleLinkStandbyMsg, OpponentHandleResetActionMoveSelection, OpponentHandleCmd55, + OpponentHandleDebugMenu, nullsub_91 }; @@ -2007,6 +2009,11 @@ static void OpponentHandleCmd55(void) OpponentBufferExecCompleted(); } +static void OpponentHandleDebugMenu(void) +{ + OpponentBufferExecCompleted(); +} + static void nullsub_91(void) { } diff --git a/src/battle_message.c b/src/battle_message.c index df02f9fcd..258ff58e5 100644 --- a/src/battle_message.c +++ b/src/battle_message.c @@ -618,6 +618,9 @@ static const u8 sText_StealthRockDmg[] = _("Pointed stones dug into\n{B_SCR_ACTI static const u8 sText_ToxicSpikesAbsorbed[] = _(""); static const u8 sText_ToxicSpikesPoisoned[] = _(""); static const u8 sText_StickyWebSwitchIn[] = _(""); +static const u8 sText_HealingWishCameTrue[] = _("The healing wish came true\nfor {B_ATK_NAME_WITH_PREFIX}!"); +static const u8 sText_HealingWishHealed[] = _("{B_ATK_NAME_WITH_PREFIX} regained health!"); +static const u8 sText_LunarDanceCameTrue[] = _("{B_ATK_NAME_WITH_PREFIX} became cloaked\nin mystical moonlight!"); const u8 *const gBattleStringsTable[BATTLESTRINGS_COUNT] = { @@ -1087,6 +1090,14 @@ const u8 *const gBattleStringsTable[BATTLESTRINGS_COUNT] = sText_ToxicSpikesAbsorbed, sText_ToxicSpikesPoisoned, sText_StickyWebSwitchIn, + sText_HealingWishCameTrue, + sText_HealingWishHealed, + sText_LunarDanceCameTrue, +}; + +const u16 gHealingWishStringIds[] = +{ + STRINGID_HEALINGWISHCAMETRUE, STRINGID_LUNARDANCECAMETRUE }; const u16 gDmgHazardsStringIds[] = diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 460583071..ce0c49430 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -4395,7 +4395,10 @@ static void atk49_moveend(void) if (!(gHitMarker & HITMARKER_OBEYS) || holdEffectAtk != HOLD_EFFECT_CHOICE_BAND || gChosenMove == MOVE_STRUGGLE || (*choicedMoveAtk != 0 && *choicedMoveAtk != 0xFFFF)) goto LOOP; - if (gChosenMove == MOVE_BATON_PASS && !(gMoveResultFlags & MOVE_RESULT_FAILED)) + if ((gBattleMoves[gChosenMove].effect == EFFECT_BATON_PASS + || gBattleMoves[gChosenMove].effect == EFFECT_HEALING_WISH + || gBattleMoves[gChosenMove].effect == EFFECT_HIT_ESCAPE) + && !(gMoveResultFlags & MOVE_RESULT_FAILED)) { gBattleScripting.atk49_state++; break; @@ -4499,7 +4502,8 @@ static void atk49_moveend(void) } if (!(gAbsentBattlerFlags & gBitTable[gBattlerAttacker]) && !(gBattleStruct->field_91 & gBitTable[gBattlerAttacker]) - && gBattleMoves[originallyUsedMove].effect != EFFECT_BATON_PASS) + && gBattleMoves[originallyUsedMove].effect != EFFECT_BATON_PASS + && gBattleMoves[originallyUsedMove].effect != EFFECT_HEALING_WISH) { if (gHitMarker & HITMARKER_OBEYS) { @@ -5308,7 +5312,6 @@ static void atk51_switchhandleorder(void) PREPARE_SPECIES_BUFFER(gBattleTextBuff1, gBattleMons[gBattlerAttacker].species) PREPARE_MON_NICK_BUFFER(gBattleTextBuff2, gActiveBattler, gBattleBufferB[gActiveBattler][1]) - break; } @@ -6341,6 +6344,9 @@ static void atk6E_setatktoplayer0(void) static void atk6F_makevisible(void) { + if (gBattleControllerExecFlags) + return; + gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]); BtlController_EmitSpriteInvisibility(0, FALSE); MarkBattlerForControllerExec(gActiveBattler); @@ -6438,6 +6444,10 @@ static void atk76_various(void) { u8 side; s32 i; + u8 data[10]; + + if (gBattleControllerExecFlags) + return; gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]); @@ -6622,6 +6632,24 @@ static void atk76_various(void) case VARIOUS_RESTORE_TARGET: gBattlerTarget = gBattleStruct->savedBattlerTarget; break; + case VARIOUS_INSTANT_HP_DROP: + BtlController_EmitHealthBarUpdate(0, INSTANT_HP_BAR_DROP); + MarkBattlerForControllerExec(gActiveBattler); + break; + case VARIOUS_CLEAR_STATUS: + gBattleMons[gActiveBattler].status1 = 0; + BtlController_EmitSetMonData(0, REQUEST_STATUS_BATTLE, 0, 4, &gBattleMons[gActiveBattler].status1); + MarkBattlerForControllerExec(gActiveBattler); + break; + case VARIOUS_RESTORE_PP: + for (i = 0; i < 4; i++) + { + gBattleMons[gActiveBattler].pp[i] = CalculatePPWithBonus(gBattleMons[gActiveBattler].moves[i], gBattleMons[gActiveBattler].ppBonuses, i); + data[i] = gBattleMons[gActiveBattler].pp[i]; + } + data[i] = gBattleMons[gActiveBattler].ppBonuses; + BtlController_EmitSetMonData(0, REQUEST_PP_DATA_BATTLE, 0, 5, data); + break; } gBattlescriptCurrInstr += 3; @@ -6884,6 +6912,9 @@ static void atk80_manipulatedamage(void) if (gBattleMoveDamage == 0) gBattleMoveDamage = 1; break; + case ATK80_FULL_ATTACKER_HP: + gBattleMoveDamage = gBattleMons[gBattlerAttacker].maxHP; + break; } gBattlescriptCurrInstr += 2;