Merge branch '_RHH/master' into _RHH/upcoming

# Conflicts:
#	data/battle_scripts_1.s
#	include/constants/battle_move_effects.h
#	src/battle_ai_util.c
#	src/battle_script_commands.c
#	src/battle_tv.c
#	src/data/battle_moves.h
#	src/data/pokemon/species_info/gen_9.h
This commit is contained in:
Eduardo Quezada 2024-01-22 15:56:10 -03:00
commit 00e2ca6030
20 changed files with 310 additions and 184 deletions

View File

@ -524,7 +524,7 @@ BattleScript_EffectShellTrap::
waitmessage B_WAIT_TIME_LONG
goto BattleScript_MoveEnd
BattleScript_EffectSteelBeam::
BattleScript_EffectMaxHp50Recoil::
attackcanceler
attackstring
ppreduce
@ -3046,6 +3046,7 @@ BattleScript_MindBlownDamp:
goto BattleScript_DampStopsExplosion
BattleScript_EffectMindBlown_HpDown:
setbyte sMULTIHIT_EFFECT, 1 @ Note to not faint the attacker
jumpifability BS_ATTACKER, ABILITY_MAGIC_GUARD, BattleScript_EffectMindBlown_AnimDmgNoFaint
dmg_1_2_attackerhp
healthbarupdate BS_ATTACKER
datahpupdate BS_ATTACKER

View File

@ -1,18 +1,19 @@
JASC-PAL
0100
15
114 109 97
16
0 0 0
115 62 231
57 95 90
52 103 15
48 101 216
225 59 159
136 154 143
49 49 49
60 195 171
76 204 74
202 150 255
142 191 235
242 193 215
238 219 161
57 95 90
255 255 255
255 204 227
202 150 255
115 62 231
48 101 216
219 48 105
76 204 74
52 103 15
136 154 143
142 191 235
255 211 201
255 235 173

Binary file not shown.

Before

Width:  |  Height:  |  Size: 324 B

After

Width:  |  Height:  |  Size: 323 B

View File

@ -222,7 +222,7 @@ struct SpecialStatus
// End of byte
u8 emergencyExited:1;
u8 afterYou:1;
u8 magicianStolen:1; // So that Life Orb doesn't activate after Magician steals it.
u8 preventLifeOrbDamage:1; // So that Life Orb doesn't activate various effects.
};
struct SideTimer

View File

@ -802,7 +802,7 @@ extern const u8 BattleScript_EffectClangorousSoul[];
extern const u8 BattleScript_EffectSkyDrop[];
extern const u8 BattleScript_EffectMeteorBeam[];
extern const u8 BattleScript_EffectCourtChange[];
extern const u8 BattleScript_EffectSteelBeam[];
extern const u8 BattleScript_EffectMaxHp50Recoil[];
extern const u8 BattleScript_EffectExtremeEvoboost[];
extern const u8 BattleScript_EffectHitSetRemoveTerrain[];
extern const u8 BattleScript_EffectDarkVoid[];

View File

@ -322,7 +322,7 @@ enum {
EFFECT_RISING_VOLTAGE,
EFFECT_BEAK_BLAST,
EFFECT_COURT_CHANGE,
EFFECT_STEEL_BEAM,
EFFECT_MAX_HP_50_RECOIL,
EFFECT_EXTREME_EVOBOOST,
EFFECT_HIT_SET_REMOVE_TERRAIN,
EFFECT_DARK_VOID,

View File

@ -632,7 +632,7 @@ static bool32 AI_IsMoveEffectInMinus(u32 battlerAtk, u32 battlerDef, u32 move, s
switch (gBattleMoves[move].effect)
{
case EFFECT_MIND_BLOWN:
case EFFECT_STEEL_BEAM:
case EFFECT_MAX_HP_50_RECOIL:
return TRUE;
case EFFECT_RECOIL_IF_MISS:
if (AI_IsDamagedByRecoil(battlerAtk))
@ -2483,17 +2483,11 @@ bool32 AI_CanPutToSleep(u32 battlerAtk, u32 battlerDef, u32 defAbility, u32 move
return TRUE;
}
static bool32 AI_CanPoisonType(u32 battlerAttacker, u32 battlerTarget, u32 move)
{
return ((AI_DATA->abilities[battlerAttacker] == ABILITY_CORROSION && gBattleMoves[move].category == BATTLE_CATEGORY_STATUS)
|| !(IS_BATTLER_OF_TYPE(battlerTarget, TYPE_POISON) || IS_BATTLER_OF_TYPE(battlerTarget, TYPE_STEEL)));
}
static bool32 AI_CanBePoisoned(u32 battlerAtk, u32 battlerDef, u32 move)
{
u32 ability = AI_DATA->abilities[battlerDef];
if (!(AI_CanPoisonType(battlerAtk, battlerDef, move))
if (!(CanPoisonType(battlerAtk, battlerDef))
|| gSideStatuses[GetBattlerSide(battlerDef)] & SIDE_STATUS_SAFEGUARD
|| gBattleMons[battlerDef].status1 & STATUS1_ANY
|| ability == ABILITY_IMMUNITY

View File

@ -5853,7 +5853,7 @@ static void Cmd_moveend(void)
gEffectBattler = gBattlerTarget;
BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_MagicianActivates;
gSpecialStatuses[gBattlerAttacker].magicianStolen = TRUE;
gSpecialStatuses[gBattlerAttacker].preventLifeOrbDamage = TRUE;
effect = TRUE;
}
gBattleScripting.moveendState++;
@ -6040,6 +6040,7 @@ static void Cmd_moveend(void)
gBattlescriptCurrInstr = BattleScript_MoveEnd; // Prevent user switch-in selection
BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_RedCardActivates;
gSpecialStatuses[gBattlerAttacker].preventLifeOrbDamage = TRUE;
effect = TRUE;
break; // Only fastest red card activates
}
@ -6066,6 +6067,7 @@ static void Cmd_moveend(void)
gLastUsedItem = gBattleMons[battler].item;
BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_EjectPackActivates;
gSpecialStatuses[gBattlerAttacker].preventLifeOrbDamage = TRUE;
effect = TRUE;
break; // Only fastest eject pack activates
}
@ -6218,7 +6220,7 @@ static void Cmd_moveend(void)
gStatuses3[gBattlerAttacker] &= ~STATUS3_ME_FIRST;
gSpecialStatuses[gBattlerAttacker].gemBoost = FALSE;
gSpecialStatuses[gBattlerAttacker].damagedMons = 0;
gSpecialStatuses[gBattlerAttacker].magicianStolen = 0;
gSpecialStatuses[gBattlerAttacker].preventLifeOrbDamage = 0;
gSpecialStatuses[gBattlerTarget].berryReduced = FALSE;
gBattleScripting.moveEffect = 0;
// clear attacker z move data
@ -8288,8 +8290,8 @@ static bool32 HasAttackerFaintedTarget(void)
bool32 CanPoisonType(u8 battlerAttacker, u8 battlerTarget)
{
return ((GetBattlerAbility(battlerAttacker) == ABILITY_CORROSION && gBattleMoves[gCurrentMove].category == BATTLE_CATEGORY_STATUS)
|| !(IS_BATTLER_OF_TYPE(battlerTarget, TYPE_POISON) || IS_BATTLER_OF_TYPE(battlerTarget, TYPE_STEEL)));
return GetBattlerAbility(battlerAttacker) == ABILITY_CORROSION
|| (!IS_BATTLER_OF_TYPE(battlerTarget, TYPE_STEEL) && !IS_BATTLER_OF_TYPE(battlerTarget, TYPE_POISON));
}
bool32 CanParalyzeType(u8 battlerAttacker, u8 battlerTarget)

View File

@ -3978,11 +3978,14 @@ static uq4_12_t GetSupremeOverlordModifier(u32 battler)
return modifier;
}
static bool32 HadMoreThanHalfHpNowHasLess(u32 battler)
static inline bool32 HadMoreThanHalfHpNowHasLess(u32 battler)
{
u32 cutoff = gBattleMons[battler].maxHP / 2;
if (gBattleMons[battler].maxHP % 2 == 1)
cutoff++;
// Had more than half of hp before, now has less
return (gBattleStruct->hpBefore[battler] >= gBattleMons[battler].maxHP / 2
&& gBattleMons[battler].hp < gBattleMons[battler].maxHP / 2);
return (gBattleStruct->hpBefore[battler] >= cutoff
&& gBattleMons[battler].hp < cutoff);
}
u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32 moveArg)
@ -5081,8 +5084,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
&& TARGET_TURN_DAMAGED
&& IsBattlerAlive(battler)
// Had more than half of hp before, now has less
&& gBattleStruct->hpBefore[battler] > gBattleMons[battler].maxHP / 2
&& gBattleMons[battler].hp < gBattleMons[battler].maxHP / 2
&& HadMoreThanHalfHpNowHasLess(battler)
&& (gMultiHitCounter == 0 || gMultiHitCounter == 1)
&& !(TestSheerForceFlag(gBattlerAttacker, gCurrentMove))
&& (CanBattlerSwitch(battler) || !(gBattleTypeFlags & BATTLE_TYPE_TRAINER))
@ -6548,6 +6550,10 @@ static u8 ItemHealHp(u32 battler, u32 itemId, bool32 end2, bool32 percentHeal)
BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_ItemHealHP_RemoveItemRet;
}
if (gBattleResources->flags->flags[battler] & RESOURCE_FLAG_EMERGENCY_EXIT
&& GetNonDynamaxMaxHP(battler) > gBattleMons[battler].maxHP / 2)
gBattleResources->flags->flags[battler] &= ~RESOURCE_FLAG_EMERGENCY_EXIT;
return ITEM_HP_CHANGE;
}
return 0;
@ -7532,7 +7538,7 @@ u8 ItemBattleEffects(u8 caseID, u32 battler, bool32 moveTurn)
if (IsBattlerAlive(gBattlerAttacker)
&& !(TestSheerForceFlag(gBattlerAttacker, gCurrentMove))
&& GetBattlerAbility(gBattlerAttacker) != ABILITY_MAGIC_GUARD
&& !gSpecialStatuses[gBattlerAttacker].magicianStolen
&& !gSpecialStatuses[gBattlerAttacker].preventLifeOrbDamage
&& gSpecialStatuses[gBattlerAttacker].damagedMons)
{
gBattleMoveDamage = GetNonDynamaxMaxHP(gBattlerAttacker) / 10;

View File

@ -2048,9 +2048,9 @@ const struct BattleMoveEffect gBattleMoveEffects[NUM_BATTLE_MOVE_EFFECTS] =
.battleTvScore = 0, // TODO: Assign points
},
[EFFECT_STEEL_BEAM] =
[EFFECT_MAX_HP_50_RECOIL] =
{
.battleScript = BattleScript_EffectSteelBeam,
.battleScript = BattleScript_EffectMaxHp50Recoil,
.battleTvScore = 0, // TODO: Assign points
},

View File

@ -11591,7 +11591,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] =
[MOVE_STEEL_BEAM] =
{
.effect = EFFECT_STEEL_BEAM,
.effect = EFFECT_MAX_HP_50_RECOIL,
.power = 140,
.type = TYPE_STEEL,
.accuracy = 95,
@ -12194,7 +12194,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] =
[MOVE_CHLOROBLAST] =
{
.effect = EFFECT_STEEL_BEAM,
.effect = EFFECT_MAX_HP_50_RECOIL,
.power = B_UPDATED_MOVE_DATA >= GEN_9 ? 150 : 120,
.type = TYPE_GRASS,
.accuracy = 95,

View File

@ -3479,7 +3479,7 @@ static const struct LevelUpMove sSeadraLevelUpLearnset[] = {
LEVEL_UP_END
};
#if P_GEN_4_CROSS_EVOS
#if P_GEN_2_CROSS_EVOS
static const struct LevelUpMove sKingdraLevelUpLearnset[] = {
LEVEL_UP_MOVE( 1, MOVE_HYDRO_PUMP),
LEVEL_UP_MOVE( 1, MOVE_YAWN),
@ -3500,7 +3500,7 @@ static const struct LevelUpMove sKingdraLevelUpLearnset[] = {
LEVEL_UP_MOVE(60, MOVE_HYDRO_PUMP),
LEVEL_UP_END
};
#endif //P_GEN_4_CROSS_EVOS
#endif //P_GEN_2_CROSS_EVOS
#endif //P_FAMILY_HORSEA
#if P_FAMILY_GOLDEEN

View File

@ -507,6 +507,7 @@ const struct SpeciesInfo gSpeciesInfoGen9[] =
.pokemonOffset = 17, \
.trainerScale = 256, \
.trainerOffset = 0, \
.teachableLearnset = sOinkologneTeachableLearnset, \
.formSpeciesIdTable = sOinkologneFormSpeciesIdTable
[SPECIES_OINKOLOGNE_MALE] =
@ -535,8 +536,7 @@ const struct SpeciesInfo gSpeciesInfoGen9[] =
PALETTES(OinkologneMale),
ICON(OinkologneMale, 1),
//FOOTPRINT(Oinkologne)
LEARNSETS(OinkologneMale),
.levelUpLearnset = sOinkologneMaleLevelUpLearnset,
},
[SPECIES_OINKOLOGNE_FEMALE] =
@ -566,7 +566,7 @@ const struct SpeciesInfo gSpeciesInfoGen9[] =
PALETTES(OinkologneFemale),
ICON(OinkologneFemale, 2),
//FOOTPRINT(Oinkologne)
LEARNSETS(OinkologneFemale),
.levelUpLearnset = sOinkologneFemaleLevelUpLearnset,
},
#endif //P_FAMILY_LECHONK

View File

@ -663,7 +663,6 @@ static const u16 sRattataTeachableLearnset[] = {
static const u16 sRaticateTeachableLearnset[] = {
MOVE_ATTRACT,
MOVE_BLIZZARD,
MOVE_BULK_UP,
MOVE_CUT,
MOVE_DIG,
MOVE_DOUBLE_TEAM,
@ -689,7 +688,6 @@ static const u16 sRaticateTeachableLearnset[] = {
MOVE_THIEF,
MOVE_THUNDER,
MOVE_THUNDERBOLT,
MOVE_TORMENT,
MOVE_TOXIC,
MOVE_BODY_SLAM,
MOVE_COUNTER,
@ -712,7 +710,6 @@ static const u16 sRaticateTeachableLearnset[] = {
#if P_ALOLAN_FORMS
static const u16 sRattataAlolanTeachableLearnset[] = {
MOVE_BLIZZARD,
MOVE_CUT,
MOVE_DIG,
MOVE_FACADE,
MOVE_ICE_BEAM,
@ -729,7 +726,6 @@ static const u16 sRattataAlolanTeachableLearnset[] = {
static const u16 sRaticateAlolanTeachableLearnset[] = {
MOVE_BLIZZARD,
MOVE_BULK_UP,
MOVE_CUT,
MOVE_DIG,
MOVE_FACADE,
MOVE_HYPER_BEAM,
@ -930,7 +926,6 @@ static const u16 sPikachuTeachableLearnset[] = {
MOVE_DOUBLE_TEAM,
MOVE_FACADE,
MOVE_FLASH,
MOVE_FLY,
MOVE_FOCUS_PUNCH,
MOVE_FRUSTRATION,
MOVE_HIDDEN_POWER,
@ -1025,7 +1020,6 @@ static const u16 sRaichuAlolanTeachableLearnset[] = {
MOVE_CALM_MIND,
MOVE_DIG,
MOVE_FACADE,
MOVE_FLASH,
MOVE_HYPER_BEAM,
MOVE_IRON_TAIL,
MOVE_LIGHT_SCREEN,
@ -1034,7 +1028,6 @@ static const u16 sRaichuAlolanTeachableLearnset[] = {
MOVE_REFLECT,
MOVE_REST,
MOVE_ROCK_SMASH,
MOVE_STRENGTH,
MOVE_THUNDERBOLT,
MOVE_THUNDER,
MOVE_TOXIC,
@ -1141,7 +1134,6 @@ static const u16 sSandslashTeachableLearnset[] = {
static const u16 sSandshrewAlolanTeachableLearnset[] = {
MOVE_BLIZZARD,
MOVE_BRICK_BREAK,
MOVE_CUT,
MOVE_DIG,
MOVE_EARTHQUAKE,
MOVE_FACADE,
@ -1149,8 +1141,6 @@ static const u16 sSandshrewAlolanTeachableLearnset[] = {
MOVE_IRON_TAIL,
MOVE_PROTECT,
MOVE_REST,
MOVE_ROCK_SMASH,
MOVE_STRENGTH,
MOVE_TOXIC,
MOVE_UNAVAILABLE,
};
@ -1158,7 +1148,6 @@ static const u16 sSandshrewAlolanTeachableLearnset[] = {
static const u16 sSandslashAlolanTeachableLearnset[] = {
MOVE_BLIZZARD,
MOVE_BRICK_BREAK,
MOVE_CUT,
MOVE_DIG,
MOVE_EARTHQUAKE,
MOVE_FACADE,
@ -1167,8 +1156,6 @@ static const u16 sSandslashAlolanTeachableLearnset[] = {
MOVE_IRON_TAIL,
MOVE_PROTECT,
MOVE_REST,
MOVE_ROCK_SMASH,
MOVE_STRENGTH,
MOVE_TOXIC,
MOVE_UNAVAILABLE,
};
@ -2382,27 +2369,23 @@ static const u16 sDugtrioTeachableLearnset[] = {
#if P_ALOLAN_FORMS
static const u16 sDiglettAlolanTeachableLearnset[] = {
MOVE_CUT,
MOVE_DIG,
MOVE_EARTHQUAKE,
MOVE_FACADE,
MOVE_PROTECT,
MOVE_REST,
MOVE_ROCK_SMASH,
MOVE_SLUDGE_BOMB,
MOVE_TOXIC,
MOVE_UNAVAILABLE,
};
static const u16 sDugtrioAlolanTeachableLearnset[] = {
MOVE_CUT,
MOVE_DIG,
MOVE_EARTHQUAKE,
MOVE_FACADE,
MOVE_HYPER_BEAM,
MOVE_PROTECT,
MOVE_REST,
MOVE_ROCK_SMASH,
MOVE_SLUDGE_BOMB,
MOVE_TOXIC,
MOVE_UNAVAILABLE,
@ -2503,9 +2486,7 @@ static const u16 sPersianTeachableLearnset[] = {
#if P_ALOLAN_FORMS
static const u16 sMeowthAlolanTeachableLearnset[] = {
MOVE_CUT,
MOVE_FACADE,
MOVE_FLASH,
MOVE_IRON_TAIL,
MOVE_PROTECT,
MOVE_REST,
@ -2518,9 +2499,7 @@ static const u16 sMeowthAlolanTeachableLearnset[] = {
};
static const u16 sPersianAlolanTeachableLearnset[] = {
MOVE_CUT,
MOVE_FACADE,
MOVE_FLASH,
MOVE_HYPER_BEAM,
MOVE_IRON_TAIL,
MOVE_PROTECT,
@ -3763,7 +3742,6 @@ static const u16 sGeodudeAlolanTeachableLearnset[] = {
MOVE_PROTECT,
MOVE_REST,
MOVE_ROCK_SMASH,
MOVE_STRENGTH,
MOVE_THUNDERBOLT,
MOVE_THUNDER,
MOVE_TOXIC,
@ -3780,7 +3758,6 @@ static const u16 sGravelerAlolanTeachableLearnset[] = {
MOVE_PROTECT,
MOVE_REST,
MOVE_ROCK_SMASH,
MOVE_STRENGTH,
MOVE_THUNDERBOLT,
MOVE_THUNDER,
MOVE_TOXIC,
@ -3798,7 +3775,6 @@ static const u16 sGolemAlolanTeachableLearnset[] = {
MOVE_PROTECT,
MOVE_REST,
MOVE_ROCK_SMASH,
MOVE_STRENGTH,
MOVE_THUNDERBOLT,
MOVE_THUNDER,
MOVE_TOXIC,
@ -4637,7 +4613,6 @@ static const u16 sGrimerAlolanTeachableLearnset[] = {
MOVE_REST,
MOVE_SHADOW_BALL,
MOVE_SLUDGE_BOMB,
MOVE_STRENGTH,
MOVE_TAUNT,
MOVE_TOXIC,
MOVE_UNAVAILABLE,
@ -4652,10 +4627,8 @@ static const u16 sMukAlolanTeachableLearnset[] = {
MOVE_HYPER_BEAM,
MOVE_PROTECT,
MOVE_REST,
MOVE_ROCK_SMASH,
MOVE_SHADOW_BALL,
MOVE_SLUDGE_BOMB,
MOVE_STRENGTH,
MOVE_TAUNT,
MOVE_TOXIC,
MOVE_UNAVAILABLE,
@ -5301,7 +5274,6 @@ static const u16 sExeggutorAlolanTeachableLearnset[] = {
MOVE_EARTHQUAKE,
MOVE_FACADE,
MOVE_FLAMETHROWER,
MOVE_FLASH,
MOVE_HYPER_BEAM,
MOVE_IRON_TAIL,
MOVE_LIGHT_SCREEN,
@ -5311,7 +5283,6 @@ static const u16 sExeggutorAlolanTeachableLearnset[] = {
MOVE_REST,
MOVE_SOLAR_BEAM,
MOVE_SLUDGE_BOMB,
MOVE_STRENGTH,
MOVE_TOXIC,
MOVE_UNAVAILABLE,
};
@ -5434,9 +5405,7 @@ static const u16 sMarowakAlolanTeachableLearnset[] = {
MOVE_IRON_TAIL,
MOVE_PROTECT,
MOVE_REST,
MOVE_ROCK_SMASH,
MOVE_SHADOW_BALL,
MOVE_STRENGTH,
MOVE_THUNDERBOLT,
MOVE_THUNDER,
MOVE_TOXIC,
@ -7315,8 +7284,6 @@ static const u16 sTaurosTeachableLearnset[] = {
#if P_PALDEAN_FORMS
static const u16 sTaurosPaldeanCombatBreedTeachableLearnset[] = {
MOVE_ATTRACT,
MOVE_BLIZZARD,
MOVE_BODY_SLAM,
MOVE_BULLDOZE,
MOVE_CLOSE_COMBAT,
@ -7324,31 +7291,20 @@ static const u16 sTaurosPaldeanCombatBreedTeachableLearnset[] = {
MOVE_EARTHQUAKE,
MOVE_ENDURE,
MOVE_FACADE,
MOVE_FIRE_BLAST,
MOVE_FLAMETHROWER,
MOVE_FRUSTRATION,
MOVE_GIGA_IMPACT,
MOVE_HELPING_HAND,
MOVE_HIDDEN_POWER,
MOVE_HYPER_BEAM,
MOVE_ICE_BEAM,
MOVE_ICY_WIND,
MOVE_IRON_HEAD,
MOVE_OUTRAGE,
MOVE_PROTECT,
MOVE_RAIN_DANCE,
MOVE_REST,
MOVE_RETURN,
MOVE_REVERSAL,
MOVE_ROCK_SLIDE,
MOVE_ROCK_TOMB,
MOVE_SANDSTORM,
MOVE_SCARY_FACE,
MOVE_SECRET_POWER,
MOVE_SHADOW_BALL,
MOVE_SLEEP_TALK,
MOVE_SMART_STRIKE,
MOVE_SOLAR_BEAM,
MOVE_STOMPING_TANTRUM,
MOVE_STONE_EDGE,
MOVE_SUBSTITUTE,
@ -7357,9 +7313,6 @@ static const u16 sTaurosPaldeanCombatBreedTeachableLearnset[] = {
MOVE_TAKE_DOWN,
MOVE_TERA_BLAST,
MOVE_THIEF,
MOVE_THUNDER,
MOVE_THUNDERBOLT,
MOVE_TOXIC,
MOVE_TRAILBLAZE,
MOVE_WILD_CHARGE,
MOVE_ZEN_HEADBUTT,
@ -7367,8 +7320,6 @@ static const u16 sTaurosPaldeanCombatBreedTeachableLearnset[] = {
};
static const u16 sTaurosPaldeanBlazeBreedTeachableLearnset[] = {
MOVE_ATTRACT,
MOVE_BLIZZARD,
MOVE_BODY_SLAM,
MOVE_BULLDOZE,
MOVE_CLOSE_COMBAT,
@ -7378,40 +7329,27 @@ static const u16 sTaurosPaldeanBlazeBreedTeachableLearnset[] = {
MOVE_FACADE,
MOVE_FIRE_BLAST,
MOVE_FLAMETHROWER,
MOVE_FRUSTRATION,
MOVE_GIGA_IMPACT,
MOVE_HELPING_HAND,
MOVE_HIDDEN_POWER,
MOVE_HYPER_BEAM,
MOVE_ICE_BEAM,
MOVE_ICY_WIND,
MOVE_IRON_HEAD,
MOVE_OUTRAGE,
MOVE_PROTECT,
MOVE_RAIN_DANCE,
MOVE_REST,
MOVE_RETURN,
MOVE_REVERSAL,
MOVE_ROCK_SLIDE,
MOVE_ROCK_TOMB,
MOVE_SANDSTORM,
MOVE_SCARY_FACE,
MOVE_SECRET_POWER,
MOVE_SHADOW_BALL,
MOVE_SLEEP_TALK,
MOVE_SMART_STRIKE,
MOVE_SOLAR_BEAM,
MOVE_STOMPING_TANTRUM,
MOVE_STONE_EDGE,
MOVE_SUBSTITUTE,
MOVE_SUNNY_DAY,
MOVE_SURF,
MOVE_TAKE_DOWN,
MOVE_TERA_BLAST,
MOVE_THIEF,
MOVE_THUNDER,
MOVE_THUNDERBOLT,
MOVE_TOXIC,
MOVE_TRAILBLAZE,
MOVE_WILD_CHARGE,
MOVE_ZEN_HEADBUTT,
@ -7419,8 +7357,6 @@ static const u16 sTaurosPaldeanBlazeBreedTeachableLearnset[] = {
};
static const u16 sTaurosPaldeanAquaBreedTeachableLearnset[] = {
MOVE_ATTRACT,
MOVE_BLIZZARD,
MOVE_BODY_SLAM,
MOVE_BULLDOZE,
MOVE_CLOSE_COMBAT,
@ -7428,42 +7364,27 @@ static const u16 sTaurosPaldeanAquaBreedTeachableLearnset[] = {
MOVE_EARTHQUAKE,
MOVE_ENDURE,
MOVE_FACADE,
MOVE_FIRE_BLAST,
MOVE_FLAMETHROWER,
MOVE_FRUSTRATION,
MOVE_GIGA_IMPACT,
MOVE_HELPING_HAND,
MOVE_HIDDEN_POWER,
MOVE_HYPER_BEAM,
MOVE_ICE_BEAM,
MOVE_ICY_WIND,
MOVE_IRON_HEAD,
MOVE_OUTRAGE,
MOVE_PROTECT,
MOVE_RAIN_DANCE,
MOVE_REST,
MOVE_RETURN,
MOVE_REVERSAL,
MOVE_ROCK_SLIDE,
MOVE_ROCK_TOMB,
MOVE_SANDSTORM,
MOVE_SCARY_FACE,
MOVE_SECRET_POWER,
MOVE_SHADOW_BALL,
MOVE_SLEEP_TALK,
MOVE_SMART_STRIKE,
MOVE_SOLAR_BEAM,
MOVE_STOMPING_TANTRUM,
MOVE_STONE_EDGE,
MOVE_SUBSTITUTE,
MOVE_SUNNY_DAY,
MOVE_SURF,
MOVE_TAKE_DOWN,
MOVE_TERA_BLAST,
MOVE_THIEF,
MOVE_THUNDER,
MOVE_THUNDERBOLT,
MOVE_TOXIC,
MOVE_TRAILBLAZE,
MOVE_WILD_CHARGE,
MOVE_ZEN_HEADBUTT,
@ -7942,7 +7863,6 @@ static const u16 sPorygonTeachableLearnset[] = {
MOVE_THUNDER,
MOVE_THUNDERBOLT,
MOVE_TOXIC,
MOVE_DEFENSE_CURL,
MOVE_DOUBLE_EDGE,
MOVE_DREAM_EATER,
MOVE_ENDURE,
@ -10623,38 +10543,27 @@ static const u16 sQuagsireTeachableLearnset[] = {
static const u16 sWooperPaldeanTeachableLearnset[] = {
MOVE_ACID_SPRAY,
MOVE_AMNESIA,
MOVE_ATTRACT,
MOVE_AVALANCHE,
MOVE_BLIZZARD,
MOVE_BODY_SLAM,
MOVE_BULLDOZE,
MOVE_CHILLING_WATER,
MOVE_DIG,
MOVE_EARTH_POWER,
MOVE_EARTHQUAKE,
MOVE_ENCORE,
MOVE_ENDURE,
MOVE_FACADE,
MOVE_FRUSTRATION,
MOVE_HELPING_HAND,
MOVE_HIDDEN_POWER,
MOVE_HYDRO_PUMP,
MOVE_ICE_BEAM,
MOVE_ICY_WIND,
MOVE_LIQUIDATION,
MOVE_MUD_SHOT,
MOVE_MUD_SLAP,
MOVE_PROTECT,
MOVE_RAIN_DANCE,
MOVE_REST,
MOVE_RETURN,
MOVE_ROCK_SLIDE,
MOVE_ROCK_TOMB,
MOVE_SANDSTORM,
MOVE_SECRET_POWER,
MOVE_SLEEP_TALK,
MOVE_SLUDGE_BOMB,
MOVE_SNOWSCAPE,
MOVE_SPIKES,
MOVE_STEALTH_ROCK,
MOVE_STOMPING_TANTRUM,
@ -12566,9 +12475,6 @@ static const u16 sWyrdeerTeachableLearnset[] = {
#if P_FAMILY_SMEARGLE
static const u16 sSmeargleTeachableLearnset[] = {
MOVE_FLAMETHROWER,
MOVE_SEISMIC_TOSS,
MOVE_SLEEP_TALK,
MOVE_UNAVAILABLE,
};
#endif //P_FAMILY_SMEARGLE
@ -14883,7 +14789,6 @@ static const u16 sShedinjaTeachableLearnset[] = {
MOVE_SNORE,
MOVE_SUBSTITUTE,
MOVE_SWAGGER,
MOVE_SWORDS_DANCE,
MOVE_UNAVAILABLE,
};
#endif //P_FAMILY_NINCADA
@ -19263,17 +19168,11 @@ static const u16 sDeoxysNormalTeachableLearnset[] = {
MOVE_TOXIC,
MOVE_WATER_PULSE,
MOVE_BODY_SLAM,
MOVE_COUNTER,
MOVE_DOUBLE_EDGE,
MOVE_DREAM_EATER,
MOVE_DYNAMIC_PUNCH,
MOVE_ENDURE,
MOVE_FIRE_PUNCH,
MOVE_ICE_PUNCH,
MOVE_ICY_WIND,
MOVE_MEGA_KICK,
MOVE_MEGA_PUNCH,
MOVE_MIMIC,
MOVE_MUD_SLAP,
MOVE_PSYCH_UP,
MOVE_ROCK_SLIDE,
@ -33089,7 +32988,6 @@ static const u16 sMeltanTeachableLearnset[] = {
MOVE_IRON_DEFENSE,
MOVE_GYRO_BALL,
MOVE_STEEL_BEAM,
MOVE_HIDDEN_POWER,
MOVE_UNAVAILABLE,
};
@ -33134,7 +33032,6 @@ static const u16 sMelmetalTeachableLearnset[] = {
MOVE_BODY_PRESS,
MOVE_STEEL_BEAM,
MOVE_STEEL_ROLLER,
MOVE_HIDDEN_POWER,
MOVE_UNAVAILABLE,
};
#endif //P_FAMILY_MELTAN
@ -35502,43 +35399,7 @@ static const u16 sLechonkTeachableLearnset[] = {
MOVE_UNAVAILABLE,
};
static const u16 sOinkologneMaleTeachableLearnset[] = {
MOVE_BODY_PRESS,
MOVE_BODY_SLAM,
MOVE_BULLDOZE,
MOVE_BULLET_SEED,
MOVE_CHILLING_WATER,
MOVE_DIG,
MOVE_DISARMING_VOICE,
MOVE_EARTH_POWER,
MOVE_ENDURE,
MOVE_ENERGY_BALL,
MOVE_FACADE,
MOVE_GIGA_IMPACT,
MOVE_HELPING_HAND,
MOVE_HYPER_BEAM,
MOVE_HYPER_VOICE,
MOVE_IRON_HEAD,
MOVE_MUD_SHOT,
MOVE_MUD_SLAP,
MOVE_PLAY_ROUGH,
MOVE_PROTECT,
MOVE_RAIN_DANCE,
MOVE_REST,
MOVE_SEED_BOMB,
MOVE_SLEEP_TALK,
MOVE_STOMPING_TANTRUM,
MOVE_SUBSTITUTE,
MOVE_SUNNY_DAY,
MOVE_TAKE_DOWN,
MOVE_TERA_BLAST,
MOVE_THIEF,
MOVE_TRAILBLAZE,
MOVE_ZEN_HEADBUTT,
MOVE_UNAVAILABLE,
};
static const u16 sOinkologneFemaleTeachableLearnset[] = {
static const u16 sOinkologneTeachableLearnset[] = {
MOVE_BODY_PRESS,
MOVE_BODY_SLAM,
MOVE_BULLDOZE,

View File

@ -0,0 +1,128 @@
#include "global.h"
#include "test/battle.h"
SINGLE_BATTLE_TEST("Corrosion can poison or badly poison a Pokemon regardless of its typing")
{
u16 species;
PARAMETRIZE { species = SPECIES_ODDISH; }
PARAMETRIZE { species = SPECIES_BELDUM; }
GIVEN {
ASSUME(MoveHasMoveEffect(MOVE_TWINEEDLE, MOVE_EFFECT_POISON) == TRUE);
PLAYER(SPECIES_SALANDIT) { Ability(ABILITY_CORROSION); }
OPPONENT(species);
} WHEN {
TURN { MOVE(player, MOVE_TWINEEDLE); }
} SCENE {
ANIMATION(ANIM_TYPE_MOVE, MOVE_TWINEEDLE, player);
HP_BAR(opponent);
ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_PSN, opponent);
STATUS_ICON(opponent, poison: TRUE);
}
}
SINGLE_BATTLE_TEST("Corrosion can poison or badly poison a Steel type with a status poison effect")
{
u16 move;
PARAMETRIZE { move = MOVE_POISON_POWDER; }
PARAMETRIZE { move = MOVE_TOXIC; }
GIVEN {
ASSUME(gBattleMoves[MOVE_POISON_POWDER].effect == EFFECT_POISON);
ASSUME(gBattleMoves[MOVE_TOXIC].effect == EFFECT_TOXIC);
PLAYER(SPECIES_SALANDIT) { Ability(ABILITY_CORROSION); }
OPPONENT(SPECIES_BELDUM);
} WHEN {
TURN { MOVE(player, move); }
} SCENE {
ANIMATION(ANIM_TYPE_MOVE, move, player);
ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_PSN, opponent);
if (move == MOVE_POISON_POWDER)
STATUS_ICON(opponent, poison: TRUE);
else
STATUS_ICON(opponent, badPoison: TRUE);
}
}
SINGLE_BATTLE_TEST("Corrosion does not effect poison type damaging moves if the target is immune to it")
{
GIVEN {
ASSUME(MoveHasMoveEffect(MOVE_SLUDGE_BOMB, MOVE_EFFECT_POISON) == TRUE);
PLAYER(SPECIES_SALANDIT) { Ability(ABILITY_CORROSION); }
OPPONENT(SPECIES_BELDUM);
} WHEN {
TURN { MOVE(player, MOVE_SLUDGE_BOMB); }
} SCENE {
NONE_OF {
ANIMATION(ANIM_TYPE_MOVE, MOVE_SLUDGE_BOMB, player);
HP_BAR(opponent);
ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_PSN, opponent);
STATUS_ICON(opponent, poison: TRUE);
}
}
}
SINGLE_BATTLE_TEST("Corrosion can poison Poison- and Steel-type targets if it uses Fling while holding a Toxic Orb or a Poison Barb")
{
u16 heldItem;
PARAMETRIZE { heldItem = ITEM_POISON_BARB; }
PARAMETRIZE { heldItem = ITEM_TOXIC_ORB; }
GIVEN {
ASSUME(gBattleMoves[MOVE_FLING].effect == EFFECT_FLING);
ASSUME(gItems[ITEM_POISON_BARB].holdEffect == HOLD_EFFECT_POISON_POWER);
ASSUME(gItems[ITEM_TOXIC_ORB].holdEffect == HOLD_EFFECT_TOXIC_ORB);
PLAYER(SPECIES_SALANDIT) { Ability(ABILITY_CORROSION); Item(heldItem); }
OPPONENT(SPECIES_ODDISH);
} WHEN {
TURN { MOVE(player, MOVE_FLING); }
} SCENE {
ANIMATION(ANIM_TYPE_MOVE, MOVE_FLING, player);
HP_BAR(opponent);
ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_PSN, opponent);
if (heldItem == ITEM_POISON_BARB)
STATUS_ICON(opponent, poison: TRUE);
else
STATUS_ICON(opponent, badPoison: TRUE);
}
}
SINGLE_BATTLE_TEST("If a Poison- or Steel-type Pokémon with Corrosion holds a Toxic Orb, it will badly poison itself")
{
GIVEN {
ASSUME(gItems[ITEM_TOXIC_ORB].holdEffect == HOLD_EFFECT_TOXIC_ORB);
PLAYER(SPECIES_SALANDIT) { Ability(ABILITY_CORROSION); Item(ITEM_TOXIC_ORB); }
OPPONENT(SPECIES_ODDISH);
} WHEN {
TURN { }
} SCENE {
ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_PSN, player);
STATUS_ICON(player, badPoison: TRUE);
}
}
SINGLE_BATTLE_TEST("If a Poison- or Steel-type Pokémon with Corrosion poisons a target with Synchronize, Synchronize will not poison Poison- or Steel-type Pokémon")
{
GIVEN {
ASSUME(gBattleMoves[MOVE_TOXIC].effect == EFFECT_TOXIC);
PLAYER(SPECIES_SALANDIT) { Ability(ABILITY_CORROSION); }
OPPONENT(SPECIES_ABRA) { Ability(ABILITY_SYNCHRONIZE); }
} WHEN {
TURN { MOVE(player, MOVE_TOXIC); }
} SCENE {
ANIMATION(ANIM_TYPE_MOVE, MOVE_TOXIC, player);
ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_PSN, opponent);
STATUS_ICON(opponent, badPoison: TRUE);
NONE_OF {
ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_PSN, player);
STATUS_ICON(player, badPoison: TRUE);
}
}
}
TO_DO_BATTLE_TEST("Corrosion cannot bypass moves or Abilities that prevent poisoning, such as Safeguard or Immunity");
TO_DO_BATTLE_TEST("If the Pokémon with this Ability uses Magic Coat to reflect a status move that inflicts poison, the reflected move will be able to poison Poison- or Steel-type Pokémon.");
TO_DO_BATTLE_TEST("Moves used by a Pokémon with Corrosion that are reflected by Magic Coat or Magic Bounce do not retain the ability to poison Poison- or Steel-type Pokémon.")

View File

@ -0,0 +1,38 @@
#include "global.h"
#include "test/battle.h"
SINGLE_BATTLE_TEST("Emergency Exit switches out when taking 50% max-hp damage")
{
GIVEN {
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_GOLISOPOD) { Ability(ABILITY_EMERGENCY_EXIT); MaxHP(263); HP(262); };
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN {
MOVE(player, MOVE_SUPER_FANG);
SEND_OUT(opponent, 1);
}
} SCENE {
ANIMATION(ANIM_TYPE_MOVE, MOVE_SUPER_FANG, player);
HP_BAR(opponent);
ABILITY_POPUP(opponent, ABILITY_EMERGENCY_EXIT);
}
}
SINGLE_BATTLE_TEST("Emergency Exit switches out when taking 50% max-hp damage after a restore hp hold effect was used")
{
GIVEN {
PLAYER(SPECIES_WOBBUFFET)
OPPONENT(SPECIES_GOLISOPOD) { Ability(ABILITY_EMERGENCY_EXIT); MaxHP(263); HP(262); Item(ITEM_SITRUS_BERRY); };
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN {
MOVE(player, MOVE_SUPER_FANG);
}
} SCENE {
ANIMATION(ANIM_TYPE_MOVE, MOVE_SUPER_FANG, player);
HP_BAR(opponent);
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, opponent);
NOT ABILITY_POPUP(opponent, ABILITY_EMERGENCY_EXIT);
}
}

View File

@ -0,0 +1,26 @@
#include "global.h"
#include "test/battle.h"
ASSUMPTIONS
{
ASSUME(gItems[ITEM_EJECT_PACK].holdEffect == HOLD_EFFECT_EJECT_PACK);
}
SINGLE_BATTLE_TEST("Eject Pack does not cause the new pokemon to lose hp due to it's held Life Orb")
{
GIVEN {
ASSUME(gItems[ITEM_LIFE_ORB].holdEffect == HOLD_EFFECT_LIFE_ORB);
PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_EJECT_PACK); }
PLAYER(SPECIES_WYNAUT) { Item(ITEM_LIFE_ORB); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { MOVE(player, MOVE_OVERHEAT); SEND_OUT(player, 1); }
} SCENE {
ANIMATION(ANIM_TYPE_MOVE, MOVE_OVERHEAT, player);
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player);
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, player);
MESSAGE("Wobbuffet is switched out with the Eject Pack!");
MESSAGE("Go! Wynaut!");
NOT MESSAGE("Wynaut was hurt by its Life Orb!");
}
}

View File

@ -430,4 +430,21 @@ SINGLE_BATTLE_TEST("Red Card is consumed after dragged out replacement has its S
}
}
SINGLE_BATTLE_TEST("Red Card does not cause the dragged out mon to lose hp due to it's held Life Orb")
{
GIVEN {
PLAYER(SPECIES_WOBBUFFET);
PLAYER(SPECIES_WYNAUT) { Item(ITEM_LIFE_ORB); }
OPPONENT(SPECIES_WOBBUFFET) { Item(ITEM_RED_CARD); }
} WHEN {
TURN { MOVE(player, MOVE_TACKLE); }
} SCENE {
ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, player);
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, opponent);
MESSAGE("Foe Wobbuffet held up its Red Card against Wobbuffet!");
MESSAGE("Wynaut was dragged out!");
NOT MESSAGE("Wynaut was hurt by its Life Orb!");
}
}
// SINGLE_BATTLE_TEST("Red Card activates but fails if the attacker has Dynamaxed")

View File

@ -0,0 +1,39 @@
#include "global.h"
#include "test/battle.h"
ASSUMPTIONS
{
ASSUME(gBattleMoves[MOVE_STEEL_BEAM].effect == EFFECT_MAX_HP_50_RECOIL);
}
SINGLE_BATTLE_TEST("Steel Beam causes the user to take damage equal to half of its maximum HP")
{
s16 recoilDamage;
GIVEN {
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { MOVE(player, MOVE_STEEL_BEAM); }
} SCENE {
ANIMATION(ANIM_TYPE_MOVE, MOVE_STEEL_BEAM, player);
HP_BAR(opponent);
HP_BAR(player, captureDamage: &recoilDamage);
} THEN {
EXPECT_EQ(player->maxHP / 2, recoilDamage);
}
}
SINGLE_BATTLE_TEST("Steel Beam hp loss is prevented by Magic Guard")
{
GIVEN {
PLAYER(SPECIES_CLEFAIRY) { Ability(ABILITY_MAGIC_GUARD); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { MOVE(player, MOVE_STEEL_BEAM); }
} SCENE {
ANIMATION(ANIM_TYPE_MOVE, MOVE_STEEL_BEAM, player);
HP_BAR(opponent);
NOT HP_BAR(player);
}
}

View File

@ -105,3 +105,16 @@ DOUBLE_BATTLE_TEST("Mind Blown causes everyone to faint in a double battle")
MESSAGE("Wobbuffet fainted!");
}
}
SINGLE_BATTLE_TEST("Mind Blown hp loss is prevented by Magic Guard")
{
GIVEN {
PLAYER(SPECIES_CLEFAIRY) { Ability(ABILITY_MAGIC_GUARD); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { MOVE(player, MOVE_MIND_BLOWN); }
} SCENE {
NOT HP_BAR(player);
ANIMATION(ANIM_TYPE_MOVE, MOVE_MIND_BLOWN, player);
}
}