diff --git a/data/battle_scripts_1.s b/data/battle_scripts_1.s index 603e2c5ce..29931e597 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -344,6 +344,38 @@ gBattleScriptsForMoveEffects:: @ 82D86A8 .4byte BattleScript_EffectBelch .4byte BattleScript_EffectPartingShot .4byte BattleScript_EffectSpectralThief + .4byte BattleScript_EffectVCreate + +BattleScript_EffectVCreate: + setmoveeffect MOVE_EFFECT_V_CREATE | MOVE_EFFECT_AFFECTS_USER + goto BattleScript_EffectHit + +BattleScript_VCreateStatLoss:: + jumpifstat BS_ATTACKER, CMP_GREATER_THAN, STAT_DEF, 0x0, BattleScript_VCreateStatAnim + jumpifstat BS_ATTACKER, CMP_GREATER_THAN, STAT_SPDEF, 0x0, BattleScript_VCreateStatAnim + jumpifstat BS_ATTACKER, CMP_EQUAL, STAT_SPEED, 0x0, BattleScript_VCreateStatLossRet +BattleScript_VCreateStatAnim: + setbyte sSTAT_ANIM_PLAYED, FALSE + playstatchangeanimation BS_ATTACKER, BIT_DEF | BIT_SPDEF | BIT_SPEED, ATK48_STAT_NEGATIVE | ATK48_DONT_CHECK_LOWER + setstatchanger STAT_DEF, 1, TRUE + statbuffchange MOVE_EFFECT_AFFECTS_USER | STAT_CHANGE_NOT_PROTECT_AFFECTED | MOVE_EFFECT_CERTAIN, BattleScript_VCreateTrySpDef + jumpifbyte CMP_EQUAL, cMULTISTRING_CHOOSER, 0x2, BattleScript_VCreateTrySpDef + printfromtable gStatUpStringIds + waitmessage 0x40 +BattleScript_VCreateTrySpDef: + setstatchanger STAT_SPDEF, 1, TRUE + statbuffchange MOVE_EFFECT_AFFECTS_USER | STAT_CHANGE_NOT_PROTECT_AFFECTED | MOVE_EFFECT_CERTAIN, BattleScript_VCreateTrySpeed + jumpifbyte CMP_EQUAL, cMULTISTRING_CHOOSER, 0x2, BattleScript_VCreateTrySpeed + printfromtable gStatUpStringIds + waitmessage 0x40 +BattleScript_VCreateTrySpeed: + setstatchanger STAT_SPEED, 1, TRUE + statbuffchange MOVE_EFFECT_AFFECTS_USER | STAT_CHANGE_NOT_PROTECT_AFFECTED | MOVE_EFFECT_CERTAIN, BattleScript_VCreateStatLossRet + jumpifbyte CMP_EQUAL, cMULTISTRING_CHOOSER, 0x2, BattleScript_VCreateStatLossRet + printfromtable gStatUpStringIds + waitmessage 0x40 +BattleScript_VCreateStatLossRet: + return BattleScript_SpectralThiefSteal:: printstring STRINGID_SPECTRALTHIEFSTEAL diff --git a/include/battle_scripts.h b/include/battle_scripts.h index 098eda042..1c68b909b 100644 --- a/include/battle_scripts.h +++ b/include/battle_scripts.h @@ -299,5 +299,6 @@ extern const u8 BattleScript_StatUpMsg[]; extern const u8 BattleScript_DefiantActivates[]; extern const u8 BattleScript_PowderMoveNoEffect[]; extern const u8 BattleScript_GrassyTerrainLoop[]; +extern const u8 BattleScript_VCreateStatLoss[]; #endif // GUARD_BATTLE_SCRIPTS_H diff --git a/include/constants/battle.h b/include/constants/battle.h index 63db1523c..c42188596 100644 --- a/include/constants/battle.h +++ b/include/constants/battle.h @@ -325,6 +325,7 @@ #define MOVE_EFFECT_FLAME_BURST 0x3D #define MOVE_EFFECT_FEINT 0x3E #define MOVE_EFFECT_SPECTRAL_THIEF 0x3F +#define MOVE_EFFECT_V_CREATE 0x40 #define MOVE_EFFECT_AFFECTS_USER 0x4000 #define MOVE_EFFECT_CERTAIN 0x8000 diff --git a/include/constants/battle_move_effects.h b/include/constants/battle_move_effects.h index 85cac188e..588fe9773 100644 --- a/include/constants/battle_move_effects.h +++ b/include/constants/battle_move_effects.h @@ -332,5 +332,6 @@ #define EFFECT_BELCH 326 #define EFFECT_PARTING_SHOT 327 #define EFFECT_SPECTRAL_THIEF 328 +#define EFFECT_V_CREATE 329 #endif // GUARD_CONSTANTS_BATTLE_MOVE_EFFECTS_H diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 29fb9cddc..4ef73926c 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -2782,6 +2782,10 @@ void SetMoveEffect(bool32 primary, u32 certain) gBattlescriptCurrInstr = BattleScript_SpectralThiefSteal; } break; + case MOVE_EFFECT_V_CREATE: + BattleScriptPush(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = BattleScript_VCreateStatLoss; + break; } } } @@ -4040,18 +4044,27 @@ static void atk47_setgraphicalstatchangevalues(void) static void atk48_playstatchangeanimation(void) { + u32 ability; u32 currStat = 0; - u16 statAnimId = 0; - s32 changeableStatsCount = 0; - u8 statsToCheck = 0; + u32 statAnimId = 0; + u32 changeableStatsCount = 0; + u32 statsToCheck = 0; + u32 startingStatAnimId = 0; + u32 flags = gBattlescriptCurrInstr[3]; gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]); + ability = GetBattlerAbility(gActiveBattler); statsToCheck = gBattlescriptCurrInstr[2]; - if (gBattlescriptCurrInstr[3] & ATK48_STAT_NEGATIVE) // goes down + // Handle Contrary and Simple + if (ability == ABILITY_CONTRARY) + flags ^= ATK48_STAT_NEGATIVE; + else if (ability == ABILITY_SIMPLE) + flags |= ATK48_STAT_BY_TWO; + + if (flags & ATK48_STAT_NEGATIVE) // goes down { - s16 startingStatAnimId; - if (gBattlescriptCurrInstr[3] & ATK48_STAT_BY_TWO) + if (flags & ATK48_STAT_BY_TWO) startingStatAnimId = STAT_ANIM_MINUS2 - 1; else startingStatAnimId = STAT_ANIM_MINUS1 - 1; @@ -4060,7 +4073,7 @@ static void atk48_playstatchangeanimation(void) { if (statsToCheck & 1) { - if (gBattlescriptCurrInstr[3] & ATK48_DONT_CHECK_LOWER) + if (flags & ATK48_DONT_CHECK_LOWER) { if (gBattleMons[gActiveBattler].statStages[currStat] > 0) { @@ -4069,10 +4082,10 @@ static void atk48_playstatchangeanimation(void) } } else if (!gSideTimers[GET_BATTLER_SIDE(gActiveBattler)].mistTimer - && gBattleMons[gActiveBattler].ability != ABILITY_CLEAR_BODY - && gBattleMons[gActiveBattler].ability != ABILITY_WHITE_SMOKE - && !(gBattleMons[gActiveBattler].ability == ABILITY_KEEN_EYE && currStat == STAT_ACC) - && !(gBattleMons[gActiveBattler].ability == ABILITY_HYPER_CUTTER && currStat == STAT_ATK)) + && ability != ABILITY_CLEAR_BODY + && ability != ABILITY_WHITE_SMOKE + && !(ability == ABILITY_KEEN_EYE && currStat == STAT_ACC) + && !(ability == ABILITY_HYPER_CUTTER && currStat == STAT_ATK)) { if (gBattleMons[gActiveBattler].statStages[currStat] > 0) { @@ -4086,7 +4099,7 @@ static void atk48_playstatchangeanimation(void) if (changeableStatsCount > 1) // more than one stat, so the color is gray { - if (gBattlescriptCurrInstr[3] & ATK48_STAT_BY_TWO) + if (flags & ATK48_STAT_BY_TWO) statAnimId = STAT_ANIM_MULTIPLE_MINUS2; else statAnimId = STAT_ANIM_MULTIPLE_MINUS1; @@ -4094,8 +4107,7 @@ static void atk48_playstatchangeanimation(void) } else // goes up { - s16 startingStatAnimId; - if (gBattlescriptCurrInstr[3] & ATK48_STAT_BY_TWO) + if (flags & ATK48_STAT_BY_TWO) startingStatAnimId = STAT_ANIM_PLUS2 - 1; else startingStatAnimId = STAT_ANIM_PLUS1 - 1; @@ -4112,14 +4124,14 @@ static void atk48_playstatchangeanimation(void) if (changeableStatsCount > 1) // more than one stat, so the color is gray { - if (gBattlescriptCurrInstr[3] & ATK48_STAT_BY_TWO) + if (flags & ATK48_STAT_BY_TWO) statAnimId = STAT_ANIM_MULTIPLE_PLUS2; else statAnimId = STAT_ANIM_MULTIPLE_PLUS1; } } - if (gBattlescriptCurrInstr[3] & ATK48_ONLY_MULTIPLE && changeableStatsCount < 2) + if (flags & ATK48_ONLY_MULTIPLE && changeableStatsCount < 2) { gBattlescriptCurrInstr += 4; } @@ -4127,7 +4139,7 @@ static void atk48_playstatchangeanimation(void) { BtlController_EmitBattleAnimation(0, B_ANIM_STATS_CHANGE, statAnimId); MarkBattlerForControllerExec(gActiveBattler); - if (gBattlescriptCurrInstr[3] & ATK48_ONLY_MULTIPLE && changeableStatsCount > 1) + if (flags & ATK48_ONLY_MULTIPLE && changeableStatsCount > 1) gBattleScripting.statAnimPlayed = TRUE; gBattlescriptCurrInstr += 4; } @@ -7978,9 +7990,14 @@ static u32 ChangeStatBuffs(s8 statValue, u32 statId, u32 flags, const u8 *BS_ptr static void atk89_statbuffchange(void) { + u16 flags = T1_READ_16(gBattlescriptCurrInstr + 1); + const u8 *ptrBefore = gBattlescriptCurrInstr; const u8 *jumpPtr = T1_READ_PTR(gBattlescriptCurrInstr + 3); - if (ChangeStatBuffs(GET_STAT_BUFF_VALUE_WITH_SIGN(gBattleScripting.statChanger), GET_STAT_BUFF_ID(gBattleScripting.statChanger), T1_READ_16(gBattlescriptCurrInstr + 1), jumpPtr) == STAT_CHANGE_WORKED) + + if (ChangeStatBuffs(GET_STAT_BUFF_VALUE_WITH_SIGN(gBattleScripting.statChanger), GET_STAT_BUFF_ID(gBattleScripting.statChanger), flags, jumpPtr) == STAT_CHANGE_WORKED) gBattlescriptCurrInstr += 7; + else if (gBattlescriptCurrInstr == ptrBefore) // Prevent infinite looping. + gBattlescriptCurrInstr = jumpPtr; } static void atk8A_normalisebuffs(void) // haze diff --git a/src/data/battle_moves.h b/src/data/battle_moves.h index 4816621b0..89f499c2b 100644 --- a/src/data/battle_moves.h +++ b/src/data/battle_moves.h @@ -7813,7 +7813,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = [MOVE_V_CREATE] = { - .effect = EFFECT_PLACEHOLDER, // Needs a custom move effect + .effect = EFFECT_V_CREATE, .power = 180, .type = TYPE_FIRE, .accuracy = 95,