From dc39f76a95df8ae759cf6d0ab5d49fe9bb6caa34 Mon Sep 17 00:00:00 2001 From: DizzyEggg Date: Thu, 14 Feb 2019 12:15:53 +0100 Subject: [PATCH] Spectral Thief effect --- asm/macros/battle_script.inc | 4 ++ data/battle_scripts_1.s | 14 +++++ include/battle.h | 1 + include/battle_message.h | 1 + include/battle_scripts.h | 2 + include/constants/battle.h | 2 +- include/constants/battle_move_effects.h | 1 + include/constants/battle_script_commands.h | 49 ++++++++--------- include/constants/battle_string_ids.h | 1 + src/battle_message.c | 2 + src/battle_script_commands.c | 63 ++++++++++++++++++++-- src/data/battle_moves.h | 6 +-- 12 files changed, 115 insertions(+), 31 deletions(-) diff --git a/asm/macros/battle_script.inc b/asm/macros/battle_script.inc index ba5a371d9a..b37c842f28 100644 --- a/asm/macros/battle_script.inc +++ b/asm/macros/battle_script.inc @@ -1584,6 +1584,10 @@ .macro setpowder battler:req various \battler, VARIOUS_SET_POWDER .endm + + .macro spectralthiefprintstats + various BS_ATTACKER, VARIOUS_SPECTRAL_THIEF + .endm @ helpful macros .macro setstatchanger stat:req, stages:req, down:req diff --git a/data/battle_scripts_1.s b/data/battle_scripts_1.s index 0087f0d279..08ab61d712 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -343,6 +343,19 @@ gBattleScriptsForMoveEffects:: @ 82D86A8 .4byte BattleScript_EffectSpAtkUpHit .4byte BattleScript_EffectBelch .4byte BattleScript_EffectPartingShot + .4byte BattleScript_EffectSpectralThief + +BattleScript_SpectralThiefSteal:: + printstring STRINGID_SPECTRALTHIEFSTEAL + waitmessage 0x40 + setbyte sB_ANIM_ARG2, 0 + playanimation BS_ATTACKER, B_ANIM_STATS_CHANGE, sB_ANIM_ARG1 + spectralthiefprintstats + return + +BattleScript_EffectSpectralThief: + setmoveeffect MOVE_EFFECT_SPECTRAL_THIEF + goto BattleScript_EffectHit BattleScript_EffectPartingShot:: attackcanceler @@ -2002,6 +2015,7 @@ BattleScript_StatUpEnd:: BattleScript_StatUp:: playanimation BS_EFFECT_BATTLER, B_ANIM_STATS_CHANGE, sB_ANIM_ARG1 +BattleScript_StatUpMsg:: printfromtable gStatUpStringIds waitmessage 0x40 return diff --git a/include/battle.h b/include/battle.h index 731c5775dc..d8232f9d7c 100644 --- a/include/battle.h +++ b/include/battle.h @@ -573,6 +573,7 @@ struct BattleStruct bool8 trainerSlideLowHpMsgDone; u8 introState; u8 ateBerry[2]; // array id determined by side, each party pokemon as bit + u8 stolenStats[NUM_BATTLE_STATS]; // hp byte is used for which stats to raise, other inform about by how many stages }; #define GET_MOVE_TYPE(move, typeArg) \ diff --git a/include/battle_message.h b/include/battle_message.h index cb39fa7fec..b2ca235e2a 100644 --- a/include/battle_message.h +++ b/include/battle_message.h @@ -308,6 +308,7 @@ extern const u8 gText_BattleRecordedOnPass[]; extern const u8 gText_BattleTourney[]; extern const u16 gMissStringIds[]; +extern const u16 gStatUpStringIds[]; extern const u16 gTrappingMoves[]; #endif // GUARD_BATTLE_MESSAGE_H diff --git a/include/battle_scripts.h b/include/battle_scripts.h index 1fd78d7f96..94574f965e 100644 --- a/include/battle_scripts.h +++ b/include/battle_scripts.h @@ -293,5 +293,7 @@ extern const u8 BattleScript_PsychicSurgeActivates[]; extern const u8 BattleScript_GrassySurgeActivates[]; extern const u8 BattleScript_MistySurgeActivates[]; extern const u8 BattleScript_ElectricSurgeActivates[]; +extern const u8 BattleScript_SpectralThiefSteal[]; +extern const u8 BattleScript_StatUpMsg[]; #endif // GUARD_BATTLE_SCRIPTS_H diff --git a/include/constants/battle.h b/include/constants/battle.h index b3f5704966..a41da06e99 100644 --- a/include/constants/battle.h +++ b/include/constants/battle.h @@ -325,7 +325,7 @@ #define MOVE_EFFECT_SMACK_DOWN 0x3C #define MOVE_EFFECT_FLAME_BURST 0x3D #define MOVE_EFFECT_FEINT 0x3E -#define MOVE_EFFECT_NOTHING_3F 0x3F +#define MOVE_EFFECT_SPECTRAL_THIEF 0x3F #define MOVE_EFFECT_AFFECTS_USER 0x40 #define MOVE_EFFECT_CERTAIN 0x80 diff --git a/include/constants/battle_move_effects.h b/include/constants/battle_move_effects.h index d6171a8e01..85cac188e3 100644 --- a/include/constants/battle_move_effects.h +++ b/include/constants/battle_move_effects.h @@ -331,5 +331,6 @@ #define EFFECT_SP_ATTACK_UP_HIT 325 #define EFFECT_BELCH 326 #define EFFECT_PARTING_SHOT 327 +#define EFFECT_SPECTRAL_THIEF 328 #endif // GUARD_CONSTANTS_BATTLE_MOVE_EFFECTS_H diff --git a/include/constants/battle_script_commands.h b/include/constants/battle_script_commands.h index da1c073e4b..b0544a0343 100644 --- a/include/constants/battle_script_commands.h +++ b/include/constants/battle_script_commands.h @@ -50,7 +50,7 @@ #define BS_OPPONENT1 12 #define BS_PLAYER2 13 #define BS_OPPONENT2 14 -#define BS_ABILITY_BATTLER 15 +#define BS_ABILITY_BATTLER 15 // atk 01, accuracy calc #define NO_ACC_CALC_CHECK_LOCK_ON 0xFFFF @@ -110,30 +110,31 @@ #define VARIOUS_TRY_ELECTRIFY 48 #define VARIOUS_TRY_REFLECT_TYPE 49 #define VARIOUS_TRY_SOAK 50 -#define VARIOUS_HANDLE_MEGA_EVO 51 -#define VARIOUS_TRY_LAST_RESORT 52 -#define VARIOUS_ARGUMENT_STATUS_EFFECT 53 -#define VARIOUS_TRY_HIT_SWITCH_TARGET 54 -#define VARIOUS_TRY_AUTONOMIZE 55 -#define VARIOUS_TRY_COPYCAT 56 -#define VARIOUS_ABILITY_POPUP 57 -#define VARIOUS_DEFOG 58 -#define VARIOUS_JUMP_IF_TARGET_ALLY 59 -#define VARIOUS_TRY_SYNCHRONOISE 60 -#define VARIOUS_PSYCHO_SHIFT 61 -#define VARIOUS_CURE_STATUS 62 -#define VARIOUS_POWER_TRICK 63 -#define VARIOUS_AFTER_YOU 64 -#define VARIOUS_BESTOW 65 -#define VARIOUS_ARGUMENT_TO_MOVE_EFFECT 66 -#define VARIOUS_JUMP_IF_NOT_GROUNDED 67 -#define VARIOUS_HANDLE_TRAINER_SLIDE_MSG 68 +#define VARIOUS_HANDLE_MEGA_EVO 51 +#define VARIOUS_TRY_LAST_RESORT 52 +#define VARIOUS_ARGUMENT_STATUS_EFFECT 53 +#define VARIOUS_TRY_HIT_SWITCH_TARGET 54 +#define VARIOUS_TRY_AUTONOMIZE 55 +#define VARIOUS_TRY_COPYCAT 56 +#define VARIOUS_ABILITY_POPUP 57 +#define VARIOUS_DEFOG 58 +#define VARIOUS_JUMP_IF_TARGET_ALLY 59 +#define VARIOUS_TRY_SYNCHRONOISE 60 +#define VARIOUS_PSYCHO_SHIFT 61 +#define VARIOUS_CURE_STATUS 62 +#define VARIOUS_POWER_TRICK 63 +#define VARIOUS_AFTER_YOU 64 +#define VARIOUS_BESTOW 65 +#define VARIOUS_ARGUMENT_TO_MOVE_EFFECT 66 +#define VARIOUS_JUMP_IF_NOT_GROUNDED 67 +#define VARIOUS_HANDLE_TRAINER_SLIDE_MSG 68 #define VARIOUS_TRY_TRAINER_SLIDE_MSG_FIRST_OFF 69 -#define VARIOUS_TRY_TRAINER_SLIDE_MSG_LAST_ON 70 -#define VARIOUS_SET_AURORA_VEIL 71 -#define VARIOUS_TRY_THIRD_TYPE 72 -#define VARIOUS_ACUPRESSURE 73 -#define VARIOUS_SET_POWDER 74 +#define VARIOUS_TRY_TRAINER_SLIDE_MSG_LAST_ON 70 +#define VARIOUS_SET_AURORA_VEIL 71 +#define VARIOUS_TRY_THIRD_TYPE 72 +#define VARIOUS_ACUPRESSURE 73 +#define VARIOUS_SET_POWDER 74 +#define VARIOUS_SPECTRAL_THIEF 75 // 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 c1e0dda3bb..8c863c2a72 100644 --- a/include/constants/battle_string_ids.h +++ b/include/constants/battle_string_ids.h @@ -517,6 +517,7 @@ #define STRINGID_COVEREDINPOWDER 513 #define STRINGID_POWDEREXPLODES 514 #define STRINGID_BELCHCANTSELECT 515 +#define STRINGID_SPECTRALTHIEFSTEAL 516 #define BATTLESTRINGS_COUNT 528 diff --git a/src/battle_message.c b/src/battle_message.c index 1faa6543b2..82060876fa 100644 --- a/src/battle_message.c +++ b/src/battle_message.c @@ -642,9 +642,11 @@ static const u8 sText_PokemonCannotUseMove[] = _("{B_ATK_NAME_WITH_PREFIX} canno static const u8 sText_CoveredInPowder[] = _("{B_DEF_NAME_WITH_PREFIX} is covered in powder!"); static const u8 sText_PowderExplodes[] = _("When the flame touched the powder\non the Pokémon, it exploded!"); static const u8 sText_BelchCantUse[] = _("Belch cannot be used!\p"); +static const u8 sText_SpectralThiefSteal[] = _("{B_ATK_NAME_WITH_PREFIX} stole the target's\nboosted stats!"); const u8 *const gBattleStringsTable[BATTLESTRINGS_COUNT] = { + [STRINGID_SPECTRALTHIEFSTEAL - 12] = sText_SpectralThiefSteal, [STRINGID_BELCHCANTSELECT - 12] = sText_BelchCantUse, [STRINGID_TRAINER1LOSETEXT - 12] = sText_Trainer1LoseText, [STRINGID_PKMNGAINEDEXP - 12] = sText_PkmnGainedEXP, diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index ff6fd67c92..2400a4ab9b 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -1987,7 +1987,7 @@ u8 GetBattlerTurnOrderNum(u8 battlerId) void SetMoveEffect(bool8 primary, u8 certain) { - s32 i; + s32 i, byTwo; bool32 statusChanged = FALSE; u8 affectsUser = 0; // 0x40 otherwise bool32 noSunCanFreeze = TRUE; @@ -2742,6 +2742,46 @@ void SetMoveEffect(bool8 primary, u8 certain) } } break; + case MOVE_EFFECT_SPECTRAL_THIEF: + gBattleStruct->stolenStats[0] = 0; // Stats to steal. + gBattleScripting.animArg1 = 0; + for (i = STAT_ATK; i < NUM_BATTLE_STATS; i++) + { + if (gBattleMons[gBattlerTarget].statStages[i] > 6 && gBattleMons[gBattlerAttacker].statStages[i] != 12) + { + gBattleStruct->stolenStats[0] |= gBitTable[i]; + // Store by how many stages to raise the stat. + gBattleStruct->stolenStats[i] = gBattleMons[gBattlerTarget].statStages[i] - 6; + while (gBattleMons[gBattlerAttacker].statStages[i] + gBattleStruct->stolenStats[i] > 12) + gBattleStruct->stolenStats[i]--; + gBattleMons[gBattlerTarget].statStages[i] = 6; + + if (gBattleStruct->stolenStats[i] >= 2) + byTwo++; + + if (gBattleScripting.animArg1 == 0) + { + if (byTwo) + gBattleScripting.animArg1 = STAT_ANIM_PLUS2 - 1 + i; + else + gBattleScripting.animArg1 = STAT_ANIM_PLUS1 - 1 + i; + } + else + { + if (byTwo) + gBattleScripting.animArg1 = STAT_ANIM_MULTIPLE_PLUS2; + else + gBattleScripting.animArg1 = STAT_ANIM_MULTIPLE_PLUS1; + } + } + } + + if (gBattleStruct->stolenStats[0] != 0) + { + BattleScriptPush(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = BattleScript_SpectralThiefSteal; + } + break; } } } @@ -6332,6 +6372,23 @@ static void atk76_various(void) switch (gBattlescriptCurrInstr[2]) { + case VARIOUS_SPECTRAL_THIEF: + // Raise stats + for (i = STAT_ATK; i < NUM_BATTLE_STATS; i++) + { + if (gBattleStruct->stolenStats[0] & gBitTable[i]) + { + gBattleStruct->stolenStats[0] &= ~(gBitTable[i]); + SET_STATCHANGER(i, gBattleStruct->stolenStats[i], FALSE); + if (ChangeStatBuffs(gBattleScripting.statChanger & 0xF0, i, MOVE_EFFECT_CERTAIN | MOVE_EFFECT_AFFECTS_USER, NULL) == STAT_CHANGE_WORKED) + { + BattleScriptPushCursor(); + gBattlescriptCurrInstr = BattleScript_StatUpMsg; + return; + } + } + } + break; case VARIOUS_SET_POWDER: gBattleMons[gActiveBattler].status2 |= STATUS2_POWDER; break; @@ -7810,7 +7867,7 @@ static u8 ChangeStatBuffs(s8 statValue, u8 statId, u8 flags, const u8 *BS_ptr) gBattleTextBuff2[3] = STRINGID_STATHARSHLY >> 8; index = 4; } - else if (statValue == -3) + else if (statValue <= -3) { gBattleTextBuff2[1] = B_BUFF_STRING; gBattleTextBuff2[2] = STRINGID_SEVERELY & 0xFF; @@ -7844,7 +7901,7 @@ static u8 ChangeStatBuffs(s8 statValue, u8 statId, u8 flags, const u8 *BS_ptr) gBattleTextBuff2[3] = STRINGID_STATSHARPLY >> 8; index = 4; } - else if (statValue == 3) + else if (statValue >= 3) { gBattleTextBuff2[1] = B_BUFF_STRING; gBattleTextBuff2[2] = STRINGID_DRASTICALLY & 0xFF; diff --git a/src/data/battle_moves.h b/src/data/battle_moves.h index 195cb27acf..ed39e27f52 100644 --- a/src/data/battle_moves.h +++ b/src/data/battle_moves.h @@ -2266,7 +2266,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = .target = MOVE_TARGET_SELECTED, .priority = 0, .flags = FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED, - .split = SPLIT_PHYSICAL, + .split = SPLIT_SPECIAL, }, [MOVE_SUPER_FANG] = @@ -9347,12 +9347,12 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = [MOVE_SPECTRAL_THIEF] = { - .effect = EFFECT_PLACEHOLDER, + .effect = EFFECT_SPECTRAL_THIEF, .power = 90, .type = TYPE_GHOST, .accuracy = 100, .pp = 10, - .secondaryEffectChance = 0, + .secondaryEffectChance = 100, .target = MOVE_TARGET_SELECTED, .priority = 0, .flags = FLAG_MAKES_CONTACT | FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGSROCK_AFFECTED,