diff --git a/asm/macros/battle_script.inc b/asm/macros/battle_script.inc index fb34f4fc5..12bc6f531 100644 --- a/asm/macros/battle_script.inc +++ b/asm/macros/battle_script.inc @@ -1496,6 +1496,11 @@ .4byte \ptr .endm + .macro trycopycat ptr + various BS_ATTACKER, VARIOUS_TRY_COPYCAT + .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 efd3e8e39..fd27394fe 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -316,6 +316,19 @@ gBattleScriptsForMoveEffects:: @ 82D86A8 .4byte BattleScript_EffectTechnoBlast .4byte BattleScript_EffectJudgment .4byte BattleScript_EffectAutonomize + .4byte BattleScript_EffectCopycat + +BattleScript_EffectCopycat: + attackcanceler + attackstring + pause 0x5 + trycopycat BattleScript_CopycatFail + attackanimation + waitanimation + jumptorandomattack TRUE +BattleScript_CopycatFail: + ppreduce + goto BattleScript_ButItFailed BattleScript_EffectAutonomize: setstatchanger STAT_SPEED, 2, FALSE diff --git a/include/battle.h b/include/battle.h index e35f2e635..576388243 100644 --- a/include/battle.h +++ b/include/battle.h @@ -827,6 +827,7 @@ extern u16 gLastLandedMoves[MAX_BATTLERS_COUNT]; extern u16 gLastHitByType[MAX_BATTLERS_COUNT]; extern u16 gLastResultingMoves[MAX_BATTLERS_COUNT]; extern u16 gLockedMoves[MAX_BATTLERS_COUNT]; +extern u16 gLastUsedMove; extern u8 gLastHitBy[MAX_BATTLERS_COUNT]; extern u16 gChosenMoveByBattler[MAX_BATTLERS_COUNT]; extern u16 gMoveResultFlags; diff --git a/include/constants/battle_move_effects.h b/include/constants/battle_move_effects.h index 93f4f727e..c67ea43a1 100644 --- a/include/constants/battle_move_effects.h +++ b/include/constants/battle_move_effects.h @@ -305,5 +305,6 @@ #define EFFECT_TECHNO_BLAST 299 #define EFFECT_JUDGMENT 300 #define EFFECT_AUTONOMIZE 301 +#define EFFECT_COPYCAT 302 #endif // GUARD_CONSTANTS_BATTLE_MOVE_EFFECTS_H diff --git a/include/constants/battle_script_commands.h b/include/constants/battle_script_commands.h index 062db7ccc..9dc0f664c 100644 --- a/include/constants/battle_script_commands.h +++ b/include/constants/battle_script_commands.h @@ -105,6 +105,7 @@ #define VARIOUS_ARGUMENT_STATUS_EFFECT 53 #define VARIOUS_TRY_HIT_SWITCH_TARGET 54 #define VARIOUS_TRY_AUTONOMIZE 55 +#define VARIOUS_TRY_COPYCAT 56 // atk80, dmg manipulation #define ATK80_DMG_CHANGE_SIGN 0 diff --git a/src/battle_main.c b/src/battle_main.c index cbd4945e7..638fc3e58 100644 --- a/src/battle_main.c +++ b/src/battle_main.c @@ -246,6 +246,7 @@ EWRAM_DATA u16 gLastLandedMoves[MAX_BATTLERS_COUNT] = {0}; EWRAM_DATA u16 gLastHitByType[MAX_BATTLERS_COUNT] = {0}; EWRAM_DATA u16 gLastResultingMoves[MAX_BATTLERS_COUNT] = {0}; EWRAM_DATA u16 gLockedMoves[MAX_BATTLERS_COUNT] = {0}; +EWRAM_DATA u16 gLastUsedMove = 0; EWRAM_DATA u8 gLastHitBy[MAX_BATTLERS_COUNT] = {0}; EWRAM_DATA u16 gChosenMoveByBattler[MAX_BATTLERS_COUNT] = {0}; EWRAM_DATA u16 gMoveResultFlags = 0; @@ -3009,6 +3010,7 @@ static void BattleStartClearSetData(void) gPalaceSelectionBattleScripts[i] = 0; } + gLastUsedMove = 0; gFieldStatuses = 0; memset(&gFieldTimers, 0, sizeof(gFieldTimers)); diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index ec4d6bca7..e22eed110 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -785,9 +785,11 @@ static const u16 sProtectSuccessRates[] = {USHRT_MAX, USHRT_MAX / 2, USHRT_MAX / #define MIMIC_FORBIDDEN_END 0xFFFE #define METRONOME_FORBIDDEN_END 0xFFFF #define ASSIST_FORBIDDEN_END 0xFFFF +#define COPYCAT_FORBIDDEN_END 0xFFFF static const u16 sMovesForbiddenToCopy[] = { + MOVE_TRANSFORM, MOVE_METRONOME, MOVE_STRUGGLE, MOVE_SKETCH, @@ -807,6 +809,15 @@ static const u16 sMovesForbiddenToCopy[] = MOVE_COVET, MOVE_TRICK, MOVE_FOCUS_PUNCH, + MOVE_CIRCLE_THROW, + MOVE_DRAGON_TAIL, + MOVE_RAGE_POWDER, + MOVE_MAT_BLOCK, + MOVE_SPIKY_SHIELD, + MOVE_SHELL_TRAP, + MOVE_SPOTLIGHT, + MOVE_FEINT, + MOVE_KING_S_SHIELD, METRONOME_FORBIDDEN_END }; @@ -4241,6 +4252,7 @@ static void atk49_moveend(void) if (gHitMarker & HITMARKER_ATTACKSTRING_PRINTED) { gLastPrintedMoves[gBattlerAttacker] = gChosenMove; + gLastUsedMove = gCurrentMove; } if (!(gAbsentBattlerFlags & gBitTable[gBattlerAttacker]) && !(gBattleStruct->field_91 & gBitTable[gBattlerAttacker]) @@ -6746,6 +6758,24 @@ static void atk76_various(void) gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); } return; + case VARIOUS_TRY_COPYCAT: + for (i = 0; sMovesForbiddenToCopy[i] != COPYCAT_FORBIDDEN_END; i++) + { + if (sMovesForbiddenToCopy[i] == gLastUsedMove) + break; + } + if (gLastUsedMove == 0 || gLastUsedMove == 0xFFFF || sMovesForbiddenToCopy[i] != COPYCAT_FORBIDDEN_END) + { + gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); + } + else + { + gRandomMove = gLastUsedMove; + gHitMarker &= ~(HITMARKER_ATTACKSTRING_PRINTED); + gBattlerTarget = GetMoveTarget(gRandomMove, 0); + gBattlescriptCurrInstr += 7; + } + return; } gBattlescriptCurrInstr += 3; diff --git a/src/data/battle_moves.h b/src/data/battle_moves.h index 6858d869e..50c202328 100644 --- a/src/data/battle_moves.h +++ b/src/data/battle_moves.h @@ -4601,7 +4601,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = .split = SPLIT_STATUS, }, { // MOVE_COPYCAT - .effect = EFFECT_PLACEHOLDER, // Needs a custom move effect + .effect = EFFECT_COPYCAT, .power = 0, .type = TYPE_NORMAL, .accuracy = 0,