sovereignx/include/battle_util.h

325 lines
13 KiB
C
Raw Permalink 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
enum MoveBlocked
{
MOVE_BLOCKED_BY_NO_ABILITY,
MOVE_BLOCKED_BY_SOUNDPROOF_OR_BULLETPROOF,
MOVE_BLOCKED_BY_DAZZLING,
MOVE_BLOCKED_BY_PARTNER_DAZZLING,
MOVE_BLOCKED_BY_GOOD_AS_GOLD,
};
enum MoveAbsorbed
{
MOVE_ABSORBED_BY_NO_ABILITY,
MOVE_ABSORBED_BY_DRAIN_HP_ABILITY,
MOVE_ABSORBED_BY_STAT_INCREASE_ABILITY,
MOVE_ABSORBED_BY_BOOST_FLASH_FIRE,
};
enum {
ABILITYEFFECT_ON_SWITCHIN,
ABILITYEFFECT_ENDTURN,
ABILITYEFFECT_MOVES_BLOCK,
ABILITYEFFECT_WOULD_BLOCK, // Checks immunity without triggering a script
ABILITYEFFECT_ABSORBING,
ABILITYEFFECT_WOULD_ABSORB, // Checks immunity without triggering a script
ABILITYEFFECT_MOVE_END_ATTACKER,
ABILITYEFFECT_MOVE_END,
ABILITYEFFECT_IMMUNITY,
ABILITYEFFECT_SYNCHRONIZE,
ABILITYEFFECT_ATK_SYNCHRONIZE,
ABILITYEFFECT_MOVE_END_OTHER,
ABILITYEFFECT_NEUTRALIZINGGAS,
ABILITYEFFECT_FIELD_SPORT, // Only used if B_SPORT_TURNS >= GEN_6
ABILITYEFFECT_ON_WEATHER,
ABILITYEFFECT_ON_TERRAIN,
ABILITYEFFECT_SWITCH_IN_TERRAIN,
ABILITYEFFECT_SWITCH_IN_WEATHER,
ABILITYEFFECT_OPPORTUNIST,
ABILITYEFFECT_SWITCH_IN_STATUSES,
};
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
enum ItemEffect
{
ITEMEFFECT_NONE,
ITEMEFFECT_ON_SWITCH_IN,
ITEMEFFECT_ON_SWITCH_IN_FIRST_TURN,
ITEMEFFECT_NORMAL,
ITEMEFFECT_MOVE_END,
ITEMEFFECT_KINGSROCK,
ITEMEFFECT_TARGET,
ITEMEFFECT_ORBS,
ITEMEFFECT_LIFEORB_SHELLBELL,
ITEMEFFECT_USE_LAST_ITEM, // move end effects for just the battler, not whole field
ITEMEFFECT_STATS_CHANGED, // For White Herb and Eject Pack
};
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
// Lowest and highest percentages used for damage roll calculations
#define DMG_ROLL_PERCENT_LO 85
#define DMG_ROLL_PERCENT_HI 100
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_STANCE_CHANGE_1,
CANCELLER_ASLEEP,
CANCELLER_FROZEN,
CANCELLER_OBEDIENCE,
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_STANCE_CHANGE_2,
CANCELLER_POWDER_MOVE,
CANCELLER_POWDER_STATUS,
CANCELLER_THROAT_CHOP,
CANCELLER_EXPLODING_DAMP,
CANCELLER_MULTIHIT_MOVES,
CANCELLER_Z_MOVES,
CANCELLER_END,
CANCELLER_PSYCHIC_TERRAIN,
CANCELLER_END2,
};
enum {
OBEYS,
DISOBEYS_LOAFS,
DISOBEYS_HITS_SELF,
DISOBEYS_FALL_ASLEEP,
DISOBEYS_WHILE_ASLEEP,
DISOBEYS_RANDOM_MOVE,
};
2019-05-20 11:03:00 +01:00
extern const struct TypePower gNaturalGiftTable[];
struct DamageCalculationData
{
u32 battlerAtk:3;
u32 battlerDef:3;
u32 move:16;
u32 moveType:5;
u32 isCrit:1;
u32 randomFactor:1;
u32 updateFlags:1;
u32 padding:2;
};
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 CanAbilityBlockMove(u32 battlerAtk, u32 battlerDef, u32 move, u32 abilityDef);
u32 CanPartnerAbilityBlockMove(u32 battlerAtk, u32 battlerDef, u32 move, u32 abilityDef);
u32 CanAbilityAbsorbMove(u32 battlerAtk, u32 battlerDef, u32 abilityDef, u32 move, u32 moveType);
u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32 moveArg);
bool32 TryPrimalReversion(u32 battler);
bool32 IsNeutralizingGasOnField(void);
2024-07-26 20:11:16 +01:00
bool32 IsMoldBreakerTypeAbility(u32 battler, 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 battlerAtk, u32 battlerDef, 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);
u32 ItemBattleEffects(enum ItemEffect, 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);
u8 GetAttackerObedienceForAction();
u32 GetBattlerHoldEffect(u32 battler, bool32 checkNegating);
u32 GetBattlerHoldEffectIgnoreAbility(u32 battler, bool32 checkNegating);
u32 GetBattlerHoldEffectInternal(u32 battler, bool32 checkNegating, bool32 checkAbility);
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(struct DamageCalculationData *damageCalcData, u32 fixedBasePower);
s32 CalculateMoveDamageVars(struct DamageCalculationData *damageCalcData, u32 fixedBasePower, uq4_12_t typeEffectivenessModifier,
u32 weather, 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);
uq4_12_t GetOverworldTypeEffectiveness(struct Pokemon *mon, u8 moveType);
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);
Gimmick Refactor (#4449) * consolidated gimmick checks, triggers, communication, and activation; updated test runner * fixed improper use of .usableGimmick * cleaning up battle_dynamax.c, changing function args to u32s * fixed '#ifdef TESTING' causing errors * updated z-moves to use gimmick interface, pared down redundancies; no AI/tests * added support for z-moves in tests, consolidated gimmick fields * removed ShouldUseMaxMove and .usingMaxMove * renamed TryChangeZIndicator, updated z move display * added several z-move tests and fixed various z-move interactions; fixed z-move category calc * fixed useless battler arg in GetTypeBasedZMove * added basic test check for bad Z-Move or Mega usage * reworked test runner gimmick functionality; added support for Ultra Burst + Z-Move to test Light That Burns the Sky * fixed gimmick test logic; fixed damage category override * fixed mega rayquaza test fail * consolidated gimmick indicator logic; added graphics to gGimmicksInfo * removed TeraData struct * reimplemented AI logic for Z-Moves; no changes * updated Z-Move and Ultra Burst trigger gfx * added testrunner check for multiple gimmick use * fixed duplicate z-move call in test * reorganized data/graphics/gimmicks.h * added signature Z-Move ability tests; implemented Guardian of Alola * fixed bad test update * fixed Thousand Arrows not affecting Tera Flying; clean-up * fixed -ate tests * fixed tera tests * fixed tera tests really * fixed last batch of tests * fixed -ate mega test again * code review * code review pt.2 * tweaked CanTera again * dynamax flag only required for player
2024-06-22 21:25:40 +01:00
void ActivateMegaEvolution(u32 battler);
void ActivateUltraBurst(u32 battler);
bool32 IsBattlerMegaEvolved(u32 battler);
bool32 IsBattlerPrimalReverted(u32 battler);
bool32 IsBattlerUltraBursted(u32 battler);
u16 GetBattleFormChangeTargetSpecies(u32 battler, u16 method);
bool32 TryBattleFormChange(u32 battler, u32 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);
bool32 IsBelchPreventingMove(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);
void SetShellSideArmCategory(void);
bool32 MoveIsAffectedBySheerForce(u32 move);
2024-02-26 06:11:21 +00:00
bool32 TestIfSheerForceAffected(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);
u32 TryHandleSeed(u32 battler, u32 terrainFlag, u32 statId, u32 itemId, enum ItemEffect caseID);
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 PickupHasValidTarget(u32 battler);
bool32 CantPickupItem(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);
2024-02-26 05:21:38 +00:00
bool32 MoveHasAdditionalEffect(u32 move, u32 moveEffect);
bool32 MoveHasAdditionalEffectWithChance(u32 move, u32 moveEffect, u32 chance);
bool32 MoveHasAdditionalEffectSelf(u32 move, u32 moveEffect);
bool32 MoveHasAdditionalEffectSelfArg(u32 move, u32 moveEffect, u32 argument);
bool32 MoveHasChargeTurnAdditionalEffect(u32 move);
bool32 CanTargetPartner(u32 battlerAtk, u32 battlerDef);
bool32 TargetFullyImmuneToCurrMove(u32 battlerAtk, u32 battlerDef);
2017-10-06 16:06:45 +01:00
bool32 CanBeSlept(u32 battler, u32 ability);
bool32 CanBePoisoned(u32 battlerAtk, u32 battlerDef, u32 defAbility);
bool32 CanBeBurned(u32 battler, u32 ability);
bool32 CanBeParalyzed(u32 battler, u32 ability);
bool32 CanBeFrozen(u32 battler);
bool32 CanGetFrostbite(u32 battler);
bool32 CanBeConfused(u32 battler);
bool32 IsBattlerTerrainAffected(u32 battler, u32 terrainFlag);
u32 GetBattlerAffectionHearts(u32 battler);
void TryToRevertMimicryAndFlags(void);
u32 CountBattlerStatIncreases(u32 battler, bool32 countEvasionAcc);
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, bool32 ignoreTera);
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);
u32 GetMoveType(u32 move);
2017-10-06 16:06:45 +01:00
#endif // GUARD_BATTLE_UTIL_H