diff --git a/docs/tutorials/how_to_new_move.md b/docs/tutorials/how_to_new_move.md index e3a2eb0a12..e4289f4c58 100644 --- a/docs/tutorials/how_to_new_move.md +++ b/docs/tutorials/how_to_new_move.md @@ -169,8 +169,6 @@ Each move can have up to 15 additional effects, allowing you to construct monstr .moveEffect = MOVE_EFFECT_ALL_STATS_UP, .chance = 40, .self = TRUE, - },{ - .moveEffect = MOVE_EFFECT_RAPID_SPIN, },{ .moveEffect = MOVE_EFFECT_DEF_MINUS_2, .chance = 50, diff --git a/graphics/pokemon/clodsire/anim_front.png b/graphics/pokemon/clodsire/anim_front.png new file mode 100644 index 0000000000..1630189f62 Binary files /dev/null and b/graphics/pokemon/clodsire/anim_front.png differ diff --git a/graphics/pokemon/clodsire/back.png b/graphics/pokemon/clodsire/back.png index 64132a060f..115f842435 100755 Binary files a/graphics/pokemon/clodsire/back.png and b/graphics/pokemon/clodsire/back.png differ diff --git a/graphics/pokemon/clodsire/front.png b/graphics/pokemon/clodsire/front.png deleted file mode 100755 index 2722b7eb70..0000000000 Binary files a/graphics/pokemon/clodsire/front.png and /dev/null differ diff --git a/graphics/pokemon/clodsire/normal.pal b/graphics/pokemon/clodsire/normal.pal index c7d36df32c..bf8f45d0c8 100755 --- a/graphics/pokemon/clodsire/normal.pal +++ b/graphics/pokemon/clodsire/normal.pal @@ -1,19 +1,19 @@ JASC-PAL 0100 16 -152 208 160 -64 60 48 -128 108 96 +153 211 165 +248 141 165 +176 90 105 +105 54 57 +184 160 162 +152 122 126 +86 71 72 +128 109 102 96 80 72 -48 40 32 +69 60 50 +51 41 36 +46 39 36 16 16 16 -184 160 160 -208 208 208 -40 36 32 -152 120 120 -80 68 72 -104 52 56 -176 88 104 -248 140 160 -0 0 0 -0 0 0 +215 189 217 +152 116 156 +91 67 108 diff --git a/graphics/pokemon/clodsire/shiny.pal b/graphics/pokemon/clodsire/shiny.pal index fcf3c9dc23..e3c18d79db 100755 --- a/graphics/pokemon/clodsire/shiny.pal +++ b/graphics/pokemon/clodsire/shiny.pal @@ -1,19 +1,19 @@ JASC-PAL 0100 16 -152 208 160 -74 67 90 -127 116 143 -107 97 124 -46 40 44 -16 16 16 +153 211 165 +248 141 142 +176 94 90 +105 62 54 160 158 197 -205 180 170 -40 36 32 127 127 157 87 85 112 -104 52 56 -176 88 104 -248 140 160 -0 0 0 -0 0 0 +127 116 143 +107 97 124 +74 67 90 +49 43 62 +46 40 44 +16 16 16 +230 209 181 +201 159 123 +99 63 59 diff --git a/graphics/pokemon/grookey/back.png b/graphics/pokemon/grookey/back.png index b7f6c6076e..bdcc5924d4 100644 Binary files a/graphics/pokemon/grookey/back.png and b/graphics/pokemon/grookey/back.png differ diff --git a/graphics/pokemon/grookey/overworld.png b/graphics/pokemon/grookey/overworld.png index 2fb8352956..928fd09bc4 100644 Binary files a/graphics/pokemon/grookey/overworld.png and b/graphics/pokemon/grookey/overworld.png differ diff --git a/include/battle_util.h b/include/battle_util.h index 69ba274df3..d6ff55ffee 100644 --- a/include/battle_util.h +++ b/include/battle_util.h @@ -155,6 +155,7 @@ struct DamageCalculationData u32 updateFlags:1; u32 padding:2; }; +STATIC_ASSERT(sizeof(struct DamageCalculationData) <= 4, StructExceedsFourBytes); enum SleepClauseBlock { diff --git a/include/constants/battle.h b/include/constants/battle.h index a05d9e8e96..853094d853 100644 --- a/include/constants/battle.h +++ b/include/constants/battle.h @@ -364,61 +364,60 @@ enum BattleWeather #define MOVE_EFFECT_PREVENT_ESCAPE 33 #define MOVE_EFFECT_NIGHTMARE 34 #define MOVE_EFFECT_ALL_STATS_UP 35 -#define MOVE_EFFECT_RAPID_SPIN 36 -#define MOVE_EFFECT_REMOVE_STATUS 37 -#define MOVE_EFFECT_ATK_DEF_DOWN 38 -#define MOVE_EFFECT_ATK_PLUS_2 39 -#define MOVE_EFFECT_DEF_PLUS_2 40 -#define MOVE_EFFECT_SPD_PLUS_2 41 -#define MOVE_EFFECT_SP_ATK_PLUS_2 42 -#define MOVE_EFFECT_SP_DEF_PLUS_2 43 -#define MOVE_EFFECT_ACC_PLUS_2 44 -#define MOVE_EFFECT_EVS_PLUS_2 45 -#define MOVE_EFFECT_ATK_MINUS_2 46 -#define MOVE_EFFECT_DEF_MINUS_2 47 -#define MOVE_EFFECT_SPD_MINUS_2 48 -#define MOVE_EFFECT_SP_ATK_MINUS_2 49 -#define MOVE_EFFECT_SP_DEF_MINUS_2 50 -#define MOVE_EFFECT_ACC_MINUS_2 51 -#define MOVE_EFFECT_EVS_MINUS_2 52 -#define MOVE_EFFECT_SCALE_SHOT 53 -#define MOVE_EFFECT_THRASH 54 -#define MOVE_EFFECT_KNOCK_OFF 55 -#define MOVE_EFFECT_DEF_SPDEF_DOWN 56 -#define MOVE_EFFECT_CLEAR_SMOG 57 -#define MOVE_EFFECT_SMACK_DOWN 58 -#define MOVE_EFFECT_FLAME_BURST 59 -#define MOVE_EFFECT_FEINT 60 -#define MOVE_EFFECT_SPECTRAL_THIEF 61 -#define MOVE_EFFECT_V_CREATE 62 -#define MOVE_EFFECT_HAPPY_HOUR 63 -#define MOVE_EFFECT_CORE_ENFORCER 64 -#define MOVE_EFFECT_THROAT_CHOP 65 -#define MOVE_EFFECT_INCINERATE 66 -#define MOVE_EFFECT_BUG_BITE 67 -#define MOVE_EFFECT_RECOIL_HP_25 68 -#define MOVE_EFFECT_TRAP_BOTH 69 -#define MOVE_EFFECT_ROUND 70 -#define MOVE_EFFECT_STOCKPILE_WORE_OFF 71 -#define MOVE_EFFECT_DIRE_CLAW 72 -#define MOVE_EFFECT_STEALTH_ROCK 73 -#define MOVE_EFFECT_SPIKES 74 -#define MOVE_EFFECT_SYRUP_BOMB 75 -#define MOVE_EFFECT_FLORAL_HEALING 76 -#define MOVE_EFFECT_SECRET_POWER 77 -#define MOVE_EFFECT_PSYCHIC_NOISE 78 -#define MOVE_EFFECT_TERA_BLAST 79 -#define MOVE_EFFECT_ORDER_UP 80 -#define MOVE_EFFECT_ION_DELUGE 81 -#define MOVE_EFFECT_AROMATHERAPY 82 // No functionality yet -#define MOVE_EFFECT_HAZE 83 -#define MOVE_EFFECT_LEECH_SEED 84 -#define MOVE_EFFECT_REFLECT 85 -#define MOVE_EFFECT_LIGHT_SCREEN 86 -#define MOVE_EFFECT_SALT_CURE 87 -#define MOVE_EFFECT_EERIE_SPELL 88 +#define MOVE_EFFECT_REMOVE_STATUS 36 +#define MOVE_EFFECT_ATK_DEF_DOWN 37 +#define MOVE_EFFECT_ATK_PLUS_2 38 +#define MOVE_EFFECT_DEF_PLUS_2 39 +#define MOVE_EFFECT_SPD_PLUS_2 40 +#define MOVE_EFFECT_SP_ATK_PLUS_2 41 +#define MOVE_EFFECT_SP_DEF_PLUS_2 42 +#define MOVE_EFFECT_ACC_PLUS_2 43 +#define MOVE_EFFECT_EVS_PLUS_2 44 +#define MOVE_EFFECT_ATK_MINUS_2 45 +#define MOVE_EFFECT_DEF_MINUS_2 46 +#define MOVE_EFFECT_SPD_MINUS_2 47 +#define MOVE_EFFECT_SP_ATK_MINUS_2 48 +#define MOVE_EFFECT_SP_DEF_MINUS_2 49 +#define MOVE_EFFECT_ACC_MINUS_2 50 +#define MOVE_EFFECT_EVS_MINUS_2 51 +#define MOVE_EFFECT_SCALE_SHOT 52 +#define MOVE_EFFECT_THRASH 53 +#define MOVE_EFFECT_KNOCK_OFF 54 +#define MOVE_EFFECT_DEF_SPDEF_DOWN 55 +#define MOVE_EFFECT_CLEAR_SMOG 56 +#define MOVE_EFFECT_SMACK_DOWN 57 +#define MOVE_EFFECT_FLAME_BURST 58 +#define MOVE_EFFECT_FEINT 59 +#define MOVE_EFFECT_SPECTRAL_THIEF 60 +#define MOVE_EFFECT_V_CREATE 61 +#define MOVE_EFFECT_HAPPY_HOUR 62 +#define MOVE_EFFECT_CORE_ENFORCER 63 +#define MOVE_EFFECT_THROAT_CHOP 64 +#define MOVE_EFFECT_INCINERATE 65 +#define MOVE_EFFECT_BUG_BITE 66 +#define MOVE_EFFECT_RECOIL_HP_25 67 +#define MOVE_EFFECT_TRAP_BOTH 68 +#define MOVE_EFFECT_ROUND 69 +#define MOVE_EFFECT_STOCKPILE_WORE_OFF 70 +#define MOVE_EFFECT_DIRE_CLAW 71 +#define MOVE_EFFECT_STEALTH_ROCK 72 +#define MOVE_EFFECT_SPIKES 73 +#define MOVE_EFFECT_SYRUP_BOMB 74 +#define MOVE_EFFECT_FLORAL_HEALING 75 +#define MOVE_EFFECT_SECRET_POWER 76 +#define MOVE_EFFECT_PSYCHIC_NOISE 77 +#define MOVE_EFFECT_TERA_BLAST 78 +#define MOVE_EFFECT_ORDER_UP 79 +#define MOVE_EFFECT_ION_DELUGE 80 +#define MOVE_EFFECT_AROMATHERAPY 81 // No functionality yet +#define MOVE_EFFECT_HAZE 82 +#define MOVE_EFFECT_LEECH_SEED 83 +#define MOVE_EFFECT_REFLECT 84 +#define MOVE_EFFECT_LIGHT_SCREEN 85 +#define MOVE_EFFECT_SALT_CURE 86 +#define MOVE_EFFECT_EERIE_SPELL 87 -#define NUM_MOVE_EFFECTS 89 +#define NUM_MOVE_EFFECTS 88 #define MOVE_EFFECT_AFFECTS_USER 0x2000 #define MOVE_EFFECT_CERTAIN 0x4000 diff --git a/include/constants/battle_move_effects.h b/include/constants/battle_move_effects.h index df752bf496..4d2ccef9ac 100644 --- a/include/constants/battle_move_effects.h +++ b/include/constants/battle_move_effects.h @@ -351,6 +351,7 @@ enum { EFFECT_GUARDIAN_OF_ALOLA, EFFECT_SHELL_SIDE_ARM, EFFECT_ORDER_UP, + EFFECT_RAPID_SPIN, NUM_BATTLE_MOVE_EFFECTS, }; diff --git a/include/constants/battle_script_commands.h b/include/constants/battle_script_commands.h index 808ee406d2..bcf11683a1 100644 --- a/include/constants/battle_script_commands.h +++ b/include/constants/battle_script_commands.h @@ -284,6 +284,7 @@ enum MoveEndEffects MOVEEND_MULTIHIT_MOVE, MOVEEND_DEFROST, MOVEEND_RECOIL, + MOVEEND_RAPID_SPIN, MOVEEND_ITEM_EFFECTS_ATTACKER, MOVEEND_MAGICIAN, // Occurs after final multi-hit strike, and after other items/abilities would activate MOVEEND_RED_CARD, // Red Card triggers before Eject Pack diff --git a/src/battle_ai_main.c b/src/battle_ai_main.c index 480bf39342..66774d1afe 100644 --- a/src/battle_ai_main.c +++ b/src/battle_ai_main.c @@ -3091,7 +3091,7 @@ static s32 AI_DoubleBattle(u32 battlerAtk, u32 battlerDef, u32 move, s32 score) case EFFECT_ENTRAINMENT: if (partnerHasBadAbility && IsAbilityOfRating(aiData->abilities[battlerAtk], 0)) { - RETURN_SCORE_PLUS(WEAK_EFFECT); + RETURN_SCORE_PLUS(DECENT_EFFECT); } break; case EFFECT_SOAK: @@ -3642,7 +3642,7 @@ static u32 AI_CalcMoveEffectScore(u32 battlerAtk, u32 battlerDef, u32 move) case EFFECT_LEECH_SEED: if (IS_BATTLER_OF_TYPE(battlerDef, TYPE_GRASS) || gStatuses3[battlerDef] & STATUS3_LEECHSEED - || HasMoveWithAdditionalEffect(battlerDef, MOVE_EFFECT_RAPID_SPIN) + || HasMoveEffect(battlerDef, EFFECT_RAPID_SPIN) || aiData->abilities[battlerDef] == ABILITY_LIQUID_OOZE || aiData->abilities[battlerDef] == ABILITY_MAGIC_GUARD) break; @@ -4198,9 +4198,13 @@ static u32 AI_CalcMoveEffectScore(u32 battlerAtk, u32 battlerDef, u32 move) case EFFECT_ENTRAINMENT: if (GetActiveGimmick(battlerDef) == GIMMICK_DYNAMAX) break; - else if ((IsAbilityOfRating(aiData->abilities[battlerDef], 5) || gAbilitiesInfo[aiData->abilities[battlerAtk]].aiRating <= 0) - && (aiData->abilities[battlerDef] != aiData->abilities[battlerAtk] && !(gStatuses3[battlerDef] & STATUS3_GASTRO_ACID))) - ADJUST_SCORE(DECENT_EFFECT); + if (aiData->abilities[battlerDef] != aiData->abilities[battlerAtk] && !(gStatuses3[battlerDef] & STATUS3_GASTRO_ACID)) + { + if (gAbilitiesInfo[aiData->abilities[battlerAtk]].aiRating <= 0) + ADJUST_SCORE(DECENT_EFFECT); + else if (IsAbilityOfRating(aiData->abilities[battlerDef], 5) && gAbilitiesInfo[aiData->abilities[battlerAtk]].aiRating <= 3) + ADJUST_SCORE(WEAK_EFFECT); + } break; case EFFECT_IMPRISON: if (predictedMove != MOVE_NONE && HasMove(battlerAtk, predictedMove)) @@ -4557,6 +4561,12 @@ static u32 AI_CalcMoveEffectScore(u32 battlerAtk, u32 battlerDef, u32 move) || gBattleMons[BATTLE_PARTNER(battlerAtk)].status1 & STATUS1_ANY) ADJUST_SCORE(GOOD_EFFECT); break; + case EFFECT_RAPID_SPIN: + if ((gSideStatuses[GetBattlerSide(battlerAtk)] & SIDE_STATUS_HAZARDS_ANY && CountUsablePartyMons(battlerAtk) != 0) + || (gStatuses3[battlerAtk] & STATUS3_LEECHSEED || gBattleMons[battlerAtk].status2 & STATUS2_WRAPPED)) + ADJUST_SCORE(GOOD_EFFECT); + break; + } // move effect checks u32 additionalEffectCount = GetMoveAdditionalEffectCount(move); @@ -4601,11 +4611,6 @@ static u32 AI_CalcMoveEffectScore(u32 battlerAtk, u32 battlerDef, u32 move) case MOVE_EFFECT_EVS_PLUS_2: ADJUST_SCORE(IncreaseStatUpScore(battlerAtk, battlerDef, STAT_CHANGE_EVASION)); break; - case MOVE_EFFECT_RAPID_SPIN: - if ((gSideStatuses[GetBattlerSide(battlerAtk)] & SIDE_STATUS_HAZARDS_ANY && CountUsablePartyMons(battlerAtk) != 0) - || (gStatuses3[battlerAtk] & STATUS3_LEECHSEED || gBattleMons[battlerAtk].status2 & STATUS2_WRAPPED)) - ADJUST_SCORE(GOOD_EFFECT); - break; } } else @@ -4800,7 +4805,7 @@ static u32 AI_CalcMoveEffectScore(u32 battlerAtk, u32 battlerDef, u32 move) } break; case MOVE_EFFECT_WRAP: - if (!HasMoveWithAdditionalEffect(battlerDef, MOVE_EFFECT_RAPID_SPIN) && ShouldTrap(battlerAtk, battlerDef, move)) + if (!HasMoveEffect(battlerDef, EFFECT_RAPID_SPIN) && ShouldTrap(battlerAtk, battlerDef, move)) ADJUST_SCORE(BEST_EFFECT); break; case MOVE_EFFECT_SALT_CURE: @@ -5470,6 +5475,10 @@ static s32 AI_PredictSwitch(u32 battlerAtk, u32 battlerDef, u32 move, s32 score) if (opposingHazardFlags != 0) ADJUST_SCORE(GOOD_EFFECT); break; + case EFFECT_RAPID_SPIN: + if (aiHazardFlags != 0) + ADJUST_SCORE(BEST_EFFECT); + break; case EFFECT_DEFOG: if (aiHazardFlags != 0) ADJUST_SCORE(GOOD_EFFECT); @@ -5525,10 +5534,6 @@ static s32 AI_PredictSwitch(u32 battlerAtk, u32 battlerDef, u32 move, s32 score) case MOVE_EFFECT_WRAP: ADJUST_SCORE(-GOOD_EFFECT); break; - case MOVE_EFFECT_RAPID_SPIN: - if (aiHazardFlags != 0) - ADJUST_SCORE(BEST_EFFECT); - break; case MOVE_EFFECT_FEINT: ADJUST_SCORE(-BEST_EFFECT); break; diff --git a/src/battle_ai_switch_items.c b/src/battle_ai_switch_items.c index fef38ecf90..7087a7dc20 100644 --- a/src/battle_ai_switch_items.c +++ b/src/battle_ai_switch_items.c @@ -825,7 +825,7 @@ static bool32 CanMonSurviveHazardSwitchin(u32 battler) { aiMove = GetMonData(&party[i], MON_DATA_MOVE1 + j, NULL); u32 aiEffect = GetMoveEffect(aiMove); - if (MoveHasAdditionalEffectSelf(aiMove, MOVE_EFFECT_RAPID_SPIN) + if (aiEffect == EFFECT_RAPID_SPIN || (B_DEFOG_EFFECT_CLEARING >= GEN_6 && aiEffect == EFFECT_DEFOG) || aiEffect == EFFECT_TIDY_UP) { diff --git a/src/battle_ai_util.c b/src/battle_ai_util.c index 9732176997..d3a427890c 100644 --- a/src/battle_ai_util.c +++ b/src/battle_ai_util.c @@ -4123,7 +4123,7 @@ bool32 AI_ShouldSetUpHazards(u32 battlerAtk, u32 battlerDef, struct AiLogicData { if (aiData->abilities[battlerDef] == ABILITY_MAGIC_BOUNCE || CountUsablePartyMons(battlerDef) == 0 - || HasMoveWithAdditionalEffect(battlerDef, MOVE_EFFECT_RAPID_SPIN) + || HasMoveEffect(battlerDef, EFFECT_RAPID_SPIN) || HasMoveEffect(battlerDef, EFFECT_DEFOG)) return FALSE; diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index ec98f9fcd6..bb4a63d227 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -3795,10 +3795,6 @@ void SetMoveEffect(bool32 primary, bool32 certain) gBattlescriptCurrInstr = BattleScript_AllStatsUp; } break; - case MOVE_EFFECT_RAPID_SPIN: - BattleScriptPush(gBattlescriptCurrInstr + 1); - gBattlescriptCurrInstr = BattleScript_RapidSpinAway; - break; case MOVE_EFFECT_ATK_DEF_DOWN: // SuperPower if (!NoAliveMonsForEitherParty()) { @@ -6138,6 +6134,17 @@ static void Cmd_moveend(void) gBattleScripting.moveendState++; break; } + case MOVEEND_RAPID_SPIN: + if (gMovesInfo[gCurrentMove].effect == EFFECT_RAPID_SPIN + && !(gHitMarker & HITMARKER_UNABLE_TO_USE_MOVE) + && IsBattlerTurnDamaged(gBattlerTarget)) + { + BattleScriptPushCursor(); + gBattlescriptCurrInstr = BattleScript_RapidSpinAway; + effect = TRUE; + } + gBattleScripting.moveendState++; + break; case MOVEEND_ITEM_EFFECTS_ATTACKER: if (ItemBattleEffects(ITEMEFFECT_MOVE_END, gBattlerAttacker, FALSE)) effect = TRUE; @@ -14416,7 +14423,6 @@ static void Cmd_setcharge(void) gDisableStructs[battler].chargeTimer = 2; else gDisableStructs[battler].chargeTimer = 0; - gBattlescriptCurrInstr++; gBattlescriptCurrInstr = cmd->nextInstr; } diff --git a/src/battle_tv.c b/src/battle_tv.c index e5be946d81..2dd171a35a 100644 --- a/src/battle_tv.c +++ b/src/battle_tv.c @@ -934,7 +934,7 @@ static void AddMovePoints(u8 caseId, u16 arg1, u8 arg2, u8 arg3) // Various cases to add/remove points if (GetMoveRecoil(arg2) > 0) baseFromEffect++; // Recoil moves - if (MoveHasAdditionalEffect(arg2, MOVE_EFFECT_RAPID_SPIN)) + if (gMovesInfo[arg2].effect == EFFECT_RAPID_SPIN) baseFromEffect++; if (MoveHasAdditionalEffect(arg2, MOVE_EFFECT_SP_ATK_MINUS_2) || MoveHasAdditionalEffect(arg2, MOVE_EFFECT_ATK_DEF_DOWN)) baseFromEffect += 2; // Overheat, Superpower, etc. diff --git a/src/data/battle_move_effects.h b/src/data/battle_move_effects.h index b9fcdd59f6..c3077632f9 100644 --- a/src/data/battle_move_effects.h +++ b/src/data/battle_move_effects.h @@ -2240,4 +2240,10 @@ const struct BattleMoveEffect gBattleMoveEffects[NUM_BATTLE_MOVE_EFFECTS] = .battleScript = BattleScript_EffectHit, .battleTvScore = 0, // TODO: Assign points }, + + [EFFECT_RAPID_SPIN] = + { + .battleScript = BattleScript_EffectHit, + .battleTvScore = 0, // TODO: Assign points + }, }; diff --git a/src/data/graphics/pokemon.h b/src/data/graphics/pokemon.h index 141e2f16f8..00d878ba0c 100644 --- a/src/data/graphics/pokemon.h +++ b/src/data/graphics/pokemon.h @@ -7696,7 +7696,7 @@ const u32 gObjectEventPic_Substitute[] = INCBIN_COMP("graphics/pokemon/question_ #endif //OW_PKMN_OBJECTS_SHARE_PALETTES #endif //OW_POKEMON_OBJECT_EVENTS - const u32 gMonFrontPic_Clodsire[] = INCBIN_U32("graphics/pokemon/clodsire/front.4bpp.lz"); + const u32 gMonFrontPic_Clodsire[] = INCBIN_U32("graphics/pokemon/clodsire/anim_front.4bpp.lz"); const u32 gMonPalette_Clodsire[] = INCBIN_U32("graphics/pokemon/clodsire/normal.gbapal.lz"); const u32 gMonBackPic_Clodsire[] = INCBIN_U32("graphics/pokemon/clodsire/back.4bpp.lz"); const u32 gMonShinyPalette_Clodsire[] = INCBIN_U32("graphics/pokemon/clodsire/shiny.gbapal.lz"); diff --git a/src/data/moves_info.h b/src/data/moves_info.h index ec9e209dda..6f8d658560 100644 --- a/src/data/moves_info.h +++ b/src/data/moves_info.h @@ -5806,7 +5806,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .description = COMPOUND_STRING( "Spins the body at high\n" "speed to strike the foe."), - .effect = EFFECT_HIT, + .effect = EFFECT_RAPID_SPIN, .power = B_UPDATED_MOVE_DATA >= GEN_8 ? 50 : 20, .type = TYPE_NORMAL, .accuracy = 100, @@ -5815,12 +5815,9 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .priority = 0, .category = DAMAGE_CATEGORY_PHYSICAL, .makesContact = TRUE, - .additionalEffects = ADDITIONAL_EFFECTS({ - .moveEffect = MOVE_EFFECT_RAPID_SPIN, - .self = TRUE, - } + .additionalEffects = ADDITIONAL_EFFECTS( #if B_SPEED_BUFFING_RAPID_SPIN >= GEN_8 - ,{ + { .moveEffect = MOVE_EFFECT_SPD_PLUS_1, .self = TRUE, .chance = 100, @@ -19571,7 +19568,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .description = COMPOUND_STRING( "Erases trap moves and Leech\n" "Seed. Poisons adjacent foes."), - .effect = EFFECT_HIT, + .effect = EFFECT_RAPID_SPIN, .power = 30, .type = TYPE_POISON, .accuracy = 100, @@ -19580,10 +19577,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .priority = 0, .category = DAMAGE_CATEGORY_PHYSICAL, .makesContact = TRUE, - .additionalEffects = ADDITIONAL_EFFECTS({ - .moveEffect = MOVE_EFFECT_RAPID_SPIN, - .self = TRUE, - }, + .additionalEffects = ADDITIONAL_EFFECTS( { .moveEffect = MOVE_EFFECT_POISON, .chance = 100, diff --git a/src/data/pokemon/species_info/gen_2_families.h b/src/data/pokemon/species_info/gen_2_families.h index d7db791052..4e8804dacf 100644 --- a/src/data/pokemon/species_info/gen_2_families.h +++ b/src/data/pokemon/species_info/gen_2_families.h @@ -3500,7 +3500,7 @@ const struct SpeciesInfo gSpeciesInfoGen2[] = .frontPic = gMonFrontPic_Clodsire, .frontPicSize = MON_COORDS_SIZE(64, 64), .frontPicYOffset = 8, - .frontAnimFrames = sAnims_SingleFramePlaceHolder, + .frontAnimFrames = sAnims_TwoFramePlaceHolder, //.frontAnimId = ANIM_V_SQUISH_AND_BOUNCE, .backPic = gMonBackPic_Clodsire, .backPicSize = MON_COORDS_SIZE(64, 64), diff --git a/test/battle/ability/shield_dust.c b/test/battle/ability/shield_dust.c index bb56f84211..c5a9fbec66 100644 --- a/test/battle/ability/shield_dust.c +++ b/test/battle/ability/shield_dust.c @@ -93,8 +93,8 @@ SINGLE_BATTLE_TEST("Shield Dust does not block self-targeting effects, primary o PARAMETRIZE { move = MOVE_METEOR_ASSAULT; } GIVEN { + ASSUME(gMovesInfo[MOVE_RAPID_SPIN].effect == EFFECT_RAPID_SPIN); ASSUME(MoveHasAdditionalEffectSelf(MOVE_POWER_UP_PUNCH, MOVE_EFFECT_ATK_PLUS_1) == TRUE); - ASSUME(MoveHasAdditionalEffectSelf(MOVE_RAPID_SPIN, MOVE_EFFECT_RAPID_SPIN) == TRUE); ASSUME(MoveHasAdditionalEffectSelf(MOVE_LEAF_STORM, MOVE_EFFECT_SP_ATK_MINUS_2) == TRUE); ASSUME(MoveHasAdditionalEffectSelf(MOVE_METEOR_ASSAULT, MOVE_EFFECT_RECHARGE) == TRUE); PLAYER(SPECIES_WOBBUFFET); diff --git a/test/battle/ai/ai_powerful_status.c b/test/battle/ai/ai_powerful_status.c index 99aff19384..414ba7329a 100644 --- a/test/battle/ai/ai_powerful_status.c +++ b/test/battle/ai/ai_powerful_status.c @@ -22,7 +22,7 @@ AI_SINGLE_BATTLE_TEST("AI prefers to set up a powerful Status over fainting a ta AI_SINGLE_BATTLE_TEST("AI will try to do damage on target instead of setting up hazards if target has a way to remove them") { GIVEN { - ASSUME(MoveHasAdditionalEffectSelf(MOVE_RAPID_SPIN, MOVE_EFFECT_RAPID_SPIN) == TRUE); + ASSUME(GetMoveEffect(MOVE_RAPID_SPIN) == EFFECT_RAPID_SPIN); ASSUME(GetMoveEffect(MOVE_STEALTH_ROCK) == EFFECT_STEALTH_ROCK); ASSUME(GetMovePower(MOVE_TACKLE) > 0); AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_POWERFUL_STATUS | AI_FLAG_OMNISCIENT); diff --git a/test/battle/hold_effect/covert_cloak.c b/test/battle/hold_effect/covert_cloak.c index 183033cb71..0920fc0ab9 100644 --- a/test/battle/hold_effect/covert_cloak.c +++ b/test/battle/hold_effect/covert_cloak.c @@ -97,8 +97,8 @@ SINGLE_BATTLE_TEST("Covert Cloak does not block self-targeting effects, primary PARAMETRIZE { move = MOVE_METEOR_ASSAULT; } GIVEN { + ASSUME(gMovesInfo[MOVE_RAPID_SPIN].effect == EFFECT_RAPID_SPIN); ASSUME(MoveHasAdditionalEffectSelf(MOVE_POWER_UP_PUNCH, MOVE_EFFECT_ATK_PLUS_1) == TRUE); - ASSUME(MoveHasAdditionalEffectSelf(MOVE_RAPID_SPIN, MOVE_EFFECT_RAPID_SPIN) == TRUE); ASSUME(MoveHasAdditionalEffectSelf(MOVE_LEAF_STORM, MOVE_EFFECT_SP_ATK_MINUS_2) == TRUE); ASSUME(MoveHasAdditionalEffectSelf(MOVE_METEOR_ASSAULT, MOVE_EFFECT_RECHARGE) == TRUE); PLAYER(SPECIES_WOBBUFFET); diff --git a/test/battle/move_effect/entrainment.c b/test/battle/move_effect/entrainment.c index b43f6dcbc1..cccae86759 100644 --- a/test/battle/move_effect/entrainment.c +++ b/test/battle/move_effect/entrainment.c @@ -1,6 +1,19 @@ #include "global.h" #include "test/battle.h" +AI_DOUBLE_BATTLE_TEST("AI prefers Entrainment'ing good abilities onto partner with bad ability") +{ + GIVEN { + AI_FLAGS(AI_FLAG_SMART_TRAINER); + PLAYER(SPECIES_QUAXWELL) { Level(18); Ability(ABILITY_TORRENT); Moves(MOVE_WATER_GUN); }; + PLAYER(SPECIES_CORPHISH) { Level(18); Moves(MOVE_WATER_GUN); }; + OPPONENT(SPECIES_SMEARGLE) { Level(17); Ability(ABILITY_TECHNICIAN); Moves(MOVE_AERIAL_ACE, MOVE_ENTRAINMENT, MOVE_FLAME_WHEEL, MOVE_MAGICAL_LEAF); } + OPPONENT(SPECIES_ARCHEN) { Level(17); Ability(ABILITY_DEFEATIST); Moves(MOVE_DUAL_WINGBEAT, MOVE_ROCK_TOMB); } + } WHEN { + TURN { EXPECT_MOVE(opponentLeft, MOVE_ENTRAINMENT); EXPECT_MOVE(opponentRight, MOVE_DUAL_WINGBEAT); MOVE(playerLeft, MOVE_WATER_GUN); MOVE(playerRight, MOVE_WATER_GUN); } + } +} + TO_DO_BATTLE_TEST("Entrainment changes the target's Ability to match the user's"); TO_DO_BATTLE_TEST("Entrainment fails if the user's ability has cantBeCopied flag"); TO_DO_BATTLE_TEST("Entrainment fails if the targets's ability has cantBeOverwritten flag"); diff --git a/test/battle/move_effect_secondary/rapid_spin.c b/test/battle/move_effect/rapid_spin.c similarity index 65% rename from test/battle/move_effect_secondary/rapid_spin.c rename to test/battle/move_effect/rapid_spin.c index 4e490164d7..e5457395b9 100644 --- a/test/battle/move_effect_secondary/rapid_spin.c +++ b/test/battle/move_effect/rapid_spin.c @@ -3,15 +3,30 @@ ASSUMPTIONS { - ASSUME(MoveHasAdditionalEffectSelf(MOVE_RAPID_SPIN, MOVE_EFFECT_RAPID_SPIN) == TRUE); + ASSUME(gMovesInfo[MOVE_RAPID_SPIN].effect == EFFECT_RAPID_SPIN); + ASSUME(gMovesInfo[MOVE_MORTAL_SPIN].effect == EFFECT_RAPID_SPIN); #if B_SPEED_BUFFING_RAPID_SPIN >= GEN_8 ASSUME(MoveHasAdditionalEffectSelf(MOVE_RAPID_SPIN, MOVE_EFFECT_SPD_PLUS_1) == TRUE); #endif - ASSUME(MoveHasAdditionalEffectSelf(MOVE_MORTAL_SPIN, MOVE_EFFECT_RAPID_SPIN) == TRUE); ASSUME(MoveHasAdditionalEffect(MOVE_MORTAL_SPIN, MOVE_EFFECT_POISON) == TRUE); } -SINGLE_BATTLE_TEST("Rapin Spin blows away Wrap, hazards and raises Speed (Gen 8+)") +SINGLE_BATTLE_TEST("Rapid Spin activates after Toxic Debris") +{ + GIVEN { + PLAYER(SPECIES_GLIMMORA) { Ability(ABILITY_TOXIC_DEBRIS); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(opponent, MOVE_RAPID_SPIN); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_RAPID_SPIN, opponent); + ABILITY_POPUP(player, ABILITY_TOXIC_DEBRIS); + MESSAGE("Poison spikes were scattered on the ground all around the opposing team!"); + MESSAGE("The opposing Wobbuffet blew away Toxic Spikes!"); + } +} + +SINGLE_BATTLE_TEST("Rapid Spin blows away Wrap, hazards and raises Speed (Gen 8+)") { GIVEN { PLAYER(SPECIES_WOBBUFFET); @@ -22,16 +37,16 @@ SINGLE_BATTLE_TEST("Rapin Spin blows away Wrap, hazards and raises Speed (Gen 8+ } SCENE { ANIMATION(ANIM_TYPE_MOVE, MOVE_STEALTH_ROCK, opponent); ANIMATION(ANIM_TYPE_MOVE, MOVE_RAPID_SPIN, player); - MESSAGE("Wobbuffet got free of the opposing Wobbuffet's Wrap!"); - MESSAGE("Wobbuffet blew away Stealth Rock!"); #if B_SPEED_BUFFING_RAPID_SPIN >= GEN_8 ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); MESSAGE("Wobbuffet's Speed rose!"); #endif + MESSAGE("Wobbuffet got free of the opposing Wobbuffet's Wrap!"); + MESSAGE("Wobbuffet blew away Stealth Rock!"); } } -SINGLE_BATTLE_TEST("Mortal Spin blows away Wrap, hazards and poisons foe") +SINGLE_BATTLE_TEST("Rapid Spin: Mortal Spin blows away Wrap, hazards and poisons foe") { GIVEN { PLAYER(SPECIES_WOBBUFFET); @@ -42,10 +57,9 @@ SINGLE_BATTLE_TEST("Mortal Spin blows away Wrap, hazards and poisons foe") } SCENE { ANIMATION(ANIM_TYPE_MOVE, MOVE_STEALTH_ROCK, opponent); ANIMATION(ANIM_TYPE_MOVE, MOVE_MORTAL_SPIN, player); - MESSAGE("Wobbuffet got free of the opposing Wobbuffet's Wrap!"); - MESSAGE("Wobbuffet blew away Stealth Rock!"); MESSAGE("The opposing Wobbuffet was poisoned!"); STATUS_ICON(opponent, poison: TRUE); + MESSAGE("Wobbuffet got free of the opposing Wobbuffet's Wrap!"); + MESSAGE("Wobbuffet blew away Stealth Rock!"); } } - diff --git a/test/battle/trainer_control.h b/test/battle/trainer_control.h index 9bb878f76f..5b8aa02291 100644 --- a/test/battle/trainer_control.h +++ b/test/battle/trainer_control.h @@ -17,7 +17,7 @@ .trainerClass = TRAINER_CLASS_PKMN_TRAINER_1, #line 4 .trainerPic = TRAINER_PIC_RED, - .encounterMusic_gender = + .encounterMusic_gender = #line 6 TRAINER_ENCOUNTER_MUSIC_MALE, #line 7