Use dedicated functions for Mud/Water Sport (#7248)
This commit is contained in:
parent
92b4b7f0a0
commit
e503f97f32
@ -54,7 +54,6 @@ enum {
|
||||
ABILITYEFFECT_ATK_SYNCHRONIZE,
|
||||
ABILITYEFFECT_MOVE_END_OTHER,
|
||||
ABILITYEFFECT_NEUTRALIZINGGAS,
|
||||
ABILITYEFFECT_FIELD_SPORT, // Only used if B_SPORT_TURNS >= GEN_6
|
||||
ABILITYEFFECT_ON_WEATHER,
|
||||
ABILITYEFFECT_ON_TERRAIN,
|
||||
ABILITYEFFECT_SWITCH_IN_TERRAIN,
|
||||
@ -63,10 +62,6 @@ enum {
|
||||
ABILITYEFFECT_SWITCH_IN_STATUSES,
|
||||
};
|
||||
|
||||
// Special cases
|
||||
#define ABILITYEFFECT_MUD_SPORT 252 // Only used if B_SPORT_TURNS >= GEN_6
|
||||
#define ABILITYEFFECT_WATER_SPORT 253 // Only used if B_SPORT_TURNS >= GEN_6
|
||||
|
||||
// For the first argument of ItemBattleEffects, to deteremine which block of item effects to try
|
||||
enum ItemCaseId
|
||||
{
|
||||
|
||||
@ -167,7 +167,9 @@ enum VolatileFlags
|
||||
F(VOLATILE_CURSED, cursed, (u32, 1), V_BATON_PASSABLE) \
|
||||
F(VOLATILE_FORESIGHT, foresight, (u32, 1)) \
|
||||
F(VOLATILE_DRAGON_CHEER, dragonCheer, (u32, 1), V_BATON_PASSABLE) \
|
||||
F(VOLATILE_FOCUS_ENERGY, focusEnergy, (u32, 1), V_BATON_PASSABLE)
|
||||
F(VOLATILE_FOCUS_ENERGY, focusEnergy, (u32, 1), V_BATON_PASSABLE) \
|
||||
F(VOLATILE_MUD_SPORT, mudSport, (u32, 1), V_BATON_PASSABLE) \
|
||||
F(VOLATILE_WATER_SPORT, waterSport, (u32, 1), V_BATON_PASSABLE)
|
||||
|
||||
/* Use within a macro to get the maximum allowed value for a volatile. Requires _typeBitSize and debug parameters as input. */
|
||||
#define GET_VOLATILE_MAXIMUM(_typeBitSize, ...) INVOKE_WITH_B(GET_VOLATILE_MAXIMUM_, _typeBitSize)
|
||||
|
||||
@ -2050,13 +2050,13 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
|
||||
break;
|
||||
case EFFECT_MUD_SPORT:
|
||||
if (gFieldStatuses & STATUS_FIELD_MUDSPORT
|
||||
|| gStatuses4[battlerAtk] & STATUS4_MUD_SPORT
|
||||
|| gBattleMons[battlerAtk].volatiles.mudSport
|
||||
|| PartnerHasSameMoveEffectWithoutTarget(BATTLE_PARTNER(battlerAtk), move, aiData->partnerMove))
|
||||
ADJUST_SCORE(-10);
|
||||
break;
|
||||
case EFFECT_WATER_SPORT:
|
||||
if (gFieldStatuses & STATUS_FIELD_WATERSPORT
|
||||
|| gStatuses4[battlerAtk] & STATUS4_WATER_SPORT
|
||||
|| gBattleMons[battlerAtk].volatiles.waterSport
|
||||
|| PartnerHasSameMoveEffectWithoutTarget(BATTLE_PARTNER(battlerAtk), move, aiData->partnerMove))
|
||||
ADJUST_SCORE(-10);
|
||||
break;
|
||||
|
||||
@ -169,8 +169,6 @@ enum
|
||||
enum
|
||||
{
|
||||
LIST_STATUS4_ELECTRIFIED,
|
||||
LIST_STATUS4_MUD_SPORT,
|
||||
LIST_STATUS4_WATER_SPORT,
|
||||
LIST_STATUS4_SALT_CURE,
|
||||
LIST_STATUS4_SYRUP_BOMB,
|
||||
LIST_STATUS4_GLAIVE_RUSH,
|
||||
@ -348,8 +346,6 @@ static const u8 sText_LaserFocus[] = _("Laser Focus");
|
||||
static const u8 sText_PowerTrick[] = _("Power Trick");
|
||||
static const u8 sText_SkyDropped[] = _("Sky Dropped");
|
||||
static const u8 sText_Electrified[] = _("Electrified");
|
||||
static const u8 sText_MudSport[] = _("Mud Sport");
|
||||
static const u8 sText_WaterSport[] = _("Water Sport");
|
||||
static const u8 sText_InfiniteConfusion[] = _("Infinite Confusion");
|
||||
static const u8 sText_SaltCure[] = _("Salt Cure");
|
||||
static const u8 sText_SyrupBomb[] = _("Syrup Bomb");
|
||||
@ -548,6 +544,8 @@ static const struct ListMenuItem sVolatileStatusListItems[] =
|
||||
{COMPOUND_STRING("Foresight"), VOLATILE_FORESIGHT},
|
||||
{COMPOUND_STRING("DragonCheer"), VOLATILE_DRAGON_CHEER},
|
||||
{COMPOUND_STRING("FocusEnergy"), VOLATILE_FOCUS_ENERGY},
|
||||
{COMPOUND_STRING("MudSport"), VOLATILE_MUD_SPORT},
|
||||
{COMPOUND_STRING("WaterSport"), VOLATILE_WATER_SPORT},
|
||||
};
|
||||
|
||||
static const struct ListMenuItem sStatus3ListItems[] =
|
||||
@ -580,8 +578,6 @@ static const struct ListMenuItem sStatus3ListItems[] =
|
||||
static const struct ListMenuItem sStatus4ListItems[] =
|
||||
{
|
||||
{sText_Electrified, LIST_STATUS4_ELECTRIFIED},
|
||||
{sText_MudSport, LIST_STATUS4_MUD_SPORT},
|
||||
{sText_WaterSport, LIST_STATUS4_WATER_SPORT},
|
||||
{sText_SaltCure, LIST_STATUS4_SALT_CURE},
|
||||
{sText_SyrupBomb, LIST_STATUS4_SYRUP_BOMB},
|
||||
{sText_GlaiveRush, LIST_STATUS4_GLAIVE_RUSH},
|
||||
|
||||
@ -3156,7 +3156,7 @@ void SwitchInClearSetData(u32 battler)
|
||||
gStatuses3[battler] &= (STATUS3_LEECHSEED_BATTLER | STATUS3_LEECHSEED | STATUS3_ALWAYS_HITS | STATUS3_PERISH_SONG | STATUS3_ROOTED
|
||||
| STATUS3_GASTRO_ACID | STATUS3_EMBARGO | STATUS3_TELEKINESIS | STATUS3_MAGNET_RISE | STATUS3_HEAL_BLOCK
|
||||
| STATUS3_AQUA_RING | STATUS3_POWER_TRICK);
|
||||
gStatuses4[battler] &= (STATUS4_MUD_SPORT | STATUS4_WATER_SPORT | STATUS4_INFINITE_CONFUSION);
|
||||
gStatuses4[battler] &= STATUS4_INFINITE_CONFUSION;
|
||||
for (i = 0; i < gBattlersCount; i++)
|
||||
{
|
||||
if (!IsBattlerAlly(battler, i)
|
||||
|
||||
@ -15393,9 +15393,9 @@ static void Cmd_settypebasedhalvers(void)
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!(gStatuses4[gBattlerAttacker] & STATUS4_MUD_SPORT))
|
||||
if (!gBattleMons[gBattlerAttacker].volatiles.waterSport)
|
||||
{
|
||||
gStatuses4[gBattlerAttacker] |= STATUS4_MUD_SPORT;
|
||||
gBattleMons[gBattlerAttacker].volatiles.waterSport = TRUE;
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_WEAKEN_ELECTRIC;
|
||||
worked = TRUE;
|
||||
}
|
||||
@ -15415,9 +15415,9 @@ static void Cmd_settypebasedhalvers(void)
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!(gStatuses4[gBattlerAttacker] & STATUS4_WATER_SPORT))
|
||||
if (!gBattleMons[gBattlerAttacker].volatiles.mudSport)
|
||||
{
|
||||
gStatuses4[gBattlerAttacker] |= STATUS4_WATER_SPORT;
|
||||
gBattleMons[gBattlerAttacker].volatiles.mudSport = TRUE;
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_WEAKEN_FIRE;
|
||||
worked = TRUE;
|
||||
}
|
||||
|
||||
@ -5199,35 +5199,6 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case ABILITYEFFECT_FIELD_SPORT:
|
||||
switch (gLastUsedAbility)
|
||||
{
|
||||
case ABILITYEFFECT_MUD_SPORT:
|
||||
for (i = 0; i < gBattlersCount; i++)
|
||||
{
|
||||
if (gStatuses4[i] & STATUS4_MUD_SPORT)
|
||||
effect = i + 1;
|
||||
}
|
||||
break;
|
||||
case ABILITYEFFECT_WATER_SPORT:
|
||||
for (i = 0; i < gBattlersCount; i++)
|
||||
{
|
||||
if (gStatuses4[i] & STATUS4_WATER_SPORT)
|
||||
effect = i + 1;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
for (i = 0; i < gBattlersCount; i++)
|
||||
{
|
||||
if (gBattleMons[i].ability == ability)
|
||||
{
|
||||
gLastUsedAbility = ability;
|
||||
effect = i + 1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case ABILITYEFFECT_ON_WEATHER: // For ability effects that activate when the battle weather changes.
|
||||
gLastUsedAbility = GetBattlerAbility(battler);
|
||||
switch (gLastUsedAbility)
|
||||
@ -7933,6 +7904,40 @@ u32 CalcFuryCutterBasePower(u32 basePower, u32 furyCutterCounter)
|
||||
return basePower;
|
||||
}
|
||||
|
||||
static inline u32 IsFieldMudSportAffected(u32 moveType)
|
||||
{
|
||||
if (moveType == TYPE_ELECTRIC && (gFieldStatuses & STATUS_FIELD_MUDSPORT))
|
||||
return TRUE;
|
||||
|
||||
if (B_SPORT_TURNS < GEN_6)
|
||||
{
|
||||
for (u32 battler = 0; battler < gBattlersCount; battler++)
|
||||
{
|
||||
if (gBattleMons[battler].volatiles.mudSport)
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static inline u32 IsFieldWaterSportAffected(u32 moveType)
|
||||
{
|
||||
if (moveType == TYPE_FIRE && (gFieldStatuses & STATUS_FIELD_WATERSPORT))
|
||||
return TRUE;
|
||||
|
||||
if (B_SPORT_TURNS < GEN_6)
|
||||
{
|
||||
for (u32 battler = 0; battler < gBattlersCount; battler++)
|
||||
{
|
||||
if (gBattleMons[battler].volatiles.waterSport)
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static inline u32 CalcMoveBasePower(struct DamageContext *ctx)
|
||||
{
|
||||
u32 battlerAtk = ctx->battlerAtk;
|
||||
@ -8268,12 +8273,9 @@ static inline u32 CalcMoveBasePowerAfterModifiers(struct DamageContext *ctx)
|
||||
modifier = uq4_12_multiply(modifier, (B_TERRAIN_TYPE_BOOST >= GEN_8 ? UQ_4_12(1.3) : UQ_4_12(1.5)));
|
||||
if (IsBattlerTerrainAffected(battlerAtk, STATUS_FIELD_PSYCHIC_TERRAIN) && moveType == TYPE_PSYCHIC)
|
||||
modifier = uq4_12_multiply(modifier, (B_TERRAIN_TYPE_BOOST >= GEN_8 ? UQ_4_12(1.3) : UQ_4_12(1.5)));
|
||||
|
||||
if (moveType == TYPE_ELECTRIC && ((gFieldStatuses & STATUS_FIELD_MUDSPORT)
|
||||
|| AbilityBattleEffects(ABILITYEFFECT_FIELD_SPORT, 0, 0, ABILITYEFFECT_MUD_SPORT, 0)))
|
||||
if (IsFieldMudSportAffected(ctx->moveType))
|
||||
modifier = uq4_12_multiply(modifier, UQ_4_12(B_SPORT_DMG_REDUCTION >= GEN_5 ? 0.33 : 0.5));
|
||||
if (moveType == TYPE_FIRE && ((gFieldStatuses & STATUS_FIELD_WATERSPORT)
|
||||
|| AbilityBattleEffects(ABILITYEFFECT_FIELD_SPORT, 0, 0, ABILITYEFFECT_WATER_SPORT, 0)))
|
||||
if (IsFieldWaterSportAffected(ctx->moveType))
|
||||
modifier = uq4_12_multiply(modifier, UQ_4_12(B_SPORT_DMG_REDUCTION >= GEN_5 ? 0.33 : 0.5));
|
||||
|
||||
// attacker's abilities
|
||||
|
||||
@ -2,3 +2,33 @@
|
||||
#include "test/battle.h"
|
||||
|
||||
TO_DO_BATTLE_TEST("TODO: Write Mud Sport (Move Effect) test titles")
|
||||
|
||||
SINGLE_BATTLE_TEST("Mud Sport reduces the damage of Electric Type moves by 67% (Gen5+)")
|
||||
{
|
||||
s16 playerDmg[2];
|
||||
s16 opponentDmg[2];
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_SHOCK_WAVE); MOVE(opponent, MOVE_SHOCK_WAVE); }
|
||||
TURN { MOVE(player, MOVE_MUD_SPORT); }
|
||||
TURN { MOVE(player, MOVE_SHOCK_WAVE); MOVE(opponent, MOVE_SHOCK_WAVE); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_SHOCK_WAVE, player);
|
||||
HP_BAR(opponent, captureDamage: &opponentDmg[0]);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_SHOCK_WAVE, opponent);
|
||||
HP_BAR(player, captureDamage: &playerDmg[0]);
|
||||
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_MUD_SPORT, player);
|
||||
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_SHOCK_WAVE, player);
|
||||
HP_BAR(opponent, captureDamage: &opponentDmg[1]);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_SHOCK_WAVE, opponent);
|
||||
HP_BAR(player, captureDamage: &playerDmg[1]);
|
||||
|
||||
} THEN {
|
||||
EXPECT_MUL_EQ(opponentDmg[0], Q_4_12(0.33), opponentDmg[1]);
|
||||
EXPECT_MUL_EQ(playerDmg[0], Q_4_12(0.33), playerDmg[1]);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,3 +2,33 @@
|
||||
#include "test/battle.h"
|
||||
|
||||
TO_DO_BATTLE_TEST("TODO: Write Water Sport (Move Effect) test titles")
|
||||
|
||||
SINGLE_BATTLE_TEST("Water Sport reduces the damage of Fire Type moves by 67% (Gen5+)")
|
||||
{
|
||||
s16 playerDmg[2];
|
||||
s16 opponentDmg[2];
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_FIRE_PLEDGE); MOVE(opponent, MOVE_FIRE_PLEDGE); }
|
||||
TURN { MOVE(player, MOVE_WATER_SPORT); }
|
||||
TURN { MOVE(player, MOVE_FIRE_PLEDGE); MOVE(opponent, MOVE_FIRE_PLEDGE); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_FIRE_PLEDGE, player);
|
||||
HP_BAR(opponent, captureDamage: &opponentDmg[0]);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_FIRE_PLEDGE, opponent);
|
||||
HP_BAR(player, captureDamage: &playerDmg[0]);
|
||||
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_WATER_SPORT, player);
|
||||
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_FIRE_PLEDGE, player);
|
||||
HP_BAR(opponent, captureDamage: &opponentDmg[1]);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_FIRE_PLEDGE, opponent);
|
||||
HP_BAR(player, captureDamage: &playerDmg[1]);
|
||||
|
||||
} THEN {
|
||||
EXPECT_MUL_EQ(opponentDmg[0], Q_4_12(0.33), opponentDmg[1]);
|
||||
EXPECT_MUL_EQ(playerDmg[0], Q_4_12(0.33), playerDmg[1]);
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user