diff --git a/asm/macros/battle_script.inc b/asm/macros/battle_script.inc index ac1f3b5f0..95b3a2303 100644 --- a/asm/macros/battle_script.inc +++ b/asm/macros/battle_script.inc @@ -959,8 +959,9 @@ .4byte \param0 .endm - .macro nop_C1 + .macro setstickyweb ptr .byte 0xc1 + .4byte \ptr .endm .macro selectfirstvalidtarget @@ -1250,6 +1251,11 @@ .4byte \ptr .endm + .macro metalburstdamagecalculator ptr + .byte 0xff + .4byte \ptr + .endm + @ various command changed to more readable macros .macro cancelmultiturnmoves bank various \bank, VARIOUS_CANCEL_MULTI_TURN_MOVES @@ -1400,6 +1406,16 @@ .2byte \move .endm + .macro setluckychant battler ptr + various \battler VARIOUS_SET_LUCKY_CHANT + .4byte \ptr + .endm + + .macro suckerpunchcheck ptr + various BS_ATTACKER, VARIOUS_SUCKER_PUNCH_CHECK + .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 cf6e8ef8a..fed31bb51 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -270,6 +270,38 @@ gBattleScriptsForMoveEffects:: @ 82D86A8 .4byte BattleScript_EffectHeartSwap .4byte BattleScript_EffectPowerSplit .4byte BattleScript_EffectGuardSplit + .4byte BattleScript_EffectStickyWeb + .4byte BattleScript_EffectMetalBurst + .4byte BattleScript_EffectLuckyChant + .4byte BattleScript_EffectSuckerPunch + +BattleScript_EffectSuckerPunch: + attackcanceler + suckerpunchcheck BattleScript_ButItFailedAtkStringPpReduce + accuracycheck BattleScript_PrintMoveMissed, ACC_CURR_MOVE + goto BattleScript_HitFromAtkString + +BattleScript_EffectLuckyChant: + attackcanceler + attackstring + ppreduce + setluckychant BS_ATTACKER, BattleScript_ButItFailed + attackanimation + waitanimation + printstring STRINGID_SHIELDEDFROMCRITICALHITS + waitmessage 0x40 + goto BattleScript_MoveEnd + +BattleScript_EffectMetalBurst: + attackcanceler + metalburstdamagecalculator BattleScript_ButItFailedAtkStringPpReduce + accuracycheck BattleScript_PrintMoveMissed, ACC_CURR_MOVE + attackstring + ppreduce + typecalc + bichalfword gMoveResultFlags, MOVE_RESULT_NOT_VERY_EFFECTIVE | MOVE_RESULT_SUPER_EFFECTIVE + adjustdamage + goto BattleScript_HitFromAtkAnimation BattleScript_EffectHealingWish: attackcanceler @@ -422,6 +454,17 @@ BattleScript_EffectStealthRock: waitmessage 0x40 goto BattleScript_MoveEnd +BattleScript_EffectStickyWeb: + attackcanceler + attackstring + ppreduce + setstickyweb BattleScript_ButItFailed + attackanimation + waitanimation + printstring STRINGID_STICKYWEBUSED + waitmessage 0x40 + goto BattleScript_MoveEnd + BattleScript_EffectGastroAcid: attackcanceler accuracycheck BattleScript_PrintMoveMissed, ACC_CURR_MOVE diff --git a/include/constants/battle_move_effects.h b/include/constants/battle_move_effects.h index 2c3c2f666..dab3b46be 100644 --- a/include/constants/battle_move_effects.h +++ b/include/constants/battle_move_effects.h @@ -259,5 +259,9 @@ #define EFFECT_HEART_SWAP 253 #define EFFECT_POWER_SPLIT 254 #define EFFECT_GUARD_SPLIT 255 +#define EFFECT_STICKY_WEB 256 +#define EFFECT_METAL_BURST 257 +#define EFFECT_LUCKY_CHANT 258 +#define EFFECT_SUCKER_PUNCH 259 #endif // GUARD_CONSTANTS_BATTLE_MOVE_EFFECTS_H diff --git a/include/constants/battle_script_commands.h b/include/constants/battle_script_commands.h index 66de41c2a..e8706ed31 100644 --- a/include/constants/battle_script_commands.h +++ b/include/constants/battle_script_commands.h @@ -83,6 +83,8 @@ #define VARIOUS_TRY_ACTIVATE_MOXIE 34 #define VARIOUS_TRY_ACTIVATE_FELL_STINGER 35 #define VARIOUS_PLAY_MOVE_ANIMATION 36 +#define VARIOUS_SET_LUCKY_CHANT 37 +#define VARIOUS_SUCKER_PUNCH_CHECK 38 // 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 528e4419c..63bbf599f 100644 --- a/include/constants/battle_string_ids.h +++ b/include/constants/battle_string_ids.h @@ -490,7 +490,8 @@ #define STRINGID_GRAVITYPREVENTSUSAGE 487 #define STRINGID_HEALBLOCKPREVENTSUSAGE 488 #define STRINGID_NOTDONEYET 489 +#define STRINGID_STICKYWEBUSED 490 -#define BATTLESTRINGS_COUNT 501 +#define BATTLESTRINGS_COUNT 506 #endif // GUARD_CONSTANTS_BATTLE_STRING_IDS_H diff --git a/include/data/battle_moves.h b/include/data/battle_moves.h index 1f6c3d159..c7dcd5749 100644 --- a/include/data/battle_moves.h +++ b/include/data/battle_moves.h @@ -4420,7 +4420,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_GEN6] = .split = SPLIT_STATUS, }, { // MOVE_METAL_BURST - .effect = EFFECT_PLACEHOLDER, // Needs a custom move effect (Counters 1.5x damage) + .effect = EFFECT_METAL_BURST, .power = 0, .type = TYPE_STEEL, .accuracy = 100, @@ -4576,7 +4576,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_GEN6] = .split = SPLIT_STATUS, }, { // MOVE_LUCKY_CHANT - .effect = EFFECT_PLACEHOLDER, // Needs a custom move effect + .effect = EFFECT_LUCKY_CHANT, .power = 0, .type = TYPE_NORMAL, .accuracy = 0, @@ -4672,7 +4672,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_GEN6] = .split = SPLIT_STATUS, }, { // MOVE_SUCKER_PUNCH - .effect = EFFECT_PLACEHOLDER, // Needs a custom move effect + .effect = EFFECT_SUCKER_PUNCH, .power = 70, .type = TYPE_DARK, .accuracy = 100, @@ -6772,7 +6772,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_GEN6] = .split = SPLIT_STATUS, }, { // MOVE_STICKY_WEB - .effect = EFFECT_PLACEHOLDER, // Needs a custom move effect + .effect = EFFECT_STICKY_WEB, .power = 0, .type = TYPE_BUG, .accuracy = 0, diff --git a/include/pokemon.h b/include/pokemon.h index d979d9b5e..9b03e0001 100644 --- a/include/pokemon.h +++ b/include/pokemon.h @@ -353,9 +353,11 @@ struct BaseStats u8 noFlip : 1; }; +// Argument and effect field are temporarily switched till functions referencing gBattleMoves are decompiled. + struct BattleMove { - u8 effect; + u8 argument; u8 power; u8 type; u8 accuracy; @@ -365,7 +367,7 @@ struct BattleMove s8 priority; u32 flags; u8 split; - u8 argument; + u16 effect; }; struct SpindaSpot diff --git a/src/battle_message.c b/src/battle_message.c index b1387dd16..ecaa88aad 100644 --- a/src/battle_message.c +++ b/src/battle_message.c @@ -628,6 +628,7 @@ static const u8 sText_TargetStatWontGoHigher[] = _("{B_DEF_NAME_WITH_PREFIX}’s static const u8 sText_PkmnMoveBouncedViaAbility[] = _("{B_ATK_NAME_WITH_PREFIX}’s {B_CURRENT_MOVE} was\nbounced back by {B_DEF_NAME_WITH_PREFIX}’s\l{B_DEF_ABILITY}!"); 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[] = _(""); // New selection strings, they must end with "\p". // Use {B_LAST_ITEM} and {B_CURRENT_MOVE}. @@ -1116,6 +1117,7 @@ const u8 *const gBattleStringsTable[BATTLESTRINGS_COUNT] = sText_GravityPreventsUsage, sText_HealBlockPreventsUsage, sText_NotDoneYet, + sText_StickyWebUsed, }; const u16 gMagicCoatBounceStringIds[] = diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index e5f351f36..6a086fd56 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -284,7 +284,7 @@ static void atkBD_copyfoestats(void); static void atkBE_rapidspinfree(void); static void atkBF_setdefensecurlbit(void); static void atkC0_recoverbasedonsunlight(void); -static void atkC1_nop(void); +static void atkC1_setstickyweb(void); static void atkC2_selectfirstvalidtarget(void); static void atkC3_trysetfutureattack(void); static void atkC4_trydobeatup(void); @@ -346,6 +346,7 @@ static void atkFB_averagestats(void); static void atkFC_jumpifoppositegenders(void); static void atkFD_trygetbaddreamstarget(void); static void atkFE_tryworryseed(void); +static void atkFF_metalburstdamagecalculator(void); void (* const gBattleScriptingCommandsTable[])(void) = { @@ -542,7 +543,7 @@ void (* const gBattleScriptingCommandsTable[])(void) = atkBE_rapidspinfree, atkBF_setdefensecurlbit, atkC0_recoverbasedonsunlight, - atkC1_nop, + atkC1_setstickyweb, atkC2_selectfirstvalidtarget, atkC3_trysetfutureattack, atkC4_trydobeatup, @@ -604,6 +605,7 @@ void (* const gBattleScriptingCommandsTable[])(void) = atkFC_jumpifoppositegenders, atkFD_trygetbaddreamstarget, atkFE_tryworryseed, + atkFF_metalburstdamagecalculator, }; struct StatFractions @@ -6307,6 +6309,27 @@ static void atk76_various(void) MarkBattlerForControllerExec(gActiveBattler); gBattlescriptCurrInstr += 5; return; + case VARIOUS_SET_LUCKY_CHANT: + if (!(gSideStatuses[GET_BATTLER_SIDE(gActiveBattler)] & SIDE_STATUS_LUCKY_CHANT)) + { + gSideStatuses[GET_BATTLER_SIDE(gActiveBattler)] |= SIDE_STATUS_LUCKY_CHANT; + gSideTimers[GET_BATTLER_SIDE(gActiveBattler)].luckyChantBattlerId = gActiveBattler; + gSideTimers[GET_BATTLER_SIDE(gActiveBattler)].luckyChantTimer = 5; + gBattlescriptCurrInstr += 7; + } + else + { + gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); + } + return; + case VARIOUS_SUCKER_PUNCH_CHECK: + if (GetBattlerTurnOrderNum(gBattlerAttacker) > GetBattlerTurnOrderNum(gBattlerTarget)) + gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); + else if (gBattleMoves[gBattleMons[gBattlerTarget].moves[gBattleStruct->chosenMovePositions[gBattlerTarget]]].power == 0) + gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); + else + gBattlescriptCurrInstr += 7; + return; } gBattlescriptCurrInstr += 3; @@ -8649,9 +8672,19 @@ static void atkC0_recoverbasedonsunlight(void) } } -static void atkC1_nop(void) +static void atkC1_setstickyweb(void) { - gBattlescriptCurrInstr++; + u8 targetSide = GetBattlerSide(gBattlerTarget); + if (gSideStatuses[targetSide] & SIDE_STATUS_STICKY_WEB) + { + gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); + } + else + { + gSideStatuses[targetSide] |= SIDE_STATUS_STICKY_WEB; + gSideTimers[targetSide].stickyWebAmount = 1; + gBattlescriptCurrInstr += 5; + } } static void atkC2_selectfirstvalidtarget(void) @@ -10161,3 +10194,42 @@ static void atkFE_tryworryseed(void) break; } } + +static void atkFF_metalburstdamagecalculator(void) +{ + u8 sideAttacker = GetBattlerSide(gBattlerAttacker); + u8 sideTarget = 0; + + if (gProtectStructs[gBattlerAttacker].physicalDmg + && sideAttacker != (sideTarget = GetBattlerSide(gProtectStructs[gBattlerAttacker].physicalBattlerId)) + && gBattleMons[gProtectStructs[gBattlerAttacker].physicalBattlerId].hp) + { + gBattleMoveDamage = gProtectStructs[gBattlerAttacker].physicalDmg * 150 / 100; + + if (gSideTimers[sideTarget].followmeTimer && gBattleMons[gSideTimers[sideTarget].followmeTarget].hp) + gBattlerTarget = gSideTimers[sideTarget].followmeTarget; + else + gBattlerTarget = gProtectStructs[gBattlerAttacker].physicalBattlerId; + + gBattlescriptCurrInstr += 5; + } + else if (gProtectStructs[gBattlerAttacker].specialDmg + && sideAttacker != (sideTarget = GetBattlerSide(gProtectStructs[gBattlerAttacker].specialBattlerId)) + && gBattleMons[gProtectStructs[gBattlerAttacker].specialBattlerId].hp) + { + gBattleMoveDamage = gProtectStructs[gBattlerAttacker].specialDmg * 150 / 100; + + if (gSideTimers[sideTarget].followmeTimer && gBattleMons[gSideTimers[sideTarget].followmeTarget].hp) + gBattlerTarget = gSideTimers[sideTarget].followmeTarget; + else + gBattlerTarget = gProtectStructs[gBattlerAttacker].specialBattlerId; + + gBattlescriptCurrInstr += 5; + } + else + { + gSpecialStatuses[gBattlerAttacker].flag20 = 1; + gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); + } +} +