sovereignx/include/battle_util.h

255 lines
12 KiB
C
Raw Normal View History

2017-10-06 16:06:45 +01:00
#ifndef GUARD_BATTLE_UTIL_H
#define GUARD_BATTLE_UTIL_H
#define MOVE_LIMITATION_ZEROMOVE (1 << 0)
#define MOVE_LIMITATION_PP (1 << 1)
#define MOVE_LIMITATION_DISABLED (1 << 2)
#define MOVE_LIMITATION_TORMENTED (1 << 3)
#define MOVE_LIMITATION_TAUNT (1 << 4)
#define MOVE_LIMITATION_IMPRISON (1 << 5)
2022-08-24 03:40:04 +01:00
#define MOVE_LIMITATION_ENCORE (1 << 6)
#define MOVE_LIMITATION_CHOICE_ITEM (1 << 7)
#define MOVE_LIMITATION_ASSAULT_VEST (1 << 8)
#define MOVE_LIMITATION_GRAVITY (1 << 9)
#define MOVE_LIMITATION_HEAL_BLOCK (1 << 10)
#define MOVE_LIMITATION_BELCH (1 << 11)
#define MOVE_LIMITATION_THROAT_CHOP (1 << 12)
#define MOVE_LIMITATION_STUFF_CHEEKS (1 << 13)
#define MOVE_LIMITATION_CANT_USE_TWICE (1 << 14)
#define MOVE_LIMITATION_PLACEHOLDER (1 << 15)
2022-08-24 03:40:04 +01:00
#define MOVE_LIMITATIONS_ALL 0xFFFF
2017-10-06 16:06:45 +01:00
2021-10-30 03:32:19 +01:00
#define ABILITYEFFECT_ON_SWITCHIN 0
#define ABILITYEFFECT_ENDTURN 1
#define ABILITYEFFECT_MOVES_BLOCK 2
#define ABILITYEFFECT_ABSORBING 3
#define ABILITYEFFECT_MOVE_END_ATTACKER 4
#define ABILITYEFFECT_MOVE_END 5
#define ABILITYEFFECT_IMMUNITY 6
#define ABILITYEFFECT_SYNCHRONIZE 7
#define ABILITYEFFECT_ATK_SYNCHRONIZE 8
#define ABILITYEFFECT_TRACE1 9
#define ABILITYEFFECT_TRACE2 10
#define ABILITYEFFECT_MOVE_END_OTHER 11
#define ABILITYEFFECT_NEUTRALIZINGGAS 12
#define ABILITYEFFECT_FIELD_SPORT 13 // Only used if B_SPORT_TURNS >= GEN_6
#define ABILITYEFFECT_ON_WEATHER 14
#define ABILITYEFFECT_ON_TERRAIN 15
#define ABILITYEFFECT_SWITCH_IN_TERRAIN 16
#define ABILITYEFFECT_SWITCH_IN_WEATHER 17
#define ABILITYEFFECT_OPPORTUNIST 18
2021-10-30 03:32:19 +01:00
// Special cases
#define ABILITYEFFECT_MUD_SPORT 252 // Only used if B_SPORT_TURNS >= GEN_6
#define ABILITYEFFECT_WATER_SPORT 253 // Only used if B_SPORT_TURNS >= GEN_6
2017-10-06 16:06:45 +01:00
2021-10-04 15:21:03 +01:00
// For the first argument of ItemBattleEffects, to deteremine which block of item effects to try
#define ITEMEFFECT_ON_SWITCH_IN 0
#define ITEMEFFECT_NORMAL 1
#define ITEMEFFECT_DUMMY 2 // Unused, empty
#define ITEMEFFECT_MOVE_END 3
#define ITEMEFFECT_KINGSROCK 4
#define ITEMEFFECT_TARGET 5
#define ITEMEFFECT_ORBS 6
#define ITEMEFFECT_LIFEORB_SHELLBELL 7
2022-05-13 21:21:41 +01:00
#define ITEMEFFECT_USE_LAST_ITEM 8 // move end effects for just the battler, not whole field
2017-10-06 16:06:45 +01:00
#define WEATHER_HAS_EFFECT ((!IsAbilityOnField(ABILITY_CLOUD_NINE) && !IsAbilityOnField(ABILITY_AIR_LOCK)))
2017-10-06 16:06:45 +01:00
#define IS_WHOLE_SIDE_ALIVE(battler) ((IsBattlerAlive(battler) && IsBattlerAlive(BATTLE_PARTNER(battler))))
#define IS_ALIVE_AND_PRESENT(battler) (IsBattlerAlive(battler) && IsBattlerSpritePresent(battler))
2019-03-06 11:09:34 +00:00
2019-05-20 11:03:00 +01:00
// for Natural Gift and Fling
struct TypePower
{
u8 type;
u8 power;
u16 effect;
};
enum
{
CANCELLER_FLAGS,
CANCELLER_SKY_DROP,
CANCELLER_ASLEEP,
CANCELLER_FROZEN,
CANCELLER_TRUANT,
CANCELLER_RECHARGE,
CANCELLER_FLINCH,
CANCELLER_DISABLED,
CANCELLER_GRAVITY,
CANCELLER_HEAL_BLOCKED,
CANCELLER_TAUNTED,
CANCELLER_IMPRISONED,
CANCELLER_CONFUSED,
CANCELLER_PARALYSED,
CANCELLER_IN_LOVE,
CANCELLER_BIDE,
CANCELLER_THAW,
CANCELLER_POWDER_MOVE,
CANCELLER_POWDER_STATUS,
CANCELLER_THROAT_CHOP,
CANCELLER_MULTIHIT_MOVES,
CANCELLER_Z_MOVES,
CANCELLER_END,
CANCELLER_PSYCHIC_TERRAIN,
CANCELLER_END2,
};
2019-05-20 11:03:00 +01:00
extern const struct TypePower gNaturalGiftTable[];
2021-06-25 20:37:59 +01:00
void HandleAction_ThrowBall(void);
bool32 IsAffectedByFollowMe(u32 battlerAtk, u32 defSide, u32 move);
void HandleAction_UseMove(void);
void HandleAction_Switch(void);
void HandleAction_UseItem(void);
bool32 TryRunFromBattle(u32 battler);
void HandleAction_Run(void);
void HandleAction_WatchesCarefully(void);
void HandleAction_SafariZoneBallThrow(void);
void HandleAction_ThrowPokeblock(void);
void HandleAction_GoNear(void);
void HandleAction_SafariZoneRun(void);
void HandleAction_WallyBallThrow(void);
void HandleAction_TryFinish(void);
void HandleAction_NothingIsFainted(void);
void HandleAction_ActionFinished(void);
2018-02-08 10:17:41 +00:00
u8 GetBattlerForBattleScript(u8 caseId);
bool32 IsBattlerMarkedForControllerExec(u32 battler);
void MarkBattlerForControllerExec(u32 battler);
void MarkBattlerReceivedLinkData(u32 battler);
const u8* CancelMultiTurnMoves(u32 battler);
bool32 WasUnableToUseMove(u32 battler);
void PrepareStringBattle(u16 stringId, u32 battler);
2017-10-06 16:06:45 +01:00
void ResetSentPokesToOpponentValue(void);
void OpponentSwitchInResetSentPokesToOpponentValue(u32 battler);
void UpdateSentPokesToOpponentValue(u32 battler);
void BattleScriptPush(const u8 *bsPtr);
2017-10-06 16:06:45 +01:00
void BattleScriptPushCursor(void);
void BattleScriptPop(void);
2023-08-30 09:18:31 +01:00
u32 TrySetCantSelectMoveBattleScript(u32 battler);
u8 CheckMoveLimitations(u32 battler, u8 unusableMoves, u16 check);
2023-08-30 09:18:31 +01:00
bool32 AreAllMovesUnusable(u32 battler);
u8 GetImprisonedMovesCount(u32 battler, u16 move);
2018-07-21 11:10:08 +01:00
u8 DoFieldEndTurnEffects(void);
2020-04-13 14:00:17 +01:00
s32 GetDrainedBigRootHp(u32 battler, s32 hp);
2018-07-18 21:07:48 +01:00
u8 DoBattlerEndTurnEffects(void);
bool32 HandleWishPerishSongOnTurnEnd(void);
bool32 HandleFaintedMonActions(void);
2018-08-11 11:16:00 +01:00
void TryClearRageAndFuryCutter(void);
u8 AtkCanceller_UnableToUseMove(u32 moveType);
void SetAtkCancellerForCalledMove(void);
2018-12-01 10:35:49 +00:00
u8 AtkCanceller_UnableToUseMove2(void);
bool32 HasNoMonsToSwitch(u32 battler, u8 r1, u8 r2);
bool32 TryChangeBattleWeather(u32 battler, u32 weatherEnumId, bool32 viaAbility);
u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32 moveArg);
bool32 TryPrimalReversion(u32 battler);
bool32 IsNeutralizingGasOnField(void);
bool32 IsMoldBreakerTypeAbility(u32 ability);
u32 GetBattlerAbility(u32 battler);
2023-08-30 09:18:31 +01:00
u32 IsAbilityOnSide(u32 battler, u32 ability);
u32 IsAbilityOnOpposingSide(u32 battler, u32 ability);
u32 IsAbilityOnField(u32 ability);
2023-08-30 09:18:31 +01:00
u32 IsAbilityOnFieldExcept(u32 battler, u32 ability);
u32 IsAbilityPreventingEscape(u32 battler);
bool32 IsBattlerProtected(u32 battler, u32 move);
2023-08-30 09:18:31 +01:00
bool32 CanBattlerEscape(u32 battler); // no ability check
void BattleScriptExecute(const u8 *BS_ptr);
void BattleScriptPushCursorAndCallback(const u8 *BS_ptr);
u8 ItemBattleEffects(u8 caseID, u32 battler, bool32 moveTurn);
void ClearVariousBattlerFlags(u32 battler);
2017-10-06 16:06:45 +01:00
void HandleAction_RunBattleScript(void);
2023-08-30 09:18:31 +01:00
u32 SetRandomTarget(u32 battler);
2021-10-16 21:10:45 +01:00
u32 GetMoveTarget(u16 move, u8 setTarget);
2017-12-02 13:08:55 +00:00
u8 IsMonDisobedient(void);
u32 GetBattlerHoldEffect(u32 battler, bool32 checkNegating);
u32 GetBattlerHoldEffectParam(u32 battler);
bool32 IsMoveMakingContact(u32 move, u32 battlerAtk);
bool32 IsBattlerGrounded(u32 battler);
bool32 IsBattlerAlive(u32 battler);
u32 GetMoveSlot(u16 *moves, u32 move);
u32 GetBattlerWeight(u32 battler);
2023-07-06 12:41:16 +01:00
u32 CalcRolloutBasePower(u32 battlerAtk, u32 basePower, u32 rolloutTimer);
u32 CalcFuryCutterBasePower(u32 basePower, u32 furyCutterCounter);
s32 CalculateMoveDamage(u32 move, u32 battlerAtk, u32 battlerDef, u32 moveType, s32 fixedBasePower, bool32 isCrit, bool32 randomFactor, bool32 updateFlags);
2023-09-13 23:07:41 +01:00
s32 CalculateMoveDamageVars(u32 move, u32 battlerAtk, u32 battlerDef, u32 moveType, s32 fixedBasePower, uq4_12_t typeEffectivenessModifier,
u32 weather, bool32 isCrit, u32 holdEffectAtk, u32 holdEffectDef, u32 abilityAtk, u32 abilityDef);
2023-09-14 10:05:00 +01:00
uq4_12_t CalcTypeEffectivenessMultiplier(u32 move, u32 moveType, u32 battlerAtk, u32 battlerDef, u32 defAbility, bool32 recordAbilities);
uq4_12_t CalcPartyMonTypeEffectivenessMultiplier(u16 move, u16 speciesDef, u16 abilityDef);
uq4_12_t GetTypeModifier(u32 atkType, u32 defType);
s32 GetStealthHazardDamage(u8 hazardType, u32 battler);
2022-05-02 04:04:16 +01:00
s32 GetStealthHazardDamageByTypesAndHP(u8 hazardType, u8 type1, u8 type2, u32 maxHp);
bool32 CanMegaEvolve(u32 battler);
bool32 CanUltraBurst(u32 battler);
bool32 IsBattlerMegaEvolved(u32 battler);
bool32 IsBattlerPrimalReverted(u32 battler);
bool32 IsBattlerUltraBursted(u32 battler);
u16 GetBattleFormChangeTargetSpecies(u32 battler, u16 method);
bool32 TryBattleFormChange(u32 battler, u16 method);
2018-09-29 14:43:56 +01:00
bool32 DoBattlersShareType(u32 battler1, u32 battler2);
bool32 CanBattlerGetOrLoseItem(u32 battler, u16 itemId);
2023-08-30 09:18:31 +01:00
u32 GetIllusionMonSpecies(u32 battler);
struct Pokemon *GetIllusionMonPtr(u32 battler);
void ClearIllusionMon(u32 battler);
bool32 SetIllusionMon(struct Pokemon *mon, u32 battler);
bool32 ShouldGetStatBadgeBoost(u16 flagId, u32 battler);
u8 GetBattleMoveCategory(u32 moveId);
bool32 CanFling(u32 battler);
2020-12-13 22:02:21 +00:00
bool32 IsTelekinesisBannedSpecies(u16 species);
bool32 IsHealBlockPreventingMove(u32 battler, u32 move);
2023-08-30 09:18:31 +01:00
bool32 HasEnoughHpToEatBerry(u32 battler, u32 hpFraction, u32 itemId);
bool32 IsPartnerMonFromSameTrainer(u32 battler);
u8 GetCategoryBasedOnStats(u32 battler);
2024-01-30 04:27:46 +00:00
bool32 MoveIsAffectedBySheerForce(u16 move);
bool32 TestSheerForceFlag(u32 battler, u16 move);
void TryRestoreHeldItems(void);
bool32 CanStealItem(u32 battlerStealing, u32 battlerItem, u16 item);
void TrySaveExchangedItem(u32 battler, u16 stolenItem);
bool32 IsPartnerMonFromSameTrainer(u32 battler);
u8 TryHandleSeed(u32 battler, u32 terrainFlag, u8 statId, u16 itemId, bool32 execute);
bool32 IsBattlerAffectedByHazards(u32 battler, bool32 toxicSpikes);
void SortBattlersBySpeed(u8 *battlers, bool32 slowToFast);
bool32 CompareStat(u32 battler, u8 statId, u8 cmpTo, u8 cmpKind);
bool32 TryRoomService(u32 battler);
void BufferStatChange(u32 battler, u8 statId, u8 stringId);
bool32 BlocksPrankster(u16 move, u32 battlerPrankster, u32 battlerDef, bool32 checkTarget);
u16 GetUsedHeldItem(u32 battler);
bool32 IsBattlerWeatherAffected(u32 battler, u32 weatherFlags);
u32 GetBattlerMoveTargetType(u32 battler, u32 move);
bool32 CanTargetBattler(u32 battlerAtk, u32 battlerDef, u16 move);
void CopyMonLevelAndBaseStatsToBattleMon(u32 battler, struct Pokemon *mon);
void CopyMonAbilityAndTypesToBattleMon(u32 battler, struct Pokemon *mon);
2022-10-21 06:08:37 +01:00
void RecalcBattlerStats(u32 battler, struct Pokemon *mon);
bool32 IsAlly(u32 battlerAtk, u32 battlerDef);
2023-09-08 03:18:18 +01:00
bool32 IsGen6ExpShareEnabled(void);
2023-12-30 08:42:53 +00:00
bool32 MoveHasMoveEffect(u32 move, u32 moveEffect);
bool32 MoveHasMoveEffectWithChance(u32 move, u32 moveEffect, u32 chance);
bool32 MoveHasMoveEffectSelf(u32 move, u32 moveEffect);
bool32 MoveHasMoveEffectSelfArg(u32 move, u32 moveEffect, u32 argument);
Secondary effects overhaul minor follow-up (#4062) * settwoturnstring command * Unified two-turn attacks and Meteor Beam To do: Solar Beam * Solar Beam Also fixed various function, removed EFFECT_GUST (who knows why that exists?) * Updated Solar Beam + tests * Redid two turn move + animations logic Removed pointless various function; to do: remove Skull Bash, fix AI test * Removed now-pointless flag * Removed Skull Bash And temporarily commented out failing AI tests * Removed Sky Uppercut effect Not sure when or why this was ever necessary * Removed BattleScript_EffectSemiInvulnerable Now uses BattleScript_EffectTwoTurnsAttack. Kept the effect; used the argument field to determine which STATUS3 such moves should apply but added a function to jump over weather checks in BattleScript_EffectTwoTurnsAttack if the current move is semi-invulnerable (since the instant-fire weather check and STATUS3 use the same field) * Applied review changes * Replaced VARIOUS with callnative Tried to fix test but couldn't :/ wtf is going on * Fixed one AI test Cant fix the other... * Added KNOWN_FAILING to failing AI tests Separated them out into their own test * Optimised script, overhauled charge turn string setting Condensed multiple confusing macros into one, jumpifweathercheckchargeeffects. Script now tweaked and trimmed, string ids for charge turns now added to argument along with status3 (thanks to compression macro) and instant-fire-weather for semi-invulnerable and two-turn moves respectively. Also introduced a savedStringId in gBattleScripting to make string selection work. * Unified two turn move tests + minor corrections * Added semi-invulnerable move tests Set the Razor Wind test to known failing - something to do with its animation? --------- Co-authored-by: Alex <93446519+AlexOn1ine@users.noreply.github.com>
2024-02-04 22:02:59 +00:00
bool32 MoveHasChargeTurnMoveEffect(u32 move);
bool32 CanSleep(u32 battler);
bool32 CanBePoisoned(u32 battlerAttacker, u32 battlerTarget);
bool32 CanBeBurned(u32 battler);
bool32 CanBeParalyzed(u32 battler);
bool32 CanBeFrozen(u32 battler);
bool32 CanGetFrostbite(u32 battler);
bool32 CanBeConfused(u32 battler);
bool32 IsBattlerTerrainAffected(u32 battler, u32 terrainFlag);
u32 GetBattlerAffectionHearts(u32 battler);
u32 CountBattlerStatIncreases(u32 battler, bool32 countEvasionAcc);
2022-12-06 09:18:18 +00:00
bool32 IsMyceliumMightOnField(void);
bool32 ChangeTypeBasedOnTerrain(u32 battler);
void RemoveConfusionStatus(u32 battler);
u8 GetBattlerGender(u32 battler);
bool32 AreBattlersOfOppositeGender(u32 battler1, u32 battler2);
bool32 AreBattlersOfSameGender(u32 battler1, u32 battler2);
u32 CalcSecondaryEffectChance(u32 battler, u32 battlerAbility, const struct AdditionalEffect *additionalEffect);
bool32 MoveEffectIsGuaranteed(u32 battler, u32 battlerAbility, const struct AdditionalEffect *additionalEffect);
u8 GetBattlerType(u32 battler, u8 typeIndex);
Added support for XY's Sky Battles (#2950) * Original implementation from Phlayne * Moved Sky Battle Flag / Var into a config * Optimized existing code and fixed existing bugs Added error message for when sky battle var and flag are not set Merged CanDoSkyBattle and PrepareSkyBattle into one special * Added compatibility for Gen7+ * Commented out Volt Crash from banned moves * Cleaned up debug scripts from testing * Fixed bug where player did not white out even if they had no healthy Pokémon and only an egg Zeroed out both Sky Battle configs * Removed extra include from src/field_specials.c Removed extra line break in src/battle_script_commands.c * Added FLAG_DISABLED_IN_SKY_BATTLE Added FLAG_DISABLED_IN_SKY_BATTLE to appropriate moves * Changed DoesSkyBattleCancelCurrentMove to look at move flags * Fixed alignment and spacing in battle_moves.h * Added FLAG_DISABLED_IN_SKY_BATTLE to Sticky Web * Added FLAG_DISABLED_IN_SKY_BATTLE to Steel Roller * Disabled the ability to change Battle Terrain when Sky Battle is happening Stopped Ceaseless Edge from spawning Spikes when Sky Battle is happening Added B_SKY_BATTLE_STRICT_MECHANICS config * Fixed bug with SKY_BATTLE_STRICT_MECHANICS where conditions were not consistently being applied * Add rulesVariants to the BattleStruct Added skyBattle check in AllocateBattleResources * Replaced B_FLAG_SKY_BATTLE checks with rulesVariants.skyBattle checks * Fixed debug script * Reverted include/config/battle.h * Fixed spacing and placement of functions * Fixed debug script omission Fixed bug where Spikes did not set from Ceaseless Edge and Stone Axe * Added FLAG_DISABLED_IN_SKY_BATTLE to Psychic Terrain * Addressed DizzyEgg PR feedback * Forgot a file in last commit * Addressed feedback from DizzyEggg * Address Lunos' PR feedback * Update specials.inc Added an empty line at the end of data/specials.inc * Fixed spacing * Apply suggestions from code review Co-authored-by: Eduardo Quezada D'Ottone <eduardo602002@gmail.com> * Updated skyBattleBanned and HandleBattleVariantEndParty to use correct names * Removed STRICT_MOVES and STRICT_MECHANICS * Fixed minor spacing issues with merge * Merged in upcoming * Implemented feedback from Jasper https://github.com/rh-hideout/pokeemerald-expansion/pull/2950/files/5da6117d1bc725900c6386e62ab719f8e1695027 --------- Co-authored-by: Eduardo Quezada D'Ottone <eduardo602002@gmail.com>
2023-11-26 15:59:44 +00:00
bool8 CanMonParticipateInSkyBattle(struct Pokemon *mon);
bool8 IsMonBannedFromSkyBattles(u16 species);
2024-01-11 18:02:48 +00:00
void RemoveBattlerType(u32 battler, u8 type);
2017-10-06 16:06:45 +01:00
#endif // GUARD_BATTLE_UTIL_H