mirror of
https://github.com/Ninjdai1/pokeemerald.git
synced 2024-12-26 03:34:15 +01:00
Merge branch 'RHH/master' into RHH/upcoming
# Conflicts: # src/battle_util.c
This commit is contained in:
commit
47cea526ec
@ -23,8 +23,9 @@ body:
|
||||
label: Version
|
||||
description: What version of pokeemerald-expansion are you using as a base?
|
||||
options:
|
||||
- 1.5.0 (Default)
|
||||
- 1.5.1 (Default)
|
||||
- upcoming (Edge)
|
||||
- 1.5.0
|
||||
- 1.4.3
|
||||
- 1.4.2
|
||||
- 1.4.1
|
||||
|
@ -23,8 +23,9 @@ body:
|
||||
label: Version
|
||||
description: What version of pokeemerald-expansion are you using as a base?
|
||||
options:
|
||||
- 1.5.0 (Default)
|
||||
- 1.5.1 (Default)
|
||||
- upcoming (Edge)
|
||||
- 1.5.0
|
||||
- 1.4.3
|
||||
- 1.4.2
|
||||
- 1.4.1
|
||||
|
3
.github/ISSUE_TEMPLATE/04_other_errors.yaml
vendored
3
.github/ISSUE_TEMPLATE/04_other_errors.yaml
vendored
@ -23,8 +23,9 @@ body:
|
||||
label: Version
|
||||
description: What version of pokeemerald-expansion are you using as a base?
|
||||
options:
|
||||
- 1.5.0 (Default)
|
||||
- 1.5.1 (Default)
|
||||
- upcoming (Edge)
|
||||
- 1.5.0
|
||||
- 1.4.3
|
||||
- 1.4.2
|
||||
- 1.4.1
|
||||
|
@ -6634,9 +6634,6 @@ BattleScript_DoSwitchOut::
|
||||
hidepartystatussummary BS_ATTACKER
|
||||
switchinanim BS_ATTACKER, FALSE
|
||||
waitstate
|
||||
jumpifcantreverttoprimal BattleScript_DoSwitchOut2
|
||||
call BattleScript_PrimalReversionRet
|
||||
BattleScript_DoSwitchOut2:
|
||||
switchineffects BS_ATTACKER
|
||||
moveendcase MOVEEND_STATUS_IMMUNITY_ABILITIES
|
||||
moveendcase MOVEEND_MIRROR_MOVE
|
||||
@ -7791,17 +7788,12 @@ BattleScript_WishMegaEvolution::
|
||||
goto BattleScript_MegaEvolutionAfterString
|
||||
|
||||
BattleScript_PrimalReversion::
|
||||
printstring STRINGID_EMPTYSTRING3
|
||||
waitmessage 1
|
||||
setbyte gIsCriticalHit, 0
|
||||
handleprimalreversion BS_ATTACKER, 0
|
||||
handleprimalreversion BS_ATTACKER, 1
|
||||
playanimation BS_ATTACKER, B_ANIM_PRIMAL_REVERSION
|
||||
waitanimation
|
||||
handleprimalreversion BS_ATTACKER, 2
|
||||
printstring STRINGID_PKMNREVERTEDTOPRIMAL
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
switchinabilities BS_ATTACKER
|
||||
call BattleScript_PrimalReversionRet
|
||||
end2
|
||||
|
||||
BattleScript_PrimalReversionRestoreAttacker::
|
||||
call BattleScript_PrimalReversionRet
|
||||
copybyte gBattlerAttacker, sSAVED_BATTLER
|
||||
end2
|
||||
|
||||
BattleScript_PrimalReversionRet::
|
||||
@ -7815,6 +7807,7 @@ BattleScript_PrimalReversionRet::
|
||||
handleprimalreversion BS_ATTACKER, 2
|
||||
printstring STRINGID_PKMNREVERTEDTOPRIMAL
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
switchinabilities BS_ATTACKER
|
||||
return
|
||||
|
||||
BattleScript_AttackerFormChange::
|
||||
|
@ -634,7 +634,7 @@ struct BattleStruct
|
||||
bool8 friskedAbility; // If identifies two mons, show the ability pop-up only once.
|
||||
u8 sameMoveTurns[MAX_BATTLERS_COUNT]; // For Metronome, number of times the same moves has been SUCCESFULLY used.
|
||||
u16 moveEffect2; // For Knock Off
|
||||
u16 changedSpecies[PARTY_SIZE]; // For Zygarde or future forms when multiple mons can change into the same pokemon.
|
||||
u16 changedSpecies[NUM_BATTLE_SIDES][PARTY_SIZE]; // For forms when multiple mons can change into the same pokemon.
|
||||
u8 quickClawBattlerId;
|
||||
struct LostItem itemLost[PARTY_SIZE]; // Player's team that had items consumed or stolen (two bytes per party member)
|
||||
u8 blunderPolicy:1; // should blunder policy activate
|
||||
|
@ -418,6 +418,7 @@ extern const u8 BattleScript_AttackWeakenedByStrongWinds[];
|
||||
extern const u8 BattleScript_BlockedByPrimalWeatherEnd3[];
|
||||
extern const u8 BattleScript_BlockedByPrimalWeatherRet[];
|
||||
extern const u8 BattleScript_PrimalReversion[];
|
||||
extern const u8 BattleScript_PrimalReversionRestoreAttacker[];
|
||||
extern const u8 BattleScript_HyperspaceFuryRemoveProtect[];
|
||||
extern const u8 BattleScript_SelectingNotAllowedMoveGorillaTactics[];
|
||||
extern const u8 BattleScript_SelectingNotAllowedMoveGorillaTacticsInPalace[];
|
||||
|
@ -142,6 +142,7 @@ u8 AtkCanceller_UnableToUseMove2(void);
|
||||
bool8 HasNoMonsToSwitch(u8 battlerId, u8 r1, u8 r2);
|
||||
bool32 TryChangeBattleWeather(u8 battler, u32 weatherEnumId, bool32 viaAbility);
|
||||
u8 AbilityBattleEffects(u8 caseID, u8 battlerId, u16 ability, u8 special, u16 moveArg);
|
||||
bool32 TryPrimalReversion(u8 battlerId);
|
||||
bool32 IsNeutralizingGasOnField(void);
|
||||
u32 GetBattlerAbility(u8 battlerId);
|
||||
u32 IsAbilityOnSide(u32 battlerId, u32 ability);
|
||||
@ -208,6 +209,7 @@ void BufferStatChange(u8 battlerId, u8 statId, u8 stringId);
|
||||
bool32 BlocksPrankster(u16 move, u8 battlerPrankster, u8 battlerDef, bool32 checkTarget);
|
||||
u16 GetUsedHeldItem(u8 battler);
|
||||
bool32 IsBattlerWeatherAffected(u8 battlerId, u32 weatherFlags);
|
||||
u32 ApplyWeatherDamageMultiplier(u8 battlerAtk, u16 move, u8 moveType, u32 dmg, u16 holdEffectAtk, u16 holdEffectDef);
|
||||
u32 GetBattlerMoveTargetType(u8 battlerId, u16 move);
|
||||
bool32 CanTargetBattler(u8 battlerAtk, u8 battlerDef, u16 move);
|
||||
bool8 IsMoveAffectedByParentalBond(u16 move, u8 battlerId);
|
||||
|
@ -10,6 +10,7 @@
|
||||
#define I_VITAMIN_EV_CAP GEN_LATEST // In Gen8+, the Vitamins no longer have a cap of 100 EV per stat.
|
||||
#define I_BERRY_EV_JUMP GEN_LATEST // In Gen4 only, EV-lowering Berries lower a stat's EV to 100 if it is above 100.
|
||||
#define I_GRISEOUS_ORB_FORM_CHANGE GEN_LATEST // In Gen9+, the Griseous Orb no longer changes Giratina's form when held.
|
||||
#define I_GEM_BOOST_POWER GEN_LATEST // In Gen5+, the Gem boost power was reduced from 50% to 30%.
|
||||
#define I_USE_EVO_HELD_ITEMS_FROM_BAG FALSE // If TRUE, items such as Razor Claw or Electirizer will be usable from the bag to evolve a Pokémon just like in LA.
|
||||
|
||||
// TM config
|
||||
|
@ -3875,14 +3875,9 @@ static void TryDoEventsBeforeFirstTurn(void)
|
||||
while (gBattleStruct->switchInAbilitiesCounter < gBattlersCount)
|
||||
{
|
||||
gBattlerAttacker = gBattlerByTurnOrder[gBattleStruct->switchInAbilitiesCounter++];
|
||||
|
||||
// Primal Reversion
|
||||
if (GetBattlerHoldEffect(gBattlerAttacker, TRUE) == HOLD_EFFECT_PRIMAL_ORB
|
||||
&& GetBattleFormChangeTargetSpecies(gBattlerAttacker, FORM_CHANGE_BATTLE_PRIMAL_REVERSION) != SPECIES_NONE)
|
||||
{
|
||||
BattleScriptExecute(BattleScript_PrimalReversion);
|
||||
|
||||
if (TryPrimalReversion(gBattlerAttacker))
|
||||
return;
|
||||
}
|
||||
if (AbilityBattleEffects(ABILITYEFFECT_ON_SWITCHIN, gBattlerAttacker, 0, 0, 0) != 0)
|
||||
return;
|
||||
}
|
||||
@ -5454,7 +5449,8 @@ static void HandleEndTurn_FinishBattle(void)
|
||||
changedForm = TryFormChange(i, B_SIDE_PLAYER, FORM_CHANGE_END_BATTLE);
|
||||
|
||||
// Clear original species field
|
||||
gBattleStruct->changedSpecies[i] = SPECIES_NONE;
|
||||
gBattleStruct->changedSpecies[B_SIDE_PLAYER][i] = SPECIES_NONE;
|
||||
gBattleStruct->changedSpecies[B_SIDE_OPPONENT][i] = SPECIES_NONE;
|
||||
|
||||
#if B_RECALCULATE_STATS >= GEN_5
|
||||
// Recalculate the stats of every party member before the end
|
||||
|
@ -6826,7 +6826,8 @@ static void SetDmgHazardsBattlescript(u8 battlerId, u8 multistringId)
|
||||
|
||||
bool32 DoSwitchInAbilitiesItems(u32 battlerId)
|
||||
{
|
||||
return (AbilityBattleEffects(ABILITYEFFECT_ON_SWITCHIN, battlerId, 0, 0, 0)
|
||||
return (TryPrimalReversion(battlerId)
|
||||
|| AbilityBattleEffects(ABILITYEFFECT_ON_SWITCHIN, battlerId, 0, 0, 0)
|
||||
|| (gBattleWeather & B_WEATHER_ANY && WEATHER_HAS_EFFECT && AbilityBattleEffects(ABILITYEFFECT_ON_WEATHER, battlerId, 0, 0, 0))
|
||||
|| (gFieldStatuses & STATUS_FIELD_TERRAIN_ANY && AbilityBattleEffects(ABILITYEFFECT_ON_TERRAIN, battlerId, 0, 0, 0))
|
||||
|| ItemBattleEffects(ITEMEFFECT_ON_SWITCH_IN, battlerId, FALSE)
|
||||
@ -10434,7 +10435,7 @@ static void Cmd_various(void)
|
||||
{
|
||||
gBattleStruct->battleBondTransformed[GET_BATTLER_SIDE2(gBattlerAttacker)] |= gBitTable[gBattlerPartyIndexes[gBattlerAttacker]];
|
||||
PREPARE_SPECIES_BUFFER(gBattleTextBuff1, gBattleMons[gBattlerAttacker].species);
|
||||
gBattleStruct->changedSpecies[gBattlerPartyIndexes[gBattlerAttacker]] = gBattleMons[gBattlerAttacker].species;
|
||||
gBattleStruct->changedSpecies[GET_BATTLER_SIDE2(gBattlerAttacker)][gBattlerPartyIndexes[gBattlerAttacker]] = gBattleMons[gBattlerAttacker].species;
|
||||
gBattleMons[gBattlerAttacker].species = SPECIES_GRENINJA_ASH;
|
||||
BattleScriptPushCursor();
|
||||
gBattlescriptCurrInstr = BattleScript_BattleBondActivatesOnMoveEndAttacker;
|
||||
|
@ -6040,6 +6040,27 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move
|
||||
return effect;
|
||||
}
|
||||
|
||||
bool32 TryPrimalReversion(u8 battlerId)
|
||||
{
|
||||
if (GetBattlerHoldEffect(battlerId, FALSE) == HOLD_EFFECT_PRIMAL_ORB
|
||||
&& GetBattleFormChangeTargetSpecies(battlerId, FORM_CHANGE_BATTLE_PRIMAL_REVERSION) != SPECIES_NONE)
|
||||
{
|
||||
if (gBattlerAttacker == battlerId)
|
||||
{
|
||||
BattleScriptExecute(BattleScript_PrimalReversion);
|
||||
}
|
||||
else
|
||||
{
|
||||
// edge case for scenarios like a switch-in after activated eject button
|
||||
gBattleScripting.savedBattler = gBattlerAttacker;
|
||||
gBattlerAttacker = battlerId;
|
||||
BattleScriptExecute(BattleScript_PrimalReversionRestoreAttacker);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
bool32 IsNeutralizingGasBannedAbility(u32 ability)
|
||||
{
|
||||
switch (ability)
|
||||
@ -8784,14 +8805,16 @@ static u32 CalcMoveBasePowerAfterModifiers(u16 move, u8 battlerAtk, u8 battlerDe
|
||||
case ABILITY_PROTOSYNTHESIS:
|
||||
{
|
||||
u8 atkHighestStat = GetHighestStatId(battlerAtk);
|
||||
if (gBattleWeather & B_WEATHER_SUN && WEATHER_HAS_EFFECT && (atkHighestStat == STAT_ATK || atkHighestStat == STAT_SPATK))
|
||||
if (gBattleWeather & B_WEATHER_SUN && WEATHER_HAS_EFFECT
|
||||
&& ((IS_MOVE_PHYSICAL(move) && atkHighestStat == STAT_ATK) || (IS_MOVE_SPECIAL(move) && atkHighestStat == STAT_SPATK)))
|
||||
modifier = uq4_12_multiply(modifier, UQ_4_12(1.3));
|
||||
}
|
||||
break;
|
||||
case ABILITY_QUARK_DRIVE:
|
||||
{
|
||||
u8 atkHighestStat = GetHighestStatId(battlerAtk);
|
||||
if (gFieldStatuses & STATUS_FIELD_ELECTRIC_TERRAIN && (atkHighestStat == STAT_ATK || atkHighestStat == STAT_SPATK))
|
||||
if (gFieldStatuses & STATUS_FIELD_ELECTRIC_TERRAIN
|
||||
&& ((IS_MOVE_PHYSICAL(move) && atkHighestStat == STAT_ATK) || (IS_MOVE_SPECIAL(move) && atkHighestStat == STAT_SPATK)))
|
||||
modifier = uq4_12_multiply(modifier, UQ_4_12(1.3));
|
||||
}
|
||||
break;
|
||||
@ -8882,14 +8905,16 @@ static u32 CalcMoveBasePowerAfterModifiers(u16 move, u8 battlerAtk, u8 battlerDe
|
||||
case ABILITY_PROTOSYNTHESIS:
|
||||
{
|
||||
u8 defHighestStat = GetHighestStatId(battlerDef);
|
||||
if (gBattleWeather & B_WEATHER_SUN && WEATHER_HAS_EFFECT && (defHighestStat == STAT_DEF || defHighestStat == STAT_SPDEF))
|
||||
if (gBattleWeather & B_WEATHER_SUN && WEATHER_HAS_EFFECT
|
||||
&& ((IS_MOVE_PHYSICAL(move) && defHighestStat == STAT_DEF) || (IS_MOVE_SPECIAL(move) && defHighestStat == STAT_SPDEF)))
|
||||
modifier = uq4_12_multiply(modifier, UQ_4_12(0.7));
|
||||
}
|
||||
break;
|
||||
case ABILITY_QUARK_DRIVE:
|
||||
{
|
||||
u8 defHighestStat = GetHighestStatId(battlerDef);
|
||||
if (gFieldStatuses & STATUS_FIELD_ELECTRIC_TERRAIN && (defHighestStat == STAT_DEF || defHighestStat == STAT_SPDEF))
|
||||
if (gFieldStatuses & STATUS_FIELD_ELECTRIC_TERRAIN
|
||||
&& ((IS_MOVE_PHYSICAL(move) && defHighestStat == STAT_DEF) || (IS_MOVE_SPECIAL(move) && defHighestStat == STAT_SPDEF)))
|
||||
modifier = uq4_12_multiply(modifier, UQ_4_12(0.7));
|
||||
}
|
||||
break;
|
||||
@ -8933,10 +8958,6 @@ static u32 CalcMoveBasePowerAfterModifiers(u16 move, u8 battlerAtk, u8 battlerDe
|
||||
#endif
|
||||
modifier = uq4_12_multiply(modifier, holdEffectModifier);
|
||||
break;
|
||||
case HOLD_EFFECT_GEMS:
|
||||
if (gSpecialStatuses[battlerAtk].gemBoost && gBattleMons[battlerAtk].item)
|
||||
modifier = uq4_12_multiply(modifier, UQ_4_12(1.0) + sPercentToModifier[gSpecialStatuses[battlerAtk].gemParam]);
|
||||
break;
|
||||
case HOLD_EFFECT_BUG_POWER:
|
||||
case HOLD_EFFECT_STEEL_POWER:
|
||||
case HOLD_EFFECT_GROUND_POWER:
|
||||
@ -9027,6 +9048,8 @@ static u32 CalcMoveBasePowerAfterModifiers(u16 move, u8 battlerAtk, u8 battlerDe
|
||||
// various effects
|
||||
if (gProtectStructs[battlerAtk].helpingHand)
|
||||
modifier = uq4_12_multiply(modifier, UQ_4_12(1.5));
|
||||
if (gSpecialStatuses[battlerAtk].gemBoost)
|
||||
modifier = uq4_12_multiply(modifier, UQ_4_12(1.0) + sPercentToModifier[gSpecialStatuses[battlerAtk].gemParam]);
|
||||
if (gStatuses3[battlerAtk] & STATUS3_CHARGED_UP && moveType == TYPE_ELECTRIC)
|
||||
modifier = uq4_12_multiply(modifier, UQ_4_12(2.0));
|
||||
if (gStatuses3[battlerAtk] & STATUS3_ME_FIRST)
|
||||
@ -9423,6 +9446,8 @@ static u32 CalcFinalDmg(u32 dmg, u16 move, u8 battlerAtk, u8 battlerDef, u8 move
|
||||
u32 defSide = GET_BATTLER_SIDE(battlerDef);
|
||||
uq4_12_t finalModifier = UQ_4_12(1.0);
|
||||
u16 itemDef = gBattleMons[battlerDef].item;
|
||||
u16 holdEffectAtk = GetBattlerHoldEffect(battlerAtk, TRUE);
|
||||
u16 holdEffectDef = GetBattlerHoldEffect(battlerDef, TRUE);
|
||||
|
||||
// check multiple targets in double battle
|
||||
if (GetMoveTargetCount(move, battlerAtk, battlerDef) >= 2)
|
||||
@ -9452,28 +9477,15 @@ static u32 CalcFinalDmg(u32 dmg, u16 move, u8 battlerAtk, u8 battlerDef, u8 move
|
||||
dmg = ApplyModifier(UQ_4_12(0.5), dmg);
|
||||
|
||||
// check frostbite
|
||||
if (gBattleMons[battlerAtk].status1 & STATUS1_FROSTBITE && !IS_MOVE_PHYSICAL(move)
|
||||
if (gBattleMons[battlerAtk].status1 & STATUS1_FROSTBITE && IS_MOVE_SPECIAL(move)
|
||||
#if B_BURN_FACADE_DMG >= GEN_6
|
||||
&& gBattleMoves[move].effect != EFFECT_FACADE
|
||||
#endif
|
||||
&& abilityAtk != ABILITY_GUTS)
|
||||
dmg = ApplyModifier(UQ_4_12(0.5), dmg);
|
||||
|
||||
// check sunny/rain weather
|
||||
if (IsBattlerWeatherAffected(battlerAtk, B_WEATHER_RAIN))
|
||||
{
|
||||
if (moveType == TYPE_FIRE)
|
||||
dmg = ApplyModifier(UQ_4_12(0.5), dmg);
|
||||
else if (moveType == TYPE_WATER)
|
||||
dmg = ApplyModifier(UQ_4_12(1.5), dmg);
|
||||
}
|
||||
else if (IsBattlerWeatherAffected(battlerAtk, B_WEATHER_SUN))
|
||||
{
|
||||
if (moveType == TYPE_FIRE || gBattleMoves[move].effect == EFFECT_HYDRO_STEAM)
|
||||
dmg = ApplyModifier(UQ_4_12(1.5), dmg);
|
||||
else if (moveType == TYPE_WATER)
|
||||
dmg = ApplyModifier(UQ_4_12(0.5), dmg);
|
||||
}
|
||||
// check weather
|
||||
dmg = ApplyWeatherDamageMultiplier(battlerAtk, move, moveType, dmg, holdEffectAtk, holdEffectDef);
|
||||
|
||||
// check stab
|
||||
if (IS_BATTLER_OF_TYPE(battlerAtk, moveType) && move != MOVE_STRUGGLE && move != MOVE_NONE)
|
||||
@ -9562,7 +9574,7 @@ static u32 CalcFinalDmg(u32 dmg, u16 move, u8 battlerAtk, u8 battlerDef, u8 move
|
||||
}
|
||||
|
||||
// attacker's hold effect
|
||||
switch (GetBattlerHoldEffect(battlerAtk, TRUE))
|
||||
switch (holdEffectAtk)
|
||||
{
|
||||
case HOLD_EFFECT_METRONOME:
|
||||
percentBoost = min((gBattleStruct->sameMoveTurns[battlerAtk] * GetBattlerHoldEffectParam(battlerAtk)), 100);
|
||||
@ -9578,7 +9590,7 @@ static u32 CalcFinalDmg(u32 dmg, u16 move, u8 battlerAtk, u8 battlerDef, u8 move
|
||||
}
|
||||
|
||||
// target's hold effect
|
||||
switch (GetBattlerHoldEffect(battlerDef, TRUE))
|
||||
switch (holdEffectDef)
|
||||
{
|
||||
// berries reducing dmg
|
||||
case HOLD_EFFECT_RESIST_BERRY:
|
||||
@ -10152,8 +10164,8 @@ bool32 TryBattleFormChange(u8 battlerId, u16 method)
|
||||
if (targetSpecies != SPECIES_NONE)
|
||||
{
|
||||
// Saves the original species on the first form change for the player.
|
||||
if (side == B_SIDE_PLAYER && gBattleStruct->changedSpecies[monId] == SPECIES_NONE)
|
||||
gBattleStruct->changedSpecies[monId] = gBattleMons[battlerId].species;
|
||||
if (gBattleStruct->changedSpecies[side][monId] == SPECIES_NONE)
|
||||
gBattleStruct->changedSpecies[side][monId] = gBattleMons[battlerId].species;
|
||||
|
||||
TryToSetBattleFormChangeMoves(&party[monId], method);
|
||||
SetMonData(&party[monId], MON_DATA_SPECIES, &targetSpecies);
|
||||
@ -10161,7 +10173,7 @@ bool32 TryBattleFormChange(u8 battlerId, u16 method)
|
||||
RecalcBattlerStats(battlerId, &party[monId]);
|
||||
return TRUE;
|
||||
}
|
||||
else if (gBattleStruct->changedSpecies[monId] != SPECIES_NONE)
|
||||
else if (gBattleStruct->changedSpecies[side][monId] != SPECIES_NONE)
|
||||
{
|
||||
bool8 restoreSpecies = FALSE;
|
||||
|
||||
@ -10177,7 +10189,7 @@ bool32 TryBattleFormChange(u8 battlerId, u16 method)
|
||||
{
|
||||
// Reverts the original species
|
||||
TryToSetBattleFormChangeMoves(&party[monId], method);
|
||||
SetMonData(&party[monId], MON_DATA_SPECIES, &gBattleStruct->changedSpecies[monId]);
|
||||
SetMonData(&party[monId], MON_DATA_SPECIES, &gBattleStruct->changedSpecies[side][monId]);
|
||||
RecalcBattlerStats(battlerId, &party[monId]);
|
||||
return TRUE;
|
||||
}
|
||||
@ -10765,6 +10777,34 @@ bool32 IsBattlerWeatherAffected(u8 battlerId, u32 weatherFlags)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Utility Umbrella holders take normal damage from what would be rain- and sun-weakened attacks.
|
||||
u32 ApplyWeatherDamageMultiplier(u8 battlerAtk, u16 move, u8 moveType, u32 dmg, u16 holdEffectAtk, u16 holdEffectDef)
|
||||
{
|
||||
if (WEATHER_HAS_EFFECT)
|
||||
{
|
||||
if (gBattleMoves[move].effect == EFFECT_HYDRO_STEAM && (gBattleWeather & B_WEATHER_SUN) && holdEffectAtk != HOLD_EFFECT_UTILITY_UMBRELLA)
|
||||
dmg = ApplyModifier(UQ_4_12(1.5), dmg);
|
||||
else if (holdEffectDef != HOLD_EFFECT_UTILITY_UMBRELLA)
|
||||
{
|
||||
if (gBattleWeather & B_WEATHER_RAIN)
|
||||
{
|
||||
if (moveType == TYPE_FIRE)
|
||||
dmg = ApplyModifier(UQ_4_12(0.5), dmg);
|
||||
else if (moveType == TYPE_WATER)
|
||||
dmg = ApplyModifier(UQ_4_12(1.5), dmg);
|
||||
}
|
||||
else if (gBattleWeather & B_WEATHER_SUN)
|
||||
{
|
||||
if (moveType == TYPE_FIRE)
|
||||
dmg = ApplyModifier(UQ_4_12(1.5), dmg);
|
||||
else if (moveType == TYPE_WATER)
|
||||
dmg = ApplyModifier(UQ_4_12(0.5), dmg);
|
||||
}
|
||||
}
|
||||
}
|
||||
return dmg;
|
||||
}
|
||||
|
||||
// Gets move target before redirection effects etc. are applied
|
||||
// Possible return values are defined in battle.h following MOVE_TARGET_SELECTED
|
||||
u32 GetBattlerMoveTargetType(u8 battlerId, u16 move)
|
||||
|
@ -6,6 +6,12 @@
|
||||
#define EVO_HELD_ITEM_FIELD_FUNC ItemUseOutOfBattle_CannotUse
|
||||
#endif
|
||||
|
||||
#if I_GEM_BOOST_POWER >= GEN_5
|
||||
#define GEM_BOOST_PARAM 30
|
||||
#else
|
||||
#define GEM_BOOST_PARAM 50
|
||||
#endif
|
||||
|
||||
const struct Item gItems[] =
|
||||
{
|
||||
[ITEM_NONE] =
|
||||
@ -4416,7 +4422,7 @@ const struct Item gItems[] =
|
||||
.itemId = ITEM_NORMAL_GEM,
|
||||
.price = 4000,
|
||||
.holdEffect = HOLD_EFFECT_GEMS,
|
||||
.holdEffectParam = 30,
|
||||
.holdEffectParam = GEM_BOOST_PARAM,
|
||||
.description = sNormalGemDesc,
|
||||
.pocket = POCKET_ITEMS,
|
||||
.type = ITEM_USE_BAG_MENU,
|
||||
@ -4430,7 +4436,7 @@ const struct Item gItems[] =
|
||||
.itemId = ITEM_FIRE_GEM,
|
||||
.price = 4000,
|
||||
.holdEffect = HOLD_EFFECT_GEMS,
|
||||
.holdEffectParam = 30,
|
||||
.holdEffectParam = GEM_BOOST_PARAM,
|
||||
.description = sFireGemDesc,
|
||||
.pocket = POCKET_ITEMS,
|
||||
.type = ITEM_USE_BAG_MENU,
|
||||
@ -4444,7 +4450,7 @@ const struct Item gItems[] =
|
||||
.itemId = ITEM_WATER_GEM,
|
||||
.price = 4000,
|
||||
.holdEffect = HOLD_EFFECT_GEMS,
|
||||
.holdEffectParam = 30,
|
||||
.holdEffectParam = GEM_BOOST_PARAM,
|
||||
.description = sWaterGemDesc,
|
||||
.pocket = POCKET_ITEMS,
|
||||
.type = ITEM_USE_BAG_MENU,
|
||||
@ -4458,7 +4464,7 @@ const struct Item gItems[] =
|
||||
.itemId = ITEM_ELECTRIC_GEM,
|
||||
.price = 4000,
|
||||
.holdEffect = HOLD_EFFECT_GEMS,
|
||||
.holdEffectParam = 30,
|
||||
.holdEffectParam = GEM_BOOST_PARAM,
|
||||
.description = sElectricGemDesc,
|
||||
.pocket = POCKET_ITEMS,
|
||||
.type = ITEM_USE_BAG_MENU,
|
||||
@ -4472,7 +4478,7 @@ const struct Item gItems[] =
|
||||
.itemId = ITEM_GRASS_GEM,
|
||||
.price = 4000,
|
||||
.holdEffect = HOLD_EFFECT_GEMS,
|
||||
.holdEffectParam = 30,
|
||||
.holdEffectParam = GEM_BOOST_PARAM,
|
||||
.description = sGrassGemDesc,
|
||||
.pocket = POCKET_ITEMS,
|
||||
.type = ITEM_USE_BAG_MENU,
|
||||
@ -4486,7 +4492,7 @@ const struct Item gItems[] =
|
||||
.itemId = ITEM_ICE_GEM,
|
||||
.price = 4000,
|
||||
.holdEffect = HOLD_EFFECT_GEMS,
|
||||
.holdEffectParam = 30,
|
||||
.holdEffectParam = GEM_BOOST_PARAM,
|
||||
.description = sIceGemDesc,
|
||||
.pocket = POCKET_ITEMS,
|
||||
.type = ITEM_USE_BAG_MENU,
|
||||
@ -4500,7 +4506,7 @@ const struct Item gItems[] =
|
||||
.itemId = ITEM_FIGHTING_GEM,
|
||||
.price = 4000,
|
||||
.holdEffect = HOLD_EFFECT_GEMS,
|
||||
.holdEffectParam = 30,
|
||||
.holdEffectParam = GEM_BOOST_PARAM,
|
||||
.description = sFightingGemDesc,
|
||||
.pocket = POCKET_ITEMS,
|
||||
.type = ITEM_USE_BAG_MENU,
|
||||
@ -4514,7 +4520,7 @@ const struct Item gItems[] =
|
||||
.itemId = ITEM_POISON_GEM,
|
||||
.price = 4000,
|
||||
.holdEffect = HOLD_EFFECT_GEMS,
|
||||
.holdEffectParam = 30,
|
||||
.holdEffectParam = GEM_BOOST_PARAM,
|
||||
.description = sPoisonGemDesc,
|
||||
.pocket = POCKET_ITEMS,
|
||||
.type = ITEM_USE_BAG_MENU,
|
||||
@ -4528,7 +4534,7 @@ const struct Item gItems[] =
|
||||
.itemId = ITEM_GROUND_GEM,
|
||||
.price = 4000,
|
||||
.holdEffect = HOLD_EFFECT_GEMS,
|
||||
.holdEffectParam = 30,
|
||||
.holdEffectParam = GEM_BOOST_PARAM,
|
||||
.description = sGroundGemDesc,
|
||||
.pocket = POCKET_ITEMS,
|
||||
.type = ITEM_USE_BAG_MENU,
|
||||
@ -4542,7 +4548,7 @@ const struct Item gItems[] =
|
||||
.itemId = ITEM_FLYING_GEM,
|
||||
.price = 4000,
|
||||
.holdEffect = HOLD_EFFECT_GEMS,
|
||||
.holdEffectParam = 30,
|
||||
.holdEffectParam = GEM_BOOST_PARAM,
|
||||
.description = sFlyingGemDesc,
|
||||
.pocket = POCKET_ITEMS,
|
||||
.type = ITEM_USE_BAG_MENU,
|
||||
@ -4556,7 +4562,7 @@ const struct Item gItems[] =
|
||||
.itemId = ITEM_PSYCHIC_GEM,
|
||||
.price = 4000,
|
||||
.holdEffect = HOLD_EFFECT_GEMS,
|
||||
.holdEffectParam = 30,
|
||||
.holdEffectParam = GEM_BOOST_PARAM,
|
||||
.description = sPsychicGemDesc,
|
||||
.pocket = POCKET_ITEMS,
|
||||
.type = ITEM_USE_BAG_MENU,
|
||||
@ -4570,7 +4576,7 @@ const struct Item gItems[] =
|
||||
.itemId = ITEM_BUG_GEM,
|
||||
.price = 4000,
|
||||
.holdEffect = HOLD_EFFECT_GEMS,
|
||||
.holdEffectParam = 30,
|
||||
.holdEffectParam = GEM_BOOST_PARAM,
|
||||
.description = sBugGemDesc,
|
||||
.pocket = POCKET_ITEMS,
|
||||
.type = ITEM_USE_BAG_MENU,
|
||||
@ -4584,7 +4590,7 @@ const struct Item gItems[] =
|
||||
.itemId = ITEM_ROCK_GEM,
|
||||
.price = 4000,
|
||||
.holdEffect = HOLD_EFFECT_GEMS,
|
||||
.holdEffectParam = 30,
|
||||
.holdEffectParam = GEM_BOOST_PARAM,
|
||||
.description = sRockGemDesc,
|
||||
.pocket = POCKET_ITEMS,
|
||||
.type = ITEM_USE_BAG_MENU,
|
||||
@ -4598,7 +4604,7 @@ const struct Item gItems[] =
|
||||
.itemId = ITEM_GHOST_GEM,
|
||||
.price = 4000,
|
||||
.holdEffect = HOLD_EFFECT_GEMS,
|
||||
.holdEffectParam = 30,
|
||||
.holdEffectParam = GEM_BOOST_PARAM,
|
||||
.description = sGhostGemDesc,
|
||||
.pocket = POCKET_ITEMS,
|
||||
.type = ITEM_USE_BAG_MENU,
|
||||
@ -4612,7 +4618,7 @@ const struct Item gItems[] =
|
||||
.itemId = ITEM_DRAGON_GEM,
|
||||
.price = 4000,
|
||||
.holdEffect = HOLD_EFFECT_GEMS,
|
||||
.holdEffectParam = 30,
|
||||
.holdEffectParam = GEM_BOOST_PARAM,
|
||||
.description = sDragonGemDesc,
|
||||
.pocket = POCKET_ITEMS,
|
||||
.type = ITEM_USE_BAG_MENU,
|
||||
@ -4626,7 +4632,7 @@ const struct Item gItems[] =
|
||||
.itemId = ITEM_DARK_GEM,
|
||||
.price = 4000,
|
||||
.holdEffect = HOLD_EFFECT_GEMS,
|
||||
.holdEffectParam = 30,
|
||||
.holdEffectParam = GEM_BOOST_PARAM,
|
||||
.description = sDarkGemDesc,
|
||||
.pocket = POCKET_ITEMS,
|
||||
.type = ITEM_USE_BAG_MENU,
|
||||
@ -4640,7 +4646,7 @@ const struct Item gItems[] =
|
||||
.itemId = ITEM_STEEL_GEM,
|
||||
.price = 4000,
|
||||
.holdEffect = HOLD_EFFECT_GEMS,
|
||||
.holdEffectParam = 30,
|
||||
.holdEffectParam = GEM_BOOST_PARAM,
|
||||
.description = sSteelGemDesc,
|
||||
.pocket = POCKET_ITEMS,
|
||||
.type = ITEM_USE_BAG_MENU,
|
||||
@ -4654,7 +4660,7 @@ const struct Item gItems[] =
|
||||
.itemId = ITEM_FAIRY_GEM,
|
||||
.price = 4000,
|
||||
.holdEffect = HOLD_EFFECT_GEMS,
|
||||
.holdEffectParam = 30,
|
||||
.holdEffectParam = GEM_BOOST_PARAM,
|
||||
.description = sFairyGemDesc,
|
||||
.pocket = POCKET_ITEMS,
|
||||
.type = ITEM_USE_BAG_MENU,
|
||||
|
@ -8549,7 +8549,7 @@ bool32 TryFormChange(u32 monId, u32 side, u16 method)
|
||||
targetSpecies = GetFormChangeTargetSpecies(&party[monId], method, 0);
|
||||
|
||||
if (targetSpecies == SPECIES_NONE && gBattleStruct != NULL)
|
||||
targetSpecies = gBattleStruct->changedSpecies[monId];
|
||||
targetSpecies = gBattleStruct->changedSpecies[side][monId];
|
||||
|
||||
if (targetSpecies != SPECIES_NONE)
|
||||
{
|
||||
|
87
test/ability_protosynthesis.c
Normal file
87
test/ability_protosynthesis.c
Normal file
@ -0,0 +1,87 @@
|
||||
#include "global.h"
|
||||
#include "test_battle.h"
|
||||
|
||||
ASSUMPTIONS
|
||||
{
|
||||
ASSUME(gBattleMoves[MOVE_TACKLE].split == SPLIT_PHYSICAL);
|
||||
ASSUME(gBattleMoves[MOVE_ROUND].split == SPLIT_SPECIAL);
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Protosynthesis boosts the highest stat")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_ABRA) { Ability(ABILITY_PROTOSYNTHESIS); }
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_SUNNY_DAY); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_SUNNY_DAY, player);
|
||||
ABILITY_POPUP(player, ABILITY_PROTOSYNTHESIS);
|
||||
MESSAGE("The harsh sunlight activated Abra's Protosynthesis!");
|
||||
MESSAGE("Abra's Sp. Atk was heightened!");
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Protosynthesis boosts either Attack or Special Attack, not both")
|
||||
{
|
||||
u16 species;
|
||||
u32 move;
|
||||
u16 damage[2];
|
||||
|
||||
PARAMETRIZE { species = SPECIES_BELLSPROUT; move = MOVE_TACKLE; }
|
||||
PARAMETRIZE { species = SPECIES_BELLSPROUT; move = MOVE_ROUND; }
|
||||
|
||||
PARAMETRIZE { species = SPECIES_ABRA; move = MOVE_TACKLE; }
|
||||
PARAMETRIZE { species = SPECIES_ABRA; move = MOVE_ROUND; }
|
||||
|
||||
GIVEN {
|
||||
PLAYER(species) { Ability(ABILITY_PROTOSYNTHESIS); }
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(player, move); }
|
||||
TURN { MOVE(opponent, MOVE_SUNNY_DAY); MOVE(player, move); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, move, player);
|
||||
HP_BAR(opponent, captureDamage: &damage[0]);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_SUNNY_DAY, opponent);
|
||||
ANIMATION(ANIM_TYPE_MOVE, move, player);
|
||||
HP_BAR(opponent, captureDamage: &damage[1]);
|
||||
} THEN {
|
||||
if ((move == MOVE_TACKLE && species == SPECIES_BELLSPROUT) || (move == MOVE_ROUND && species == SPECIES_ABRA))
|
||||
EXPECT_MUL_EQ(damage[0], Q_4_12(1.3), damage[1]);
|
||||
else
|
||||
EXPECT_EQ(damage[0], damage[1]);
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Protosynthesis either boosts Defense or Special Defense, not both")
|
||||
{
|
||||
u16 species;
|
||||
u32 move;
|
||||
u16 damage[2];
|
||||
|
||||
PARAMETRIZE { species = SPECIES_ONIX; move = MOVE_TACKLE; }
|
||||
PARAMETRIZE { species = SPECIES_ONIX; move = MOVE_ROUND; }
|
||||
|
||||
PARAMETRIZE { species = SPECIES_BLASTOISE; move = MOVE_TACKLE; }
|
||||
PARAMETRIZE { species = SPECIES_BLASTOISE; move = MOVE_ROUND; }
|
||||
|
||||
GIVEN {
|
||||
PLAYER(species) { Ability(ABILITY_PROTOSYNTHESIS); }
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(opponent, move); }
|
||||
TURN { MOVE(player, MOVE_SUNNY_DAY); MOVE(opponent, move); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, move, opponent);
|
||||
HP_BAR(player, captureDamage: &damage[0]);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_SUNNY_DAY, player);
|
||||
ANIMATION(ANIM_TYPE_MOVE, move, opponent);
|
||||
HP_BAR(player, captureDamage: &damage[1]);
|
||||
} THEN {
|
||||
if ((move == MOVE_TACKLE && species == SPECIES_ONIX) || (move == MOVE_ROUND && species == SPECIES_BLASTOISE))
|
||||
EXPECT_MUL_EQ(damage[0], Q_4_12(0.7), damage[1]);
|
||||
else
|
||||
EXPECT_EQ(damage[0], damage[1]);
|
||||
}
|
||||
}
|
87
test/ability_quark_drive.c
Normal file
87
test/ability_quark_drive.c
Normal file
@ -0,0 +1,87 @@
|
||||
#include "global.h"
|
||||
#include "test_battle.h"
|
||||
|
||||
ASSUMPTIONS
|
||||
{
|
||||
ASSUME(gBattleMoves[MOVE_TACKLE].split == SPLIT_PHYSICAL);
|
||||
ASSUME(gBattleMoves[MOVE_ROUND].split == SPLIT_SPECIAL);
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Quark Drive boosts the highest stat")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_ABRA) { Ability(ABILITY_QUARK_DRIVE); }
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_ELECTRIC_TERRAIN); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_ELECTRIC_TERRAIN, player);
|
||||
ABILITY_POPUP(player, ABILITY_QUARK_DRIVE);
|
||||
MESSAGE("The Electric Terrain activated Abra's Quark Drive!");
|
||||
MESSAGE("Abra's Sp. Atk was heightened!");
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Quark Drive boosts either Attack or Special Attack, not both")
|
||||
{
|
||||
u16 species;
|
||||
u32 move;
|
||||
u16 damage[2];
|
||||
|
||||
PARAMETRIZE { species = SPECIES_BELLSPROUT; move = MOVE_TACKLE; }
|
||||
PARAMETRIZE { species = SPECIES_BELLSPROUT; move = MOVE_ROUND; }
|
||||
|
||||
PARAMETRIZE { species = SPECIES_ABRA; move = MOVE_TACKLE; }
|
||||
PARAMETRIZE { species = SPECIES_ABRA; move = MOVE_ROUND; }
|
||||
|
||||
GIVEN {
|
||||
PLAYER(species) { Ability(ABILITY_QUARK_DRIVE); }
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(player, move); }
|
||||
TURN { MOVE(opponent, MOVE_ELECTRIC_TERRAIN); MOVE(player, move); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, move, player);
|
||||
HP_BAR(opponent, captureDamage: &damage[0]);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_ELECTRIC_TERRAIN, opponent);
|
||||
ANIMATION(ANIM_TYPE_MOVE, move, player);
|
||||
HP_BAR(opponent, captureDamage: &damage[1]);
|
||||
} THEN {
|
||||
if ((move == MOVE_TACKLE && species == SPECIES_BELLSPROUT) || (move == MOVE_ROUND && species == SPECIES_ABRA))
|
||||
EXPECT_MUL_EQ(damage[0], Q_4_12(1.3), damage[1]);
|
||||
else
|
||||
EXPECT_EQ(damage[0], damage[1]);
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Quark Drive either boosts Defense or Special Defense, not both")
|
||||
{
|
||||
u16 species;
|
||||
u32 move;
|
||||
u16 damage[2];
|
||||
|
||||
PARAMETRIZE { species = SPECIES_ONIX; move = MOVE_TACKLE; }
|
||||
PARAMETRIZE { species = SPECIES_ONIX; move = MOVE_ROUND; }
|
||||
|
||||
PARAMETRIZE { species = SPECIES_BLASTOISE; move = MOVE_TACKLE; }
|
||||
PARAMETRIZE { species = SPECIES_BLASTOISE; move = MOVE_ROUND; }
|
||||
|
||||
GIVEN {
|
||||
PLAYER(species) { Ability(ABILITY_QUARK_DRIVE); }
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(opponent, move); }
|
||||
TURN { MOVE(player, MOVE_ELECTRIC_TERRAIN); MOVE(opponent, move); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, move, opponent);
|
||||
HP_BAR(player, captureDamage: &damage[0]);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_ELECTRIC_TERRAIN, player);
|
||||
ANIMATION(ANIM_TYPE_MOVE, move, opponent);
|
||||
HP_BAR(player, captureDamage: &damage[1]);
|
||||
} THEN {
|
||||
if ((move == MOVE_TACKLE && species == SPECIES_ONIX) || (move == MOVE_ROUND && species == SPECIES_BLASTOISE))
|
||||
EXPECT_MUL_EQ(damage[0], Q_4_12(0.7), damage[1]);
|
||||
else
|
||||
EXPECT_EQ(damage[0], damage[1]);
|
||||
}
|
||||
}
|
89
test/hold_effect_gems.c
Normal file
89
test/hold_effect_gems.c
Normal file
@ -0,0 +1,89 @@
|
||||
#include "global.h"
|
||||
#include "test_battle.h"
|
||||
|
||||
ASSUMPTIONS
|
||||
{
|
||||
ASSUME(gItems[ITEM_NORMAL_GEM].holdEffect == HOLD_EFFECT_GEMS);
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Gem is consumed when it corresponds to the type of a move")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_NORMAL_GEM); };
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_EMBER); }
|
||||
TURN { MOVE(player, MOVE_TACKLE); }
|
||||
} SCENE {
|
||||
NONE_OF {
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, player);
|
||||
MESSAGE("Fire Gem strengthened Wobbuffet's power!");
|
||||
}
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_EMBER, player);
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, player);
|
||||
MESSAGE("Normal Gem strengthened Wobbuffet's power!");
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, player);
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Gem boost is only applied once")
|
||||
{
|
||||
s16 boostedHit;
|
||||
s16 normalHit;
|
||||
|
||||
GIVEN {
|
||||
ASSUME(I_GEM_BOOST_POWER >= GEN_5);
|
||||
PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_NORMAL_GEM); };
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_TACKLE); }
|
||||
TURN { MOVE(player, MOVE_TACKLE); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, player);
|
||||
MESSAGE("Normal Gem strengthened Wobbuffet's power!");
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, player);
|
||||
HP_BAR(opponent, captureDamage: &boostedHit);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, player);
|
||||
HP_BAR(opponent, captureDamage: &normalHit);
|
||||
} THEN {
|
||||
EXPECT_MUL_EQ(normalHit, Q_4_12(1.3), boostedHit);
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Gem modifier is used for all hits of Multi Hit Moves")
|
||||
{
|
||||
s16 firstHit;
|
||||
s16 secondHit;
|
||||
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_NORMAL_GEM); };
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN {
|
||||
MOVE(player, MOVE_DOUBLE_HIT);
|
||||
}
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_DOUBLE_HIT, player);
|
||||
HP_BAR(opponent, captureDamage: &firstHit);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_DOUBLE_HIT, player);
|
||||
HP_BAR(opponent, captureDamage: &secondHit);
|
||||
} THEN {
|
||||
EXPECT_EQ(firstHit, secondHit);
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Gem is consumed if the move type is changed")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_DELCATTY) { Ability(ABILITY_NORMALIZE); Item(ITEM_NORMAL_GEM); };
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN {
|
||||
MOVE(player, MOVE_FEINT_ATTACK);
|
||||
}
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, player);
|
||||
MESSAGE("Normal Gem strengthened Delcatty's power!");
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_FEINT_ATTACK, player);
|
||||
}
|
||||
}
|
54
test/hold_effect_utility_umbrella.c
Normal file
54
test/hold_effect_utility_umbrella.c
Normal file
@ -0,0 +1,54 @@
|
||||
#include "global.h"
|
||||
#include "test_battle.h"
|
||||
|
||||
// Please add Utility Umbrella interactions with move, item and ability effects on their respective files.
|
||||
ASSUMPTIONS
|
||||
{
|
||||
ASSUME(gItems[ITEM_UTILITY_UMBRELLA].holdEffect == HOLD_EFFECT_UTILITY_UMBRELLA);
|
||||
ASSUME(gBattleMoves[MOVE_EMBER].type == TYPE_FIRE);
|
||||
ASSUME(gBattleMoves[MOVE_WATER_GUN].type == TYPE_WATER);
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Utility Umbrella blocks Sun damage modifiers", s16 damage)
|
||||
{
|
||||
u16 setupMove, attackingMove, heldItem;
|
||||
PARAMETRIZE { setupMove = MOVE_SUNNY_DAY; attackingMove = MOVE_EMBER; heldItem = ITEM_UTILITY_UMBRELLA; }
|
||||
PARAMETRIZE { setupMove = MOVE_SUNNY_DAY; attackingMove = MOVE_EMBER; heldItem = ITEM_NONE; }
|
||||
PARAMETRIZE { setupMove = MOVE_SUNNY_DAY; attackingMove = MOVE_WATER_GUN; heldItem = ITEM_UTILITY_UMBRELLA; }
|
||||
PARAMETRIZE { setupMove = MOVE_SUNNY_DAY; attackingMove = MOVE_WATER_GUN; heldItem = ITEM_NONE; }
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WOBBUFFET) { Item(heldItem); };
|
||||
} WHEN {
|
||||
TURN { MOVE(opponent, setupMove); }
|
||||
TURN { MOVE(player, attackingMove); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, attackingMove, player);
|
||||
HP_BAR(opponent, captureDamage: &results[i].damage);
|
||||
} FINALLY {
|
||||
EXPECT_MUL_EQ(results[0].damage, Q_4_12(1.5), results[1].damage);
|
||||
EXPECT_MUL_EQ(results[2].damage, Q_4_12(0.5), results[3].damage);
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Utility Umbrella blocks Rain damage modifiers", s16 damage)
|
||||
{
|
||||
u16 setupMove, attackingMove, heldItem;
|
||||
PARAMETRIZE { setupMove = MOVE_RAIN_DANCE; attackingMove = MOVE_EMBER; heldItem = ITEM_UTILITY_UMBRELLA; }
|
||||
PARAMETRIZE { setupMove = MOVE_RAIN_DANCE; attackingMove = MOVE_EMBER; heldItem = ITEM_NONE; }
|
||||
PARAMETRIZE { setupMove = MOVE_RAIN_DANCE; attackingMove = MOVE_WATER_GUN; heldItem = ITEM_UTILITY_UMBRELLA; }
|
||||
PARAMETRIZE { setupMove = MOVE_RAIN_DANCE; attackingMove = MOVE_WATER_GUN; heldItem = ITEM_NONE; }
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WOBBUFFET) { Item(heldItem); };
|
||||
} WHEN {
|
||||
TURN { MOVE(opponent, setupMove); }
|
||||
TURN { MOVE(player, attackingMove); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, attackingMove, player);
|
||||
HP_BAR(opponent, captureDamage: &results[i].damage);
|
||||
} FINALLY {
|
||||
EXPECT_MUL_EQ(results[0].damage, Q_4_12(0.5), results[1].damage);
|
||||
EXPECT_MUL_EQ(results[2].damage, Q_4_12(1.5), results[3].damage);
|
||||
}
|
||||
}
|
50
test/move_effect_hydro_steam.c
Normal file
50
test/move_effect_hydro_steam.c
Normal file
@ -0,0 +1,50 @@
|
||||
#include "global.h"
|
||||
#include "test_battle.h"
|
||||
|
||||
ASSUMPTIONS
|
||||
{
|
||||
ASSUME(gBattleMoves[MOVE_HYDRO_STEAM].effect == EFFECT_HYDRO_STEAM);
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Hydro Steam deals 1.5x damage under both Sunlight and Rain", s16 damage)
|
||||
{
|
||||
u16 setupMove;
|
||||
PARAMETRIZE { setupMove = MOVE_CELEBRATE; }
|
||||
PARAMETRIZE { setupMove = MOVE_SUNNY_DAY; }
|
||||
PARAMETRIZE { setupMove = MOVE_RAIN_DANCE; }
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(player, setupMove); }
|
||||
TURN { MOVE(player, MOVE_HYDRO_STEAM); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_HYDRO_STEAM, player);
|
||||
HP_BAR(opponent, captureDamage: &results[i].damage);
|
||||
} FINALLY {
|
||||
EXPECT_MUL_EQ(results[0].damage, Q_4_12(1.5), results[2].damage);
|
||||
EXPECT_MUL_EQ(results[0].damage, Q_4_12(1.5), results[1].damage);
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Hydro Steam is affected by Utility Umbrella", s16 damage)
|
||||
{
|
||||
u32 itemPlayer;
|
||||
u32 itemOpponent;
|
||||
PARAMETRIZE { itemPlayer = ITEM_UTILITY_UMBRELLA; itemOpponent = ITEM_NONE; }
|
||||
PARAMETRIZE { itemPlayer = ITEM_NONE; itemOpponent = ITEM_UTILITY_UMBRELLA; }
|
||||
PARAMETRIZE { itemPlayer = ITEM_UTILITY_UMBRELLA; itemOpponent = ITEM_UTILITY_UMBRELLA; }
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET) { Item(itemPlayer); };
|
||||
OPPONENT(SPECIES_WOBBUFFET) {Item(itemOpponent); };
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_SUNNY_DAY); }
|
||||
TURN { MOVE(player, MOVE_HYDRO_STEAM); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_HYDRO_STEAM, player);
|
||||
HP_BAR(opponent, captureDamage: &results[i].damage);
|
||||
} FINALLY {
|
||||
EXPECT_MUL_EQ(results[2].damage, Q_4_12(1.5), results[1].damage);
|
||||
EXPECT_MUL_EQ(results[2].damage, Q_4_12(0.5), results[0].damage);
|
||||
}
|
||||
}
|
216
test/primal_reversion.c
Normal file
216
test/primal_reversion.c
Normal file
@ -0,0 +1,216 @@
|
||||
#include "global.h"
|
||||
#include "test_battle.h"
|
||||
|
||||
SINGLE_BATTLE_TEST("Primal reversion happens for Groudon only when holding Red Orb")
|
||||
{
|
||||
u16 heldItem;
|
||||
PARAMETRIZE { heldItem = ITEM_NONE;}
|
||||
PARAMETRIZE { heldItem = ITEM_RED_ORB;}
|
||||
PARAMETRIZE { heldItem = ITEM_BLUE_ORB;}
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_GROUDON) { Item(heldItem); }
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_CELEBRATE); }
|
||||
} SCENE {
|
||||
if (heldItem == ITEM_RED_ORB) {
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_PRIMAL_REVERSION, player);
|
||||
MESSAGE("Groudon's Primal Reversion! It reverted to its primal form!");
|
||||
}
|
||||
else {
|
||||
NONE_OF {
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_PRIMAL_REVERSION, player);
|
||||
MESSAGE("Groudon's Primal Reversion! It reverted to its primal form!");
|
||||
}
|
||||
}
|
||||
} THEN {
|
||||
if (heldItem == ITEM_RED_ORB) {
|
||||
EXPECT_EQ(player->species, SPECIES_GROUDON_PRIMAL);
|
||||
}
|
||||
else {
|
||||
EXPECT_EQ(player->species, SPECIES_GROUDON);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Primal reversion happens for Kyogre only when holding Blue Orb")
|
||||
{
|
||||
u16 heldItem;
|
||||
PARAMETRIZE { heldItem = ITEM_NONE;}
|
||||
PARAMETRIZE { heldItem = ITEM_RED_ORB;}
|
||||
PARAMETRIZE { heldItem = ITEM_BLUE_ORB;}
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_KYOGRE) { Item(heldItem); }
|
||||
} WHEN {
|
||||
TURN { MOVE(opponent, MOVE_CELEBRATE); }
|
||||
} SCENE {
|
||||
if (heldItem == ITEM_BLUE_ORB) {
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_PRIMAL_REVERSION, opponent);
|
||||
MESSAGE("Foe Kyogre's Primal Reversion! It reverted to its primal form!");
|
||||
}
|
||||
else {
|
||||
NONE_OF {
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_PRIMAL_REVERSION, opponent);
|
||||
MESSAGE("Foe Kyogre's Primal Reversion! It reverted to its primal form!");
|
||||
}
|
||||
}
|
||||
} THEN {
|
||||
if (heldItem == ITEM_BLUE_ORB) {
|
||||
EXPECT_EQ(opponent->species, SPECIES_KYOGRE_PRIMAL);
|
||||
}
|
||||
else {
|
||||
EXPECT_EQ(opponent->species, SPECIES_KYOGRE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DOUBLE_BATTLE_TEST("Primal reversion's order is determined by Speed - opponent faster")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_KYOGRE) { Item(ITEM_BLUE_ORB); Speed(5); };
|
||||
PLAYER(SPECIES_GROUDON) { Item(ITEM_RED_ORB); Speed(15); };
|
||||
OPPONENT(SPECIES_GROUDON) { Item(ITEM_RED_ORB); Speed(10); }
|
||||
OPPONENT(SPECIES_KYOGRE) { Item(ITEM_BLUE_ORB); Speed(20); }
|
||||
} WHEN {
|
||||
TURN { MOVE(opponentLeft, MOVE_CELEBRATE); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_PRIMAL_REVERSION, opponentRight);
|
||||
MESSAGE("Foe Kyogre's Primal Reversion! It reverted to its primal form!");
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_PRIMAL_REVERSION, playerRight);
|
||||
MESSAGE("Groudon's Primal Reversion! It reverted to its primal form!");
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_PRIMAL_REVERSION, opponentLeft);
|
||||
MESSAGE("Foe Groudon's Primal Reversion! It reverted to its primal form!");
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_PRIMAL_REVERSION, playerLeft);
|
||||
MESSAGE("Kyogre's Primal Reversion! It reverted to its primal form!");
|
||||
} THEN {
|
||||
EXPECT_EQ(playerLeft->species, SPECIES_KYOGRE_PRIMAL);
|
||||
EXPECT_EQ(opponentLeft->species, SPECIES_GROUDON_PRIMAL);
|
||||
EXPECT_EQ(opponentRight->species, SPECIES_KYOGRE_PRIMAL);
|
||||
EXPECT_EQ(playerRight->species, SPECIES_GROUDON_PRIMAL);
|
||||
}
|
||||
}
|
||||
|
||||
DOUBLE_BATTLE_TEST("Primal reversion's order is determined by Speed - player faster")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_KYOGRE) { Item(ITEM_BLUE_ORB); Speed(20); };
|
||||
PLAYER(SPECIES_GROUDON) { Item(ITEM_RED_ORB); Speed(30); };
|
||||
OPPONENT(SPECIES_GROUDON) { Item(ITEM_RED_ORB); Speed(10); }
|
||||
OPPONENT(SPECIES_KYOGRE) { Item(ITEM_BLUE_ORB); Speed(2); }
|
||||
} WHEN {
|
||||
TURN { MOVE(opponentLeft, MOVE_CELEBRATE); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_PRIMAL_REVERSION, playerRight);
|
||||
MESSAGE("Groudon's Primal Reversion! It reverted to its primal form!");
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_PRIMAL_REVERSION, playerLeft);
|
||||
MESSAGE("Kyogre's Primal Reversion! It reverted to its primal form!");
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_PRIMAL_REVERSION, opponentLeft);
|
||||
MESSAGE("Foe Groudon's Primal Reversion! It reverted to its primal form!");
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_PRIMAL_REVERSION, opponentRight);
|
||||
MESSAGE("Foe Kyogre's Primal Reversion! It reverted to its primal form!");
|
||||
} THEN {
|
||||
EXPECT_EQ(playerLeft->species, SPECIES_KYOGRE_PRIMAL);
|
||||
EXPECT_EQ(opponentLeft->species, SPECIES_GROUDON_PRIMAL);
|
||||
EXPECT_EQ(opponentRight->species, SPECIES_KYOGRE_PRIMAL);
|
||||
EXPECT_EQ(playerRight->species, SPECIES_GROUDON_PRIMAL);
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Primal reversion happens after a mon is sent out after a mon is fainted")
|
||||
{
|
||||
GIVEN {
|
||||
ASSUME(gBattleMoves[MOVE_TACKLE].power != 0);
|
||||
PLAYER(SPECIES_WOBBUFFET) {HP(1); }
|
||||
PLAYER(SPECIES_GROUDON) { Item(ITEM_RED_ORB); }
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(opponent, MOVE_TACKLE); SEND_OUT(player, 1); }
|
||||
TURN { MOVE(opponent, MOVE_TACKLE); }
|
||||
} SCENE {
|
||||
MESSAGE("Wobbuffet fainted!");
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_PRIMAL_REVERSION, player);
|
||||
MESSAGE("Groudon's Primal Reversion! It reverted to its primal form!");
|
||||
} THEN {
|
||||
EXPECT_EQ(player->species, SPECIES_GROUDON_PRIMAL);
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Primal reversion happens after a mon is switched in")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
PLAYER(SPECIES_GROUDON) { Item(ITEM_RED_ORB); }
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { SWITCH(player, 1); MOVE(opponent, MOVE_CELEBRATE); }
|
||||
TURN { MOVE(opponent, MOVE_CELEBRATE); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_PRIMAL_REVERSION, player);
|
||||
MESSAGE("Groudon's Primal Reversion! It reverted to its primal form!");
|
||||
} THEN {
|
||||
EXPECT_EQ(player->species, SPECIES_GROUDON_PRIMAL);
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Primal reversion happens after a switch-in caused by Eject Button")
|
||||
{
|
||||
GIVEN {
|
||||
ASSUME(gBattleMoves[MOVE_TACKLE].power != 0);
|
||||
ASSUME(gItems[ITEM_EJECT_BUTTON].holdEffect == HOLD_EFFECT_EJECT_BUTTON);
|
||||
PLAYER(SPECIES_WOBBUFFET) {Item(ITEM_EJECT_BUTTON); }
|
||||
PLAYER(SPECIES_GROUDON) { Item(ITEM_RED_ORB); }
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(opponent, MOVE_TACKLE); SEND_OUT(player, 1); }
|
||||
TURN { MOVE(opponent, MOVE_TACKLE); }
|
||||
} SCENE {
|
||||
MESSAGE("Wobbuffet is switched out with the Eject Button!");
|
||||
MESSAGE("Go! Groudon!");
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_PRIMAL_REVERSION, player);
|
||||
MESSAGE("Groudon's Primal Reversion! It reverted to its primal form!");
|
||||
} THEN {
|
||||
EXPECT_EQ(player->species, SPECIES_GROUDON_PRIMAL);
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Primal reversion happens after a switch-in caused by Red Card")
|
||||
{
|
||||
GIVEN {
|
||||
ASSUME(gBattleMoves[MOVE_TACKLE].power != 0);
|
||||
ASSUME(gItems[ITEM_RED_CARD].holdEffect == HOLD_EFFECT_RED_CARD);
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
PLAYER(SPECIES_GROUDON) { Item(ITEM_RED_ORB); }
|
||||
OPPONENT(SPECIES_WOBBUFFET) {Item(ITEM_RED_CARD); }
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_TACKLE); }
|
||||
} SCENE {
|
||||
MESSAGE("Foe Wobbuffet held up its Red Card against Wobbuffet!");
|
||||
MESSAGE("Groudon was dragged out!");
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_PRIMAL_REVERSION, player);
|
||||
MESSAGE("Groudon's Primal Reversion! It reverted to its primal form!");
|
||||
} THEN {
|
||||
EXPECT_EQ(player->species, SPECIES_GROUDON_PRIMAL);
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Primal reversion happens after the entry hazards damage")
|
||||
{
|
||||
GIVEN {
|
||||
ASSUME(gBattleMoves[MOVE_SPIKES].effect == EFFECT_SPIKES);
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
PLAYER(SPECIES_GROUDON) { Item(ITEM_RED_ORB); }
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(opponent, MOVE_SPIKES); }
|
||||
TURN { MOVE(opponent, MOVE_SPIKES); SWITCH(player, 1);}
|
||||
} SCENE {
|
||||
MESSAGE("Go! Groudon!");
|
||||
HP_BAR(player);
|
||||
MESSAGE("Groudon is hurt by spikes!");
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_PRIMAL_REVERSION, player);
|
||||
MESSAGE("Groudon's Primal Reversion! It reverted to its primal form!");
|
||||
} THEN {
|
||||
EXPECT_EQ(player->species, SPECIES_GROUDON_PRIMAL);
|
||||
}
|
||||
}
|
47
test/weather_rain.c
Normal file
47
test/weather_rain.c
Normal file
@ -0,0 +1,47 @@
|
||||
#include "global.h"
|
||||
#include "test_battle.h"
|
||||
|
||||
// Please add Rain interactions with move, item and ability effects on their respective files.
|
||||
ASSUMPTIONS
|
||||
{
|
||||
ASSUME(gBattleMoves[MOVE_EMBER].type == TYPE_FIRE);
|
||||
ASSUME(gBattleMoves[MOVE_WATER_GUN].type == TYPE_WATER);
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Rain multiplies the power of Fire-type moves by 0.5x", s16 damage)
|
||||
{
|
||||
u32 setupMove;
|
||||
PARAMETRIZE { setupMove = MOVE_CELEBRATE; }
|
||||
PARAMETRIZE { setupMove = MOVE_RAIN_DANCE; }
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(player, setupMove); }
|
||||
TURN { MOVE(player, MOVE_EMBER); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_EMBER, player);
|
||||
HP_BAR(opponent, captureDamage: &results[i].damage);
|
||||
} FINALLY {
|
||||
EXPECT_MUL_EQ(results[0].damage, Q_4_12(0.5), results[1].damage);
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Rain multiplies the power of Water-type moves by 1.5x", s16 damage)
|
||||
{
|
||||
u32 setupMove;
|
||||
PARAMETRIZE { setupMove = MOVE_CELEBRATE; }
|
||||
PARAMETRIZE { setupMove = MOVE_RAIN_DANCE; }
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(player, setupMove); }
|
||||
TURN { MOVE(player, MOVE_WATER_GUN); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_WATER_GUN, player);
|
||||
HP_BAR(opponent, captureDamage: &results[i].damage);
|
||||
} FINALLY {
|
||||
EXPECT_MUL_EQ(results[0].damage, Q_4_12(1.5), results[1].damage);
|
||||
}
|
||||
}
|
47
test/weather_sunlight.c
Normal file
47
test/weather_sunlight.c
Normal file
@ -0,0 +1,47 @@
|
||||
#include "global.h"
|
||||
#include "test_battle.h"
|
||||
|
||||
// Please add Sunlight interactions with move, item and ability effects on their respective files.
|
||||
ASSUMPTIONS
|
||||
{
|
||||
ASSUME(gBattleMoves[MOVE_EMBER].type == TYPE_FIRE);
|
||||
ASSUME(gBattleMoves[MOVE_WATER_GUN].type == TYPE_WATER);
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Sunlight multiplies the power of Fire-type moves by 1.5x", s16 damage)
|
||||
{
|
||||
u32 setupMove;
|
||||
PARAMETRIZE { setupMove = MOVE_CELEBRATE; }
|
||||
PARAMETRIZE { setupMove = MOVE_SUNNY_DAY; }
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(player, setupMove); }
|
||||
TURN { MOVE(player, MOVE_EMBER); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_EMBER, player);
|
||||
HP_BAR(opponent, captureDamage: &results[i].damage);
|
||||
} FINALLY {
|
||||
EXPECT_MUL_EQ(results[0].damage, Q_4_12(1.5), results[1].damage);
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Sunlight multiplies the power of Water-type moves by 0.5x", s16 damage)
|
||||
{
|
||||
u32 setupMove;
|
||||
PARAMETRIZE { setupMove = MOVE_CELEBRATE; }
|
||||
PARAMETRIZE { setupMove = MOVE_SUNNY_DAY; }
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(player, setupMove); }
|
||||
TURN { MOVE(player, MOVE_WATER_GUN); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_WATER_GUN, player);
|
||||
HP_BAR(opponent, captureDamage: &results[i].damage);
|
||||
} FINALLY {
|
||||
EXPECT_MUL_EQ(results[0].damage, Q_4_12(0.5), results[1].damage);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user