From e152a5524d8ab942dbc7301122d295789fa60ee4 Mon Sep 17 00:00:00 2001 From: Kevin van Rijn Date: Tue, 7 Jan 2025 19:38:35 +0100 Subject: [PATCH] Add Mystery Dungeon Moves --- data/battle_anim_scripts.s | 39 +++++++++++++++++++ include/battle_anim_scripts.h | 4 ++ include/constants/moves.h | 6 ++- src/data/moves_info.h | 45 ++++++++++++++++++++++ src/pokemon.c | 15 ++++++++ test/battle/move_effect/fixed_damage_arg.c | 14 +++++++ 6 files changed, 122 insertions(+), 1 deletion(-) diff --git a/data/battle_anim_scripts.s b/data/battle_anim_scripts.s index ae8642feb4..fed1185f92 100644 --- a/data/battle_anim_scripts.s +++ b/data/battle_anim_scripts.s @@ -28989,6 +28989,45 @@ gBattleAnimSpecial_CriticalCaptureBallThrow:: jumpreteq -1, BallThrowTrainerBlock goto BallThrowEnd +@@@@@@@@@@ MYSTERY DUNGEON MOVES @@@@@@@@@@ +gBattleAnimMove_WideSlash:: + loadspritegfx ANIM_TAG_AIR_WAVE + loadspritegfx ANIM_TAG_CUT + loadspritegfx ANIM_TAG_IMPACT + delay 0 + monbg ANIM_DEF_PARTNER + setalpha 12, 8 + delay 0 + playsewithpan SE_M_CUT, SOUND_PAN_TARGET + createsprite gAirCutterSliceSpriteTemplate, ANIM_ATTACKER, 2, 40, -32, 0, 2 + delay 5 + createvisualtask AnimTask_ShakeMon2, 2, ANIM_TARGET, 2, 0, 8, 1 + createvisualtask AnimTask_ShakeMon2, 2, ANIM_DEF_PARTNER, 2, 0, 8, 1 + waitforvisualfinish + blendoff + clearmonbg ANIM_DEF_PARTNER + delay 0 + end + +gBattleAnimMove_VacuumCut:: + loadspritegfx ANIM_TAG_AIR_WAVE + loadspritegfx ANIM_TAG_CUT + loadspritegfx ANIM_TAG_IMPACT + delay 0 + monbg ANIM_DEF_PARTNER + setalpha 12, 8 + delay 0 + createvisualtask AnimTask_AirCutterProjectile, 2, 32, -24, 6 * 256, 2, 128 @ 6 * 256 == Q_8_8(6) + waitforvisualfinish + delay 0 + createvisualtask AnimTask_ShakeMon2, 2, ANIM_TARGET, 2, 0, 8, 1 + createvisualtask AnimTask_ShakeMon2, 2, ANIM_DEF_PARTNER, 2, 0, 8, 1 + waitforvisualfinish + blendoff + clearmonbg ANIM_DEF_PARTNER + delay 0 + end + @@@@@@@@@@ Z MOVES @@@@@@@@@@ gBattleAnimMove_BreakneckBlitz:: loadspritegfx ANIM_TAG_HOLLOW_ORB diff --git a/include/battle_anim_scripts.h b/include/battle_anim_scripts.h index 6c49788975..37f42d95b8 100644 --- a/include/battle_anim_scripts.h +++ b/include/battle_anim_scripts.h @@ -1004,6 +1004,10 @@ extern const u8 gBattleAnimGeneral_TeraCharge[]; extern const u8 gBattleAnimGeneral_TeraActivate[]; extern const u8 gBattleAnimGeneral_SimpleHeal[]; +// Mystery Dungeon Moves +extern const u8 gBattleAnimMove_WideSlash[]; +extern const u8 gBattleAnimMove_VacuumCut[]; + // special animations extern const u8 gBattleAnimSpecial_LevelUp[]; extern const u8 gBattleAnimSpecial_SwitchOutPlayerMon[]; diff --git a/include/constants/moves.h b/include/constants/moves.h index dc8bc59a3f..0b42ec675f 100644 --- a/include/constants/moves.h +++ b/include/constants/moves.h @@ -910,7 +910,11 @@ #define MOVES_COUNT_GEN9 848 -#define MOVES_COUNT MOVES_COUNT_GEN9 +// Mystery Dungeon Moves +#define MOVE_WIDE_SLASH (MOVES_COUNT_GEN9 + 0) +#define MOVE_VACUUM_CUT (MOVES_COUNT_GEN9 + 1) + +#define MOVES_COUNT (MOVES_COUNT_GEN9 + 2) // Z Moves #define MOVE_BREAKNECK_BLITZ (MOVES_COUNT + 0) diff --git a/src/data/moves_info.h b/src/data/moves_info.h index 4ff3b71f4c..2d79a05271 100644 --- a/src/data/moves_info.h +++ b/src/data/moves_info.h @@ -20724,6 +20724,51 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .battleAnimScript = gBattleAnimMove_MalignantChain, }, + // Mystery Dungeon Moves + [MOVE_WIDE_SLASH] = + { + .name = COMPOUND_STRING("Wide Slash"), + .description = COMPOUND_STRING( + "Slashes with claws, etc.\n" + "Deals typeless damage."), + .effect = EFFECT_HIT, + .power = 100, + .type = TYPE_MYSTERY, + .accuracy = 85, + .pp = 10, + .target = MOVE_TARGET_BOTH, + .priority = 0, + .category = DAMAGE_CATEGORY_PHYSICAL, + .makesContact = TRUE, + .slicingMove = TRUE, + .contestEffect = CONTEST_EFFECT_STARTLE_MONS_SAME_TYPE_APPEAL, + .contestCategory = CONTEST_CATEGORY_COOL, + .contestComboStarterId = 0, + .contestComboMoves = {0}, + .battleAnimScript = gBattleAnimMove_WideSlash, + }, + [MOVE_VACUUM_CUT] = + { + .name = COMPOUND_STRING("Vacuum-Cut"), + .description = COMPOUND_STRING( + "Attack that always inflicts\n" + "35 HP typeless damage."), + .effect = EFFECT_FIXED_DAMAGE_ARG, + .power = 1, + .type = TYPE_MYSTERY, + .accuracy = 100, + .pp = 10, + .target = MOVE_TARGET_BOTH, + .priority = 0, + .category = DAMAGE_CATEGORY_SPECIAL, + .argument = 35, + .contestEffect = CONTEST_EFFECT_STARTLE_MONS_SAME_TYPE_APPEAL, + .contestCategory = CONTEST_CATEGORY_COOL, + .contestComboStarterId = 0, + .contestComboMoves = {0}, + .battleAnimScript = gBattleAnimMove_VacuumCut, + }, + // Z-Moves [MOVE_BREAKNECK_BLITZ] = { diff --git a/src/pokemon.c b/src/pokemon.c index d6ed5020b8..3274e0076e 100644 --- a/src/pokemon.c +++ b/src/pokemon.c @@ -5509,6 +5509,8 @@ static const u16 sUniversalMoves[] = MOVE_SECRET_POWER, MOVE_SUBSTITUTE, MOVE_TERA_BLAST, + MOVE_WIDE_SLASH, + MOVE_VACUUM_CUT, }; u8 CanLearnTeachableMove(u16 species, u16 move) @@ -5559,6 +5561,19 @@ u8 CanLearnTeachableMove(u16 species, u16 move) } else { + switch (species) + { + case SPECIES_MAGIKARP: + case SPECIES_DITTO: + case SPECIES_SMEARGLE: + case SPECIES_WURMPLE: + case SPECIES_SILCOON: + case SPECIES_CASCOON: + case SPECIES_KRICKETOT: + if(move == MOVE_WIDE_SLASH || move == MOVE_VACUUM_CUT) + return TRUE; + } + const struct LevelUpMove *learnset = GetSpeciesLevelUpLearnset(species); if (P_TM_LITERACY < GEN_6) diff --git a/test/battle/move_effect/fixed_damage_arg.c b/test/battle/move_effect/fixed_damage_arg.c index 484601be05..f893cdf979 100644 --- a/test/battle/move_effect/fixed_damage_arg.c +++ b/test/battle/move_effect/fixed_damage_arg.c @@ -4,6 +4,8 @@ ASSUMPTIONS { ASSUME(gMovesInfo[MOVE_SONIC_BOOM].effect == EFFECT_FIXED_DAMAGE_ARG); + ASSUME(gMovesInfo[MOVE_VACUUM_CUT].type == TYPE_MYSTERY); + ASSUME(gMovesInfo[MOVE_VACUUM_CUT].effect == EFFECT_FIXED_DAMAGE_ARG); } SINGLE_BATTLE_TEST("Sonic Boom deals fixed damage", s16 damage) @@ -39,3 +41,15 @@ SINGLE_BATTLE_TEST("Sonic Boom doesn't affect ghost types") MESSAGE("It doesn't affect the opposing Gastly…"); } } + +SINGLE_BATTLE_TEST("Vacuum-Cut bypasses Wonder Guard") +{ + GIVEN { + PLAYER(SPECIES_SHEDINJA) { Ability(ABILITY_WONDER_GUARD); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(opponent, MOVE_VACUUM_CUT); } + } SCENE { + MESSAGE("Shedinja fainted!"); + } +}