EndTurnEffectsOrder Refactor
This commit is contained in:
parent
37dd57b1b5
commit
f2bd88a7f9
@ -1007,7 +1007,7 @@
|
||||
.4byte \jumpInstr
|
||||
.endm
|
||||
|
||||
.macro unused_bb
|
||||
.macro tryhealingitem
|
||||
.byte 0xbb
|
||||
.endm
|
||||
|
||||
@ -1140,9 +1140,8 @@
|
||||
.4byte \failInstr
|
||||
.endm
|
||||
|
||||
.macro trywish turnNumber:req, failInstr:req
|
||||
.macro trywish failInstr:req
|
||||
.byte 0xd4
|
||||
.byte \turnNumber
|
||||
.4byte \failInstr
|
||||
.endm
|
||||
|
||||
|
||||
@ -410,12 +410,12 @@ BattleScript_MoveEffectSaltCure::
|
||||
return
|
||||
|
||||
BattleScript_SaltCureExtraDamage::
|
||||
playanimation BS_TARGET, B_ANIM_SALT_CURE_DAMAGE, NULL
|
||||
playanimation BS_ATTACKER, B_ANIM_SALT_CURE_DAMAGE, NULL
|
||||
waitanimation
|
||||
call BattleScript_HurtTarget_NoString
|
||||
printstring STRINGID_TARGETISHURTBYSALTCURE
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
tryfaintmon BS_TARGET
|
||||
tryfaintmon BS_ATTACKER
|
||||
end2
|
||||
|
||||
BattleScript_HurtTarget_NoString:
|
||||
@ -5044,7 +5044,7 @@ BattleScript_EffectWish::
|
||||
attackcanceler
|
||||
attackstring
|
||||
ppreduce
|
||||
trywish 0, BattleScript_ButItFailed
|
||||
trywish BattleScript_ButItFailed
|
||||
attackanimation
|
||||
waitanimation
|
||||
goto BattleScript_MoveEnd
|
||||
@ -5842,13 +5842,13 @@ BattleScript_FogEnded_Ret::
|
||||
return
|
||||
|
||||
BattleScript_IceBodyHeal::
|
||||
call BattleScript_AbilityPopUpScripting
|
||||
playanimation BS_SCRIPTING, B_ANIM_SIMPLE_HEAL
|
||||
healthbarupdate BS_SCRIPTING
|
||||
datahpupdate BS_SCRIPTING
|
||||
call BattleScript_AbilityPopUp
|
||||
playanimation BS_ATTACKER, B_ANIM_SIMPLE_HEAL
|
||||
healthbarupdate BS_ATTACKER
|
||||
datahpupdate BS_ATTACKER
|
||||
printstring STRINGID_ICEBODYHPGAIN
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
end2
|
||||
end3
|
||||
|
||||
BattleScript_OverworldStatusStarts::
|
||||
printfromtable gStartingStatusStringIds
|
||||
@ -6674,7 +6674,6 @@ BattleScript_SelectingNotAllowedCurrentMoveInPalace::
|
||||
goto BattleScript_SelectingUnusableMoveInPalace
|
||||
|
||||
BattleScript_WishComesTrue::
|
||||
trywish 1, BattleScript_WishButFullHp
|
||||
playanimation BS_TARGET, B_ANIM_WISH_HEAL
|
||||
printstring STRINGID_PKMNWISHCAMETRUE
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
@ -6993,7 +6992,7 @@ BattleScript_CudChewActivates::
|
||||
pause B_WAIT_TIME_SHORTEST
|
||||
call BattleScript_AbilityPopUp
|
||||
setbyte sBERRY_OVERRIDE, 1 @ override the requirements for eating berries
|
||||
consumeberry BS_SCRIPTING, FALSE
|
||||
consumeberry BS_ATTACKER, FALSE
|
||||
setbyte sBERRY_OVERRIDE, 0
|
||||
end3
|
||||
|
||||
@ -7145,6 +7144,7 @@ BattleScript_DoTurnDmg:
|
||||
datahpupdate BS_ATTACKER
|
||||
tryfaintmon BS_ATTACKER
|
||||
checkteamslost BattleScript_DoTurnDmgEnd
|
||||
tryhealingitem
|
||||
BattleScript_DoTurnDmgEnd:
|
||||
end2
|
||||
|
||||
@ -7608,6 +7608,37 @@ BattleScript_EmergencyExitWildNoPopUp::
|
||||
finishaction
|
||||
return
|
||||
|
||||
BattleScript_EmergencyExitEnd2::
|
||||
pause 5
|
||||
call BattleScript_AbilityPopUp
|
||||
pause B_WAIT_TIME_LONG
|
||||
playanimation BS_ATTACKER, B_ANIM_SLIDE_OFFSCREEN
|
||||
waitanimation
|
||||
openpartyscreen BS_ATTACKER, BattleScript_EmergencyExitRetEnd2
|
||||
switchoutabilities BS_ATTACKER
|
||||
waitstate
|
||||
switchhandleorder BS_ATTACKER, 2
|
||||
returntoball BS_TARGET, FALSE
|
||||
getswitchedmondata BS_ATTACKER
|
||||
switchindataupdate BS_ATTACKER
|
||||
hpthresholds BS_ATTACKER
|
||||
printstring STRINGID_SWITCHINMON
|
||||
switchinanim BS_ATTACKER, FALSE, TRUE
|
||||
waitstate
|
||||
switchineffects BS_ATTACKER
|
||||
BattleScript_EmergencyExitRetEnd2:
|
||||
end2
|
||||
|
||||
BattleScript_EmergencyExitWildEnd2::
|
||||
pause 5
|
||||
call BattleScript_AbilityPopUp
|
||||
pause B_WAIT_TIME_LONG
|
||||
playanimation BS_ATTACKER, B_ANIM_SLIDE_OFFSCREEN
|
||||
waitanimation
|
||||
setoutcomeonteleport BS_ATTACKER
|
||||
finishaction
|
||||
end2
|
||||
|
||||
BattleScript_TraceActivates::
|
||||
pause B_WAIT_TIME_SHORT
|
||||
call BattleScript_AbilityPopUpScripting
|
||||
@ -7650,6 +7681,7 @@ BattleScript_PickupActivates::
|
||||
call BattleScript_AbilityPopUp
|
||||
printstring STRINGID_XFOUNDONEY
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
tryhealingitem
|
||||
BattleScript_PickupActivatesEnd:
|
||||
end3
|
||||
|
||||
@ -7659,6 +7691,7 @@ BattleScript_HarvestActivates::
|
||||
call BattleScript_AbilityPopUp
|
||||
printstring STRINGID_HARVESTBERRY
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
tryhealingitem
|
||||
BattleScript_HarvestActivatesEnd:
|
||||
end3
|
||||
|
||||
@ -9937,7 +9970,7 @@ BattleScript_DynamaxBegins::
|
||||
BattleScript_DynamaxEnds::
|
||||
flushtextbox
|
||||
updatedynamax
|
||||
playanimation BS_SCRIPTING, B_ANIM_FORM_CHANGE
|
||||
playanimation BS_ATTACKER, B_ANIM_FORM_CHANGE
|
||||
waitanimation
|
||||
end2
|
||||
|
||||
|
||||
23
endturneffect_bak.c
Normal file
23
endturneffect_bak.c
Normal file
@ -0,0 +1,23 @@
|
||||
bool32 HandleWishPerishSongOnTurnEnd(void)
|
||||
{
|
||||
gHitMarker |= (HITMARKER_GRUDGE | HITMARKER_IGNORE_BIDE);
|
||||
|
||||
if ((gBattleTypeFlags & BATTLE_TYPE_ARENA)
|
||||
&& gBattleStruct->arenaTurnCounter == 2
|
||||
&& IsBattlerAlive(B_POSITION_PLAYER_LEFT) && IsBattlerAlive(B_POSITION_OPPONENT_LEFT))
|
||||
{
|
||||
s32 i;
|
||||
|
||||
// This seems to be a bug?
|
||||
for (i = 0; i < 2; i++)
|
||||
CancelMultiTurnMoves(i);
|
||||
|
||||
gBattlescriptCurrInstr = BattleScript_ArenaDoJudgment;
|
||||
BattleScriptExecute(BattleScript_ArenaDoJudgment);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gHitMarker &= ~(HITMARKER_GRUDGE | HITMARKER_IGNORE_BIDE);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
@ -104,7 +104,7 @@ struct DisableStruct
|
||||
u8 telekinesisTimer;
|
||||
u8 healBlockTimer;
|
||||
u8 laserFocusTimer;
|
||||
u8 throatChopTimer;
|
||||
u16 throatChopTimer;
|
||||
u8 wrapTurns;
|
||||
u8 syrupBombTimer;
|
||||
u8 tormentTimer:4; // used for G-Max Meltdown
|
||||
@ -647,9 +647,9 @@ struct BattlerState
|
||||
struct BattleStruct
|
||||
{
|
||||
struct BattlerState battlerState[MAX_BATTLERS_COUNT];
|
||||
u8 turnEffectsTracker;
|
||||
u8 eventBlockCounter;
|
||||
u8 turnEffectsBattlerId;
|
||||
u8 turnCountersTracker;
|
||||
u8 endTurnEventsCounter;
|
||||
u16 wrappedMove[MAX_BATTLERS_COUNT];
|
||||
u16 moveTarget[MAX_BATTLERS_COUNT];
|
||||
u32 expShareExpValue;
|
||||
@ -721,8 +721,6 @@ struct BattleStruct
|
||||
struct LinkBattlerHeader linkBattlerHeader;
|
||||
struct BattleVideo battleVideo;
|
||||
} multiBuffer;
|
||||
u8 wishPerishSongState;
|
||||
u8 wishPerishSongBattlerId;
|
||||
u8 startingStatus:6; // status to apply at battle start. defined in constants/battle.h
|
||||
u8 startingStatusDone:1;
|
||||
u8 terrainDone:1;
|
||||
|
||||
6
include/battle_end_turn.h
Normal file
6
include/battle_end_turn.h
Normal file
@ -0,0 +1,6 @@
|
||||
#ifndef GUARD_BATTLE_END_TURN
|
||||
#define GUARD_BATTLE_END_TURN
|
||||
|
||||
u32 DoEndTurnEffects(void);
|
||||
|
||||
#endif // GUARD_BATTLE_END_TURN
|
||||
@ -42,7 +42,7 @@ bool32 CanPoisonType(u8 battlerAttacker, u8 battlerTarget);
|
||||
bool32 CanParalyzeType(u8 battlerAttacker, u8 battlerTarget);
|
||||
bool32 CanUseLastResort(u8 battlerId);
|
||||
u32 IsFlowerVeilProtected(u32 battler);
|
||||
u32 IsLeafGuardProtected(u32 battler);
|
||||
u32 IsLeafGuardProtected(u32 battler, u32 ability);
|
||||
bool32 IsShieldsDownProtected(u32 battler);
|
||||
u32 IsAbilityStatusProtected(u32 battler);
|
||||
bool32 TryResetBattlerStatChanges(u8 battler);
|
||||
|
||||
@ -101,6 +101,7 @@ extern const u8 BattleScript_SelectingTormentedMoveInPalace[];
|
||||
extern const u8 BattleScript_SelectingNotAllowedMoveTaunt[];
|
||||
extern const u8 BattleScript_MoveUsedIsTaunted[];
|
||||
extern const u8 BattleScript_SelectingNotAllowedMoveTauntInPalace[];
|
||||
extern const u8 BattleScript_WishButFullHp[];
|
||||
extern const u8 BattleScript_WishComesTrue[];
|
||||
extern const u8 BattleScript_IngrainTurnHeal[];
|
||||
extern const u8 BattleScript_AtkDefDown[];
|
||||
@ -387,6 +388,8 @@ extern const u8 BattleScript_EmergencyExit[];
|
||||
extern const u8 BattleScript_EmergencyExitNoPopUp[];
|
||||
extern const u8 BattleScript_EmergencyExitWild[];
|
||||
extern const u8 BattleScript_EmergencyExitWildNoPopUp[];
|
||||
extern const u8 BattleScript_EmergencyExitEnd2[];
|
||||
extern const u8 BattleScript_EmergencyExitWildEnd2[];
|
||||
extern const u8 BattleScript_CheekPouchActivates[];
|
||||
extern const u8 BattleScript_TotemVar[];
|
||||
extern const u8 BattleScript_TotemFlaredToLife[];
|
||||
|
||||
@ -73,6 +73,7 @@ enum ItemCaseId
|
||||
ITEMEFFECT_ON_SWITCH_IN,
|
||||
ITEMEFFECT_ON_SWITCH_IN_FIRST_TURN,
|
||||
ITEMEFFECT_NORMAL,
|
||||
ITEMEFFECT_TRY_HEALING,
|
||||
ITEMEFFECT_MOVE_END,
|
||||
ITEMEFFECT_KINGSROCK,
|
||||
ITEMEFFECT_TARGET,
|
||||
@ -174,6 +175,8 @@ enum SleepClauseBlock
|
||||
};
|
||||
|
||||
void HandleAction_ThrowBall(void);
|
||||
u32 GetCurrentBattleWeather(void);
|
||||
u32 EndOrConinueWeather(void);
|
||||
bool32 IsAffectedByFollowMe(u32 battlerAtk, u32 defSide, u32 move);
|
||||
void HandleAction_UseMove(void);
|
||||
void HandleAction_Switch(void);
|
||||
@ -206,10 +209,8 @@ u32 TrySetCantSelectMoveBattleScript(u32 battler);
|
||||
u8 CheckMoveLimitations(u32 battler, u8 unusableMoves, u16 check);
|
||||
bool32 AreAllMovesUnusable(u32 battler);
|
||||
u8 GetImprisonedMovesCount(u32 battler, u16 move);
|
||||
u8 DoFieldEndTurnEffects(void);
|
||||
s32 GetDrainedBigRootHp(u32 battler, s32 hp);
|
||||
u8 DoBattlerEndTurnEffects(void);
|
||||
bool32 HandleWishPerishSongOnTurnEnd(void);
|
||||
u32 DoEndTurnEffects(void);
|
||||
bool32 HandleFaintedMonActions(void);
|
||||
void TryClearRageAndFuryCutter(void);
|
||||
u32 AtkCanceller_MoveSuccessOrder(void);
|
||||
@ -327,6 +328,7 @@ bool32 CanBeConfused(u32 battler);
|
||||
bool32 IsBattlerTerrainAffected(u32 battler, u32 terrainFlag);
|
||||
u32 GetBattlerAffectionHearts(u32 battler);
|
||||
void TryToRevertMimicryAndFlags(void);
|
||||
bool32 BattleArenaTurnEnd(void);
|
||||
u32 CountBattlerStatIncreases(u32 battler, bool32 countEvasionAcc);
|
||||
bool32 ChangeTypeBasedOnTerrain(u32 battler);
|
||||
void RemoveConfusionStatus(u32 battler);
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
// still has them in the ROM. This is because the developers forgot
|
||||
// to define NDEBUG before release, however this has been changed as
|
||||
// Ruby's actual debug build does not use the AGBPrint features.
|
||||
#define NDEBUG
|
||||
// #define NDEBUG
|
||||
|
||||
// To enable printf debugging, comment out "#define NDEBUG". This allows
|
||||
// the various AGBPrint functions to be used. (See include/gba/isagbprint.h).
|
||||
|
||||
@ -533,9 +533,6 @@ enum BattleWeather
|
||||
#define HANDLE_TYPE_PRIMAL_REVERSION 1
|
||||
#define HANDLE_TYPE_ULTRA_BURST 2
|
||||
|
||||
// Constants for Torment
|
||||
#define PERMANENT_TORMENT 0xF
|
||||
|
||||
// Constants for B_VAR_STARTING_STATUS
|
||||
// Timer value controlled by B_VAR_STARTING_STATUS_TIMER
|
||||
enum StartingStatus
|
||||
|
||||
@ -1058,7 +1058,7 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
|
||||
// the following checks apply to any target (including user)
|
||||
|
||||
// throat chop check
|
||||
if (gDisableStructs[battlerAtk].throatChopTimer && IsSoundMove(move))
|
||||
if (gDisableStructs[battlerAtk].throatChopTimer > gBattleTurnCounter && IsSoundMove(move))
|
||||
return 0; // Can't even select move at all
|
||||
// heal block check
|
||||
if (gStatuses3[battlerAtk] & STATUS3_HEAL_BLOCK && IsHealBlockPreventingMove(battlerAtk, move))
|
||||
@ -2463,7 +2463,7 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
|
||||
case EFFECT_EMBARGO:
|
||||
if (aiData->abilities[battlerDef] == ABILITY_KLUTZ
|
||||
|| gFieldStatuses & STATUS_FIELD_MAGIC_ROOM
|
||||
|| gDisableStructs[battlerDef].embargoTimer != 0
|
||||
|| gStatuses3[battlerDef] & STATUS3_EMBARGO
|
||||
|| PartnerMoveIsSameAsAttacker(BATTLE_PARTNER(battlerAtk), battlerDef, move, aiData->partnerMove))
|
||||
ADJUST_SCORE(-10);
|
||||
break;
|
||||
@ -2481,7 +2481,7 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
|
||||
ADJUST_SCORE(-10);
|
||||
break;
|
||||
case EFFECT_HEAL_BLOCK:
|
||||
if (gDisableStructs[battlerDef].healBlockTimer != 0
|
||||
if (gStatuses3[battlerDef] & STATUS3_HEAL_BLOCK
|
||||
|| PartnerMoveIsSameAsAttacker(BATTLE_PARTNER(battlerAtk), battlerDef, move, aiData->partnerMove))
|
||||
ADJUST_SCORE(-10);
|
||||
break;
|
||||
|
||||
@ -178,7 +178,7 @@ void ActivateDynamax(u32 battler)
|
||||
// Set appropriate use flags.
|
||||
SetActiveGimmick(battler, GIMMICK_DYNAMAX);
|
||||
SetGimmickAsActivated(battler, GIMMICK_DYNAMAX);
|
||||
gBattleStruct->dynamax.dynamaxTurns[battler] = DYNAMAX_TURNS_COUNT;
|
||||
gBattleStruct->dynamax.dynamaxTurns[battler] = gBattleTurnCounter + DYNAMAX_TURNS_COUNT;
|
||||
|
||||
// Substitute is removed upon Dynamaxing.
|
||||
gBattleMons[battler].status2 &= ~STATUS2_SUBSTITUTE;
|
||||
@ -212,7 +212,6 @@ void UndoDynamax(u32 battler)
|
||||
|
||||
// Makes sure there are no Dynamax flags set, including on switch / faint.
|
||||
SetActiveGimmick(battler, GIMMICK_NONE);
|
||||
gBattleStruct->dynamax.dynamaxTurns[battler] = 0;
|
||||
|
||||
// Undo form change if needed.
|
||||
if (IsGigantamaxed(battler))
|
||||
@ -511,13 +510,12 @@ static u32 GetMaxMoveStatusEffect(u32 move)
|
||||
void BS_UpdateDynamax(void)
|
||||
{
|
||||
NATIVE_ARGS();
|
||||
u32 battler = gBattleScripting.battler;
|
||||
struct Pokemon *mon = GetPartyBattlerData(battler);
|
||||
struct Pokemon *mon = GetPartyBattlerData(gBattlerAttacker);
|
||||
|
||||
if (!IsGigantamaxed(battler)) // RecalcBattlerStats will get called on form change.
|
||||
RecalcBattlerStats(battler, mon, GetActiveGimmick(battler) == GIMMICK_DYNAMAX);
|
||||
if (!IsGigantamaxed(gBattlerAttacker)) // RecalcBattlerStats will get called on form change.
|
||||
RecalcBattlerStats(gBattlerAttacker, mon, GetActiveGimmick(gBattlerAttacker) == GIMMICK_DYNAMAX);
|
||||
|
||||
UpdateHealthboxAttribute(gHealthboxSpriteIds[battler], mon, HEALTHBOX_ALL);
|
||||
UpdateHealthboxAttribute(gHealthboxSpriteIds[gBattlerAttacker], mon, HEALTHBOX_ALL);
|
||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||
}
|
||||
|
||||
|
||||
1422
src/battle_end_turn.c
Normal file
1422
src/battle_end_turn.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -5,6 +5,7 @@
|
||||
#include "battle_ai_util.h"
|
||||
#include "battle_arena.h"
|
||||
#include "battle_controllers.h"
|
||||
#include "battle_end_turn.h"
|
||||
#include "battle_interface.h"
|
||||
#include "battle_main.h"
|
||||
#include "battle_message.h"
|
||||
@ -3895,13 +3896,11 @@ static void TryDoEventsBeforeFirstTurn(void)
|
||||
gBattleStruct->appearedInBattle |= 1u << gBattlerPartyIndexes[i];
|
||||
}
|
||||
|
||||
*(&gBattleStruct->turnEffectsTracker) = 0;
|
||||
*(&gBattleStruct->eventBlockCounter) = 0;
|
||||
*(&gBattleStruct->turnEffectsBattlerId) = 0;
|
||||
*(&gBattleStruct->wishPerishSongState) = 0;
|
||||
*(&gBattleStruct->wishPerishSongBattlerId) = 0;
|
||||
gBattleScripting.moveendState = 0;
|
||||
gBattleStruct->faintedActionsState = 0;
|
||||
gBattleStruct->turnCountersTracker = 0;
|
||||
gBattleStruct->endTurnEventsCounter = 0;
|
||||
|
||||
memset(gQueuedStatBoosts, 0, sizeof(gQueuedStatBoosts));
|
||||
SetShellSideArmCategory();
|
||||
@ -3935,11 +3934,9 @@ static void HandleEndTurn_ContinueBattle(void)
|
||||
if ((gBattleMons[i].status1 & STATUS1_SLEEP) && (gBattleMons[i].status2 & STATUS2_MULTIPLETURNS))
|
||||
CancelMultiTurnMoves(i);
|
||||
}
|
||||
gBattleStruct->turnEffectsTracker = 0;
|
||||
gBattleStruct->eventBlockCounter = 0;
|
||||
gBattleStruct->turnEffectsBattlerId = 0;
|
||||
gBattleStruct->wishPerishSongState = 0;
|
||||
gBattleStruct->wishPerishSongBattlerId = 0;
|
||||
gBattleStruct->turnCountersTracker = 0;
|
||||
gBattleStruct->endTurnEventsCounter = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -3950,18 +3947,14 @@ void BattleTurnPassed(void)
|
||||
gBattleStruct->speedTieBreaks = RandomUniform(RNG_SPEED_TIE, 0, Factorial(MAX_BATTLERS_COUNT) - 1);
|
||||
|
||||
TurnValuesCleanUp(TRUE);
|
||||
if (gBattleOutcome == 0)
|
||||
{
|
||||
if (DoFieldEndTurnEffects())
|
||||
return;
|
||||
if (DoBattlerEndTurnEffects())
|
||||
return;
|
||||
if (HandleWishPerishSongOnTurnEnd())
|
||||
return;
|
||||
}
|
||||
|
||||
if (gBattleOutcome == 0 && DoEndTurnEffects())
|
||||
return;
|
||||
if (BattleArenaTurnEnd())
|
||||
return;
|
||||
if (HandleFaintedMonActions())
|
||||
return;
|
||||
|
||||
gBattleStruct->faintedActionsState = 0;
|
||||
|
||||
TurnValuesCleanUp(FALSE);
|
||||
@ -3995,15 +3988,19 @@ void BattleTurnPassed(void)
|
||||
gChosenMoveByBattler[i] = MOVE_NONE;
|
||||
gBattleStruct->battlerState[i].absentBattlerFlags = gAbsentBattlerFlags & (1u << i);
|
||||
gBattleStruct->monToSwitchIntoId[i] = PARTY_SIZE;
|
||||
gStatuses4[i] &= ~STATUS4_ELECTRIFIED;
|
||||
gBattleMons[i].status2 &= ~STATUS2_FLINCHED;
|
||||
gBattleMons[i].status2 &= ~STATUS2_POWDER;
|
||||
}
|
||||
|
||||
for (i = 0; i < NUM_BATTLE_SIDES; i++)
|
||||
{
|
||||
if (gSideTimers[i].retaliateTimer > 0)
|
||||
gSideTimers[i].retaliateTimer--;
|
||||
|
||||
}
|
||||
|
||||
gFieldStatuses &= ~STATUS_FIELD_ION_DELUGE;
|
||||
|
||||
BattlePutTextOnWindow(gText_EmptyString3, B_WIN_MSG);
|
||||
AssignUsableGimmicks();
|
||||
SetShellSideArmCategory();
|
||||
|
||||
@ -955,7 +955,8 @@ const u16 gTerrainPreventsStringIds[] =
|
||||
|
||||
const u16 gHealingWishStringIds[] =
|
||||
{
|
||||
STRINGID_HEALINGWISHCAMETRUE, STRINGID_LUNARDANCECAMETRUE
|
||||
STRINGID_HEALINGWISHCAMETRUE,
|
||||
STRINGID_LUNARDANCECAMETRUE
|
||||
};
|
||||
|
||||
const u16 gDmgHazardsStringIds[] =
|
||||
|
||||
@ -523,7 +523,7 @@ static void Cmd_presentdamagecalculation(void);
|
||||
static void Cmd_setsafeguard(void);
|
||||
static void Cmd_magnitudedamagecalculation(void);
|
||||
static void Cmd_jumpifnopursuitswitchdmg(void);
|
||||
static void Cmd_unused_bb(void);
|
||||
static void Cmd_tryhealingitem(void);
|
||||
static void Cmd_halvehp(void);
|
||||
static void Cmd_copyfoestats(void);
|
||||
static void Cmd_rapidspinfree(void);
|
||||
@ -782,7 +782,7 @@ void (* const gBattleScriptingCommandsTable[])(void) =
|
||||
Cmd_setsafeguard, //0xB8
|
||||
Cmd_magnitudedamagecalculation, //0xB9
|
||||
Cmd_jumpifnopursuitswitchdmg, //0xBA
|
||||
Cmd_unused_bb, //0xBB
|
||||
Cmd_tryhealingitem, //0xBB
|
||||
Cmd_halvehp, //0xBC
|
||||
Cmd_copyfoestats, //0xBD
|
||||
Cmd_rapidspinfree, //0xBE
|
||||
@ -3935,7 +3935,7 @@ void SetMoveEffect(bool32 primary, bool32 certain)
|
||||
}
|
||||
break;
|
||||
case MOVE_EFFECT_THROAT_CHOP:
|
||||
gDisableStructs[gEffectBattler].throatChopTimer = 2;
|
||||
gDisableStructs[gEffectBattler].throatChopTimer = gBattleTurnCounter + 2;
|
||||
gBattlescriptCurrInstr++;
|
||||
break;
|
||||
case MOVE_EFFECT_INCINERATE:
|
||||
@ -4142,7 +4142,7 @@ void SetMoveEffect(bool32 primary, bool32 certain)
|
||||
else if (!(gStatuses3[gEffectBattler] & STATUS3_HEAL_BLOCK))
|
||||
{
|
||||
gStatuses3[gEffectBattler] |= STATUS3_HEAL_BLOCK;
|
||||
gDisableStructs[gEffectBattler].healBlockTimer = 2;
|
||||
gDisableStructs[gEffectBattler].healBlockTimer = gBattleTurnCounter + 2;
|
||||
BattleScriptPush(gBattlescriptCurrInstr + 1);
|
||||
gBattlescriptCurrInstr = BattleScript_EffectPsychicNoise;
|
||||
}
|
||||
@ -7106,7 +7106,7 @@ static void Cmd_sethealblock(void)
|
||||
else
|
||||
{
|
||||
gStatuses3[gBattlerTarget] |= STATUS3_HEAL_BLOCK;
|
||||
gDisableStructs[gBattlerTarget].healBlockTimer = 5;
|
||||
gDisableStructs[gBattlerTarget].healBlockTimer = gBattleTurnCounter + 5;
|
||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||
}
|
||||
}
|
||||
@ -7760,6 +7760,7 @@ static bool32 DoSwitchInEffectsForBattler(u32 battler)
|
||||
else if ((gBattleStruct->battlerState[battler].storedHealingWish || gBattleStruct->battlerState[battler].storedLunarDance)
|
||||
&& (gBattleMons[battler].hp != gBattleMons[battler].maxHP || gBattleMons[battler].status1 != 0 || B_HEALING_WISH_SWITCH < GEN_8))
|
||||
{
|
||||
gBattlerAttacker = battler;
|
||||
if (gBattleStruct->battlerState[battler].storedHealingWish)
|
||||
{
|
||||
BattleScriptPushCursor();
|
||||
@ -9320,10 +9321,10 @@ u32 IsFlowerVeilProtected(u32 battler)
|
||||
return 0;
|
||||
}
|
||||
|
||||
u32 IsLeafGuardProtected(u32 battler)
|
||||
u32 IsLeafGuardProtected(u32 battler, u32 ability)
|
||||
{
|
||||
if (IsBattlerWeatherAffected(battler, B_WEATHER_SUN))
|
||||
return GetBattlerAbility(battler) == ABILITY_LEAF_GUARD;
|
||||
return ability == ABILITY_LEAF_GUARD;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
@ -9337,7 +9338,7 @@ bool32 IsShieldsDownProtected(u32 battler)
|
||||
u32 IsAbilityStatusProtected(u32 battler)
|
||||
{
|
||||
return IsFlowerVeilProtected(battler)
|
||||
|| IsLeafGuardProtected(battler)
|
||||
|| IsLeafGuardProtected(battler, GetBattlerAbility(battler))
|
||||
|| IsShieldsDownProtected(battler);
|
||||
}
|
||||
|
||||
@ -11169,7 +11170,7 @@ static void Cmd_various(void)
|
||||
case VARIOUS_JUMP_IF_LEAF_GUARD_PROTECTED:
|
||||
{
|
||||
VARIOUS_ARGS(const u8 *jumpInstr);
|
||||
if (IsLeafGuardProtected(battler))
|
||||
if (IsLeafGuardProtected(battler, GetBattlerAbility(battler)))
|
||||
{
|
||||
gBattlerAbility = battler;
|
||||
gBattlescriptCurrInstr = cmd->jumpInstr;
|
||||
@ -13896,7 +13897,7 @@ static void Cmd_setembargo(void)
|
||||
else
|
||||
{
|
||||
gStatuses3[gBattlerTarget] |= STATUS3_EMBARGO;
|
||||
gDisableStructs[gBattlerTarget].embargoTimer = 5;
|
||||
gDisableStructs[gBattlerTarget].embargoTimer = gBattleTurnCounter + 5;
|
||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||
}
|
||||
}
|
||||
@ -14073,8 +14074,18 @@ static void Cmd_jumpifnopursuitswitchdmg(void)
|
||||
}
|
||||
}
|
||||
|
||||
static void Cmd_unused_bb(void)
|
||||
static void Cmd_tryhealingitem(void)
|
||||
{
|
||||
CMD_ARGS();
|
||||
|
||||
if (gItemsInfo[gBattleMons[gBattlerAttacker].item].pocket == POCKET_BERRIES
|
||||
|| GetBattlerHoldEffect(gBattlerAttacker, TRUE) == HOLD_EFFECT_RESTORE_HP) // Edge case for Berry Juice
|
||||
{
|
||||
if (ItemBattleEffects(ITEMEFFECT_TRY_HEALING, gBattlerAttacker, FALSE))
|
||||
return;
|
||||
}
|
||||
|
||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||
}
|
||||
|
||||
// Belly Drum, Fillet Away
|
||||
@ -14528,7 +14539,6 @@ static void Cmd_settorment(void)
|
||||
else
|
||||
{
|
||||
gBattleMons[gBattlerTarget].status2 |= STATUS2_TORMENT;
|
||||
gDisableStructs[gBattlerTarget].tormentTimer = PERMANENT_TORMENT; // permanent
|
||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||
}
|
||||
}
|
||||
@ -14736,43 +14746,17 @@ static void Cmd_trycopyability(void)
|
||||
|
||||
static void Cmd_trywish(void)
|
||||
{
|
||||
CMD_ARGS(u8 turnNumber, const u8 *failInstr);
|
||||
CMD_ARGS(const u8 *failInstr);
|
||||
|
||||
switch (cmd->turnNumber)
|
||||
if (gWishFutureKnock.wishCounter[gBattlerAttacker] <= gBattleTurnCounter)
|
||||
{
|
||||
case 0: // use wish
|
||||
if (gWishFutureKnock.wishCounter[gBattlerAttacker] <= gBattleTurnCounter)
|
||||
{
|
||||
gWishFutureKnock.wishCounter[gBattlerAttacker] = gBattleTurnCounter + 2;
|
||||
gWishFutureKnock.wishPartyId[gBattlerAttacker] = gBattlerPartyIndexes[gBattlerAttacker];
|
||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||
}
|
||||
else
|
||||
{
|
||||
gBattlescriptCurrInstr = cmd->failInstr;
|
||||
}
|
||||
break;
|
||||
case 1: // heal effect
|
||||
PREPARE_MON_NICK_WITH_PREFIX_BUFFER(gBattleTextBuff1, gBattlerTarget, gWishFutureKnock.wishPartyId[gBattlerTarget])
|
||||
if (B_WISH_HP_SOURCE >= GEN_5)
|
||||
{
|
||||
if (GetBattlerSide(gBattlerTarget) == B_SIDE_PLAYER)
|
||||
gBattleStruct->moveDamage[gBattlerTarget] = max(1, GetMonData(&gPlayerParty[gWishFutureKnock.wishPartyId[gBattlerTarget]], MON_DATA_MAX_HP) / 2);
|
||||
else
|
||||
gBattleStruct->moveDamage[gBattlerTarget] = max(1, GetMonData(&gEnemyParty[gWishFutureKnock.wishPartyId[gBattlerTarget]], MON_DATA_MAX_HP) / 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
gBattleStruct->moveDamage[gBattlerTarget] = max(1, GetNonDynamaxMaxHP(gBattlerAttacker) / 2);
|
||||
}
|
||||
|
||||
gBattleStruct->moveDamage[gBattlerTarget] *= -1;
|
||||
if (gBattleMons[gBattlerTarget].hp == gBattleMons[gBattlerTarget].maxHP)
|
||||
gBattlescriptCurrInstr = cmd->failInstr;
|
||||
else
|
||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||
|
||||
break;
|
||||
gWishFutureKnock.wishCounter[gBattlerAttacker] = gBattleTurnCounter + 2;
|
||||
gWishFutureKnock.wishPartyId[gBattlerAttacker] = gBattlerPartyIndexes[gBattlerAttacker];
|
||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||
}
|
||||
else
|
||||
{
|
||||
gBattlescriptCurrInstr = cmd->failInstr;
|
||||
}
|
||||
}
|
||||
|
||||
@ -15005,9 +14989,9 @@ static void Cmd_setuserstatus3(void)
|
||||
{
|
||||
gStatuses3[gBattlerAttacker] |= flags;
|
||||
if (flags & STATUS3_MAGNET_RISE)
|
||||
gDisableStructs[gBattlerAttacker].magnetRiseTimer = 5;
|
||||
gDisableStructs[gBattlerAttacker].magnetRiseTimer = gBattleTurnCounter + 5;
|
||||
if (flags & STATUS3_LASER_FOCUS)
|
||||
gDisableStructs[gBattlerAttacker].laserFocusTimer = 2;
|
||||
gDisableStructs[gBattlerAttacker].laserFocusTimer = gBattleTurnCounter + 2;
|
||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||
}
|
||||
}
|
||||
@ -16144,7 +16128,7 @@ static void Cmd_settelekinesis(void)
|
||||
else
|
||||
{
|
||||
gStatuses3[gBattlerTarget] |= STATUS3_TELEKINESIS;
|
||||
gDisableStructs[gBattlerTarget].telekinesisTimer = 3;
|
||||
gDisableStructs[gBattlerTarget].telekinesisTimer = gBattleTurnCounter + 3;
|
||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||
}
|
||||
}
|
||||
|
||||
1483
src/battle_util.c
1483
src/battle_util.c
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -47,3 +47,45 @@ SINGLE_BATTLE_TEST("Emergency Exit switches out when going below 50% max-HP but
|
||||
ABILITY_POPUP(opponent, ABILITY_EMERGENCY_EXIT);
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Emergency Exit activ out when taking taking residual damage and falling under 50% max-hp damage - Burn")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_GOLISOPOD) { Ability(ABILITY_EMERGENCY_EXIT); MaxHP(263); HP(134); Status1(STATUS1_BURN); };
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { SEND_OUT(opponent, 1); }
|
||||
} SCENE {
|
||||
HP_BAR(opponent);
|
||||
ABILITY_POPUP(opponent, ABILITY_EMERGENCY_EXIT);
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Emergency Exit activ out when taking taking residual damage and falling under 50% max-hp damage - Weather")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_GOLISOPOD) { Ability(ABILITY_EMERGENCY_EXIT); MaxHP(263); HP(134); };
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_SANDSTORM); SEND_OUT(opponent, 1); }
|
||||
} SCENE {
|
||||
HP_BAR(opponent);
|
||||
ABILITY_POPUP(opponent, ABILITY_EMERGENCY_EXIT);
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Emergency Exit activ out when taking taking residual damage and falling under 50% max-hp damage - Salt Cure")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_GOLISOPOD) { Ability(ABILITY_EMERGENCY_EXIT); MaxHP(263); HP(160); };
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_SALT_CURE); SEND_OUT(opponent, 1); }
|
||||
} SCENE {
|
||||
HP_BAR(opponent);
|
||||
ABILITY_POPUP(opponent, ABILITY_EMERGENCY_EXIT);
|
||||
}
|
||||
}
|
||||
|
||||
@ -107,11 +107,11 @@ DOUBLE_BATTLE_TEST("Court Change used by the player swaps Mist, Safeguard, Auror
|
||||
MESSAGE("Wynaut used Court Change!");
|
||||
MESSAGE("Wynaut swapped the battle effects affecting each side of the field!");
|
||||
// The effects now end for the player side.
|
||||
MESSAGE("Your team's Mist wore off!");
|
||||
MESSAGE("Your team is no longer protected by Safeguard!");
|
||||
MESSAGE("Your team's Mist wore off!");
|
||||
MESSAGE("Your team's Reflect wore off!");
|
||||
MESSAGE("Your team's Aurora Veil wore off!");
|
||||
MESSAGE("Your team's Tailwind petered out!");
|
||||
MESSAGE("Your team's Aurora Veil wore off!");
|
||||
MESSAGE("Your team's Light Screen wore off!");
|
||||
}
|
||||
}
|
||||
@ -144,11 +144,12 @@ DOUBLE_BATTLE_TEST("Court Change used by the opponent swaps Mist, Safeguard, Aur
|
||||
MESSAGE("The opposing Wynaut used Court Change!");
|
||||
MESSAGE("The opposing Wynaut swapped the battle effects affecting each side of the field!");
|
||||
// The effects now end for the player side.
|
||||
MESSAGE("The opposing team's Mist wore off!");
|
||||
MESSAGE("The snow stopped.");
|
||||
MESSAGE("The opposing team is no longer protected by Safeguard!");
|
||||
MESSAGE("The opposing team's Mist wore off!");
|
||||
MESSAGE("The opposing team's Reflect wore off!");
|
||||
MESSAGE("The opposing team's Aurora Veil wore off!");
|
||||
MESSAGE("The opposing team's Tailwind petered out!");
|
||||
MESSAGE("The opposing team's Aurora Veil wore off!");
|
||||
MESSAGE("The opposing team's Light Screen wore off!");
|
||||
}
|
||||
}
|
||||
|
||||
25
test/battle/move_effect/wish.c
Normal file
25
test/battle/move_effect/wish.c
Normal file
@ -0,0 +1,25 @@
|
||||
#include "global.h"
|
||||
#include "test/battle.h"
|
||||
|
||||
ASSUMPTIONS
|
||||
{
|
||||
ASSUME(GetMoveEffect(MOVE_WISH) == EFFECT_WISH);
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Wish restores 50% of max player HP")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WYNAUT) { HP(50); MaxHP(100); }
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_WISH); }
|
||||
TURN { }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_WISH, player);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, player);
|
||||
MESSAGE("Wynaut's wish came true!");
|
||||
HP_BAR(player, hp: 100);
|
||||
MESSAGE("Wynaut's HP was restored.");
|
||||
}
|
||||
}
|
||||
|
||||
@ -24,22 +24,24 @@ SINGLE_BATTLE_TEST("Throat Chop prevents the usage of sound moves")
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Throat Chop won't work through a substitute")
|
||||
SINGLE_BATTLE_TEST("Throat Chop prevents sound base moves for 2 turns")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_INCINEROAR) { Speed(100); };
|
||||
OPPONENT(SPECIES_WOBBUFFET) { Speed(50); };
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WOBBUFFET) { Moves(MOVE_HYPER_VOICE, MOVE_ALLURING_VOICE, MOVE_OVERDRIVE, MOVE_ROUND); }
|
||||
} WHEN {
|
||||
TURN { MOVE(opponent, MOVE_SUBSTITUTE); }
|
||||
TURN { MOVE(player, MOVE_THROAT_CHOP); MOVE(opponent, MOVE_HYPER_VOICE); }
|
||||
TURN {}
|
||||
TURN { MOVE(opponent, MOVE_HYPER_VOICE); MOVE(player, MOVE_THROAT_CHOP); }
|
||||
TURN { FORCED_MOVE(opponent); }
|
||||
TURN { MOVE(opponent, MOVE_HYPER_VOICE); MOVE(player, MOVE_THROAT_CHOP); }
|
||||
TURN { FORCED_MOVE(opponent); }
|
||||
TURN { MOVE(opponent, MOVE_HYPER_VOICE); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_SUBSTITUTE, opponent);
|
||||
HP_BAR(opponent);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_HYPER_VOICE, opponent);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_THROAT_CHOP, player);
|
||||
NONE_OF {
|
||||
MESSAGE("The effects of Throat Chop prevent the opposing Wobbuffet from using certain moves!");
|
||||
}
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_STRUGGLE, opponent);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_HYPER_VOICE, opponent);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_THROAT_CHOP, player);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_STRUGGLE, opponent);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_HYPER_VOICE, opponent);
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user