From 875b413a09ac811e2bf843f566bf22e48150fa38 Mon Sep 17 00:00:00 2001 From: DizzyEggg Date: Thu, 9 May 2019 20:31:58 +0200 Subject: [PATCH] Various battle target items --- data/battle_scripts_1.s | 80 +++++++++++++- include/battle_scripts.h | 6 ++ include/battle_util.h | 1 + include/constants/battle_script_commands.h | 17 +-- include/constants/battle_string_ids.h | 2 + src/battle_message.c | 4 + src/battle_script_commands.c | 15 ++- src/battle_util.c | 119 ++++++++++++++++++++- 8 files changed, 225 insertions(+), 19 deletions(-) diff --git a/data/battle_scripts_1.s b/data/battle_scripts_1.s index e57eda0304..38a3f500cb 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -5206,6 +5206,46 @@ BattleScript_RoarSuccessRet: returntoball BS_TARGET waitstate return + +BattleScript_WeaknessPolicy:: + copybyte sBATTLER, gBattlerTarget + jumpifstat BS_TARGET, CMP_LESS_THAN, STAT_ATK, 0xC, BattleScript_WeaknessPolicyAtk + jumpifstat BS_TARGET, CMP_EQUAL, STAT_SPATK, 0xC, BattleScript_WeaknessPolicyEnd +BattleScript_WeaknessPolicyAtk: + playanimation BS_TARGET, B_ANIM_ITEM_EFFECT, NULL + waitanimation + setbyte sSTAT_ANIM_PLAYED, FALSE + playstatchangeanimation BS_TARGET, BIT_ATK | BIT_SPATK, ATK48_STAT_BY_TWO + setstatchanger STAT_ATK, 2, FALSE + statbuffchange STAT_CHANGE_BS_PTR, BattleScript_WeaknessPolicySpAtk + jumpifbyte CMP_EQUAL, cMULTISTRING_CHOOSER, 0x2, BattleScript_WeaknessPolicySpAtk + printstring STRINGID_USINGXTHEYOFZN + waitmessage 0x40 +BattleScript_WeaknessPolicySpAtk: + setstatchanger STAT_SPATK, 2, FALSE + statbuffchange STAT_CHANGE_BS_PTR, BattleScript_WeaknessPolicyRemoveItem + jumpifbyte CMP_EQUAL, cMULTISTRING_CHOOSER, 0x2, BattleScript_WeaknessPolicyRemoveItem + printstring STRINGID_USINGXTHEYOFZN + waitmessage 0x40 +BattleScript_WeaknessPolicyRemoveItem: + removeitem BS_TARGET +BattleScript_WeaknessPolicyEnd: + return + +BattleScript_TargetItemStatRaise:: + copybyte sBATTLER, gBattlerTarget + statbuffchange 0, BattleScript_TargetItemStatRaiseRemoveItemRet + jumpifbyte CMP_EQUAL, cMULTISTRING_CHOOSER, 0x2, BattleScript_TargetItemStatRaiseRemoveItemRet + playanimation BS_TARGET, B_ANIM_ITEM_EFFECT, NULL + waitanimation + setgraphicalstatchangevalues + playanimation BS_TARGET, B_ANIM_STATS_CHANGE, sB_ANIM_ARG1 + waitanimation + printstring STRINGID_USINGXTHEYOFZN + waitmessage 0x40 + removeitem BS_TARGET +BattleScript_TargetItemStatRaiseRemoveItemRet: + return BattleScript_MistProtected:: pause 0x20 @@ -5317,7 +5357,7 @@ BattleScript_ToxicSpikesPoisoned:: BattleScript_StickyWebOnSwitchIn:: savetarget - copybyte gBattlerTarget sBATTLER + copybyte gBattlerTarget, sBATTLER printstring STRINGID_STICKYWEBSWITCHIN waitmessage 0x40 statbuffchange STAT_CHANGE_BS_PTR, BattleScript_StickyWebOnSwitchInEnd @@ -6549,10 +6589,9 @@ BattleScript_ImposterActivates:: printstring STRINGID_IMPOSTERTRANSFORM waitmessage 0x40 end3 - -BattleScript_RoughSkinActivates:: + +BattleScript_HurtAttacker: orword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_x100000 - call BattleScript_AbilityPopUp healthbarupdate BS_ATTACKER datahpupdate BS_ATTACKER printstring STRINGID_PKMNHURTSWITH @@ -6560,6 +6599,17 @@ BattleScript_RoughSkinActivates:: tryfaintmon BS_ATTACKER, FALSE, NULL return +BattleScript_RoughSkinActivates:: + call BattleScript_AbilityPopUp + call BattleScript_HurtAttacker + return + +BattleScript_RockyHelmetActivates:: + playanimation BS_TARGET, B_ANIM_ITEM_EFFECT, NULL + waitanimation + call BattleScript_HurtAttacker + return + BattleScript_SpikyShieldEffect:: orword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_x100000 bichalfword gMoveResultFlags, MOVE_RESULT_NO_EFFECT @@ -6798,6 +6848,28 @@ BattleScript_BerryPPHealEnd2:: BattleScript_ItemHealHP_End2:: call BattleScript_ItemHealHP_Ret end2 + +BattleScript_AirBaloonMsgIn:: + printstring STRINGID_AIRBALLOONFLOAT + waitmessage 0x40 + end2 + +BattleScript_AirBaloonMsgPop:: + printstring STRINGID_AIRBALLOONPOP + waitmessage 0x40 + removeitem BS_TARGET + return + +BattleScript_ItemHurtEnd2:: + playanimation BS_ATTACKER, B_ANIM_MON_HIT, NULL + waitanimation + orword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_x100000 + healthbarupdate BS_ATTACKER + datahpupdate BS_ATTACKER + printstring STRINGID_HURTBYITEM + waitmessage 0x40 + tryfaintmon BS_ATTACKER, FALSE, NULL + end2 BattleScript_ItemHealHP_Ret:: playanimation BS_ATTACKER, B_ANIM_ITEM_EFFECT, NULL diff --git a/include/battle_scripts.h b/include/battle_scripts.h index f80671a1a1..7628b35bb4 100644 --- a/include/battle_scripts.h +++ b/include/battle_scripts.h @@ -312,5 +312,11 @@ extern const u8 BattleScript_ThroatChopEndTurn[]; extern const u8 BattleScript_GemActivates[]; extern const u8 BattleScript_BerryReduceDmg[]; extern const u8 BattleScript_PrintBerryReduceString[]; +extern const u8 BattleScript_WeaknessPolicy[]; +extern const u8 BattleScript_TargetItemStatRaise[]; +extern const u8 BattleScript_RockyHelmetActivates[]; +extern const u8 BattleScript_ItemHurtEnd2[]; +extern const u8 BattleScript_AirBaloonMsgIn[]; +extern const u8 BattleScript_AirBaloonMsgPop[]; #endif // GUARD_BATTLE_SCRIPTS_H diff --git a/include/battle_util.h b/include/battle_util.h index f2671a6ad6..6031bf874f 100644 --- a/include/battle_util.h +++ b/include/battle_util.h @@ -25,6 +25,7 @@ #define ITEMEFFECT_ON_SWITCH_IN 0x0 #define ITEMEFFECT_MOVE_END 0x3 #define ITEMEFFECT_KINGSROCK_SHELLBELL 0x4 +#define ITEMEFFECT_TARGET 0x5 #define WEATHER_HAS_EFFECT ((!IsAbilityOnField(ABILITY_CLOUD_NINE) && !IsAbilityOnField(ABILITY_AIR_LOCK))) diff --git a/include/constants/battle_script_commands.h b/include/constants/battle_script_commands.h index 683f3ea372..775f8b337b 100644 --- a/include/constants/battle_script_commands.h +++ b/include/constants/battle_script_commands.h @@ -175,14 +175,15 @@ #define ATK49_ATTACKER_INVISIBLE 9 #define ATK49_ATTACKER_VISIBLE 10 #define ATK49_TARGET_VISIBLE 11 -#define ATK49_ITEM_EFFECTS_ALL 12 -#define ATK49_KINGSROCK_SHELLBELL 13 -#define ATK49_SUBSTITUTE 14 -#define ATK49_UPDATE_LAST_MOVES 15 -#define ATK49_MIRROR_MOVE 16 -#define ATK49_NEXT_TARGET 17 -#define ATK49_CLEAR_BITS 18 -#define ATK49_COUNT 19 +#define ATK49_ITEM_EFFECTS_TARGET 12 +#define ATK49_ITEM_EFFECTS_ALL 13 +#define ATK49_KINGSROCK_SHELLBELL 14 +#define ATK49_SUBSTITUTE 15 +#define ATK49_UPDATE_LAST_MOVES 16 +#define ATK49_MIRROR_MOVE 17 +#define ATK49_NEXT_TARGET 18 +#define ATK49_CLEAR_BITS 19 +#define ATK49_COUNT 20 #define BIT_HP 0x1 #define BIT_ATK 0x2 diff --git a/include/constants/battle_string_ids.h b/include/constants/battle_string_ids.h index 0d419b9611..711512edf4 100644 --- a/include/constants/battle_string_ids.h +++ b/include/constants/battle_string_ids.h @@ -535,6 +535,8 @@ #define STRINGID_GEMACTIVATES 531 #define STRINGID_BERRYDMGREDUCES 532 #define STRINGID_TARGETATEITEM 533 +#define STRINGID_AIRBALLOONFLOAT 534 +#define STRINGID_AIRBALLOONPOP 535 #define BATTLESTRINGS_COUNT 530 diff --git a/src/battle_message.c b/src/battle_message.c index 8244709d7c..e98a20798c 100644 --- a/src/battle_message.c +++ b/src/battle_message.c @@ -660,9 +660,13 @@ static const u8 sText_LaserFocusMessage[] = _("{B_ATK_NAME_WITH_PREFIX}\nconcent static const u8 sText_GemActivates[] = _("{B_LAST_ITEM} strengthened\n{B_ATK_NAME_WITH_PREFIX}'s power!"); static const u8 sText_BerryDmgReducing[] = _("{B_LAST_ITEM} weakened the damage\nto {B_DEF_NAME_WITH_PREFIX}!"); static const u8 sText_TargetAteItem[] = _("{B_DEF_NAME_WITH_PREFIX} ate its {B_LAST_ITEM}!"); +static const u8 sText_AirBalloonFloat[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX} floats in the air\nwith its {B_LAST_ITEM}!"); +static const u8 sText_AirBalloonPop[] = _("{B_DEF_NAME_WITH_PREFIX}'s {B_LAST_ITEM} popped!"); const u8 *const gBattleStringsTable[BATTLESTRINGS_COUNT] = { + [STRINGID_AIRBALLOONPOP - 12] = sText_AirBalloonPop, + [STRINGID_AIRBALLOONFLOAT - 12] = sText_AirBalloonFloat, [STRINGID_TARGETATEITEM - 12] = sText_TargetAteItem, [STRINGID_BERRYDMGREDUCES - 12] = sText_BerryDmgReducing, [STRINGID_GEMACTIVATES - 12] = sText_GemActivates, diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index a8fd91003d..8c6ebf27a5 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -4402,6 +4402,11 @@ static void atk49_moveend(void) } gBattleScripting.atk49_state++; break; + case ATK49_ITEM_EFFECTS_TARGET: + if (ItemBattleEffects(ITEMEFFECT_TARGET, gBattlerTarget, FALSE)) + effect = TRUE; + gBattleScripting.atk49_state++; + break; case ATK49_ITEM_EFFECTS_ALL: // item effects for all battlers if (ItemBattleEffects(ITEMEFFECT_MOVE_END, 0, FALSE)) effect = TRUE; @@ -5969,18 +5974,24 @@ static void atk69_setgravity(void) static void atk6A_removeitem(void) { gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]); - gBattleStruct->usedHeldItems[gActiveBattler] = gBattleMons[gActiveBattler].item; + + // Popped Air Balloon cannot be restored by no means. + if (GetBattlerHoldEffect(gActiveBattler, TRUE) != HOLD_EFFECT_AIR_BALLOON) + gBattleStruct->usedHeldItems[gActiveBattler] = gBattleMons[gActiveBattler].item; + gBattleMons[gActiveBattler].item = 0; BtlController_EmitSetMonData(0, REQUEST_HELDITEM_BATTLE, 0, 2, &gBattleMons[gActiveBattler].item); MarkBattlerForControllerExec(gActiveBattler); + ClearBattlerItemEffectHistory(gActiveBattler); + gBattlescriptCurrInstr += 2; } static void atk6B_atknameinbuff1(void) { - PREPARE_MON_NICK_BUFFER(gBattleTextBuff1, gBattlerAttacker, gBattlerPartyIndexes[gBattlerAttacker]) + PREPARE_MON_NICK_BUFFER(gBattleTextBuff1, gBattlerAttacker, gBattlerPartyIndexes[gBattlerAttacker]); gBattlescriptCurrInstr++; } diff --git a/src/battle_util.c b/src/battle_util.c index aa6f9d1cec..aab30c15e8 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -3721,7 +3721,7 @@ static bool32 HasEnoughHpToEatBerry(u8 battlerId, u32 hpFraction) u8 ItemBattleEffects(u8 caseID, u8 battlerId, bool8 moveTurn) { - int i = 0; + int i = 0, moveType; u8 effect = ITEM_NO_EFFECT; u8 changedPP = 0; u8 battlerHoldEffect, atkHoldEffect; @@ -3762,6 +3762,12 @@ u8 ItemBattleEffects(u8 caseID, u8 battlerId, bool8 moveTurn) BattleScriptExecute(BattleScript_WhiteHerbEnd2); } break; + case HOLD_EFFECT_AIR_BALLOON: + effect = ITEM_EFFECT_OTHER; + gBattleScripting.battler = battlerId; + BattleScriptExecute(BattleScript_AirBaloonMsgIn); + RecordItemEffectBattle(battlerId, HOLD_EFFECT_AIR_BALLOON); + break; } break; case 1: @@ -3833,14 +3839,28 @@ u8 ItemBattleEffects(u8 caseID, u8 battlerId, bool8 moveTurn) BattleScriptExecute(BattleScript_WhiteHerbEnd2); } break; + case HOLD_EFFECT_BLACK_SLUDGE: + if (IS_BATTLER_OF_TYPE(battlerId, TYPE_POISON)) + goto LEFTOVERS; + case HOLD_EFFECT_STICKY_BARB: + if (!moveTurn) + { + gBattleMoveDamage = gBattleMons[battlerId].maxHP / 8; + if (gBattleMoveDamage == 0) + gBattleMoveDamage = 1; + BattleScriptExecute(BattleScript_ItemHurtEnd2); + effect = ITEM_HP_CHANGE; + RecordItemEffectBattle(battlerId, battlerHoldEffect); + PREPARE_ITEM_BUFFER(gBattleTextBuff1, gLastUsedItem); + } + break; case HOLD_EFFECT_LEFTOVERS: + LEFTOVERS: if (gBattleMons[battlerId].hp < gBattleMons[battlerId].maxHP && !moveTurn) { gBattleMoveDamage = gBattleMons[battlerId].maxHP / 16; if (gBattleMoveDamage == 0) gBattleMoveDamage = 1; - if (gBattleMons[battlerId].hp + gBattleMoveDamage > gBattleMons[battlerId].maxHP) - gBattleMoveDamage = gBattleMons[battlerId].maxHP - gBattleMons[battlerId].hp; gBattleMoveDamage *= -1; BattleScriptExecute(BattleScript_ItemHealHP_End2); effect = ITEM_HP_CHANGE; @@ -4303,7 +4323,8 @@ u8 ItemBattleEffects(u8 caseID, u8 battlerId, bool8 moveTurn) } break; } - if (effect) + + if (effect == ITEM_STATUS_CHANGE) { gBattleScripting.battler = battlerId; gPotentialItemEffectBattler = battlerId; @@ -4355,6 +4376,92 @@ u8 ItemBattleEffects(u8 caseID, u8 battlerId, bool8 moveTurn) } } break; + case ITEMEFFECT_TARGET: + if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)) + { + GET_MOVE_TYPE(gCurrentMove, moveType); + switch (battlerHoldEffect) + { + case HOLD_EFFECT_AIR_BALLOON: + if (TARGET_TURN_DAMAGED) + { + effect = ITEM_EFFECT_OTHER; + BattleScriptPushCursor(); + gBattlescriptCurrInstr = BattleScript_AirBaloonMsgPop; + } + break; + case HOLD_EFFECT_ROCKY_HELMET: + if (TARGET_TURN_DAMAGED + && IsMoveMakingContact(gCurrentMove, gBattlerAttacker) + && GetBattlerAbility(gBattlerAttacker) != ABILITY_MAGIC_GUARD) + { + gBattleMoveDamage = gBattleMons[gBattlerAttacker].hp / 6; + if (gBattleMoveDamage == 0) + gBattleMoveDamage = 1; + effect = ITEM_HP_CHANGE; + BattleScriptPushCursor(); + gBattlescriptCurrInstr = BattleScript_RockyHelmetActivates; + PREPARE_ITEM_BUFFER(gBattleTextBuff1, gLastUsedItem); + RecordItemEffectBattle(battlerId, HOLD_EFFECT_ROCKY_HELMET); + } + break; + case HOLD_EFFECT_WEAKNESS_POLICY: + if (IsBattlerAlive(battlerId) + && TARGET_TURN_DAMAGED + && gMoveResultFlags & MOVE_RESULT_SUPER_EFFECTIVE) + { + effect = ITEM_STATS_CHANGE; + BattleScriptPushCursor(); + gBattlescriptCurrInstr = BattleScript_WeaknessPolicy; + } + break; + case HOLD_EFFECT_SNOWBALL: + if (IsBattlerAlive(battlerId) + && TARGET_TURN_DAMAGED + && moveType == TYPE_ICE) + { + effect = ITEM_STATS_CHANGE; + BattleScriptPushCursor(); + gBattlescriptCurrInstr = BattleScript_TargetItemStatRaise; + gBattleScripting.statChanger = SET_STATCHANGER(STAT_ATK, 1, FALSE); + } + break; + case HOLD_EFFECT_LUMINOUS_MOSS: + if (IsBattlerAlive(battlerId) + && TARGET_TURN_DAMAGED + && moveType == TYPE_WATER) + { + effect = ITEM_STATS_CHANGE; + BattleScriptPushCursor(); + gBattlescriptCurrInstr = BattleScript_TargetItemStatRaise; + gBattleScripting.statChanger = SET_STATCHANGER(STAT_SPDEF, 1, FALSE); + } + break; + case HOLD_EFFECT_CELL_BATTERY: + if (IsBattlerAlive(battlerId) + && TARGET_TURN_DAMAGED + && moveType == TYPE_ELECTRIC) + { + effect = ITEM_STATS_CHANGE; + BattleScriptPushCursor(); + gBattlescriptCurrInstr = BattleScript_TargetItemStatRaise; + gBattleScripting.statChanger = SET_STATCHANGER(STAT_ATK, 1, FALSE); + } + break; + case HOLD_EFFECT_ABSORB_BULB: + if (IsBattlerAlive(battlerId) + && TARGET_TURN_DAMAGED + && moveType == TYPE_WATER) + { + effect = ITEM_STATS_CHANGE; + BattleScriptPushCursor(); + gBattlescriptCurrInstr = BattleScript_TargetItemStatRaise; + gBattleScripting.statChanger = SET_STATCHANGER(STAT_SPATK, 1, FALSE); + } + break; + } + } + break; } // Berry was successfully used on a Pokemon. @@ -4608,7 +4715,7 @@ u32 GetBattlerHoldEffect(u8 battlerId, bool32 checkNegating) gPotentialItemEffectBattler = battlerId; - if (USE_BATTLE_DEBUG && gBattleStruct->debugHoldEffects[battlerId] != 0) + if (USE_BATTLE_DEBUG && gBattleStruct->debugHoldEffects[battlerId] != 0 && gBattleMons[battlerId].item) return gBattleStruct->debugHoldEffects[battlerId]; else if (gBattleMons[battlerId].item == ITEM_ENIGMA_BERRY) return gEnigmaBerries[battlerId].holdEffect; @@ -4651,6 +4758,8 @@ bool32 IsBattlerGrounded(u8 battlerId) return FALSE; else if (gStatuses3[battlerId] & STATUS3_MAGNET_RISE) return FALSE; + else if (GetBattlerHoldEffect(battlerId, TRUE) == HOLD_EFFECT_AIR_BALLOON) + return FALSE; else if (GetBattlerAbility(battlerId) == ABILITY_LEVITATE) return FALSE; else if (IS_BATTLER_OF_TYPE(battlerId, TYPE_FLYING))