mirror of
https://github.com/pret/pokeemerald.git
synced 2026-04-19 21:57:27 -05:00
763 lines
22 KiB
C
763 lines
22 KiB
C
#ifndef GUARD_MOVES_H
|
|
#define GUARD_MOVES_H
|
|
|
|
#include "contest_effect.h"
|
|
#include "constants/battle.h"
|
|
#include "constants/battle_factory.h"
|
|
#include "constants/battle_move_effects.h"
|
|
#include "constants/battle_string_ids.h"
|
|
#include "constants/moves.h"
|
|
|
|
// For defining EFFECT_HIT etc. with battle TV scores and flags etc.
|
|
struct __attribute__((packed, aligned(2))) BattleMoveEffect
|
|
{
|
|
const u8 *battleScript;
|
|
u16 battleTvScore:3;
|
|
enum FactoryStyle battleFactoryStyle:4;
|
|
u16 encourageEncore:1;
|
|
u16 twoTurnEffect:1;
|
|
u16 semiInvulnerableEffect:1;
|
|
u16 usesProtectCounter:1;
|
|
u16 padding:5;
|
|
};
|
|
|
|
#define EFFECTS_ARR(...) (const struct AdditionalEffect[]) {__VA_ARGS__}
|
|
#define ADDITIONAL_EFFECTS(...) EFFECTS_ARR( __VA_ARGS__ ), .numAdditionalEffects = ARRAY_COUNT(EFFECTS_ARR( __VA_ARGS__ ))
|
|
|
|
struct AdditionalEffect
|
|
{
|
|
enum MoveEffect moveEffect;
|
|
u8 self:1;
|
|
u8 onlyIfTargetRaisedStats:1;
|
|
u8 onChargeTurnOnly:1;
|
|
u8 sheerForceOverride:1; // Handles edge cases for Sheer Force - if TRUE, boosts when it shouldn't, or doesn't boost when it should
|
|
u8 padding:4;
|
|
union PACKED {
|
|
enum WrappedStringID wrapped;
|
|
} multistring;
|
|
u8 chance; // 0% = effect certain, primary effect
|
|
};
|
|
|
|
enum ProtectType
|
|
{
|
|
PROTECT_TYPE_NONE,
|
|
PROTECT_TYPE_SIDE,
|
|
PROTECT_TYPE_SINGLE,
|
|
};
|
|
|
|
enum ProtectMethod
|
|
{
|
|
PROTECT_NONE,
|
|
PROTECT_NORMAL,
|
|
PROTECT_SPIKY_SHIELD,
|
|
PROTECT_KINGS_SHIELD,
|
|
PROTECT_BANEFUL_BUNKER,
|
|
PROTECT_BURNING_BULWARK,
|
|
PROTECT_OBSTRUCT,
|
|
PROTECT_SILK_TRAP,
|
|
PROTECT_MAX_GUARD,
|
|
PROTECT_WIDE_GUARD,
|
|
PROTECT_QUICK_GUARD,
|
|
PROTECT_CRAFTY_SHIELD,
|
|
PROTECT_MAT_BLOCK,
|
|
};
|
|
|
|
enum TerrainGroundCheck
|
|
{
|
|
GROUND_CHECK_NONE,
|
|
GROUND_CHECK_USER,
|
|
GROUND_CHECK_TARGET,
|
|
};
|
|
|
|
struct MoveInfo
|
|
{
|
|
const u8 *name;
|
|
const u8 *description;
|
|
enum BattleMoveEffects effect;
|
|
enum Type type:5; // Up to 32
|
|
enum DamageCategory category:2;
|
|
u16 power:9; // up to 511
|
|
// end of word
|
|
u16 accuracy:7;
|
|
u16 target:9;
|
|
u8 pp;
|
|
union {
|
|
u8 effect;
|
|
u8 powerOverride;
|
|
} zMove;
|
|
// end of word
|
|
s32 priority:4;
|
|
u32 strikeCount:4; // Max 15 hits. Defaults to 1 if not set. May apply its effect on each hit.
|
|
u32 multiHit:1; // Takes presendance over strikeCount
|
|
u32 explosion:1;
|
|
u32 criticalHitStage:2;
|
|
bool32 alwaysCriticalHit:1;
|
|
u32 numAdditionalEffects:3; // limited to 7
|
|
// Flags
|
|
bool32 makesContact:1;
|
|
bool32 ignoresProtect:1;
|
|
bool32 magicCoatAffected:1;
|
|
bool32 snatchAffected:1;
|
|
bool32 ignoresKingsRock:1;
|
|
bool32 punchingMove:1;
|
|
bool32 bitingMove:1;
|
|
bool32 pulseMove:1;
|
|
bool32 soundMove:1;
|
|
bool32 ballisticMove:1;
|
|
bool32 powderMove:1;
|
|
bool32 danceMove:1;
|
|
bool32 windMove:1;
|
|
bool32 slicingMove:1;
|
|
bool32 healingMove:1;
|
|
bool32 minimizeDoubleDamage:1;
|
|
// end of word
|
|
bool32 ignoresTargetAbility:1;
|
|
bool32 ignoresTargetDefenseEvasionStages:1;
|
|
bool32 damagesUnderground:1;
|
|
bool32 damagesUnderwater:1;
|
|
bool32 damagesAirborne:1;
|
|
bool32 damagesAirborneDoubleDamage:1;
|
|
bool32 ignoreTypeIfFlyingAndUngrounded:1;
|
|
bool32 thawsUser:1;
|
|
bool32 ignoresSubstitute:1;
|
|
bool32 forcePressure:1;
|
|
bool32 cantUseTwice:1;
|
|
bool32 alwaysHitsInRain:1;
|
|
bool32 accuracy50InSun:1;
|
|
bool32 alwaysHitsInHailSnow:1;
|
|
// Ban flags
|
|
bool32 gravityBanned:1;
|
|
bool32 mirrorMoveBanned:1;
|
|
bool32 meFirstBanned:1;
|
|
bool32 mimicBanned:1;
|
|
bool32 metronomeBanned:1;
|
|
bool32 copycatBanned:1;
|
|
bool32 assistBanned:1; // Matches same moves as copycatBanned + semi-invulnerable moves and Mirror Coat.
|
|
bool32 sleepTalkBanned:1;
|
|
bool32 instructBanned:1;
|
|
bool32 encoreBanned:1;
|
|
bool32 parentalBondBanned:1;
|
|
bool32 skyBattleBanned:1;
|
|
bool32 sketchBanned:1;
|
|
bool32 dampBanned:1;
|
|
//Other
|
|
bool32 validApprenticeMove:1;
|
|
u32 padding:3;
|
|
// end of word
|
|
|
|
union {
|
|
struct {
|
|
u16 stringId;
|
|
union {
|
|
u16 status;
|
|
u16 weather;
|
|
};
|
|
} twoTurnAttack;
|
|
struct {
|
|
u16 species;
|
|
u16 power:9;
|
|
u16 numOfHits:7;
|
|
} speciesPowerOverride;
|
|
struct {
|
|
u16 damagePercent:12;
|
|
u16 damageCategories:4; // bit field
|
|
} reflectDamage;
|
|
struct {
|
|
u16 terrain;
|
|
u16 percent:14;
|
|
enum TerrainGroundCheck groundCheck:2;
|
|
u16 hitsBothFoes:1;
|
|
} terrainBoost;
|
|
u32 protectMethod;
|
|
u32 status;
|
|
u32 moveProperty;
|
|
u32 holdEffect;
|
|
u32 type;
|
|
u32 fixedDamage;
|
|
u32 damagePercentage;
|
|
u32 absorbPercentage;
|
|
u32 recoilPercentage;
|
|
u32 nonVolatileStatus;
|
|
u32 overwriteAbility;
|
|
} argument;
|
|
|
|
// primary/secondary effects
|
|
const struct AdditionalEffect *additionalEffects;
|
|
|
|
// contest parameters
|
|
u8 contestEffect;
|
|
u8 contestCategory:3;
|
|
u8 contestComboStarterId;
|
|
u8 contestComboMoves[MAX_COMBO_MOVES];
|
|
const u8 *battleAnimScript;
|
|
};
|
|
|
|
extern const struct MoveInfo gMovesInfo[MOVES_COUNT_ALL];
|
|
extern const u8 gNotDoneYetDescription[];
|
|
extern const struct BattleMoveEffect gBattleMoveEffects[];
|
|
|
|
static inline u32 SanitizeMoveId(u32 moveId)
|
|
{
|
|
assertf(moveId < MOVES_COUNT_ALL, "invalid move: %d", moveId)
|
|
{
|
|
return MOVE_NONE;
|
|
}
|
|
|
|
return moveId;
|
|
}
|
|
|
|
static inline const u8 *GetMoveName(u32 moveId)
|
|
{
|
|
return gMovesInfo[SanitizeMoveId(moveId)].name;
|
|
}
|
|
|
|
static inline enum BattleMoveEffects GetMoveEffect(u32 moveId)
|
|
{
|
|
return gMovesInfo[SanitizeMoveId(moveId)].effect;
|
|
}
|
|
|
|
static inline const u8 *GetMoveDescription(u32 moveId)
|
|
{
|
|
moveId = SanitizeMoveId(moveId);
|
|
if (GetMoveEffect(moveId) == EFFECT_PLACEHOLDER)
|
|
return gNotDoneYetDescription;
|
|
return gMovesInfo[moveId].description;
|
|
}
|
|
|
|
static inline enum Type GetMoveType(u32 moveId)
|
|
{
|
|
return gMovesInfo[SanitizeMoveId(moveId)].type;
|
|
}
|
|
|
|
static inline enum DamageCategory GetMoveCategory(u32 moveId)
|
|
{
|
|
return gMovesInfo[SanitizeMoveId(moveId)].category;
|
|
}
|
|
|
|
static inline u32 GetMovePower(u32 moveId)
|
|
{
|
|
return gMovesInfo[SanitizeMoveId(moveId)].power;
|
|
}
|
|
|
|
static inline u32 GetMoveAccuracy(u32 moveId)
|
|
{
|
|
return gMovesInfo[SanitizeMoveId(moveId)].accuracy;
|
|
}
|
|
|
|
static inline u32 GetMoveTarget(u32 moveId)
|
|
{
|
|
moveId = SanitizeMoveId(moveId);
|
|
u32 target = gMovesInfo[moveId].target;
|
|
assertf(target != TARGET_SMART || gMovesInfo[moveId].strikeCount > 1, "Smart target requires strikeCount > 1: %S", gMovesInfo[moveId].name);
|
|
return target;
|
|
}
|
|
|
|
static inline u32 GetMovePP(u32 moveId)
|
|
{
|
|
return gMovesInfo[SanitizeMoveId(moveId)].pp;
|
|
}
|
|
|
|
static inline u32 GetMoveZEffect(u32 moveId)
|
|
{
|
|
moveId = SanitizeMoveId(moveId);
|
|
assertf(GetMoveCategory(moveId) == DAMAGE_CATEGORY_STATUS, "not a status move: %S", gMovesInfo[moveId].name);
|
|
return gMovesInfo[moveId].zMove.effect;
|
|
}
|
|
|
|
static inline u32 GetMoveZPowerOverride(u32 moveId)
|
|
{
|
|
moveId = SanitizeMoveId(moveId);
|
|
assertf(GetMoveCategory(moveId) != DAMAGE_CATEGORY_STATUS, "not a damaging move: %S", gMovesInfo[moveId].name);
|
|
return gMovesInfo[moveId].zMove.powerOverride;
|
|
}
|
|
|
|
static inline s32 GetMovePriority(u32 moveId)
|
|
{
|
|
return gMovesInfo[SanitizeMoveId(moveId)].priority;
|
|
}
|
|
|
|
static inline u32 GetMoveStrikeCount(u32 moveId)
|
|
{
|
|
return gMovesInfo[SanitizeMoveId(moveId)].strikeCount;
|
|
}
|
|
|
|
static inline u32 IsMultiHitMove(u32 moveId)
|
|
{
|
|
return gMovesInfo[SanitizeMoveId(moveId)].multiHit;
|
|
}
|
|
|
|
static inline u32 IsExplosionMove(u32 move)
|
|
{
|
|
return gMovesInfo[SanitizeMoveId(move)].explosion;
|
|
}
|
|
|
|
static inline u32 GetMoveCriticalHitStage(u32 moveId)
|
|
{
|
|
return gMovesInfo[SanitizeMoveId(moveId)].criticalHitStage;
|
|
}
|
|
|
|
static inline bool32 MoveAlwaysCrits(u32 moveId)
|
|
{
|
|
return gMovesInfo[SanitizeMoveId(moveId)].alwaysCriticalHit;
|
|
}
|
|
|
|
static inline u32 GetMoveAdditionalEffectCount(u32 moveId)
|
|
{
|
|
return gMovesInfo[SanitizeMoveId(moveId)].numAdditionalEffects;
|
|
}
|
|
|
|
static inline bool32 MoveMakesContact(u32 moveId)
|
|
{
|
|
return gMovesInfo[SanitizeMoveId(moveId)].makesContact;
|
|
}
|
|
|
|
static inline bool32 MoveIgnoresProtect(u32 moveId)
|
|
{
|
|
return gMovesInfo[SanitizeMoveId(moveId)].ignoresProtect;
|
|
}
|
|
|
|
static inline bool32 MoveCanBeBouncedBack(u32 moveId)
|
|
{
|
|
return gMovesInfo[SanitizeMoveId(moveId)].magicCoatAffected;
|
|
}
|
|
|
|
static inline bool32 MoveCanBeSnatched(u32 moveId)
|
|
{
|
|
return gMovesInfo[SanitizeMoveId(moveId)].snatchAffected;
|
|
}
|
|
|
|
static inline bool32 MoveIgnoresKingsRock(u32 moveId)
|
|
{
|
|
return gMovesInfo[SanitizeMoveId(moveId)].ignoresKingsRock;
|
|
}
|
|
|
|
static inline bool32 IsPunchingMove(u32 moveId)
|
|
{
|
|
return gMovesInfo[SanitizeMoveId(moveId)].punchingMove;
|
|
}
|
|
|
|
static inline bool32 IsBitingMove(u32 moveId)
|
|
{
|
|
return gMovesInfo[SanitizeMoveId(moveId)].bitingMove;
|
|
}
|
|
|
|
static inline bool32 IsPulseMove(u32 moveId)
|
|
{
|
|
return gMovesInfo[SanitizeMoveId(moveId)].pulseMove;
|
|
}
|
|
|
|
static inline bool32 IsSoundMove(u32 moveId)
|
|
{
|
|
return gMovesInfo[SanitizeMoveId(moveId)].soundMove;
|
|
}
|
|
|
|
static inline bool32 IsBallisticMove(u32 moveId)
|
|
{
|
|
return gMovesInfo[SanitizeMoveId(moveId)].ballisticMove;
|
|
}
|
|
|
|
static inline bool32 IsPowderMove(u32 moveId)
|
|
{
|
|
return gMovesInfo[SanitizeMoveId(moveId)].powderMove;
|
|
}
|
|
|
|
static inline bool32 IsDanceMove(u32 moveId)
|
|
{
|
|
return gMovesInfo[SanitizeMoveId(moveId)].danceMove;
|
|
}
|
|
|
|
static inline bool32 IsWindMove(u32 moveId)
|
|
{
|
|
return gMovesInfo[SanitizeMoveId(moveId)].windMove;
|
|
}
|
|
|
|
static inline bool32 IsSlicingMove(u32 moveId)
|
|
{
|
|
return gMovesInfo[SanitizeMoveId(moveId)].slicingMove;
|
|
}
|
|
|
|
static inline bool32 IsHealingMove(u32 moveId)
|
|
{
|
|
return gMovesInfo[SanitizeMoveId(moveId)].healingMove;
|
|
}
|
|
|
|
static inline bool32 MoveIncreasesPowerToMinimizedTargets(u32 moveId)
|
|
{
|
|
return gMovesInfo[SanitizeMoveId(moveId)].minimizeDoubleDamage;
|
|
}
|
|
|
|
static inline bool32 MoveIgnoresTargetAbility(u32 moveId)
|
|
{
|
|
return gMovesInfo[SanitizeMoveId(moveId)].ignoresTargetAbility;
|
|
}
|
|
|
|
static inline bool32 MoveIgnoresDefenseEvasionStages(u32 moveId)
|
|
{
|
|
return gMovesInfo[SanitizeMoveId(moveId)].ignoresTargetDefenseEvasionStages;
|
|
}
|
|
|
|
static inline bool32 MoveDamagesUnderground(u32 moveId)
|
|
{
|
|
return gMovesInfo[SanitizeMoveId(moveId)].damagesUnderground;
|
|
}
|
|
|
|
static inline bool32 MoveDamagesUnderWater(u32 moveId)
|
|
{
|
|
return gMovesInfo[SanitizeMoveId(moveId)].damagesUnderwater;
|
|
}
|
|
|
|
static inline bool32 MoveDamagesAirborne(u32 moveId)
|
|
{
|
|
return gMovesInfo[SanitizeMoveId(moveId)].damagesAirborne;
|
|
}
|
|
|
|
static inline bool32 MoveDamagesAirborneDoubleDamage(u32 moveId)
|
|
{
|
|
return gMovesInfo[SanitizeMoveId(moveId)].damagesAirborneDoubleDamage;
|
|
}
|
|
|
|
static inline bool32 MoveIgnoresTypeIfFlyingAndUngrounded(u32 moveId)
|
|
{
|
|
return gMovesInfo[SanitizeMoveId(moveId)].ignoreTypeIfFlyingAndUngrounded;
|
|
}
|
|
|
|
static inline bool32 MoveThawsUser(u32 moveId)
|
|
{
|
|
return gMovesInfo[SanitizeMoveId(moveId)].thawsUser;
|
|
}
|
|
|
|
static inline bool32 MoveIgnoresSubstitute(u32 moveId)
|
|
{
|
|
return gMovesInfo[SanitizeMoveId(moveId)].ignoresSubstitute;
|
|
}
|
|
|
|
static inline bool32 MoveForcesPressure(u32 moveId)
|
|
{
|
|
return gMovesInfo[SanitizeMoveId(moveId)].forcePressure;
|
|
}
|
|
|
|
static inline bool32 MoveCantBeUsedTwice(u32 moveId)
|
|
{
|
|
return gMovesInfo[SanitizeMoveId(moveId)].cantUseTwice;
|
|
}
|
|
|
|
static inline bool32 MoveAlwaysHitsInRain(u32 moveId)
|
|
{
|
|
return gMovesInfo[SanitizeMoveId(moveId)].alwaysHitsInRain;
|
|
}
|
|
|
|
static inline bool32 MoveHas50AccuracyInSun(u32 moveId)
|
|
{
|
|
return gMovesInfo[SanitizeMoveId(moveId)].accuracy50InSun;
|
|
}
|
|
|
|
static inline bool32 MoveAlwaysHitsInHailSnow(u32 moveId)
|
|
{
|
|
return gMovesInfo[SanitizeMoveId(moveId)].alwaysHitsInHailSnow;
|
|
}
|
|
|
|
static inline bool32 IsMoveGravityBanned(u32 moveId)
|
|
{
|
|
return gMovesInfo[SanitizeMoveId(moveId)].gravityBanned;
|
|
}
|
|
|
|
static inline bool32 IsMoveMirrorMoveBanned(u32 moveId)
|
|
{
|
|
return gMovesInfo[SanitizeMoveId(moveId)].mirrorMoveBanned;
|
|
}
|
|
|
|
static inline bool32 IsMoveMeFirstBanned(u32 moveId)
|
|
{
|
|
return gMovesInfo[SanitizeMoveId(moveId)].meFirstBanned;
|
|
}
|
|
|
|
static inline bool32 IsMoveMimicBanned(u32 moveId)
|
|
{
|
|
return gMovesInfo[SanitizeMoveId(moveId)].mimicBanned;
|
|
}
|
|
|
|
static inline bool32 IsMoveMetronomeBanned(u32 moveId)
|
|
{
|
|
return gMovesInfo[SanitizeMoveId(moveId)].metronomeBanned;
|
|
}
|
|
|
|
static inline bool32 IsMoveCopycatBanned(u32 moveId)
|
|
{
|
|
return gMovesInfo[SanitizeMoveId(moveId)].copycatBanned;
|
|
}
|
|
|
|
static inline bool32 IsMoveAssistBanned(u32 moveId)
|
|
{
|
|
return gMovesInfo[SanitizeMoveId(moveId)].assistBanned;
|
|
}
|
|
|
|
static inline bool32 IsMoveSleepTalkBanned(u32 moveId)
|
|
{
|
|
return gMovesInfo[SanitizeMoveId(moveId)].sleepTalkBanned;
|
|
}
|
|
|
|
static inline bool32 IsMoveInstructBanned(u32 moveId)
|
|
{
|
|
return gMovesInfo[SanitizeMoveId(moveId)].instructBanned;
|
|
}
|
|
|
|
static inline bool32 IsMoveEncoreBanned(u32 moveId)
|
|
{
|
|
return gMovesInfo[SanitizeMoveId(moveId)].encoreBanned;
|
|
}
|
|
|
|
static inline bool32 IsMoveParentalBondBanned(u32 moveId)
|
|
{
|
|
return gMovesInfo[SanitizeMoveId(moveId)].parentalBondBanned;
|
|
}
|
|
|
|
static inline bool32 IsMoveSkyBattleBanned(u32 moveId)
|
|
{
|
|
return gMovesInfo[SanitizeMoveId(moveId)].skyBattleBanned;
|
|
}
|
|
|
|
static inline bool32 IsMoveSketchBanned(u32 moveId)
|
|
{
|
|
return gMovesInfo[SanitizeMoveId(moveId)].sketchBanned;
|
|
}
|
|
|
|
static inline bool32 IsMoveDampBanned(u32 moveId)
|
|
{
|
|
return gMovesInfo[SanitizeMoveId(moveId)].dampBanned;
|
|
}
|
|
|
|
static inline bool32 IsValidApprenticeMove(u32 moveId)
|
|
{
|
|
return gMovesInfo[SanitizeMoveId(moveId)].validApprenticeMove;
|
|
}
|
|
|
|
static inline u32 GetMoveTwoTurnAttackStringId(u32 moveId)
|
|
{
|
|
moveId = SanitizeMoveId(moveId);
|
|
enum BattleMoveEffects effect = gMovesInfo[moveId].effect;
|
|
assertf(gBattleMoveEffects[effect].twoTurnEffect, "not a two-turn move: %S", gMovesInfo[moveId].name);
|
|
return gMovesInfo[moveId].argument.twoTurnAttack.stringId;
|
|
}
|
|
|
|
static inline u32 GetMoveTwoTurnAttackStatus(u32 moveId)
|
|
{
|
|
moveId = SanitizeMoveId(moveId);
|
|
enum BattleMoveEffects effect = gMovesInfo[moveId].effect;
|
|
assertf(effect == EFFECT_SEMI_INVULNERABLE || effect == EFFECT_SKY_DROP, "not a two-turn move with status: %S", gMovesInfo[moveId].name);
|
|
return gMovesInfo[moveId].argument.twoTurnAttack.status;
|
|
}
|
|
|
|
static inline u32 GetMoveTwoTurnAttackWeather(u32 moveId)
|
|
{
|
|
moveId = SanitizeMoveId(moveId);
|
|
enum BattleMoveEffects effect = gMovesInfo[moveId].effect;
|
|
assertf(effect == EFFECT_TWO_TURNS_ATTACK || effect == EFFECT_SOLAR_BEAM, "not a two-turn move with weather: %S", gMovesInfo[moveId].name);
|
|
return gMovesInfo[moveId].argument.twoTurnAttack.weather;
|
|
}
|
|
|
|
static inline u32 GetMoveSpeciesPowerOverride_Species(u32 moveId)
|
|
{
|
|
moveId = SanitizeMoveId(moveId);
|
|
assertf(gMovesInfo[moveId].effect == EFFECT_SPECIES_POWER_OVERRIDE, "not a species power override move: %S", GetMoveName(moveId));
|
|
return gMovesInfo[SanitizeMoveId(moveId)].argument.speciesPowerOverride.species;
|
|
}
|
|
|
|
static inline u32 GetMoveSpeciesPowerOverride_Power(u32 moveId)
|
|
{
|
|
moveId = SanitizeMoveId(moveId);
|
|
assertf(gMovesInfo[moveId].effect == EFFECT_SPECIES_POWER_OVERRIDE, "not a species power override move: %S", GetMoveName(moveId));
|
|
return gMovesInfo[SanitizeMoveId(moveId)].argument.speciesPowerOverride.power;
|
|
}
|
|
|
|
static inline u32 GetMoveSpeciesPowerOverride_NumOfHits(u32 moveId)
|
|
{
|
|
moveId = SanitizeMoveId(moveId);
|
|
assertf(gMovesInfo[moveId].effect == EFFECT_SPECIES_POWER_OVERRIDE, "not a species power override move: %S", GetMoveName(moveId));
|
|
return gMovesInfo[SanitizeMoveId(moveId)].argument.speciesPowerOverride.numOfHits;
|
|
}
|
|
|
|
static inline u32 GetMoveReflectDamage_DamagePercent(u32 moveId)
|
|
{
|
|
moveId = SanitizeMoveId(moveId);
|
|
assertf(gMovesInfo[moveId].effect == EFFECT_REFLECT_DAMAGE, "not a damage reflection move: %S", GetMoveName(moveId));
|
|
return gMovesInfo[SanitizeMoveId(moveId)].argument.reflectDamage.damagePercent;
|
|
}
|
|
|
|
static inline u32 GetMoveReflectDamage_DamageCategories(u32 moveId)
|
|
{
|
|
moveId = SanitizeMoveId(moveId);
|
|
assertf(gMovesInfo[moveId].effect == EFFECT_REFLECT_DAMAGE, "not a damage reflection move: %S", GetMoveName(moveId));
|
|
return gMovesInfo[SanitizeMoveId(moveId)].argument.reflectDamage.damageCategories;
|
|
}
|
|
|
|
static inline u32 GetMoveTerrainBoost_Terrain(u32 moveId)
|
|
{
|
|
moveId = SanitizeMoveId(moveId);
|
|
assertf(gMovesInfo[moveId].effect == EFFECT_TERRAIN_BOOST, "not a terrain boosted move: %S", GetMoveName(moveId));
|
|
return gMovesInfo[moveId].argument.terrainBoost.terrain;
|
|
}
|
|
|
|
static inline u32 GetMoveTerrainBoost_Percent(u32 moveId)
|
|
{
|
|
moveId = SanitizeMoveId(moveId);
|
|
assertf(gMovesInfo[moveId].effect == EFFECT_TERRAIN_BOOST, "not a terrain boosted move: %S", GetMoveName(moveId));
|
|
return gMovesInfo[moveId].argument.terrainBoost.percent;
|
|
}
|
|
|
|
static inline u32 GetMoveTerrainBoost_GroundCheck(u32 moveId)
|
|
{
|
|
moveId = SanitizeMoveId(moveId);
|
|
assertf(gMovesInfo[moveId].effect == EFFECT_TERRAIN_BOOST, "not a terrain boosted move: %S", GetMoveName(moveId));
|
|
return gMovesInfo[moveId].argument.terrainBoost.groundCheck;
|
|
}
|
|
|
|
static inline u32 GetMoveTerrainBoost_HitsBothFoes(u32 moveId)
|
|
{
|
|
moveId = SanitizeMoveId(moveId);
|
|
assertf(gMovesInfo[moveId].effect == EFFECT_TERRAIN_BOOST, "not a terrain boosted move: %S", GetMoveName(moveId));
|
|
return gMovesInfo[moveId].argument.terrainBoost.hitsBothFoes;
|
|
}
|
|
|
|
static inline enum ProtectMethod GetMoveProtectMethod(u32 moveId)
|
|
{
|
|
moveId = SanitizeMoveId(moveId);
|
|
enum BattleMoveEffects effect = gMovesInfo[moveId].effect;
|
|
assertf(effect == EFFECT_PROTECT || effect == EFFECT_ENDURE || effect == EFFECT_MAT_BLOCK, "not a protect move: %S", GetMoveName(moveId));
|
|
return gMovesInfo[moveId].argument.protectMethod;
|
|
}
|
|
|
|
static inline u32 GetMoveEffectArg_Status(u32 moveId)
|
|
{
|
|
// Forward-declared here because 'include/battle_util.h' includes
|
|
// this file.
|
|
extern bool32 MoveHasAdditionalEffect(u32 move, u32 moveEffect);
|
|
|
|
moveId = SanitizeMoveId(moveId);
|
|
enum BattleMoveEffects effect = gMovesInfo[moveId].effect;
|
|
assertf(effect == EFFECT_FOCUS_ENERGY || effect == EFFECT_DOUBLE_POWER_ON_ARG_STATUS || MoveHasAdditionalEffect(moveId, MOVE_EFFECT_REMOVE_STATUS), "not a move with status: %S", gMovesInfo[moveId].name);
|
|
return gMovesInfo[moveId].argument.status;
|
|
}
|
|
|
|
static inline u32 GetMoveEffectArg_MoveProperty(u32 moveId)
|
|
{
|
|
moveId = SanitizeMoveId(moveId);
|
|
enum BattleMoveEffects effect = gMovesInfo[moveId].effect;
|
|
assertf(effect == EFFECT_FIRST_TURN_ONLY || effect == EFFECT_HEAL_PULSE, "not a move with moveProperty: %S", gMovesInfo[moveId].name);
|
|
return gMovesInfo[SanitizeMoveId(moveId)].argument.moveProperty;
|
|
}
|
|
|
|
static inline u32 GetMoveEffectArg_HoldEffect(u32 moveId)
|
|
{
|
|
moveId = SanitizeMoveId(moveId);
|
|
enum BattleMoveEffects effect = gMovesInfo[moveId].effect;
|
|
assertf(effect == EFFECT_CHANGE_TYPE_ON_ITEM, "not a move with a hold effect: %S", gMovesInfo[moveId].name);
|
|
return gMovesInfo[moveId].argument.holdEffect;
|
|
}
|
|
|
|
static inline u32 GetMoveArgType(u32 moveId)
|
|
{
|
|
moveId = SanitizeMoveId(moveId);
|
|
enum BattleMoveEffects effect = gMovesInfo[moveId].effect;
|
|
assertf(effect == EFFECT_SOAK || effect == EFFECT_TWO_TYPED_MOVE || effect == EFFECT_THIRD_TYPE || effect == EFFECT_SUPER_EFFECTIVE_ON_ARG || effect == EFFECT_FAIL_IF_NOT_ARG_TYPE, "not a move with a type: %S", gMovesInfo[moveId].name);
|
|
return gMovesInfo[moveId].argument.type;
|
|
}
|
|
|
|
static inline u32 GetMoveFixedHPDamage(u32 moveId)
|
|
{
|
|
moveId = SanitizeMoveId(moveId);
|
|
assertf(gMovesInfo[moveId].effect == EFFECT_FIXED_HP_DAMAGE, "not a fixed-damage move: %S", gMovesInfo[moveId].name);
|
|
return gMovesInfo[moveId].argument.fixedDamage;
|
|
}
|
|
|
|
static inline u32 GetMoveAbsorbPercentage(u32 moveId)
|
|
{
|
|
moveId = SanitizeMoveId(moveId);
|
|
enum BattleMoveEffects effect = gMovesInfo[moveId].effect;
|
|
assertf(effect == EFFECT_ABSORB || effect == EFFECT_DREAM_EATER, "not an absorbing move: %S", gMovesInfo[moveId].name);
|
|
if (gMovesInfo[moveId].argument.absorbPercentage == 0)
|
|
return 50;
|
|
return gMovesInfo[moveId].argument.absorbPercentage;
|
|
}
|
|
|
|
static inline u32 GetMoveRecoil(u32 moveId)
|
|
{
|
|
moveId = SanitizeMoveId(moveId);
|
|
assertf(gMovesInfo[moveId].effect == EFFECT_RECOIL, "not a recoil move: %S", gMovesInfo[moveId].name);
|
|
return gMovesInfo[moveId].argument.recoilPercentage;
|
|
}
|
|
|
|
static inline u32 GetMoveNonVolatileStatus(u32 move)
|
|
{
|
|
move = SanitizeMoveId(move);
|
|
switch (GetMoveEffect(move))
|
|
{
|
|
case EFFECT_NON_VOLATILE_STATUS:
|
|
case EFFECT_YAWN:
|
|
case EFFECT_DARK_VOID:
|
|
return gMovesInfo[move].argument.nonVolatileStatus;
|
|
default:
|
|
return MOVE_EFFECT_NONE;
|
|
}
|
|
}
|
|
|
|
static inline u32 GetMoveDamagePercentage(u32 move)
|
|
{
|
|
move = SanitizeMoveId(move);
|
|
assertf(gMovesInfo[move].effect == EFFECT_FIXED_PERCENT_DAMAGE, "not a percentage-damage move: %S", gMovesInfo[move].name);
|
|
return gMovesInfo[move].argument.damagePercentage;
|
|
}
|
|
|
|
static inline u32 GetMoveOverwriteAbility(u32 move)
|
|
{
|
|
move = SanitizeMoveId(move);
|
|
assertf(gMovesInfo[move].effect == EFFECT_OVERWRITE_ABILITY, "not a move that overwrites abilities: %S", gMovesInfo[move].name);
|
|
return gMovesInfo[move].argument.overwriteAbility;
|
|
}
|
|
|
|
static inline const struct AdditionalEffect *GetMoveAdditionalEffectById(u32 moveId, u32 effect)
|
|
{
|
|
return &gMovesInfo[SanitizeMoveId(moveId)].additionalEffects[effect];
|
|
}
|
|
|
|
static inline u32 GetMoveContestEffect(u32 moveId)
|
|
{
|
|
return gMovesInfo[SanitizeMoveId(moveId)].contestEffect;
|
|
}
|
|
|
|
static inline u32 GetMoveContestCategory(u32 moveId)
|
|
{
|
|
return gMovesInfo[SanitizeMoveId(moveId)].contestCategory;
|
|
}
|
|
|
|
static inline u32 GetMoveContestComboStarter(u32 moveId)
|
|
{
|
|
return gMovesInfo[SanitizeMoveId(moveId)].contestComboStarterId;
|
|
}
|
|
|
|
static inline u32 GetMoveContestComboMoves(u32 moveId, u32 comboMove)
|
|
{
|
|
return gMovesInfo[SanitizeMoveId(moveId)].contestComboMoves[comboMove];
|
|
}
|
|
|
|
static inline const u8 *GetMoveAnimationScript(u32 moveId)
|
|
{
|
|
moveId = SanitizeMoveId(moveId);
|
|
assertf(gMovesInfo[moveId].battleAnimScript, "No animation for %S", gMovesInfo[moveId].name)
|
|
{
|
|
return gMovesInfo[MOVE_NONE].battleAnimScript;
|
|
}
|
|
return gMovesInfo[moveId].battleAnimScript;
|
|
}
|
|
|
|
static inline const u8 *GetMoveBattleScript(u32 moveId)
|
|
{
|
|
moveId = SanitizeMoveId(moveId);
|
|
assertf(gBattleMoveEffects[GetMoveEffect(moveId)].battleScript, "No battle script for %S", gMovesInfo[moveId].name)
|
|
{
|
|
return gBattleMoveEffects[EFFECT_PLACEHOLDER].battleScript;
|
|
}
|
|
return gBattleMoveEffects[GetMoveEffect(moveId)].battleScript;
|
|
}
|
|
|
|
#endif // GUARD_MOVES_H
|