mirror of
https://github.com/pret/pokeemerald.git
synced 2026-06-02 22:05:46 -05:00
Remove redundant bit for Throat Spray (#6593)
This commit is contained in:
parent
6a70f4f390
commit
caa878002a
|
|
@ -146,7 +146,7 @@ struct ProtectStruct
|
|||
u32 stealMove:1;
|
||||
u32 prlzImmobility:1;
|
||||
u32 confusionSelfDmg:1;
|
||||
u32 targetAffected:1;
|
||||
u32 touchedProtectLike:1;
|
||||
u32 chargingTurn:1;
|
||||
u32 fleeType:2; // 0: Normal, 1: FLEE_ITEM, 2: FLEE_ABILITY
|
||||
u32 usedImprisonedMove:1;
|
||||
|
|
@ -164,7 +164,6 @@ struct ProtectStruct
|
|||
u32 statRaised:1;
|
||||
u32 usedCustapBerry:1; // also quick claw
|
||||
// End of 32-bit bitfield
|
||||
u16 touchedProtectLike:1;
|
||||
u16 disableEjectPack:1;
|
||||
u16 statFell:1;
|
||||
u16 pranksterElevated:1;
|
||||
|
|
@ -175,7 +174,7 @@ struct ProtectStruct
|
|||
u16 eatMirrorHerb:1;
|
||||
u16 activateOpportunist:2; // 2 - to copy stats. 1 - stats copied (do not repeat). 0 - no stats to copy
|
||||
u16 usedAllySwitch:1;
|
||||
u16 padding:4;
|
||||
u16 padding:5;
|
||||
// End of 16-bit bitfield
|
||||
u16 physicalDmg;
|
||||
u16 specialDmg;
|
||||
|
|
|
|||
|
|
@ -3286,7 +3286,6 @@ const u8* FaintClearSetData(u32 battler)
|
|||
gProtectStructs[battler].stealMove = FALSE;
|
||||
gProtectStructs[battler].prlzImmobility = FALSE;
|
||||
gProtectStructs[battler].confusionSelfDmg = FALSE;
|
||||
gProtectStructs[battler].targetAffected = FALSE;
|
||||
gProtectStructs[battler].chargingTurn = FALSE;
|
||||
gProtectStructs[battler].fleeType = 0;
|
||||
gProtectStructs[battler].usedImprisonedMove = FALSE;
|
||||
|
|
|
|||
|
|
@ -1155,12 +1155,11 @@ bool32 IsMoveNotAllowedInSkyBattles(u32 move)
|
|||
|
||||
u32 NumAffectedSpreadMoveTargets(void)
|
||||
{
|
||||
u32 targetCount = 1;
|
||||
u32 targetCount = 0;
|
||||
|
||||
if (!IsDoubleSpreadMove())
|
||||
return targetCount;
|
||||
|
||||
targetCount = 0;
|
||||
for (u32 battler = 0; battler < gBattlersCount; battler++)
|
||||
{
|
||||
if (!(gBattleStruct->moveResultFlags[battler] & MOVE_RESULT_NO_EFFECT))
|
||||
|
|
@ -7113,10 +7112,6 @@ static void Cmd_moveend(void)
|
|||
case MOVEEND_NEXT_TARGET: // For moves hitting two opposing Pokemon.
|
||||
{
|
||||
u16 moveTarget = GetBattlerMoveTargetType(gBattlerAttacker, gCurrentMove);
|
||||
// Set a flag if move hits either target (for throat spray that can't check damage)
|
||||
if (!(gHitMarker & HITMARKER_UNABLE_TO_USE_MOVE)
|
||||
&& !(gBattleStruct->moveResultFlags[gBattlerTarget] & MOVE_RESULT_NO_EFFECT))
|
||||
gProtectStructs[gBattlerAttacker].targetAffected = TRUE;
|
||||
|
||||
gBattleStruct->battlerState[gBattlerAttacker].targetsDone[gBattlerTarget] = TRUE;
|
||||
if (!(gHitMarker & HITMARKER_UNABLE_TO_USE_MOVE)
|
||||
|
|
@ -7566,7 +7561,6 @@ static void Cmd_moveend(void)
|
|||
DebugPrintfLevel(MGBA_LOG_WARN, "savedTargetCount is greater than 0! More calls to SaveBattlerTarget than RestoreBattlerTarget!");
|
||||
// #endif
|
||||
}
|
||||
gProtectStructs[gBattlerAttacker].targetAffected = FALSE;
|
||||
gProtectStructs[gBattlerAttacker].shellTrap = FALSE;
|
||||
gBattleStruct->ateBoost[gBattlerAttacker] = FALSE;
|
||||
gStatuses3[gBattlerAttacker] &= ~STATUS3_ME_FIRST;
|
||||
|
|
|
|||
|
|
@ -65,6 +65,7 @@ static u32 GetFlingPowerFromItemId(u32 itemId);
|
|||
static void SetRandomMultiHitCounter();
|
||||
static u32 GetBattlerItemHoldEffectParam(u32 battler, u32 item);
|
||||
static bool32 CanBeInfinitelyConfused(u32 battler);
|
||||
static bool32 IsAnyTargetAffected(u32 battlerAtk);
|
||||
|
||||
ARM_FUNC NOINLINE static uq4_12_t PercentToUQ4_12(u32 percent);
|
||||
ARM_FUNC NOINLINE static uq4_12_t PercentToUQ4_12_Floored(u32 percent);
|
||||
|
|
@ -4801,8 +4802,8 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
|
|||
break;
|
||||
case ABILITY_IMPOSTER:
|
||||
{
|
||||
u32 diagonalBattler = BATTLE_OPPOSITE(battler);
|
||||
if (IsDoubleBattle())
|
||||
u32 diagonalBattler = BATTLE_OPPOSITE(battler);
|
||||
if (IsDoubleBattle())
|
||||
diagonalBattler = BATTLE_PARTNER(diagonalBattler);
|
||||
if (IsBattlerAlive(diagonalBattler)
|
||||
&& !(gBattleMons[diagonalBattler].status2 & (STATUS2_TRANSFORMED | STATUS2_SUBSTITUTE))
|
||||
|
|
@ -8213,9 +8214,9 @@ u32 ItemBattleEffects(enum ItemCaseId caseID, u32 battler, bool32 moveTurn)
|
|||
}
|
||||
break;
|
||||
case HOLD_EFFECT_THROAT_SPRAY: // Does NOT need to be a damaging move
|
||||
if (gProtectStructs[gBattlerAttacker].targetAffected
|
||||
if (IsSoundMove(gCurrentMove)
|
||||
&& IsBattlerAlive(gBattlerAttacker)
|
||||
&& IsSoundMove(gCurrentMove)
|
||||
&& IsAnyTargetAffected(gBattlerAttacker)
|
||||
&& CompareStat(gBattlerAttacker, STAT_SPATK, MAX_STAT_STAGE, CMP_LESS_THAN)
|
||||
&& !NoAliveMonsForEitherParty()) // Don't activate if battle will end
|
||||
{
|
||||
|
|
@ -12408,3 +12409,16 @@ bool32 HasWeatherEffect(void)
|
|||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static bool32 IsAnyTargetAffected(u32 battlerAtk)
|
||||
{
|
||||
for (u32 battlerDef = 0; battlerDef < gBattlersCount; battlerDef++)
|
||||
{
|
||||
if (battlerAtk == battlerDef)
|
||||
continue;
|
||||
|
||||
if (!(gBattleStruct->moveResultFlags[battlerDef] & MOVE_RESULT_NO_EFFECT))
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
|
|
|||
90
test/battle/hold_effect/throat_spray.c
Normal file
90
test/battle/hold_effect/throat_spray.c
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
#include "global.h"
|
||||
#include "test/battle.h"
|
||||
|
||||
ASSUMPTIONS
|
||||
{
|
||||
ASSUME(ItemId_GetHoldEffect(ITEM_THROAT_SPRAY) == HOLD_EFFECT_THROAT_SPRAY);
|
||||
ASSUME(IsSoundMove(MOVE_HYPER_VOICE) == TRUE);
|
||||
}
|
||||
|
||||
DOUBLE_BATTLE_TEST("Throat Spray activates after both hits of a spread move")
|
||||
{
|
||||
s16 firstHit, secondHit;
|
||||
|
||||
GIVEN {
|
||||
ASSUME(GetMoveTarget(MOVE_HYPER_VOICE) == MOVE_TARGET_BOTH);
|
||||
PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_THROAT_SPRAY); }
|
||||
PLAYER(SPECIES_WYNAUT);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(playerLeft, MOVE_HYPER_VOICE); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_HYPER_VOICE, playerLeft);
|
||||
HP_BAR(opponentLeft, captureDamage: &firstHit);
|
||||
HP_BAR(opponentRight, captureDamage: &secondHit);
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, playerLeft);
|
||||
} THEN {
|
||||
EXPECT_EQ(firstHit, secondHit);
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Throat Spray increases Sp. Atk by one stage")
|
||||
{
|
||||
s16 normalHit;
|
||||
s16 boostedHit;
|
||||
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_THROAT_SPRAY); }
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_HYPER_VOICE); }
|
||||
TURN { MOVE(player, MOVE_HYPER_VOICE); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_HYPER_VOICE, player);
|
||||
HP_BAR(opponent, captureDamage: &normalHit);
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, player);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_HYPER_VOICE, player);
|
||||
HP_BAR(opponent, captureDamage: &boostedHit);
|
||||
} THEN {
|
||||
EXPECT_MUL_EQ(normalHit, Q_4_12(1.5), boostedHit);
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Throat Spray activates when a sound move is used")
|
||||
{
|
||||
u32 move;
|
||||
|
||||
PARAMETRIZE { move = MOVE_SWIFT; }
|
||||
PARAMETRIZE { move = MOVE_HYPER_VOICE; }
|
||||
|
||||
GIVEN {
|
||||
ASSUME(IsSoundMove(MOVE_SWIFT) != IsSoundMove(MOVE_HYPER_VOICE));
|
||||
PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_THROAT_SPRAY); }
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(player, move); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, move, player);
|
||||
if (move == MOVE_HYPER_VOICE)
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, player);
|
||||
else
|
||||
NOT ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, player);
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Throat Spray does not activate if move fails")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_THROAT_SPRAY); }
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(opponent, MOVE_PROTECT); MOVE(player, MOVE_HYPER_VOICE); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_PROTECT, opponent);
|
||||
NONE_OF {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_HYPER_VOICE, player);
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, player);
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user