#include "global.h" #include "dungeon_pokemon_attributes.h" #include "dungeon_util.h" #include "dungeon_message.h" #include "moves.h" #include "status_checks_1.h" #include "dungeon_ai_targeting.h" #include "structs/str_damage.h" #include "constants/ability.h" #include "constants/status.h" #include "constants/weather.h" #include "constants/iq_skill.h" #include "type_chart.h" #include "position_util.h" #include "dungeon_items.h" #include "code_806CD90.h" #include "move_util.h" #include "code_808417C.h" #include "dungeon_capabilities.h" #include "move_effects_target.h" #include "status.h" #include "weather.h" #include "code_8077274_1.h" #include "charge_move.h" #include "dungeon_random.h" #include "targeting_flags.h" #include "targeting.h" #include "called_move_data.h" #include "dungeon_map_access.h" #include "math.h" #include "code_800DAC0.h" #include "text_util.h" #include "dungeon_visibility.h" #include "code_807CD9C.h" #include "dungeon_engine.h" #include "status_actions.h" #include "code_8045A00.h" #include "code_803E668.h" #include "code_803E724.h" #include "code_803E46C.h" #include "code_8041AD0.h" extern void sub_80429C8(Entity *r0); extern bool8 sub_8045888(Entity *r0); extern void HandleDealingDamage(Entity *attacker, Entity *target, struct DamageStruct *dmgStruct, bool32 isFalseSwipe, bool32 giveExp, s16 arg4, bool32 arg8, s32 argC); extern void CalcDamage(Entity *, Entity *, u8, u32, u32, struct DamageStruct *dmgStruct, u32, u16, u32); extern s16 sub_8057600(Move *move, s32 itemID); extern void sub_803ED30(s32, Entity *r0, u8, s32); extern void sub_8042238(Entity *pokemon, Entity *target); extern void sub_806A1E8(Entity *pokemon); extern bool8 sub_8044B28(void); extern void sub_804178C(u32); extern void sub_8071DA4(Entity *); extern void sub_80428A0(Entity *r0); extern bool8 sub_8040BB0(Entity *entity, Move *move, bool8); extern void sub_8040DA0(Entity *entity, Move *move); extern u16 sub_80412E0(u16 moveId, u8 weather, u8 a2); extern void sub_800569C(DungeonPos *, axdata *, u8); extern u8 GetBodySize(s16 index); extern void sub_800EF10(u16 r0); extern s32 sub_800E710(s16 a0, u16 a1); extern void sub_800E3AC(s32 a0, DungeonPos *pos, s32 a2); extern void sub_8041168(Entity *entity, Entity *entity2, Move *,DungeonPos *); extern Entity *sub_80696A8(Entity *a0); extern Entity *GetMonsterAtPos(DungeonPos *pos); extern Entity *sub_80696FC(Entity *); extern Entity *sub_806977C(Entity *); extern void sub_806F2BC(Entity *attacker, Entity *target, u8 moveType, s32 a2, struct DamageStruct *dmgStruct); extern void sub_806ACE8(Entity *entity, Move *move); extern s32 sub_8057070(Move *move); extern bool8 MoveRequiresCharging(Entity* pokemon,u16 param_2); extern s32 sub_800ED20(u16 param_1); extern bool32 sub_8058F04(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern void sub_8042930(Entity *r0); extern void sub_8041B48(Entity *pokemon); extern void sub_8041BA8(Entity *pokemon); extern void sub_8042950(Entity *r0); extern bool8 sub_8057634(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 YawnMoveAction(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 NightmareMoveAction(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_805783C(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 EncoreMoveAction(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_8057974(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 PainSplitMoveAction(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 TormentMoveAction(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_8057BC4(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_8057C88(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 WhirlpoolMoveAction(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 SurfMoveAction(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_805889C(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_8057D7C(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_8057D9C(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 SmokescreenMoveAction(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_8057FCC(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_8057FF4(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_805805C(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_805816C(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_80581D0(Entity *pokemon, Entity *target, Move *move, u32 param_4); extern bool8 sub_8058B3C(Entity *pokemon, Entity *target, Move *move, u32 param_4); extern bool8 sub_8058270(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_80582C4(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_80583D8(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_8058430(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_8058478(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_80584C0(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_8058548(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_8058580(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 BrickBreakMoveAction(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_8058638(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_80586DC(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_8058770(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_80587E8(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_8058838(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_8058858(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_80588B8(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_80588F4(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_8058930(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_8058C00(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_8058A18(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_8058BF0(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_8058E5C(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_8058FBC(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_80590D4(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_8059190(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_80591E4(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 SkillSwapMoveAction(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_8059424(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_805946C(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_8059528(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_8059540(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_80595A0(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_80595EC(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_805C138(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_80598CC(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_8059928(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_8059988(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_8059A2C(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_8059AA8(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_8059AB8(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_8059AF8(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_8059D00(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_8059D48(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_8059D98(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_8059DA4(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_8059DB4(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_8059DC4(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_8059E0C(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 TriAttackMoveAction(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_805A120(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_805A210(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_805A258(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_805A2A0(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 RolePlayMoveAction(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_805A3DC(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_805A464(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 CurseMoveAction(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_805A568(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 FocusEnergyMoveAction(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 TickleMoveAction(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_805A688(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 KnockOffMoveAction(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 SecretPowerMoveAction(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_805AC90(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_805AD04(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_805AD34(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_805AD54(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_805AE3C(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_805AE74(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_805AECC(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 PresentMoveAction(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_805AFA4(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_805B028(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_805B074(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_805B0BC(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_805B17C(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 WrapMoveAction(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_805B264(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_805B324(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 DestinyBondMoveAction(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_805B388(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_805B3E0(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_805B454(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 MimicMoveAction(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_805B53C(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 LeechSeedMoveAction(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_805B668(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_805B910(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_805B808(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_805A408(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_8059050(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_8059FC8(Entity * pokemon,Entity * target,Move * move,u32 param_4,u8 param_5); extern bool8 sub_8059E54(Entity * pokemon,Entity * target,Move * move,u32 param_4,u8 param_5); extern void SetShopkeeperAggression(Entity *, Entity *); extern bool8 MoveCausesPaused(Move *move); extern void sub_8069F9C(Entity *pokemon,Entity * target,Move *move); extern void sub_806A120(Entity *pokemon,Entity * target,Move *move); extern bool8 sub_8058C98(Entity *pokemon, Entity *target, Move *move, u32 param_4, u32 param_5); extern bool8 sub_805B3FC(Entity *pokemon, Entity *target, Move *move, u32 param_4, u32 param_5); extern bool8 sub_805A5E8(Entity *pokemon, Entity *target, Move *move, u32 param_4, u32 param_5); extern bool8 sub_8058B84(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_8059714(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_80576F8(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_8059080(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_8059D58(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_805B164(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_8059A18(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 BulkUpMoveAction(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_80582D4(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 RageMoveAction(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_8059B94(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_805B3B4(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_8059588(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_805A2B0(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_805B2FC(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_8059CD8(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_8058A7C(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_8057F7C(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_8057ED0(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_8058CEC(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_805A2C8(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_8057C68(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 SolarBeamMoveAction(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 SkyAttackMoveAction(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_8058D38(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 SandstormMoveAction(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 SafeguardMoveAction(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 MistMoveAction(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 LightScreenMoveAction(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_805768C(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_8057F24(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_80599EC(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_80589D4(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_8059AC4(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_805A4D4(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_8058EE0(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_8058A08(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 CounterMoveAction(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 BideMoveAction(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_805836C(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 TrapperOrbAction(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_805A450(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 RazorWindMoveAction(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 FocusPunchMoveAction(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 MagicCoatMoveAction(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_8057748(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 MudWaterSportMoveAction(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_805A4FC(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_8058C48(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 SpikesMoveAction(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_80578EC(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_80588A8(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 WishMoveAction(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_8057E6C(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_8059CF0(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_80582AC(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_8058A54(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 VitalThrowMoveAction(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 FlyMoveAction(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_8059F38(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 DiveMoveAction(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 DigMoveAction(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_8057824(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_805825C(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 GrudgeMoveAction(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_805A4C0(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_805AAD0(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_805B314(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 ProtectMoveAction(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_8059004(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_80597F0(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 ChargeMoveAction(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_8058D44(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 StockpileMoveAction(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 SpitUpMoveAction(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 SwallowMoveAction(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 RainDanceMoveAction(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 InvisifyOrbAction(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 MirrorCoatMoveAction(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 PerishSongMoveAction(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_8057CD0(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 SunnyDayMoveAction(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 EndureMoveAction(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 HelpingHandMoveAction(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 BellyDrumMoveAction(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_80578FC(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_8057BB4(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 TransformMoveAction(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 HailMoveAction(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_8058234(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_805A85C(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 ReboundOrbAction(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 NaturePowerMoveAction(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 SketchMoveAction(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_8057E50(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 ConversionMoveAction(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 SnatchMoveAction(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 HandleColorChange(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 PsychUpMoveAction(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 SnoreMoveAction(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 sub_805B618(Entity *pokemon, Entity *target, Move *move, s32 param_4); extern bool8 Conversion2MoveAction(Entity *pokemon, Entity *target, Move *move, s32 param_4); s32 HandleDamagingMove(Entity *, Entity *, Move *, s32, s32); static s32 TryHitTarget(Entity *attacker, Entity *target, Move *move, struct DamageStruct *dmgStruct, s16 unk); static void TriggerTargetAbilityEffect(Entity *attacker); static bool8 AccuracyCalc(Entity *attacker, Entity *target, Move *move, s32 accuracyType, bool8 selfAlwaysHits); bool8 TryUseChosenMove(struct Entity *attacker, u32 r6, s32 itemId, u32 var_30, bool32 isLinkedMove, struct Move *move); bool8 sub_8056468(Entity *entity, Move *move, const u8 *str, Entity **unkArray, bool32 itemId, bool8 arg_4, bool32 unused); bool8 sub_805744C(Entity * pokemon, Move *move, bool8 param_3); static void SetTargetsForMove(Entity **targetsArray, Entity *attacker, Move *move); void sub_80566F8(Entity *attacker, Move *move, s32 a2, bool8 a3, s32 itemId, s32 isLinkedMove); static s32 SetNewTarget(s32 targetArrId, Entity **targetsArray, s32 targetFlags_, Entity *attacker, Entity *target, Move *move, bool32 canHitAnyone_); bool8 sub_8055988(Entity *r2, Entity *r4); void sub_80559DC(Entity *entity1, Entity *entity2); static void SortTargets(Entity **targetsArray, Entity *attacker); extern const s32 gUnknown_8106A50; extern const s32 gUnknown_8106A4C; extern const s16 gUnknown_80F5006; extern const s32 gUnknown_80F519C; extern const s32 gUnknown_80F51A0; extern const s32 gUnknown_80F50F4[2][21]; extern const s16 gUnknown_80F4E70[]; extern const s16 gUnknown_80F4E74[]; extern const u16 gUnknown_80F5004; extern const u8 *const gUnknown_80FEEA4; extern const u8 *const gUnknown_80FEEC8; extern const u8 *const gUnknown_80FEEEC; extern const u8 *const gUnknown_80FEF0C; extern const u8 *const gUnknown_80FEF30; extern const u8 *const gUnknown_80FEF4C; extern const u8 *const gUnknown_80FEF50; extern const u8 *const gUnknown_80FEF54; extern const u8 *const gUnknown_80FEF74; extern const u8 *const gUnknown_80FEF98; extern const u8 *const gUnknown_80FEFD0; extern const u8 *const gUnknown_80FECA4; extern const u8 *const gUnknown_80F9158; extern const u8 *const gUnknown_80FC72C; extern const u8 *const gUnknown_80FC700; extern const u8 *const gUnknown_80FC6D0; extern const u8 *const gUnknown_80FC710; extern const u8 *const gUnknown_80FC6FC; extern const u8 *const gUnknown_80FECBC; extern const u8 *const gUnknown_80FECE0; extern const u8 *const gUnknown_80F9688; extern const u8 *const gUnknown_80FC714; extern const u8 *const gUnknown_80FC718; extern const u8 *const gUnknown_80FC6A8; extern const u8 *const gUnknown_80FD2D0; extern const u8 *const gUnknown_80FD2DC; extern const u8 *const gUnknown_80F93C8; extern const u8 *const gUnknown_80FC690; extern const u8 *const gUnknown_80FC6A4; extern const u8 *const gUnknown_80FCD28; extern const u8 *const gUnknown_80FCD0C; extern const u8 *const gUnknown_80FDD88; extern const u8 *const gUnknown_80FDD20; extern const u8 *const gUnknown_80FDDA8; extern const u8 *const gUnknown_80FDD48; extern const u8 *const gUnknown_80FDDAC; extern const u8 *const gUnknown_80FC52C; extern const u8 *const gUnknown_80FC558; extern const u8 *const gUnknown_80FC574; extern const u8 *const gUnknown_8100524; extern const u8 *const gUnknown_80F9364; extern const u8 *const gUnknown_80F93A4; extern const u8 *const gUnknown_80F9384; extern const u8 *const gUnknown_80F9380; extern Entity *gUnknown_203B438; EWRAM_DATA s32 gUnknown_202F208 = 0; EWRAM_DATA s32 gUnknown_202F20C = 0; EWRAM_DATA s32 gUnknown_202F210 = 0; EWRAM_DATA s32 gUnknown_202F214 = 0; EWRAM_DATA u8 gUnknown_202F218 = 0; EWRAM_DATA u8 gUnknown_202F219 = 0; EWRAM_DATA u8 gUnknown_202F21A = 0; EWRAM_DATA s32 gUnknown_202F21C = 0; EWRAM_DATA u8 gUnknown_202F220 = 0; EWRAM_DATA u8 gUnknown_202F221 = 0; EWRAM_DATA u8 gUnknown_202F222 = 0; EWRAM_DATA s32 gUnknown_202F224 = 0; EWRAM_DATA s32 gMetronomeCalledArrayId = 0; #define MAX_MOVE_TARGETS 64 static void UseMoveAgainstTargets(Entity **targetsArray, Entity *attacker, Move *move, s32 itemId, bool32 isLinkedMove) { s32 i = 0; u16 moveId; Entity *originalAttacker; Entity *currTargetSaved; Entity *currTarget; EntityInfo *targetInfo; bool32 moveHits; bool32 lightRodRedirect; bool32 moveRedirected; moveId = move->id; for (i = 0; i < MAX_MOVE_TARGETS; i++) { currTargetSaved = NULL; // Only for Pass Scarf currTarget = targetsArray[i]; moveHits = TRUE; lightRodRedirect = FALSE; moveRedirected = FALSE; if (currTarget == NULL) break; if (!EntityExists(attacker)) break; if (EntityExists(currTarget)) { bool32 r4; bool8 moveHadEffect; originalAttacker = attacker; targetInfo = GetEntInfo(currTarget); targetInfo->unk15A = 0; if (CanBeSnatched(moveId) && gDungeon->snatchPokemon != NULL) { Entity *snatchMon = gDungeon->snatchPokemon; if (GetEntityType(snatchMon) == ENTITY_MONSTER && snatchMon != attacker && GetEntInfo(snatchMon)->unk98 == gDungeon->unk17B3C && targetInfo->unkFF == 0) { TryDisplayDungeonLoggableMessage3(attacker, currTarget, gUnknown_80FCD28); // The move was snatched. currTarget = snatchMon; } } else if (GetMoveTypeForMonster(attacker, move) == TYPE_ELECTRIC && gDungeon->lightningRodPokemon != NULL) { Entity *lightRodMon = gDungeon->lightningRodPokemon; if (GetEntityType(lightRodMon) == ENTITY_MONSTER) { EntityInfo *lightRodInfo = GetEntInfo(lightRodMon); if (lightRodInfo->unk98 == gDungeon->unk17B38 && GetTreatmentBetweenMonsters(lightRodMon, attacker, TRUE, FALSE) == 1 && ((targetInfo->unkFF == 0 && lightRodInfo->unkFF == 0) || currTarget == lightRodMon)) { sub_8042930(lightRodMon); TryDisplayDungeonLoggableMessage3(attacker, currTarget, gUnknown_80FCD0C); // A Lightningrod took the move currTarget = lightRodMon; lightRodRedirect = TRUE; } } } else if (HasHeldItem(currTarget, ITEM_PASS_SCARF)) { if (!CannotAttack(currTarget, FALSE) && (GetMoveTargetAndRangeForPokemon(attacker, move, FALSE) & 0xF0) == 0 && FixedPointToInt(targetInfo->belly) >= gUnknown_80F5006 && targetInfo->unkFF == 0) { s32 direction1 = targetInfo->action.direction; s32 direction2 = targetInfo->action.direction; if (IsBossFight()) { TryDisplayDungeonLoggableMessage3(attacker, currTarget, gUnknown_80FDD88); // A mysterious force prevents moves from being passed off! } else { s32 j; Entity *tileEntity; for (j = 0; j < 8; j++) { direction2++; direction2 &= DIRECTION_MASK; tileEntity = GetTile(currTarget->pos.x + gAdjacentTileOffsets[direction2].x, currTarget->pos.y + gAdjacentTileOffsets[direction2].y)->monster; if (EntityExists(tileEntity) && GetEntityType(tileEntity) == ENTITY_MONSTER) { if (sub_8045888(currTarget)) { s32 k; for (k = 0; k < 24; k++) { sub_806CE68(currTarget, direction1); sub_803E708(2, 0x43); direction1++; direction1 &= DIRECTION_MASK; } while (direction1 != direction2) { sub_806CE68(currTarget, direction1); sub_803E708(2, 0x43); direction1++; direction1 &= DIRECTION_MASK; } sub_806CE68(currTarget, direction1); sub_803E708(2, 0x43); } targetInfo->belly = FixedPoint_Subtract(targetInfo->belly, IntToFixedPoint(gUnknown_80F5006)); if (move->id == MOVE_REGULAR_ATTACK) { TryDisplayDungeonLoggableMessage3(attacker, currTarget, gUnknown_80FDDA8); // Attack was passed off } else { TryDisplayDungeonLoggableMessage3(attacker, currTarget, gUnknown_80FDD20); // Move was passed off } currTargetSaved = currTarget; currTarget = tileEntity; break; } } if (j == 8) { if (move->id == MOVE_REGULAR_ATTACK) { TryDisplayDungeonLoggableMessage3(attacker, currTarget, gUnknown_80FDDAC); // There's no one to pass off to! } else { TryDisplayDungeonLoggableMessage3(attacker, currTarget, gUnknown_80FDD48); //There's no one to pass off to! } } } } } gUnknown_202F208++; gUnknown_202F20C++; targetInfo = GetEntInfo(currTarget); // currTarget could've been changed, hence info pointers needs to be reloaded targetInfo->unk15A = 0; if (targetInfo->isNotTeamMember) { targetInfo->targetPos = attacker->pos; } sub_806A1E8(currTarget); TrySendImmobilizeSleepEndMsg(attacker, currTarget); r4 = FALSE; if (!MoveMatchesBideClassStatus(attacker, move)) { r4 = (MoveRequiresCharging(attacker, move->id) != 0); } if (!lightRodRedirect) { if (targetInfo->reflectClassStatus.status == STATUS_MAGIC_COAT) { if (IsReflectedByMagicCoat(moveId) && sub_8055988(attacker, currTarget)) { TryDisplayDungeonLoggableMessage3(attacker, currTarget, gUnknown_80FC52C); // The target~27s Magic Coat bounced it back! sub_8041B48(currTarget); sub_80559DC(currTarget, attacker); currTarget = attacker; targetInfo = GetEntInfo(attacker); targetInfo->unk15A = 0; moveRedirected = TRUE; } } else if (targetInfo->reflectClassStatus.status == STATUS_MIRROR_MOVE) { s32 target = GetMoveTargetAndRangeForPokemon(attacker, move, FALSE); if (moveId != MOVE_REGULAR_ATTACK && moveId != MOVE_PROJECTILE && !r4 && ((target & 0xF) == 0 || (target & 0xF) == 4 || (target & 0xF) == 5 || (target & 0xF) == 2) && sub_8055988(attacker, currTarget)) { TryDisplayDungeonLoggableMessage3(attacker, currTarget, gUnknown_80FC558); // The target~27s Mirror Move returned it! sub_8041BA8(currTarget); sub_80559DC(currTarget, attacker); currTarget = attacker; targetInfo = GetEntInfo(attacker); targetInfo->unk15A = 0; moveRedirected = TRUE; } } } if (!lightRodRedirect) { if (targetInfo->reflectClassStatus.status == STATUS_PROTECT) { s16 targetFlags = GetMoveTargetAndRangeForPokemon(attacker, move, FALSE); s32 targetFlagsAnd = targetFlags & 0xF; if ((targetFlagsAnd == 0 || targetFlagsAnd == 4 || targetFlagsAnd == 5 || targetFlagsAnd == 2) && !r4) { SubstitutePlaceholderStringTags(gFormatBuffer_Monsters[1], currTarget, 0); TryDisplayDungeonLoggableMessage3(attacker, currTarget, gUnknown_80FC574); // protected itself! moveHits = FALSE; } } } if (sub_80571F0(currTarget, move)) { moveHits = FALSE; } if (moveHits) { if (HasAbility(currTarget, ABILITY_SOUNDPROOF) && IsSoundMove(move)) { SubstitutePlaceholderStringTags(gFormatBuffer_Monsters[1], currTarget, 0); TryDisplayDungeonLoggableMessage3(attacker, currTarget, gUnknown_8100524); // Soundproof suppressed the sound move! moveHits = FALSE; } } if (moveHits) { bool8 selfAlwaysHits = (moveRedirected == FALSE); if (move->id == MOVE_ENDURE || move->id == MOVE_DETECT || move->id == MOVE_PROTECT) { selfAlwaysHits = FALSE; } if (!AccuracyCalc(attacker, currTarget, move, ACCURACY_1, selfAlwaysHits)) { moveHits = FALSE; } } if (moveHits && lightRodRedirect) { moveHits = FALSE; } if (sub_8045888(currTarget)) { sub_803E708(4, 0x4A); sub_8041168(attacker, currTarget, move, NULL); } if (!moveHits) { if (GetEntInfo(attacker)->isTeamLeader) { sub_80421C0(attacker, 0x156); } else { sub_80421C0(attacker, 0x157); } SetMessageArgument_2(gFormatBuffer_Monsters[1], GetEntInfo(currTarget), 0); // Interesting that these 3 strings are the same. Curious if that's the case in Blue/Europe versions. if (attacker == currTarget) { TryDisplayDungeonLoggableMessage3(attacker, attacker, gUnknown_80F9380); // The move missed } else if (GetTreatmentBetweenMonsters(attacker, currTarget, TRUE, FALSE) == 0) { TryDisplayDungeonLoggableMessage3(attacker, currTarget, gUnknown_80F9384); // The move missed } else if (lightRodRedirect) { TryDisplayDungeonLoggableMessage3(attacker, currTarget, gUnknown_80F93A4); // The move missed } else { TryDisplayDungeonLoggableMessage3(attacker, currTarget, gUnknown_80F9364); // is unaffected! } if (sub_8045888(currTarget)) { sub_803ED30(9999, currTarget, 1, -1); } switch (moveId) { case MOVE_HI_JUMP_KICK: sub_8059FC8(attacker, currTarget, move, itemId, 1); break; case MOVE_JUMP_KICK: sub_8059E54(attacker, currTarget, move, itemId, 1); break; } if (sub_8044B28()) break; // breaks out of the loop } else { s32 expMultiplierBeforeMove = targetInfo->expMultiplier; if (targetInfo->isNotTeamMember) { if (move->id != MOVE_REGULAR_ATTACK && itemId == 0 && expMultiplierBeforeMove == EXP_HALVED) { targetInfo->expMultiplier = EXP_REGULAR; } if (isLinkedMove == TRUE) { targetInfo->expMultiplier = EXP_BOOSTED; } } if (targetInfo->unk164 == 0xFF && sub_80717A4(currTarget, MOVE_SLEEP_TALK)) { targetInfo->unk164 = GetDirectionTowardsPosition(&currTarget->pos, &attacker->pos); } if (targetInfo->unk165 == 0xFF && sub_80717A4(currTarget, MOVE_SNORE)) { targetInfo->unk165 = GetDirectionTowardsPosition(&currTarget->pos, &attacker->pos); } if (HasAbility(currTarget, ABILITY_PRESSURE) && GetTreatmentBetweenMonsters(attacker, currTarget, TRUE, FALSE) == 1 && move->id != MOVE_REGULAR_ATTACK && move->id != MOVE_STRUGGLE && itemId == 0 && move->PP != 0) { if (!(move->moveFlags2 & MOVE_FLAG2_x10)) { sub_8042950(attacker); } move->moveFlags2 |= MOVE_FLAG2_x10; } if ((GetMoveTargetAndRangeForPokemon(attacker, move, FALSE) & 0xF) == 0) { SetShopkeeperAggression(attacker, currTarget); } targetInfo->unk158 = 1; // They really must've had a soft spot for all these giant switches switch (moveId) { case MOVE_THRASH: case MOVE_CUT: case MOVE_ROCK_THROW: case MOVE_DOUBLESLAP: case MOVE_SHADOW_PUNCH: case MOVE_EXTREMESPEED: case MOVE_SKY_UPPERCUT: case MOVE_SWIFT: case MOVE_TACKLE: case MOVE_WATERFALL: case MOVE_SLAM: case MOVE_BULLET_SEED: case MOVE_EGG_BOMB: case MOVE_FAINT_ATTACK: case MOVE_BARRAGE: case MOVE_PECK: case MOVE_ARM_THRUST: case MOVE_HORN_ATTACK: case MOVE_WING_ATTACK: case MOVE_AERIAL_ACE: case MOVE_ICICLE_SPEAR: case MOVE_VINE_WHIP: case MOVE_SHOCK_WAVE: case MOVE_QUICK_ATTACK: case MOVE_SPIKE_CANNON: case MOVE_DRAGON_CLAW: case MOVE_DRILL_PECK: case MOVE_DOUBLE_KICK: case MOVE_HYDRO_PUMP: case MOVE_HYPER_VOICE: case MOVE_VICEGRIP: case MOVE_POUND: case MOVE_SCRATCH: case MOVE_BONE_RUSH: case MOVE_BONEMERANG: case MOVE_MAGICAL_LEAF: case MOVE_MACH_PUNCH: case MOVE_PIN_MISSILE: case MOVE_WATER_GUN: case MOVE_FURY_ATTACK: case MOVE_FURY_SWIPES: case MOVE_MEGA_KICK: case MOVE_MEGA_PUNCH: case MOVE_MEGAHORN: case MOVE_FURY_CUTTER: case MOVE_COMET_PUNCH: case MOVE_ROCK_BLAST: case MOVE_AEROBLAST: case MOVE_WIDE_SLASH: case MOVE_SPIN_SLASH: case MOVE_BLOOP_SLASH: moveHadEffect = (HandleDamagingMove(attacker, currTarget, move, 0x100, itemId) != 0); break; case MOVE_REGULAR_ATTACK: moveHadEffect = (HandleDamagingMove(attacker, currTarget, move, 0x80, itemId) != 0); break; case MOVE_NOTHING: moveHadEffect = (HandleDamagingMove(attacker, currTarget, move, 0, itemId) != 0); break; case MOVE_EARTHQUAKE: moveHadEffect = sub_8058F04(attacker, currTarget, move, itemId); break; case MOVE_GUST: moveHadEffect = sub_8058270(attacker, currTarget, move, itemId); break; case MOVE_STRUGGLE: moveHadEffect = sub_805B968(attacker, currTarget, move, itemId); break; case MOVE_FLAME_WHEEL: moveHadEffect = sub_805816C(attacker, currTarget, move, itemId); break; case MOVE_FLAMETHROWER: case MOVE_FIRE_BLAST: case MOVE_HEAT_WAVE: case MOVE_EMBER: case MOVE_FIRE_PUNCH: moveHadEffect = sub_80581D0(attacker, currTarget, move, itemId); break; case MOVE_POWDER_SNOW: case MOVE_BLIZZARD: case MOVE_ICE_PUNCH: case MOVE_ICE_BEAM: moveHadEffect = sub_8058B3C(attacker, currTarget, move, itemId); break; case MOVE_FRENZY_PLANT: case MOVE_HYDRO_CANNON: case MOVE_HYPER_BEAM: moveHadEffect = sub_805A568(attacker, currTarget, move, itemId); break; case MOVE_FOCUS_ENERGY: moveHadEffect = FocusEnergyMoveAction(attacker, currTarget, move, itemId); break; case MOVE_AIR_CUTTER: case MOVE_KARATE_CHOP: case MOVE_SLASH: case MOVE_CRABHAMMER: case MOVE_CROSS_CHOP: case MOVE_RAZOR_LEAF: case MOVE_LEAF_BLADE: moveHadEffect = (HandleDamagingMove(attacker, currTarget, move, 0x100, itemId) != 0); break; case MOVE_FISSURE: moveHadEffect = sub_80590D4(attacker, currTarget, move, itemId); break; case MOVE_SHEER_COLD: case MOVE_GUILLOTINE: moveHadEffect = sub_80595EC(attacker, currTarget, move, itemId); break; case MOVE_ONE_SHOT: moveHadEffect = sub_805C138(attacker, currTarget, move, itemId); break; case MOVE_CLAMP: case MOVE_BIND: case MOVE_SAND_TOMB: case MOVE_FIRE_SPIN: moveHadEffect = sub_805B17C(attacker, currTarget, move, itemId); break; case MOVE_WHIRLPOOL: moveHadEffect = WhirlpoolMoveAction(attacker, currTarget, move, itemId); break; case MOVE_SURF: moveHadEffect = SurfMoveAction(attacker, currTarget, move, itemId); break; case MOVE_SPIDER_WEB: case MOVE_MEAN_LOOK: moveHadEffect = sub_805889C(attacker, currTarget, move, itemId); break; case MOVE_POISON_STING: case MOVE_SLUDGE: case MOVE_SLUDGE_BOMB: moveHadEffect = sub_8059E0C(attacker, currTarget, move, itemId); break; case MOVE_PSYCHIC: moveHadEffect = sub_8058C98(attacker, currTarget, move, gUnknown_8106A50, itemId); break; case MOVE_ACID: moveHadEffect = sub_8058C98(attacker, currTarget, move, gUnknown_8106A4C, itemId); break; case MOVE_METAL_CLAW: moveHadEffect = sub_805B3FC(attacker, currTarget, move, gUnknown_8106A4C, itemId); break; case MOVE_STEEL_WING: moveHadEffect = sub_805A5E8(attacker, currTarget, move, gUnknown_8106A4C, itemId); break; case MOVE_POISON_TAIL: moveHadEffect = sub_805B074(attacker, currTarget, move, itemId); break; case MOVE_TWISTER: moveHadEffect = sub_8059928(attacker, currTarget, move, itemId); break; case MOVE_CONSTRICT: case MOVE_BUBBLEBEAM: moveHadEffect = sub_8058580(attacker, currTarget, move, itemId); break; case MOVE_SILVER_WIND: case MOVE_ANCIENTPOWER: moveHadEffect = sub_8058930(attacker, currTarget, move, itemId); break; case MOVE_PSYBEAM: case MOVE_SIGNAL_BEAM: case MOVE_CONFUSION: moveHadEffect = sub_8058C00(attacker, currTarget, move, itemId); break; case MOVE_MIST_BALL: moveHadEffect = sub_805B324(attacker, currTarget, move, itemId); break; case MOVE_LUSTER_PURGE: moveHadEffect = sub_805B910(attacker, currTarget, move, itemId); break; case MOVE_CRUSH_CLAW: moveHadEffect = sub_805AE74(attacker, currTarget, move, itemId); break; case MOVE_SMOG: moveHadEffect = sub_8059540(attacker, currTarget, move, itemId); break; case MOVE_SACRED_FIRE: moveHadEffect = sub_80595A0(attacker, currTarget, move, itemId); break; case MOVE_THUNDERSHOCK: moveHadEffect = sub_8059D00(attacker, currTarget, move, itemId); break; case MOVE_LICK: case MOVE_SPARK: case MOVE_BODY_SLAM: case MOVE_DRAGONBREATH: moveHadEffect = sub_8058FBC(attacker, currTarget, move, itemId); break; case MOVE_EXTRASENSORY: case MOVE_HYPER_FANG: case MOVE_BONE_CLUB: moveHadEffect = sub_8059190(attacker, currTarget, move, itemId); break; case MOVE_BITE: case MOVE_NEEDLE_ARM: case MOVE_STOMP: case MOVE_ROLLING_KICK: moveHadEffect = sub_8058430(attacker, currTarget, move, itemId); break; case MOVE_HEADBUTT: moveHadEffect = sub_8059424(attacker, currTarget, move, itemId); break; case MOVE_ROCK_SLIDE: case MOVE_ASTONISH: moveHadEffect = sub_8057C88(attacker, currTarget, move, itemId); break; case MOVE_CRUNCH: case MOVE_SHADOW_BALL: moveHadEffect = sub_80583D8(attacker, currTarget, move, itemId); break; case MOVE_DIZZY_PUNCH: case MOVE_WATER_PULSE: moveHadEffect = sub_805AC90(attacker, currTarget, move, itemId); break; case MOVE_TRI_ATTACK: moveHadEffect = TriAttackMoveAction(attacker, currTarget, move, itemId); break; case MOVE_METEOR_MASH: moveHadEffect = sub_8058B84(attacker, currTarget, move, itemId); break; case MOVE_BLAZE_KICK: moveHadEffect = sub_805AECC(attacker, currTarget, move, itemId); break; case MOVE_ATTRACT: moveHadEffect = sub_805B454(attacker, currTarget, move, itemId); break; case MOVE_DISABLE: moveHadEffect = sub_80582C4(attacker, currTarget, move, itemId); break; case MOVE_FAKE_OUT: moveHadEffect = sub_805A408(attacker, currTarget, move, itemId); break; case MOVE_SONICBOOM: moveHadEffect = sub_8059714(attacker, currTarget, move, itemId); break; case MOVE_DRAGON_RAGE: moveHadEffect = sub_805B808(attacker, currTarget, move, itemId); break; case MOVE_STUN_SPORE: moveHadEffect = sub_8059050(attacker, currTarget, move, itemId); break; case MOVE_THUNDER: case MOVE_THUNDERPUNCH: moveHadEffect = sub_8058478(attacker, currTarget, move, itemId); break; case MOVE_LOVELY_KISS: case MOVE_SING: case MOVE_SPORE: case MOVE_GRASSWHISTLE: case MOVE_HYPNOSIS: case MOVE_SLEEP_POWDER: moveHadEffect = sub_80576F8(attacker, currTarget, move, itemId); break; case MOVE_YAWN: moveHadEffect = YawnMoveAction(attacker, currTarget, move, itemId); break; case MOVE_THUNDERBOLT: moveHadEffect = sub_8059080(attacker, currTarget, move, itemId); break; case MOVE_BLOCK: moveHadEffect = sub_8059D98(attacker, currTarget, move, itemId); break; case MOVE_HORN_DRILL: moveHadEffect = sub_8059AF8(attacker, currTarget, move, itemId); break; case MOVE_CONFUSE_RAY: case MOVE_SUPERSONIC: case MOVE_SWEET_KISS: case MOVE_TEETER_DANCE: case MOVE_TOTTER: moveHadEffect = sub_8059AA8(attacker, currTarget, move, itemId); break; case MOVE_POISON_GAS: case MOVE_POISONPOWDER: moveHadEffect = sub_8059DA4(attacker, currTarget, move, itemId); break; case MOVE_THUNDER_WAVE: moveHadEffect = sub_8059D48(attacker, currTarget, move, itemId); break; case MOVE_GLARE: moveHadEffect = sub_805B028(attacker, currTarget, move, itemId); break; case MOVE_ZAP_CANNON: moveHadEffect = sub_8059D58(attacker, currTarget, move, itemId); break; case MOVE_SUPERPOWER: moveHadEffect = TickleMoveAction(attacker, currTarget, move, itemId); break; case MOVE_ROCK_TOMB: case MOVE_ICY_WIND: case MOVE_MUD_SHOT: moveHadEffect = sub_8058638(attacker, currTarget, move, itemId); break; case MOVE_DYNAMICPUNCH: moveHadEffect = sub_805A688(attacker, currTarget, move, itemId); break; case MOVE_FAKE_TEARS: moveHadEffect = sub_8057D7C(attacker, currTarget, move, itemId); break; case MOVE_WHIRLWIND: case MOVE_ROAR: case MOVE_BLOWBACK: moveHadEffect = sub_805B0BC(attacker, currTarget, move, itemId); break; case MOVE_PAIN_SPLIT: moveHadEffect = PainSplitMoveAction(attacker, currTarget, move, itemId); break; case MOVE_TAIL_GLOW: moveHadEffect = sub_805B164(attacker, currTarget, move, itemId); break; case MOVE_MINIMIZE: moveHadEffect = sub_8059A18(attacker, currTarget, move, itemId); break; case MOVE_DRAGON_DANCE: moveHadEffect = sub_805B884(attacker, currTarget, move, itemId); break; case MOVE_BULK_UP: moveHadEffect = BulkUpMoveAction(attacker, currTarget, move, itemId); break; case MOVE_SHARPEN: case MOVE_HOWL: case MOVE_MEDITATE: moveHadEffect = sub_80582D4(attacker, currTarget, move, itemId); break; case MOVE_RAGE: moveHadEffect = RageMoveAction(attacker, currTarget, move, itemId); break; case MOVE_SWORDS_DANCE: moveHadEffect = sub_8059B94(attacker, currTarget, move, itemId); break; case MOVE_CALM_MIND: moveHadEffect = sub_805B3B4(attacker, currTarget, move, itemId); break; case MOVE_GROWTH: moveHadEffect = sub_8059588(attacker, currTarget, move, itemId); break; case MOVE_AMNESIA: moveHadEffect = sub_805A2B0(attacker, currTarget, move, itemId); break; case MOVE_DEFENSE_CURL: moveHadEffect = sub_805B2FC(attacker, currTarget, move, itemId); break; case MOVE_IRON_DEFENSE: case MOVE_ACID_ARMOR: case MOVE_BARRIER: moveHadEffect = sub_8059CD8(attacker, currTarget, move, itemId); break; case MOVE_COSMIC_POWER: moveHadEffect = sub_8058A7C(attacker, currTarget, move, itemId); break; case MOVE_MUDDY_WATER: moveHadEffect = sub_80598CC(attacker, currTarget, move, itemId); break; case MOVE_OCTAZOOKA: moveHadEffect = sub_8057F7C(attacker, currTarget, move, itemId); break; case MOVE_AURORA_BEAM: moveHadEffect = sub_8057ED0(attacker, currTarget, move, itemId); break; case MOVE_PSYCHO_BOOST: moveHadEffect = sub_8058CEC(attacker, currTarget, move, itemId); break; case MOVE_SCARY_FACE: case MOVE_COTTON_SPORE: moveHadEffect = sub_8058BF0(attacker, currTarget, move, itemId); break; case MOVE_GROWL: moveHadEffect = sub_805A2C8(attacker, currTarget, move, itemId); break; case MOVE_FEATHERDANCE: moveHadEffect = sub_805AD34(attacker, currTarget, move, itemId); break; case MOVE_SCREECH: moveHadEffect = sub_8057C68(attacker, currTarget, move, itemId); break; case MOVE_SEISMIC_TOSS: case MOVE_NIGHT_SHADE: moveHadEffect = sub_8059A2C(attacker, currTarget, move, itemId); break; case MOVE_GIGA_DRAIN: case MOVE_LEECH_LIFE: case MOVE_MEGA_DRAIN: moveHadEffect = sub_80586DC(attacker, currTarget, move, itemId); break; case MOVE_DOUBLE_EDGE: moveHadEffect = sub_805946C(attacker, currTarget, move, itemId); break; case MOVE_SUBMISSION: case MOVE_TAKE_DOWN: case MOVE_VOLT_TACKLE: moveHadEffect = sub_8058E5C(attacker, currTarget, move, itemId); break; case MOVE_ABSORB: moveHadEffect = sub_80591E4(attacker, currTarget, move, itemId); break; case MOVE_SWAGGER: moveHadEffect = sub_8057BC4(attacker, currTarget, move, itemId); break; case MOVE_TRIPLE_KICK: moveHadEffect = sub_805A210(attacker, currTarget, move, itemId); break; case MOVE_TWINEEDLE: moveHadEffect = sub_8059988(attacker, currTarget, move, itemId); break; case MOVE_SOLARBEAM: moveHadEffect = SolarBeamMoveAction(attacker, currTarget, move, itemId); break; case MOVE_SKY_ATTACK: moveHadEffect = SkyAttackMoveAction(attacker, currTarget, move, itemId); break; case MOVE_SLOW_DOWN: moveHadEffect = sub_805BE90(attacker, currTarget, move, itemId); break; case MOVE_OUTRAGE: case MOVE_PETAL_DANCE: moveHadEffect = sub_80588B8(attacker, currTarget, move, itemId); break; case MOVE_WRAP: moveHadEffect = WrapMoveAction(attacker, currTarget, move, itemId); break; case MOVE_UPROAR: moveHadEffect = sub_8058D38(attacker, currTarget, move, itemId); break; case MOVE_POISON_FANG: moveHadEffect = sub_8059DC4(attacker, currTarget, move, itemId); break; case MOVE_PRESENT: moveHadEffect = PresentMoveAction(attacker, currTarget, move, itemId); break; case MOVE_REFLECT: moveHadEffect = ReflectMoveAction(attacker, currTarget, move, itemId); break; case MOVE_SANDSTORM: moveHadEffect = SandstormMoveAction(attacker, currTarget, move, itemId); break; case MOVE_SAFEGUARD: moveHadEffect = SafeguardMoveAction(attacker, currTarget, move, itemId); break; case MOVE_MIST: moveHadEffect = MistMoveAction(attacker, currTarget, move, itemId); break; case MOVE_LIGHT_SCREEN: moveHadEffect = LightScreenMoveAction(attacker, currTarget, move, itemId); break; case MOVE_ICE_BALL: case MOVE_ROLLOUT: moveHadEffect = sub_805768C(attacker, currTarget, move, itemId); break; case MOVE_MEMENTO: moveHadEffect = sub_8057F24(attacker, currTarget, move, itemId); break; case MOVE_SOFTBOILED: case MOVE_MILK_DRINK: moveHadEffect = sub_80599EC(attacker, currTarget, move, itemId); break; case MOVE_SYNTHESIS: moveHadEffect = sub_80589D4(attacker, currTarget, move, itemId); break; case MOVE_MOONLIGHT: moveHadEffect = sub_8059AC4(attacker, currTarget, move, itemId); break; case MOVE_REST: moveHadEffect = sub_805A4D4(attacker, currTarget, move, itemId); break; case MOVE_RECOVER: case MOVE_SLACK_OFF: moveHadEffect = sub_8058EE0(attacker, currTarget, move, itemId); break; case MOVE_SCAN: moveHadEffect = ScannerOrbAction(attacker, currTarget, move, itemId); break; case MOVE_TRICK: moveHadEffect = sub_805A120(attacker, currTarget, move, itemId); break; case MOVE_TAKEAWAY: moveHadEffect = sub_805BA50(attacker, currTarget, move, itemId); break; case MOVE_THIEF: case MOVE_COVET: moveHadEffect = sub_805A2A0(attacker, currTarget, move, itemId); break; case MOVE_AGILITY: case MOVE_SPEED_BOOST: moveHadEffect = sub_8058A08(attacker, currTarget, move, itemId); break; case MOVE_PURSUIT: case MOVE_COUNTER: moveHadEffect = CounterMoveAction(attacker, currTarget, move, itemId); break; case MOVE_BIDE: case MOVE_REVENGE: moveHadEffect = BideMoveAction(attacker, currTarget, move, itemId); break; case MOVE_BIDE_2: moveHadEffect = sub_805836C(attacker, currTarget, move, itemId); break; case MOVE_TRAPPER: moveHadEffect = TrapperOrbAction(attacker, currTarget, move, itemId); break; case MOVE_SLEEP_TALK: moveHadEffect = sub_805A450(attacker, currTarget, move, itemId); break; case MOVE_CURSE: moveHadEffect = CurseMoveAction(attacker, currTarget, move, itemId); break; case MOVE_HI_JUMP_KICK: moveHadEffect = sub_8059FC8(attacker, currTarget, move, itemId, 0); break; case MOVE_BLAST_BURN: moveHadEffect = sub_805AE3C(attacker, currTarget, move, itemId); break; case MOVE_HIDDEN_POWER: moveHadEffect = sub_805B3E0(attacker, currTarget, move, itemId); break; case MOVE_RAZOR_WIND: moveHadEffect = RazorWindMoveAction(attacker, currTarget, move, itemId); break; case MOVE_FOCUS_PUNCH: moveHadEffect = FocusPunchMoveAction(attacker, currTarget, move, itemId); break; case MOVE_MAGIC_COAT: moveHadEffect = MagicCoatMoveAction(attacker, currTarget, move, itemId); break; case MOVE_NIGHTMARE: moveHadEffect = NightmareMoveAction(attacker, currTarget, move, itemId); break; case MOVE_MORNING_SUN: moveHadEffect = sub_8057748(attacker, currTarget, move, itemId); break; case MOVE_VACUUM_CUT: moveHadEffect = sub_805C1BC(attacker, currTarget, move, itemId); break; case MOVE_MUD_SPORT: case MOVE_WATER_SPORT: moveHadEffect = MudWaterSportMoveAction(attacker, currTarget, move, itemId); break; case MOVE_IRON_TAIL: moveHadEffect = sub_8057634(attacker, currTarget, move, itemId); break; case MOVE_TAIL_WHIP: case MOVE_LEER: moveHadEffect = sub_805A3DC(attacker, currTarget, move, itemId); break; case MOVE_WILL_O_WISP: moveHadEffect = sub_8057FF4(attacker, currTarget, move, itemId); break; case MOVE_INGRAIN: moveHadEffect = sub_805A4FC(attacker, currTarget, move, itemId); break; case MOVE_PSYWAVE: moveHadEffect = sub_8058C48(attacker, currTarget, move, itemId); break; case MOVE_LEECH_SEED: moveHadEffect = LeechSeedMoveAction(attacker, currTarget, move, itemId); break; case MOVE_SPIKES: moveHadEffect = SpikesMoveAction(attacker, currTarget, move, itemId); break; case MOVE_AROMATHERAPY: case MOVE_HEAL_BELL: case MOVE_REFRESH: moveHadEffect = sub_80578EC(attacker, currTarget, move, itemId); break; case MOVE_HAZE: moveHadEffect = sub_80588A8(attacker, currTarget, move, itemId); break; case MOVE_POWER_EARS: moveHadEffect = RadarOrbAction(attacker, currTarget, move, itemId); break; case MOVE_SIESTA: moveHadEffect = sub_805BC70(attacker, currTarget, move, itemId); break; case MOVE_SMELLINGSALT: moveHadEffect = sub_80587E8(attacker, currTarget, move, itemId); break; case MOVE_MAGNITUDE: moveHadEffect = sub_805B264(attacker, currTarget, move, itemId); break; case MOVE_SKULL_BASH: moveHadEffect = SkullBashMoveAction(attacker, currTarget, move, itemId); break; case MOVE_WISH: moveHadEffect = WishMoveAction(attacker, currTarget, move, itemId); break; case MOVE_FLATTER: moveHadEffect = sub_8057FCC(attacker, currTarget, move, itemId); break; case MOVE_MUD_SLAP: moveHadEffect = sub_805A258(attacker, currTarget, move, itemId); break; case MOVE_SAND_ATTACK: case MOVE_KINESIS: case MOVE_FLASH: moveHadEffect = sub_8059528(attacker, currTarget, move, itemId); break; case MOVE_OVERHEAT: moveHadEffect = sub_8057E6C(attacker, currTarget, move, itemId); break; case MOVE_TOXIC: moveHadEffect = sub_8059DB4(attacker, currTarget, move, itemId); break; case MOVE_METAL_SOUND: moveHadEffect = sub_8058838(attacker, currTarget, move, itemId); break; case MOVE_TORMENT: moveHadEffect = TormentMoveAction(attacker, currTarget, move, itemId); break; case MOVE_SUPER_FANG: moveHadEffect = sub_8057974(attacker, currTarget, move, itemId); break; case MOVE_FALSE_SWIPE: moveHadEffect = sub_805B388(attacker, currTarget, move, itemId); break; case MOVE_TWO_EDGE: moveHadEffect = sub_805BC98(attacker, currTarget, move, itemId); break; case MOVE_ENDEAVOR: moveHadEffect = sub_80584C0(attacker, currTarget, move, itemId); break; case MOVE_BATON_PASS: case MOVE_SWITCHER: moveHadEffect = sub_805BB74(attacker, currTarget, move, itemId); break; case MOVE_DREAM_EATER: moveHadEffect = sub_805B668(attacker, currTarget, move, itemId); break; case MOVE_SEARCHLIGHT: moveHadEffect = LuminousOrbAction(attacker, currTarget, move, itemId); break; case MOVE_FILL_IN: moveHadEffect = FillInOrbAction(attacker, currTarget, move, itemId); break; case MOVE_TELEPORT: case MOVE_WARP: moveHadEffect = sub_8059CF0(attacker, currTarget, move, itemId); break; case MOVE_DROUGHT: moveHadEffect = sub_805BF34(attacker, currTarget, move, itemId); break; case MOVE_SEE_STAIRS: moveHadEffect = StairsOrbAction(attacker, currTarget, move, itemId); break; case MOVE_BRICK_BREAK: moveHadEffect = BrickBreakMoveAction(attacker, currTarget, move, itemId); break; case MOVE_HARDEN: case MOVE_WITHDRAW: moveHadEffect = sub_80582AC(attacker, currTarget, move, itemId); break; case MOVE_MIND_READER: case MOVE_LOCK_ON: moveHadEffect = sub_8058A54(attacker, currTarget, move, itemId); break; case MOVE_VITAL_THROW: moveHadEffect = VitalThrowMoveAction(attacker, currTarget, move, itemId); break; case MOVE_FLY: moveHadEffect = FlyMoveAction(attacker, currTarget, move, itemId); break; case MOVE_BOUNCE: moveHadEffect = sub_8059F38(attacker, currTarget, move, itemId); break; case MOVE_DIVE: moveHadEffect = DiveMoveAction(attacker, currTarget, move, itemId); break; case MOVE_DIG: moveHadEffect = DigMoveAction(attacker, currTarget, move, itemId); break; case MOVE_SWEET_SCENT: moveHadEffect = sub_8057824(attacker, currTarget, move, itemId); break; case MOVE_DOUBLE_TEAM: moveHadEffect = sub_805825C(attacker, currTarget, move, itemId); break; case MOVE_KNOCK_OFF: moveHadEffect = KnockOffMoveAction(attacker, currTarget, move, itemId); break; case MOVE_TRAP_BUSTER: moveHadEffect = TrapbustOrbAction(attacker, currTarget, move, itemId); break; case MOVE_LONG_TOSS: moveHadEffect = LongtossOrbAction(attacker, currTarget, move, itemId); break; case MOVE_PIERCE: moveHadEffect = PierceOrbAction(attacker, currTarget, move, itemId); break; case MOVE_GRUDGE: moveHadEffect = GrudgeMoveAction(attacker, currTarget, move, itemId); break; case MOVE_PETRIFY: moveHadEffect = PetrifyOrbAction(attacker, currTarget, move, itemId); break; case MOVE_ASSIST: moveHadEffect = sub_805A4C0(attacker, currTarget, move, itemId); break; case MOVE_DOOM_DESIRE: case MOVE_FUTURE_SIGHT: moveHadEffect = sub_805AAD0(attacker, currTarget, move, itemId); break; case MOVE_SHOCKER: moveHadEffect = ShockerOrbAction(attacker, currTarget, move, itemId); break; case MOVE_FOLLOW_ME: case MOVE_SUBSTITUTE: case MOVE_DECOY_MAKER: moveHadEffect = sub_805B314(attacker, currTarget, move, itemId); break; case MOVE_JUMP_KICK: moveHadEffect = sub_8059E54(attacker, currTarget, move, itemId, 0); break; case MOVE_PROTECT: case MOVE_DETECT: moveHadEffect = ProtectMoveAction(attacker, currTarget, move, itemId); break; case MOVE_TAUNT: moveHadEffect = sub_8059AB8(attacker, currTarget, move, itemId); break; case MOVE_TICKLE: moveHadEffect = sub_8058858(attacker, currTarget, move, itemId); break; case MOVE_REVERSAL: case MOVE_FLAIL: moveHadEffect = sub_8058770(attacker, currTarget, move, itemId); break; case MOVE_SELFDESTRUCT: moveHadEffect = sub_8059004(attacker, currTarget, move, itemId); break; case MOVE_EXPLOSION: moveHadEffect = sub_80597F0(attacker, currTarget, move, itemId); break; case MOVE_CHARGE: moveHadEffect = ChargeMoveAction(attacker, currTarget, move, itemId); break; case MOVE_FACADE: moveHadEffect = sub_8058548(attacker, currTarget, move, itemId); break; case MOVE_LOW_KICK: moveHadEffect = sub_80588F4(attacker, currTarget, move, itemId); break; case MOVE_WATER_SPOUT: moveHadEffect = sub_8058D44(attacker, currTarget, move, itemId); break; case MOVE_ERUPTION: moveHadEffect = sub_805AFA4(attacker, currTarget, move, itemId); break; case MOVE_SMOKESCREEN: moveHadEffect = SmokescreenMoveAction(attacker, currTarget, move, itemId); break; case MOVE_SEE_TRAP: moveHadEffect = sub_805BA44(attacker, currTarget, move, itemId); break; case MOVE_STOCKPILE: moveHadEffect = StockpileMoveAction(attacker, currTarget, move, itemId); break; case MOVE_SPIT_UP: moveHadEffect = SpitUpMoveAction(attacker, currTarget, move, itemId); break; case MOVE_SWALLOW: moveHadEffect = SwallowMoveAction(attacker, currTarget, move, itemId); break; case MOVE_RAIN_DANCE: moveHadEffect = RainDanceMoveAction(attacker, currTarget, move, itemId); break; case MOVE_SPITE: moveHadEffect = sub_8057D9C(attacker, currTarget, move, itemId); break; case MOVE_INVISIFY: moveHadEffect = InvisifyOrbAction(attacker, currTarget, move, itemId); break; case MOVE_MIRROR_COAT: moveHadEffect = MirrorCoatMoveAction(attacker, currTarget, move, itemId); break; case MOVE_PERISH_SONG: moveHadEffect = PerishSongMoveAction(attacker, currTarget, move, itemId); break; case MOVE_RAPID_SPIN: moveHadEffect = sub_8058A18(attacker, currTarget, move, itemId); break; case MOVE_DESTINY_BOND: moveHadEffect = DestinyBondMoveAction(attacker, currTarget, move, itemId); break; case MOVE_ENCORE: moveHadEffect = EncoreMoveAction(attacker, currTarget, move, itemId); break; case MOVE_WEATHER_BALL: moveHadEffect = sub_8057CD0(attacker, currTarget, move, itemId); break; case MOVE_SUNNY_DAY: moveHadEffect = SunnyDayMoveAction(attacker, currTarget, move, itemId); break; case MOVE_PAY_DAY: moveHadEffect = sub_805A464(attacker, currTarget, move, itemId); break; case MOVE_ONE_ROOM: moveHadEffect = sub_805C2A0(attacker, currTarget, move, itemId); break; case MOVE_ENDURE: moveHadEffect = EndureMoveAction(attacker, currTarget, move, itemId); break; case MOVE_HELPING_HAND: moveHadEffect = HelpingHandMoveAction(attacker, currTarget, move, itemId); break; case MOVE_BELLY_DRUM: moveHadEffect = BellyDrumMoveAction(attacker, currTarget, move, itemId); break; case MOVE_FAMISH: moveHadEffect = sub_805C288(attacker, currTarget, move, itemId); break; case MOVE_CHARM: moveHadEffect = sub_805783C(attacker, currTarget, move, itemId); break; case MOVE_BUBBLE: moveHadEffect = sub_80578FC(attacker, currTarget, move, itemId); break; case MOVE_STRING_SHOT: moveHadEffect = sub_8057BB4(attacker, currTarget, move, itemId); break; case MOVE_ROCK_SMASH: case MOVE_EXCAVATE: moveHadEffect = RockSmashMoveAction(attacker, currTarget, move, itemId); break; case MOVE_TRANSFORM: moveHadEffect = TransformMoveAction(attacker, currTarget, move, itemId); break; case MOVE_HAIL: moveHadEffect = HailMoveAction(attacker, currTarget, move, itemId); break; case MOVE_MOBILE: moveHadEffect = MobileOrbAction(attacker, currTarget, move, itemId); break; case MOVE_ODOR_SLEUTH: case MOVE_FORESIGHT: moveHadEffect = sub_8058234(attacker, currTarget, move, itemId); break; case MOVE_SPLASH: moveHadEffect = sub_805A85C(attacker, currTarget, move, itemId); break; case MOVE_TRANSFER: moveHadEffect = TransferOrbAction(attacker, currTarget, move, itemId); break; case MOVE_STAY_AWAY: moveHadEffect = sub_805BB98(attacker, currTarget, move, itemId); break; case MOVE_BEAT_UP: moveHadEffect = sub_805AD54(attacker, currTarget, move, itemId); break; case MOVE_REBOUND: moveHadEffect = ReboundOrbAction(attacker, currTarget, move, itemId); break; case MOVE_IMPRISON: case MOVE_OBSERVER: moveHadEffect = sub_805AD04(attacker, currTarget, move, itemId); break; case MOVE_WILD_CALL: moveHadEffect = sub_805C080(attacker, currTarget, move, itemId); break; case MOVE_REVIVER: moveHadEffect = sub_805C1E4(attacker, currTarget, move, itemId); break; case MOVE_ESCAPE: moveHadEffect = EscapeOrbAction(attacker, currTarget, move, itemId); break; case MOVE_SECRET_POWER: moveHadEffect = SecretPowerMoveAction(attacker, currTarget, move, itemId); break; case MOVE_NATURE_POWER: moveHadEffect = NaturePowerMoveAction(attacker, currTarget, move, itemId); break; case MOVE_ITEMIZE: moveHadEffect = sub_805C3F8(attacker, currTarget, move, itemId); break; case MOVE_SKETCH: moveHadEffect = SketchMoveAction(attacker, currTarget, move, itemId); break; case MOVE_MIRROR_MOVE: moveHadEffect = sub_8057E50(attacker, currTarget, move, itemId); break; case MOVE_ROLE_PLAY: moveHadEffect = RolePlayMoveAction(attacker, currTarget, move, itemId); break; case MOVE_SKILL_SWAP: moveHadEffect = SkillSwapMoveAction(attacker, currTarget, move, itemId); break; case MOVE_CONVERSION: moveHadEffect = ConversionMoveAction(attacker, currTarget, move, itemId); break; case MOVE_CLEANSE: moveHadEffect = CleanseOrbAction(attacker, currTarget, move, itemId); break; case MOVE_RETURN: moveHadEffect = sub_805805C(attacker, currTarget, move, itemId); break; case MOVE_SNATCH: moveHadEffect = SnatchMoveAction(attacker, currTarget, move, itemId); break; case MOVE_CAMOUFLAGE: moveHadEffect = HandleColorChange(attacker, currTarget, move, itemId); break; case MOVE_FRUSTRATION: moveHadEffect = sub_805B53C(attacker, currTarget, move, itemId); break; case MOVE_PSYCH_UP: moveHadEffect = PsychUpMoveAction(attacker, currTarget, move, itemId); break; case MOVE_SNORE: moveHadEffect = SnoreMoveAction(attacker, currTarget, move, itemId); break; case MOVE_RECYCLE: moveHadEffect = RecycleMoveAction(attacker, currTarget, move, itemId); break; case MOVE_NO_MOVE: moveHadEffect = SilenceOrbAction(attacker, currTarget, move, itemId); break; case MOVE_METRONOME: moveHadEffect = sub_805B618(attacker, currTarget, move, itemId); break; case MOVE_HP_GAUGE: moveHadEffect = IdentifyOrbAction(attacker, currTarget, move, itemId); break; case MOVE_CONVERSION_2: moveHadEffect = Conversion2MoveAction(attacker, currTarget, move, itemId); break; case MOVE_POUNCE: moveHadEffect = sub_805BEB8(attacker, currTarget, move, itemId); break; case MOVE_TRAWL: moveHadEffect = sub_805BEC8(attacker, currTarget, move, itemId); break; case MOVE_MIMIC: moveHadEffect = MimicMoveAction(attacker, currTarget, move, itemId); break; case MOVE_STRENGTH: case MOVE_HURL: moveHadEffect = sub_805C45C(attacker, currTarget, move, itemId); break; case MOVE_ECHO: moveHadEffect = sub_805C208(attacker, currTarget, move, itemId); break; default: moveHadEffect = FALSE; break; } if (sub_8044B28()) { break; } if (EntityExists(currTargetSaved)) { sub_806CE68(currTargetSaved, GetEntInfo(currTargetSaved)->action.direction); } if (!moveHadEffect) { if (EntityExists(attacker) && EntityExists(currTarget) && targetInfo->isNotTeamMember) { targetInfo->expMultiplier = expMultiplierBeforeMove; } } else { if (MoveCausesPaused(move) && RollSecondaryEffect(attacker, 0)) { gUnknown_202F222 = 1; } } if (EntityExists(currTarget)) { targetInfo->unk158 = 1; } if (moveId != MOVE_SKILL_SWAP) { TriggerTargetAbilityEffect(attacker); sub_8069F9C(attacker, currTarget, move); sub_806A120(attacker, currTarget, move); } } attacker = originalAttacker; } } if (!sub_8044B28()) { if (EntityExists(attacker) && GetEntInfo(attacker)->unk154 != 0) { GetEntInfo(attacker)->unk154 = 0; sub_807D148(attacker, attacker, 0, NULL); } if (EntityExists(attacker) && GetEntInfo(attacker)->unk155 != 0) { GetEntInfo(attacker)->unk155 = 0; LowerAttackStageTarget(attacker, attacker, gUnknown_8106A50, 2, 0, FALSE); } } } bool32 HandleRegularDamagingMove(Entity *attacker, Entity *target, Move *move, s32 itemId) { return (HandleDamagingMove(attacker, target, move, 0x100, itemId) != 0); } s32 HandleDamagingMove(Entity *attacker, Entity *target, Move *move, s32 r9, s32 itemId) { struct DamageStruct dmgStruct; s16 unk; s32 moveType = GetMoveTypeForMonster(attacker, move); s32 movePower = GetMovePower(attacker, move); s32 critChance = GetMoveCritChance(move); CalcDamage(attacker, target, moveType, movePower, critChance, &dmgStruct, r9, move->id, 1); unk = sub_8057600(move, itemId); return TryHitTarget(attacker, target, move, &dmgStruct, unk); } s32 sub_80556BC(Entity *attacker, Entity *target, u8 moveType, Move *move, s32 r9, s32 itemId) { struct DamageStruct dmgStruct; s16 unk; s32 movePower = GetMovePower(attacker, move); s32 critChance = GetMoveCritChance(move); CalcDamage(attacker, target, moveType, movePower, critChance, &dmgStruct, r9, move->id, 1); unk = sub_8057600(move, itemId); return TryHitTarget(attacker, target, move, &dmgStruct, unk); } static s32 TryHitTarget(Entity *attacker, Entity *target, Move *move, struct DamageStruct *dmgStruct, s16 unk_) { s32 unk = unk_; // It's happening again... if (AccuracyCalc(attacker, target, move, ACCURACY_2, TRUE)) { // Move hits bool32 isFalseSwipe = (move->id == MOVE_FALSE_SWIPE); if (HasAbility(target, ABILITY_ILLUMINATE)) { gDungeon->unk644.unk1E = 999; gDungeon->unk17B34 = target; gDungeon->unk17B40 = target->spawnGenID; } HandleDealingDamage(attacker, target, dmgStruct, isFalseSwipe, TRUE, unk, TRUE, 0); } else { SetMessageArgument_2(gFormatBuffer_Monsters[1], GetEntInfo(target), 0); if (sub_8045888(attacker) && sub_8045888(target)) { sub_803ED30(9999, target, 1, -1); TryDisplayDungeonLoggableMessage4(attacker, target, gUnknown_80F9688); // It took no damage! sub_8042238(attacker, target); } else { TryDisplayDungeonLoggableMessage3(attacker, target, gUnknown_80F9688); // It took no damage! } dmgStruct->tookNoDamage = TRUE; } if (dmgStruct->tookNoDamage) { return 0; } if (EntityExists(target)) { GetEntInfo(target)->unk15A = 1; } return dmgStruct->dmg; } s32 sub_8055864(Entity *attacker, Entity *target, Move *move, s32 param_4, s32 itemId) { struct DamageStruct dmgStruct; s32 moveType = GetMoveTypeForMonster(attacker, move); sub_806F2BC(attacker, target, moveType, param_4, &dmgStruct); HandleDealingDamage(attacker, target, &dmgStruct, FALSE, TRUE, sub_8057600(move, itemId), TRUE, 0); if (dmgStruct.tookNoDamage) { return 0; } if (EntityExists(target)) { GetEntInfo(target)->unk15A = 1; } return dmgStruct.dmg; } // This unused function returns FALSE if target's typing makes it immune to move's type. UNUSED bool32 TargetNotImmuneTo(Move *move, Entity *target) { s32 i; s32 dmg = 1; bool32 ghostImmunity = FALSE; EntityInfo *targetInfo = GetEntInfo(target); s32 moveType = GetMoveType(move); if (moveType == TYPE_NORMAL || moveType == TYPE_FIGHTING) { ghostImmunity = TRUE; } for (i = 0; i < 2; i++) { s32 multiplier[4] = {0, 1, 1, 1}; // EFFECTIVENESS_IMMUNE is 0, others are 1 s32 effectiveness; if (ghostImmunity && targetInfo->types[i] == TYPE_GHOST && !targetInfo->exposed) { effectiveness = EFFECTIVENESS_IMMUNE; } else { effectiveness = gTypeEffectivenessChart[moveType][targetInfo->types[i]]; } dmg *= multiplier[effectiveness]; if (dmg == 0) break; } return (dmg != 0); } bool8 sub_8055988(Entity *r2, Entity *r4) { if (r2 != r4 && abs(r2->pos.x - r4->pos.x) <= 1 && abs(r2->pos.y - r4->pos.y) <= 1 && CanAttackInDirection(r4, GetDirectionTowardsPosition(&r4->pos, &r2->pos))) { return TRUE; } return FALSE; } void sub_80559DC(Entity *entity1, Entity *entity2) { EntityInfo *entInfo = GetEntInfo(entity1); s32 direction = GetDirectionTowardsPosition(&entity1->pos, &entity2->pos); entInfo->action.direction = direction & DIRECTION_MASK; sub_806CE68(entity1, direction); } bool32 sub_8055A00(Entity *attacker, s32 firstMoveId, s32 var_34, s32 itemId, s32 arg_0) { s32 i, j; s32 moveId; EntityInfo *attackerInfo = GetEntInfo(attacker); bool32 isLinkedMove; moveId = firstMoveId; if (firstMoveId >= MAX_MON_MOVES) return FALSE; attackerInfo->abilityEffectFlags = 0; attackerInfo->unk159 = 0; if (attackerInfo->cringeClassStatus.status == STATUS_CRINGE) { SubstitutePlaceholderStringTags(gFormatBuffer_Monsters[0], attacker, 0); LogMessageByIdWithPopupCheckUser(attacker, gUnknown_80FC714); // is cringing! return FALSE; } else if (attackerInfo->cringeClassStatus.status == STATUS_INFATUATED) { SubstitutePlaceholderStringTags(gFormatBuffer_Monsters[0], attacker, 0); LogMessageByIdWithPopupCheckUser(attacker, gUnknown_80FC718); // is infatuated! return FALSE; } else if (attackerInfo->burnClassStatus.status == STATUS_PARALYSIS) { SubstitutePlaceholderStringTags(gFormatBuffer_Monsters[0], attacker, 0); LogMessageByIdWithPopupCheckUser(attacker, gUnknown_80FC6A8); // is paralyzed! return FALSE; } gUnknown_202F222 = 0; gUnknown_202F208 = 0; gUnknown_202F221 = 0; for (i = 0; i < MAX_MON_MOVES; i++) { attackerInfo->mimicMoveIDs[i] = 0; } for (i = 0, j = 0; i < MAX_MON_MOVES; i++) { j++; if (++moveId >= MAX_MON_MOVES) break; if (!(attackerInfo->moves.moves[moveId].moveFlags & MOVE_FLAG_SUBSEQUENT_IN_LINK_CHAIN)) break; } isLinkedMove = (j > 1); moveId = firstMoveId; while (1) { Move *currMove = &attackerInfo->moves.moves[moveId]; if (!EntityExists(attacker) || sub_8044B28()) break; if (currMove->id == MOVE_SNORE || currMove->id == MOVE_SLEEP_TALK) { if (!IsSleeping(attacker)) { if (CannotAttack(attacker, TRUE)) break; } } else { if (CannotAttack(attacker, FALSE)) break; } if (gUnknown_202F221 != 0) break; if (MoveFlagExists(currMove)) { bool32 moveUsable = TRUE; bool32 var_28 = FALSE; bool32 statusMoveMatch = MoveMatchesBideClassStatus(attacker, currMove); if (currMove->PP != 0) { if (!statusMoveMatch) { var_28 = TRUE; } } else { if (!statusMoveMatch) { sub_80928C0(gFormatBuffer_Items[0], currMove, NULL); LogMessageByIdWithPopupCheckUser(attacker, gUnknown_80F93C8); // The move can't be used! moveUsable = FALSE; } } if (moveUsable) { bool32 moveWasUsed; s32 unkBefore = gUnknown_202F208; attackerInfo->unk159 = statusMoveMatch; if (currMove->id == MOVE_ASSIST) { Move assistMove = *currMove; assistMove.id = sub_8057144(attacker); sub_80928C0(gFormatBuffer_Items[0], &assistMove, NULL); LogMessageByIdWithPopupCheckUser(attacker, gUnknown_80FD2DC); // Assist: moveWasUsed = TryUseChosenMove(attacker, var_34, itemId, arg_0, isLinkedMove, &assistMove); } else { moveWasUsed = TryUseChosenMove(attacker, var_34, itemId, arg_0, isLinkedMove, currMove); } if (var_28 && moveWasUsed) { if (currMove->moveFlags2 & MOVE_FLAG2_UNK4) { currMove->moveFlags2 &= ~(MOVE_FLAG2_UNK4); } else { currMove->moveFlags2 |= MOVE_FLAG_TEMPORARY; } } if (unkBefore == gUnknown_202F208) { if (itemId == 0) { LogMessageByIdWithPopupCheckUser(attacker, gUnknown_80FC690); // The currMove failed! } else { LogMessageByIdWithPopupCheckUser(attacker, gUnknown_80FC6A4); // The Orb failed! } } } } sub_804178C(1); if (!EntityExists(attacker) || sub_8044B28()) break; if (++moveId >= MAX_MON_MOVES) break; if (!MoveFlagLinkChain(&attackerInfo->moves.moves[moveId])) break; } if (EntityExists(attacker)) { for (i = 0; i < MAX_MON_MOVES; i++) { if (attackerInfo->mimicMoveIDs[i] != 0) { Move mimicMove, assistMove; Move *movePtr; movePtr = &mimicMove; sub_8092AA8(&mimicMove, attackerInfo->mimicMoveIDs[i]); if (MoveFlagExists(&mimicMove)) { if (mimicMove.id == MOVE_ASSIST) { assistMove = mimicMove; assistMove.id = sub_8057144(attacker); movePtr = &assistMove; sub_80928C0(gFormatBuffer_Items[0], &assistMove, NULL); LogMessageByIdWithPopupCheckUser(attacker, gUnknown_80FD2DC); // Assist: } TryUseChosenMove(attacker, 0, itemId, arg_0, isLinkedMove, movePtr); } sub_804178C(1); } } } if (EntityExists(attacker)) { sub_8071DA4(attacker); if (EntityExists(attacker) && gUnknown_202F222 != 0) { gUnknown_202F222 = 0; if (EntityExists(attacker)) { EntityInfo *attackerInfo = GetEntInfo(attacker); s32 statusTurns = CalculateStatusTurns(attacker, gUnknown_80F4E70, TRUE); PausedStatusTarget(attacker, attacker, 1, statusTurns, FALSE); SetExpMultplier(attackerInfo); } } } return TRUE; } static void TriggerTargetAbilityEffect(Entity *attacker) { if (EntityExists(attacker)) { EntityInfo *entInfo = GetEntInfo(attacker); if (entInfo->abilityEffectFlags & ABILITY_FLAG_ARENA_TRAP) { LogMessageByIdWithPopupCheckUser(attacker, gUnknown_80FEEA4); // Arena Trap prevents movement! ImmobilizedStatusTarget(attacker, attacker); } if (entInfo->abilityEffectFlags & ABILITY_FLAG_SHADOW_TAG) { LogMessageByIdWithPopupCheckUser(attacker, gUnknown_80FEEC8); // Shadow Tag prevents movement! ImmobilizedStatusTarget(attacker, attacker); } if (entInfo->abilityEffectFlags & ABILITY_FLAG_MAGNET_PULL) { LogMessageByIdWithPopupCheckUser(attacker, gUnknown_80FEEEC); // Magnet Pull prevents movement! ImmobilizedStatusTarget(attacker, attacker); } if (entInfo->abilityEffectFlags & ABILITY_FLAG_STATIC) { LogMessageByIdWithPopupCheckUser(attacker, gUnknown_80FEF0C); // Static caused paralysis! ParalyzeStatusTarget(attacker, attacker, TRUE); } if (entInfo->abilityEffectFlags & ABILITY_FLAG_EFFECT_SPORE_PRLZ) { LogMessageByIdWithPopupCheckUser(attacker, gUnknown_80FEF30); // Effect Spore scattered spores ParalyzeStatusTarget(attacker, attacker, TRUE); } if (entInfo->abilityEffectFlags & ABILITY_FLAG_POISON_POINT) { LogMessageByIdWithPopupCheckUser(attacker, gUnknown_80FEF4C); // Poison Point struck! PoisonedStatusTarget(attacker, attacker, TRUE); } if (entInfo->abilityEffectFlags & ABILITY_FLAG_EFFECT_SPORE_PSN) { LogMessageByIdWithPopupCheckUser(attacker, gUnknown_80FEF50); // Effect Spore scattered spores! PoisonedStatusTarget(attacker, attacker, TRUE); } if (entInfo->abilityEffectFlags & ABILITY_FLAG_EFFECT_SPORE_SLP) { LogMessageByIdWithPopupCheckUser(attacker, gUnknown_80FEF54); // Effect Spore scattered spores! sub_8075C58(attacker, attacker, CalculateStatusTurns(attacker, gUnknown_80F4E74, TRUE), TRUE); } if (entInfo->abilityEffectFlags & ABILITY_FLAG_FLAME_BODY) { LogMessageByIdWithPopupCheckUser(attacker, gUnknown_80FEF74); // Flame Body caused a burn! BurnedStatusTarget(attacker, attacker, TRUE, TRUE); } if (entInfo->abilityEffectFlags & ABILITY_FLAG_CUTE_CHARM) { LogMessageByIdWithPopupCheckUser(attacker, gUnknown_80FEF98); // Cute Charm caused infatuation InfatuateStatusTarget(attacker, attacker, TRUE); } if (entInfo->abilityEffectFlags & ABILITY_FLAG_STENCH) { SubstitutePlaceholderStringTags(gFormatBuffer_Monsters[0], attacker, 0); LogMessageByIdWithPopupCheckUser(attacker, gUnknown_80FEFD0); // A horrid stench billowed out sub_80428A0(attacker); entInfo->terrifiedTurns = gUnknown_80F5004; } entInfo->abilityEffectFlags = 0; } } bool8 TryUseChosenMove(struct Entity *attacker, u32 r6, s32 itemId, u32 var_30, bool32 isLinkedMove, struct Move *move) { s32 i; Entity *targetsArray[MAX_MOVE_TARGETS + 1]; const u8 *msg; Move metronomeMove, naturePwrMove; s32 var_2C; s32 var_28; s32 var_24; bool8 moveUsable; msg = NULL; targetsArray[0] = NULL; sub_804178C(1); if (move->id == MOVE_METRONOME) { gMetronomeCalledArrayId = DungeonRandInt(METRONOME_AVAILABLE_CALLED_MOVES); InitPokemonMove(&metronomeMove, gMetronomeCalledMoves[gMetronomeCalledArrayId].moveID); metronomeMove.moveFlags = move->moveFlags; metronomeMove.moveFlags2 = move->moveFlags2; sub_8056468(attacker, move, gUnknown_80FECBC, targetsArray, itemId, TRUE, FALSE); sub_804178C(1); move = &metronomeMove; } else if (move->id == MOVE_NATURE_POWER) { s32 tileset = gDungeon->tileset; if (tileset < 0) tileset = 0; if (tileset > 74) tileset = 74; InitPokemonMove(&naturePwrMove, gNaturePowerCalledMoves[tileset].moveID); naturePwrMove.moveFlags = move->moveFlags; naturePwrMove.moveFlags2 = move->moveFlags2; sub_8056468(attacker, move, gUnknown_80FECE0, targetsArray, itemId, TRUE, FALSE); sub_804178C(1); move = &naturePwrMove; } var_28 = 0; if ((GetMoveTargetAndRangeForPokemon(attacker, move, TRUE) & (0xF0)) == TARGETING_FLAG_TARGET_LINE) { var_28 = 10; } if ((GetMoveTargetAndRangeForPokemon(attacker, move, TRUE) & (0xF0)) == TARGETING_FLAG_CUT_CORNERS) { var_28 = 1; if ((move->id != MOVE_SOLARBEAM || GetApparentWeather(attacker) != WEATHER_SUNNY) && DoesMoveCharge(move->id)) { if (!MoveMatchesBideClassStatus(attacker, move)) { var_28 = 0; } } } SetMessageArgument_2(gFormatBuffer_Monsters[0], GetEntInfo(attacker), 0); sub_80928C0(gFormatBuffer_Items[0], move, NULL); if (MoveMatchesBideClassStatus(attacker, move)) { msg = gUnknown_80FC72C; // mon loosed move GetEntInfo(attacker)->unkFF = 0; moveUsable = sub_805744C(attacker, move, TRUE); } else { if (itemId == 0) { msg = GetMoveUseText(move->id); } else { msg = gUnknown_80F9158; } moveUsable = CanMonsterUseMove(attacker, move, TRUE); } if (moveUsable && r6) { sub_806ACE8(attacker, move); } if (GetEntInfo(attacker)->muzzled.muzzled == TRUE && FailsWhileMuzzled(move->id)) { SubstitutePlaceholderStringTags(gFormatBuffer_Monsters[0], attacker, 0); LogMessageByIdWithPopupCheckUser(attacker, msg); sub_803E708(0xA, 0x3F); LogMessageByIdWithPopupCheckUser(attacker, gUnknown_80FC710); // is muzzled! return FALSE; } else if (!moveUsable) { SetMessageArgument_2(gFormatBuffer_Monsters[0], GetEntInfo(attacker), 0); if (itemId == 0) { sub_80928C0(gFormatBuffer_Items[0], move, NULL); LogMessageByIdWithPopupCheckUser(attacker, msg); sub_803E708(0xA, 0x3F); LogMessageByIdWithPopupCheckUser(attacker, gUnknown_80FC6D0); // But the move couldn't be used! } else { BufferItemName(gFormatBuffer_Items[0], itemId, NULL); LogMessageByIdWithPopupCheckUser(attacker, msg); sub_803E708(0xA, 0x3F); LogMessageByIdWithPopupCheckUser(attacker, gUnknown_80FC6FC); // But Orbs are prevented from being used! } return FALSE; } gUnknown_202F214 = 0; gUnknown_202F20C = 0; gUnknown_202F210 = 0; gUnknown_202F218 = 0; gUnknown_202F219 = 0; gUnknown_202F21A = 0; gUnknown_202F21C = 0; gUnknown_202F220 = 0; if (isLinkedMove && GetEntInfo(attacker)->unk153 <= 3) { GetEntInfo(attacker)->unk153++; } var_2C = sub_8057070(move); for (i = 0; i < var_2C; i++) { u8 r4; EntityInfo *entInfo; var_24 = 1; if (gUnknown_202F220 != 0 || gUnknown_202F221 != 0) break; if (!EntityExists(attacker) || sub_8044B28()) return TRUE; entInfo = GetEntInfo(attacker); if (var_30 != 0 || move->id == MOVE_SNORE || move->id == MOVE_SLEEP_TALK) { if (!IsSleeping(attacker) && CannotAttack(attacker, TRUE)) break; } else { if (CannotAttack(attacker, FALSE)) break; } entInfo->unk14A = 0; if (move->id == MOVE_THRASH) { GetEntInfo(attacker)->action.direction = DungeonRandInt(NUM_DIRECTIONS); TargetTileInFront(attacker); var_24 = 0; } gUnknown_203B438 = NULL; targetsArray[0] = 0; if (var_28 == 0 || var_28 == 1) { SetTargetsForMove(targetsArray, attacker, move); SortTargets(targetsArray, attacker); if (i != 0 && var_24 != 0 && targetsArray[0] == NULL) break; } r4 = sub_8056468(attacker, move, msg, targetsArray, itemId, (i == 0), var_28); msg = NULL; if (gUnknown_203B438 != 0) { sub_806A1E8(gUnknown_203B438); } if (GetEntInfo(attacker)->cringeClassStatus.status != STATUS_CONFUSED && GetEntInfo(attacker)->cringeClassStatus.status != STATUS_COWERING) { EntityInfo *entInfo = GetEntInfo(attacker); entInfo->targetPos.x = 0; entInfo->targetPos.y = 0; } gUnknown_202F214++; if (var_28 != 0) { sub_80566F8(attacker, move, var_28, r4, itemId, isLinkedMove); } else { UseMoveAgainstTargets(targetsArray, attacker, move, itemId, isLinkedMove); } if (!EntityExists(attacker)) break; sub_806CF18(attacker); if (GetEntInfo(attacker)->unk14A == 0) { GetEntInfo(attacker)->unk14A = 0; // Redundant as it's already 0 sub_8079764(attacker); } } if (gUnknown_202F21A != 0) { EndFrozenClassStatus(attacker, attacker); EndLeechSeedClassStatus(attacker, attacker); } if (gUnknown_202F219 != 0 && EntityExists(attacker)) { EntityInfo *entInfo = GetEntInfo(attacker); ConfuseStatusTarget(attacker, attacker, FALSE); SetExpMultplier(entInfo); } return TRUE; } bool8 sub_8056468(Entity *entity, Move *move, const u8 *str, Entity **unkArray, bool32 itemId, bool8 arg_4, bool32 unused) { s32 i; bool8 ret = FALSE; bool32 r7 = (sub_8045888(entity) != FALSE); if (str != NULL) { for (i = 0; i < 65; i++) { if (unkArray[i] == NULL) { break; } if (sub_8045888(unkArray[i])) { r7 = TRUE; break; } } if (r7) { SetMessageArgument_2(gFormatBuffer_Monsters[0], GetEntInfo(entity), 0); if (itemId == 0) { sub_80928C0(gFormatBuffer_Items[0], move, NULL); } else { BufferItemName(gFormatBuffer_Items[0], itemId, NULL); } } if (move->id != MOVE_REGULAR_ATTACK) { DisplayDungeonLoggableMessageTrue(entity, str); } else { DisplayDungeonLoggableMessageFalse(entity, str); } } if (r7) { if (arg_4) { ret = sub_8040BB0(entity, move, TRUE); } else { ret = sub_8040BB0(entity, move, FALSE); } sub_8040DA0(entity, move); } else { sub_806CE68(entity, GetEntInfo(entity)->action.direction); } return ret; } struct UnkStruct_sub_800E308_1 { s16 unk0; s16 unk2; DungeonPos unk4; DungeonPos unk8; s32 unkC; s32 unk10; }; // Maybe DungeonPos? Maybe not, sub_800E308 is called only by sub_8056564, so :shrug: struct UnkStruct_sub_800E308_2 { s16 u0; s16 u2; }; extern s32 sub_800E308(struct UnkStruct_sub_800E308_1 *, struct UnkStruct_sub_800E308_2 *); #ifdef NONMATCHING // https://decomp.me/scratch/fTUsI s32 sub_8056564(Entity *entity, DungeonPos *pos, Move *move, s32 r4) { struct UnkStruct_sub_800E308_1 unkSp1; struct UnkStruct_sub_800E308_2 unkSp2; EntityInfo *entInfo = GetEntInfo(entity); if (!gDungeon->unk181e8.blinded && (GetBodySize(entInfo->apparentID) < 4 || r4 == 1)) { unkStruct_80BDBC4 *unkStruct = sub_800ECB8(sub_80412E0(move->id, GetApparentWeather(entity), 1)); s32 unk6 = unkStruct->unk6; // This part with unkPos doesn't match PixelPos unkPos = {pos->x * 0x1800, pos->y * 0x1800}; unkPos.x += 0x1000; unkPos.y += 0xC00; unkSp2.u0 = unkPos.x / 256; unkSp2.u2 = unkPos.y / 256; if (unk6 != 0) { s32 someRetVal; sub_800EF10(sub_80412E0(move->id, GetApparentWeather(entity), 1)); sub_803E46C(0x5E); someRetVal = sub_800E710(entInfo->apparentID, sub_80412E0(move->id, GetApparentWeather(entity), 1)); if (someRetVal != -1) { sub_800569C(&unkSp1.unk8, &entity->axObj.axdata, someRetVal); } else { unkSp1.unk8 = (DungeonPos) {0}; } unkSp1.unk0 = sub_80412E0(move->id, GetApparentWeather(entity), 1); unkSp1.unk2 = entInfo->apparentID; unkSp1.unk4.x = entity->pixelPos.x / 256; unkSp1.unk4.y = entity->pixelPos.y / 256; unkSp1.unkC = entInfo->action.direction; unkSp1.unk10 = 0; return sub_800E308(&unkSp1, &unkSp2); } } return -1; } #else NAKED s32 sub_8056564(Entity *entity, DungeonPos *pos, Move *move, s32 r4) { asm_unified("push {r4-r7,lr}\n" " mov r7, r9\n" " mov r6, r8\n" " push {r6,r7}\n" " sub sp, 0x18\n" " adds r6, r0, 0\n" " adds r5, r1, 0\n" " adds r7, r2, 0\n" " adds r4, r3, 0\n" " ldr r0, [r6, 0x70]\n" " mov r8, r0\n" " ldr r0, _08056680\n" " ldr r0, [r0]\n" " ldr r1, _08056684\n" " adds r0, r1\n" " ldrb r0, [r0]\n" " mov r9, r0\n" " cmp r0, 0\n" " beq _0805658C\n" " b _080566E4\n" "_0805658C:\n" " mov r2, r8\n" " movs r1, 0x4\n" " ldrsh r0, [r2, r1]\n" " bl GetBodySize\n" " lsls r0, 24\n" " lsrs r0, 24\n" " cmp r0, 0x3\n" " bls _080565A4\n" " cmp r4, 0x1\n" " bne _080565A4\n" " b _080566E4\n" "_080565A4:\n" " ldrh r4, [r7, 0x2]\n" " adds r0, r6, 0\n" " bl GetApparentWeather\n" " adds r1, r0, 0\n" " lsls r1, 24\n" " lsrs r1, 24\n" " adds r0, r4, 0\n" " movs r2, 0x1\n" " bl sub_80412E0\n" " lsls r0, 16\n" " lsrs r0, 16\n" " bl sub_800ECB8\n" " movs r2, 0x6\n" " ldrsh r4, [r0, r2]\n" " movs r1, 0\n" " ldrsh r0, [r5, r1]\n" " lsls r1, r0, 1\n" " adds r1, r0\n" " lsls r1, 11\n" " movs r0, 0x2\n" " ldrsh r2, [r5, r0]\n" " lsls r0, r2, 1\n" " adds r0, r2\n" " lsls r0, 11\n" " movs r2, 0x80\n" " lsls r2, 5\n" " adds r3, r0, r2\n" " movs r2, 0xC0\n" " lsls r2, 4\n" " adds r0, r1, r2\n" " cmp r0, 0\n" " bge _080565EC\n" " adds r0, 0xFF\n" "_080565EC:\n" " lsls r0, 8\n" " lsrs r0, 16\n" " ldr r1, _08056688\n" " ldr r2, [sp, 0x14]\n" " ands r2, r1\n" " orrs r2, r0\n" " str r2, [sp, 0x14]\n" " adds r0, r3, 0\n" " cmp r0, 0\n" " bge _08056602\n" " adds r0, 0xFF\n" "_08056602:\n" " lsls r0, 8\n" " lsrs r0, 16\n" " lsls r0, 16\n" " ldr r1, _0805668C\n" " ands r2, r1\n" " orrs r2, r0\n" " str r2, [sp, 0x14]\n" " cmp r4, 0\n" " beq _080566E4\n" " ldrh r4, [r7, 0x2]\n" " adds r0, r6, 0\n" " bl GetApparentWeather\n" " adds r1, r0, 0\n" " lsls r1, 24\n" " lsrs r1, 24\n" " adds r0, r4, 0\n" " movs r2, 0x1\n" " bl sub_80412E0\n" " lsls r0, 16\n" " lsrs r0, 16\n" " bl sub_800EF10\n" " bl sub_800EF64\n" " movs r0, 0x5E\n" " bl sub_803E46C\n" " mov r0, r8\n" " movs r1, 0x4\n" " ldrsh r5, [r0, r1]\n" " ldrh r4, [r7, 0x2]\n" " adds r0, r6, 0\n" " bl GetApparentWeather\n" " adds r1, r0, 0\n" " lsls r1, 24\n" " lsrs r1, 24\n" " adds r0, r4, 0\n" " movs r2, 0x1\n" " bl sub_80412E0\n" " adds r1, r0, 0\n" " lsls r1, 16\n" " lsrs r1, 16\n" " adds r0, r5, 0\n" " bl sub_800E710\n" " adds r2, r0, 0\n" " movs r0, 0x1\n" " negs r0, r0\n" " cmp r2, r0\n" " beq _08056690\n" " add r0, sp, 0x8\n" " adds r1, r6, 0\n" " adds r1, 0x28\n" " lsls r2, 24\n" " lsrs r2, 24\n" " bl sub_800569C\n" " b _08056694\n" " .align 2, 0\n" "_08056680: .4byte gDungeon\n" "_08056684: .4byte 0x0001820a\n" "_08056688: .4byte 0xffff0000\n" "_0805668C: .4byte 0x0000ffff\n" "_08056690:\n" " mov r2, r9\n" " str r2, [sp, 0x8]\n" "_08056694:\n" " ldrh r4, [r7, 0x2]\n" " adds r0, r6, 0\n" " bl GetApparentWeather\n" " adds r1, r0, 0\n" " lsls r1, 24\n" " lsrs r1, 24\n" " adds r0, r4, 0\n" " movs r2, 0x1\n" " bl sub_80412E0\n" " mov r1, sp\n" " strh r0, [r1]\n" " mov r2, r8\n" " ldrh r0, [r2, 0x4]\n" " strh r0, [r1, 0x2]\n" " ldr r0, [r6, 0xC]\n" " cmp r0, 0\n" " bge _080566BC\n" " adds r0, 0xFF\n" "_080566BC:\n" " asrs r0, 8\n" " strh r0, [r1, 0x4]\n" " mov r1, sp\n" " ldr r0, [r6, 0x10]\n" " cmp r0, 0\n" " bge _080566CA\n" " adds r0, 0xFF\n" "_080566CA:\n" " asrs r0, 8\n" " strh r0, [r1, 0x6]\n" " mov r0, r8\n" " adds r0, 0x46\n" " ldrb r0, [r0]\n" " str r0, [sp, 0xC]\n" " movs r0, 0\n" " str r0, [sp, 0x10]\n" " add r1, sp, 0x14\n" " mov r0, sp\n" " bl sub_800E308\n" " b _080566E8\n" "_080566E4:\n" " movs r0, 0x1\n" " negs r0, r0\n" "_080566E8:\n" " add sp, 0x18\n" " pop {r3,r4}\n" " mov r8, r3\n" " mov r9, r4\n" " pop {r4-r7}\n" " pop {r1}\n" " bx r1"); } #endif // NONMATCHING // This would signify a new file starts here, but it makes little sense tbh. UNUSED static const char sPksDirMeme[] = "pksdir0"; static const s32 gUnknown_81069D4[NUM_DIRECTIONS] = { [DIRECTION_SOUTH] = 1, [DIRECTION_SOUTHEAST] = 1, [DIRECTION_EAST] = 1, [DIRECTION_NORTHEAST] = 0, [DIRECTION_NORTH] = 0, [DIRECTION_NORTHWEST] = 0, [DIRECTION_WEST] = 1, [DIRECTION_SOUTHWEST] = 1 }; // This function looks important, but what does it do? void sub_80566F8(Entity *attacker, Move *move, s32 a2, bool8 a3, s32 itemId, s32 isLinkedMove) { DungeonPos var_68; DungeonPos var_64; Entity *targetsArray[2]; // Only 2 hmm s32 var_4C, var_48; s32 i, j; s32 targetArrId; s32 var_3C; s32 var_38; s32 var_34; s32 var_30; s32 var_2C; s32 var_28, var_24; s32 someCount; EntityInfo *attackerInfo; s32 unkRetVal; s32 divResult; s32 r9; targetArrId = 0; someCount = 0; attackerInfo = GetEntInfo(attacker); unkRetVal = sub_800ED20(move->id); var_30 = 2; if (unkRetVal != 1) { var_30 = 6; if (unkRetVal == 2) { var_30 = 3; } } var_68.x = attacker->pos.x; var_68.y = attacker->pos.y; var_4C = gAdjacentTileOffsets[attackerInfo->action.direction].x; var_48 = gAdjacentTileOffsets[attackerInfo->action.direction].y; for (i = 0; i < a2; i++) { const Tile *tile; if (var_68.x < 0 || var_68.y < 0 || var_68.x > 55 || var_68.y > 31) break; var_68.x += var_4C; var_68.y += var_48; someCount++; tile = GetTile(var_68.x, var_68.y); if (!(tile->terrainType & (TERRAIN_TYPE_NORMAL | TERRAIN_TYPE_SECONDARY))) break; if (tile->monster != NULL && GetEntityType(tile->monster) == ENTITY_MONSTER) break; } if (MoveRequiresCharging(attacker, move->id) && !MoveMatchesBideClassStatus(attacker, move)) { var_34 = -1; } else { var_34 = sub_8056564(attacker, &var_68, move, a2); } var_68.x = attacker->pos.x; var_68.y = attacker->pos.y; var_4C = gAdjacentTileOffsets[attackerInfo->action.direction].x; var_48 = gAdjacentTileOffsets[attackerInfo->action.direction].y; divResult = someCount * (24 / var_30); if (a2 > 1) { var_3C = divResult + 8; if (var_3C >= 64) { var_3C = 64; } } else { var_3C = 32; } r9 = 0; var_2C = 0x80000 / divResult; var_38 = gUnknown_81069D4[attackerInfo->action.direction]; gDungeon->unk1BDD4.unk1C05E = 1; for (i = 0; i < a2; i++) { DungeonPos var_68Before; const Tile *tile; if (var_68.x < 0 || var_68.y < 0 || var_68.x > 55 || var_68.y > 31) break; var_68Before = var_68; var_68.x += var_4C; var_68.y += var_48; if (sub_803F428(&var_68) && !gDungeon->unk181e8.blinded) { PixelPos pos32; pos32.x = (var_68Before.x * 0x1800) + 0xC00; pos32.y = (var_68Before.y * 0x1800) + 0x1000; var_28 = var_30 * (var_4C << 8); var_24 = var_30 * (var_48 << 8); for (j = 0; j < 24 / var_30; j++) { if (var_34 >= 0) { s32 r3; s32 r2; if (a3 != 0) { r3 = sin_4096(r9 / 256) * var_3C; } else { r3 = 0; } var_64.x = pos32.x / 256; var_64.y = (pos32.y - r3) / 256; r2 = pos32.y / 256; r2 -= gDungeon->unk181e8.cameraPixelPos.y; r2 /= 2; sub_800E3AC(var_34, &var_64, r2 + var_38); } sub_803E46C(0x30); pos32.x += var_28; pos32.y += var_24; r9 += var_2C; } } else { r9 += (24 / var_30) * var_2C; } tile = GetTile(var_68.x, var_68.y); if (!(tile->terrainType & (TERRAIN_TYPE_NORMAL | TERRAIN_TYPE_SECONDARY))) break; if (tile->monster != NULL && GetEntityType(tile->monster) == ENTITY_MONSTER && !sub_80571F0(tile->monster, move)) { if (targetArrId <= 0) { bool8 canHitAnyone = FALSE; s32 targetFlags; EntityInfo *attackerInfo = GetEntInfo(attacker); if (attackerInfo->cringeClassStatus.status == STATUS_CONFUSED || attackerInfo->blinkerClassStatus.status == STATUS_BLINKER || attackerInfo->cringeClassStatus.status == STATUS_COWERING) { canHitAnyone = TRUE; } targetFlags = GetMoveTargetAndRangeForPokemon(attacker, move, FALSE); targetArrId = SetNewTarget(targetArrId, targetsArray, targetFlags, attacker, tile->monster, move, canHitAnyone); } break; } } if (var_34 >= 0) { sub_800DC14(var_34); } sub_804178C(1); gDungeon->unk1BDD4.unk1C05E = 0; if (targetArrId > 0) { targetsArray[targetArrId] = NULL; UseMoveAgainstTargets(targetsArray, attacker, move, itemId, isLinkedMove); } else if (a2 == 1 && sub_803F428(&var_68)) { sub_803E708(1, 0x4A); sub_8041168(attacker, NULL, move, &var_68); } } static bool8 AccuracyCalc(Entity *attacker, Entity *target, Move *move, s32 accuracyType, bool8 selfAlwaysHits) { s32 statStageAccuracy, statStageEvasion; s32 statStageMul; s32 accuracy = GetMoveAccuracyOrAIChance(move, accuracyType); s32 rand = DungeonRandInt(100); EntityInfo *attackerInfo = GetEntInfo(attacker); EntityInfo *targetInfo = GetEntInfo(target); if (selfAlwaysHits && attacker == target) return TRUE; if (move->id == MOVE_REGULAR_ATTACK && IQSkillIsEnabled(attacker, IQ_SURE_HIT_ATTACKER)) return TRUE; if (attackerInfo->sureShotClassStatus.status == STATUS_SURE_SHOT) return TRUE; if (attackerInfo->sureShotClassStatus.status == STATUS_WHIFFER) return FALSE; if (accuracy > 100) return TRUE; if (HasHeldItem(target, ITEM_DETECT_BAND)) { accuracy -= gUnknown_80F519C; } if (IQSkillIsEnabled(target, IQ_QUICK_DODGER)) { accuracy -= gUnknown_80F51A0; } statStageAccuracy = attackerInfo->hitChanceStages[0]; if (HasAbility(attacker, ABILITY_COMPOUNDEYES)) { statStageAccuracy += 2; } if (move->id == MOVE_THUNDER) { s32 weather = GetApparentWeather(attacker); if (weather == WEATHER_RAIN) { return TRUE; } else if (weather == WEATHER_SUNNY) { statStageAccuracy -= 2; } } if (statStageAccuracy < 0) statStageAccuracy = 0; if (statStageAccuracy > 20) statStageAccuracy = 20; statStageMul = gUnknown_80F50F4[0][statStageAccuracy]; if (statStageMul < 0) statStageMul = 0; if (statStageMul > (256 * 100)) statStageMul = (256 * 100); accuracy *= statStageMul; accuracy /= 256; statStageEvasion = targetInfo->hitChanceStages[1]; if (targetInfo->exposed) { statStageEvasion = 10; } if (GetApparentWeather(target) == WEATHER_SANDSTORM && HasAbility(target, ABILITY_SAND_VEIL)) { statStageEvasion += 2; } if (HasAbility(attacker, ABILITY_HUSTLE)) { bool32 specialMove = (IsTypePhysical(GetMoveType(move)) == FALSE); if (!specialMove) { statStageEvasion += 2; } } if (statStageEvasion < 0) statStageEvasion = 0; if (statStageEvasion > 20) statStageEvasion = 20; statStageMul = gUnknown_80F50F4[1][statStageEvasion]; if (statStageMul < 0) statStageMul = 0; if (statStageMul > (256 * 100)) statStageMul = (256 * 100); accuracy *= statStageMul; accuracy /= 256; if (rand < accuracy) return TRUE; else return FALSE; } static void SetTargetsForMove(Entity **targetsArray, Entity *attacker, Move *move) { s32 targetFlags; s32 targetFlagsAnd; s32 arrId = 0; bool8 canHitPartner = (GetEntInfo(attacker)->cringeClassStatus.status == STATUS_CONFUSED || GetEntInfo(attacker)->blinkerClassStatus.status == STATUS_BLINKER || GetEntInfo(attacker)->cringeClassStatus.status == STATUS_COWERING); bool8 canHitSelf = (GetEntInfo(attacker)->cringeClassStatus.status == STATUS_CONFUSED || GetEntInfo(attacker)->cringeClassStatus.status == STATUS_COWERING); if (IQSkillIsEnabled(attacker, IQ_NONTRAITOR)) { canHitSelf = FALSE; canHitPartner = FALSE; } targetFlags = GetMoveTargetAndRangeForPokemon(attacker, move, FALSE); if ((targetFlags & 0xF) == 4) { bool32 usable = MoveMatchesBideClassStatus(attacker, move); if (move->id == MOVE_SOLARBEAM && GetApparentWeather(attacker) == WEATHER_SUNNY) { usable = TRUE; } if (usable) targetFlags = 0; else targetFlags = 0x73; } targetFlagsAnd = targetFlags & 0xF0; if (targetFlagsAnd == 0) { Entity *targetEntity = sub_80696A8(attacker); if (targetEntity != NULL) { arrId = SetNewTarget(arrId, targetsArray, targetFlags, attacker, targetEntity, move, canHitPartner); } } else if (targetFlagsAnd == 0x10 || targetFlagsAnd == 0x20) { s32 i; s32 direction, to; EntityInfo *entInfo = GetEntInfo(attacker); if (targetFlagsAnd == 0x20) { direction = entInfo->action.direction; to = 8; } else { direction = entInfo->action.direction - 1; to = 3; } for (i = 0; i < to; i++, direction++) { Entity *targetEntity; DungeonPos unkPositon; direction &= DIRECTION_MASK; unkPositon.x = attacker->pos.x + gAdjacentTileOffsets[direction].x ; unkPositon.y = attacker->pos.y + gAdjacentTileOffsets[direction].y; targetEntity = GetMonsterAtPos(&unkPositon); if (targetEntity != NULL) { arrId = SetNewTarget(arrId, targetsArray, targetFlags, attacker, targetEntity, move, canHitPartner); } } } else if (targetFlagsAnd == 0x30) { s32 i; for (i = 0; i < DUNGEON_MAX_POKEMON; i++) { Entity *dungeonMon = gDungeon->activePokemon[i]; if (EntityExists(dungeonMon) && sub_8045A70(attacker, dungeonMon)) { if (dungeonMon == attacker) { arrId = SetNewTarget(arrId, targetsArray, targetFlags, attacker, attacker, move, canHitSelf); } else { arrId = SetNewTarget(arrId, targetsArray, targetFlags, attacker, dungeonMon, move, canHitPartner); } } } } else if (targetFlagsAnd == 0x40) { bool32 r4 = FALSE; Entity *targetEntity = sub_80696FC(attacker); if (targetEntity != NULL) { s32 arrIdBefore = arrId; arrId = SetNewTarget(arrId, targetsArray, targetFlags, attacker, targetEntity, move, canHitPartner); r4 = (arrId != arrIdBefore); } if (!r4) { targetEntity = sub_806977C(attacker); if (targetEntity != NULL) { arrId = SetNewTarget(arrId, targetsArray, targetFlags, attacker, targetEntity, move, canHitPartner); } } } else if (targetFlagsAnd == 0x50) { // Nothing happens here } else if (targetFlagsAnd == 0x80) { Entity *targetEntity = sub_80696FC(attacker); if (targetEntity != NULL) { arrId = SetNewTarget(arrId, targetsArray, targetFlags, attacker, targetEntity, move, canHitPartner); } } else if (targetFlagsAnd == 0x60) { s32 i; for (i = 0; i < DUNGEON_MAX_POKEMON; i++) { Entity *dungeonMon = gDungeon->activePokemon[i]; if (EntityExists(dungeonMon)) { arrId = SetNewTarget(arrId, targetsArray, targetFlags, attacker, dungeonMon, move, canHitPartner); } } } else if (targetFlagsAnd == 0x70) { arrId = SetNewTarget(arrId, targetsArray, targetFlags, attacker, attacker, move, canHitPartner); } targetsArray[arrId] = NULL; } static s32 SetNewTarget(s32 targetArrId, Entity **targetsArray, s32 targetFlags_, Entity *attacker, Entity *target, Move *move, bool32 canHitAnyone_) { bool32 canHitTarget; EntityInfo *targetInfo; // It's happening again, all over the codebase there are problems with s16 arguments, where the lsl/asr asm can't be matched. What is going on with that? s32 targetFlags = (s16)targetFlags_; bool8 canHitAnyone = canHitAnyone_; canHitTarget = FALSE; targetInfo = GetEntInfo(target); if (move->id == MOVE_BATON_PASS && attacker == target) return targetArrId; if (targetInfo->shopkeeper == SHOPKEEPER_MODE_SHOPKEEPER) return targetArrId; if (targetInfo->monsterBehavior == BEHAVIOR_DIGLETT || targetInfo->monsterBehavior == BEHAVIOR_RESCUE_TARGET) return targetArrId; if (canHitAnyone) { canHitTarget = TRUE; } else { s32 targetFlagsAnd = targetFlags & 0xF; if (targetFlagsAnd == 0 || targetFlagsAnd == 4) { if (GetTreatmentBetweenMonsters(attacker, target, TRUE, FALSE) == 1) { canHitTarget = TRUE; } } else if (targetFlagsAnd == 1) { if (GetTreatmentBetweenMonsters(attacker, target, TRUE, FALSE) == 0) { canHitTarget = TRUE; } } else if (targetFlagsAnd == 2) { canHitTarget = TRUE; } else if (targetFlagsAnd == 5) { if (attacker != target) { canHitTarget = TRUE; } } else if (targetFlagsAnd == 6) { if (GetTreatmentBetweenMonsters(attacker, target, TRUE, FALSE) == 0 && attacker != target) { canHitTarget = TRUE; } } else if (targetFlagsAnd == 3) { canHitTarget = TRUE; } } if (sub_80571F0(target, move)) { canHitTarget = FALSE; } if (canHitTarget && targetArrId < MAX_MOVE_TARGETS) { targetsArray[targetArrId] = target; if (!GetEntInfo(target)->isNotTeamMember && gUnknown_203B438 == NULL) { gUnknown_203B438 = target; } targetArrId++; } return targetArrId; } struct MultiTurnChargeMove { u16 moveID; u8 status; }; const struct MultiTurnChargeMove gMultiTurnChargeMoves[10] = { {MOVE_SOLARBEAM, STATUS_SOLARBEAM}, {MOVE_SKY_ATTACK, STATUS_SKY_ATTACK}, {MOVE_RAZOR_WIND, STATUS_RAZOR_WIND}, {MOVE_FOCUS_PUNCH, STATUS_FOCUS_PUNCH}, {MOVE_SKULL_BASH, STATUS_SKULL_BASH}, {MOVE_FLY, STATUS_FLYING}, {MOVE_BOUNCE, STATUS_BOUNCING}, {MOVE_DIVE, STATUS_DIVING}, {MOVE_DIG, STATUS_DIGGING}, {MOVE_NOTHING, STATUS_NONE} }; const u32 gMultiTurnBideClassStatuses[10] = { STATUS_SOLARBEAM, STATUS_SKY_ATTACK, STATUS_RAZOR_WIND, STATUS_FOCUS_PUNCH, STATUS_SKULL_BASH, STATUS_FLYING, STATUS_BOUNCING, STATUS_DIVING, STATUS_DIGGING, STATUS_NONE }; s32 sub_8057070(Move *move) { s32 numberOfChainedHits = GetMoveNumberOfChainedHits(move); if (numberOfChainedHits == 0) return DungeonRandRange(2, 6); else return numberOfChainedHits; } bool8 MoveCausesPaused(Move *move) { if(move->id == MOVE_FRENZY_PLANT) return TRUE; if(move->id == MOVE_HYDRO_CANNON) return TRUE; if(move->id == MOVE_HYPER_BEAM) return TRUE; if(move->id == MOVE_BLAST_BURN) return TRUE; return FALSE; } bool8 MoveMatchesBideClassStatus(Entity *pokemon, Move *move) { if (!EntityExists(pokemon)) { return FALSE; } else { EntityInfo *pokemonInfo = GetEntInfo(pokemon); s32 i; for (i = 0; i < 100; i++) { if (gMultiTurnChargeMoves[i].moveID == MOVE_NOTHING) { return FALSE; } if (move->id == gMultiTurnChargeMoves[i].moveID && pokemonInfo->bideClassStatus.status == gMultiTurnChargeMoves[i].status) { return TRUE; } } return FALSE; } } bool8 IsChargingAnyTwoTurnMove(Entity *pokemon, bool8 checkCharge) { if (!EntityExists(pokemon)) { return FALSE; } else { EntityInfo *pokemonInfo = GetEntInfo(pokemon); int i = 0; u8 *bideClassStatusPointer = &pokemonInfo->bideClassStatus.status; u8 *bideClassStatusPointer2; u8 chargeStatus = STATUS_CHARGING; for (; i < 100; i++) { u8 currentStatus = gMultiTurnBideClassStatuses[i]; u8 bideClassStatus; if (currentStatus == STATUS_NONE) { return FALSE; } bideClassStatus = *bideClassStatusPointer; bideClassStatusPointer2 = &pokemonInfo->bideClassStatus.status; if (bideClassStatus == currentStatus) { return TRUE; } } // BUG: This condition is never reached because the for loop terminates by returning FALSE at the end of the gMultiTurnBideClassStatuses array. if (checkCharge && *bideClassStatusPointer2 == chargeStatus) { return TRUE; } return FALSE; } } u32 sub_8057144(Entity * pokemon) { Move *moveStack[80]; int i, j, nMoves; nMoves = 0; for (i = 0; i < DUNGEON_MAX_POKEMON; i++) { Entity *dungeonMon = gDungeon->activePokemon[i]; if (EntityExists(dungeonMon)) { Move *moves = GetEntInfo(dungeonMon)->moves.moves; for (j = 0; j < MAX_MON_MOVES; j++) { if (moves[j].moveFlags & MOVE_FLAG_EXISTS && !MoveRequiresCharging(pokemon, moves[j].id) && moves[j].id != MOVE_SKETCH && nMoves < 80) { moveStack[nMoves++] = &moves[j]; } } } } if (nMoves == 0) { return MOVE_REGULAR_ATTACK; } else { return moveStack[DungeonRandInt(nMoves)]->id; } } bool8 sub_80571F0(Entity * pokemon, Move *move) { u16 moveID; s32 tileset; EntityInfo *entityInfo; entityInfo = GetEntInfo(pokemon); if (entityInfo->unkFF == 1) { moveID = move->id; if ((moveID == MOVE_SKY_UPPERCUT) || (moveID == MOVE_TWISTER) || (moveID == MOVE_GUST) || (moveID == MOVE_THUNDER)) return FALSE; else return TRUE; } else if (entityInfo->unkFF == 2) { if (entityInfo->bideClassStatus.status == STATUS_DIVING) { if (move->id == MOVE_WHIRLPOOL || move->id == MOVE_SURF) return FALSE; } else if (entityInfo->bideClassStatus.status == STATUS_DIGGING) { moveID = move->id; if (moveID == MOVE_EARTHQUAKE || moveID == MOVE_MAGNITUDE) return FALSE; if (moveID == MOVE_NATURE_POWER) { tileset = gDungeon->tileset; if (tileset < 0) { tileset = 0; } if (0x4a < tileset) { tileset = 0x4a; } if (gNaturePowerCalledMoves[tileset].moveID == MOVE_EARTHQUAKE) return FALSE; } } return TRUE; } return FALSE; } bool8 sub_805727C(Entity * pokemon, Entity * target, s32 chance) { bool8 uVar2; if (sub_8044B28()) return FALSE; if (!EntityExists(pokemon) || !EntityExists(target)) return FALSE; if (GetEntInfo(target)->unk158 == 0 || GetEntInfo(target)->HP == 0) return FALSE; if (chance != 0) { if (HasAbility(pokemon, ABILITY_SERENE_GRACE)) { uVar2 = DungeonRandOutcome_2(chance * 2); } else { uVar2 = DungeonRandOutcome_2(chance); } } else { uVar2 = TRUE; } if (uVar2 && (pokemon != target) && HasAbility(target, ABILITY_SHIELD_DUST)) { sub_80429C8(target); return FALSE; } return uVar2; } bool8 RollSecondaryEffect(Entity *pokemon, s32 chance) { if(!EntityExists(pokemon)) return FALSE; if(chance == 0) return TRUE; if(HasAbility(pokemon, ABILITY_SERENE_GRACE)) return DungeonRandOutcome_2(chance * 2); else return DungeonRandOutcome_2(chance); } bool8 CanAIUseMove(Entity *pokemon, s32 moveIndex, bool8 hasPPChecker) { s32 i; EntityInfo *pokemonInfo = GetEntInfo(pokemon); Move *move = &pokemonInfo->moves.moves[moveIndex]; if (!MoveFlagExists(move)) return FALSE; if (MoveFlagLinkChain(move) || MoveFlagDisabled(move) || MoveFlagSealed(move)) return FALSE; for (i = 0; i < MAX_MON_MOVES; i++) { if (CanMonsterUseMove(pokemon, move, hasPPChecker)) return TRUE; move++; if (move >= &pokemonInfo->moves.moves[MAX_MON_MOVES]) break; if (!(move->moveFlags & MOVE_FLAG_SUBSEQUENT_IN_LINK_CHAIN)) break; } return FALSE; } bool8 CanMonsterUseMove(Entity *pokemon, Move *move, bool8 hasPPChecker) { EntityInfo *pokemonInfo = GetEntInfo(pokemon); if (move->id == MOVE_REGULAR_ATTACK) { return TRUE; } if (move->moveFlags & MOVE_FLAG_DISABLED || move->moveFlags2 & MOVE_FLAG_SEALED) { return FALSE; } if (hasPPChecker) { if (move->PP == 0) { return FALSE; } if (pokemonInfo->cringeClassStatus.status == STATUS_TAUNTED && !MoveIgnoresTaunted(move)) { return FALSE; } if (pokemonInfo->cringeClassStatus.status == STATUS_ENCORE) { if (move->id == MOVE_STRUGGLE) { if (!(pokemonInfo->moves.struggleMoveFlags & MOVE_FLAG_LAST_USED)) { return FALSE; } } else if (!(move->moveFlags & MOVE_FLAG_LAST_USED)) { return FALSE; } } } return TRUE; } bool8 sub_805744C(Entity * pokemon, Move *move, bool8 param_3) { EntityInfo *entityInfo; entityInfo = GetEntInfo(pokemon); if (move->id != MOVE_REGULAR_ATTACK) { if (((move->moveFlags & MOVE_FLAG_DISABLED)) || ((move->moveFlags2 & MOVE_FLAG_EXISTS))) { return FALSE; } if (param_3 != 0) { if ((entityInfo->cringeClassStatus.status == STATUS_TAUNTED) && (!MoveIgnoresTaunted(move))) return FALSE; if (entityInfo->cringeClassStatus.status == STATUS_ENCORE) { if (move->id == MOVE_STRUGGLE) { if((entityInfo->moves.struggleMoveFlags & MOVE_FLAG_LAST_USED) == 0) return FALSE; } else { if((move->moveFlags & MOVE_FLAG_LAST_USED) == 0) return FALSE; } } } } return TRUE; } // Attacker always goes last static void SortTargets(Entity **targetsArray, Entity *attacker) { Entity *localArray[MAX_MOVE_TARGETS + 1]; s32 i; s32 count = 0; for (i = 0; i < MAX_MOVE_TARGETS + 1; i++) { if (targetsArray[i] == NULL) break; if (targetsArray[i] == attacker) continue; if (count >= MAX_MOVE_TARGETS) break; localArray[count++] = targetsArray[i]; } for (i = 0; i < MAX_MOVE_TARGETS + 1; i++) { if (targetsArray[i] == NULL) break; if (targetsArray[i] != attacker) continue; if (count >= MAX_MOVE_TARGETS) break; localArray[count++] = targetsArray[i]; } for (; count < MAX_MOVE_TARGETS + 1; count++) { localArray[count] = NULL; } for (i = 0; i < MAX_MOVE_TARGETS + 1; i++) { targetsArray[i] = localArray[i]; } } // TODO: This file could(should?) be merged with move_actions.c, status_actions.c and move_checks.c into one.