diff --git a/data/battle_ai_scripts.s b/data/battle_ai_scripts.s deleted file mode 100644 index f22ff96f4..000000000 --- a/data/battle_ai_scripts.s +++ /dev/null @@ -1,4186 +0,0 @@ -#include "constants/battle.h" -#include "constants/battle_ai.h" -#include "constants/abilities.h" -#include "constants/items.h" -#include "constants/moves.h" -#include "constants/battle_move_effects.h" -#include "constants/hold_effects.h" -#include "constants/pokemon.h" - .include "asm/macros/battle_ai_script.inc" - - .section script_data, "aw", %progbits - - .align 2 -gBattleAI_ScriptsTable:: @ 82DBEF8 - .4byte AI_CheckBadMove @ AI_SCRIPT_CHECK_BAD_MOVE - .4byte AI_TryToFaint @ AI_SCRIPT_TRY_TO_FAINT - .4byte AI_CheckViability @ AI_SCRIPT_CHECK_VIABILITY - .4byte AI_SetupFirstTurn @ AI_SCRIPT_SETUP_FIRST_TURN - .4byte AI_Risky @ AI_SCRIPT_RISKY - .4byte AI_PreferStrongestMove @ AI_SCRIPT_PREFER_STRONGEST_MOVE - .4byte AI_PreferBatonPass @ AI_SCRIPT_PREFER_BATON_PASS - .4byte AI_DoubleBattle @ AI_SCRIPT_DOUBLE_BATTLE - .4byte AI_HPAware @ AI_SCRIPT_HP_AWARE - .4byte AI_Unknown @ AI_SCRIPT_UNKNOWN - .4byte AI_Ret - .4byte AI_Ret - .4byte AI_Ret - .4byte AI_Ret - .4byte AI_Ret - .4byte AI_Ret - .4byte AI_Ret - .4byte AI_Ret - .4byte AI_Ret - .4byte AI_Ret - .4byte AI_Ret - .4byte AI_Ret - .4byte AI_Ret - .4byte AI_Ret - .4byte AI_Ret - .4byte AI_Ret - .4byte AI_Ret - .4byte AI_Ret - .4byte AI_Ret - .4byte AI_Roaming @ AI_SCRIPT_ROAMING - .4byte AI_Safari @ AI_SCRIPT_SAFARI - .4byte AI_FirstBattle @ AI_SCRIPT_FIRST_BATTLE - -AI_CheckBadMove: - if_target_is_ally AI_Ret -@ Check powder moves - if_move_flag FLAG_POWDER, AI_CBM_PowderMoves - goto AI_CBM_CheckIfNegatesType -AI_CBM_PowderMoves: - if_type AI_TARGET, TYPE_GRASS, Score_Minus10 - if_ability AI_TARGET, ABILITY_OVERCOAT, Score_Minus10 - get_hold_effect AI_TARGET - if_equal HOLD_EFFECT_SAFETY_GOOGLES Score_Minus10 - -AI_CBM_CheckIfNegatesType: - if_type_effectiveness AI_EFFECTIVENESS_x0, Score_Minus10 - get_ability AI_USER - if_equal ABILITY_MOLD_BREAKER, AI_CheckBadMove_CheckEffect - if_equal ABILITY_TERAVOLT, AI_CheckBadMove_CheckEffect - if_equal ABILITY_TURBOBLAZE, AI_CheckBadMove_CheckEffect - get_ability AI_TARGET - if_equal ABILITY_VOLT_ABSORB, CheckIfVoltAbsorbCancelsElectric - if_equal ABILITY_LIGHTNING_ROD, CheckIfVoltAbsorbCancelsElectric - if_equal ABILITY_MOTOR_DRIVE, CheckIfVoltAbsorbCancelsElectric - if_equal ABILITY_WATER_ABSORB, CheckIfWaterAbsorbCancelsWater - if_equal ABILITY_STORM_DRAIN, CheckIfWaterAbsorbCancelsWater - if_equal ABILITY_DRY_SKIN, CheckIfWaterAbsorbCancelsWater - if_equal ABILITY_FLASH_FIRE, CheckIfFlashFireCancelsFire - if_equal ABILITY_WONDER_GUARD, CheckIfWonderGuardCancelsMove - if_equal ABILITY_LEVITATE, CheckIfLevitateCancelsGroundMove - if_equal ABILITY_SOUNDPROOF, CheckIfSoundproofCancelsMove - goto AI_CheckBadMove_CheckEffect - -CheckIfSoundproofCancelsMove: - if_move_flag FLAG_SOUND, Score_Minus10 - goto AI_CheckBadMove_CheckEffect - -CheckIfVoltAbsorbCancelsElectric: @ 82DBFBD - get_curr_move_type - if_equal TYPE_ELECTRIC, Score_Minus12 - goto AI_CheckBadMove_CheckEffect - -CheckIfWaterAbsorbCancelsWater: @ 82DBFCA - get_curr_move_type - if_equal TYPE_WATER, Score_Minus12 - goto AI_CheckBadMove_CheckEffect - -CheckIfFlashFireCancelsFire: @ 82DBFD7 - get_curr_move_type - if_equal TYPE_FIRE, Score_Minus12 - goto AI_CheckBadMove_CheckEffect - -CheckIfWonderGuardCancelsMove: @ 82DBFE4 - if_type_effectiveness AI_EFFECTIVENESS_x2, AI_CheckBadMove_CheckEffect - if_type_effectiveness AI_EFFECTIVENESS_x4, AI_CheckBadMove_CheckEffect - goto Score_Minus10 - -CheckIfLevitateCancelsGroundMove: @ 82DBFEF - get_curr_move_type - if_equal TYPE_GROUND, Score_Minus10 - -AI_CheckBadMove_CheckEffect: @ 82DC045 - if_effect EFFECT_SLEEP, AI_CBM_Sleep - if_effect EFFECT_EXPLOSION, AI_CBM_Explosion - if_effect EFFECT_DREAM_EATER, AI_CBM_DreamEater - if_effect EFFECT_ATTACK_UP, AI_CBM_AttackUp - if_effect EFFECT_DEFENSE_UP, AI_CBM_DefenseUp - if_effect EFFECT_SPEED_UP, AI_CBM_SpeedUp - if_effect EFFECT_SPECIAL_ATTACK_UP, AI_CBM_SpAtkUp - if_effect EFFECT_SPECIAL_DEFENSE_UP, AI_CBM_SpDefUp - if_effect EFFECT_ACCURACY_UP, AI_CBM_AccUp - if_effect EFFECT_EVASION_UP, AI_CBM_EvasionUp - if_effect EFFECT_ATTACK_DOWN, AI_CBM_AttackDown - if_effect EFFECT_DEFENSE_DOWN, AI_CBM_DefenseDown - if_effect EFFECT_SPEED_DOWN, AI_CBM_SpeedDown - if_effect EFFECT_SPECIAL_ATTACK_DOWN, AI_CBM_SpAtkDown - if_effect EFFECT_SPECIAL_DEFENSE_DOWN, AI_CBM_SpDefDown - if_effect EFFECT_ACCURACY_DOWN, AI_CBM_AccDown - if_effect EFFECT_EVASION_DOWN, AI_CBM_EvasionDown - if_effect EFFECT_HAZE, AI_CBM_Haze - if_effect EFFECT_BIDE, AI_CBM_HighRiskForDamage - if_effect EFFECT_ROAR, AI_CBM_Roar - if_effect EFFECT_TOXIC, AI_CBM_Toxic - if_effect EFFECT_LIGHT_SCREEN, AI_CBM_LightScreen - if_effect EFFECT_OHKO, AI_CBM_OneHitKO - if_effect EFFECT_SUPER_FANG, AI_CBM_HighRiskForDamage - if_effect EFFECT_MIST, AI_CBM_Mist - if_effect EFFECT_FOCUS_ENERGY, AI_CBM_FocusEnergy - if_effect EFFECT_CONFUSE, AI_CBM_Confuse - if_effect EFFECT_ATTACK_UP_2, AI_CBM_AttackUp - if_effect EFFECT_DEFENSE_UP_2, AI_CBM_DefenseUp - if_effect EFFECT_SPEED_UP_2, AI_CBM_SpeedUp - if_effect EFFECT_SPECIAL_ATTACK_UP_2, AI_CBM_SpAtkUp - if_effect EFFECT_SPECIAL_DEFENSE_UP_2, AI_CBM_SpDefUp - if_effect EFFECT_ACCURACY_UP_2, AI_CBM_AccUp - if_effect EFFECT_EVASION_UP_2, AI_CBM_EvasionUp - if_effect EFFECT_ATTACK_DOWN_2, AI_CBM_AttackDown - if_effect EFFECT_DEFENSE_DOWN_2, AI_CBM_DefenseDown - if_effect EFFECT_SPEED_DOWN_2, AI_CBM_SpeedDown - if_effect EFFECT_SPECIAL_ATTACK_DOWN_2, AI_CBM_SpAtkDown - if_effect EFFECT_SPECIAL_DEFENSE_DOWN_2, AI_CBM_SpDefDown - if_effect EFFECT_ACCURACY_DOWN_2, AI_CBM_AccDown - if_effect EFFECT_EVASION_DOWN_2, AI_CBM_EvasionDown - if_effect EFFECT_REFLECT, AI_CBM_Reflect - if_effect EFFECT_POISON, AI_CBM_Toxic - if_effect EFFECT_PARALYZE, AI_CBM_Paralyze - if_effect EFFECT_SUBSTITUTE, AI_CBM_Substitute - if_effect EFFECT_RECHARGE, AI_CBM_HighRiskForDamage - if_effect EFFECT_LEECH_SEED, AI_CBM_LeechSeed - if_effect EFFECT_DISABLE, AI_CBM_Disable - if_effect EFFECT_LEVEL_DAMAGE, AI_CBM_HighRiskForDamage - if_effect EFFECT_PSYWAVE, AI_CBM_HighRiskForDamage - if_effect EFFECT_COUNTER, AI_CBM_HighRiskForDamage - if_effect EFFECT_ENCORE, AI_CBM_Encore - if_effect EFFECT_SNORE, AI_CBM_DamageDuringSleep - if_effect EFFECT_SLEEP_TALK, AI_CBM_DamageDuringSleep - if_effect EFFECT_FLAIL, AI_CBM_HighRiskForDamage - if_effect EFFECT_MEAN_LOOK, AI_CBM_CantEscape - if_effect EFFECT_NIGHTMARE, AI_CBM_Nightmare - if_effect EFFECT_MINIMIZE, AI_CBM_EvasionUp - if_effect EFFECT_CURSE, AI_CBM_Curse - if_effect EFFECT_SPIKES, AI_CBM_Spikes - if_effect EFFECT_FORESIGHT, AI_CBM_Foresight - if_effect EFFECT_PERISH_SONG, AI_CBM_PerishSong - if_effect EFFECT_SANDSTORM, AI_CBM_Sandstorm - if_effect EFFECT_SWAGGER, AI_CBM_Confuse - if_effect EFFECT_ATTRACT, AI_CBM_Attract - if_effect EFFECT_CAPTIVATE, AI_CBM_Captivate - if_effect EFFECT_RETURN, AI_CBM_HighRiskForDamage - if_effect EFFECT_PRESENT, AI_CBM_HighRiskForDamage - if_effect EFFECT_FRUSTRATION, AI_CBM_HighRiskForDamage - if_effect EFFECT_SAFEGUARD, AI_CBM_Safeguard - if_effect EFFECT_MAGNITUDE, AI_CBM_Magnitude - if_effect EFFECT_BATON_PASS, AI_CBM_BatonPass - if_effect EFFECT_SONICBOOM, AI_CBM_HighRiskForDamage - if_effect EFFECT_RAIN_DANCE, AI_CBM_RainDance - if_effect EFFECT_SUNNY_DAY, AI_CBM_SunnyDay - if_effect EFFECT_BELLY_DRUM, AI_CBM_BellyDrum - if_effect EFFECT_PSYCH_UP, AI_CBM_Haze - if_effect EFFECT_MIRROR_COAT, AI_CBM_HighRiskForDamage - if_effect EFFECT_SKULL_BASH, AI_CBM_HighRiskForDamage - if_effect EFFECT_FUTURE_SIGHT, AI_CBM_FutureSight - if_effect EFFECT_TELEPORT, Score_Minus10 - if_effect EFFECT_DEFENSE_CURL, AI_CBM_DefenseUp - if_effect EFFECT_FAKE_OUT, AI_CBM_FakeOut - if_effect EFFECT_STOCKPILE, AI_CBM_Stockpile - if_effect EFFECT_SPIT_UP, AI_CBM_SpitUpAndSwallow - if_effect EFFECT_SWALLOW, AI_CBM_SpitUpAndSwallow - if_effect EFFECT_HAIL, AI_CBM_Hail - if_effect EFFECT_TORMENT, AI_CBM_Torment - if_effect EFFECT_FLATTER, AI_CBM_Confuse - if_effect EFFECT_WILL_O_WISP, AI_CBM_WillOWisp - if_effect EFFECT_MEMENTO, AI_CBM_Memento - if_effect EFFECT_FOCUS_PUNCH, AI_CBM_HighRiskForDamage - if_effect EFFECT_HELPING_HAND, AI_CBM_HelpingHand - if_effect EFFECT_TRICK, AI_CBM_TrickAndKnockOff - if_effect EFFECT_INGRAIN, AI_CBM_Ingrain - if_effect EFFECT_SUPERPOWER, AI_CBM_HighRiskForDamage - if_effect EFFECT_RECYCLE, AI_CBM_Recycle - if_effect EFFECT_KNOCK_OFF, AI_CBM_TrickAndKnockOff - if_effect EFFECT_ENDEAVOR, AI_CBM_HighRiskForDamage - if_effect EFFECT_IMPRISON, AI_CBM_Imprison - if_effect EFFECT_REFRESH, AI_CBM_Refresh - if_effect EFFECT_LOW_KICK, AI_CBM_HighRiskForDamage - if_effect EFFECT_MUD_SPORT, AI_CBM_MudSport - if_effect EFFECT_TICKLE, AI_CBM_Tickle - if_effect EFFECT_COSMIC_POWER, AI_CBM_CosmicPower - if_effect EFFECT_BULK_UP, AI_CBM_BulkUp - if_effect EFFECT_WATER_SPORT, AI_CBM_WaterSport - if_effect EFFECT_CALM_MIND, AI_CBM_CalmMind - if_effect EFFECT_DRAGON_DANCE, AI_CBM_DragonDance - if_effect EFFECT_STICKY_WEB, AI_CBM_StickyWeb - if_effect EFFECT_STEALTH_ROCK, AI_CBM_StealthRock - if_effect EFFECT_TOXIC_SPIKES, AI_CBM_ToxicSpikes - if_effect EFFECT_AQUA_RING, AI_CBM_AquaRing - if_effect EFFECT_GRAVITY, AI_CBM_Gravity - if_effect EFFECT_EMBARGO, AI_CBM_Embargo - if_effect EFFECT_LUCKY_CHANT, AI_CBM_LuckyChant - if_effect EFFECT_HEAL_PULSE, Score_Minus5 - if_effect EFFECT_QUASH, AI_CBM_Quash - if_effect EFFECT_GASTRO_ACID, AI_CBM_GastroAcid - if_effect EFFECT_HEAL_BLOCK, AI_CBM_HealBlock - if_effect EFFECT_WORRY_SEED, AI_CBM_WorrySeed - if_effect EFFECT_MIRACLE_EYE, AI_CBM_MiracleEye - if_effect EFFECT_MAGNET_RISE, AI_CBM_MagnetRise - if_effect EFFECT_TELEKINESIS, AI_CBM_Telekinesis - if_effect EFFECT_MISTY_TERRAIN, AI_CBM_MistyTerrain - if_effect EFFECT_GRASSY_TERRAIN, AI_CBM_GrassyTerrain - if_effect EFFECT_ELECTRIC_TERRAIN, AI_CBM_ElectricTerrain - if_effect EFFECT_PSYCHIC_TERRAIN, AI_CBM_PsychicTerrain - if_effect EFFECT_QUIVER_DANCE, AI_CBM_QuiverDance - if_effect EFFECT_COIL, AI_CBM_Coil - if_effect EFFECT_TAILWIND, AI_CBM_Tailwind - if_effect EFFECT_SIMPLE_BEAM, AI_CBM_SimpleBeam - if_effect EFFECT_NATURAL_GIFT, AI_CBM_NaturalGift - if_effect EFFECT_FLING, AI_CBM_Fling - if_effect EFFECT_ATTACK_ACCURACY_UP, AI_CBM_AtkAccUp - if_effect EFFECT_ATTACK_SPATK_UP, AI_CBM_AtkSpAtkUp - if_effect EFFECT_GROWTH, AI_CBM_AtkSpAtkUp - if_effect EFFECT_AROMATIC_MIST, AI_CBM_AromaticMist - if_effect EFFECT_ACUPRESSURE, AI_CBM_Acupressure - if_effect EFFECT_BESTOW, AI_CBM_Bestow - if_effect EFFECT_PSYCHO_SHIFT, AI_CBM_PsychicShift - if_effect EFFECT_DEFOG, AI_CBM_Defog - if_effect EFFECT_SYNCHRONOISE, AI_CBM_Synchronoise - if_effect EFFECT_AUTOTOMIZE, AI_CBM_SpeedUp - if_effect EFFECT_TOXIC_THREAD, AI_CBM_ToxicThread - if_effect EFFECT_VENOM_DRENCH, AI_CBM_VenomDrench - if_effect EFFECT_DEFENSE_UP_3, AI_CBM_DefenseUp - if_effect EFFECT_SHIFT_GEAR, AI_CBM_DragonDance - if_effect EFFECT_NOBLE_ROAR, AI_CBM_NobleRoar - if_effect EFFECT_SHELL_SMASH, AI_CBM_ShellSmash - if_effect EFFECT_LAST_RESORT, AI_CBM_LastResort - if_effect EFFECT_BELCH, AI_CBM_Belch - if_effect EFFECT_DO_NOTHING, Score_Minus8 - if_effect EFFECT_POWDER, AI_CBM_Powder - if_effect EFFECT_PROTECT, AI_CBM_Protect - if_effect EFFECT_TAUNT, AI_CBM_Taunt - if_effect EFFECT_HEAL_BELL, AI_CBM_HealBell - if_effect EFFECT_FOLLOW_ME, AI_CBM_FollowMe - if_effect EFFECT_GEOMANCY, AI_CBM_QuiverDance - if_effect EFFECT_FAIRY_LOCK, AI_CBM_FairyLock - if_effect EFFECT_ALLY_SWITCH, AI_CBM_HelpingHand - if_effect EFFECT_TRICK_ROOM, AI_CBM_TrickRoom - if_effect EFFECT_WONDER_ROOM, AI_CBM_WonderRoom - if_effect EFFECT_MAGIC_ROOM, AI_CBM_MagicRoom - if_effect EFFECT_SOAK, AI_CBM_Soak - if_effect EFFECT_LOCK_ON, AI_CBM_LockOn - end - -AI_CBM_LockOn: - if_status3 AI_TARGET, STATUS3_ALWAYS_HITS, Score_Minus10 - if_ability AI_TARGET, ABILITY_NO_GUARD, Score_Minus10 - if_ability AI_USER, ABILITY_NO_GUARD, Score_Minus10 - end - -AI_CBM_Soak: - if_type AI_TARGET, TYPE_WATER, Score_Minus10 - end - -AI_CBM_TrickRoom: - if_field_status STATUS_FIELD_TRICK_ROOM, Score_Minus10 - end - -AI_CBM_WonderRoom: - if_field_status STATUS_FIELD_WONDER_ROOM, Score_Minus10 - end - -AI_CBM_MagicRoom: - if_field_status STATUS_FIELD_MAGIC_ROOM, Score_Minus10 - end - -AI_CBM_FairyLock: - if_field_status STATUS_FIELD_FAIRY_LOCK, Score_Minus10 - if_status2 AI_TARGET, STATUS2_ESCAPE_PREVENTION | STATUS2_WRAPPED, Score_Minus10 - end - -AI_CBM_Geomancy: - call AI_CBM_QuiverDance - end - -AI_CBM_FollowMe: - if_not_double_battle Score_Minus10 - if_battler_absent AI_USER_PARTNER, Score_Minus10 - end - -AI_CBM_HealBell: - if_status AI_TARGET, STATUS1_ANY, AI_CBM_HealBell_End - if_status_in_party AI_TARGET, STATUS1_ANY, AI_CBM_HealBell_End - score -5 -AI_CBM_HealBell_End: - end - -AI_CBM_Taunt: - if_target_taunted Score_Minus10 - end - -AI_CBM_Protect: - get_protect_count AI_USER - if_more_than 2, Score_Minus10 - if_status AI_TARGET, STATUS1_SLEEP | STATUS1_FREEZE, Score_Minus8 - end - -AI_CBM_Powder: - if_type AI_TARGET, TYPE_FIRE, AI_Ret - if_has_move_with_type AI_TARGET, TYPE_FIRE, AI_Ret - score -5 - end - -AI_CBM_Belch: - if_cant_use_belch AI_USER, Score_Minus10 - end - -AI_CBM_LastResort: - if_cant_use_last_resort AI_USER, Score_Minus10 - end - -AI_CBM_ShellSmash: - if_ability AI_USER, ABILITY_CONTRARY, AI_CBM_ShellSmashContrary - if_stat_level_not_equal AI_USER, STAT_SPATK, 12, AI_Ret - if_stat_level_not_equal AI_USER, STAT_SPEED, 12, AI_Ret - if_stat_level_equal AI_USER, STAT_ATK, 12, Score_Minus10 - end -AI_CBM_ShellSmashContrary: - if_stat_level_not_equal AI_USER, STAT_DEF, 12, AI_Ret - if_stat_level_equal AI_USER, STAT_SPDEF, 12, Score_Minus10 - end - -AI_CBM_NobleRoar: - if_stat_level_not_equal AI_TARGET, STAT_SPATK, 12, AI_Ret - if_stat_level_equal AI_TARGET, STAT_ATK, 12, Score_Minus10 - end - -AI_CBM_VenomDrench: - if_not_status AI_TARGET, STATUS1_PSN_ANY, Score_Minus10 - if_stat_level_not_equal AI_TARGET, STAT_SPEED, 12, AI_Ret - if_stat_level_not_equal AI_TARGET, STAT_SPATK, 12, AI_Ret - if_stat_level_equal AI_TARGET, STAT_ATK, 12, Score_Minus10 - end - -AI_CBM_ToxicThread: - if_stat_level_not_equal AI_TARGET, STAT_SPEED, 12, AI_Ret - goto AI_CBM_Toxic - -AI_CBM_Synchronoise: - if_share_type AI_USER, AI_TARGET AI_Ret - goto Score_Minus10 - -AI_CBM_Defog: - if_side_affecting AI_USER, SIDE_STATUS_SPIKES | SIDE_STATUS_STEALTH_ROCK | SIDE_STATUS_TOXIC_SPIKES | SIDE_STATUS_STICKY_WEB, AI_Ret - goto AI_CBM_EvasionDown - -AI_CBM_PsychicShift: - if_not_status AI_USER, STATUS1_ANY, Score_Minus10 - if_status AI_TARGET, STATUS1_ANY, Score_Minus10 - if_status AI_USER, STATUS1_PARALYSIS, AI_CBM_Paralyze - if_status AI_USER, STATUS1_PSN_ANY, AI_CBM_Toxic - if_status AI_USER, STATUS1_BURN, AI_CBM_WillOWisp - if_status AI_USER, STATUS1_SLEEP, AI_CBM_Sleep - end - -AI_CBM_Bestow: - if_holds_no_item AI_USER, Score_Minus10 - end - -AI_CBM_Acupressure: - if_double_battle AI_Ret - if_stat_level_not_equal AI_USER, STAT_ATK, 12, AI_Ret - if_stat_level_not_equal AI_USER, STAT_DEF, 12, AI_Ret - if_stat_level_not_equal AI_USER, STAT_SPATK, 12, AI_Ret - if_stat_level_not_equal AI_USER, STAT_SPDEF, 12, AI_Ret - if_stat_level_not_equal AI_USER, STAT_SPEED, 12, AI_Ret - if_stat_level_not_equal AI_USER, STAT_ACC, 12, AI_Ret - if_stat_level_equal AI_USER, STAT_EVASION, 12, Score_Minus10 - end - -AI_CBM_AromaticMist: - if_target_is_ally AI_Ret - goto Score_Minus10 - -AI_CBM_AtkAccUp: - if_stat_level_not_equal AI_USER, STAT_ATK, 12, AI_Ret - if_stat_level_equal AI_USER, STAT_ACC, 12, Score_Minus10 - end - -AI_CBM_AtkSpAtkUp: - if_stat_level_not_equal AI_USER, STAT_ATK, 12, AI_Ret - if_stat_level_equal AI_USER, STAT_SPATK, 12, Score_Minus10 - end - -AI_CBM_Fling: - if_holds_no_item AI_USER, Score_Minus10 - if_ability AI_USER, ABILITY_KLUTZ, Score_Minus10 - if_status3 AI_USER, STATUS3_EMBARGO, Score_Minus10 - if_field_status STATUS_FIELD_MAGIC_ROOM, Score_Minus10 - end - -AI_CBM_NaturalGift: - if_doesnt_hold_berry AI_USER, Score_Minus10 - if_ability AI_USER, ABILITY_KLUTZ, Score_Minus10 - if_status3 AI_USER, STATUS3_EMBARGO, Score_Minus10 - if_field_status STATUS_FIELD_MAGIC_ROOM, Score_Minus10 - end - -AI_CBM_SimpleBeam: - if_ability AI_TARGET, ABILITY_SIMPLE, Score_Minus10 - end - -AI_CBM_Tailwind: - if_side_affecting AI_USER, SIDE_STATUS_TAILWIND, Score_Minus10 - end - -AI_CBM_QuiverDance: - if_stat_level_not_equal AI_USER, STAT_SPATK, 12, AI_Ret - if_stat_level_not_equal AI_USER, STAT_SPDEF, 12, AI_Ret - if_stat_level_equal AI_USER, STAT_SPEED, 12, Score_Minus10 - end - -AI_CBM_Coil: - if_stat_level_not_equal AI_USER, STAT_ATK, 12, AI_Ret - if_stat_level_not_equal AI_USER, STAT_DEF, 12, AI_Ret - if_stat_level_equal AI_USER, STAT_ACC, 12, Score_Minus10 - end - -AI_CBM_MistyTerrain: - if_field_status STATUS_FIELD_MISTY_TERRAIN, Score_Minus10 - end - -AI_CBM_GrassyTerrain: - if_field_status STATUS_FIELD_GRASSY_TERRAIN, Score_Minus10 - end - -AI_CBM_ElectricTerrain: - if_field_status STATUS_FIELD_ELECTRIC_TERRAIN, Score_Minus10 - end - -AI_CBM_PsychicTerrain: - if_field_status STATUS_FIELD_PSYCHIC_TERRAIN, Score_Minus10 - end - -AI_CBM_Quash: - if_not_double_battle Score_Minus10 - end - -AI_CBM_Telekinesis: - if_status3 AI_TARGET, STATUS3_TELEKINESIS, Score_Minus10 - end - -AI_CBM_MagnetRise: - if_status3 AI_USER, STATUS3_MAGNET_RISE, Score_Minus10 - end - -AI_CBM_MiracleEye: - if_status3 AI_TARGET, STATUS3_MIRACLE_EYED, Score_Minus10 - if_status2 AI_TARGET, STATUS2_FORESIGHT, Score_Minus10 - end - -AI_CBM_WorrySeed: - get_ability AI_TARGET - if_equal ABILITY_INSOMNIA, Score_Minus10 - if_equal ABILITY_VITAL_SPIRIT, Score_Minus10 - end - -AI_CBM_HealBlock: - if_status3 AI_TARGET, STATUS3_HEAL_BLOCK, Score_Minus10 - end - -AI_CBM_GastroAcid: - if_status3 AI_TARGET, STATUS3_GASTRO_ACID, Score_Minus10 - end - -AI_CBM_AquaRing: - if_status3 AI_USER, STATUS3_AQUA_RING, Score_Minus10 - end - -AI_CBM_LuckyChant: - if_side_affecting AI_USER, SIDE_STATUS_LUCKY_CHANT, Score_Minus10 - end - -AI_CBM_Embargo: - if_status3 AI_TARGET, STATUS3_EMBARGO, Score_Minus10 - end - -AI_CBM_Gravity: - if_field_status STATUS_FIELD_GRAVITY, Score_Minus10 - end - -@ Don't use hazards if target side has no mons to switch -AI_CBM_Hazards: - count_usable_party_mons AI_TARGET - if_equal 0, Score_Minus10 - end - -AI_CBM_ToxicSpikes: - if_not_side_affecting AI_TARGET, SIDE_STATUS_TOXIC_SPIKES, AI_Ret - get_hazards_count AI_TARGET, EFFECT_TOXIC_SPIKES - if_equal 2, Score_Minus10 - goto AI_CBM_Hazards - -AI_CBM_StealthRock: - if_side_affecting AI_TARGET, SIDE_STATUS_STEALTH_ROCK, Score_Minus10 - goto AI_CBM_Hazards - -AI_CBM_StickyWeb: - if_side_affecting AI_TARGET, SIDE_STATUS_STICKY_WEB, Score_Minus10 - goto AI_CBM_Hazards - -AI_CBM_Sleep: @ 82DC2D4 - get_ability AI_TARGET - if_equal ABILITY_INSOMNIA, Score_Minus10 - if_equal ABILITY_VITAL_SPIRIT, Score_Minus10 - if_status AI_TARGET, STATUS1_ANY, Score_Minus10 - if_side_affecting AI_TARGET, SIDE_STATUS_SAFEGUARD, Score_Minus10 - end - -AI_CBM_Explosion: @ 82DC2F7 - if_type_effectiveness AI_EFFECTIVENESS_x0, Score_Minus10 - get_ability AI_TARGET - if_equal ABILITY_DAMP, Score_Minus10 - count_usable_party_mons AI_USER - if_not_equal 0, AI_CBM_Explosion_End - count_usable_party_mons AI_TARGET - if_not_equal 0, Score_Minus10 - goto Score_Minus1 - -AI_CBM_Explosion_End: @ 82DC31A - end - -AI_CBM_Nightmare: @ 82DC31B - if_status2 AI_TARGET, STATUS2_NIGHTMARE, Score_Minus10 - if_not_status AI_TARGET, STATUS1_SLEEP, Score_Minus8 - end - -AI_CBM_DreamEater: @ 82DC330 - if_not_status AI_TARGET, STATUS1_SLEEP, Score_Minus8 - if_type_effectiveness AI_EFFECTIVENESS_x0, Score_Minus10 - end - -AI_CBM_BellyDrum: @ 82DC341 - if_hp_less_than AI_USER, 51, Score_Minus10 - -AI_CBM_AttackUp: @ 82DC348 - if_stat_level_equal AI_USER, STAT_ATK, 12, Score_Minus10 - @ Do not raise attack if has no physical moves - if_has_move_with_effect AI_USER, EFFECT_BATON_PASS, AI_Ret - if_has_no_physical_move AI_USER, Score_Minus10 - end - -AI_CBM_DefenseUp: @ 82DC351 - if_stat_level_equal AI_USER, STAT_DEF, MAX_STAT_STAGE, Score_Minus10 - end - -AI_CBM_SpeedUp: @ 82DC35A - if_stat_level_equal AI_USER, STAT_SPEED, MAX_STAT_STAGE, Score_Minus10 - end - -AI_CBM_SpAtkUp: @ 82DC363 - if_stat_level_equal AI_USER, STAT_SPATK, 12, Score_Minus10 - @ Do not raise sp. attack if has no special moves - if_has_move_with_effect AI_USER, EFFECT_BATON_PASS, AI_Ret - if_has_no_special_move AI_USER, Score_Minus10 - end - -AI_CBM_SpDefUp: @ 82DC36C - if_stat_level_equal AI_USER, STAT_SPDEF, MAX_STAT_STAGE, Score_Minus10 - end - -AI_CBM_AccUp: @ 82DC375 - if_stat_level_equal AI_USER, STAT_ACC, MAX_STAT_STAGE, Score_Minus10 - end - -AI_CBM_EvasionUp: @ 82DC37E - if_stat_level_equal AI_USER, STAT_EVASION, MAX_STAT_STAGE, Score_Minus10 - end - -AI_CBM_AttackDown: @ 82DC387 - if_stat_level_equal AI_TARGET, STAT_ATK, MIN_STAT_STAGE, Score_Minus10 - get_ability AI_TARGET - if_equal ABILITY_HYPER_CUTTER, Score_Minus10 - goto CheckIfAbilityBlocksStatChange - -AI_CBM_DefenseDown: @ 82DC39C - if_stat_level_equal AI_TARGET, STAT_DEF, 0, Score_Minus10 - get_ability AI_TARGET - if_equal ABILITY_BIG_PECKS, Score_Minus10 - goto CheckIfAbilityBlocksStatChange - -AI_CBM_SpeedDown: @ 82DC3A9 - if_stat_level_equal AI_TARGET, STAT_SPEED, MIN_STAT_STAGE, Score_Minus10 - if_ability AI_TARGET, ABILITY_SPEED_BOOST, Score_Minus10 - goto CheckIfAbilityBlocksStatChange - -AI_CBM_SpAtkDown: @ 82DC3BF - if_stat_level_equal AI_TARGET, STAT_SPATK, MIN_STAT_STAGE, Score_Minus10 - goto CheckIfAbilityBlocksStatChange - -AI_CBM_SpDefDown: @ 82DC3CC - if_stat_level_equal AI_TARGET, STAT_SPDEF, MIN_STAT_STAGE, Score_Minus10 - goto CheckIfAbilityBlocksStatChange - -AI_CBM_AccDown: @ 82DC3D9 - if_stat_level_equal AI_TARGET, STAT_ACC, MIN_STAT_STAGE, Score_Minus10 - get_ability AI_TARGET - if_equal ABILITY_KEEN_EYE, Score_Minus10 - goto CheckIfAbilityBlocksStatChange - -AI_CBM_EvasionDown: @ 82DC3EE - if_stat_level_equal AI_TARGET, STAT_EVASION, MIN_STAT_STAGE, Score_Minus10 - -CheckIfAbilityBlocksStatChange: @ 82DC3F6 - get_ability AI_TARGET - if_equal ABILITY_CLEAR_BODY, Score_Minus10 - if_equal ABILITY_WHITE_SMOKE, Score_Minus10 - end - -AI_CBM_Haze: @ 82DC405 - if_stat_level_less_than AI_USER, STAT_ATK, DEFAULT_STAT_STAGE, AI_CBM_Haze_End - if_stat_level_less_than AI_USER, STAT_DEF, DEFAULT_STAT_STAGE, AI_CBM_Haze_End - if_stat_level_less_than AI_USER, STAT_SPEED, DEFAULT_STAT_STAGE, AI_CBM_Haze_End - if_stat_level_less_than AI_USER, STAT_SPATK, DEFAULT_STAT_STAGE, AI_CBM_Haze_End - if_stat_level_less_than AI_USER, STAT_SPDEF, DEFAULT_STAT_STAGE, AI_CBM_Haze_End - if_stat_level_less_than AI_USER, STAT_ACC, DEFAULT_STAT_STAGE, AI_CBM_Haze_End - if_stat_level_less_than AI_USER, STAT_EVASION, DEFAULT_STAT_STAGE, AI_CBM_Haze_End - if_stat_level_more_than AI_TARGET, STAT_ATK, DEFAULT_STAT_STAGE, AI_CBM_Haze_End - if_stat_level_more_than AI_TARGET, STAT_DEF, DEFAULT_STAT_STAGE, AI_CBM_Haze_End - if_stat_level_more_than AI_TARGET, STAT_SPEED, DEFAULT_STAT_STAGE, AI_CBM_Haze_End - if_stat_level_more_than AI_TARGET, STAT_SPATK, DEFAULT_STAT_STAGE, AI_CBM_Haze_End - if_stat_level_more_than AI_TARGET, STAT_SPDEF, DEFAULT_STAT_STAGE, AI_CBM_Haze_End - if_stat_level_more_than AI_TARGET, STAT_ACC, DEFAULT_STAT_STAGE, AI_CBM_Haze_End - if_stat_level_more_than AI_TARGET, STAT_EVASION, DEFAULT_STAT_STAGE, AI_CBM_Haze_End - goto Score_Minus10 - -AI_CBM_Haze_End: @ 82DC47A - end - -AI_CBM_Roar: @ 82DC47B - count_usable_party_mons AI_TARGET - if_equal 0, Score_Minus10 - get_ability AI_TARGET - if_equal ABILITY_SUCTION_CUPS, Score_Minus10 - end - -AI_CBM_Toxic: @ 82DC48C - get_target_type1 - if_equal TYPE_STEEL, Score_Minus10 - if_equal TYPE_POISON, Score_Minus10 - get_target_type2 - if_equal TYPE_STEEL, Score_Minus10 - if_equal TYPE_POISON, Score_Minus10 - get_ability AI_TARGET - if_equal ABILITY_IMMUNITY, Score_Minus10 - if_equal ABILITY_TOXIC_BOOST, Score_Minus10 - if_status AI_TARGET, STATUS1_ANY, Score_Minus10 - if_side_affecting AI_TARGET, SIDE_STATUS_SAFEGUARD, Score_Minus10 - end - -AI_CBM_LightScreen: @ 82DC4C5 - if_side_affecting AI_USER, SIDE_STATUS_LIGHTSCREEN, Score_Minus8 - end - -AI_CBM_OneHitKO: @ 82DC4D0 - if_type_effectiveness AI_EFFECTIVENESS_x0, Score_Minus10 - get_ability AI_TARGET - if_equal ABILITY_STURDY, Score_Minus10 - if_level_cond 1, Score_Minus10 - end - -AI_CBM_Magnitude: @ 82DC4E5 - get_ability AI_TARGET - if_equal ABILITY_LEVITATE, Score_Minus10 - -AI_CBM_HighRiskForDamage: @ 82DC4ED - if_type_effectiveness AI_EFFECTIVENESS_x0, Score_Minus10 - get_ability AI_TARGET - if_not_equal ABILITY_WONDER_GUARD, AI_CBM_HighRiskForDamage_End - if_type_effectiveness AI_EFFECTIVENESS_x2, AI_CBM_HighRiskForDamage_End - goto Score_Minus10 - -AI_CBM_HighRiskForDamage_End: @ 82DC506 - end - -AI_CBM_Mist: @ 82DC507 - if_side_affecting AI_USER, SIDE_STATUS_MIST, Score_Minus8 - end - -AI_CBM_FocusEnergy: @ 82DC512 - if_status2 AI_USER, STATUS2_FOCUS_ENERGY, Score_Minus10 - end - -AI_CBM_Confuse: @ 82DC51D - if_status2 AI_TARGET, STATUS2_CONFUSION, Score_Minus5 - get_ability AI_TARGET - if_equal ABILITY_OWN_TEMPO, Score_Minus10 - if_side_affecting AI_TARGET, SIDE_STATUS_SAFEGUARD, Score_Minus10 - end - -AI_CBM_Reflect: @ 82DC53A - if_side_affecting AI_USER, SIDE_STATUS_REFLECT, Score_Minus8 - end - -AI_CBM_Paralyze: @ 82DC545 - if_type_effectiveness AI_EFFECTIVENESS_x0, Score_Minus10 - get_ability AI_TARGET - if_equal ABILITY_LIMBER, Score_Minus10 - if_status AI_TARGET, STATUS1_ANY, Score_Minus10 - if_side_affecting AI_TARGET, SIDE_STATUS_SAFEGUARD, Score_Minus10 - end - -AI_CBM_Substitute: @ 82DC568 - if_status2 AI_USER, STATUS2_SUBSTITUTE, Score_Minus8 - if_hp_less_than AI_USER, 26, Score_Minus10 - end - -AI_CBM_LeechSeed: @ 82DC57A - if_status3 AI_TARGET, STATUS3_LEECHSEED, Score_Minus10 - if_type AI_TARGET, TYPE_GRASS, Score_Minus10 - end - -AI_CBM_Disable: @ 82DC595 - if_any_move_disabled AI_TARGET, Score_Minus8 - if_no_move_used AI_TARGET, Score_Minus8 - end - -AI_CBM_Encore: @ 82DC59D - if_any_move_encored AI_TARGET, Score_Minus8 - if_no_move_used AI_TARGET, Score_Minus8 - end - -AI_CBM_DamageDuringSleep: @ 82DC5A5 - if_not_status AI_USER, STATUS1_SLEEP, Score_Minus8 - end - -AI_CBM_CantEscape: @ 82DC5B0 - if_status2 AI_TARGET, STATUS2_ESCAPE_PREVENTION, Score_Minus10 - end - -AI_CBM_Curse: @ 82DC5BB - if_stat_level_equal AI_USER, STAT_ATK, MAX_STAT_STAGE, Score_Minus10 - if_stat_level_equal AI_USER, STAT_DEF, MAX_STAT_STAGE, Score_Minus8 - end - -AI_CBM_Spikes: @ 82DC5CC - call AI_CBM_Hazards - if_not_side_affecting AI_TARGET, SIDE_STATUS_SPIKES, AI_Ret - get_hazards_count AI_TARGET, EFFECT_SPIKES - if_equal 3, Score_Minus10 - end - -AI_CBM_Foresight: @ 82DC5D7 - if_status2 AI_TARGET, STATUS2_FORESIGHT, Score_Minus10 - if_status3 AI_TARGET, STATUS3_MIRACLE_EYED, Score_Minus10 - end - -AI_CBM_PerishSong: @ 82DC5E2 - if_status3 AI_TARGET, STATUS3_PERISH_SONG, Score_Minus10 - end - -AI_CBM_Sandstorm: @ 82DC5ED - get_weather - if_equal AI_WEATHER_SANDSTORM, Score_Minus8 - end - -AI_IsOppositeGender: - get_ability AI_TARGET - if_equal ABILITY_OBLIVIOUS, Score_Minus10 - get_gender AI_USER - if_equal MON_MALE, AI_IsOppositeGenderFemale - if_equal MON_FEMALE, AI_IsOppositeGenderMale - goto Score_Minus10 -AI_IsOppositeGenderFemale: @ 82DC61A - get_gender AI_TARGET - if_equal MON_FEMALE, AI_CBM_Attract_End - goto Score_Minus10 -AI_IsOppositeGenderMale: @ 82DC627 - get_gender AI_TARGET - if_equal MON_MALE, AI_CBM_Attract_End - goto Score_Minus10 - end - -AI_CBM_Captivate: - call AI_IsOppositeGender - goto AI_CBM_SpAtkDown - -AI_CBM_Attract: @ 82DC5F5 - if_status2 AI_TARGET, STATUS2_INFATUATION, Score_Minus10 - call AI_IsOppositeGender - end - -AI_CBM_Attract_End: @ 82DC634 - end - -AI_CBM_Safeguard: @ 82DC635 - if_side_affecting AI_USER, SIDE_STATUS_SAFEGUARD, Score_Minus8 - end - -AI_CBM_Memento: @ 82DC640 - if_stat_level_equal AI_TARGET, STAT_ATK, MIN_STAT_STAGE, Score_Minus10 - if_stat_level_equal AI_TARGET, STAT_SPATK, MIN_STAT_STAGE, Score_Minus8 - -AI_CBM_BatonPass: @ 82DC650 - count_usable_party_mons AI_USER - if_equal 0, Score_Minus10 - end - -AI_CBM_RainDance: @ 82DC659 - get_weather - if_equal AI_WEATHER_RAIN, Score_Minus8 - end - -AI_CBM_SunnyDay: @ 82DC661 - get_weather - if_equal AI_WEATHER_SUN, Score_Minus8 - end - -AI_CBM_FutureSight: @ 82DC669 - if_side_affecting AI_TARGET, SIDE_STATUS_FUTUREATTACK, Score_Minus12 - if_side_affecting AI_USER, SIDE_STATUS_FUTUREATTACK, Score_Minus12 - score +5 - end - -AI_CBM_FakeOut: @ 82DC680 - is_first_turn_for AI_USER - if_equal 0, Score_Minus10 - end - -AI_CBM_Stockpile: @ 82DC689 - get_stockpile_count AI_USER - if_equal 3, Score_Minus10 - end - -AI_CBM_SpitUpAndSwallow: @ 82DC692 - if_type_effectiveness AI_EFFECTIVENESS_x0, Score_Minus10 - get_stockpile_count AI_USER - if_equal 0, Score_Minus10 - end - -AI_CBM_Hail: @ 82DC6A1 - get_weather - if_equal AI_WEATHER_HAIL, Score_Minus8 - end - -AI_CBM_Torment: @ 82DC6A9 - if_status2 AI_TARGET, STATUS2_TORMENT, Score_Minus10 - end - -AI_CBM_WillOWisp: @ 82DC6B4 - get_ability AI_TARGET - if_equal ABILITY_WATER_VEIL, Score_Minus10 - if_equal ABILITY_FLARE_BOOST, Score_Minus10 - if_equal ABILITY_FLASH_FIRE, Score_Minus10 - if_status AI_TARGET, STATUS1_ANY, Score_Minus10 - if_type AI_TARGET, TYPE_FIRE, Score_Minus10 - if_side_affecting AI_TARGET, SIDE_STATUS_SAFEGUARD, Score_Minus10 - end - -AI_CBM_HelpingHand: @ 82DC6E3 - if_not_double_battle Score_Minus10 - if_battler_absent AI_USER_PARTNER, Score_Minus10 - end - -AI_CBM_TrickAndKnockOff: @ 82DC6EB - get_ability AI_TARGET - if_equal ABILITY_STICKY_HOLD, Score_Minus10 - end - -AI_CBM_Ingrain: @ 82DC6F4 - if_status3 AI_USER, STATUS3_ROOTED, Score_Minus10 - end - -AI_CBM_Recycle: @ 82DC6FF - get_used_held_item AI_USER - if_equal 0, Score_Minus10 - end - -AI_CBM_Imprison: @ 82DC708 - if_status3 AI_USER, STATUS3_IMPRISONED_OTHERS, Score_Minus10 - end - -AI_CBM_Refresh: @ 82DC713 - if_not_status AI_USER, STATUS1_POISON | STATUS1_BURN | STATUS1_PARALYSIS | STATUS1_TOXIC_POISON, Score_Minus10 - end - -AI_CBM_MudSport: @ 82DC71E - if_field_status STATUS_FIELD_MUDSPORT, Score_Minus10 - end - -AI_CBM_Tickle: @ 82DC729 - if_stat_level_equal AI_TARGET, STAT_ATK, MIN_STAT_STAGE, Score_Minus10 - if_stat_level_equal AI_TARGET, STAT_DEF, MIN_STAT_STAGE, Score_Minus8 - end - -AI_CBM_CosmicPower: @ 82DC73A - if_stat_level_equal AI_USER, STAT_DEF, MAX_STAT_STAGE, Score_Minus10 - if_stat_level_equal AI_USER, STAT_SPDEF, MAX_STAT_STAGE, Score_Minus8 - end - -AI_CBM_BulkUp: @ 82DC74B - if_stat_level_equal AI_USER, STAT_ATK, MAX_STAT_STAGE, Score_Minus10 - if_stat_level_equal AI_USER, STAT_DEF, MAX_STAT_STAGE, Score_Minus8 - end - -AI_CBM_WaterSport: @ 82DC75C - if_field_status STATUS_FIELD_WATERSPORT, Score_Minus10 - end - -AI_CBM_CalmMind: @ 82DC767 - if_stat_level_equal AI_USER, STAT_SPATK, MAX_STAT_STAGE, Score_Minus10 - if_stat_level_equal AI_USER, STAT_SPDEF, MAX_STAT_STAGE, Score_Minus8 - end - -AI_CBM_DragonDance: @ 82DC778 - if_stat_level_equal AI_USER, STAT_ATK, MAX_STAT_STAGE, Score_Minus10 - if_stat_level_equal AI_USER, STAT_SPEED, MAX_STAT_STAGE, Score_Minus8 - end - -Score_Minus1: - score -1 - end - -Score_Minus2: - score -2 - end - -Score_Minus3: - score -3 - end - -Score_Minus5: - score -5 - end - -Score_Minus8: - score -8 - end - -Score_Minus10: - score -10 - end - -Score_Minus12: - score -12 - end - -Score_Minus30: - score -30 - end - -Score_Plus1: - score +1 - end - -Score_Plus2: - score +2 - end - -Score_Plus3: - score +3 - end - -Score_Plus5: - score +5 - end - -Score_Plus10: - score +10 - end - -@ omae wa mou shindeiru -@ Basically a scenario where the players mon is faster, able to hit and able to OHKO -@ In which, it would be best to use a priority move to deal any damage -AI_CheckIfAlreadyDead: - if_status2 AI_TARGET, STATUS2_RECHARGE | STATUS2_BIDE, AI_Ret - if_ai_can_go_down AI_CheckIfAlreadyDeadPriorities - end -AI_CheckIfAlreadyDeadPriorities: - if_target_faster Score_Minus1 - if_random_less_than 126, AI_Ret - score +1 - end - -@ The purpose is to use a move effect that hits the hardest or similar -AI_CV_DmgMove: - get_considered_move_power - if_equal 0, AI_Ret - get_how_powerful_move_is - if_equal MOVE_POWER_WEAK, Score_Minus1 - end - -@ If move deals shit damage, and there are other mons to switch in, use support moves instead -AI_WeakDmg: - get_considered_move_power - if_equal 0, AI_Ret - if_has_no_move_with_split AI_USER, SPLIT_STATUS, AI_Ret - get_curr_dmg_hp_percent - if_more_than 30, AI_Ret - if_more_than 20, Score_Minus1 - get_how_powerful_move_is - if_equal MOVE_POWER_BEST, Score_Minus2 - score -3 - end - -AI_DiscourageMagicGuard: - if_no_ability AI_TARGET, ABILITY_MAGIC_GUARD, AI_DiscourageMagicGuardEnd - if_effect EFFECT_POISON, Score_Minus5 - if_effect EFFECT_WILL_O_WISP, Score_Minus5 - if_effect EFFECT_TOXIC, Score_Minus5 - if_effect EFFECT_LEECH_SEED, Score_Minus5 - if_no_type AI_TARGET, TYPE_GHOST, AI_DiscourageMagicGuardEnd - if_effect EFFECT_CURSE, Score_Minus5 -AI_DiscourageMagicGuardEnd: - end - -AI_CheckViability: - if_target_is_ally AI_Ret - call_if_always_hit AI_CV_AlwaysHit - call_if_move_flag FLAG_HIGH_CRIT, AI_CV_HighCrit - call AI_CheckIfAlreadyDead - call AI_CV_DmgMove - call AI_WeakDmg - call AI_DiscourageMagicGuard - if_effect EFFECT_HIT, AI_CV_Hit - if_effect EFFECT_SLEEP, AI_CV_Sleep - if_effect EFFECT_ABSORB, AI_CV_Absorb - if_effect EFFECT_EXPLOSION, AI_CV_SelfKO - if_effect EFFECT_DREAM_EATER, AI_CV_DreamEater - if_effect EFFECT_MIRROR_MOVE, AI_CV_MirrorMove - if_effect EFFECT_ATTACK_UP, AI_CV_AttackUp - if_effect EFFECT_DEFENSE_UP, AI_CV_DefenseUp - if_effect EFFECT_SPEED_UP, AI_CV_SpeedUp - if_effect EFFECT_SPECIAL_ATTACK_UP, AI_CV_SpAtkUp - if_effect EFFECT_SPECIAL_DEFENSE_UP, AI_CV_SpDefUp - if_effect EFFECT_ACCURACY_UP, AI_CV_AccuracyUp - if_effect EFFECT_EVASION_UP, AI_CV_EvasionUp - if_effect EFFECT_ATTACK_DOWN, AI_CV_AttackDown - if_effect EFFECT_DEFENSE_DOWN, AI_CV_DefenseDown - if_effect EFFECT_SPEED_DOWN, AI_CV_SpeedDown - if_effect EFFECT_SPECIAL_ATTACK_DOWN, AI_CV_SpAtkDown - if_effect EFFECT_SPECIAL_DEFENSE_DOWN, AI_CV_SpDefDown - if_effect EFFECT_ACCURACY_DOWN, AI_CV_AccuracyDown - if_effect EFFECT_EVASION_DOWN, AI_CV_EvasionDown - if_effect EFFECT_HAZE, AI_CV_Haze - if_effect EFFECT_BIDE, AI_CV_Bide - if_effect EFFECT_ROAR, AI_CV_Roar - if_effect EFFECT_CONVERSION, AI_CV_Conversion - if_effect EFFECT_RESTORE_HP, AI_CV_Heal - if_effect EFFECT_SOFTBOILED, AI_CV_Heal - if_effect EFFECT_SWALLOW, AI_CV_Heal - if_effect EFFECT_ROOST, AI_CV_Heal - if_effect EFFECT_TOXIC, AI_CV_Toxic - if_effect EFFECT_LIGHT_SCREEN, AI_CV_LightScreen - if_effect EFFECT_REST, AI_CV_Rest - if_effect EFFECT_OHKO, AI_CV_OneHitKO - if_effect EFFECT_SUPER_FANG, AI_CV_SuperFang - if_effect EFFECT_TRAP, AI_CV_Trap - if_effect EFFECT_CONFUSE, AI_CV_Confuse - if_effect EFFECT_FOCUS_ENERGY, AI_CV_FocusEnergy - if_effect EFFECT_ATTACK_UP_2, AI_CV_AttackUp - if_effect EFFECT_DEFENSE_UP_2, AI_CV_DefenseUp - if_effect EFFECT_SPEED_UP_2, AI_CV_SpeedUp - if_effect EFFECT_SPECIAL_ATTACK_UP_2, AI_CV_SpAtkUp - if_effect EFFECT_SPECIAL_DEFENSE_UP_2, AI_CV_SpDefUp - if_effect EFFECT_ACCURACY_UP_2, AI_CV_AccuracyUp - if_effect EFFECT_EVASION_UP_2, AI_CV_EvasionUp - if_effect EFFECT_ATTACK_DOWN_2, AI_CV_AttackDown - if_effect EFFECT_DEFENSE_DOWN_2, AI_CV_DefenseDown - if_effect EFFECT_SPEED_DOWN_2, AI_CV_SpeedDown - if_effect EFFECT_SPECIAL_ATTACK_DOWN_2, AI_CV_SpAtkDown - if_effect EFFECT_SPECIAL_DEFENSE_DOWN_2, AI_CV_SpDefDown - if_effect EFFECT_ACCURACY_DOWN_2, AI_CV_AccuracyDown - if_effect EFFECT_EVASION_DOWN_2, AI_CV_EvasionDown - if_effect EFFECT_REFLECT, AI_CV_Reflect - if_effect EFFECT_AURORA_VEIL, AI_CV_AuroraVeil - if_effect EFFECT_POISON, AI_CV_Poison - if_effect EFFECT_TOXIC_THREAD, AI_CV_ToxicThread - if_effect EFFECT_PARALYZE, AI_CV_Paralyze - if_effect EFFECT_SWAGGER, AI_CV_Swagger - if_effect EFFECT_SPEED_DOWN_HIT, AI_CV_SpeedDownFromChance - if_effect EFFECT_TWO_TURNS_ATTACK, AI_CV_ChargeUpMove - if_effect EFFECT_VITAL_THROW, AI_CV_VitalThrow - if_effect EFFECT_SUBSTITUTE, AI_CV_Substitute - if_effect EFFECT_RECHARGE, AI_CV_Recharge - if_effect EFFECT_LEECH_SEED, AI_CV_LeechSeed - if_effect EFFECT_DISABLE, AI_CV_Disable - if_effect EFFECT_COUNTER, AI_CV_Counter - if_effect EFFECT_ENCORE, AI_CV_Encore - if_effect EFFECT_PAIN_SPLIT, AI_CV_PainSplit - if_effect EFFECT_LOCK_ON, AI_CV_LockOn - if_effect EFFECT_SLEEP_TALK, AI_CV_SleepTalk - if_effect EFFECT_SNORE, AI_CV_SleepTalk - if_effect EFFECT_DESTINY_BOND, AI_CV_DestinyBond - if_effect EFFECT_FLAIL, AI_CV_Flail - if_effect EFFECT_HEAL_BELL, AI_CV_HealBell - if_effect EFFECT_THIEF, AI_CV_Thief - if_effect EFFECT_MEAN_LOOK, AI_CV_Trap - if_effect EFFECT_MINIMIZE, AI_CV_EvasionUp - if_effect EFFECT_CURSE, AI_CV_Curse - if_effect EFFECT_PROTECT, AI_CV_Protect - if_effect EFFECT_FORESIGHT, AI_CV_Foresight - if_effect EFFECT_ENDURE, AI_CV_Endure - if_effect EFFECT_BATON_PASS, AI_CV_BatonPass - if_effect EFFECT_PURSUIT, AI_CV_Pursuit - if_effect EFFECT_MORNING_SUN, AI_CV_HealWeather - if_effect EFFECT_SYNTHESIS, AI_CV_HealWeather - if_effect EFFECT_MOONLIGHT, AI_CV_HealWeather - if_effect EFFECT_SHORE_UP, AI_CV_Heal - if_effect EFFECT_RAIN_DANCE, AI_CV_RainDance - if_effect EFFECT_SUNNY_DAY, AI_CV_SunnyDay - if_effect EFFECT_BELLY_DRUM, AI_CV_BellyDrum - if_effect EFFECT_PSYCH_UP, AI_CV_PsychUp - if_effect EFFECT_MIRROR_COAT, AI_CV_MirrorCoat - if_effect EFFECT_SKULL_BASH, AI_CV_ChargeUpMove - if_effect EFFECT_SOLARBEAM, AI_CV_ChargeUpMove - if_effect EFFECT_GEOMANCY, AI_CV_Geomancy - if_effect EFFECT_SEMI_INVULNERABLE, AI_CV_SemiInvulnerable - if_effect EFFECT_SOFTBOILED, AI_CV_Heal - if_effect EFFECT_FAKE_OUT, AI_CV_FakeOut - if_effect EFFECT_SPIT_UP, AI_CV_SpitUp - if_effect EFFECT_HAIL, AI_CV_Sandstorm - if_effect EFFECT_SANDSTORM, AI_CV_Sandstorm - if_effect EFFECT_FLATTER, AI_CV_Flatter - if_effect EFFECT_MEMENTO, AI_CV_SelfKO - if_effect EFFECT_FACADE, AI_CV_Facade - if_effect EFFECT_FOCUS_PUNCH, AI_CV_FocusPunch - if_effect EFFECT_SMELLINGSALT, AI_CV_SmellingSalt - if_effect EFFECT_TRICK, AI_CV_Trick - if_effect EFFECT_ROLE_PLAY, AI_CV_ChangeSelfAbility - if_effect EFFECT_SUPERPOWER, AI_CV_Superpower - if_effect EFFECT_MAGIC_COAT, AI_CV_MagicCoat - if_effect EFFECT_RECYCLE, AI_CV_Recycle - if_effect EFFECT_REVENGE, AI_CV_Revenge - if_effect EFFECT_BRICK_BREAK, AI_CV_BrickBreak - if_effect EFFECT_KNOCK_OFF, AI_CV_KnockOff - if_effect EFFECT_ENDEAVOR, AI_CV_Endeavor - if_effect EFFECT_ERUPTION, AI_CV_Eruption - if_effect EFFECT_SKILL_SWAP, AI_CV_ChangeSelfAbility - if_effect EFFECT_IMPRISON, AI_CV_Imprison - if_effect EFFECT_REFRESH, AI_CV_Refresh - if_effect EFFECT_SNATCH, AI_CV_Snatch - if_effect EFFECT_MUD_SPORT, AI_CV_MudSport - if_effect EFFECT_OVERHEAT, AI_CV_Overheat - if_effect EFFECT_TICKLE, AI_CV_DefenseDown - if_effect EFFECT_COSMIC_POWER, AI_CV_SpDefUp - if_effect EFFECT_BULK_UP, AI_CV_DefenseUp - if_effect EFFECT_WATER_SPORT, AI_CV_WaterSport - if_effect EFFECT_CALM_MIND, AI_CV_SpDefUp - if_effect EFFECT_DRAGON_DANCE, AI_CV_DragonDance - if_effect EFFECT_POWDER, AI_CV_Powder - if_effect EFFECT_MISTY_TERRAIN, AI_CV_MistyTerrain - if_effect EFFECT_GRASSY_TERRAIN, AI_CV_GrassyTerrain - if_effect EFFECT_ELECTRIC_TERRAIN, AI_CV_ElectricTerrain - if_effect EFFECT_PSYCHIC_TERRAIN, AI_CV_PsychicTerrain - if_effect EFFECT_STEALTH_ROCK, AI_CV_Hazards - if_effect EFFECT_SPIKES, AI_CV_Hazards - if_effect EFFECT_STICKY_WEB, AI_CV_Hazards - if_effect EFFECT_TOXIC_SPIKES, AI_CV_Hazards - if_effect EFFECT_PERISH_SONG, AI_CV_PerishSong - end - -AI_CV_PerishSong: - get_ability AI_USER - if_equal ABILITY_ARENA_TRAP, AI_CV_PerishSong_ArenaTrap - if_equal ABILITY_MAGNET_PULL, AI_CV_PerishSong_MagnetPull - if_equal ABILITY_SHADOW_TAG, AI_CV_PerishSong_ShadowTag -AI_CV_PerishSongCheckTrap: - if_status2 AI_TARGET, STATUS2_WRAPPED | STATUS2_ESCAPE_PREVENTION, Score_Plus3 - @ If has a move that can trap, use it first, then use Perish Song - if_double_battle AI_Ret - if_has_move_with_effect AI_USER, EFFECT_TRAP, Score_Minus5 - if_has_move_with_effect AI_USER, EFFECT_MEAN_LOOK, Score_Minus5 - end -AI_CV_PerishSong_ArenaTrap: - if_grounded AI_TARGET, Score_Plus2 - goto AI_CV_PerishSongCheckTrap -AI_CV_PerishSong_MagnetPull: - if_type AI_TARGET, TYPE_STEEL, Score_Plus2 - goto AI_CV_PerishSongCheckTrap -AI_CV_PerishSong_ShadowTag: - if_no_ability AI_TARGET, ABILITY_SHADOW_TAG, Score_Plus2 - goto AI_CV_PerishSongCheckTrap - -AI_CV_Hazards: - if_ability AI_TARGET, ABILITY_MAGIC_BOUNCE, AI_CV_HzardsEnd - is_first_turn_for AI_USER - if_equal 0, AI_CV_HzardsEnd - score +2 -AI_CV_HzardsEnd: - end -AI_CV_StealthRock2: - score -2 - goto AI_CV_HzardsEnd - -AI_CV_MistyTerrain: - call AI_CV_TerrainExpander - end - -AI_CV_GrassyTerrain: - call AI_CV_TerrainExpander - end - -AI_CV_ElectricTerrain: - call AI_CV_TerrainExpander - end - -AI_CV_PsychicTerrain: - call AI_CV_TerrainExpander - end - -AI_CV_TerrainExpander: - get_hold_effect AI_USER - if_equal HOLD_EFFECT_TERRAIN_EXTENDER, Score_Plus2 - end - -AI_CV_Powder: - if_type AI_TARGET, TYPE_FIRE, AI_CV_Powder2 - if_has_move_with_type AI_TARGET, TYPE_FIRE, AI_CV_Powder2 - score -2 - end -AI_CV_Powder2: - is_first_turn_for AI_TARGET - if_equal 0, AI_CV_Powder3 - if_random_less_than 100, AI_CV_Powder3 - score +1 -AI_CV_Powder3: - if_type AI_USER, TYPE_BUG, AI_CV_Powder4 - if_type AI_USER, TYPE_GRASS, AI_CV_Powder4 - if_no_type AI_USER, TYPE_STEEL, AI_CV_Powder5 -AI_CV_Powder4: - score +1 -AI_CV_Powder5: - get_last_used_bank_move AI_USER - if_equal_u32 MOVE_POWDER, AI_CV_Powder6 - if_random_less_than 150, Score_Minus1 - if_random_less_than 200, AI_Ret - score +2 - end -AI_CV_Powder6: - if_random_less_than 136, Score_Minus2 - score +1 - end - -AI_CV_Hit: - end - -AI_CV_Sleep: @ 82DCA92 - if_has_move_with_effect AI_TARGET, EFFECT_DREAM_EATER, AI_CV_SleepEncourageSlpDamage - if_has_move_with_effect AI_TARGET, EFFECT_NIGHTMARE, AI_CV_SleepEncourageSlpDamage - goto AI_CV_Sleep_End - -AI_CV_SleepEncourageSlpDamage: @ 82DCAA5 - if_random_less_than 128, AI_CV_Sleep_End - score +1 - -AI_CV_Sleep_End: @ 82DCAAD - end - -AI_CV_Absorb: @ 82DCAAE - if_type_effectiveness AI_EFFECTIVENESS_x0_5, AI_CV_AbsorbEncourageMaybe - if_type_effectiveness AI_EFFECTIVENESS_x0_25, AI_CV_AbsorbEncourageMaybe - goto AI_CV_Absorb_End - -AI_CV_AbsorbEncourageMaybe: @ 82DCABF - if_random_less_than 50, AI_CV_Absorb_End - score -3 - -AI_CV_Absorb_End: @ 82DCAC7 - end - -AI_CV_SelfKO: @ 82DCAC8 - if_stat_level_less_than AI_TARGET, STAT_EVASION, 7, AI_CV_SelfKO_Encourage1 - score -1 - if_stat_level_less_than AI_TARGET, STAT_EVASION, 10, AI_CV_SelfKO_Encourage1 - if_random_less_than 128, AI_CV_SelfKO_Encourage1 - score -1 - -AI_CV_SelfKO_Encourage1: @ 82DCAE2 - if_hp_less_than AI_USER, 80, AI_CV_SelfKO_Encourage2 - if_target_faster AI_CV_SelfKO_Encourage2 - if_random_less_than 50, AI_CV_SelfKO_End - goto Score_Minus3 - -AI_CV_SelfKO_Encourage2: @ 82DCAFA - if_hp_more_than AI_USER, 50, AI_CV_SelfKO_Encourage4 - if_random_less_than 128, AI_CV_SelfKO_Encourage3 - score +1 - -AI_CV_SelfKO_Encourage3: @ 82DCB09 - if_hp_more_than AI_USER, 30, AI_CV_SelfKO_End - if_random_less_than 50, AI_CV_SelfKO_End - score +1 - goto AI_CV_SelfKO_End - -AI_CV_SelfKO_Encourage4: @ 82DCB1D - if_random_less_than 50, AI_CV_SelfKO_End - score -1 - -AI_CV_SelfKO_End: @ 82DCB25 - end - -AI_CV_DreamEater: @ 82DCB26 - if_type_effectiveness AI_EFFECTIVENESS_x0_25, AI_CV_DreamEater_ScoreDown1 - if_type_effectiveness AI_EFFECTIVENESS_x0_5, AI_CV_DreamEater_ScoreDown1 - goto AI_CV_DreamEater_End - -AI_CV_DreamEater_ScoreDown1: @ 82DCB37 - score -1 - -AI_CV_DreamEater_End: @ 82DCB39 - end - -AI_CV_MirrorMove: @ 82DCB3A - if_target_faster AI_CV_MirrorMove2 - get_last_used_bank_move AI_TARGET - if_not_in_hwords AI_CV_MirrorMove_EncouragedMovesToMirror, AI_CV_MirrorMove2 - if_random_less_than 128, AI_CV_MirrorMove_End - score +2 - goto AI_CV_MirrorMove_End - -AI_CV_MirrorMove2: @ 82DCB58 - get_last_used_bank_move AI_TARGET - if_in_hwords AI_CV_MirrorMove_EncouragedMovesToMirror, AI_CV_MirrorMove_End - if_random_less_than 80, AI_CV_MirrorMove_End - score -1 - -AI_CV_MirrorMove_End: @ 82DCB6B - end - -.align 1 -AI_CV_MirrorMove_EncouragedMovesToMirror: @ 82DCB6C - .2byte MOVE_SLEEP_POWDER - .2byte MOVE_LOVELY_KISS - .2byte MOVE_SPORE - .2byte MOVE_HYPNOSIS - .2byte MOVE_SING - .2byte MOVE_GRASS_WHISTLE - .2byte MOVE_SHADOW_PUNCH - .2byte MOVE_SAND_ATTACK - .2byte MOVE_SMOKESCREEN - .2byte MOVE_TOXIC - .2byte MOVE_GUILLOTINE - .2byte MOVE_HORN_DRILL - .2byte MOVE_FISSURE - .2byte MOVE_SHEER_COLD - .2byte MOVE_CROSS_CHOP - .2byte MOVE_AEROBLAST - .2byte MOVE_CONFUSE_RAY - .2byte MOVE_SWEET_KISS - .2byte MOVE_SCREECH - .2byte MOVE_COTTON_SPORE - .2byte MOVE_SCARY_FACE - .2byte MOVE_FAKE_TEARS - .2byte MOVE_METAL_SOUND - .2byte MOVE_THUNDER_WAVE - .2byte MOVE_GLARE - .2byte MOVE_POISON_POWDER - .2byte MOVE_SHADOW_BALL - .2byte MOVE_DYNAMIC_PUNCH - .2byte MOVE_HYPER_BEAM - .2byte MOVE_EXTREME_SPEED - .2byte MOVE_THIEF - .2byte MOVE_COVET - .2byte MOVE_ATTRACT - .2byte MOVE_SWAGGER - .2byte MOVE_TORMENT - .2byte MOVE_FLATTER - .2byte MOVE_TRICK - .2byte MOVE_SUPERPOWER - .2byte MOVE_SKILL_SWAP - .2byte -1 - -AI_CV_AttackUp: @ 82DCBBC - if_physical_moves_unusable AI_USER, AI_TARGET, Score_Minus8 - if_stat_level_less_than AI_USER, STAT_ATK, 9, AI_CV_AttackUp2 - if_random_less_than 100, AI_CV_AttackUp3 - score -1 - goto AI_CV_AttackUp3 - -AI_CV_AttackUp2: @ 82DCBD1 - if_hp_not_equal AI_USER, 100, AI_CV_AttackUp3 - if_random_less_than 128, AI_CV_AttackUp3 - score +2 - -AI_CV_AttackUp3: @ 82DCBE0 - if_hp_more_than AI_USER, 70, AI_CV_AttackUp_End - if_hp_less_than AI_USER, 40, AI_CV_AttackUp_ScoreDown2 - if_random_less_than 40, AI_CV_AttackUp_End - -AI_CV_AttackUp_ScoreDown2: @ 82DCBF4 - score -2 - -AI_CV_AttackUp_End: @ 82DCBF6 - end - -AI_CV_DefenseUp: @ 82DCBF7 - if_stat_level_less_than AI_USER, STAT_DEF, 9, AI_CV_DefenseUp2 - if_random_less_than 100, AI_CV_DefenseUp3 - score -1 - goto AI_CV_DefenseUp3 - -AI_CV_DefenseUp2: @ 82DCC0C - if_hp_not_equal AI_USER, 100, AI_CV_DefenseUp3 - if_random_less_than 128, AI_CV_DefenseUp3 - score +2 - -AI_CV_DefenseUp3: @ 82DCC1B - if_hp_less_than AI_USER, 70, AI_CV_DefenseUp4 - if_random_less_than 200, AI_CV_DefenseUp_End - -AI_CV_DefenseUp4: @ 82DCC28 - if_hp_less_than AI_USER, 40, AI_CV_DefenseUp_ScoreDown2 - get_last_used_bank_move AI_TARGET - get_move_power_from_result - if_equal 0, AI_CV_DefenseUp5 - get_last_used_bank_move AI_TARGET - get_move_split_from_result - if_not_equal SPLIT_PHYSICAL, AI_CV_DefenseUp_ScoreDown2 - if_random_less_than 60, AI_CV_DefenseUp_End - -AI_CV_DefenseUp5: @ 82DCC4A - if_random_less_than 60, AI_CV_DefenseUp_End - -AI_CV_DefenseUp_ScoreDown2: @ 82DCC50 - score -2 - -AI_CV_DefenseUp_End: @ 82DCC52 - end - -AI_CV_SpeedUp: @ 82DCC5D - if_target_faster AI_CV_SpeedUp2 - score -3 - goto AI_CV_SpeedUp_End - -AI_CV_SpeedUp2: @ 82DCC6A - if_random_less_than 70, AI_CV_SpeedUp_End - score +3 - -AI_CV_SpeedUp_End: @ 82DCC72 - end - -AI_CV_SpAtkUp: @ 82DCC73 - if_stat_level_less_than AI_USER, STAT_SPATK, 9, AI_CV_SpAtkUp2 - if_random_less_than 100, AI_CV_SpAtkUp3 - score -1 - goto AI_CV_SpAtkUp3 - -AI_CV_SpAtkUp2: @ 82DCC88 - if_hp_not_equal AI_USER, 100, AI_CV_SpAtkUp3 - if_random_less_than 128, AI_CV_SpAtkUp3 - score +2 - -AI_CV_SpAtkUp3: @ 82DCC97 - if_hp_more_than AI_USER, 70, AI_CV_SpAtkUp_End - if_hp_less_than AI_USER, 40, AI_CV_SpAtkUp_ScoreDown2 - if_random_less_than 70, AI_CV_SpAtkUp_End - -AI_CV_SpAtkUp_ScoreDown2: @ 82DCCAB - score -2 - -AI_CV_SpAtkUp_End: @ 82DCCAD - end - -AI_CV_SpDefUp: @ 82DCCAE - if_stat_level_less_than AI_USER, STAT_SPDEF, 9, AI_CV_SpDefUp2 - if_random_less_than 100, AI_CV_SpDefUp3 - score -1 - goto AI_CV_SpDefUp3 - -AI_CV_SpDefUp2: @ 82DCCC3 - if_hp_not_equal AI_USER, 100, AI_CV_SpDefUp3 - if_random_less_than 128, AI_CV_SpDefUp3 - score +2 - -AI_CV_SpDefUp3: @ 82DCCD2 - if_hp_less_than AI_USER, 70, AI_CV_SpDefUp4 - if_random_less_than 200, AI_CV_SpDefUp_End - -AI_CV_SpDefUp4: @ 82DCCDF - if_hp_less_than AI_USER, 40, AI_CV_SpDefUp_ScoreDown2 - get_last_used_bank_move AI_TARGET - get_move_power_from_result - if_equal 0, AI_CV_SpDefUp5 - get_last_used_bank_move AI_TARGET - get_move_split_from_result - if_not_equal SPLIT_SPECIAL, AI_CV_SpDefUp_ScoreDown2 - if_random_less_than 60, AI_CV_SpDefUp_End - -AI_CV_SpDefUp5: @ 82DCD01 - if_random_less_than 60, AI_CV_SpDefUp_End - -AI_CV_SpDefUp_ScoreDown2: @ 82DCD07 - score -2 - -AI_CV_SpDefUp_End: @ 82DCD09 - end - -AI_CV_AccuracyUp: - if_stat_level_less_than AI_USER, STAT_ACC, 9, AI_CV_AccuracyUp2 - if_random_less_than 50, AI_CV_AccuracyUp2 - score -2 - -AI_CV_AccuracyUp2: - if_hp_more_than AI_USER, 70, AI_CV_AccuracyUp_End - score -2 - -AI_CV_AccuracyUp_End: - end - -AI_CV_EvasionUp: - if_hp_less_than AI_USER, 90, AI_CV_EvasionUp2 - if_random_less_than 100, AI_CV_EvasionUp2 - score +3 - -AI_CV_EvasionUp2: - if_stat_level_less_than AI_USER, STAT_EVASION, 9, AI_CV_EvasionUp3 - if_random_less_than 128, AI_CV_EvasionUp3 - score -1 - -AI_CV_EvasionUp3: - if_not_status AI_TARGET, STATUS1_TOXIC_POISON, AI_CV_EvasionUp5 - if_hp_more_than AI_USER, 50, AI_CV_EvasionUp4 - if_random_less_than 80, AI_CV_EvasionUp5 - -AI_CV_EvasionUp4: - if_random_less_than 50, AI_CV_EvasionUp5 - score +3 - -AI_CV_EvasionUp5: - if_not_status3 AI_TARGET, STATUS3_LEECHSEED, AI_CV_EvasionUp6 - if_random_less_than 70, AI_CV_EvasionUp6 - score +3 - -AI_CV_EvasionUp6: - if_not_status3 AI_USER, STATUS3_ROOTED, AI_CV_EvasionUp7 - if_random_less_than 128, AI_CV_EvasionUp7 - score +2 - -AI_CV_EvasionUp7: - if_not_status2 AI_TARGET, STATUS2_CURSED, AI_CV_EvasionUp8 - if_random_less_than 70, AI_CV_EvasionUp8 - score +3 - -AI_CV_EvasionUp8: - if_hp_more_than AI_USER, 70, AI_CV_EvasionUp_End - if_stat_level_equal AI_USER, STAT_EVASION, DEFAULT_STAT_STAGE, AI_CV_EvasionUp_End - if_hp_less_than AI_USER, 40, AI_CV_EvasionUp_ScoreDown2 - if_hp_less_than AI_TARGET, 40, AI_CV_EvasionUp_ScoreDown2 - if_random_less_than 70, AI_CV_EvasionUp_End - -AI_CV_EvasionUp_ScoreDown2: - score -2 - -AI_CV_EvasionUp_End: - end - -AI_CV_AlwaysHit: - if_stat_level_more_than AI_TARGET, STAT_EVASION, 10, AI_CV_AlwaysHit_ScoreUp1 - if_stat_level_less_than AI_USER, STAT_ACC, 2, AI_CV_AlwaysHit_ScoreUp1 - if_stat_level_more_than AI_TARGET, STAT_EVASION, 8, AI_CV_AlwaysHit2 - if_stat_level_less_than AI_USER, STAT_ACC, 4, AI_CV_AlwaysHit2 - goto AI_CV_AlwaysHit_End - -AI_CV_AlwaysHit_ScoreUp1: - score +1 - -AI_CV_AlwaysHit2: - if_random_less_than 100, AI_CV_AlwaysHit_End - score +1 - -AI_CV_AlwaysHit_End: - end - -AI_CV_AttackDown: @ 82DCDF8 - if_stat_level_equal AI_TARGET, STAT_ATK, DEFAULT_STAT_STAGE, AI_CV_AttackDown3 - score -1 - if_hp_more_than AI_USER, 90, AI_CV_AttackDown2 - score -1 - -AI_CV_AttackDown2: @ 82DCE0B - if_stat_level_more_than AI_TARGET, STAT_ATK, 3, AI_CV_AttackDown3 - if_random_less_than 50, AI_CV_AttackDown3 - score -2 - -AI_CV_AttackDown3: @ 82DCE1B - if_hp_more_than AI_TARGET, 70, AI_CV_AttackDown4 - score -2 - -AI_CV_AttackDown4: @ 82DCE24 - get_target_type1 - if_in_bytes AI_CV_AttackDown_UnknownTypeList, AI_CV_AttackDown_End - get_target_type2 - if_in_bytes AI_CV_AttackDown_UnknownTypeList, AI_CV_AttackDown_End - if_random_less_than 50, AI_CV_AttackDown_End - score -2 - -AI_CV_AttackDown_End: @ 82DCE42 - end - -AI_CV_AttackDown_UnknownTypeList: - .byte TYPE_NORMAL - .byte TYPE_FIGHTING - .byte TYPE_GROUND - .byte TYPE_ROCK - .byte TYPE_BUG - .byte TYPE_STEEL - .byte -1 - -AI_CV_DefenseDown: - if_hp_less_than AI_USER, 70, AI_CV_DefenseDown2 - if_stat_level_more_than AI_TARGET, STAT_DEF, 3, AI_CV_DefenseDown3 - -AI_CV_DefenseDown2: - if_random_less_than 50, AI_CV_DefenseDown3 - score -2 - -AI_CV_DefenseDown3: - if_hp_more_than AI_TARGET, 70, AI_CV_DefenseDown_End - score -2 - -AI_CV_DefenseDown_End: - end - -AI_CV_SpeedDownFromChance: @ 82DCE6B - if_move MOVE_ICY_WIND, AI_CV_SpeedDown - if_move MOVE_ROCK_TOMB, AI_CV_SpeedDown - if_move MOVE_MUD_SHOT, AI_CV_SpeedDown - end - -AI_CV_SpeedDown: @ 82DCE81 - if_target_faster AI_CV_SpeedDown2 - score -3 - goto AI_CV_SpeedDown_End -AI_CV_SpeedDown2: @ 82DCE8E - if_random_less_than 70, AI_CV_SpeedDown_End - score +2 -AI_CV_SpeedDown_End: @ 82DCE96 - end - -AI_CV_SpAtkDown: - if_stat_level_equal AI_TARGET, STAT_ATK, DEFAULT_STAT_STAGE, AI_CV_SpAtkDown3 - score -1 - if_hp_more_than AI_USER, 90, AI_CV_SpAtkDown2 - score -1 - -AI_CV_SpAtkDown2: - if_stat_level_more_than AI_TARGET, STAT_SPATK, 3, AI_CV_SpAtkDown3 - if_random_less_than 50, AI_CV_SpAtkDown3 - score -2 - -AI_CV_SpAtkDown3: - if_hp_more_than AI_TARGET, 70, AI_CV_SpAtkDown4 - score -2 - -AI_CV_SpAtkDown4: - get_target_type1 - if_in_bytes AI_CV_SpAtkDown_SpecialTypeList, AI_CV_SpAtkDown_End - get_target_type2 - if_in_bytes AI_CV_SpAtkDown_SpecialTypeList, AI_CV_SpAtkDown_End - if_random_less_than 50, AI_CV_SpAtkDown_End - score -2 - -AI_CV_SpAtkDown_End: @ 82DCEE1 - end - -AI_CV_SpAtkDown_SpecialTypeList: @ 82DCEE2 - .byte TYPE_FIRE - .byte TYPE_WATER - .byte TYPE_GRASS - .byte TYPE_ELECTRIC - .byte TYPE_PSYCHIC - .byte TYPE_ICE - .byte TYPE_DRAGON - .byte TYPE_DARK - .byte -1 - -AI_CV_SpDefDown: @ 82DCEEB - if_hp_less_than AI_USER, 70, AI_CV_SpDefDown2 - if_stat_level_more_than AI_TARGET, STAT_SPDEF, 3, AI_CV_SpDefDown3 - -AI_CV_SpDefDown2: @ 82DCEFA - if_random_less_than 50, AI_CV_SpDefDown3 - score -2 - -AI_CV_SpDefDown3: @ 82DCF02 - if_hp_more_than AI_TARGET, 70, AI_CV_SpDefDown_End - score -2 - -AI_CV_SpDefDown_End: @ 82DCF0B - end - -AI_CV_AccuracyDown: @ 82DCF0C - if_hp_less_than AI_USER, 70, AI_CV_AccuracyDown2 - if_hp_more_than AI_TARGET, 70, AI_CV_AccuracyDown3 - -AI_CV_AccuracyDown2: - if_random_less_than 100, AI_CV_AccuracyDown3 - score -1 - -AI_CV_AccuracyDown3: - if_stat_level_more_than AI_USER, STAT_ACC, 4, AI_CV_AccuracyDown4 - if_random_less_than 80, AI_CV_AccuracyDown4 - score -2 - -AI_CV_AccuracyDown4: - if_not_status AI_TARGET, STATUS1_TOXIC_POISON, AI_CV_AccuracyDown5 - if_random_less_than 70, AI_CV_AccuracyDown5 - score +2 - -AI_CV_AccuracyDown5: - if_not_status3 AI_TARGET, STATUS3_LEECHSEED, AI_CV_AccuracyDown6 - if_random_less_than 70, AI_CV_AccuracyDown6 - score +2 - -AI_CV_AccuracyDown6: - if_not_status3 AI_USER, STATUS3_ROOTED, AI_CV_AccuracyDown7 - if_random_less_than 128, AI_CV_AccuracyDown7 - score +1 - -AI_CV_AccuracyDown7: - if_not_status2 AI_TARGET, STATUS2_CURSED, AI_CV_AccuracyDown8 - if_random_less_than 70, AI_CV_AccuracyDown8 - score +2 - -AI_CV_AccuracyDown8: - if_hp_more_than AI_USER, 70, AI_CV_AccuracyDown_End - if_stat_level_equal AI_TARGET, STAT_ACC, DEFAULT_STAT_STAGE, AI_CV_AccuracyDown_End - if_hp_less_than AI_USER, 40, AI_CV_AccuracyDown_ScoreDown2 - if_hp_less_than AI_TARGET, 40, AI_CV_AccuracyDown_ScoreDown2 - if_random_less_than 70, AI_CV_AccuracyDown_End - -AI_CV_AccuracyDown_ScoreDown2: - score -2 - -AI_CV_AccuracyDown_End: - end - -AI_CV_EvasionDown: - if_hp_less_than AI_USER, 70, AI_CV_EvasionDown2 - if_stat_level_more_than AI_TARGET, STAT_EVASION, 3, AI_CV_EvasionDown3 -AI_CV_EvasionDown2: - if_random_less_than 50, AI_CV_EvasionDown3 - score -2 -AI_CV_EvasionDown3: - if_hp_more_than AI_TARGET, 70, AI_CV_EvasionDown_4 - score -2 -AI_CV_EvasionDown_4: - if_stat_level_less_than AI_USER, STAT_ACC, 6, AI_CV_EvasionDown_5 - if_stat_level_less_than AI_TARGET, STAT_EVASION, 7, AI_CV_EvasionDown_6 - if_ability AI_USER, ABILITY_NO_GUARD, AI_CV_EvasionDown_6 -AI_CV_EvasionDown_End: - end -AI_CV_EvasionDown_5: - score +1 - goto AI_CV_EvasionDown_End -AI_CV_EvasionDown_6: - score -2 - goto AI_CV_EvasionDown_End - -AI_CV_Haze: - if_stat_level_more_than AI_USER, STAT_ATK, 8, AI_CV_Haze2 - if_stat_level_more_than AI_USER, STAT_DEF, 8, AI_CV_Haze2 - if_stat_level_more_than AI_USER, STAT_SPATK, 8, AI_CV_Haze2 - if_stat_level_more_than AI_USER, STAT_SPDEF, 8, AI_CV_Haze2 - if_stat_level_more_than AI_USER, STAT_EVASION, 8, AI_CV_Haze2 - if_stat_level_less_than AI_TARGET, STAT_ATK, 4, AI_CV_Haze2 - if_stat_level_less_than AI_TARGET, STAT_DEF, 4, AI_CV_Haze2 - if_stat_level_less_than AI_TARGET, STAT_SPATK, 4, AI_CV_Haze2 - if_stat_level_less_than AI_TARGET, STAT_SPDEF, 4, AI_CV_Haze2 - if_stat_level_less_than AI_TARGET, STAT_ACC, 4, AI_CV_Haze2 - goto AI_CV_Haze3 - -AI_CV_Haze2: - if_random_less_than 50, AI_CV_Haze3 - score -3 - -AI_CV_Haze3: - if_stat_level_more_than AI_TARGET, STAT_ATK, 8, AI_CV_Haze4 - if_stat_level_more_than AI_TARGET, STAT_DEF, 8, AI_CV_Haze4 - if_stat_level_more_than AI_TARGET, STAT_SPATK, 8, AI_CV_Haze4 - if_stat_level_more_than AI_TARGET, STAT_SPDEF, 8, AI_CV_Haze4 - if_stat_level_more_than AI_TARGET, STAT_EVASION, 8, AI_CV_Haze4 - if_stat_level_less_than AI_USER, STAT_ATK, 4, AI_CV_Haze4 - if_stat_level_less_than AI_USER, STAT_DEF, 4, AI_CV_Haze4 - if_stat_level_less_than AI_USER, STAT_SPATK, 4, AI_CV_Haze4 - if_stat_level_less_than AI_USER, STAT_SPDEF, 4, AI_CV_Haze4 - if_stat_level_less_than AI_USER, STAT_ACC, 4, AI_CV_Haze4 - if_random_less_than 50, AI_CV_Haze_End - score -1 - goto AI_CV_Haze_End - -AI_CV_Haze4: - if_random_less_than 50, AI_CV_Haze_End - score +3 - -AI_CV_Haze_End: - end - -AI_CV_Bide: - if_hp_more_than AI_USER, 90, AI_CV_Bide_End - score -2 - -AI_CV_Bide_End: - end - -AI_CV_Roar: - if_stat_level_more_than AI_TARGET, STAT_ATK, 8, AI_CV_Roar2 - if_stat_level_more_than AI_TARGET, STAT_DEF, 8, AI_CV_Roar2 - if_stat_level_more_than AI_TARGET, STAT_SPATK, 8, AI_CV_Roar2 - if_stat_level_more_than AI_TARGET, STAT_SPDEF, 8, AI_CV_Roar2 - if_stat_level_more_than AI_TARGET, STAT_EVASION, 8, AI_CV_Roar2 - score -3 - goto AI_CV_Roar_End - -AI_CV_Roar2: - if_random_less_than 128, AI_CV_Roar_End - score +2 - -AI_CV_Roar_End: - end - -AI_CV_Conversion: - if_hp_more_than AI_USER, 90, AI_CV_Conversion2 - score -2 - -AI_CV_Conversion2: - get_turn_count - if_equal 0, AI_CV_Conversion_End - if_random_less_than 200, Score_Minus2 - -AI_CV_Conversion_End: - end - -AI_CV_HealWeather: - get_weather - if_equal AI_WEATHER_HAIL, AI_CV_HealWeather_ScoreDown2 - if_equal AI_WEATHER_RAIN, AI_CV_HealWeather_ScoreDown2 - if_equal AI_WEATHER_SANDSTORM, AI_CV_HealWeather_ScoreDown2 - goto AI_CV_Heal - -AI_CV_HealWeather_ScoreDown2: - score -2 - -AI_CV_Heal: - if_hp_equal AI_USER, 100, AI_CV_Heal3 - if_target_faster AI_CV_Heal4 - score -8 - goto AI_CV_Heal_End - -AI_CV_Heal2: - if_hp_less_than AI_USER, 50, AI_CV_Heal5 - if_hp_more_than AI_USER, 80, AI_CV_Heal3 - if_random_less_than 70, AI_CV_Heal5 - -AI_CV_Heal3: - score -3 - goto AI_CV_Heal_End - -AI_CV_Heal4: - if_hp_less_than AI_USER, 70, AI_CV_Heal5 - if_random_less_than 30, AI_CV_Heal5 - score -3 - goto AI_CV_Heal_End - -AI_CV_Heal5: - if_doesnt_have_move_with_effect AI_TARGET, EFFECT_SNATCH, AI_CV_Heal6 - if_random_less_than 100, AI_CV_Heal_End - -AI_CV_Heal6: - if_random_less_than 20, AI_CV_Heal_End - score +2 - -AI_CV_Heal_End: - end - -EncouragePsnVenoshock: - if_doesnt_have_move_with_effect AI_USER, EFFECT_VENOSHOCK, EncouragePsnVenoshockEnd - score +1 - if_random_less_than 128, EncouragePsnVenoshockEnd - score +1 -EncouragePsnVenoshockEnd: - end - -AI_CV_Toxic: - call EncouragePsnVenoshock -AI_CV_LeechSeed: - if_user_has_no_attacking_moves AI_CV_Toxic3 - if_hp_more_than AI_USER, 50, AI_CV_Toxic2 - if_random_less_than 50, AI_CV_Toxic2 - score -3 -AI_CV_Toxic2: - if_hp_more_than AI_TARGET, 50, AI_CV_Toxic3 - if_random_less_than 50, AI_CV_Toxic3 - score -3 -AI_CV_Toxic3: - if_has_move_with_effect AI_USER, EFFECT_SPECIAL_DEFENSE_UP, AI_CV_Toxic4 - if_has_move_with_effect AI_USER, EFFECT_PROTECT, AI_CV_Toxic4 - goto AI_CV_Toxic_End -AI_CV_Toxic4: - if_random_less_than 60, AI_CV_Toxic_End - score +2 -AI_CV_Toxic_End: - end - -AI_CV_LightScreen: - call EncourageLightClay - if_hp_less_than AI_USER, 50, AI_CV_LightScreen_ScoreDown2 - get_target_type1 - if_in_bytes AI_CV_LightScreen_SpecialTypeList, AI_CV_LightScreen_End - get_target_type2 - if_in_bytes AI_CV_LightScreen_SpecialTypeList, AI_CV_LightScreen_End - if_random_less_than 50, AI_CV_LightScreen_End -AI_CV_LightScreen_ScoreDown2: - score -2 -AI_CV_LightScreen_End: - end - -AI_CV_LightScreen_SpecialTypeList: - .byte TYPE_FIRE - .byte TYPE_WATER - .byte TYPE_GRASS - .byte TYPE_ELECTRIC - .byte TYPE_PSYCHIC - .byte TYPE_ICE - .byte TYPE_DRAGON - .byte TYPE_DARK - .byte -1 - -AI_CV_Rest: - if_target_faster AI_CV_Rest4 - if_hp_not_equal AI_USER, 100, AI_CV_Rest2 - score -8 - goto AI_CV_Rest_End - -AI_CV_Rest2: - if_hp_less_than AI_USER, 40, AI_CV_Rest6 - if_hp_more_than AI_USER, 50, AI_CV_Rest3 - if_random_less_than 70, AI_CV_Rest6 - -AI_CV_Rest3: - score -3 - goto AI_CV_Rest_End - -AI_CV_Rest4: - if_hp_less_than AI_USER, 60, AI_CV_Rest6 - if_hp_more_than AI_USER, 70, AI_CV_Rest5 - if_random_less_than 50, AI_CV_Rest6 - -AI_CV_Rest5: - score -3 - goto AI_CV_Rest_End - -AI_CV_Rest6: - if_doesnt_have_move_with_effect AI_TARGET, EFFECT_SNATCH, AI_CV_Rest7 - if_random_less_than 50, AI_CV_Rest_End - -AI_CV_Rest7: - if_random_less_than 10, AI_CV_Rest_End - score +3 - -AI_CV_Rest_End: - end - -AI_CV_OneHitKO: - if_status3 AI_TARGET, STATUS3_ALWAYS_HITS, Score_Plus5 - end - -AI_CV_SuperFang: - if_hp_more_than AI_TARGET, 50, AI_CV_SuperFang_End - score -1 - -AI_CV_SuperFang_End: - end - -AI_CV_Trap: - if_status2 AI_TARGET, STATUS2_WRAPPED | STATUS2_ESCAPE_PREVENTION, AI_CV_TrapEnd - if_status3 AI_TARGET, STATUS3_PERISH_SONG, AI_CV_Trap5 - if_doesnt_have_move_with_effect AI_USER, EFFECT_PERISH_SONG, AI_CV_Trap1 - score +3 -AI_CV_Trap1: - if_status AI_TARGET, STATUS1_TOXIC_POISON, AI_CV_Trap2 - if_status2 AI_TARGET, STATUS2_CURSED | STATUS2_INFATUATION, AI_CV_Trap2 - goto AI_CV_TrapItem -AI_CV_Trap5: - score +2 - goto AI_CV_TrapItem -AI_CV_Trap2: - if_random_less_than 128, AI_CV_TrapItem - score +1 -AI_CV_TrapItem: - get_considered_move_power - if_equal 0, AI_CV_TrapEnd - if_status2 AI_TARGET, STATUS2_WRAPPED, AI_CV_TrapEnd - get_hold_effect AI_USER - if_equal HOLD_EFFECT_GRIP_CLAW AI_CV_Trap4 - if_equal HOLD_EFFECT_BINDING_BAND AI_CV_Trap4 - goto AI_CV_TrapEnd -AI_CV_Trap4: - score +2 -AI_CV_TrapEnd: - end - -AI_CV_HighCrit: - if_type_effectiveness AI_EFFECTIVENESS_x0_25, AI_CV_HighCrit_End - if_type_effectiveness AI_EFFECTIVENESS_x0_5, AI_CV_HighCrit_End - if_type_effectiveness AI_EFFECTIVENESS_x2, AI_CV_HighCrit2 - if_type_effectiveness AI_EFFECTIVENESS_x4, AI_CV_HighCrit2 - if_random_less_than 128, AI_CV_HighCrit_End - -AI_CV_HighCrit2: - if_random_less_than 128, AI_CV_HighCrit_End - score +1 - -AI_CV_HighCrit_End: - end - -AI_CV_FocusEnergy: - if_has_move_with_flag AI_USER, FLAG_HIGH_CRIT, AI_CV_FocusEnergy2 -AI_CV_FocusEnergy3: - get_hold_effect AI_USER - if_not_equal HOLD_EFFECT_SCOPE_LENS, AI_CV_FocusEnergyEnd - score +1 -AI_CV_FocusEnergyEnd: - end -AI_CV_FocusEnergy2: - score +1 - goto AI_CV_FocusEnergy3 - -AI_CV_Swagger: - if_doesnt_have_move_with_effect AI_USER, EFFECT_FOUL_PLAY, AI_CV_Swagger2 - score +1 -AI_CV_Swagger2: - if_has_move AI_USER, MOVE_PSYCH_UP, AI_CV_SwaggerHasPsychUp - -AI_CV_Flatter: - if_random_less_than 128, AI_CV_Confuse - score +1 - -AI_CV_Confuse: - if_hp_more_than AI_TARGET, 70, AI_CV_Confuse_End - if_random_less_than 128, AI_CV_Confuse2 - score -1 - -AI_CV_Confuse2: - if_hp_more_than AI_TARGET, 50, AI_CV_Confuse_End - score -1 - if_hp_more_than AI_TARGET, 30, AI_CV_Confuse_End - score -1 - -AI_CV_Confuse_End: - end - -AI_CV_SwaggerHasPsychUp: - if_stat_level_more_than AI_TARGET, STAT_ATK, 3, AI_CV_SwaggerHasPsychUp_Minus5 - score +3 - get_turn_count - if_not_equal 0, AI_CV_SwaggerHasPsychUp_End - score +2 - goto AI_CV_SwaggerHasPsychUp_End - -AI_CV_SwaggerHasPsychUp_Minus5: - score -5 - -AI_CV_SwaggerHasPsychUp_End: - end - -EncourageLightClay: - get_hold_effect AI_USER - if_not_equal HOLD_EFFECT_LIGHT_CLAY, EncourageLightClayEnd - score +1 - if_random_less_than 111, EncourageLightClayEnd - score +1 -EncourageLightClayEnd: - end - -AI_CV_AuroraVeil: - call EncourageLightClay - end - -AI_CV_Reflect: - call EncourageLightClay - if_hp_less_than AI_USER, 50, AI_CV_Reflect_ScoreDown2 - get_target_type1 - if_in_bytes AI_CV_Reflect_PhysicalTypeList, AI_CV_Reflect_End - get_target_type2 - if_in_bytes AI_CV_Reflect_PhysicalTypeList, AI_CV_Reflect_End - if_random_less_than 50, AI_CV_Reflect_End -AI_CV_Reflect_ScoreDown2: - score -2 -AI_CV_Reflect_End: - end - -AI_CV_Reflect_PhysicalTypeList: - .byte TYPE_NORMAL - .byte TYPE_FIGHTING - .byte TYPE_FLYING - .byte TYPE_POISON - .byte TYPE_GROUND - .byte TYPE_ROCK - .byte TYPE_BUG - .byte TYPE_GHOST - .byte TYPE_STEEL - .byte -1 - -AI_CV_ToxicThread: - if_status AI_TARGET, STATUS1_ANY, AI_CV_ToxicThreadSpd - call EncouragePsnVenoshock -AI_CV_ToxicThreadSpd: - if_target_faster AI_CV_ToxicThread2 - if_not_status AI_TARGET, STATUS1_ANY, AI_CV_ToxicThread3 - score -1 - goto AI_CV_ToxicThread3 -AI_CV_ToxicThread2: - score +1 -AI_CV_ToxicThread3: - goto AI_CV_Poison2 - -AI_CV_Poison: - call EncouragePsnVenoshock -AI_CV_Poison2: - if_hp_less_than AI_USER, 50, AI_CV_Poison_ScoreDown1 - if_hp_more_than AI_TARGET, 50, AI_CV_Poison_End -AI_CV_Poison_ScoreDown1: - score -1 -AI_CV_Poison_End: - end - -AI_CV_Paralyze: - if_target_faster AI_CV_Paralyze2 - if_hp_more_than AI_USER, 70, AI_CV_Paralyze_End - score -1 - goto AI_CV_Paralyze_End - -AI_CV_Paralyze2: - if_random_less_than 20, AI_CV_Paralyze_End - score +3 - -AI_CV_Paralyze_End: - end - -AI_CV_VitalThrow: - if_target_faster AI_CV_VitalThrow_End - if_hp_more_than AI_USER, 60, AI_CV_VitalThrow_End - if_hp_less_than AI_USER, 40, AI_CV_VitalThrow2 - if_random_less_than 180, AI_CV_VitalThrow_End - -AI_CV_VitalThrow2: - if_random_less_than 50, AI_CV_VitalThrow_End - score -1 - -AI_CV_VitalThrow_End: - end - -AI_CV_Substitute: - if_not_status2 AI_TARGET, STATUS2_WRAPPED | STATUS2_ESCAPE_PREVENTION, AI_CV_Substitute1 - if_status3 AI_TARGET, STATUS3_PERISH_SONG, AI_CV_SubstitutePlus3Continue - if_status AI_TARGET, STATUS1_BURN | STATUS1_PSN_ANY, AI_CV_SubstitutePlus1Continue - goto AI_CV_Substitute1 -AI_CV_SubstitutePlus1Continue: - score +1 - goto AI_CV_Substitute1 -AI_CV_SubstitutePlus3Continue: - score +3 -AI_CV_Substitute1: - if_hp_more_than AI_USER, 90, AI_CV_Substitute4 - if_hp_more_than AI_USER, 70, AI_CV_Substitute3 - if_hp_more_than AI_USER, 50, AI_CV_Substitute2 - if_random_less_than 100, AI_CV_Substitute2 - score -1 -AI_CV_Substitute2: - if_random_less_than 100, AI_CV_Substitute3 - score -1 -AI_CV_Substitute3: - if_random_less_than 100, AI_CV_Substitute4 - score -1 -AI_CV_Substitute4: - if_target_faster AI_CV_Substitute_End - get_last_used_bank_move AI_TARGET - get_move_effect_from_result - if_equal EFFECT_SLEEP, AI_CV_Substitute5 - if_equal EFFECT_TOXIC, AI_CV_Substitute5 - if_equal EFFECT_POISON, AI_CV_Substitute5 - if_equal EFFECT_PARALYZE, AI_CV_Substitute5 - if_equal EFFECT_WILL_O_WISP, AI_CV_Substitute5 - if_equal EFFECT_CONFUSE, AI_CV_Substitute6 - if_equal EFFECT_LEECH_SEED, AI_CV_Substitute7 - goto AI_CV_Substitute_End -AI_CV_Substitute5: - if_not_status AI_TARGET, STATUS1_ANY, AI_CV_Substitute8 - goto AI_CV_Substitute_End -AI_CV_Substitute6: - if_not_status2 AI_TARGET, STATUS2_CONFUSION, AI_CV_Substitute8 - goto AI_CV_Substitute_End -AI_CV_Substitute7: - if_status3 AI_TARGET, STATUS3_LEECHSEED, AI_CV_Substitute_End -AI_CV_Substitute8: - if_random_less_than 100, AI_CV_Substitute_End - score +1 -AI_CV_Substitute_End: - end - -AI_CV_Recharge: - if_type_effectiveness AI_EFFECTIVENESS_x0_25, AI_CV_Recharge_ScoreDown1 - if_type_effectiveness AI_EFFECTIVENESS_x0_5, AI_CV_Recharge_ScoreDown1 - if_target_faster AI_CV_Recharge2 - if_hp_more_than AI_USER, 40, AI_CV_Recharge_ScoreDown1 - goto AI_CV_Recharge_End - -AI_CV_Recharge2: - if_hp_less_than AI_USER, 60, AI_CV_Recharge_End - -AI_CV_Recharge_ScoreDown1: - score -1 - -AI_CV_Recharge_End: - end - -AI_CV_Disable: - if_target_faster AI_CV_Disable_End - get_last_used_bank_move AI_TARGET - get_move_power_from_result - if_equal 0, AI_CV_Disable2 - score +1 - goto AI_CV_Disable_End - -AI_CV_Disable2: - if_random_less_than 100, AI_CV_Disable_End - score -1 - -AI_CV_Disable_End: - end - -AI_CV_Counter: - if_status AI_TARGET, STATUS1_SLEEP, AI_CV_Counter_ScoreDown1 - if_status2 AI_TARGET, STATUS2_INFATUATION, AI_CV_Counter_ScoreDown1 - if_status2 AI_TARGET, STATUS2_CONFUSION, AI_CV_Counter_ScoreDown1 - if_hp_more_than AI_USER, 30, AI_CV_Counter2 - if_random_less_than 10, AI_CV_Counter2 - score -1 - -AI_CV_Counter2: - if_hp_more_than AI_USER, 50, AI_CV_Counter3 - if_random_less_than 100, AI_CV_Counter3 - score -1 - -AI_CV_Counter3: - if_has_move AI_USER, MOVE_MIRROR_COAT, AI_CV_Counter7 - get_last_used_bank_move AI_TARGET - get_move_power_from_result - if_equal 0, AI_CV_Counter5 - if_target_not_taunted AI_CV_Counter4 - if_random_less_than 100, AI_CV_Counter4 - score +1 - -AI_CV_Counter4: - get_last_used_bank_move AI_TARGET - get_move_split_from_result - if_not_equal SPLIT_PHYSICAL, AI_CV_Counter_ScoreDown1 - if_random_less_than 100, AI_CV_Counter_End - score +1 - goto AI_CV_Counter_End - -AI_CV_Counter5: - if_target_not_taunted AI_CV_Counter6 - if_random_less_than 100, AI_CV_Counter6 - score +1 - -AI_CV_Counter6: - if_has_no_physical_move AI_TARGET, AI_CV_Counter_ScoreDown1 - if_random_less_than 50, AI_CV_Counter_End - -AI_CV_Counter7: - if_random_less_than 100, AI_CV_Counter8 - score +4 - -AI_CV_Counter8: - end - -AI_CV_Counter_ScoreDown1: - score -1 - -AI_CV_Counter_End: - end - -AI_CV_Encore: - if_any_move_disabled AI_TARGET, AI_CV_Encore2 - if_target_faster AI_CV_Encore_ScoreDown2 - get_last_used_bank_move AI_TARGET - get_move_effect_from_result - if_not_in_bytes AI_CV_Encore_EncouragedMovesToEncore, AI_CV_Encore_ScoreDown2 - -AI_CV_Encore2: - if_random_less_than 30, AI_CV_Encore_End - score +3 - goto AI_CV_Encore_End - -AI_CV_Encore_ScoreDown2: - score -2 - -AI_CV_Encore_End: - end - -AI_CV_Encore_EncouragedMovesToEncore: - .byte EFFECT_DREAM_EATER - .byte EFFECT_ATTACK_UP - .byte EFFECT_DEFENSE_UP - .byte EFFECT_SPEED_UP - .byte EFFECT_SPECIAL_ATTACK_UP - .byte EFFECT_HAZE - .byte EFFECT_ROAR - .byte EFFECT_CONVERSION - .byte EFFECT_TOXIC - .byte EFFECT_LIGHT_SCREEN - .byte EFFECT_REST - .byte EFFECT_SUPER_FANG - .byte EFFECT_SPECIAL_DEFENSE_UP_2 - .byte EFFECT_CONFUSE - .byte EFFECT_POISON - .byte EFFECT_PARALYZE - .byte EFFECT_LEECH_SEED - .byte EFFECT_DO_NOTHING - .byte EFFECT_ATTACK_UP_2 - .byte EFFECT_ENCORE - .byte EFFECT_CONVERSION_2 - .byte EFFECT_LOCK_ON - .byte EFFECT_HEAL_BELL - .byte EFFECT_MEAN_LOOK - .byte EFFECT_NIGHTMARE - .byte EFFECT_PROTECT - .byte EFFECT_SKILL_SWAP - .byte EFFECT_FORESIGHT - .byte EFFECT_PERISH_SONG - .byte EFFECT_SANDSTORM - .byte EFFECT_ENDURE - .byte EFFECT_SWAGGER - .byte EFFECT_ATTRACT - .byte EFFECT_SAFEGUARD - .byte EFFECT_RAIN_DANCE - .byte EFFECT_SUNNY_DAY - .byte EFFECT_BELLY_DRUM - .byte EFFECT_PSYCH_UP - .byte EFFECT_FUTURE_SIGHT - .byte EFFECT_FAKE_OUT - .byte EFFECT_STOCKPILE - .byte EFFECT_SPIT_UP - .byte EFFECT_SWALLOW - .byte EFFECT_HAIL - .byte EFFECT_TORMENT - .byte EFFECT_WILL_O_WISP - .byte EFFECT_FOLLOW_ME - .byte EFFECT_CHARGE - .byte EFFECT_TRICK - .byte EFFECT_ROLE_PLAY - .byte EFFECT_INGRAIN - .byte EFFECT_RECYCLE - .byte EFFECT_KNOCK_OFF - .byte EFFECT_SKILL_SWAP - .byte EFFECT_IMPRISON - .byte EFFECT_REFRESH - .byte EFFECT_GRUDGE - .byte EFFECT_TEETER_DANCE - .byte EFFECT_MUD_SPORT - .byte EFFECT_WATER_SPORT - .byte EFFECT_DRAGON_DANCE - .byte EFFECT_CAMOUFLAGE - .byte -1 - -AI_CV_PainSplit: - if_hp_less_than AI_TARGET, 80, AI_CV_PainSplit_ScoreDown1 - if_target_faster AI_CV_PainSplit2 - if_hp_more_than AI_USER, 40, AI_CV_PainSplit_ScoreDown1 - score +1 - goto AI_CV_PainSplit_End - -AI_CV_PainSplit2: - if_hp_more_than AI_USER, 60, AI_CV_PainSplit_ScoreDown1 - score +1 - goto AI_CV_PainSplit_End - -AI_CV_PainSplit_ScoreDown1: - score -1 - -AI_CV_PainSplit_End: - end - -AI_EncourageIfHasOHKO: - if_level_cond 1, AI_EncourageIfHasOHKORet - if_has_move_with_effect AI_USER, EFFECT_OHKO, Score_Plus3 -AI_EncourageIfHasOHKORet: - end - -AI_EncourageIfHasLowAccuracyMove: - if_ability AI_USER, ABILITY_COMPOUND_EYES, AI_EncourageIfHasVeryLowAccuracyMove - get_hold_effect AI_USER - if_equal HOLD_EFFECT_WIDE_LENS, AI_EncourageIfHasVeryLowAccuracyMove - if_equal HOLD_EFFECT_ZOOM_LENS, AI_EncourageIfHasVeryLowAccuracyMove - if_has_move_with_accuracy_lt AI_USER, 86, Score_Plus3 - if_has_move_with_accuracy_lt AI_USER, 91, Score_Plus1 - goto Score_Minus1 -AI_EncourageIfHasVeryLowAccuracyMove: - if_has_move_with_accuracy_lt AI_USER, 81, Score_Plus3 - if_has_move_with_accuracy_lt AI_USER, 86, Score_Plus1 - goto Score_Minus1 - -AI_CV_LockOn: - call AI_EncourageIfHasOHKO - call AI_EncourageIfHasLowAccuracyMove -AI_CV_LockOn2: - if_random_less_than 128, AI_CV_LockOn_End - score +1 - -AI_CV_LockOn_End: - end - -AI_CV_SleepTalk: - is_wakeup_turn AI_USER - if_equal 1, Score_Minus5 - if_status AI_USER, STATUS1_SLEEP, Score_Plus10 - score -5 - end - -AI_CV_DestinyBond: - score -1 - if_target_faster AI_CV_DestinyBond_End - if_hp_more_than AI_USER, 70, AI_CV_DestinyBond_End - if_random_less_than 128, AI_CV_DestinyBond2 - score +1 - -AI_CV_DestinyBond2: - if_hp_more_than AI_USER, 50, AI_CV_DestinyBond_End - if_random_less_than 128, AI_CV_DestinyBond3 - score +1 - -AI_CV_DestinyBond3: - if_hp_more_than AI_USER, 30, AI_CV_DestinyBond_End - if_random_less_than 100, AI_CV_DestinyBond_End - score +2 - -AI_CV_DestinyBond_End: - end - -AI_CV_Flail: - if_target_faster AI_CV_Flail2 - if_hp_more_than AI_USER, 33, AI_CV_Flail_ScoreDown1 - if_hp_more_than AI_USER, 20, AI_CV_Flail_End - if_hp_less_than AI_USER, 8, AI_CV_Flail_ScoreUp1 - goto AI_CV_Flail3 - -AI_CV_Flail2: - if_hp_more_than AI_USER, 60, AI_CV_Flail_ScoreDown1 - if_hp_more_than AI_USER, 40, AI_CV_Flail_End - goto AI_CV_Flail3 - -AI_CV_Flail_ScoreUp1: - score +1 - -AI_CV_Flail3: - if_random_less_than 100, AI_CV_Flail_End - score +1 - goto AI_CV_Flail_End - -AI_CV_Flail_ScoreDown1: - score -1 - -AI_CV_Flail_End: - end - -AI_CV_HealBell: - if_move MOVE_HEAL_BELL AI_CV_HealBell2 -AI_CV_HealBellEnd: - end -@ Don't use Heal Bell to heal a partner that has Soundproof -AI_CV_HealBell2: - if_status AI_USER, STATUS1_ANY, AI_CV_HealBellEnd - if_not_status AI_USER_PARTNER, STATUS1_ANY, AI_CV_HealBellEnd - if_ability AI_USER_PARTNER, ABILITY_SOUNDPROOF, Score_Minus3 - goto AI_CV_HealBellEnd - -AI_CV_Thief: - get_hold_effect AI_TARGET - if_not_in_bytes AI_CV_Thief_EncourageItemsToSteal, AI_CV_Thief_ScoreDown2 - if_random_less_than 50, AI_CV_Thief_End - score +1 - goto AI_CV_Thief_End - -AI_CV_Thief_ScoreDown2: - score -2 - -AI_CV_Thief_End: - end - -AI_CV_Thief_EncourageItemsToSteal: - .byte HOLD_EFFECT_CURE_SLP - .byte HOLD_EFFECT_CURE_STATUS - .byte HOLD_EFFECT_RESTORE_HP - .byte HOLD_EFFECT_EVASION_UP - .byte HOLD_EFFECT_LEFTOVERS - .byte HOLD_EFFECT_LIGHT_BALL - .byte HOLD_EFFECT_THICK_CLUB - .byte -1 - -AI_CV_Curse: - if_type AI_USER, TYPE_GHOST, AI_CV_CurseGhost - if_stat_level_more_than AI_USER, STAT_DEF, 9, AI_CV_Curse2 - if_random_less_than 128, AI_CV_Curse2 - score +1 -AI_CV_Curse2: - if_stat_level_more_than AI_USER, STAT_ATK, 9, AI_CV_Curse3 - if_random_less_than 128, AI_CV_Curse3 - score +1 -AI_CV_Curse3: - if_stat_level_more_than AI_USER, STAT_DEF, 6, AI_CV_Curse4 - if_random_less_than 98, AI_CV_Curse4 - score +1 -AI_CV_Curse4: - if_stat_level_more_than AI_USER, STAT_ATK, 6, AI_CV_Curse5 - if_random_less_than 99, AI_CV_Curse5 - score +1 -AI_CV_Curse5: - get_hold_effect AI_USER - if_not_equal HOLD_EFFECT_RESTORE_STATS, AI_CV_Curse_End - score +2 - goto AI_CV_Curse_End -AI_CV_CurseGhost: - if_hp_more_than AI_USER, 80, AI_CV_Curse_End - score -1 -AI_CV_Curse_End: - end - -AI_CV_Protect: - get_protect_count AI_USER - if_more_than 1, AI_CV_Protect_ScoreDown2 - if_status AI_USER, STATUS1_PSN_ANY | STATUS1_BURN, AI_CV_ProtectUserStatused - if_status2 AI_USER, STATUS2_CURSED | STATUS2_INFATUATION, AI_CV_ProtectUserStatused - if_status3 AI_USER, STATUS3_PERISH_SONG | STATUS3_LEECHSEED | STATUS3_YAWN, AI_CV_ProtectUserStatused - if_has_move_with_effect AI_TARGET, EFFECT_RESTORE_HP, AI_CV_Protect3 - if_has_move_with_effect AI_TARGET, EFFECT_DEFENSE_CURL, AI_CV_Protect3 - if_status AI_TARGET, STATUS1_TOXIC_POISON, AI_CV_Protect_ScoreUp2 - if_status2 AI_TARGET, STATUS2_CURSED | STATUS2_INFATUATION, AI_CV_Protect_ScoreUp2 - if_status3 AI_TARGET, STATUS3_PERISH_SONG | STATUS3_LEECHSEED | STATUS3_YAWN, AI_CV_Protect_ScoreUp2 - get_last_used_bank_move AI_TARGET - get_move_effect_from_result - if_not_equal EFFECT_LOCK_ON, AI_CV_Protect_ScoreUp2 - goto AI_CV_Protect2 -AI_CV_Protect_ScoreUp2: - score +2 -AI_CV_Protect2: - if_random_less_than 128, AI_CV_Protect4 - score -1 -AI_CV_Protect4: - get_protect_count AI_USER - if_equal 0, AI_CV_Protect_End - score -1 - if_random_less_than 128, AI_CV_Protect_End - score -1 - goto AI_CV_Protect_End -AI_CV_ProtectUserStatused: - score -1 - if_double_battle AI_CV_Protect4 - score -1 - goto AI_CV_Protect4 -AI_CV_Protect3: - get_last_used_bank_move AI_TARGET - get_move_effect_from_result - if_not_equal EFFECT_LOCK_ON, AI_CV_Protect_End -AI_CV_Protect_ScoreDown2: - score -2 -AI_CV_Protect_End: - end - -AI_CV_Foresight: - if_has_move_with_type AI_USER, TYPE_NORMAL, AI_CV_ForesightGhost - if_has_move_with_type AI_USER, TYPE_FIGHTING, AI_CV_ForesightGhost - goto AI_CV_ForesightEvs -AI_CV_ForesightGhost: - if_type AI_USER, TYPE_GHOST, AI_CV_Foresight2 -AI_CV_ForesightEvs: - if_stat_level_more_than AI_USER, STAT_EVASION, 8, AI_CV_Foresight3 - score -3 - goto AI_CV_Foresight_End -AI_CV_Foresight2: - if_random_less_than 80, AI_CV_Foresight_End -AI_CV_Foresight3: - if_random_less_than 80, AI_CV_Foresight_End - score +2 -AI_CV_Foresight_End: - end - -AI_CV_Endure: - get_protect_count AI_USER - if_more_than 1, AI_CV_Endure2 - if_hp_less_than AI_USER, 8, AI_CV_Endure2 - if_hp_less_than AI_USER, 14, AI_CV_Endure4 - if_hp_less_than AI_USER, 35, AI_CV_Endure3 - if_doesnt_have_move_with_effect AI_USER, EFFECT_FLAIL, AI_CV_Endure2 - score +1 - goto AI_CV_Endure_End -AI_CV_Endure2: - score -3 - goto AI_CV_Endure_End -AI_CV_Endure4: - score -1 - goto AI_CV_Endure_End -AI_CV_Endure3: - if_has_move_with_effect AI_USER, EFFECT_FLAIL, Score_Plus2 - if_random_less_than 70, AI_CV_Endure_End - score +1 -AI_CV_Endure_End: - end - -AI_CV_BatonPass: - if_stat_level_more_than AI_USER, STAT_ATK, 8, AI_CV_BatonPass2 - if_stat_level_more_than AI_USER, STAT_DEF, 8, AI_CV_BatonPass2 - if_stat_level_more_than AI_USER, STAT_SPATK, 8, AI_CV_BatonPass2 - if_stat_level_more_than AI_USER, STAT_SPDEF, 8, AI_CV_BatonPass2 - if_stat_level_more_than AI_USER, STAT_EVASION, 8, AI_CV_BatonPass2 - goto AI_CV_BatonPass5 -AI_CV_BatonPass2: - if_target_faster AI_CV_BatonPass3 - if_hp_more_than AI_USER, 60, AI_CV_BatonPass_Last - goto AI_CV_BatonPass4 -AI_CV_BatonPass3: - if_hp_more_than AI_USER, 70, AI_CV_BatonPass_Last -AI_CV_BatonPass4: - if_random_less_than 80, AI_CV_BatonPass_Last - score +2 - goto AI_CV_BatonPass_Last -AI_CV_BatonPass5: - if_stat_level_more_than AI_USER, STAT_ATK, 7, AI_CV_BatonPass7 - if_stat_level_more_than AI_USER, STAT_DEF, 7, AI_CV_BatonPass7 - if_stat_level_more_than AI_USER, STAT_SPATK, 7, AI_CV_BatonPass7 - if_stat_level_more_than AI_USER, STAT_SPDEF, 7, AI_CV_BatonPass7 - if_stat_level_more_than AI_USER, STAT_EVASION, 7, AI_CV_BatonPass7 - goto AI_CV_BatonPass_ScoreDown2 -AI_CV_BatonPass7: - if_target_faster AI_CV_BatonPass8 - if_ai_can_go_down AI_CV_BatonPass4 - if_hp_more_than AI_USER, 60, AI_CV_BatonPass_ScoreDown2 - goto AI_CV_BatonPass_Last -AI_CV_BatonPass8: - if_ai_can_go_down AI_CV_BatonPass_ScoreDown2 - if_hp_less_than AI_USER, 70, AI_CV_BatonPass_Last - goto AI_CV_BatonPass_ScoreDown2 -AI_CV_BatonPass9: - if_stat_level_more_than AI_USER, STAT_ATK, 6, AI_CV_BatonPass10 - if_stat_level_more_than AI_USER, STAT_DEF, 6, AI_CV_BatonPass10 - if_stat_level_more_than AI_USER, STAT_SPATK, 6, AI_CV_BatonPass10 - if_stat_level_more_than AI_USER, STAT_SPDEF, 6, AI_CV_BatonPass10 - if_stat_level_more_than AI_USER, STAT_EVASION, 6, AI_CV_BatonPass10 - goto AI_CV_BatonPass_ScoreDown2 -AI_CV_BatonPass10: - if_target_faster AI_CV_BatonPass11 - if_ai_can_go_down AI_CV_BatonPass4 - if_hp_more_than AI_USER, 60, AI_CV_BatonPass_ScoreDown2 - goto AI_CV_BatonPass_Last -AI_CV_BatonPass11: - if_ai_can_go_down AI_CV_BatonPass_ScoreDown2 - if_hp_less_than AI_USER, 70, AI_CV_BatonPass_Last - goto AI_CV_BatonPass_ScoreDown2 -AI_CV_BatonPass_ScoreDown2: - score -2 - end -AI_CV_BatonPass_Last: - get_best_dmg_hp_percent - if_less_than 10, Score_Plus2 - if_less_than 20, Score_Plus1 -AI_CV_BatonPass_End: - end - -AI_CV_Pursuit: - is_first_turn_for AI_USER - if_not_equal 0, AI_CV_Pursuit_End - get_target_type1 - if_equal TYPE_GHOST, AI_CV_Pursuit2 - get_target_type1 - if_equal TYPE_PSYCHIC, AI_CV_Pursuit2 - get_target_type2 - if_equal TYPE_GHOST, AI_CV_Pursuit2 - get_target_type2 - if_equal TYPE_PSYCHIC, AI_CV_Pursuit2 - goto AI_CV_Pursuit_End - -AI_CV_Pursuit2: - if_random_less_than 128, AI_CV_Pursuit_End - score +1 - -AI_CV_Pursuit_End: - end - -AI_CV_RainDance: - get_weather - if_equal AI_WEATHER_RAIN, AI_CV_RainDance_End - if_user_faster AI_CV_RainDance2 - get_ability AI_USER - if_equal ABILITY_SWIFT_SWIM, AI_CV_RainDance3 - get_ability AI_USER_PARTNER - if_equal ABILITY_SWIFT_SWIM, AI_CV_RainDance3 -AI_CV_RainDance2: - if_hp_less_than AI_USER, 40, AI_CV_RainDance_ScoreDown1 - get_weather - if_equal AI_WEATHER_HAIL, AI_CV_RainDance3 - if_equal AI_WEATHER_SUN, AI_CV_RainDance3 - if_equal AI_WEATHER_SANDSTORM, AI_CV_RainDance3 - if_ability AI_USER, ABILITY_RAIN_DISH, AI_CV_RainDance3 - if_ability AI_USER_PARTNER, ABILITY_RAIN_DISH, AI_CV_RainDance3 - if_ability AI_USER, ABILITY_HYDRATION, AI_CV_Hydration - if_no_ability AI_USER_PARTNER, ABILITY_HYDRATION, AI_CV_RainDance_Rock -AI_CV_Hydration: - if_status AI_USER, STATUS1_ANY, AI_CV_RainDance3 - if_status AI_USER_PARTNER, STATUS1_ANY, AI_CV_RainDance3 - goto AI_CV_RainDance_Rock -AI_CV_RainDance3: - score +1 - goto AI_CV_RainDance_Rock -AI_CV_RainDance_ScoreDown1: - score -1 -AI_CV_RainDance_Rock: - get_hold_effect AI_USER - if_not_equal HOLD_EFFECT_DAMP_ROCK, AI_CV_RainDance_Opponent - score +2 -AI_CV_RainDance_Opponent: - if_has_move_with_type AI_TARGET, TYPE_FIRE, AI_CV_RainDance_OpponentPlus - if_no_type AI_TARGET, TYPE_FIRE, AI_CV_RainDance_End -AI_CV_RainDance_OpponentPlus: - score +1 -AI_CV_RainDance_End: - end - -AI_CV_SunnyDay: - get_weather - if_equal AI_WEATHER_SUN, AI_CV_SunnyDay_End - if_hp_less_than AI_USER, 40, AI_CV_SunnyDay_ScoreDown1 - get_weather - if_equal AI_WEATHER_HAIL, AI_CV_SunnyDay2 - if_equal AI_WEATHER_RAIN, AI_CV_SunnyDay2 - if_equal AI_WEATHER_SANDSTORM, AI_CV_SunnyDay2 - goto AI_CV_SunnyDay_Rock -AI_CV_SunnyDay2: - score +1 - goto AI_CV_SunnyDay_Rock -AI_CV_SunnyDay_ScoreDown1: - score -1 -AI_CV_SunnyDay_Rock: - get_hold_effect AI_USER - if_not_equal HOLD_EFFECT_HEAT_ROCK, AI_CV_SunnyDay_Moves - score +2 -AI_CV_SunnyDay_Moves: - if_has_move_with_effect AI_USER, EFFECT_SOLARBEAM, AI_CV_SunnyDay_MovesPlus - if_has_move_with_effect AI_USER, EFFECT_SYNTHESIS, AI_CV_SunnyDay_MovesPlus - if_has_move_with_effect AI_USER_PARTNER, EFFECT_SOLARBEAM, AI_CV_SunnyDay_MovesPlus - if_has_move_with_effect AI_USER_PARTNER, EFFECT_SYNTHESIS, AI_CV_SunnyDay_MovesPlus - if_has_move_with_type AI_USER, TYPE_FIRE, AI_CV_SunnyDay_MovesPlus - goto AI_CV_SunnyDay_Abilities -AI_CV_SunnyDay_MovesPlus: - score +1 -AI_CV_SunnyDay_Abilities: - if_user_faster AI_CV_SunnyDay_Abilities2 - if_ability AI_USER, ABILITY_CHLOROPHYLL, AI_CV_SunnyDay_AbilitiesPlus - get_ability AI_USER_PARTNER - if_not_equal ABILITY_CHLOROPHYLL, AI_CV_SunnyDay_Abilities2 -AI_CV_SunnyDay_AbilitiesPlus: - score +1 -AI_CV_SunnyDay_Abilities2: - if_ability AI_USER, ABILITY_LEAF_GUARD, AI_CV_SunnyDay_Abilities2Plus - get_ability AI_USER_PARTNER - if_not_equal ABILITY_LEAF_GUARD, AI_CV_SunnyDay_Opponent -AI_CV_SunnyDay_Abilities2Plus: - score + 1 -@ If target is fire type, giving him a sunny day boost may not be a good idea -AI_CV_SunnyDay_Opponent: - if_ability AI_USER, ABILITY_FLASH_FIRE, AI_CV_SunnyDay_Opponent2 - if_has_move_with_type AI_TARGET, TYPE_FIRE, AI_CV_SunnyDay_OpponentMinus - if_no_type AI_TARGET, TYPE_FIRE, AI_CV_SunnyDay_Opponent2 -AI_CV_SunnyDay_OpponentMinus: - score -1 -AI_CV_SunnyDay_Opponent2: - if_has_move_with_type AI_TARGET, TYPE_WATER, AI_CV_SunnyDay_Opponent2Plus - if_no_type AI_TARGET, TYPE_WATER, AI_CV_SunnyDay_End -AI_CV_SunnyDay_Opponent2Plus: - score +1 -AI_CV_SunnyDay_End: - end - -AI_CV_BellyDrum: - if_hp_less_than AI_USER, 90, AI_CV_BellyDrum_ScoreDown2 - goto AI_CV_BellyDrum_End - -AI_CV_BellyDrum_ScoreDown2: - score -2 - -AI_CV_BellyDrum_End: - end - -AI_CV_PsychUp: - if_stat_level_more_than AI_TARGET, STAT_ATK, 8, AI_CV_PsychUp2 - if_stat_level_more_than AI_TARGET, STAT_DEF, 8, AI_CV_PsychUp2 - if_stat_level_more_than AI_TARGET, STAT_SPATK, 8, AI_CV_PsychUp2 - if_stat_level_more_than AI_TARGET, STAT_SPDEF, 8, AI_CV_PsychUp2 - if_stat_level_more_than AI_TARGET, STAT_EVASION, 8, AI_CV_PsychUp2 - goto AI_CV_PsychUp_ScoreDown2 - -AI_CV_PsychUp2: - if_stat_level_less_than AI_USER, STAT_ATK, 7, AI_CV_PsychUp3 - if_stat_level_less_than AI_USER, STAT_DEF, 7, AI_CV_PsychUp3 - if_stat_level_less_than AI_USER, STAT_SPATK, 7, AI_CV_PsychUp3 - if_stat_level_less_than AI_USER, STAT_SPDEF, 7, AI_CV_PsychUp3 - if_stat_level_less_than AI_USER, STAT_EVASION, 7, AI_CV_PsychUp_ScoreUp1 - if_random_less_than 50, AI_CV_PsychUp_End - goto AI_CV_PsychUp_ScoreDown2 - -AI_CV_PsychUp_ScoreUp1: - score +1 - -AI_CV_PsychUp3: - score +1 - end - -AI_CV_PsychUp_ScoreDown2: - score -2 - -AI_CV_PsychUp_End: - end - -AI_CV_MirrorCoat: - if_status AI_TARGET, STATUS1_SLEEP, AI_CV_MirrorCoat_ScoreDown1 - if_status2 AI_TARGET, STATUS2_INFATUATION, AI_CV_MirrorCoat_ScoreDown1 - if_status2 AI_TARGET, STATUS2_CONFUSION, AI_CV_MirrorCoat_ScoreDown1 - if_hp_more_than AI_USER, 30, AI_CV_MirrorCoat2 - if_random_less_than 10, AI_CV_MirrorCoat2 - score -1 - -AI_CV_MirrorCoat2: - if_hp_more_than AI_USER, 50, AI_CV_MirrorCoat3 - if_random_less_than 100, AI_CV_MirrorCoat3 - score -1 - -AI_CV_MirrorCoat3: - if_has_move AI_USER, MOVE_COUNTER, AI_CV_MirrorCoat_ScoreUp4 - get_last_used_bank_move AI_TARGET - get_move_power_from_result - if_equal 0, AI_CV_MirrorCoat5 - if_target_not_taunted AI_CV_MirrorCoat4 - if_random_less_than 100, AI_CV_MirrorCoat4 - score +1 - -AI_CV_MirrorCoat4: - get_last_used_bank_move AI_TARGET - get_move_split_from_result - if_not_equal SPLIT_SPECIAL, AI_CV_MirrorCoat_ScoreDown1 - if_random_less_than 100, AI_CV_MirrorCoat_End - score +1 - goto AI_CV_MirrorCoat_End - -AI_CV_MirrorCoat5: - if_target_not_taunted AI_CV_MirrorCoat6 - if_random_less_than 100, AI_CV_MirrorCoat6 - score +1 - -AI_CV_MirrorCoat6: - if_has_no_special_move AI_TARGET, AI_CV_MirrorCoat_ScoreDown1 - if_random_less_than 50, AI_CV_MirrorCoat_End - -AI_CV_MirrorCoat_ScoreUp4: - if_random_less_than 100, AI_CV_MirrorCoat_ScoreUp4_End - score +4 - -AI_CV_MirrorCoat_ScoreUp4_End: - end - -AI_CV_MirrorCoat_ScoreDown1: - score -1 - -AI_CV_MirrorCoat_End: - end - -AI_CV_Geomancy: - get_hold_effect AI_USER - if_equal HOLD_EFFECT_POWER_HERB, AI_CV_ChargeUpMove_ScoreUp2 - end - -AI_CV_ChargeUpMove: - get_hold_effect AI_USER - if_equal HOLD_EFFECT_POWER_HERB, AI_CV_ChargeUpMove_ScoreUp2 - if_type_effectiveness AI_EFFECTIVENESS_x0_25, AI_CV_ChargeUpMove_ScoreDown2 - if_type_effectiveness AI_EFFECTIVENESS_x0_5, AI_CV_ChargeUpMove_ScoreDown2 - if_has_move_with_effect AI_TARGET, EFFECT_PROTECT, AI_CV_ChargeUpMove_ScoreDown2 - if_hp_more_than AI_USER, 38, AI_CV_ChargeUpMove_End - score -1 - goto AI_CV_ChargeUpMove_End - -AI_CV_ChargeUpMove_ScoreDown2: - score -2 - -AI_CV_ChargeUpMove_End: - end -AI_CV_ChargeUpMove_ScoreUp2: - score +2 - goto AI_CV_ChargeUpMove_End - -AI_CV_SemiInvulnerable: - get_hold_effect AI_USER - if_equal HOLD_EFFECT_POWER_HERB, AI_CV_ChargeUpMove_ScoreUp2 - if_doesnt_have_move_with_effect AI_TARGET, EFFECT_PROTECT, AI_CV_SemiInvulnerable2 - score -1 - goto AI_CV_SemiInvulnerable_End - -AI_CV_SemiInvulnerable2: - if_status AI_TARGET, STATUS1_TOXIC_POISON, AI_CV_SemiInvulnerable_TryEncourage - if_status2 AI_TARGET, STATUS2_CURSED, AI_CV_SemiInvulnerable_TryEncourage - if_status3 AI_TARGET, STATUS3_LEECHSEED, AI_CV_SemiInvulnerable_TryEncourage - get_weather - if_equal AI_WEATHER_HAIL, AI_CV_SemiInvulnerable_CheckIceType - if_equal AI_WEATHER_SANDSTORM, AI_CV_SemiInvulnerable_CheckSandstormTypes - goto AI_CV_SemiInvulnerable5 - -AI_CV_SemiInvulnerable_CheckSandstormTypes: - get_user_type1 - if_in_bytes AI_CV_SandstormResistantTypes, AI_CV_SemiInvulnerable_TryEncourage - get_user_type2 - if_in_bytes AI_CV_SandstormResistantTypes, AI_CV_SemiInvulnerable_TryEncourage - get_ability AI_USER - if_in_bytes AI_SandstormResistantAbilities, AI_CV_SemiInvulnerable_TryEncourage - goto AI_CV_SemiInvulnerable5 - -AI_CV_SemiInvulnerable_CheckIceType: - get_user_type1 - if_equal TYPE_ICE, AI_CV_SemiInvulnerable_TryEncourage - get_user_type2 - if_equal TYPE_ICE, AI_CV_SemiInvulnerable_TryEncourage - get_ability AI_USER - if_in_bytes AI_HailResistantAbilities, AI_CV_SemiInvulnerable_TryEncourage - -AI_CV_SemiInvulnerable5: - if_target_faster AI_CV_SemiInvulnerable_End - get_last_used_bank_move AI_TARGET - get_move_effect_from_result - if_not_equal EFFECT_LOCK_ON, AI_CV_SemiInvulnerable_TryEncourage - goto AI_CV_SemiInvulnerable_End - -AI_CV_SemiInvulnerable_TryEncourage: - if_random_less_than 80, AI_CV_SemiInvulnerable_End - score +1 - -AI_CV_SemiInvulnerable_End: - end - -AI_CV_SandstormResistantTypes: - .byte TYPE_GROUND - .byte TYPE_ROCK - .byte TYPE_STEEL - .byte -1 - -AI_SandstormResistantAbilities: - .byte ABILITY_SAND_VEIL - .byte ABILITY_SAND_FORCE - .byte ABILITY_SAND_RUSH - .byte ABILITY_OVERCOAT - .byte ABILITY_MAGIC_GUARD - .byte -1 - -AI_HailResistantAbilities: - .byte ABILITY_ICE_BODY - .byte ABILITY_SNOW_CLOAK - .byte ABILITY_OVERCOAT - .byte ABILITY_MAGIC_GUARD - .byte -1 - -AI_CV_FakeOut: - if_ability AI_TARGET, ABILITY_INNER_FOCUS, AI_CV_FakeOut_End - if_double_battle AI_CV_FakeOut_Double - score +5 - end -AI_CV_FakeOut_Double: - score +2 -AI_CV_FakeOut_End: - end - -AI_CV_SpitUp: - get_stockpile_count AI_USER - if_less_than 2, AI_CV_SpitUp_End - if_random_less_than 80, AI_CV_SpitUp_End - score +2 - -AI_CV_SpitUp_End: - end - -AI_CV_Hail: - if_hp_less_than AI_USER, 40, AI_CV_Hail_ScoreDown1 - get_weather - if_equal AI_WEATHER_SUN, AI_CV_Hail2 - if_equal AI_WEATHER_RAIN, AI_CV_Hail2 - if_equal AI_WEATHER_SANDSTORM, AI_CV_Hail2 - goto AI_CV_Hail_Rock -AI_CV_Hail2: - score +1 - goto AI_CV_Hail_Rock -AI_CV_Hail_ScoreDown1: - score -1 -AI_CV_Hail_Rock: - get_hold_effect AI_USER - if_not_equal HOLD_EFFECT_ICY_ROCK, AI_CV_Hail_Ability - score +2 -AI_CV_Hail_Ability: - get_ability AI_USER - if_equal ABILITY_ICE_BODY, AI_CV_Hail_AbilityPlus - if_equal ABILITY_SNOW_CLOAK, AI_CV_Hail_AbilityPlus - if_equal ABILITY_SLUSH_RUSH, AI_CV_Hail_AbilityPlus - if_not_equal ABILITY_FORECAST, AI_CV_Hail_Move -AI_CV_Hail_AbilityPlus: - score +1 -AI_CV_Hail_Move: - if_has_move AI_USER, MOVE_BLIZZARD, AI_CV_Hail_MovePlus - if_has_move AI_USER_PARTNER, MOVE_BLIZZARD, AI_CV_Hail_MovePlus - goto AI_CV_Hail_End -AI_CV_Hail_MovePlus: - score +1 -AI_CV_Hail_End: - end - -AI_CV_Sandstorm: - if_hp_less_than AI_USER, 40, AI_CV_Sandstorm_ScoreDown1 - get_weather - if_equal AI_WEATHER_SUN, AI_CV_Sandstorm2 - if_equal AI_WEATHER_RAIN, AI_CV_Sandstorm2 - if_equal AI_WEATHER_HAIL, AI_CV_Sandstorm2 - goto AI_CV_Sandstorm_End -AI_CV_Sandstorm2: - score +1 - goto AI_CV_Sandstorm_End -AI_CV_Sandstorm_ScoreDown1: - score -1 -AI_CV_Sandstorm_Rock: - get_hold_effect AI_USER - if_not_equal HOLD_EFFECT_SMOOTH_ROCK, AI_CV_Sandstorm_Ability - score +2 -AI_CV_Sandstorm_Ability: - get_ability AI_USER - if_equal ABILITY_SAND_VEIL, AI_CV_Sandstorm_AbilityPlus - if_equal ABILITY_SAND_RUSH, AI_CV_Sandstorm_AbilityPlus - if_not_equal ABILITY_SAND_VEIL, AI_CV_Sandstorm_End -AI_CV_Sandstorm_AbilityPlus: - score +1, -AI_CV_Sandstorm_End: - end - -AI_CV_Facade: - if_not_status AI_USER, STATUS1_POISON | STATUS1_BURN | STATUS1_PARALYSIS | STATUS1_TOXIC_POISON, AI_CV_Facade_End - score +1 -AI_CV_Facade_End: - end - -AI_CV_FocusPunch: - if_type_effectiveness AI_EFFECTIVENESS_x0_25, AI_CV_FocusPunch2 - if_type_effectiveness AI_EFFECTIVENESS_x0_5, AI_CV_FocusPunch2 - if_status AI_TARGET, STATUS1_SLEEP, AI_CV_FocusPunch_ScoreUp1 - if_status2 AI_TARGET, STATUS2_INFATUATION, AI_CV_FocusPunch3 - if_status2 AI_TARGET, STATUS2_CONFUSION, AI_CV_FocusPunch3 - is_first_turn_for AI_USER - if_not_equal 0, AI_CV_FocusPunch_End - if_random_less_than 100, AI_CV_FocusPunch_End - score +1 - goto AI_CV_FocusPunch_End - -AI_CV_FocusPunch2: - score -1 - goto AI_CV_FocusPunch_End - -AI_CV_FocusPunch3: - if_random_less_than 100, AI_CV_FocusPunch_End - if_status2 AI_USER, STATUS2_SUBSTITUTE, Score_Plus5 - -AI_CV_FocusPunch_ScoreUp1: - score +1 - -AI_CV_FocusPunch_End: - end - -AI_CV_SmellingSalt: - if_status AI_TARGET, STATUS1_PARALYSIS, AI_CV_SmellingSalt_ScoreUp1 - goto AI_CV_SmellingSalt_End - -AI_CV_SmellingSalt_ScoreUp1: - score +1 - -AI_CV_SmellingSalt_End: - end - -AI_CV_Trick: - get_hold_effect AI_USER - if_in_bytes AI_CV_Trick_EffectsToEncourage2, AI_CV_Trick3 - if_in_bytes AI_CV_Trick_EffectsToEncourage, AI_CV_Trick4 - -AI_CV_Trick2: - score -3 - goto AI_CV_Trick_End - -AI_CV_Trick3: - get_hold_effect AI_TARGET - if_in_bytes AI_CV_Trick_EffectsToEncourage2, AI_CV_Trick2 - score +5 - goto AI_CV_Trick_End - -AI_CV_Trick4: - get_hold_effect AI_TARGET - if_in_bytes AI_CV_Trick_EffectsToEncourage, AI_CV_Trick2 - if_random_less_than 50, AI_CV_Trick_End - score +2 - -AI_CV_Trick_End: - end - -AI_CV_Trick_EffectsToEncourage: - .byte HOLD_EFFECT_CONFUSE_SPICY - .byte HOLD_EFFECT_CONFUSE_DRY - .byte HOLD_EFFECT_CONFUSE_SWEET - .byte HOLD_EFFECT_CONFUSE_BITTER - .byte HOLD_EFFECT_CONFUSE_SOUR - .byte HOLD_EFFECT_MACHO_BRACE - .byte HOLD_EFFECT_CHOICE_BAND - .byte -1 - -AI_CV_Trick_EffectsToEncourage2: - .byte HOLD_EFFECT_CHOICE_BAND - .byte -1 - -AI_CV_ChangeSelfAbility: - get_ability AI_USER - if_in_bytes AI_CV_ChangeSelfAbility_AbilitiesToEncourage, AI_CV_ChangeSelfAbility2 - get_ability AI_TARGET - if_in_bytes AI_CV_ChangeSelfAbility_AbilitiesToEncourage, AI_CV_ChangeSelfAbility3 - -AI_CV_ChangeSelfAbility2: - score -1 - goto AI_CV_ChangeSelfAbility_End - -AI_CV_ChangeSelfAbility3: - if_random_less_than 50, AI_CV_ChangeSelfAbility_End - score +2 - -AI_CV_ChangeSelfAbility_End: - end - -AI_CV_ChangeSelfAbility_AbilitiesToEncourage: - .byte ABILITY_SPEED_BOOST - .byte ABILITY_BATTLE_ARMOR - .byte ABILITY_SAND_VEIL - .byte ABILITY_STATIC - .byte ABILITY_FLASH_FIRE - .byte ABILITY_WONDER_GUARD - .byte ABILITY_EFFECT_SPORE - .byte ABILITY_SWIFT_SWIM - .byte ABILITY_HUGE_POWER - .byte ABILITY_RAIN_DISH - .byte ABILITY_CUTE_CHARM - .byte ABILITY_SHED_SKIN - .byte ABILITY_MARVEL_SCALE - .byte ABILITY_PURE_POWER - .byte ABILITY_CHLOROPHYLL - .byte ABILITY_SHIELD_DUST - .byte -1 - -AI_CV_Superpower: - if_type_effectiveness AI_EFFECTIVENESS_x0_25, AI_CV_Superpower_ScoreDown1 - if_type_effectiveness AI_EFFECTIVENESS_x0_5, AI_CV_Superpower_ScoreDown1 - if_stat_level_less_than AI_USER, STAT_ATK, DEFAULT_STAT_STAGE, AI_CV_Superpower_ScoreDown1 - if_target_faster AI_CV_Superpower2 - if_hp_more_than AI_USER, 40, AI_CV_Superpower_ScoreDown1 - goto AI_CV_Superpower_End - -AI_CV_Superpower2: - if_hp_less_than AI_USER, 60, AI_CV_Superpower_End - -AI_CV_Superpower_ScoreDown1: - score -1 - -AI_CV_Superpower_End: - end - -AI_CV_MagicCoat: - if_hp_more_than AI_TARGET, 30, AI_CV_MagicCoat2 - if_random_less_than 100, AI_CV_MagicCoat2 - score -1 - -AI_CV_MagicCoat2: - is_first_turn_for AI_USER - if_equal 0, AI_CV_MagicCoat4 - if_random_less_than 150, AI_CV_MagicCoat_End - score +1 - goto AI_CV_MagicCoat_End - -AI_CV_MagicCoat3: - if_random_less_than 50, AI_CV_MagicCoat_End - -AI_CV_MagicCoat4: - if_random_less_than 30, AI_CV_MagicCoat_End - score -1 - -AI_CV_MagicCoat_End: - end - -AI_CV_Recycle: - get_used_held_item AI_USER - if_not_in_bytes AI_CV_Recycle_ItemsToEncourage, AI_CV_Recycle_ScoreDown2 - if_random_less_than 50, AI_CV_Recycle_End - score +1 - goto AI_CV_Recycle_End - -AI_CV_Recycle_ScoreDown2: - score -2 - -AI_CV_Recycle_End: - end - -AI_CV_Recycle_ItemsToEncourage: - .byte ITEM_CHESTO_BERRY - .byte ITEM_LUM_BERRY - .byte ITEM_STARF_BERRY - .byte -1 - -AI_CV_Revenge: - if_status AI_TARGET, STATUS1_SLEEP, AI_CV_Revenge_ScoreDown2 - if_status2 AI_TARGET, STATUS2_INFATUATION, AI_CV_Revenge_ScoreDown2 - if_status2 AI_TARGET, STATUS2_CONFUSION, AI_CV_Revenge_ScoreDown2 - if_random_less_than 180, AI_CV_Revenge_ScoreDown2 - score +2 - goto AI_CV_Revenge_End - -AI_CV_Revenge_ScoreDown2: - score -2 - -AI_CV_Revenge_End: - end - -AI_CV_BrickBreak: - if_side_affecting AI_TARGET, SIDE_STATUS_REFLECT, AI_CV_BrickBreak_ScoreUp1 - goto AI_CV_BrickBreak_End - -AI_CV_BrickBreak_ScoreUp1: - score +1 - -AI_CV_BrickBreak_End: - end - -AI_CV_KnockOff: - if_hp_less_than AI_TARGET, 30, AI_CV_KnockOff_End - is_first_turn_for AI_USER - if_more_than 0, AI_CV_KnockOff_End - if_random_less_than 180, AI_CV_KnockOff_End - score +1 - -AI_CV_KnockOff_End: - end - -AI_CV_Endeavor: - if_hp_less_than AI_TARGET, 70, AI_CV_Endeavor_ScoreDown1 - if_target_faster AI_CV_Endeavor2 - if_hp_more_than AI_USER, 40, AI_CV_Endeavor_ScoreDown1 - score +1 - goto AI_CV_Endeavor_End - -AI_CV_Endeavor2: - if_hp_more_than AI_USER, 50, AI_CV_Endeavor_ScoreDown1 - score +1 - goto AI_CV_Endeavor_End - -AI_CV_Endeavor_ScoreDown1: - score -1 - -AI_CV_Endeavor_End: - end - -AI_CV_Eruption: - if_type_effectiveness AI_EFFECTIVENESS_x0_25, AI_CV_Eruption_ScoreDown1 - if_type_effectiveness AI_EFFECTIVENESS_x0_5, AI_CV_Eruption_ScoreDown1 - if_target_faster AI_CV_Eruption2 - if_hp_more_than AI_TARGET, 50, AI_CV_Eruption_End - goto AI_CV_Eruption_ScoreDown1 - -AI_CV_Eruption2: - if_hp_more_than AI_TARGET, 70, AI_CV_Eruption_End - -AI_CV_Eruption_ScoreDown1: - score -1 - -AI_CV_Eruption_End: - end - -AI_CV_Imprison: - is_first_turn_for AI_USER - if_more_than 0, AI_CV_Imprison_End - if_random_less_than 100, AI_CV_Imprison_End - score +2 - -AI_CV_Imprison_End: - end - -AI_CV_Refresh: - if_hp_less_than AI_TARGET, 50, AI_CV_Refresh_ScoreDown1 - goto AI_CV_Refresh_End - -AI_CV_Refresh_ScoreDown1: - score -1 - -AI_CV_Refresh_End: - end - -AI_CV_Snatch: - is_first_turn_for AI_USER - if_equal 1, AI_CV_Snatch3 - if_random_less_than 30, AI_CV_Snatch_End - if_target_faster AI_CV_Snatch2 - if_hp_not_equal AI_USER, 100, AI_CV_Snatch5 - if_hp_less_than AI_TARGET, 70, AI_CV_Snatch5 - if_random_less_than 60, AI_CV_Snatch_End - goto AI_CV_Snatch5 - -AI_CV_Snatch2: - if_hp_more_than AI_TARGET, 25, AI_CV_Snatch5 - if_has_move_with_effect AI_TARGET, EFFECT_RESTORE_HP, AI_CV_Snatch3 - if_has_move_with_effect AI_TARGET, EFFECT_DEFENSE_CURL, AI_CV_Snatch3 - goto AI_CV_Snatch4 - -AI_CV_Snatch3: - if_random_less_than 150, AI_CV_Snatch_End - score +2 - goto AI_CV_Snatch_End - -AI_CV_Snatch4: - if_random_less_than 230, AI_CV_Snatch5 - score +1 - goto AI_CV_Snatch_End - -AI_CV_Snatch5: - if_random_less_than 30, AI_CV_Snatch_End - score -2 - -AI_CV_Snatch_End: - end - -AI_CV_MudSport: - if_hp_less_than AI_USER, 50, AI_CV_MudSport_ScoreDown1 - get_target_type1 - if_equal TYPE_ELECTRIC, AI_CV_MudSport2 - get_target_type2 - if_equal TYPE_ELECTRIC, AI_CV_MudSport2 - goto AI_CV_MudSport_ScoreDown1 - -AI_CV_MudSport2: - score +1 - goto AI_CV_MudSport_End - -AI_CV_MudSport_ScoreDown1: - score -1 - -AI_CV_MudSport_End: - end - -AI_CV_Overheat: - if_type_effectiveness AI_EFFECTIVENESS_x0_25, AI_CV_Overheat_ScoreDown1 - if_type_effectiveness AI_EFFECTIVENESS_x0_5, AI_CV_Overheat_ScoreDown1 - if_target_faster AI_CV_Overheat2 - if_hp_more_than AI_USER, 60, AI_CV_Overheat_End - goto AI_CV_Overheat_ScoreDown1 - -AI_CV_Overheat2: - if_hp_more_than AI_USER, 80, AI_CV_Overheat_End - -AI_CV_Overheat_ScoreDown1: - score -1 - -AI_CV_Overheat_End: - end - -AI_CV_WaterSport: - if_hp_less_than AI_USER, 50, AI_CV_WaterSport_ScoreDown1 - get_target_type1 - if_equal TYPE_FIRE, AI_CV_WaterSport2 - get_target_type2 - if_equal TYPE_FIRE, AI_CV_WaterSport2 - goto AI_CV_WaterSport_ScoreDown1 - -AI_CV_WaterSport2: - score +1 - goto AI_CV_WaterSport_End - -AI_CV_WaterSport_ScoreDown1: - score -1 - -AI_CV_WaterSport_End: - end - -AI_CV_DragonDance: - if_target_faster AI_CV_DragonDance2 - if_hp_more_than AI_USER, 50, AI_CV_DragonDance_End - if_random_less_than 70, AI_CV_DragonDance_End - score -1 - goto AI_CV_DragonDance_End - -AI_CV_DragonDance2: - if_random_less_than 128, AI_CV_DragonDance_End - score +1 - -AI_CV_DragonDance_End: - end - -AI_TryToFaint: - if_target_is_ally AI_Ret - if_can_faint AI_TryToFaint_Can - get_how_powerful_move_is - if_equal MOVE_POWER_DISCOURAGED, Score_Minus1 -AI_TryToFaint2: - if_type_effectiveness AI_EFFECTIVENESS_x4, AI_TryToFaint_DoubleSuperEffective - goto AI_TryToFaint_CheckIfDanger -AI_TryToFaint_DoubleSuperEffective: - if_random_less_than 80, AI_TryToFaint_CheckIfDanger - score +2 - goto AI_TryToFaint_CheckIfDanger -AI_TryToFaint_Can: - if_effect EFFECT_EXPLOSION, AI_TryToFaint_CheckIfDanger - if_user_faster AI_TryToFaint_ScoreUp4 - if_move_flag FLAG_HIGH_CRIT, AI_TryToFaint_ScoreUp4 - score +2 - goto AI_TryToFaint_CheckIfDanger -AI_TryToFaint_ScoreUp4: - score +4 -AI_TryToFaint_CheckIfDanger: - if_user_faster AI_TryToFaint_End - if_ai_can_go_down AI_TryToFaint_Danger -AI_TryToFaint_End: - end -AI_TryToFaint_Danger: - get_how_powerful_move_is - if_not_equal MOVE_POWER_BEST, Score_Minus1 - score +1 - goto AI_TryToFaint_End - -AI_SetupFirstTurn: - if_target_is_ally AI_Ret - get_turn_count - if_not_equal 0, AI_SetupFirstTurn_End - get_considered_move_effect - if_not_in_hwords AI_SetupFirstTurn_SetupEffectsToEncourage, AI_SetupFirstTurn_End - score +2 -AI_SetupFirstTurn_End: - end - -.align 1 -AI_SetupFirstTurn_SetupEffectsToEncourage: - .2byte EFFECT_ATTACK_UP - .2byte EFFECT_DEFENSE_UP - .2byte EFFECT_SPEED_UP - .2byte EFFECT_SPECIAL_ATTACK_UP - .2byte EFFECT_SPECIAL_DEFENSE_UP - .2byte EFFECT_ACCURACY_UP - .2byte EFFECT_EVASION_UP - .2byte EFFECT_ATTACK_DOWN - .2byte EFFECT_DEFENSE_DOWN - .2byte EFFECT_SPEED_DOWN - .2byte EFFECT_SPECIAL_ATTACK_DOWN - .2byte EFFECT_SPECIAL_DEFENSE_DOWN - .2byte EFFECT_ACCURACY_DOWN - .2byte EFFECT_EVASION_DOWN - .2byte EFFECT_CONVERSION - .2byte EFFECT_LIGHT_SCREEN - .2byte EFFECT_SPECIAL_DEFENSE_UP_2 - .2byte EFFECT_FOCUS_ENERGY - .2byte EFFECT_CONFUSE - .2byte EFFECT_ATTACK_UP_2 - .2byte EFFECT_DEFENSE_UP_2 - .2byte EFFECT_SPEED_UP_2 - .2byte EFFECT_SPECIAL_ATTACK_UP_2 - .2byte EFFECT_SPECIAL_DEFENSE_UP_2 - .2byte EFFECT_ACCURACY_UP_2 - .2byte EFFECT_EVASION_UP_2 - .2byte EFFECT_ATTACK_DOWN_2 - .2byte EFFECT_DEFENSE_DOWN_2 - .2byte EFFECT_SPEED_DOWN_2 - .2byte EFFECT_SPECIAL_ATTACK_DOWN_2 - .2byte EFFECT_SPECIAL_DEFENSE_DOWN_2 - .2byte EFFECT_ACCURACY_DOWN_2 - .2byte EFFECT_EVASION_DOWN_2 - .2byte EFFECT_REFLECT - .2byte EFFECT_POISON - .2byte EFFECT_PARALYZE - .2byte EFFECT_SUBSTITUTE - .2byte EFFECT_LEECH_SEED - .2byte EFFECT_MINIMIZE - .2byte EFFECT_CURSE - .2byte EFFECT_SWAGGER - .2byte EFFECT_CAMOUFLAGE - .2byte EFFECT_YAWN - .2byte EFFECT_DEFENSE_CURL - .2byte EFFECT_TORMENT - .2byte EFFECT_FLATTER - .2byte EFFECT_WILL_O_WISP - .2byte EFFECT_INGRAIN - .2byte EFFECT_IMPRISON - .2byte EFFECT_TEETER_DANCE - .2byte EFFECT_TICKLE - .2byte EFFECT_COSMIC_POWER - .2byte EFFECT_BULK_UP - .2byte EFFECT_CALM_MIND - .2byte EFFECT_ACUPRESSURE - .2byte EFFECT_AUTOTOMIZE - .2byte EFFECT_SHIFT_GEAR - .2byte EFFECT_SHELL_SMASH - .2byte EFFECT_GROWTH - .2byte EFFECT_QUIVER_DANCE - .2byte EFFECT_ATTACK_SPATK_UP - .2byte EFFECT_ATTACK_ACCURACY_UP - .2byte EFFECT_PSYCHIC_TERRAIN - .2byte EFFECT_GRASSY_TERRAIN - .2byte EFFECT_ELECTRIC_TERRAIN - .2byte EFFECT_MISTY_TERRAIN - .2byte EFFECT_STEALTH_ROCK - .2byte EFFECT_TOXIC_SPIKES - .2byte EFFECT_TRICK_ROOM - .2byte EFFECT_WONDER_ROOM - .2byte EFFECT_MAGIC_ROOM - .2byte EFFECT_TAILWIND - .2byte EFFECT_DRAGON_DANCE - .2byte EFFECT_STICKY_WEB - .2byte EFFECT_RAIN_DANCE - .2byte EFFECT_SUNNY_DAY - .2byte EFFECT_SANDSTORM - .2byte EFFECT_HAIL - .2byte EFFECT_GEOMANCY - .2byte -1 - -AI_PreferStrongestMove: - if_target_is_ally AI_Ret - get_how_powerful_move_is - if_not_equal MOVE_POWER_BEST, AI_PreferStrongestMove_End - if_random_less_than 100, AI_PreferStrongestMove_End - score +2 -AI_PreferStrongestMove_End: - end - -AI_Risky: - if_target_is_ally AI_Ret - get_considered_move_effect - if_move_flag FLAG_HIGH_CRIT, AI_Risky_RandChance - if_not_in_bytes AI_Risky_EffectsToEncourage, AI_Risky_End -AI_Risky_RandChance: - if_random_less_than 128, AI_Risky_End - score +2 -AI_Risky_End: - end - -AI_Risky_EffectsToEncourage: - .byte EFFECT_SLEEP - .byte EFFECT_EXPLOSION - .byte EFFECT_MIRROR_MOVE - .byte EFFECT_OHKO - .byte EFFECT_CONFUSE - .byte EFFECT_METRONOME - .byte EFFECT_PSYWAVE - .byte EFFECT_COUNTER - .byte EFFECT_DESTINY_BOND - .byte EFFECT_SWAGGER - .byte EFFECT_ATTRACT - .byte EFFECT_PRESENT - .byte EFFECT_ALL_STATS_UP_HIT - .byte EFFECT_BELLY_DRUM - .byte EFFECT_MIRROR_COAT - .byte EFFECT_FOCUS_PUNCH - .byte EFFECT_REVENGE - .byte EFFECT_TEETER_DANCE - .byte -1 - -.align 1 -sMovesTable_ProtectMoves: - .2byte MOVE_PROTECT - .2byte MOVE_DETECT - .2byte -1 - -.align 1 -sEffectsStatRaise: - .2byte EFFECT_ATTACK_UP - .2byte EFFECT_ATTACK_UP_2 - .2byte EFFECT_DEFENSE_UP - .2byte EFFECT_DEFENSE_UP_2 - .2byte EFFECT_SPEED_UP - .2byte EFFECT_SPEED_UP_2 - .2byte EFFECT_SPECIAL_ATTACK_UP - .2byte EFFECT_SPECIAL_ATTACK_UP_2 - .2byte EFFECT_SPECIAL_DEFENSE_UP - .2byte EFFECT_SPECIAL_DEFENSE_UP_2 - .2byte EFFECT_CALM_MIND - .2byte EFFECT_DRAGON_DANCE - .2byte EFFECT_ACUPRESSURE - .2byte EFFECT_SHELL_SMASH - .2byte EFFECT_SHIFT_GEAR - .2byte EFFECT_ATTACK_ACCURACY_UP - .2byte EFFECT_ATTACK_SPATK_UP - .2byte EFFECT_GROWTH - .2byte EFFECT_COIL - .2byte EFFECT_QUIVER_DANCE - .2byte -1 - -AI_PreferBatonPass: - if_target_is_ally AI_Ret - count_usable_party_mons AI_USER - if_equal 0, AI_PreferBatonPassEnd - get_how_powerful_move_is - if_not_equal MOVE_POWER_DISCOURAGED, AI_PreferBatonPassEnd - if_doesnt_have_move_with_effect AI_USER, EFFECT_BATON_PASS, AI_PreferBatonPassEnd - get_considered_move_effect - if_in_hwords sEffectsStatRaise, AI_PreferBatonPass2 - if_effect EFFECT_PROTECT, AI_PreferBatonPass3 - if_move MOVE_BATON_PASS, AI_PreferBatonPass_EncourageIfHighStats - end -AI_PreferBatonPass2: - get_turn_count - if_equal 0, Score_Plus5 - if_hp_less_than AI_USER, 60, Score_Minus10 - goto Score_Plus1 -AI_PreferBatonPass3: - get_last_used_bank_move AI_USER - if_in_hwords sMovesTable_ProtectMoves, Score_Minus2 - score +2 - end -AI_PreferBatonPass_EncourageIfHighStats: - get_turn_count - if_equal 0, Score_Minus2 - if_stat_level_more_than AI_USER, STAT_ATK, DEFAULT_STAT_STAGE + 2, Score_Plus3 - if_stat_level_more_than AI_USER, STAT_ATK, DEFAULT_STAT_STAGE + 1, Score_Plus2 - if_stat_level_more_than AI_USER, STAT_ATK, DEFAULT_STAT_STAGE, Score_Plus1 - if_stat_level_more_than AI_USER, STAT_SPATK, DEFAULT_STAT_STAGE + 2, Score_Plus3 - if_stat_level_more_than AI_USER, STAT_SPATK, DEFAULT_STAT_STAGE + 1, Score_Plus2 - if_stat_level_more_than AI_USER, STAT_SPATK, DEFAULT_STAT_STAGE, Score_Plus1 - end -AI_PreferBatonPassEnd: - end - -AI_ConsiderAllyChosenMove: - get_ally_chosen_move - if_equal 0, AI_ConsiderAllyChosenMoveRet - get_move_effect_from_result - if_equal EFFECT_HELPING_HAND, AI_PartnerChoseHelpingHand - if_equal EFFECT_PERISH_SONG, AI_PartnerChosePerishSong - if_equal EFFECT_ALWAYS_CRIT, AI_PartnerChoseAlwaysCrit -AI_ConsiderAllyChosenMoveRet: - end - -@ Ally decided to use Frost Breath on us. we must have Anger Point as our ability -AI_PartnerChoseAlwaysCrit: - if_no_ability AI_USER, ABILITY_ANGER_POINT, AI_PartnerChoseAlwaysCritEnd - @frost breath user should be faster - compare_speeds AI_USER, AI_USER_PARTNER - if_not_equal 1, AI_PartnerChoseAlwaysCritEnd - get_considered_move_effect - if_in_hwords sEffectsAtkRaise, Score_Minus3 - @encourage moves hitting multiple opponents - get_considered_move_power - if_equal 0, AI_PartnerChoseAlwaysCritEnd - get_considered_move_target - if_equal MOVE_TARGET_BOTH, Score_Plus3 - if_equal MOVE_TARGET_FOES_AND_ALLY, Score_Plus3 -AI_PartnerChoseAlwaysCritEnd: - end - -.align 1 -sEffectsAtkRaise: - .2byte EFFECT_ATTACK_ACCURACY_UP - .2byte EFFECT_ATTACK_UP - .2byte EFFECT_ATTACK_UP_2 - .2byte EFFECT_DRAGON_DANCE - .2byte EFFECT_COIL - .2byte EFFECT_BELLY_DRUM - .2byte EFFECT_BULK_UP - .2byte -1 - -AI_PartnerChoseHelpingHand: - @ Do not use a status move if you know your move's power will be boosted - get_considered_move_power - if_equal 0, Score_Minus5 - end - -AI_PartnerChosePerishSong: - if_status2 AI_TARGET, STATUS2_ESCAPE_PREVENTION | STATUS2_WRAPPED, AI_Ret - get_considered_move_effect - if_equal EFFECT_MEAN_LOOK, Score_Plus1 - if_equal EFFECT_TRAP, Score_Plus1 - end - -AI_ConsiderAllyKnownMoves: - @ If ally already chose a move, there is nothing to do here. - get_ally_chosen_move - if_not_equal 0, AI_Ret - if_move MOVE_HELPING_HAND, AI_HelpingHandInDoubles - if_move MOVE_PERISH_SONG, AI_PerishSongInDoubles - end - -AI_HelpingHandInDoubles: - if_has_no_attacking_moves AI_USER_PARTNER, Score_Minus5 - end - -AI_PerishSongInDoubles: - if_has_move_with_effect AI_USER_PARTNER, EFFECT_MEAN_LOOK, Score_Plus1 - if_has_move_with_effect AI_USER_PARTNER, EFFECT_TRAP, Score_Plus1 - end - -AI_DoubleBattle: - call AI_ConsiderAllyChosenMove - call AI_ConsiderAllyKnownMoves - if_target_is_ally AI_TryOnAlly - if_move MOVE_SKILL_SWAP, AI_DoubleBattleSkillSwap - get_curr_move_type - if_move MOVE_EARTHQUAKE, AI_DoubleBattleAllHittingGroundMove - if_move MOVE_MAGNITUDE, AI_DoubleBattleAllHittingGroundMove - if_equal TYPE_ELECTRIC, AI_DoubleBattleElectricMove - if_equal TYPE_FIRE, AI_DoubleBattleFireMove - get_ability AI_USER - if_not_equal ABILITY_GUTS, AI_DoubleBattleCheckUserStatus - if_has_move AI_USER_PARTNER, MOVE_HELPING_HAND, AI_DoubleBattlePartnerHasHelpingHand - end - -AI_DoubleBattlePartnerHasHelpingHand: - get_how_powerful_move_is - if_not_equal MOVE_POWER_DISCOURAGED, Score_Plus1 - end - -AI_DoubleBattleCheckUserStatus: - if_status AI_USER, STATUS1_ANY, AI_DoubleBattleCheckUserStatus2 - end - -AI_DoubleBattleCheckUserStatus2: - get_how_powerful_move_is - if_equal MOVE_POWER_DISCOURAGED, Score_Minus5 - score +1 - if_equal MOVE_POWER_BEST, Score_Plus2 - end - -AI_DoubleBattleAllHittingGroundMove: - if_ability AI_USER_PARTNER, ABILITY_LEVITATE, Score_Plus2 - if_type AI_USER_PARTNER, TYPE_FLYING, Score_Plus2 - if_type AI_USER_PARTNER, TYPE_FIRE, Score_Minus10 - if_type AI_USER_PARTNER, TYPE_ELECTRIC, Score_Minus10 - if_type AI_USER_PARTNER, TYPE_POISON, Score_Minus10 - if_type AI_USER_PARTNER, TYPE_ROCK, Score_Minus10 - goto Score_Minus3 - -AI_DoubleBattleSkillSwap: - get_ability AI_USER - if_equal ABILITY_TRUANT, Score_Plus5 - get_ability AI_TARGET - if_equal ABILITY_SHADOW_TAG, Score_Plus2 - if_equal ABILITY_PURE_POWER, Score_Plus2 - end - -AI_DoubleBattleElectricMove: - if_no_ability AI_TARGET_PARTNER, ABILITY_LIGHTNING_ROD, AI_DoubleBattleElectricMoveEnd - score -2 - if_no_type AI_TARGET_PARTNER, TYPE_GROUND, AI_DoubleBattleElectricMoveEnd - score -8 - -AI_DoubleBattleElectricMoveEnd: - end - -AI_DoubleBattleFireMove: - if_flash_fired AI_USER, AI_DoubleBattleFireMove2 - end - -AI_DoubleBattleFireMove2: - goto Score_Plus1 - -AI_TryOnAlly: - get_how_powerful_move_is - if_equal MOVE_POWER_DISCOURAGED, AI_TryStatusMoveOnAlly - get_curr_move_type - if_equal TYPE_FIRE, AI_TryFireMoveOnAlly - if_effect EFFECT_ALWAYS_CRIT, AI_TryCritAngerPointAlly -AI_DiscourageOnAlly: - goto Score_Minus30 - -AI_TryFireMoveOnAlly: - if_ability AI_USER_PARTNER, ABILITY_FLASH_FIRE, AI_TryFireMoveOnAlly_FlashFire - goto AI_DiscourageOnAlly -AI_TryFireMoveOnAlly_FlashFire: - if_flash_fired AI_USER_PARTNER, AI_DiscourageOnAlly - goto Score_Plus3 - -AI_TryCritAngerPointAlly: - get_ability AI_USER_PARTNER - if_not_equal ABILITY_ANGER_POINT, AI_DiscourageOnAlly - if_stat_level_more_than AI_USER_PARTNER, STAT_ATK, 8, AI_DiscourageOnAlly - if_status2 AI_USER_PARTNER, STATUS2_SUBSTITUTE, AI_DiscourageOnAlly - if_has_no_move_with_split AI_USER_PARTNER, SPLIT_PHYSICAL, AI_DiscourageOnAlly - get_curr_dmg_hp_percent - if_more_than 34,AI_DiscourageOnAlly - if_hp_less_than AI_USER_PARTNER, 60, AI_DiscourageOnAlly - goto Score_Plus3 - -AI_TryStatusMoveOnAlly: - if_move MOVE_SKILL_SWAP, AI_TrySkillSwapOnAlly - if_move MOVE_WILL_O_WISP, AI_TryStatusOnAlly - if_move MOVE_TOXIC, AI_TryStatusOnAlly - if_move MOVE_HELPING_HAND, AI_TryHelpingHandOnAlly - if_move MOVE_SWAGGER, AI_TrySwaggerOnAlly - goto Score_Minus30 - -AI_TrySkillSwapOnAlly: - get_ability AI_TARGET - if_equal ABILITY_TRUANT, Score_Plus10 - get_ability AI_USER - if_not_equal ABILITY_LEVITATE, AI_TrySkillSwapOnAlly2 - get_ability AI_TARGET - if_equal ABILITY_LEVITATE, Score_Minus30 - get_target_type1 - if_not_equal TYPE_ELECTRIC, AI_TrySkillSwapOnAlly2 - score +1 - get_target_type2 - if_not_equal TYPE_ELECTRIC, AI_TrySkillSwapOnAlly2 - score +1 - end - -AI_TrySkillSwapOnAlly2: - if_not_equal ABILITY_COMPOUND_EYES, Score_Minus30 - if_has_move AI_USER_PARTNER, MOVE_FIRE_BLAST, AI_TrySkillSwapOnAllyPlus3 - if_has_move AI_USER_PARTNER, MOVE_THUNDER, AI_TrySkillSwapOnAllyPlus3 - if_has_move AI_USER_PARTNER, MOVE_CROSS_CHOP, AI_TrySkillSwapOnAllyPlus3 - if_has_move AI_USER_PARTNER, MOVE_HYDRO_PUMP, AI_TrySkillSwapOnAllyPlus3 - if_has_move AI_USER_PARTNER, MOVE_DYNAMIC_PUNCH, AI_TrySkillSwapOnAllyPlus3 - if_has_move AI_USER_PARTNER, MOVE_BLIZZARD, AI_TrySkillSwapOnAllyPlus3 - if_has_move AI_USER_PARTNER, MOVE_MEGAHORN, AI_TrySkillSwapOnAllyPlus3 - goto Score_Minus30 - -AI_TrySkillSwapOnAllyPlus3: - goto Score_Plus3 - -AI_TryStatusOnAlly: - get_ability AI_TARGET - if_not_equal ABILITY_GUTS, Score_Minus30 - if_status AI_TARGET, STATUS1_ANY, Score_Minus30 - if_hp_less_than AI_USER, 91, Score_Minus30 - goto Score_Plus5 - -AI_TryHelpingHandOnAlly: - if_random_less_than 64, Score_Minus1 - goto Score_Plus2 - -AI_TrySwaggerOnAlly: - if_has_no_physical_move AI_USER_PARTNER, Score_Minus30 - if_holds_item AI_TARGET, ITEM_PERSIM_BERRY, AI_TrySwaggerOnAlly2 - if_ability AI_USER_PARTNER, ABILITY_OWN_TEMPO, AI_TrySwaggerOnAlly2 - goto Score_Minus30 - -AI_TrySwaggerOnAlly2: - if_stat_level_more_than AI_TARGET, STAT_ATK, 7, AI_TrySwaggerOnAlly_End - score +3 - -AI_TrySwaggerOnAlly_End: - end - -AI_HPAware: - if_target_is_ally AI_TryOnAlly - if_hp_more_than AI_USER, 70, AI_HPAware_UserHasHighHP - if_hp_more_than AI_USER, 30, AI_HPAware_UserHasMediumHP - get_considered_move_effect - if_in_bytes AI_HPAware_DiscouragedEffectsWhenLowHP, AI_HPAware_TryToDiscourage - goto AI_HPAware_ConsiderTarget - -AI_HPAware_UserHasHighHP: - get_considered_move_effect - if_in_hwords AI_HPAware_DiscouragedEffectsWhenHighHP, AI_HPAware_TryToDiscourage - goto AI_HPAware_ConsiderTarget - -AI_HPAware_UserHasMediumHP: - get_considered_move_effect - if_in_bytes AI_HPAware_DiscouragedEffectsWhenMediumHP, AI_HPAware_TryToDiscourage - goto AI_HPAware_ConsiderTarget - -AI_HPAware_TryToDiscourage: - if_random_less_than 50, AI_HPAware_ConsiderTarget - score -2 - -AI_HPAware_ConsiderTarget: - if_hp_more_than AI_TARGET, 70, AI_HPAware_TargetHasHighHP - if_hp_more_than AI_TARGET, 30, AI_HPAware_TargetHasMediumHP - get_considered_move_effect - if_in_bytes AI_HPAware_DiscouragedEffectsWhenTargetLowHP, AI_HPAware_TargetTryToDiscourage - goto AI_HPAware_End - -AI_HPAware_TargetHasHighHP: - get_considered_move_effect - if_in_bytes AI_HPAware_DiscouragedEffectsWhenTargetHighHP, AI_HPAware_TargetTryToDiscourage - goto AI_HPAware_End - -AI_HPAware_TargetHasMediumHP: - get_considered_move_effect - if_in_bytes AI_HPAware_DiscouragedEffectsWhenTargetMediumHP, AI_HPAware_TargetTryToDiscourage - goto AI_HPAware_End - -AI_HPAware_TargetTryToDiscourage: - if_random_less_than 50, AI_HPAware_End - score -2 - -AI_HPAware_End: - end - -.align 1 -AI_HPAware_DiscouragedEffectsWhenHighHP: @ 82DE21F - .2byte EFFECT_EXPLOSION - .2byte EFFECT_RESTORE_HP - .2byte EFFECT_REST - .2byte EFFECT_DESTINY_BOND - .2byte EFFECT_FLAIL - .2byte EFFECT_ENDURE - .2byte EFFECT_MORNING_SUN - .2byte EFFECT_SYNTHESIS - .2byte EFFECT_MOONLIGHT - .2byte EFFECT_SHORE_UP - .2byte EFFECT_SOFTBOILED - .2byte EFFECT_ROOST - .2byte EFFECT_MEMENTO - .2byte EFFECT_GRUDGE - .2byte EFFECT_OVERHEAT - .2byte -1 - -AI_HPAware_DiscouragedEffectsWhenMediumHP: @ 82DE22D - .byte EFFECT_EXPLOSION - .byte EFFECT_ATTACK_UP - .byte EFFECT_DEFENSE_UP - .byte EFFECT_SPEED_UP - .byte EFFECT_SPECIAL_ATTACK_UP - .byte EFFECT_SPECIAL_DEFENSE_UP - .byte EFFECT_ACCURACY_UP - .byte EFFECT_EVASION_UP - .byte EFFECT_ATTACK_DOWN - .byte EFFECT_DEFENSE_DOWN - .byte EFFECT_SPEED_DOWN - .byte EFFECT_SPECIAL_ATTACK_DOWN - .byte EFFECT_SPECIAL_DEFENSE_DOWN - .byte EFFECT_ACCURACY_DOWN - .byte EFFECT_EVASION_DOWN - .byte EFFECT_BIDE - .byte EFFECT_CONVERSION - .byte EFFECT_LIGHT_SCREEN - .byte EFFECT_MIST - .byte EFFECT_FOCUS_ENERGY - .byte EFFECT_ATTACK_UP_2 - .byte EFFECT_DEFENSE_UP_2 - .byte EFFECT_SPEED_UP_2 - .byte EFFECT_SPECIAL_ATTACK_UP_2 - .byte EFFECT_SPECIAL_DEFENSE_UP_2 - .byte EFFECT_ACCURACY_UP_2 - .byte EFFECT_EVASION_UP_2 - .byte EFFECT_ATTACK_DOWN_2 - .byte EFFECT_DEFENSE_DOWN_2 - .byte EFFECT_SPEED_DOWN_2 - .byte EFFECT_SPECIAL_ATTACK_DOWN_2 - .byte EFFECT_SPECIAL_DEFENSE_DOWN_2 - .byte EFFECT_ACCURACY_DOWN_2 - .byte EFFECT_EVASION_DOWN_2 - .byte EFFECT_CONVERSION_2 - .byte EFFECT_SAFEGUARD - .byte EFFECT_BELLY_DRUM - .byte EFFECT_TICKLE - .byte EFFECT_COSMIC_POWER - .byte EFFECT_BULK_UP - .byte EFFECT_CALM_MIND - .byte EFFECT_DRAGON_DANCE - .byte -1 - -AI_HPAware_DiscouragedEffectsWhenLowHP: @ 82DE258 - .byte EFFECT_ATTACK_UP - .byte EFFECT_DEFENSE_UP - .byte EFFECT_SPEED_UP - .byte EFFECT_SPECIAL_ATTACK_UP - .byte EFFECT_SPECIAL_DEFENSE_UP - .byte EFFECT_ACCURACY_UP - .byte EFFECT_EVASION_UP - .byte EFFECT_ATTACK_DOWN - .byte EFFECT_DEFENSE_DOWN - .byte EFFECT_SPEED_DOWN - .byte EFFECT_SPECIAL_ATTACK_DOWN - .byte EFFECT_SPECIAL_DEFENSE_DOWN - .byte EFFECT_ACCURACY_DOWN - .byte EFFECT_EVASION_DOWN - .byte EFFECT_BIDE - .byte EFFECT_CONVERSION - .byte EFFECT_LIGHT_SCREEN - .byte EFFECT_MIST - .byte EFFECT_FOCUS_ENERGY - .byte EFFECT_ATTACK_UP_2 - .byte EFFECT_DEFENSE_UP_2 - .byte EFFECT_SPEED_UP_2 - .byte EFFECT_SPECIAL_ATTACK_UP_2 - .byte EFFECT_SPECIAL_DEFENSE_UP_2 - .byte EFFECT_ACCURACY_UP_2 - .byte EFFECT_EVASION_UP_2 - .byte EFFECT_ATTACK_DOWN_2 - .byte EFFECT_DEFENSE_DOWN_2 - .byte EFFECT_SPEED_DOWN_2 - .byte EFFECT_SPECIAL_ATTACK_DOWN_2 - .byte EFFECT_SPECIAL_DEFENSE_DOWN_2 - .byte EFFECT_ACCURACY_DOWN_2 - .byte EFFECT_EVASION_DOWN_2 - .byte EFFECT_RAGE - .byte EFFECT_CONVERSION_2 - .byte EFFECT_LOCK_ON - .byte EFFECT_SAFEGUARD - .byte EFFECT_BELLY_DRUM - .byte EFFECT_PSYCH_UP - .byte EFFECT_MIRROR_COAT - .byte EFFECT_SOLARBEAM - .byte EFFECT_ERUPTION - .byte EFFECT_TICKLE - .byte EFFECT_COSMIC_POWER - .byte EFFECT_BULK_UP - .byte EFFECT_CALM_MIND - .byte EFFECT_DRAGON_DANCE - .byte -1 - -AI_HPAware_DiscouragedEffectsWhenTargetHighHP: @ 82DE288 - .byte -1 - -AI_HPAware_DiscouragedEffectsWhenTargetMediumHP: @ 82DE289 - .byte EFFECT_ATTACK_UP - .byte EFFECT_DEFENSE_UP - .byte EFFECT_SPEED_UP - .byte EFFECT_SPECIAL_ATTACK_UP - .byte EFFECT_SPECIAL_DEFENSE_UP - .byte EFFECT_ACCURACY_UP - .byte EFFECT_EVASION_UP - .byte EFFECT_ATTACK_DOWN - .byte EFFECT_DEFENSE_DOWN - .byte EFFECT_SPEED_DOWN - .byte EFFECT_SPECIAL_ATTACK_DOWN - .byte EFFECT_SPECIAL_DEFENSE_DOWN - .byte EFFECT_ACCURACY_DOWN - .byte EFFECT_EVASION_DOWN - .byte EFFECT_MIST - .byte EFFECT_FOCUS_ENERGY - .byte EFFECT_ATTACK_UP_2 - .byte EFFECT_DEFENSE_UP_2 - .byte EFFECT_SPEED_UP_2 - .byte EFFECT_SPECIAL_ATTACK_UP_2 - .byte EFFECT_SPECIAL_DEFENSE_UP_2 - .byte EFFECT_ACCURACY_UP_2 - .byte EFFECT_EVASION_UP_2 - .byte EFFECT_ATTACK_DOWN_2 - .byte EFFECT_DEFENSE_DOWN_2 - .byte EFFECT_SPEED_DOWN_2 - .byte EFFECT_SPECIAL_ATTACK_DOWN_2 - .byte EFFECT_SPECIAL_DEFENSE_DOWN_2 - .byte EFFECT_ACCURACY_DOWN_2 - .byte EFFECT_EVASION_DOWN_2 - .byte EFFECT_POISON - .byte EFFECT_PAIN_SPLIT - .byte EFFECT_PERISH_SONG - .byte EFFECT_SAFEGUARD - .byte EFFECT_TICKLE - .byte EFFECT_COSMIC_POWER - .byte EFFECT_BULK_UP - .byte EFFECT_CALM_MIND - .byte EFFECT_DRAGON_DANCE - .byte -1 - -AI_HPAware_DiscouragedEffectsWhenTargetLowHP: @ 82DE2B1 - .byte EFFECT_SLEEP - .byte EFFECT_EXPLOSION - .byte EFFECT_ATTACK_UP - .byte EFFECT_DEFENSE_UP - .byte EFFECT_SPEED_UP - .byte EFFECT_SPECIAL_ATTACK_UP - .byte EFFECT_SPECIAL_DEFENSE_UP - .byte EFFECT_ACCURACY_UP - .byte EFFECT_EVASION_UP - .byte EFFECT_ATTACK_DOWN - .byte EFFECT_DEFENSE_DOWN - .byte EFFECT_SPEED_DOWN - .byte EFFECT_SPECIAL_ATTACK_DOWN - .byte EFFECT_SPECIAL_DEFENSE_DOWN - .byte EFFECT_ACCURACY_DOWN - .byte EFFECT_EVASION_DOWN - .byte EFFECT_BIDE - .byte EFFECT_CONVERSION - .byte EFFECT_TOXIC - .byte EFFECT_LIGHT_SCREEN - .byte EFFECT_OHKO - .byte EFFECT_SUPER_FANG - .byte EFFECT_MIST - .byte EFFECT_FOCUS_ENERGY - .byte EFFECT_CONFUSE - .byte EFFECT_ATTACK_UP_2 - .byte EFFECT_DEFENSE_UP_2 - .byte EFFECT_SPEED_UP_2 - .byte EFFECT_SPECIAL_ATTACK_UP_2 - .byte EFFECT_SPECIAL_DEFENSE_UP_2 - .byte EFFECT_ACCURACY_UP_2 - .byte EFFECT_EVASION_UP_2 - .byte EFFECT_ATTACK_DOWN_2 - .byte EFFECT_DEFENSE_DOWN_2 - .byte EFFECT_SPEED_DOWN_2 - .byte EFFECT_SPECIAL_ATTACK_DOWN_2 - .byte EFFECT_SPECIAL_DEFENSE_DOWN_2 - .byte EFFECT_ACCURACY_DOWN_2 - .byte EFFECT_EVASION_DOWN_2 - .byte EFFECT_POISON - .byte EFFECT_PARALYZE - .byte EFFECT_PAIN_SPLIT - .byte EFFECT_CONVERSION_2 - .byte EFFECT_LOCK_ON - .byte EFFECT_SPITE - .byte EFFECT_PERISH_SONG - .byte EFFECT_SWAGGER - .byte EFFECT_FURY_CUTTER - .byte EFFECT_ATTRACT - .byte EFFECT_SAFEGUARD - .byte EFFECT_PSYCH_UP - .byte EFFECT_MIRROR_COAT - .byte EFFECT_WILL_O_WISP - .byte EFFECT_TICKLE - .byte EFFECT_COSMIC_POWER - .byte EFFECT_BULK_UP - .byte EFFECT_CALM_MIND - .byte EFFECT_DRAGON_DANCE - .byte -1 - -AI_Unknown: - if_target_is_ally AI_TryOnAlly - if_not_effect EFFECT_SUNNY_DAY, AI_Unknown_End - if_equal 0, AI_Unknown_End - is_first_turn_for AI_USER - if_equal 0, AI_Unknown_End - score +5 - -AI_Unknown_End: @ 82DE308 - end - -AI_Roaming: - if_status2 AI_USER, STATUS2_WRAPPED, AI_Roaming_End - if_status2 AI_USER, STATUS2_ESCAPE_PREVENTION, AI_Roaming_End - get_ability AI_TARGET - if_equal ABILITY_SHADOW_TAG, AI_Roaming_End - get_ability AI_USER - if_equal ABILITY_LEVITATE, AI_Roaming_Flee - get_ability AI_TARGET - if_equal ABILITY_ARENA_TRAP, AI_Roaming_End - -AI_Roaming_Flee: @ 82DE335 - flee - -AI_Roaming_End: @ 82DE336 - end - -AI_Safari: - if_random_safari_flee AI_Safari_Flee - watch - -AI_Safari_Flee: - flee - -AI_FirstBattle: - if_hp_equal AI_TARGET, 20, AI_FirstBattle_Flee - if_hp_less_than AI_TARGET, 20, AI_FirstBattle_Flee - end - -AI_FirstBattle_Flee: - flee - -AI_Ret: - end diff --git a/data/battle_anim_scripts.s b/data/battle_anim_scripts.s index b883a4639..65bac00d7 100644 --- a/data/battle_anim_scripts.s +++ b/data/battle_anim_scripts.s @@ -6713,7 +6713,7 @@ Move_SEARING_SHOT: launchtemplate gSearingShotEruptionRockTemplate 0x2 0x5 0x1 0x80 0x1e 0x19 0xffec delay 0x2 launchtemplate gSearingShotEruptionRockTemplate 0x42 0x5 0x1 0xa0 0x1e 0x19 0xffec - launchtemplate gSearingShotEruptionRockTemplate 0x42 0x5 0x1 SOUND_PAN_ATTACKER 0x1e 0x19 0xffec + launchtemplate gSearingShotEruptionRockTemplate 0x42 0x5 0x1 0xa0 0x1e 0x19 0xffec delay 0x2 launchtemplate gSearingShotEruptionRockTemplate 0x42 0x5 0x1 0xe0 0x1e 0x19 0xffec delay 0xF @@ -6727,7 +6727,7 @@ Move_SEARING_SHOT: launchtemplate gSearingShotEruptionRockTemplate 0x2 0x5 0x1 0x80 0x1e 0x19 0x0 delay 0x2 launchtemplate gSearingShotEruptionRockTemplate 0x42 0x5 0x1 0xa0 0x1e 0x19 0x0 - launchtemplate gSearingShotEruptionRockTemplate 0x42 0x5 0x1 SOUND_PAN_ATTACKER 0x1e 0x19 0x0 + launchtemplate gSearingShotEruptionRockTemplate 0x42 0x5 0x1 0xa0 0x1e 0x19 0x0 delay 0x2 launchtemplate gSearingShotEruptionRockTemplate 0x42 0x5 0x1 0xe0 0x1e 0x19 0x0 delay 0x15 @@ -9063,11 +9063,11 @@ Move_EERIE_IMPULSE:: launchtemplate gZapCannonSparkSpriteTemplate, ANIM_TARGET, 7, 10, 0, 16, 30, 0, 40, 0 launchtemplate gZapCannonSparkSpriteTemplate, ANIM_TARGET, 7, 10, 0, 16, 30, 0, 40, 1 launchtemplate gZapCannonSparkSpriteTemplate, ANIM_TARGET, 7, 10, 0, 16, 30, 0, 40, 0 - launchtemplate gZapCannonSparkSpriteTemplate, ANIM_TARGET, 7, 10, 0, 16, 30, SOUND_PAN_ATTACKER, 40, 2 + launchtemplate gZapCannonSparkSpriteTemplate, ANIM_TARGET, 7, 10, 0, 16, 30, 0, 40, 2 launchtemplate gZapCannonSparkSpriteTemplate, ANIM_TARGET, 7, 10, 0, 32, 30, 0, 40, 0 launchtemplate gZapCannonSparkSpriteTemplate, ANIM_TARGET, 7, 10, 0, 32, 30, 0, 40, 1 launchtemplate gZapCannonSparkSpriteTemplate, ANIM_TARGET, 7, 10, 0, 32, 30, 0, 40, 0 - launchtemplate gZapCannonSparkSpriteTemplate, ANIM_TARGET, 7, 10, 0, 32, 30, SOUND_PAN_ATTACKER, 40, 2 + launchtemplate gZapCannonSparkSpriteTemplate, ANIM_TARGET, 7, 10, 0, 32, 30, 0, 40, 2 launchtemplate gZapCannonSparkSpriteTemplate, ANIM_TARGET, 7, 10, 0, 48, 30, 0, 40, 0 launchtemplate gZapCannonSparkSpriteTemplate, ANIM_TARGET, 7, 10, 0, 48, 30, 0, 40, 1 launchtemplate gZapCannonSparkSpriteTemplate, ANIM_TARGET, 7, 10, 0, 48, 30, 0, 40, 0 @@ -10966,11 +10966,11 @@ PollenPuffAlly: monbg ANIM_TARGET launchtemplate gPollenPuffPinkSparkleTemplate 0x84 0x7 0xa 0x0 0x10 0x1e 0xa0 0x28 0x0 launchtemplate gPollenPuffPinkSparkleTemplate 0x84 0x7 0xa 0x0 0x10 0x1e 0x120 0x28 0x0 - launchtemplate gPollenPuffPinkSparkleTemplate 0x84 0x7 0xa 0x0 0x8 0x1e SOUND_PAN_ATTACKER 0x28 0x0 + launchtemplate gPollenPuffPinkSparkleTemplate 0x84 0x7 0xa 0x0 0x8 0x1e 0x90 0x28 0x0 launchtemplate gPollenPuffPinkSparkleTemplate 0x84 0x7 0xa 0x0 0x8 0x1e 0x110 0x28 0x0 launchtemplate gPollenPuffYellowSparkleTemplate 0x84 0x7 0xa 0x0 0x10 0x1e 0xa0 0x28 0x0 launchtemplate gPollenPuffYellowSparkleTemplate 0x84 0x7 0xa 0x0 0x10 0x1e 0x120 0x28 0x0 - launchtemplate gPollenPuffYellowSparkleTemplate 0x84 0x7 0xa 0x0 0x8 0x1e SOUND_PAN_ATTACKER 0x28 0x0 + launchtemplate gPollenPuffYellowSparkleTemplate 0x84 0x7 0xa 0x0 0x8 0x1e 0x90 0x28 0x0 launchtemplate gPollenPuffYellowSparkleTemplate 0x84 0x7 0xa 0x0 0x8 0x1e 0x110 0x28 0x0 delay 0x1 launchtemplate gPollenPuffSporeTemplate 0x82 0x6 0xa 0x0 0x0 0x0 0x19 0xffe0 @@ -13015,7 +13015,7 @@ Move_PHOTON_GEYSER:: launchtemplate gPhotonGeyserZapCannonSparkTemplate 0x84 0x7 0xa 0x0 0x10 0x1e 0x0 0x28 0x0 launchtemplate gPhotonGeyserZapCannonSparkTemplate 0x84 0x7 0xa 0x0 0x10 0x1e 0x40 0x28 0x1 launchtemplate gPhotonGeyserZapCannonSparkTemplate 0x84 0x7 0xa 0x0 0x10 0x1e 0x80 0x28 0x0 - launchtemplate gPhotonGeyserZapCannonSparkTemplate 0x84 0x7 0xa 0x0 0x10 0x1e SOUND_PAN_ATTACKER 0x28 0x2 + launchtemplate gPhotonGeyserZapCannonSparkTemplate 0x84 0x7 0xa 0x0 0x10 0x1e 0x0 0x28 0x2 launchtemplate gPhotonGeyserZapCannonSparkTemplate 0x84 0x7 0xa 0x0 0x8 0x1e 0x20 0x28 0x0 launchtemplate gPhotonGeyserZapCannonSparkTemplate 0x84 0x7 0xa 0x0 0x8 0x1e 0x60 0x28 0x1 launchtemplate gPhotonGeyserZapCannonSparkTemplate 0x84 0x7 0xa 0x0 0x8 0x1e 0xa0 0x28 0x0 @@ -13326,11 +13326,11 @@ Move_BOLT_BEAK:: call BoltBeakSparks waitforvisualfinish launchtask AnimTask_BlendColorCycle 0x2 0x6 0x3 0xffe1 0x1 0x0 0x0 0x5bff - launchtemplate gHorizontalLungeSpriteTemplate 0x2 0x2 0x4 0x4 + createsprite gHorizontalLungeSpriteTemplate, 0x2, 0x2, 0x4, 0x4 delay 0x4 - launchtemplate gHornHitSpriteTemplate 0x84 0x3 0x8 0x8 0xa + createsprite gHornHitSpriteTemplate, 0x84, 0x3, 0x8, 0x8, 0xa waitforvisualfinish - launchtemplate gFlashingHitSplatSpriteTemplate 0x83 0x4 0x0 0x0 0x1 0x1 + createsprite gFlashingHitSplatSpriteTemplate, 0x83, 0x4, 0x0, 0x0, 0x1, 0x1 playsewithpan SE_M_HORN_ATTACK, SOUND_PAN_TARGET launchtask AnimTask_ShakeMon 0x2 0x5 0x1 0x3 0x0 0x6 0x1 waitforvisualfinish @@ -13340,32 +13340,32 @@ Move_BOLT_BEAK:: end BoltBeakSparks: playsewithpan SE_M_THUNDERBOLT2, SOUND_PAN_ATTACKER - launchtemplate gSparkElectricitySpriteTemplate 0x0 0x7 0x20 0x18 0xbe 0xc 0x0 0x1 0x0 + createsprite gSparkElectricitySpriteTemplate, 0x0, 0x7, 0x20, 0x18, 0xbe, 0xc, 0x0, 0x1, 0x0 delay 0x0 - launchtemplate gBoltBeakBlueSparkTemplate 0x0 0x7 0x50 0x18 0x16 0xc 0x0 0x1 0x0 - launchtemplate gSparkElectricitySpriteTemplate 0x0 0x7 0x9c 0x18 0x79 0xd 0x0 0x1 0x1 + createsprite gBoltBeakBlueSparkTemplate, 0x0, 0x7, 0x50, 0x18, 0x16, 0xc, 0x0, 0x1, 0x0 + createsprite gSparkElectricitySpriteTemplate, 0x0, 0x7, 0x9c, 0x18, 0x79, 0xd, 0x0, 0x1, 0x1 delay 0x0 launchtask AnimTask_BlendColorCycle 0x2 0x6 0x3 0xffe1 0x1 0x0 0x0 0x5bff delay 0xa launchtask AnimTask_BlendColorCycle 0x2 0x6 0x3 0xffe1 0x1 0x5 0x5 0x5bff playsewithpan SE_M_THUNDERBOLT2, SOUND_PAN_ATTACKER - launchtemplate gBoltBeakBlueSparkTemplate 0x0 0x7 0x64 0x18 0x3c 0xa 0x0 0x1 0x0 - launchtemplate gSparkElectricitySpriteTemplate 0x0 0x7 0xaa 0x18 0x2a 0xb 0x0 0x1 0x1 + createsprite gBoltBeakBlueSparkTemplate, 0x0, 0x7, 0x64, 0x18, 0x3c, 0xa, 0x0, 0x1, 0x0 + createsprite gSparkElectricitySpriteTemplate, 0x0, 0x7, 0xaa, 0x18, 0x2a, 0xb, 0x0, 0x1, 0x1 delay 0x0 - launchtemplate gBoltBeakBlueSparkTemplate 0x0 0x7 0xee 0x18 0xa5 0xa 0x0 0x1 0x1 + createsprite gBoltBeakBlueSparkTemplate, 0x0, 0x7, 0xee, 0x18, 0xa5, 0xa, 0x0, 0x1, 0x1 delay 0x0 launchtask AnimTask_BlendColorCycle 0x2 0x6 0x3 0xffe1 0x1 0x0 0x0 0x76E1 delay 0x14 launchtask AnimTask_BlendColorCycle 0x2 0x6 0x3 0xffe1 0x1 0x4 0x4 0x76E1 playsewithpan SE_M_THUNDERBOLT2, SOUND_PAN_ATTACKER - launchtemplate gSparkElectricityFlashingSpriteTemplate 0x4 0x8 0x0 0x0 0x20 0xc 0x0 0x14 0x0 0x0 - launchtemplate gBoltBeakBlueFlashingSparkTemplate 0x4 0x8 0x0 0x0 0x20 0xc 0x40 0x14 0x1 0x0 - launchtemplate gSparkElectricityFlashingSpriteTemplate 0x4 0x8 0x0 0x0 0x20 0xc 0x80 0x14 0x0 0x0 - launchtemplate gBoltBeakBlueFlashingSparkTemplate 0x4 0x8 0x0 0x0 0x20 0xc SOUND_PAN_ATTACKER 0x14 0x2 0x0 - launchtemplate gSparkElectricityFlashingSpriteTemplate 0x4 0x8 0x0 0x0 0x10 0xc 0x20 0x14 0x0 0x0 - launchtemplate gBoltBeakBlueFlashingSparkTemplate 0x4 0x8 0x0 0x0 0x10 0xc 0x60 0x14 0x1 0x0 - launchtemplate gSparkElectricityFlashingSpriteTemplate 0x4 0x8 0x0 0x0 0x10 0xc 0xa0 0x14 0x0 0x0 - launchtemplate gBoltBeakBlueFlashingSparkTemplate 0x4 0x8 0x0 0x0 0x10 0xc 0xe0 0x14 0x2 0x0 + createsprite gSparkElectricityFlashingSpriteTemplate, 0x4, 0x8, 0x0, 0x0, 0x20, 0xc, 0x0, 0x14, 0x0, 0x0 + createsprite gBoltBeakBlueFlashingSparkTemplate, 0x4, 0x8, 0x0, 0x0, 0x20, 0xc, 0x40, 0x14, 0x1, 0x0 + createsprite gSparkElectricityFlashingSpriteTemplate, 0x4, 0x8, 0x0, 0x0, 0x20, 0xc, 0x80, 0x14, 0x0, 0x0 + createsprite gBoltBeakBlueFlashingSparkTemplate, 0x4, 0x8, 0x0, 0x0, 0x20, 0xc, 0x0, 0x14, 0x2, 0x0 + createsprite gSparkElectricityFlashingSpriteTemplate, 0x4, 0x8, 0x0, 0x0, 0x10, 0xc, 0x20, 0x14, 0x0, 0x0 + createsprite gBoltBeakBlueFlashingSparkTemplate, 0x4, 0x8, 0x0, 0x0, 0x10, 0xc, 0x60, 0x14, 0x1, 0x0 + createsprite gSparkElectricityFlashingSpriteTemplate, 0x4, 0x8, 0x0, 0x0, 0x10, 0xc, 0xa0, 0x14, 0x0, 0x0 + createsprite gBoltBeakBlueFlashingSparkTemplate, 0x4, 0x8, 0x0, 0x0, 0x10, 0xc, 0xe0, 0x14, 0x2, 0x0 delay 0x4 return diff --git a/data/battle_scripts_1.s b/data/battle_scripts_1.s index 795518380..0e22ec264 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -369,6 +369,10 @@ gBattleScriptsForMoveEffects:: @ 82D86A8 .4byte BattleScript_EffectSleepHit .4byte BattleScript_EffectPhotonGeyser .4byte BattleScript_EffectShellSideArm + .4byte BattleScript_EffectAttackerDefenseDownHit + .4byte BattleScript_EffectBodyPress + .4byte BattleScript_EffectPhotonGeyser + .4byte BattleScript_EffectShellSideArm BattleScript_EffectShellSideArm: shellsidearmcheck @@ -377,6 +381,9 @@ BattleScript_EffectShellSideArm: BattleScript_EffectPhotonGeyser: photongeysercheck + +BattleScript_EffectAttackerDefenseDownHit: + setmoveeffect MOVE_EFFECT_DEF_MINUS_1 | MOVE_EFFECT_AFFECTS_USER | MOVE_EFFECT_CERTAIN goto BattleScript_EffectHit BattleScript_EffectSleepHit: @@ -893,10 +900,11 @@ BattleScript_EffectFlameBurst: BattleScript_MoveEffectFlameBurst:: tryfaintmon BS_TARGET, FALSE, NULL + copybyte sBATTLER, sSAVED_BATTLER printstring STRINGID_BURSTINGFLAMESHIT waitmessage B_WAIT_TIME_LONG savetarget - copybyte gBattlerTarget, sBATTLER + copybyte gBattlerTarget, sSAVED_BATTLER healthbarupdate BS_TARGET datahpupdate BS_TARGET tryfaintmon BS_TARGET, FALSE, NULL @@ -2062,6 +2070,7 @@ BattleScript_EffectChangeTypeOnItem: BattleScript_EffectFusionCombo: BattleScript_EffectRevelationDance: BattleScript_EffectBelch: +BattleScript_EffectBodyPress: BattleScript_HitFromAtkCanceler:: attackcanceler @@ -4200,6 +4209,15 @@ BattleScript_NotAffected:: waitmessage B_WAIT_TIME_LONG goto BattleScript_MoveEnd +BattleScript_NotAffectedAbilityPopUp:: + copybyte gBattlerAbility, gBattlerTarget + pause B_WAIT_TIME_SHORT + call BattleScript_AbilityPopUp + orhalfword gMoveResultFlags, MOVE_RESULT_DOESNT_AFFECT_FOE + resultmessage + waitmessage B_WAIT_TIME_LONG + goto BattleScript_MoveEnd + BattleScript_EffectUproar:: attackcanceler accuracycheck BattleScript_PrintMoveMissed, ACC_CURR_MOVE @@ -7414,6 +7432,18 @@ BattleScript_AbilityCuredStatus:: updatestatusicon BS_SCRIPTING return +BattleScript_BattlerShookOffTaunt:: + call BattleScript_AbilityPopUp + printstring STRINGID_PKMNSHOOKOFFTHETAUNT + waitmessage B_WAIT_TIME_LONG + return + +BattleScript_BattlerGotOverItsInfatuation:: + call BattleScript_AbilityPopUp + printstring STRINGID_PKMNGOTOVERITSINFATUATION + waitmessage B_WAIT_TIME_LONG + return + BattleScript_IgnoresWhileAsleep:: printstring STRINGID_PKMNIGNORESASLEEP waitmessage B_WAIT_TIME_LONG diff --git a/include/battle.h b/include/battle.h index 2195e0a21..4a9d4211a 100644 --- a/include/battle.h +++ b/include/battle.h @@ -239,8 +239,35 @@ struct AI_SavedBattleMon u16 species; }; +struct AiLogicData +{ + //attacker data + u16 atkAbility; + u16 atkItem; + u16 atkHoldEffect; + u8 atkParam; + u16 atkSpecies; + // target data + u16 defAbility; + u16 defItem; + u16 defHoldEffect; + u8 defParam; + u16 defSpecies; + // attacker partner data + u8 battlerAtkPartner; + u16 partnerMove; + u16 atkPartnerAbility; + u16 atkPartnerHoldEffect; + bool32 targetSameSide; + // target partner data + u8 battlerDefPartner; + u16 defPartnerAbility; + u16 defPartnerHoldEffect; +}; + struct AI_ThinkingStruct { + struct AiLogicData data; u8 aiState; u8 movesetIndex; u16 moveConsidered; @@ -293,11 +320,14 @@ struct BattleResources struct StatsArray* beforeLvlUp; struct AI_ThinkingStruct *ai; struct BattleHistory *battleHistory; - struct BattleScriptsStack *AI_ScriptsStack; u8 bufferA[MAX_BATTLERS_COUNT][0x200]; u8 bufferB[MAX_BATTLERS_COUNT][0x200]; }; +#define AI_THINKING_STRUCT ((struct AI_ThinkingStruct *)(gBattleResources->ai)) +#define AI_DATA ((struct AiLogicData *)(&gBattleResources->ai->data)) +#define BATTLE_HISTORY ((struct BattleHistory *)(gBattleResources->battleHistory)) + struct BattleResults { u8 playerFaintCounter; // 0x0 diff --git a/include/battle_ai_main.h b/include/battle_ai_main.h new file mode 100644 index 000000000..66c614f78 --- /dev/null +++ b/include/battle_ai_main.h @@ -0,0 +1,30 @@ +#ifndef GUARD_BATTLE_AI_MAIN_H +#define GUARD_BATTLE_AI_MAIN_H + +// return values for BattleAI_ChooseMoveOrAction +// 0 - 3 are move idx +#define AI_CHOICE_FLEE 4 +#define AI_CHOICE_WATCH 5 +#define AI_CHOICE_SWITCH 7 + +#define RETURN_SCORE_PLUS(val) \ +{ \ + score += val; \ + return score; \ +} + +#define RETURN_SCORE_MINUS(val) \ +{ \ + score -= val; \ + return score; \ +} + + +void BattleAI_SetupItems(void); +void BattleAI_SetupFlags(void); +void BattleAI_SetupAIData(u8 defaultScoreMoves); +u8 BattleAI_ChooseMoveOrAction(void); + +extern u8 sBattler_AI; + +#endif // GUARD_BATTLE_AI_MAIN_H diff --git a/include/battle_ai_script_commands.h b/include/battle_ai_script_commands.h deleted file mode 100644 index be3787398..000000000 --- a/include/battle_ai_script_commands.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef GUARD_BATTLE_AI_SCRIPT_COMMANDS_H -#define GUARD_BATTLE_AI_SCRIPT_COMMANDS_H - -// return values for BattleAI_ChooseMoveOrAction -// 0 - 3 are move idx -#define AI_CHOICE_FLEE 4 -#define AI_CHOICE_WATCH 5 -#define AI_CHOICE_SWITCH 7 - -s32 AI_CalcDamage(u16 move, u8 battlerAtk, u8 battlerDef); -s32 AI_CalcPartyMonDamage(u16 move, u8 battlerAtk, u8 battlerDef, struct Pokemon *mon); -u16 AI_GetTypeEffectiveness(u16 move, u8 battlerAtk, u8 battlerDef); -void BattleAI_SetupItems(void); -void BattleAI_SetupFlags(void); -void BattleAI_SetupAIData(u8 defaultScoreMoves); -u8 BattleAI_ChooseMoveOrAction(void); -bool32 IsTruantMonVulnerable(u32 battlerAI, u32 opposingBattler); -bool32 IsBattlerAIControlled(u32 battlerId); -void ClearBattlerMoveHistory(u8 battlerId); -void RecordLastUsedMoveBy(u32 battlerId, u32 move); -void RecordKnownMove(u8 battlerId, u32 move); -void RecordAbilityBattle(u8 battlerId, u16 abilityId); -void ClearBattlerAbilityHistory(u8 battlerId); -void RecordItemEffectBattle(u8 battlerId, u8 itemEffect); -void ClearBattlerItemEffectHistory(u8 battlerId); - -#endif // GUARD_BATTLE_AI_SCRIPT_COMMANDS_H diff --git a/include/battle_ai_switch_items.h b/include/battle_ai_switch_items.h index e9ef60b88..70dc41b34 100644 --- a/include/battle_ai_switch_items.h +++ b/include/battle_ai_switch_items.h @@ -34,5 +34,6 @@ enum { void GetAIPartyIndexes(u32 battlerId, s32 *firstId, s32 *lastId); void AI_TrySwitchOrUseItem(void); u8 GetMostSuitableMonToSwitchInto(void); +bool32 ShouldSwitch(void); #endif // GUARD_BATTLE_AI_SWITCH_ITEMS_H diff --git a/include/battle_ai_util.h b/include/battle_ai_util.h new file mode 100644 index 000000000..db33a7ff1 --- /dev/null +++ b/include/battle_ai_util.h @@ -0,0 +1,168 @@ +#ifndef GUARD_BATTLE_AI_UTIL_H +#define GUARD_BATTLE_AI_UTIL_H + +// for IsAiFaster +#define AI_CHECK_FASTER 0 // if_user_faster +#define AI_CHECK_SLOWER 1 // if_target_faster + +#define FOE(battler) ((battler ^ BIT_SIDE) & BIT_SIDE) + +bool32 AI_RandLessThan(u8 val); +void RecordLastUsedMoveByTarget(void); +bool32 IsBattlerAIControlled(u32 battlerId); +void ClearBattlerMoveHistory(u8 battlerId); +void RecordLastUsedMoveBy(u32 battlerId, u32 move); +void RecordKnownMove(u8 battlerId, u32 move); +void RecordAbilityBattle(u8 battlerId, u16 abilityId); +void ClearBattlerAbilityHistory(u8 battlerId); +void RecordItemEffectBattle(u8 battlerId, u8 itemEffect); +void ClearBattlerItemEffectHistory(u8 battlerId); +void SaveBattlerData(u8 battlerId); +void SetBattlerData(u8 battlerId); +void RestoreBattlerData(u8 battlerId); + +u32 GetTotalBaseStat(u32 species); +bool32 IsTruantMonVulnerable(u32 battlerAI, u32 opposingBattler); +bool32 AtMaxHp(u8 battler); +u32 GetHealthPercentage(u8 battler); +bool32 IsBattlerTrapped(u8 battler, bool8 switching); +bool32 IsAiFaster(u8 battler); +bool32 CanTargetFaintAi(u8 battlerDef, u8 battlerAtk); +bool32 CanMoveFaintBattler(u16 move, u8 battlerDef, u8 battlerAtk, u8 nHits); +bool32 CanTargetFaintAiWithMod(u8 battlerDef, u8 battlerAtk, s32 hpMod, s32 dmgMod); +s32 AI_GetAbility(u32 battlerId); +u16 AI_GetHoldEffect(u32 battlerId); +u32 AI_GetMoveAccuracy(u8 battlerAtk, u8 battlerDef, u16 atkAbility, u16 defAbility, u8 atkHoldEffect, u8 defHoldEffect, u16 move); +bool32 DoesBattlerIgnoreAbilityChecks(u16 atkAbility, u16 move); +bool32 AI_WeatherHasEffect(void); +bool32 CanAttackerFaintTarget(u8 battlerAtk, u8 battlerDef, u8 index, u8 numHits); +bool32 AI_IsBattlerGrounded(u8 battlerId); +bool32 HasDamagingMove(u8 battlerId); +bool32 HasDamagingMoveOfType(u8 battlerId, u8 type); +u32 GetBattlerSecondaryDamage(u8 battlerId); +bool32 BattlerWillFaintFromWeather(u8 battler, u16 ability); +bool32 BattlerWillFaintFromSecondaryDamage(u8 battler, u16 ability); +bool32 ShouldTryOHKO(u8 battlerAtk, u8 battlerDef, u16 atkAbility, u16 defAbility, u32 accuracy, u16 move); +bool32 ShouldUseRecoilMove(u8 battlerAtk, u8 battlerDef, u32 recoilDmg, u8 moveIndex); +u16 GetBattlerSideSpeedAverage(u8 battler); +bool32 ShouldAbsorb(u8 battlerAtk, u8 battlerDef, u16 move, s32 damage); +bool32 ShouldRecover(u8 battlerAtk, u8 battlerDef, u16 move, u8 healPercent); +bool32 ShouldSetScreen(u8 battlerAtk, u8 battlerDef, u16 moveEffect); +bool32 ShouldPivot(u8 battlerAtk, u8 battlerDef, u16 defAbility, u16 move, u8 moveIndex); +bool32 IsRecycleEncouragedItem(u16 item); +bool32 CanKnockOffItem(u8 battler, u16 item); +bool32 IsAbilityOfRating(u16 ability, s8 rating); +s8 GetAbilityRating(u16 ability); + +// stat stage checks +bool32 AnyStatIsRaised(u8 battlerId); +bool32 ShouldLowerStat(u8 battler, u16 battlerAbility, u8 stat); +bool32 BattlerStatCanRise(u8 battler, u16 battlerAbility, u8 stat); +bool32 AreBattlersStatsMaxed(u8 battler); +bool32 BattlerHasAnyStatRaised(u8 battlerId); +u32 CountPositiveStatStages(u8 battlerId); +u32 CountNegativeStatStages(u8 battlerId); +bool32 ShouldLowerAttack(u8 battlerAtk, u8 battlerDef, u16 defAbility); +bool32 ShouldLowerDefense(u8 battlerAtk, u8 battlerDef, u16 defAbility); +bool32 ShouldLowerSpeed(u8 battlerAtk, u8 battlerDef, u16 defAbility); +bool32 ShouldLowerSpAtk(u8 battlerAtk, u8 battlerDef, u16 defAbility); +bool32 ShouldLowerSpDef(u8 battlerAtk, u8 battlerDef, u16 defAbility); +bool32 ShouldLowerAccuracy(u8 battlerAtk, u8 battlerDef, u16 defAbility); +bool32 ShouldLowerEvasion(u8 battlerAtk, u8 battlerDef, u16 defAbility); + +// move checks +bool32 IsAffectedByPowder(u8 battler, u16 ability, u16 holdEffect); +bool32 MovesWithSplitUnusable(u32 attacker, u32 target, u32 split); +s32 AI_CalcDamage(u16 move, u8 battlerAtk, u8 battlerDef); +u8 GetMoveDamageResult(u16 move); +u32 GetCurrDamageHpPercent(u8 battlerAtk, u8 battlerDef); +u16 AI_GetTypeEffectiveness(u16 move, u8 battlerAtk, u8 battlerDef); +u8 AI_GetMoveEffectiveness(u16 move, u8 battlerAtk, u8 battlerDef); +u16 *GetMovesArray(u32 battler); +bool32 IsConfusionMoveEffect(u16 moveEffect); +bool32 HasMove(u32 battlerId, u32 move); +bool32 HasOnlyMovesWithSplit(u32 battlerId, u32 split, bool32 onlyOffensive); +bool32 HasMoveWithSplit(u32 battler, u32 split); +bool32 HasMoveWithType(u32 battler, u8 type); +bool32 HasMoveWithTypeAndSplit(u32 battler, u8 type, u8 split); +bool32 HasMoveEffect(u32 battlerId, u16 moveEffect); +bool32 HasMoveWithLowAccuracy(u8, u8, u8, bool32, u16, u16, u16, u16); +bool32 TestMoveFlagsInMoveset(u8 battler, u32 flags); +bool32 IsAromaVeilProtectedMove(u16 move); +bool32 IsNonVolatileStatusMoveEffect(u16 moveEffect); +bool32 IsStatLoweringMoveEffect(u16 moveEffect); +bool32 IsMoveRedirectionPrevented(u16 move, u16 atkAbility); +bool32 IsMoveEncouragedToHit(u8 battlerAtk, u8 battlerDef, u16 move); +bool32 IsHazardMoveEffect(u16 moveEffect); +bool32 MoveCallsOtherMove(u16 move); +bool32 MoveRequiresRecharging(u16 move); +bool32 IsInstructBannedMove(u16 move); +bool32 IsEncoreEncouragedEffect(u16 moveEffect); +void ProtectChecks(u8 battlerAtk, u8 battlerDef, u16 move, u16 predictedMove, s16 *score); +bool32 ShouldSetSandstorm(u8 battler, u16 ability, u16 holdEffect); +bool32 ShouldSetHail(u8 battler, u16 ability, u16 holdEffect); +bool32 ShouldSetRain(u8 battlerAtk, u16 ability, u16 holdEffect); +bool32 ShouldSetSun(u8 battlerAtk, u16 atkAbility, u16 holdEffect); +bool32 HasSleepMoveWithLowAccuracy(u8 battlerAtk, u8 battlerDef); +bool32 IsHealingMoveEffect(u16 effect); +bool32 HasHealingEffect(u32 battler); +bool32 IsTrappingMoveEffect(u16 effect); +bool32 HasTrappingMoveEffect(u8 battler); +bool32 ShouldFakeOut(u8 battlerAtk, u8 battlerDef, u16 move); +bool32 HasThawingMove(u8 battlerId); +bool32 IsStatRaisingEffect(u16 effect); +bool32 IsStatLoweringEffect(u16 effect); +bool32 IsStatRaisingEffect(u16 effect); +bool32 IsAttackBoostMoveEffect(u16 effect); +bool32 IsUngroundingEffect(u16 effect); +bool32 IsSemiInvulnerable(u8 battlerDef, u16 move); + +// status checks +bool32 CanBeBurned(u8 battler, u16 ability); +bool32 CanBePoisoned(u8 battler, u16 ability); +bool32 CanBeConfused(u8 battler, u16 ability); +bool32 CanSleep(u8 battler, u16 ability); +bool32 IsBattlerIncapacitated(u8 battler, u16 ability); +bool32 AI_CanPutToSleep(u8 battlerAtk, u8 battlerDef, u16 defAbility, u16 move, u16 partnerMove); +bool32 ShouldPoisonSelf(u8 battler, u16 ability); +bool32 AI_CanPoison(u8 battlerAtk, u8 battlerDef, u16 defAbility, u16 move, u16 partnerMove); +bool32 AI_CanParalyze(u8 battlerAtk, u8 battlerDef, u16 defAbility, u16 move, u16 partnerMove); +bool32 AI_CanConfuse(u8 battlerAtk, u8 battlerDef, u16 defAbility, u8 battlerAtkPartner, u16 move, u16 partnerMove); +bool32 ShouldBurnSelf(u8 battler, u16 ability); +bool32 AI_CanBurn(u8 battlerAtk, u8 battlerDef, u16 defAbility, u8 battlerAtkPartner, u16 move, u16 partnerMove); +bool32 AI_CanBeInfatuated(u8 battlerAtk, u8 battlerDef, u16 defAbility, u8 atkGender, u8 defGender); +bool32 AnyPartyMemberStatused(u8 battlerId, bool32 checkSoundproof); +u32 ShouldTryToFlinch(u8 battlerAtk, u8 battlerDef, u16 atkAbility, u16 defAbility, u16 move); +bool32 ShouldTrap(u8 battlerAtk, u8 battlerDef, u16 move); +bool32 IsWakeupTurn(u8 battler); + +// partner logic +u16 GetAllyChosenMove(void); +bool32 IsValidDoubleBattle(u8 battlerAtk); +bool32 IsTargetingPartner(u8 battlerAtk, u8 battlerDef); +bool32 DoesPartnerHaveSameMoveEffect(u8 battlerAtkPartner, u8 battlerDef, u16 move, u16 partnerMove); +bool32 PartnerHasSameMoveEffectWithoutTarget(u8 battlerAtkPartner, u16 move, u16 partnerMove); +bool32 PartnerMoveEffectIsStatusSameTarget(u8 battlerAtkPartner, u8 battlerDef, u16 partnerMove); +bool32 PartnerMoveEffectIsWeather(u8 battlerAtkPartner, u16 partnerMove); +bool32 PartnerMoveEffectIsTerrain(u8 battlerAtkPartner, u16 partnerMove); +bool32 PartnerMoveIs(u8 battlerAtkPartner, u16 partnerMove, u16 moveCheck); +bool32 PartnerMoveIsSameAsAttacker(u8 battlerAtkPartner, u8 battlerDef, u16 move, u16 partnerMove); +bool32 PartnerMoveIsSameNoTarget(u8 battlerAtkPartner, u16 move, u16 partnerMove); +bool32 ShouldUseWishAromatherapy(u8 battlerAtk, u8 battlerDef, u16 move); + +// party logic +s32 AI_CalcPartyMonDamage(u16 move, u8 battlerAtk, u8 battlerDef, struct Pokemon *mon); +s32 CountUsablePartyMons(u8 battlerId); +bool32 IsPartyFullyHealedExceptBattler(u8 battler); +bool32 PartyHasMoveSplit(u8 battlerId, u8 split); +bool32 SideHasMoveSplit(u8 battlerId, u8 split); + +// score increases +void IncreaseStatUpScore(u8 battlerAtk, u8 battlerDef, u8 statId, s16 *score); +void IncreasePoisonScore(u8 battlerAtk, u8 battlerdef, u16 move, s16 *score); +void IncreaseBurnScore(u8 battlerAtk, u8 battlerdef, u16 move, s16 *score); +void IncreaseParalyzeScore(u8 battlerAtk, u8 battlerDef, u16 move, s16 *score); +void IncreaseSleepScore(u8 battlerAtk, u8 battlerDef, u16 move, s16 *score); +void IncreaseConfusionScore(u8 battlerAtk, u8 battlerDef, u16 move, s16 *score); + +#endif //GUARD_BATTLE_AI_UTIL_H \ No newline at end of file diff --git a/include/battle_script_commands.h b/include/battle_script_commands.h index ff3557008..a46bf6494 100644 --- a/include/battle_script_commands.h +++ b/include/battle_script_commands.h @@ -6,6 +6,12 @@ #define WINDOW_CLEAR 0x1 #define WINDOW_x80 0x80 +struct StatFractions +{ + u8 dividend; + u8 divisor; +}; + s32 CalcCritChanceStage(u8 battlerAtk, u8 battlerDef, u32 move, bool32 recordAbility); u32 GetTotalAccuracy(u32 battlerAtk, u32 battlerDef, u32 move); u8 GetBattlerTurnOrderNum(u8 battlerId); @@ -27,8 +33,11 @@ u32 IsLeafGuardProtected(u32 battler); bool32 IsShieldsDownProtected(u32 battler); u32 IsAbilityStatusProtected(u32 battler); bool32 TryResetBattlerStatChanges(u8 battler); +bool32 CanCamouflage(u8 battlerId); +u16 GetNaturePowerMove(void); extern void (* const gBattleScriptingCommandsTable[])(void); extern const u8 gBattlePalaceNatureToMoveGroupLikelihood[NUM_NATURES][4]; +extern const struct StatFractions gAccuracyStageRatios[]; #endif // GUARD_BATTLE_SCRIPT_COMMANDS_H diff --git a/include/battle_scripts.h b/include/battle_scripts.h index 0b94a6ae7..ea85cf43c 100644 --- a/include/battle_scripts.h +++ b/include/battle_scripts.h @@ -367,5 +367,8 @@ extern const u8 BattleScript_CustapBerryActivation[]; extern const u8 BattleScript_MicleBerryActivateEnd2[]; extern const u8 BattleScript_MicleBerryActivateRet[]; extern const u8 BattleScript_JabocaRowapBerryActivates[]; +extern const u8 BattleScript_NotAffectedAbilityPopUp[]; +extern const u8 BattleScript_BattlerShookOffTaunt[]; +extern const u8 BattleScript_BattlerGotOverItsInfatuation[]; #endif // GUARD_BATTLE_SCRIPTS_H diff --git a/include/battle_util.h b/include/battle_util.h index 411e6cd52..f06a58938 100644 --- a/include/battle_util.h +++ b/include/battle_util.h @@ -131,6 +131,21 @@ void ClearIllusionMon(u32 battlerId); bool32 SetIllusionMon(struct Pokemon *mon, u32 battlerId); bool8 ShouldGetStatBadgeBoost(u16 flagId, u8 battlerId); u8 GetBattleMoveSplit(u32 moveId); +bool32 TestMoveFlags(u16 move, u32 flag); +struct Pokemon *GetBattlerPartyData(u8 battlerId); +bool32 CanFling(u8 battlerId); +bool32 IsTelekinesisBannedSpecies(u16 species); +bool32 IsHealBlockPreventingMove(u32 battler, u32 move); +bool32 IsThawingMove(u8 battlerId, u16 move); bool32 HasEnoughHpToEatBerry(u32 battlerId, u32 hpFraction, u32 itemId); +// ability checks +bool32 IsRolePlayBannedAbilityAtk(u16 ability); +bool32 IsRolePlayBannedAbility(u16 ability); +bool32 IsSkillSwapBannedAbility(u16 ability); +bool32 IsWorrySeedBannedAbility(u16 ability); +bool32 IsGastroAcidBannedAbility(u16 ability); +bool32 IsEntrainmentBannedAbilityAttacker(u16 ability); +bool32 IsEntrainmentTargetOrSimpleBeamBannedAbility(u16 ability); + #endif // GUARD_BATTLE_UTIL_H diff --git a/include/constants/battle.h b/include/constants/battle.h index 512620c06..b158076bd 100644 --- a/include/constants/battle.h +++ b/include/constants/battle.h @@ -220,6 +220,9 @@ #define SIDE_STATUS_CRAFTY_SHIELD (1 << 20) #define SIDE_STATUS_MAT_BLOCK (1 << 21) +#define SIDE_STATUS_HAZARDS_ANY (SIDE_STATUS_SPIKES | SIDE_STATUS_STICKY_WEB | SIDE_STATUS_TOXIC_SPIKES | SIDE_STATUS_STEALTH_ROCK) +#define SIDE_STATUS_SCREEN_ANY (SIDE_STATUS_REFLECT | SIDE_STATUS_LIGHTSCREEN | SIDE_STATUS_AURORA_VEIL) + // Field affecting statuses. #define STATUS_FIELD_MAGIC_ROOM (1 << 0) #define STATUS_FIELD_TRICK_ROOM (1 << 1) diff --git a/include/constants/battle_ai.h b/include/constants/battle_ai.h index 974ef2b77..7f56fbced 100644 --- a/include/constants/battle_ai.h +++ b/include/constants/battle_ai.h @@ -35,20 +35,29 @@ #define MOVE_POWER_GOOD 2 // Similar dmg range with best. #define MOVE_POWER_WEAK 3 // Significantly lower than best and good. -// script's table id to bit -#define AI_SCRIPT_CHECK_BAD_MOVE (1 << 0) -#define AI_SCRIPT_TRY_TO_FAINT (1 << 1) -#define AI_SCRIPT_CHECK_VIABILITY (1 << 2) -#define AI_SCRIPT_SETUP_FIRST_TURN (1 << 3) -#define AI_SCRIPT_RISKY (1 << 4) -#define AI_SCRIPT_PREFER_STRONGEST_MOVE (1 << 5) -#define AI_SCRIPT_PREFER_BATON_PASS (1 << 6) -#define AI_SCRIPT_DOUBLE_BATTLE (1 << 7) -#define AI_SCRIPT_HP_AWARE (1 << 8) -#define AI_SCRIPT_UNKNOWN (1 << 9) -// 10 - 28 are not used -#define AI_SCRIPT_ROAMING (1 << 29) -#define AI_SCRIPT_SAFARI (1 << 30) -#define AI_SCRIPT_FIRST_BATTLE (1 << 31) +// AI Flags. Most run specific functions to update score, new flags are used for internal logic in other scripts +#define AI_FLAG_CHECK_BAD_MOVE (1 << 0) +#define AI_FLAG_TRY_TO_FAINT (1 << 1) +#define AI_FLAG_CHECK_VIABILITY (1 << 2) +#define AI_FLAG_SETUP_FIRST_TURN (1 << 3) +#define AI_FLAG_RISKY (1 << 4) +#define AI_FLAG_PREFER_STRONGEST_MOVE (1 << 5) +#define AI_FLAG_PREFER_BATON_PASS (1 << 6) +#define AI_FLAG_DOUBLE_BATTLE (1 << 7) // removed, split between AI_FLAG_CHECK_BAD_MOVE & AI_FLAG_CHECK_GOOD_MOVE +#define AI_FLAG_HP_AWARE (1 << 8) +// New, Trainer Handicap Flags +#define AI_FLAG_NEGATE_UNAWARE (1 << 9) // AI is NOT aware of negating effects like wonder room, mold breaker, etc +#define AI_FLAG_WILL_SUICIDE (1 << 10) // AI will use explosion / self destruct / final gambit / etc +// New, Trainer Strategy Flags +#define AI_FLAG_HELP_PARTNER (1 << 11) // AI can try to help partner. If not set, will tend not to target partner +#define AI_FLAG_PREFER_STATUS_MOVES (1 << 12) // AI gets a score bonus for status moves. Should be combined with AI_FLAG_CHECK_BAD_MOVE to prevent using only status moves +#define AI_FLAG_STALL (1 << 13) // AI stalls battle and prefers secondary damage/trapping/etc. TODO not finished +#define AI_FLAG_SCREENER (1 << 14) // AI prefers screening effects like reflect, mist, etc. TODO unfinished +#define AI_FLAG_SMART_SWITCHING (1 << 15) // AI includes a lot more switching checks + +// 'other' ai logic flags +#define AI_FLAG_ROAMING (1 << 29) +#define AI_FLAG_SAFARI (1 << 30) +#define AI_FLAG_FIRST_BATTLE (1 << 31) #endif // GUARD_CONSTANTS_BATTLE_AI_H diff --git a/include/constants/battle_config.h b/include/constants/battle_config.h index 2cd9341a7..fe376da8d 100644 --- a/include/constants/battle_config.h +++ b/include/constants/battle_config.h @@ -76,59 +76,59 @@ #endif // Calculation settings -#define B_CRIT_CHANCE GEN_6 // Chances of a critical hit landing. See CalcCritChanceStage. -#define B_CRIT_MULTIPLIER GEN_6 // In Gen6+, critical hits multiply damage by 1.5 instead of 2. -#define B_EXP_CATCH GEN_6 // In Gen6+, Pokémon get experience from catching. -#define B_TRAINER_EXP_MULTIPLIER GEN_6 // In Gen7+, trainer battles no longer give a 1.5 multiplier to exp gain. -#define B_SPLIT_EXP GEN_5 // In Gen6+, all participating mon get full experience. -#define B_SCALED_EXP GEN_6 // In Gen5 and Gen7+, experience is weighted by level difference. -#define B_BURN_DAMAGE GEN_6 // In Gen7+, burn damage is 1/16th of max HP instead of 1/8th. -#define B_PARALYSIS_SPEED GEN_6 // In Gen7+, speed is decreased by 50% instead of 75%. -#define B_TERRAIN_TYPE_BOOST GEN_6 // In Gen8+, damage is boosted by 30% instead of 50%. -#define B_BINDING_DAMAGE GEN_6 // In Gen6+, binding damage is 1/8 of max HP instead of 1/16. (With Binding Band, 1/6 and 1/8 respectively.) -#define B_CONFUSION_SELF_DMG_CHANCE GEN_6 // In Gen7+, confusion has a 33.3% of self-damage, instead of 50%. -#define B_MULTI_HIT_CHANCE GEN_6 // In Gen5+, multi-hit moves have different %. See Cmd_setmultihitcounter for values. -#define B_RECOIL_IF_MISS_DMG GEN_6 // In Gen5+, Jump Kick and Hi Jump Kick will always do half of the user's max HP when missing. -#define B_PSYWAVE_DMG GEN_6 // Psywave's damage formula. See Cmd_psywavedamageeffect. -#define B_BADGE_BOOST GEN_6 // In Gen4+, Gym Badges no longer boost a Pokémon's stats +#define B_CRIT_CHANCE GEN_7 // Chances of a critical hit landing. See CalcCritChanceStage. +#define B_CRIT_MULTIPLIER GEN_7 // In Gen6+, critical hits multiply damage by 1.5 instead of 2. +#define B_EXP_CATCH GEN_7 // In Gen6+, Pokémon get experience from catching. +#define B_TRAINER_EXP_MULTIPLIER GEN_7 // In Gen7+, trainer battles no longer give a 1.5 multiplier to EXP gain. +#define B_SPLIT_EXP GEN_7 // In Gen6+, all participating mon get full experience. +#define B_SCALED_EXP GEN_7 // In Gen5 and Gen7+, experience is weighted by level difference. +#define B_BURN_DAMAGE GEN_7 // In Gen7+, burn damage is 1/16th of max HP instead of 1/8th. +#define B_PARALYSIS_SPEED GEN_7 // In Gen7+, Speed is decreased by 50% instead of 75%. +#define B_TERRAIN_TYPE_BOOST GEN_8 // In Gen8, damage is boosted by 30% instead of 50%. +#define B_BINDING_DAMAGE GEN_7 // In Gen6+, binding damage is 1/8 of max HP instead of 1/16. (With Binding Band, 1/6 and 1/8 respectively.) +#define B_CONFUSION_SELF_DMG_CHANCE GEN_7 // In Gen7+, confusion has a 33.3% of self-damage, instead of 50%. +#define B_MULTI_HIT_CHANCE GEN_7 // In Gen5+, multi-hit moves have different %. See Cmd_setmultihitcounter for values. +#define B_RECOIL_IF_MISS_DMG GEN_7 // In Gen5+, Jump Kick and High Jump Kick will always do half of the user's max HP when missing. +#define B_PSYWAVE_DMG GEN_7 // Psywave's damage formula. See Cmd_psywavedamageeffect. +#define B_BADGE_BOOST GEN_7 // In Gen4+, Gym Badges no longer boost a Pokémon's stats. // Move data settings -#define B_UPDATED_MOVE_DATA GEN_7 // Updates move data in gBattleMoves, including Power, Accuracy, PP, stat changes, targets, chances of secondary effects, etc. -#define B_PHYSICAL_SPECIAL_SPLIT GEN_6 // In Gen3, the move's type determines if it will do physical or special damage. The split icon in the summary will reflect this. -#define B_FELL_STINGER_STAT_RAISE GEN_6 // In Gen7+, it raises Atk by 3 stages instead of 2 if it causes the target to faint. -#define B_KINGS_SHIELD_LOWER_ATK GEN_6 // In Gen7+, it lowers Atk by 1 stage instead of 2 of oponents that hit it. +#define B_UPDATED_MOVE_DATA GEN_8 // Updates move data in gBattleMoves, including Power, Accuracy, PP, stat changes, targets, chances of secondary effects, etc. +#define B_PHYSICAL_SPECIAL_SPLIT GEN_7 // In Gen3, the move's type determines if it will do physical or special damage. The split icon in the summary will reflect this. +#define B_FELL_STINGER_STAT_RAISE GEN_7 // In Gen7+, it raises Atk by 3 stages instead of 2 if it causes the target to faint. +#define B_KINGS_SHIELD_LOWER_ATK GEN_7 // In Gen7+, it lowers Atk by 1 stage instead of 2 of oponents that hit it. #define B_SPEED_BUFFING_RAPID_SPIN GEN_8 // In Gen8, Rapid Spin raises the user's Speed by 1 stage. -#define B_WATER_SHURIKEN_SPLIT GEN_8 // In Gen7, Water Shuriken was changed from Physical to Special. // Other move settings -#define B_SOUND_SUBSTITUTE GEN_6 // In Gen6+, sound moves bypass Substitute. -#define B_TOXIC_NEVER_MISS GEN_6 // In Gen6+, if Toxic is used by a Poison type, it will never miss. -#define B_PAYBACK_SWITCH_BOOST GEN_6 // In Gen5+, if the opponent switches out, Payback's damage will no longer be doubled. -#define B_BINDING_TURNS GEN_6 // In Gen5+, binding moves last for 4-5 turns instead of 2-5 turns. (With Grip Claw, 7 and 5 turns respectively.) -#define B_UPROAR_TURNS GEN_6 // In Gen5+, Uproar lasts for 3 turns instead of 2-5 turns. -#define B_DISABLE_TURNS GEN_6 // Disable's turns. See Cmd_disablelastusedattack. -#define B_INCINERATE_GEMS GEN_6 // In Gen6+, Incinerate can destroy Gems. -#define B_MINIMIZE_DMG_ACC GEN_6 // In Gen6+, moves that causes double damage to minimized Pokémon will also skip accuracy checks. -#define B_PP_REDUCED_BY_SPITE GEN_6 // In Gen4+, Spite reduces the foe's last move's PP by 4, instead of 2 to 5. -#define B_CAN_SPITE_FAIL GEN_6 // In Gen4+, Spite can no longer fail if the foe's last move only has 1 remaining PP. -#define B_CRASH_IF_TARGET_IMMUNE GEN_6 // In Gen4+, The user of Jump Kick or Hi Jump Kick will "keep going and crash" if it attacks a target that is immune to the move. -#define B_TAILWIND_TIMER GEN_5 // In Gen5+, Tailwind lasts 4 turns instead of 3. -#define B_MEMENTO_FAIL GEN_4 // In Gen4+, memento fails if there is no target or if the target is protected or behind substitute. But not if atk/sp.atk are at -6 +#define B_SOUND_SUBSTITUTE GEN_7 // In Gen6+, sound moves bypass Substitute. +#define B_TOXIC_NEVER_MISS GEN_7 // In Gen6+, if Toxic is used by a Poison-type Pokémon, it will never miss. +#define B_PAYBACK_SWITCH_BOOST GEN_7 // In Gen5+, if the opponent switches out, Payback's damage will no longer be doubled. +#define B_BINDING_TURNS GEN_7 // In Gen5+, binding moves last for 4-5 turns instead of 2-5 turns. (With Grip Claw, 7 and 5 turns respectively.) +#define B_UPROAR_TURNS GEN_7 // In Gen5+, Uproar lasts for 3 turns instead of 2-5 turns. +#define B_DISABLE_TURNS GEN_7 // Disable's turns. See Cmd_disablelastusedattack. +#define B_INCINERATE_GEMS GEN_7 // In Gen6+, Incinerate can destroy Gems. +#define B_MINIMIZE_DMG_ACC GEN_7 // In Gen6+, moves that causes double damage to minimized Pokémon will also skip accuracy checks. +#define B_PP_REDUCED_BY_SPITE GEN_7 // In Gen4+, Spite reduces the foe's last move's PP by 4, instead of 2 to 5. +#define B_CAN_SPITE_FAIL GEN_7 // In Gen4+, Spite can no longer fail if the foe's last move only has 1 remaining PP. +#define B_CRASH_IF_TARGET_IMMUNE GEN_7 // In Gen4+, The user of Jump Kick or High Jump Kick will "keep going and crash" if it attacks a target that is immune to the move. +#define B_TAILWIND_TIMER GEN_7 // In Gen5+, Tailwind lasts 4 turns instead of 3. +#define B_MEMENTO_FAIL GEN_7 // In Gen4+, Memento fails if there is no target or if the target is protected or behind substitute. But not if Atk/Sp. Atk are at -6. // Ability settings -#define B_ABILITY_WEATHER GEN_6 // In Gen6+, ability-induced weather lasts 5 turns. Before, it lasted until the battle ended or until it was changed by a move. -#define B_GALE_WINGS GEN_6 // In Gen7+ requires full HP to trigger. +#define B_ABILITY_WEATHER GEN_7 // In Gen6+, ability-induced weather lasts 5 turns. Before, it lasted until the battle ended or until it was changed by a move or a different weather-affecting ability. +#define B_GALE_WINGS GEN_7 // In Gen7+ requires full HP to trigger. #define B_STANCE_CHANGE_FAIL GEN_7 // In Gen7+, Stance Change fails if the Pokémon is unable to use a move because of confusion, paralysis, etc. In Gen6, it doesn't. -#define B_GHOSTS_ESCAPE GEN_6 // In Gen6+, ghosts can escape even when blocked by abilities such as Shadow Tag. -#define B_MOODY_ACC_EVASION GEN_6 // In Gen8+, Moody CANNOT raise Accuray and Evasion any more. -#define B_FLASH_FIRE_FROZEN GEN_6 // In Gen5+, Flash Fire can trigger even when frozen, when it couldn't before. -#define B_SYNCHRONIZE_NATURE GEN_6 // In Gen8+, if the Pokémon with Synchronize is leading the party, it's 100% guaranteed that wild Pokémon will have the same ability, as opposed to 50% previously. +#define B_GHOSTS_ESCAPE GEN_7 // In Gen6+, Ghost-type Pokémon can escape even when blocked by abilities such as Shadow Tag. +#define B_MOODY_ACC_EVASION GEN_8 // In Gen8, Moody CANNOT raise Accuracy and Evasion anymore. +#define B_FLASH_FIRE_FROZEN GEN_7 // In Gen5+, Flash Fire can trigger even when frozen, when it couldn't before. +#define B_SYNCHRONIZE_NATURE GEN_8 // In Gen8, if the Pokémon with Synchronize is leading the party, it's 100% guaranteed that wild Pokémon will have the same ability, as opposed to 50% previously. #define B_UPDATED_INTIMIDATE GEN_8 // In Gen8, Intimidate doesn't work on opponents with the Inner Focus, Scrappy, Own Tempo or Oblivious abilities. // Item settings -#define B_HP_BERRIES GEN_6 // In Gen4+, berries which restore hp activate immediately after hp drops to half. In gen3, the effect occurs at the end of the turn. -#define B_BERRIES_INSTANT GEN_6 // In Gen4+, most berries activate on battle start/switch-in if applicable. In gen3, they only activate either at the move end or turn end. +#define B_HP_BERRIES GEN_7 // In Gen4+, berries which restore hp activate immediately after HP drops to half. In Gen3, the effect occurs at the end of the turn. +#define B_BERRIES_INSTANT GEN_7 // In Gen4+, most berries activate on battle start/switch-in if applicable. In Gen3, they only activate either at the move end or turn end. #define B_X_ITEMS_BUFF GEN_7 // In Gen7+, the X Items raise a stat by 2 stages instead of 1. +#define B_MENTAL_HERB GEN_5 // In Gen5+, mental herb cures Taunt, Encore, Heal Block, and Disable // Flag settings // To use the following features in scripting, replace the 0s with the flag ID you're assigning it to. @@ -153,10 +153,10 @@ // Other #define B_DOUBLE_WILD_CHANCE 0 // % chance of encountering two Pokémon in a Wild Encounter. -#define B_SLEEP_TURNS GEN_6 // In Gen5+, sleep lasts for 1-3 turns instead of 2-5 turns. -#define B_PARALYZE_ELECTRIC GEN_6 // In Gen6+, Electric-type Pokémon can't be paralyzed. -#define B_POWDER_GRASS GEN_6 // In Gen6+, Grass-type Pokémon are immune to powder and spore moves. -#define B_STEEL_RESISTANCES GEN_6 // In Gen6+, Steel-type Pokémon are no longer resistant to Dark and Ghost moves. +#define B_SLEEP_TURNS GEN_7 // In Gen5+, sleep lasts for 1-3 turns instead of 2-5 turns. +#define B_PARALYZE_ELECTRIC GEN_7 // In Gen6+, Electric-type Pokémon can't be paralyzed. +#define B_POWDER_GRASS GEN_7 // In Gen6+, Grass-type Pokémon are immune to powder and spore moves. +#define B_STEEL_RESISTANCES GEN_7 // In Gen6+, Steel-type Pokémon are no longer resistant to Dark-type and Ghost-type moves. #define B_THUNDERSTORM_TERRAIN TRUE // If TRUE, overworld Thunderstorm generates Rain and Electric Terrain as in Gen 8. // Animation Settings @@ -176,8 +176,8 @@ #define B_NEW_IMPACT_PALETTE FALSE // If set to TRUE, it updates the basic 'hit' palette. #define B_NEW_SURF_PARTICLE_PALETTE FALSE // If set to TRUE, it updates Surf's wave palette. -#define B_HIDE_HEALTHBOXES_DURING_ANIMS TRUE // If set to TRUE, hides healthboxes during move animations. -#define B_TERRAIN_BG_CHANGE TRUE // If set to TRUE, terrain moves permanently change the default battle background until the effect fades. -#define B_ENABLE_DEBUG TRUE // If set to TRUE, enables a debug menu to use in battles by pressing the Select button. +#define B_HIDE_HEALTHBOXES_DURING_ANIMS TRUE // If set to TRUE, hides healthboxes during move animations. +#define B_TERRAIN_BG_CHANGE TRUE // If set to TRUE, terrain moves permanently change the default battle background until the effect fades. +#define B_ENABLE_DEBUG TRUE // If set to TRUE, enables a debug menu to use in battles by pressing the Select button. #endif // GUARD_CONSTANTS_BATTLE_CONFIG_H diff --git a/include/constants/battle_move_effects.h b/include/constants/battle_move_effects.h index b9cf92854..931e76c58 100644 --- a/include/constants/battle_move_effects.h +++ b/include/constants/battle_move_effects.h @@ -351,9 +351,11 @@ #define EFFECT_FAIRY_LOCK 345 #define EFFECT_ALLY_SWITCH 346 #define EFFECT_SLEEP_HIT 347 // Relic Song -#define EFFECT_PHOTON_GEYSER 348 -#define EFFECT_SHELL_SIDE_ARM 349 +#define EFFECT_ATTACKER_DEFENSE_DOWN_HIT 348 +#define EFFECT_BODY_PRESS 349 +#define EFFECT_PHOTON_GEYSER 350 +#define EFFECT_SHELL_SIDE_ARM 351 -#define NUM_BATTLE_MOVE_EFFECTS 350 +#define NUM_BATTLE_MOVE_EFFECTS 352 #endif // GUARD_CONSTANTS_BATTLE_MOVE_EFFECTS_H diff --git a/include/constants/battle_string_ids.h b/include/constants/battle_string_ids.h index f929a1e87..266aef147 100644 --- a/include/constants/battle_string_ids.h +++ b/include/constants/battle_string_ids.h @@ -568,8 +568,10 @@ #define STRINGID_CURIOUSMEDICINEENTERS 564 #define STRINGID_CANACTFASTERTHANKSTO 565 #define STRINGID_MICLEBERRYACTIVATES 566 - -#define BATTLESTRINGS_COUNT 567 +#define STRINGID_PKMNSHOOKOFFTHETAUNT 567 +#define STRINGID_PKMNGOTOVERITSINFATUATION 568 + +#define BATTLESTRINGS_COUNT 569 // The below IDs are all indexes into battle message tables, // used to determine which of a set of messages to print. diff --git a/include/constants/hold_effects.h b/include/constants/hold_effects.h index 6faac46d9..3afad4f55 100644 --- a/include/constants/hold_effects.h +++ b/include/constants/hold_effects.h @@ -110,37 +110,46 @@ #define HOLD_EFFECT_ROWAP_BERRY 104 #define HOLD_EFFECT_KEE_BERRY 105 #define HOLD_EFFECT_MARANGA_BERRY 106 +#define HOLD_EFFECT_PLATE 107 // Gen5 hold effects -#define HOLD_EFFECT_FLOAT_STONE 115 -#define HOLD_EFFECT_EVIOLITE 116 -#define HOLD_EFFECT_ASSAULT_VEST 117 -#define HOLD_EFFECT_DRIVE 118 -#define HOLD_EFFECT_GEMS 119 -#define HOLD_EFFECT_ROCKY_HELMET 120 -#define HOLD_EFFECT_AIR_BALLOON 121 -#define HOLD_EFFECT_RED_CARD 122 -#define HOLD_EFFECT_RING_TARGET 123 -#define HOLD_EFFECT_BINDING_BAND 124 -#define HOLD_EFFECT_EJECT_BUTTON 125 -#define HOLD_EFFECT_ABSORB_BULB 126 -#define HOLD_EFFECT_CELL_BATTERY 127 +#define HOLD_EFFECT_FLOAT_STONE 117 +#define HOLD_EFFECT_EVIOLITE 118 +#define HOLD_EFFECT_ASSAULT_VEST 119 +#define HOLD_EFFECT_DRIVE 120 +#define HOLD_EFFECT_GEMS 121 +#define HOLD_EFFECT_ROCKY_HELMET 122 +#define HOLD_EFFECT_AIR_BALLOON 123 +#define HOLD_EFFECT_RED_CARD 124 +#define HOLD_EFFECT_RING_TARGET 125 +#define HOLD_EFFECT_BINDING_BAND 126 +#define HOLD_EFFECT_EJECT_BUTTON 127 +#define HOLD_EFFECT_ABSORB_BULB 128 +#define HOLD_EFFECT_CELL_BATTERY 129 // Gen6 hold effects -#define HOLD_EFFECT_FAIRY_POWER 129 -#define HOLD_EFFECT_MEGA_STONE 130 -#define HOLD_EFFECT_SAFETY_GOOGLES 131 -#define HOLD_EFFECT_LUMINOUS_MOSS 132 -#define HOLD_EFFECT_SNOWBALL 133 -#define HOLD_EFFECT_WEAKNESS_POLICY 134 +#define HOLD_EFFECT_FAIRY_POWER 139 +#define HOLD_EFFECT_MEGA_STONE 140 +#define HOLD_EFFECT_SAFETY_GOOGLES 141 +#define HOLD_EFFECT_LUMINOUS_MOSS 142 +#define HOLD_EFFECT_SNOWBALL 143 +#define HOLD_EFFECT_WEAKNESS_POLICY 144 // Gen7 hold effects -#define HOLD_EFFECT_PROTECTIVE_PADS 149 -#define HOLD_EFFECT_TERRAIN_EXTENDER 150 -#define HOLD_EFFECT_SEEDS 151 -#define HOLD_EFFECT_ADRENALINE_ORB 152 -#define HOLD_EFFECT_MEMORY 153 -#define HOLD_EFFECT_PLATE 154 +#define HOLD_EFFECT_PROTECTIVE_PADS 154 +#define HOLD_EFFECT_TERRAIN_EXTENDER 155 +#define HOLD_EFFECT_SEEDS 156 +#define HOLD_EFFECT_ADRENALINE_ORB 157 +#define HOLD_EFFECT_MEMORY 158 +#define HOLD_EFFECT_Z_CRYSTAL 159 + +// Gen8 hold effects +#define HOLD_EFFECT_UTILITY_UMBRELLA 169 +#define HOLD_EFFECT_EJECT_PACK 170 +#define HOLD_EFFECT_ROOM_SERVICE 171 +#define HOLD_EFFECT_BLUNDER_POLICY 172 +#define HOLD_EFFECT_HEAVY_DUTY_BOOTS 173 +#define HOLD_EFFECT_THROAT_SPRAY 174 #define HOLD_EFFECT_CHOICE(holdEffect)((holdEffect == HOLD_EFFECT_CHOICE_BAND || holdEffect == HOLD_EFFECT_CHOICE_SCARF || holdEffect == HOLD_EFFECT_CHOICE_SPECS)) diff --git a/include/constants/pokemon.h b/include/constants/pokemon.h index d11ae9391..322bee706 100644 --- a/include/constants/pokemon.h +++ b/include/constants/pokemon.h @@ -312,9 +312,9 @@ #define FLAG_POWDER (1 << 19) #define FLAG_TARGET_ABILITY_IGNORED (1 << 20) #define FLAG_DANCE (1 << 21) -#define FLAG_DMG_IN_AIR (1 << 22) // X2 dmg on air, always hits target on air -#define FLAG_HIT_IN_AIR (1 << 23) // dmg is normal, always hits target on air -#define FLAG_DAMAGE_AIRBORNE (1 << 24) // Makes a Ground type move do 1x damage to flying and levitating targets +#define FLAG_DMG_2X_IN_AIR (1 << 22) // If target is in the air, can hit and deal double damage. +#define FLAG_DMG_IN_AIR (1 << 23) // If target is in the air, can hit. +#define FLAG_DMG_UNGROUNDED_IGNORE_TYPE_IF_FLYING (1 << 24) // Makes a Ground type move do 1x damage to flying and levitating targets // Split defines. #define SPLIT_PHYSICAL 0x0 diff --git a/include/item.h b/include/item.h index 87ff57bc7..90a9c2577 100644 --- a/include/item.h +++ b/include/item.h @@ -74,5 +74,6 @@ ItemUseFunc ItemId_GetFieldFunc(u16 itemId); u8 ItemId_GetBattleUsage(u16 itemId); ItemUseFunc ItemId_GetBattleFunc(u16 itemId); u8 ItemId_GetSecondaryId(u16 itemId); +bool32 IsPinchBerryItemEffect(u16 holdEffect); #endif // GUARD_ITEM_H diff --git a/ld_script.txt b/ld_script.txt index 3976621b1..f12f513eb 100644 --- a/ld_script.txt +++ b/ld_script.txt @@ -213,7 +213,8 @@ SECTIONS { src/decoration.o(.text); src/slot_machine.o(.text); src/contest_painting.o(.text); - src/battle_ai_script_commands.o(.text); + src/battle_ai_main.o(.text); + src/battle_ai_util.o(.text); src/trader.o(.text); src/starter_choose.o(.text); src/wallclock.o(.text); @@ -345,7 +346,6 @@ SECTIONS { data/battle_scripts_1.o(script_data); data/field_effect_scripts.o(script_data); data/battle_scripts_2.o(script_data); - data/battle_ai_scripts.o(script_data); data/contest_ai_scripts.o(script_data); data/mystery_event_script_cmd_table.o(script_data); } =0 @@ -587,7 +587,8 @@ SECTIONS { src/decoration.o(.rodata); src/slot_machine.o(.rodata); src/contest_painting.o(.rodata); - src/battle_ai_script_commands.o(.rodata); + src/battle_ai_main.o(.rodata); + src/battle_ai_util.o(.rodata); src/trader.o(.rodata); src/starter_choose.o(.rodata); src/wallclock.o(.rodata); diff --git a/src/battle_ai_main.c b/src/battle_ai_main.c new file mode 100644 index 000000000..452098fec --- /dev/null +++ b/src/battle_ai_main.c @@ -0,0 +1,4976 @@ +#include "global.h" +#include "malloc.h" +#include "battle.h" +#include "battle_anim.h" +#include "battle_ai_util.h" +#include "battle_ai_main.h" +#include "battle_factory.h" +#include "battle_setup.h" +#include "data.h" +#include "item.h" +#include "pokemon.h" +#include "random.h" +#include "recorded_battle.h" +#include "util.h" +#include "constants/abilities.h" +#include "constants/battle_ai.h" +#include "constants/battle_move_effects.h" +#include "constants/hold_effects.h" +#include "constants/moves.h" +#include "constants/items.h" + +#define AI_ACTION_DONE 0x0001 +#define AI_ACTION_FLEE 0x0002 +#define AI_ACTION_WATCH 0x0004 +#define AI_ACTION_DO_NOT_ATTACK 0x0008 +#define AI_ACTION_UNK5 0x0010 +#define AI_ACTION_UNK6 0x0020 +#define AI_ACTION_UNK7 0x0040 +#define AI_ACTION_UNK8 0x0080 + +// AI states +enum +{ + AIState_SettingUp, + AIState_Processing, + AIState_FinishedProcessing, + AIState_DoNotProcess +}; + +static u8 ChooseMoveOrAction_Singles(void); +static u8 ChooseMoveOrAction_Doubles(void); +static void BattleAI_DoAIProcessing(void); + +// ewram +EWRAM_DATA const u8 *gAIScriptPtr = NULL; // Still used in contests +EWRAM_DATA u8 sBattler_AI = 0; + +// const rom data +static s16 AI_CheckBadMove(u8 battlerAtk, u8 battlerDef, u16 move, s16 score); +static s16 AI_TryToFaint(u8 battlerAtk, u8 battlerDef, u16 move, s16 score); +static s16 AI_CheckViability(u8 battlerAtk, u8 battlerDef, u16 move, s16 score); +static s16 AI_SetupFirstTurn(u8 battlerAtk, u8 battlerDef, u16 move, s16 score); +static s16 AI_Risky(u8 battlerAtk, u8 battlerDef, u16 move, s16 score); +static s16 AI_PreferStrongestMove(u8 battlerAtk, u8 battlerDef, u16 move, s16 score); +static s16 AI_PreferBatonPass(u8 battlerAtk, u8 battlerDef, u16 move, s16 score); +static s16 AI_HPAware(u8 battlerAtk, u8 battlerDef, u16 move, s16 score); +static s16 AI_Roaming(u8 battlerAtk, u8 battlerDef, u16 move, s16 score); +static s16 AI_Safari(u8 battlerAtk, u8 battlerDef, u16 move, s16 score); +static s16 AI_FirstBattle(u8 battlerAtk, u8 battlerDef, u16 move, s16 score); +static s16 AI_DoubleBattle(u8 battlerAtk, u8 battlerDef, u16 move, s16 score); + +static s16 (*const sBattleAiFuncTable[])(u8, u8, u16, s16) = +{ + [0] = AI_CheckBadMove, // AI_FLAG_CHECK_BAD_MOVE + [1] = AI_TryToFaint, // AI_FLAG_TRY_TO_FAINT + [2] = AI_CheckViability, // AI_FLAG_CHECK_VIABILITY + [3] = AI_SetupFirstTurn, // AI_FLAG_SETUP_FIRST_TURN + [4] = AI_Risky, // AI_FLAG_RISKY + [5] = AI_PreferStrongestMove, // AI_FLAG_PREFER_STRONGEST_MOVE + [6] = AI_PreferBatonPass, // AI_FLAG_PREFER_BATON_PASS + [7] = AI_DoubleBattle, // AI_FLAG_DOUBLE_BATTLE. + [8] = AI_HPAware, // AI_FLAG_HP_AWARE + [9] = NULL, // AI_FLAG_NEGATE_UNAWARE + [10] = NULL, // AI_FLAG_WILL_SUICIDE + [11] = NULL, // AI_FLAG_HELP_PARTNER + [12] = NULL, // Unused + [13] = NULL, // Unused + [14] = NULL, // Unused + [15] = NULL, // Unused + [16] = NULL, // Unused + [17] = NULL, // Unused + [18] = NULL, // Unused + [19] = NULL, // Unused + [20] = NULL, // Unused + [21] = NULL, // Unused + [22] = NULL, // Unused + [23] = NULL, // Unused + [24] = NULL, // Unused + [25] = NULL, // Unused + [26] = NULL, // Unused + [27] = NULL, // Unused + [28] = NULL, // Unused + [29] = AI_Roaming, // AI_FLAG_ROAMING + [30] = AI_Safari, // AI_FLAG_SAFARI + [31] = AI_FirstBattle, // AI_FLAG_FIRST_BATTLE +}; + +// Functions +void BattleAI_SetupItems(void) +{ + s32 i; + u8 *data = (u8 *)BATTLE_HISTORY; + + for (i = 0; i < sizeof(struct BattleHistory); i++) + data[i] = 0; + + // Items are allowed to use in ONLY trainer battles. + if ((gBattleTypeFlags & BATTLE_TYPE_TRAINER) + && !(gBattleTypeFlags & (BATTLE_TYPE_LINK | BATTLE_TYPE_SAFARI | BATTLE_TYPE_BATTLE_TOWER + | BATTLE_TYPE_EREADER_TRAINER | BATTLE_TYPE_SECRET_BASE | BATTLE_TYPE_FRONTIER + | BATTLE_TYPE_INGAME_PARTNER | BATTLE_TYPE_RECORDED_LINK) + ) + ) + { + for (i = 0; i < MAX_TRAINER_ITEMS; i++) + { + if (gTrainers[gTrainerBattleOpponent_A].items[i] != 0) + { + BATTLE_HISTORY->trainerItems[BATTLE_HISTORY->itemsNo] = gTrainers[gTrainerBattleOpponent_A].items[i]; + BATTLE_HISTORY->itemsNo++; + } + } + } +} + +void BattleAI_SetupFlags(void) +{ + if (gBattleTypeFlags & BATTLE_TYPE_RECORDED) + AI_THINKING_STRUCT->aiFlags = GetAiScriptsInRecordedBattle(); + else if (gBattleTypeFlags & BATTLE_TYPE_SAFARI) + AI_THINKING_STRUCT->aiFlags = AI_FLAG_SAFARI; + else if (gBattleTypeFlags & BATTLE_TYPE_ROAMER) + AI_THINKING_STRUCT->aiFlags = AI_FLAG_ROAMING; + else if (gBattleTypeFlags & BATTLE_TYPE_FIRST_BATTLE) + AI_THINKING_STRUCT->aiFlags = AI_FLAG_FIRST_BATTLE; + else if (gBattleTypeFlags & BATTLE_TYPE_FACTORY) + AI_THINKING_STRUCT->aiFlags = GetAiScriptsInBattleFactory(); + else if (gBattleTypeFlags & (BATTLE_TYPE_FRONTIER | BATTLE_TYPE_EREADER_TRAINER | BATTLE_TYPE_TRAINER_HILL | BATTLE_TYPE_SECRET_BASE)) + AI_THINKING_STRUCT->aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT; + else if (gBattleTypeFlags & BATTLE_TYPE_TWO_OPPONENTS) + AI_THINKING_STRUCT->aiFlags = gTrainers[gTrainerBattleOpponent_A].aiFlags | gTrainers[gTrainerBattleOpponent_B].aiFlags; + else + AI_THINKING_STRUCT->aiFlags = gTrainers[gTrainerBattleOpponent_A].aiFlags; + + if (gBattleTypeFlags & (BATTLE_TYPE_DOUBLE | BATTLE_TYPE_TWO_OPPONENTS) || gTrainers[gTrainerBattleOpponent_A].doubleBattle) + AI_THINKING_STRUCT->aiFlags |= AI_FLAG_DOUBLE_BATTLE; // Act smart in doubles and don't attack your partner. +} + +void BattleAI_SetupAIData(u8 defaultScoreMoves) +{ + s32 i, move, dmg; + u8 moveLimitations; + + // Clear AI data but preserve the flags. + u32 flags = AI_THINKING_STRUCT->aiFlags; + memset(AI_THINKING_STRUCT, 0, sizeof(struct AI_ThinkingStruct)); + AI_THINKING_STRUCT->aiFlags = flags; + + // Conditional score reset, unlike Ruby. + for (i = 0; i < MAX_MON_MOVES; i++) + { + if (defaultScoreMoves & 1) + AI_THINKING_STRUCT->score[i] = 100; + else + AI_THINKING_STRUCT->score[i] = 0; + + defaultScoreMoves >>= 1; + } + + moveLimitations = CheckMoveLimitations(gActiveBattler, 0, 0xFF); + + // Ignore moves that aren't possible to use. + for (i = 0; i < MAX_MON_MOVES; i++) + { + if (gBitTable[i] & moveLimitations) + AI_THINKING_STRUCT->score[i] = 0; + } + + sBattler_AI = gActiveBattler; + // Simulate dmg for all AI moves against all opposing targets + for (gBattlerTarget = 0; gBattlerTarget < gBattlersCount; gBattlerTarget++) + { + if (GET_BATTLER_SIDE2(sBattler_AI) == GET_BATTLER_SIDE2(gBattlerTarget)) + continue; + for (i = 0; i < MAX_MON_MOVES; i++) + { + dmg = 0; + move = gBattleMons[sBattler_AI].moves[i]; + if (gBattleMoves[move].power != 0 && !(moveLimitations & gBitTable[i])) + { + dmg = AI_CalcDamage(move, sBattler_AI, gBattlerTarget); + if (dmg == 0) + dmg = 1; + } + + AI_THINKING_STRUCT->simulatedDmg[sBattler_AI][gBattlerTarget][i] = dmg; + } + } + + gBattlerTarget = SetRandomTarget(sBattler_AI); +} + +u8 BattleAI_ChooseMoveOrAction(void) +{ + u32 savedCurrentMove = gCurrentMove; + u8 ret; + + if (!(gBattleTypeFlags & BATTLE_TYPE_DOUBLE)) + ret = ChooseMoveOrAction_Singles(); + else + ret = ChooseMoveOrAction_Doubles(); + + gCurrentMove = savedCurrentMove; + return ret; +} + +static void GetAiLogicData(u8 battlerAtk, u8 battlerDef) +{ + // attacker data + AI_DATA->atkAbility = AI_GetAbility(battlerAtk); + AI_DATA->atkItem = gBattleMons[battlerAtk].item; + AI_DATA->atkHoldEffect = AI_GetHoldEffect(battlerAtk); + AI_DATA->atkParam = GetBattlerHoldEffectParam(battlerAtk); + AI_DATA->atkSpecies = gBattleMons[battlerAtk].species; + // target data + AI_DATA->defAbility = AI_GetAbility(battlerDef); + AI_DATA->defItem = (AI_GetHoldEffect(battlerDef) == HOLD_EFFECT_NONE) ? ITEM_NONE : gBattleMons[battlerDef].item; + AI_DATA->defHoldEffect = AI_GetHoldEffect(battlerDef); + AI_DATA->defParam = GetBattlerHoldEffectParam(battlerDef); + AI_DATA->defSpecies = gBattleMons[battlerDef].species; + // attacker partner data + AI_DATA->battlerAtkPartner = BATTLE_PARTNER(battlerAtk); + AI_DATA->partnerMove = GetAllyChosenMove(); + AI_DATA->atkPartnerAbility = AI_GetAbility(AI_DATA->battlerAtkPartner); + AI_DATA->atkPartnerHoldEffect = AI_GetHoldEffect(AI_DATA->battlerAtkPartner); + // target partner data + AI_DATA->battlerDefPartner = BATTLE_PARTNER(battlerDef); + AI_DATA->defPartnerAbility = AI_GetAbility(AI_DATA->battlerDefPartner); + AI_DATA->defPartnerHoldEffect = AI_GetHoldEffect(AI_DATA->battlerDefPartner); +} + +static u8 ChooseMoveOrAction_Singles(void) +{ + u8 currentMoveArray[MAX_MON_MOVES]; + u8 consideredMoveArray[MAX_MON_MOVES]; + u32 numOfBestMoves; + s32 i, id; + u32 flags = AI_THINKING_STRUCT->aiFlags; + + RecordLastUsedMoveByTarget(); + GetAiLogicData(sBattler_AI, gBattlerTarget); + + while (flags != 0) + { + if (flags & 1) + { + AI_THINKING_STRUCT->aiState = AIState_SettingUp; + BattleAI_DoAIProcessing(); + } + flags >>= 1; + AI_THINKING_STRUCT->aiLogicId++; + AI_THINKING_STRUCT->movesetIndex = 0; + } + + for (i = 0; i < MAX_MON_MOVES; i++) + gBattleStruct->aiFinalScore[sBattler_AI][gBattlerTarget][i] = AI_THINKING_STRUCT->score[i]; + + // Check special AI actions. + if (AI_THINKING_STRUCT->aiAction & AI_ACTION_FLEE) + return AI_CHOICE_FLEE; + if (AI_THINKING_STRUCT->aiAction & AI_ACTION_WATCH) + return AI_CHOICE_WATCH; + + gActiveBattler = sBattler_AI; + // If can switch. + if (CountUsablePartyMons(sBattler_AI) > 0 + && !IsAbilityPreventingEscape(sBattler_AI) + && !(gBattleMons[gActiveBattler].status2 & (STATUS2_WRAPPED | STATUS2_ESCAPE_PREVENTION)) + && !(gStatuses3[gActiveBattler] & STATUS3_ROOTED) + && !(gBattleTypeFlags & (BATTLE_TYPE_ARENA | BATTLE_TYPE_PALACE)) + && AI_THINKING_STRUCT->aiFlags & (AI_FLAG_CHECK_VIABILITY | AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_PREFER_BATON_PASS)) + { + // Consider switching if all moves are worthless to use. + if (GetTotalBaseStat(gBattleMons[sBattler_AI].species) >= 310 // Mon is not weak. + && gBattleMons[sBattler_AI].hp >= gBattleMons[sBattler_AI].maxHP / 2) + { + s32 cap = AI_THINKING_STRUCT->aiFlags & (AI_FLAG_CHECK_VIABILITY) ? 95 : 93; + for (i = 0; i < MAX_MON_MOVES; i++) + { + if (AI_THINKING_STRUCT->score[i] > cap) + break; + } + + if (i == MAX_MON_MOVES && GetMostSuitableMonToSwitchInto() != PARTY_SIZE) + { + AI_THINKING_STRUCT->switchMon = TRUE; + return AI_CHOICE_SWITCH; + } + } + + // Consider switching if your mon with truant is bodied by Protect spam. + // Or is using a double turn semi invulnerable move(such as Fly) and is faster. + if (GetBattlerAbility(sBattler_AI) == ABILITY_TRUANT + && IsTruantMonVulnerable(sBattler_AI, gBattlerTarget) + && gDisableStructs[sBattler_AI].truantCounter + && gBattleMons[sBattler_AI].hp >= gBattleMons[sBattler_AI].maxHP / 2) + { + if (GetMostSuitableMonToSwitchInto() != PARTY_SIZE) + { + AI_THINKING_STRUCT->switchMon = TRUE; + return AI_CHOICE_SWITCH; + } + } + } + + numOfBestMoves = 1; + currentMoveArray[0] = AI_THINKING_STRUCT->score[0]; + consideredMoveArray[0] = 0; + + for (i = 1; i < MAX_MON_MOVES; i++) + { + if (gBattleMons[sBattler_AI].moves[i] != MOVE_NONE) + { + // In ruby, the order of these if statements is reversed. + if (currentMoveArray[0] == AI_THINKING_STRUCT->score[i]) + { + currentMoveArray[numOfBestMoves] = AI_THINKING_STRUCT->score[i]; + consideredMoveArray[numOfBestMoves++] = i; + } + if (currentMoveArray[0] < AI_THINKING_STRUCT->score[i]) + { + numOfBestMoves = 1; + currentMoveArray[0] = AI_THINKING_STRUCT->score[i]; + consideredMoveArray[0] = i; + } + } + } + return consideredMoveArray[Random() % numOfBestMoves]; +} + +static u8 ChooseMoveOrAction_Doubles(void) +{ + s32 i, j; + u32 flags; + s16 bestMovePointsForTarget[MAX_BATTLERS_COUNT]; + s8 mostViableTargetsArray[MAX_BATTLERS_COUNT]; + u8 actionOrMoveIndex[MAX_BATTLERS_COUNT]; + u8 mostViableMovesScores[MAX_MON_MOVES]; + u8 mostViableMovesIndices[MAX_MON_MOVES]; + s32 mostViableTargetsNo; + s32 mostViableMovesNo; + s16 mostMovePoints; + + for (i = 0; i < MAX_BATTLERS_COUNT; i++) + { + if (i == sBattler_AI || gBattleMons[i].hp == 0) + { + actionOrMoveIndex[i] = 0xFF; + bestMovePointsForTarget[i] = -1; + } + else + { + if (gBattleTypeFlags & BATTLE_TYPE_PALACE) + BattleAI_SetupAIData(gBattleStruct->palaceFlags >> 4); + else + BattleAI_SetupAIData(0xF); + + gBattlerTarget = i; + GetAiLogicData(sBattler_AI, gBattlerTarget); + + if ((i & BIT_SIDE) != (sBattler_AI & BIT_SIDE)) + RecordLastUsedMoveByTarget(); + + AI_THINKING_STRUCT->aiLogicId = 0; + AI_THINKING_STRUCT->movesetIndex = 0; + flags = AI_THINKING_STRUCT->aiFlags; + while (flags != 0) + { + if (flags & 1) + { + AI_THINKING_STRUCT->aiState = AIState_SettingUp; + BattleAI_DoAIProcessing(); + } + flags >>= 1; + AI_THINKING_STRUCT->aiLogicId++; + AI_THINKING_STRUCT->movesetIndex = 0; + } + + if (AI_THINKING_STRUCT->aiAction & AI_ACTION_FLEE) + { + actionOrMoveIndex[i] = AI_CHOICE_FLEE; + } + else if (AI_THINKING_STRUCT->aiAction & AI_ACTION_WATCH) + { + actionOrMoveIndex[i] = AI_CHOICE_WATCH; + } + else + { + mostViableMovesScores[0] = AI_THINKING_STRUCT->score[0]; + mostViableMovesIndices[0] = 0; + mostViableMovesNo = 1; + for (j = 1; j < MAX_MON_MOVES; j++) + { + if (gBattleMons[sBattler_AI].moves[j] != 0) + { + if (mostViableMovesScores[0] == AI_THINKING_STRUCT->score[j]) + { + mostViableMovesScores[mostViableMovesNo] = AI_THINKING_STRUCT->score[j]; + mostViableMovesIndices[mostViableMovesNo] = j; + mostViableMovesNo++; + } + if (mostViableMovesScores[0] < AI_THINKING_STRUCT->score[j]) + { + mostViableMovesScores[0] = AI_THINKING_STRUCT->score[j]; + mostViableMovesIndices[0] = j; + mostViableMovesNo = 1; + } + } + } + actionOrMoveIndex[i] = mostViableMovesIndices[Random() % mostViableMovesNo]; + bestMovePointsForTarget[i] = mostViableMovesScores[0]; + + // Don't use a move against ally if it has less than 100 points. + if (i == (sBattler_AI ^ BIT_FLANK) && bestMovePointsForTarget[i] < 100) + { + bestMovePointsForTarget[i] = -1; + mostViableMovesScores[0] = mostViableMovesScores[0]; // Needed to match. + } + } + + for (j = 0; j < MAX_MON_MOVES; j++) + gBattleStruct->aiFinalScore[sBattler_AI][gBattlerTarget][j] = AI_THINKING_STRUCT->score[j]; + } + } + + mostMovePoints = bestMovePointsForTarget[0]; + mostViableTargetsArray[0] = 0; + mostViableTargetsNo = 1; + + for (i = 1; i < MAX_BATTLERS_COUNT; i++) + { + if (mostMovePoints == bestMovePointsForTarget[i]) + { + mostViableTargetsArray[mostViableTargetsNo] = i; + mostViableTargetsNo++; + } + if (mostMovePoints < bestMovePointsForTarget[i]) + { + mostMovePoints = bestMovePointsForTarget[i]; + mostViableTargetsArray[0] = i; + mostViableTargetsNo = 1; + } + } + + gBattlerTarget = mostViableTargetsArray[Random() % mostViableTargetsNo]; + return actionOrMoveIndex[gBattlerTarget]; +} + +static void BattleAI_DoAIProcessing(void) +{ + while (AI_THINKING_STRUCT->aiState != AIState_FinishedProcessing) + { + switch (AI_THINKING_STRUCT->aiState) + { + case AIState_DoNotProcess: // Needed to match. + break; + case AIState_SettingUp: + if (gBattleMons[sBattler_AI].pp[AI_THINKING_STRUCT->movesetIndex] == 0) + { + AI_THINKING_STRUCT->moveConsidered = 0; + } + else + { + AI_THINKING_STRUCT->moveConsidered = gBattleMons[sBattler_AI].moves[AI_THINKING_STRUCT->movesetIndex]; + } + AI_THINKING_STRUCT->aiState++; + break; + case AIState_Processing: + if (AI_THINKING_STRUCT->moveConsidered != MOVE_NONE + && AI_THINKING_STRUCT->score[AI_THINKING_STRUCT->movesetIndex] > 0) + { + if (AI_THINKING_STRUCT->aiLogicId < ARRAY_COUNT(sBattleAiFuncTable) + && sBattleAiFuncTable[AI_THINKING_STRUCT->aiLogicId] != NULL) + { + // Call AI function + AI_THINKING_STRUCT->score[AI_THINKING_STRUCT->movesetIndex] = + sBattleAiFuncTable[AI_THINKING_STRUCT->aiLogicId](sBattler_AI, + gBattlerTarget, + AI_THINKING_STRUCT->moveConsidered, + AI_THINKING_STRUCT->score[AI_THINKING_STRUCT->movesetIndex]); + } + } + else + { + AI_THINKING_STRUCT->score[AI_THINKING_STRUCT->movesetIndex] = 0; + } + + AI_THINKING_STRUCT->movesetIndex++; + if (AI_THINKING_STRUCT->movesetIndex < MAX_MON_MOVES && !(AI_THINKING_STRUCT->aiAction & AI_ACTION_DO_NOT_ATTACK)) + AI_THINKING_STRUCT->aiState = AIState_SettingUp; + else + AI_THINKING_STRUCT->aiState++; + break; + } + } +} + +// AI Score Functions +// AI_FLAG_CHECK_BAD_MOVE - decreases move scores +static s16 AI_CheckBadMove(u8 battlerAtk, u8 battlerDef, u16 move, s16 score) +{ + // move data + u8 atkPriority = GetMovePriority(battlerAtk, move); + u16 moveEffect = gBattleMoves[move].effect; + u8 moveType = gBattleMoves[move].type; + u8 moveTarget = gBattleMoves[move].target; + u16 accuracy = AI_GetMoveAccuracy(battlerAtk, battlerDef, AI_DATA->atkAbility, AI_DATA->defAbility, AI_DATA->atkHoldEffect, AI_DATA->defHoldEffect, move); + u8 effectiveness = AI_GetMoveEffectiveness(move, battlerAtk, battlerDef); + bool32 isDoubleBattle = IsValidDoubleBattle(battlerAtk); + u32 i; + u16 predictedMove = gLastMoves[battlerDef]; // TODO better move prediction + + if (IsTargetingPartner(battlerAtk, battlerDef)) + return score; + + // check non-user target + if (!(gBattleMoves[move].target & MOVE_TARGET_USER)) + { + // handle negative checks on non-user target + // check powder moves + if (TestMoveFlags(move, FLAG_POWDER) && !IsAffectedByPowder(battlerDef, AI_DATA->defAbility, AI_DATA->defHoldEffect)) + { + RETURN_SCORE_MINUS(20); + } + + // check ground immunities + if (moveType == TYPE_GROUND + && !IsBattlerGrounded(battlerDef) + && ((AI_DATA->defAbility == ABILITY_LEVITATE + && DoesBattlerIgnoreAbilityChecks(AI_DATA->atkAbility, move)) + || AI_DATA->defHoldEffect == HOLD_EFFECT_AIR_BALLOON + || (gStatuses3[battlerDef] & (STATUS3_MAGNET_RISE | STATUS3_TELEKINESIS))) + && move != MOVE_THOUSAND_ARROWS) + { + RETURN_SCORE_MINUS(20); + } + + // check off screen + if (IsSemiInvulnerable(battlerDef, move) && moveEffect != EFFECT_SEMI_INVULNERABLE && GetWhoStrikesFirst(battlerAtk, battlerDef, TRUE) != 1) + RETURN_SCORE_MINUS(20); // if target off screen and we go first, don't use move + + // check if negates type + switch (effectiveness) + { + case AI_EFFECTIVENESS_x0: + RETURN_SCORE_MINUS(20); + break; + case AI_EFFECTIVENESS_x0_25: + RETURN_SCORE_MINUS(10); + break; + } + + // target ability checks + if (!DoesBattlerIgnoreAbilityChecks(AI_DATA->atkAbility, move)) + { + switch (AI_DATA->defAbility) + { + case ABILITY_VOLT_ABSORB: + case ABILITY_MOTOR_DRIVE: + case ABILITY_LIGHTNING_ROD: + if (moveType == TYPE_ELECTRIC) + RETURN_SCORE_MINUS(20); + break; + case ABILITY_WATER_ABSORB: + case ABILITY_DRY_SKIN: + case ABILITY_STORM_DRAIN: + if (moveType == TYPE_WATER) + RETURN_SCORE_MINUS(20); + break; + case ABILITY_FLASH_FIRE: + if (moveType == TYPE_FIRE) + RETURN_SCORE_MINUS(20); + break; + case ABILITY_WONDER_GUARD: + if (effectiveness != AI_EFFECTIVENESS_x2 && effectiveness != AI_EFFECTIVENESS_x4) + return 0; + break; + case ABILITY_SAP_SIPPER: + if (moveType == TYPE_GRASS) + RETURN_SCORE_MINUS(20); + break; + case ABILITY_JUSTIFIED: + if (moveType == TYPE_DARK && !IS_MOVE_STATUS(move)) + RETURN_SCORE_MINUS(10); + break; + case ABILITY_RATTLED: + if (!IS_MOVE_STATUS(move) + && (moveType == TYPE_DARK || moveType == TYPE_GHOST || moveType == TYPE_BUG)) + RETURN_SCORE_MINUS(10); + break; + case ABILITY_SOUNDPROOF: + if (TestMoveFlags(move, FLAG_SOUND)) + RETURN_SCORE_MINUS(10); + break; + case ABILITY_BULLETPROOF: + if (TestMoveFlags(move, FLAG_BALLISTIC)) + RETURN_SCORE_MINUS(10); + break; + case ABILITY_DAZZLING: + case ABILITY_QUEENLY_MAJESTY: + if (atkPriority > 0) + RETURN_SCORE_MINUS(10); + break; + case ABILITY_AROMA_VEIL: + if (IsAromaVeilProtectedMove(move)) + RETURN_SCORE_MINUS(10); + break; + case ABILITY_SWEET_VEIL: + if (moveEffect == EFFECT_SLEEP || moveEffect == EFFECT_YAWN) + RETURN_SCORE_MINUS(10); + break; + case ABILITY_FLOWER_VEIL: + if (IS_BATTLER_OF_TYPE(battlerDef, TYPE_GRASS) && (IsNonVolatileStatusMoveEffect(moveEffect) || IsStatLoweringMoveEffect(moveEffect))) + RETURN_SCORE_MINUS(10); + break; + case ABILITY_MAGIC_BOUNCE: + if (TestMoveFlags(move, FLAG_MAGIC_COAT_AFFECTED)) + RETURN_SCORE_MINUS(20); + break; + case ABILITY_CONTRARY: + if (IsStatLoweringMoveEffect(moveEffect)) + RETURN_SCORE_MINUS(20); + break; + case ABILITY_CLEAR_BODY: + case ABILITY_FULL_METAL_BODY: + case ABILITY_WHITE_SMOKE: + if (IsStatLoweringMoveEffect(moveEffect)) + RETURN_SCORE_MINUS(10); + break; + case ABILITY_HYPER_CUTTER: + if ((moveEffect == EFFECT_ATTACK_DOWN || moveEffect == EFFECT_ATTACK_DOWN_2) + && move != MOVE_PLAY_NICE && move != MOVE_NOBLE_ROAR && move != MOVE_TEARFUL_LOOK && move != MOVE_VENOM_DRENCH) + RETURN_SCORE_MINUS(10); + break; + case ABILITY_KEEN_EYE: + if (moveEffect == EFFECT_ACCURACY_DOWN || moveEffect == EFFECT_ACCURACY_DOWN_2) + RETURN_SCORE_MINUS(10); + break; + case ABILITY_BIG_PECKS: + if (moveEffect == EFFECT_DEFENSE_DOWN || moveEffect == EFFECT_DEFENSE_DOWN_2) + RETURN_SCORE_MINUS(10); + break; + case ABILITY_DEFIANT: + case ABILITY_COMPETITIVE: + if (IsStatLoweringMoveEffect(moveEffect) && !IsTargetingPartner(battlerAtk, battlerDef)) + RETURN_SCORE_MINUS(8); + break; + case ABILITY_COMATOSE: + if (IsNonVolatileStatusMoveEffect(moveEffect)) + RETURN_SCORE_MINUS(10); + break; + case ABILITY_SHIELDS_DOWN: + if (IsShieldsDownProtected(battlerAtk) && IsNonVolatileStatusMoveEffect(moveEffect)) + RETURN_SCORE_MINUS(10); + break; + case ABILITY_WONDER_SKIN: + if (IS_MOVE_STATUS(move)) + accuracy = 50; + break; + case ABILITY_LEAF_GUARD: + if (AI_WeatherHasEffect() && (gBattleWeather & WEATHER_SUN_ANY) + && AI_DATA->defHoldEffect != HOLD_EFFECT_UTILITY_UMBRELLA + && IsNonVolatileStatusMoveEffect(moveEffect)) + RETURN_SCORE_MINUS(10); + break; + } // def ability checks + + // target partner ability checks & not attacking partner + if (isDoubleBattle) + { + switch (AI_DATA->defPartnerAbility) + { + case ABILITY_LIGHTNING_ROD: + if (moveType == TYPE_ELECTRIC && !IsMoveRedirectionPrevented(move, AI_DATA->atkAbility)) + RETURN_SCORE_MINUS(20); + break; + case ABILITY_STORM_DRAIN: + if (moveType == TYPE_WATER && !IsMoveRedirectionPrevented(move, AI_DATA->atkAbility)) + RETURN_SCORE_MINUS(20); + break; + case ABILITY_MAGIC_BOUNCE: + if (TestMoveFlags(move, FLAG_MAGIC_COAT_AFFECTED) && moveTarget & (MOVE_TARGET_BOTH | MOVE_TARGET_FOES_AND_ALLY | MOVE_TARGET_OPPONENTS_FIELD)) + RETURN_SCORE_MINUS(20); + break; + case ABILITY_SWEET_VEIL: + if (moveEffect == EFFECT_SLEEP || moveEffect == EFFECT_YAWN) + RETURN_SCORE_MINUS(20); + break; + case ABILITY_FLOWER_VEIL: + if ((IS_BATTLER_OF_TYPE(battlerDef, TYPE_GRASS)) && (IsNonVolatileStatusMoveEffect(moveEffect) || IsStatLoweringMoveEffect(moveEffect))) + RETURN_SCORE_MINUS(10); + break; + case ABILITY_AROMA_VEIL: + if (IsAromaVeilProtectedMove(move)) + RETURN_SCORE_MINUS(10); + break; + case ABILITY_DAZZLING: + case ABILITY_QUEENLY_MAJESTY: + if (atkPriority > 0) + RETURN_SCORE_MINUS(10); + break; + } + } // def partner ability checks + } // ignore def ability check + + // gen7+ dark type mons immune to priority->elevated moves from prankster + #if B_PRANKSTER >= GEN_7 + if (AI_DATA->atkAbility == ABILITY_PRANKSTER && IS_BATTLER_OF_TYPE(battlerDef, TYPE_DARK) && IS_MOVE_STATUS(move) + && !(moveTarget & (MOVE_TARGET_OPPONENTS_FIELD | MOVE_TARGET_USER))) + RETURN_SCORE_MINUS(10); + #endif + + // terrain & effect checks + if (gFieldStatuses & STATUS_FIELD_MISTY_TERRAIN) + { + if (moveEffect == EFFECT_SLEEP || moveEffect == EFFECT_YAWN) + RETURN_SCORE_MINUS(20); + } + + if (gFieldStatuses & STATUS_FIELD_ELECTRIC_TERRAIN) + { + if (IsNonVolatileStatusMoveEffect(moveEffect) || IsConfusionMoveEffect(moveEffect)) + RETURN_SCORE_MINUS(20); + } + + if (gFieldStatuses & STATUS_FIELD_PSYCHIC_TERRAIN) + { + if (atkPriority > 0) + RETURN_SCORE_MINUS(20); + } + } // end check MOVE_TARGET_USER + +// the following checks apply to any target (including user) + + // throat chop check + if (gDisableStructs[battlerAtk].throatChopTimer && TestMoveFlags(move, FLAG_SOUND)) + return 0; // Can't even select move at all + // heal block check + if (gStatuses3[battlerAtk] & STATUS3_HEAL_BLOCK && IsHealBlockPreventingMove(battlerAtk, move)) + return 0; // Can't even select heal blocked move + // primal weather check + //TODO + + // check move effects + switch (moveEffect) + { + case EFFECT_HIT: + default: + break; // check move damage + case EFFECT_SLEEP: + if (!AI_CanPutToSleep(battlerAtk, battlerDef, AI_DATA->defAbility, move, AI_DATA->partnerMove)) + score -= 10; + break; + case EFFECT_EXPLOSION: + if (!(AI_THINKING_STRUCT->aiFlags & AI_FLAG_WILL_SUICIDE)) + score -= 2; + + if (effectiveness == AI_EFFECTIVENESS_x0) + { + score -= 10; + } + else if (IsAbilityOnField(ABILITY_DAMP) && !DoesBattlerIgnoreAbilityChecks(AI_DATA->atkAbility, move)) + { + score -= 10; + } + else if (CountUsablePartyMons(battlerAtk) == 0) + { + if (CountUsablePartyMons(battlerDef) != 0) + score -= 10; + else + score--; + } + break; + case EFFECT_DREAM_EATER: + if (!(gBattleMons[battlerDef].status1 & STATUS1_SLEEP) || AI_DATA->defAbility == ABILITY_COMATOSE) + score -= 8; + else if (effectiveness == AI_EFFECTIVENESS_x0) + score -= 10; + break; + // stat raising effects + case EFFECT_ATTACK_UP: + case EFFECT_ATTACK_UP_2: + if (!BattlerStatCanRise(battlerAtk, AI_DATA->atkAbility, STAT_ATK) || !HasMoveWithSplit(battlerAtk, SPLIT_PHYSICAL)) + score -= 10; + break; + case EFFECT_DEFENSE_UP_2: + if (move == MOVE_STUFF_CHEEKS && ItemId_GetPocket(gBattleMons[battlerAtk].item) != POCKET_BERRIES) + score -= 10; + //fallthrough + case EFFECT_DEFENSE_UP: + case EFFECT_DEFENSE_UP_3: + case EFFECT_DEFENSE_CURL: + if (!BattlerStatCanRise(battlerAtk, AI_DATA->atkAbility, STAT_DEF)) + score -= 10; + break; + case EFFECT_SPEED_UP: + case EFFECT_SPEED_UP_2: + if (!BattlerStatCanRise(battlerAtk, AI_DATA->atkAbility, STAT_SPEED)) + score -= 10; + break; + case EFFECT_SPECIAL_ATTACK_UP: + case EFFECT_SPECIAL_ATTACK_UP_2: + case EFFECT_SPECIAL_ATTACK_UP_3: + if (!BattlerStatCanRise(battlerAtk, AI_DATA->atkAbility, STAT_SPATK) || !HasMoveWithSplit(battlerAtk, SPLIT_SPECIAL)) + score -= 10; + break; + case EFFECT_SPECIAL_DEFENSE_UP: + case EFFECT_SPECIAL_DEFENSE_UP_2: + if (!BattlerStatCanRise(battlerAtk, AI_DATA->atkAbility, STAT_SPDEF)) + score -= 10; + break; + case EFFECT_ACCURACY_UP: + case EFFECT_ACCURACY_UP_2: + if (!BattlerStatCanRise(battlerAtk, AI_DATA->atkAbility, STAT_ACC)) + score -= 10; + break; + case EFFECT_EVASION_UP: + case EFFECT_EVASION_UP_2: + case EFFECT_MINIMIZE: + if (!BattlerStatCanRise(battlerAtk, AI_DATA->atkAbility, STAT_EVASION)) + score -= 10; + break; + case EFFECT_COSMIC_POWER: + if (!BattlerStatCanRise(battlerAtk, AI_DATA->atkAbility, STAT_DEF)) + score -= 10; + else if (!BattlerStatCanRise(battlerAtk, AI_DATA->atkAbility, STAT_SPDEF)) + score -= 8; + break; + case EFFECT_BULK_UP: + if (!BattlerStatCanRise(battlerAtk, AI_DATA->atkAbility, STAT_ATK) || !HasMoveWithSplit(battlerAtk, SPLIT_PHYSICAL)) + score -= 10; + else if (!BattlerStatCanRise(battlerAtk, AI_DATA->atkAbility, STAT_DEF)) + score -= 8; + break; + case EFFECT_CALM_MIND: + if (!BattlerStatCanRise(battlerAtk, AI_DATA->atkAbility, STAT_SPATK)) + score -= 10; + else if (!BattlerStatCanRise(battlerAtk, AI_DATA->atkAbility, STAT_SPDEF)) + score -= 8; + break; + case EFFECT_DRAGON_DANCE: + if (!BattlerStatCanRise(battlerAtk, AI_DATA->atkAbility, STAT_ATK) || !HasMoveWithSplit(battlerAtk, SPLIT_PHYSICAL)) + score -= 10; + else if (!BattlerStatCanRise(battlerAtk, AI_DATA->atkAbility, STAT_SPEED)) + score -= 8; + break; + case EFFECT_COIL: + if (!BattlerStatCanRise(battlerAtk, AI_DATA->atkAbility, STAT_ACC)) + score -= 10; + else if (!BattlerStatCanRise(battlerAtk, AI_DATA->atkAbility, STAT_ATK) || !HasMoveWithSplit(battlerAtk, SPLIT_PHYSICAL)) + score -= 8; + else if (!BattlerStatCanRise(battlerAtk, AI_DATA->atkAbility, STAT_DEF)) + score -= 6; + break; + case EFFECT_ATTACK_ACCURACY_UP: //hone claws + if (AI_DATA->atkAbility != ABILITY_CONTRARY) + { + if (gBattleMons[battlerAtk].statStages[STAT_ATK] >= MAX_STAT_STAGE + && (gBattleMons[battlerAtk].statStages[STAT_ACC] >= MAX_STAT_STAGE || !HasMoveWithSplit(battlerAtk, SPLIT_PHYSICAL))) + score -= 10; + break; + } + else + { + score -= 10; + } + break; + case EFFECT_CHARGE: + if (gStatuses3[battlerAtk] & STATUS3_CHARGED_UP) + score -= 20; + else if (!HasMoveWithType(battlerAtk, TYPE_ELECTRIC)) + score -= 10; + else if (!BattlerStatCanRise(battlerAtk, AI_DATA->atkAbility, STAT_SPDEF)) + score -= 5; + break; + case EFFECT_QUIVER_DANCE: + case EFFECT_GEOMANCY: + if (gBattleMons[battlerAtk].statStages[STAT_SPATK] >= MAX_STAT_STAGE || !HasMoveWithSplit(battlerAtk, SPLIT_SPECIAL)) + score -= 10; + else if (!BattlerStatCanRise(battlerAtk, AI_DATA->atkAbility, STAT_SPEED)) + score -= 8; + else if (!BattlerStatCanRise(battlerAtk, AI_DATA->atkAbility, STAT_SPDEF)) + score -= 6; + break; + case EFFECT_SHIFT_GEAR: + if (!BattlerStatCanRise(battlerAtk, AI_DATA->atkAbility, STAT_ATK) || !HasMoveWithSplit(battlerAtk, SPLIT_PHYSICAL)) + score -= 10; + else if (!BattlerStatCanRise(battlerAtk, AI_DATA->atkAbility, STAT_SPEED)) + score -= 8; + break; + case EFFECT_SHELL_SMASH: + if (AI_DATA->atkAbility == ABILITY_CONTRARY) + { + if (!BattlerStatCanRise(battlerAtk, AI_DATA->atkAbility, STAT_DEF)) + score -= 10; + else if (!BattlerStatCanRise(battlerAtk, AI_DATA->atkAbility, STAT_SPDEF)) + score -= 8; + } + else + { + if (!BattlerStatCanRise(battlerAtk, AI_DATA->atkAbility, STAT_ATK) || !HasMoveWithSplit(battlerAtk, SPLIT_PHYSICAL)) + score -= 10; + else if (!BattlerStatCanRise(battlerAtk, AI_DATA->atkAbility, STAT_SPATK) || !HasMoveWithSplit(battlerAtk, SPLIT_SPECIAL)) + score -= 8; + else if (!BattlerStatCanRise(battlerAtk, AI_DATA->atkAbility, STAT_SPEED)) + score -= 6; + } + break; + case EFFECT_GROWTH: + case EFFECT_ATTACK_SPATK_UP: // work up + if (!BattlerStatCanRise(battlerAtk, AI_DATA->atkAbility, STAT_ATK) || !HasMoveWithSplit(battlerAtk, SPLIT_PHYSICAL)) + score -= 10; + else if (!BattlerStatCanRise(battlerAtk, AI_DATA->atkAbility, STAT_SPATK) || !HasMoveWithSplit(battlerAtk, SPLIT_SPECIAL)) + score -= 8; + break; + case EFFECT_ROTOTILLER: + if (isDoubleBattle) + { + if (!(IS_BATTLER_OF_TYPE(battlerAtk, TYPE_GRASS) + && AI_IsBattlerGrounded(battlerAtk) + && (BattlerStatCanRise(battlerAtk, AI_DATA->atkAbility, STAT_ATK) || BattlerStatCanRise(battlerAtk, AI_DATA->atkAbility, STAT_SPATK))) + && !(IS_BATTLER_OF_TYPE(AI_DATA->battlerAtkPartner, TYPE_GRASS) + && AI_IsBattlerGrounded(AI_DATA->battlerAtkPartner) + && AI_DATA->atkPartnerAbility != ABILITY_CONTRARY + && (BattlerStatCanRise(AI_DATA->battlerAtkPartner, AI_DATA->atkPartnerAbility, STAT_ATK) + || BattlerStatCanRise(AI_DATA->battlerAtkPartner, AI_DATA->atkPartnerAbility, STAT_SPATK)))) + { + score -= 10; + } + } + else if (!(IS_BATTLER_OF_TYPE(battlerAtk, TYPE_GRASS) + && AI_IsBattlerGrounded(battlerAtk) + && (BattlerStatCanRise(battlerAtk, AI_DATA->atkAbility, STAT_ATK) || BattlerStatCanRise(battlerAtk, AI_DATA->atkAbility, STAT_SPATK)))) + { + score -= 10; + } + break; + case EFFECT_GEAR_UP: + if (AI_DATA->atkAbility == ABILITY_PLUS || AI_DATA->atkAbility == ABILITY_MINUS) + { + // same as growth, work up + if (!BattlerStatCanRise(battlerAtk, AI_DATA->atkAbility, STAT_ATK) || !HasMoveWithSplit(battlerAtk, SPLIT_PHYSICAL)) + score -= 10; + else if (!BattlerStatCanRise(battlerAtk, AI_DATA->atkAbility, STAT_SPATK) || !HasMoveWithSplit(battlerAtk, SPLIT_SPECIAL)) + score -= 8; + break; + } + else if (!isDoubleBattle) + { + score -= 10; // no partner and our stats wont rise, so don't use + } + + if (isDoubleBattle) + { + if (AI_DATA->atkPartnerAbility == ABILITY_PLUS || AI_DATA->atkPartnerAbility == ABILITY_MINUS) + { + if ((!BattlerStatCanRise(AI_DATA->battlerAtkPartner, AI_DATA->atkPartnerAbility, STAT_ATK) || !HasMoveWithSplit(battlerAtk, SPLIT_PHYSICAL)) + && (!BattlerStatCanRise(AI_DATA->battlerAtkPartner, AI_DATA->atkPartnerAbility, STAT_SPATK) || !HasMoveWithSplit(battlerAtk, SPLIT_SPECIAL))) + score -= 10; + } + else if (AI_DATA->atkAbility != ABILITY_PLUS && AI_DATA->atkAbility != ABILITY_MINUS) + { + score -= 10; // nor our or our partner's ability is plus/minus + } + } + break; + case EFFECT_ACUPRESSURE: + if (DoesSubstituteBlockMove(battlerAtk, battlerDef, move) || AreBattlersStatsMaxed(battlerDef)) + score -= 10; + break; + case EFFECT_MAGNETIC_FLUX: + if (AI_DATA->atkAbility == ABILITY_PLUS || AI_DATA->atkAbility == ABILITY_MINUS) + { + if (!BattlerStatCanRise(battlerAtk, AI_DATA->atkAbility, STAT_DEF)) + score -= 10; + else if (!BattlerStatCanRise(battlerAtk, AI_DATA->atkAbility, STAT_SPDEF)) + score -= 8; + } + else if (!isDoubleBattle) + { + score -= 10; // our stats wont rise from this move + } + + if (isDoubleBattle) + { + if (AI_DATA->atkPartnerAbility == ABILITY_PLUS || AI_DATA->atkPartnerAbility == ABILITY_MINUS) + { + if (!BattlerStatCanRise(AI_DATA->battlerAtkPartner, AI_DATA->atkPartnerAbility, STAT_DEF)) + score -= 10; + else if (!BattlerStatCanRise(AI_DATA->battlerAtkPartner, AI_DATA->atkPartnerAbility, STAT_SPDEF)) + score -= 8; + } + else if (AI_DATA->atkAbility != ABILITY_PLUS && AI_DATA->atkAbility != ABILITY_MINUS) + { + score -= 10; // nor our or our partner's ability is plus/minus + } + } + break; + // stat lowering effects + case EFFECT_ATTACK_DOWN: + case EFFECT_ATTACK_DOWN_2: + if (!ShouldLowerStat(battlerDef, AI_DATA->defAbility, STAT_ATK)) //|| !HasMoveWithSplit(battlerDef, SPLIT_PHYSICAL)) + score -= 10; + else if (AI_DATA->defAbility == ABILITY_HYPER_CUTTER) + score -= 10; + break; + case EFFECT_DEFENSE_DOWN: + case EFFECT_DEFENSE_DOWN_2: + if (!ShouldLowerStat(battlerDef, AI_DATA->defAbility, STAT_DEF)) + score -= 10; + break; + case EFFECT_SPEED_DOWN: + case EFFECT_SPEED_DOWN_2: + if (!ShouldLowerStat(battlerDef, AI_DATA->defAbility, STAT_SPEED)) + score -= 10; + else if (AI_DATA->defAbility == ABILITY_SPEED_BOOST) + score -= 10; + break; + case EFFECT_SPECIAL_ATTACK_DOWN: + case EFFECT_SPECIAL_ATTACK_DOWN_2: + if (!ShouldLowerStat(battlerDef, AI_DATA->defAbility, STAT_SPATK)) //|| !HasMoveWithSplit(battlerDef, SPLIT_SPECIAL)) + score -= 10; + break; + case EFFECT_SPECIAL_DEFENSE_DOWN: + case EFFECT_SPECIAL_DEFENSE_DOWN_2: + if (!ShouldLowerStat(battlerDef, AI_DATA->defAbility, STAT_SPDEF)) + score -= 10; + break; + case EFFECT_ACCURACY_DOWN: + case EFFECT_ACCURACY_DOWN_2: + if (!ShouldLowerStat(battlerDef, AI_DATA->defAbility, STAT_ACC)) + score -= 10; + else if (AI_DATA->defAbility == ABILITY_KEEN_EYE) + score -= 8; + break; + case EFFECT_EVASION_DOWN: + case EFFECT_EVASION_DOWN_2: + if (!ShouldLowerStat(battlerDef, AI_DATA->defAbility, STAT_EVASION)) + score -= 10; + break; + case EFFECT_TICKLE: + if (!ShouldLowerStat(battlerDef, AI_DATA->defAbility, STAT_ATK)) + score -= 10; + else if (!ShouldLowerStat(battlerDef, AI_DATA->defAbility, STAT_DEF)) + score -= 8; + break; + case EFFECT_VENOM_DRENCH: + if (!(gBattleMons[battlerDef].status1 & STATUS1_PSN_ANY)) + { + score -= 10; + } + else + { + if (!ShouldLowerStat(battlerDef, AI_DATA->defAbility, STAT_SPEED)) + score -= 10; + else if (!ShouldLowerStat(battlerDef, AI_DATA->defAbility, STAT_SPATK)) + score -= 8; + else if (!ShouldLowerStat(battlerDef, AI_DATA->defAbility, STAT_ATK)) + score -= 6; + } + break; + case EFFECT_NOBLE_ROAR: + if (!ShouldLowerStat(battlerDef, AI_DATA->defAbility, STAT_SPATK)) + score -= 10; + else if (!ShouldLowerStat(battlerDef, AI_DATA->defAbility, STAT_ATK)) + score -= 8; + break; + case EFFECT_CAPTIVATE: + { + u8 atkGender = GetGenderFromSpeciesAndPersonality(gBattleMons[battlerAtk].species, gBattleMons[battlerAtk].personality); + u8 defGender = GetGenderFromSpeciesAndPersonality(gBattleMons[battlerDef].species, gBattleMons[battlerDef].personality); + if (atkGender == MON_GENDERLESS || defGender == MON_GENDERLESS || atkGender == defGender) + score -= 10; + } + break; + // other + case EFFECT_HAZE: + if (PartnerHasSameMoveEffectWithoutTarget(AI_DATA->battlerAtkPartner, move, AI_DATA->partnerMove)) + { + score -= 10; // partner already using haze + } + else + { + for (i = STAT_ATK; i < NUM_BATTLE_STATS; i++) + { + if (gBattleMons[battlerAtk].statStages[i] > DEFAULT_STAT_STAGE || gBattleMons[AI_DATA->battlerAtkPartner].statStages[i] > DEFAULT_STAT_STAGE) + score -= 10; // Don't want to reset our boosted stats + } + for (i = STAT_ATK; i < NUM_BATTLE_STATS; i++) + { + if (gBattleMons[battlerDef].statStages[i] < DEFAULT_STAT_STAGE || gBattleMons[AI_DATA->battlerDefPartner].statStages[i] < DEFAULT_STAT_STAGE) + score -= 10; //Don't want to reset enemy lowered stats + } + } + break; + //case EFFECT_BIDE: + //case EFFECT_SUPER_FANG: + //case EFFECT_RECHARGE: + case EFFECT_LEVEL_DAMAGE: + case EFFECT_PSYWAVE: + //case EFFECT_COUNTER: + //case EFFECT_FLAIL: + case EFFECT_RETURN: + case EFFECT_PRESENT: + case EFFECT_FRUSTRATION: + case EFFECT_SONICBOOM: + //case EFFECT_MIRROR_COAT: + case EFFECT_SKULL_BASH: + case EFFECT_FOCUS_PUNCH: + case EFFECT_SUPERPOWER: + //case EFFECT_ENDEAVOR: + case EFFECT_LOW_KICK: + // AI_CBM_HighRiskForDamage + if (AI_DATA->defAbility == ABILITY_WONDER_GUARD && effectiveness < AI_EFFECTIVENESS_x2) + score -= 10; + break; + case EFFECT_COUNTER: + case EFFECT_MIRROR_COAT: + if (IsBattlerIncapacitated(battlerDef, AI_DATA->defAbility) || gBattleMons[battlerDef].status2 & (STATUS2_INFATUATION | STATUS2_CONFUSION)) + score--; + if (predictedMove == MOVE_NONE || GetBattleMoveSplit(predictedMove) == SPLIT_STATUS + || DoesSubstituteBlockMove(battlerAtk, AI_DATA->battlerDefPartner, predictedMove)) + score -= 10; + break; + + case EFFECT_ROAR: + if (CountUsablePartyMons(battlerDef) == 0) + score -= 10; + else if (AI_DATA->defAbility == ABILITY_SUCTION_CUPS) + score -= 10; + break; + case EFFECT_TOXIC_THREAD: + if (!ShouldLowerStat(battlerDef, AI_DATA->defAbility, STAT_SPEED)) + score--; // may still want to just poison + //fallthrough + case EFFECT_POISON: + case EFFECT_TOXIC: + if (!AI_CanPoison(battlerAtk, battlerDef, AI_DATA->defAbility, move, AI_DATA->partnerMove)) + score -= 10; + break; + case EFFECT_LIGHT_SCREEN: + if (gSideStatuses[GetBattlerSide(battlerAtk)] & SIDE_STATUS_LIGHTSCREEN + || PartnerHasSameMoveEffectWithoutTarget(AI_DATA->battlerAtkPartner, move, AI_DATA->partnerMove)) + score -= 10; + break; + case EFFECT_REFLECT: + if (gSideStatuses[GetBattlerSide(battlerAtk)] & SIDE_STATUS_REFLECT + || PartnerHasSameMoveEffectWithoutTarget(AI_DATA->battlerAtkPartner, move, AI_DATA->partnerMove)) + score -= 10; + break; + case EFFECT_AURORA_VEIL: + if (gSideStatuses[GetBattlerSide(battlerAtk)] & SIDE_STATUS_AURORA_VEIL + || PartnerHasSameMoveEffectWithoutTarget(AI_DATA->battlerAtkPartner, move, AI_DATA->partnerMove) + || !(gBattleWeather & WEATHER_HAIL_ANY)) + score -= 10; + break; + case EFFECT_OHKO: + if (!ShouldTryOHKO(battlerAtk, battlerDef, AI_DATA->atkAbility, AI_DATA->defAbility, accuracy, move)) + score -= 10; + break; + case EFFECT_MIST: + if (gSideStatuses[GetBattlerSide(battlerAtk)] & SIDE_STATUS_MIST + || PartnerHasSameMoveEffectWithoutTarget(AI_DATA->battlerAtkPartner, move, AI_DATA->partnerMove)) + score -= 10; + break; + case EFFECT_FOCUS_ENERGY: + if (gBattleMons[battlerAtk].status2 & STATUS2_FOCUS_ENERGY) + score -= 10; + break; + case EFFECT_CONFUSE: + case EFFECT_SWAGGER: + case EFFECT_FLATTER: + if (!AI_CanConfuse(battlerAtk, battlerDef, AI_DATA->defAbility, AI_DATA->battlerAtkPartner, move, AI_DATA->partnerMove)) + score -= 10; + break; + case EFFECT_PARALYZE: + if (!AI_CanParalyze(battlerAtk, battlerDef, AI_DATA->defAbility, move, AI_DATA->partnerMove)) + score -= 10; + break; + case EFFECT_SUBSTITUTE: + if (gBattleMons[battlerAtk].status2 & STATUS2_SUBSTITUTE || AI_DATA->defAbility == ABILITY_INFILTRATOR) + score -= 8; + else if (GetHealthPercentage(battlerAtk) <= 25) + score -= 10; + else if (B_SOUND_SUBSTITUTE >= GEN_6 && TestMoveFlagsInMoveset(battlerDef, FLAG_SOUND)) + score -= 8; + break; + case EFFECT_LEECH_SEED: + if (gStatuses3[battlerDef] & STATUS3_LEECHSEED + || IS_BATTLER_OF_TYPE(battlerDef, TYPE_GRASS) + || DoesPartnerHaveSameMoveEffect(AI_DATA->battlerAtkPartner, battlerDef, move, AI_DATA->partnerMove)) + score -= 10; + else if (AI_DATA->defAbility == ABILITY_LIQUID_OOZE) + score -= 3; + break; + case EFFECT_DISABLE: + if (gDisableStructs[battlerDef].disableTimer == 0 + && (B_MENTAL_HERB >= GEN_5 && AI_DATA->defHoldEffect != HOLD_EFFECT_CURE_ATTRACT) + && !PartnerHasSameMoveEffectWithoutTarget(AI_DATA->battlerAtkPartner, move, AI_DATA->partnerMove)) + { + if (GetWhoStrikesFirst(battlerAtk, battlerDef, TRUE) == 0) // attacker should go first + { + if (gLastMoves[battlerDef] == MOVE_NONE || gLastMoves[battlerDef] == 0xFFFF) + score -= 10; // no anticipated move to disable + } + else if (predictedMove == MOVE_NONE) + { + score -= 10; + } + } + else + { + score -= 10; + } + break; + case EFFECT_ENCORE: + if (gDisableStructs[battlerDef].encoreTimer == 0 + && (B_MENTAL_HERB >= GEN_5 && AI_DATA->defHoldEffect != HOLD_EFFECT_CURE_ATTRACT) + && !DoesPartnerHaveSameMoveEffect(AI_DATA->battlerAtkPartner, battlerDef, move, AI_DATA->partnerMove)) + { + if (GetWhoStrikesFirst(battlerAtk, battlerDef, TRUE) == 0) // attacker should go first + { + if (gLastMoves[battlerDef] == MOVE_NONE || gLastMoves[battlerDef] == 0xFFFF) + score -= 10; // no anticipated move to encore + } + else if (predictedMove == MOVE_NONE) + { + score -= 10; + } + } + else + { + score -= 10; + } + break; + case EFFECT_SNORE: + case EFFECT_SLEEP_TALK: + if (IsWakeupTurn(battlerAtk) || (!(gBattleMons[battlerAtk].status1 & STATUS1_SLEEP) || AI_DATA->atkAbility != ABILITY_COMATOSE)) + score -= 10; // if mon will wake up, is not asleep, or is not comatose + break; + case EFFECT_MEAN_LOOK: + if (IsBattlerTrapped(battlerDef, TRUE) || DoesPartnerHaveSameMoveEffect(AI_DATA->battlerAtkPartner, battlerDef, move, AI_DATA->partnerMove)) + score -= 10; + break; + case EFFECT_NIGHTMARE: + if (gBattleMons[battlerDef].status2 & STATUS2_NIGHTMARE) + score -= 10; + else if (!(gBattleMons[battlerDef].status1 & STATUS1_SLEEP) || AI_DATA->defAbility == ABILITY_COMATOSE) + score -= 8; + else if (DoesPartnerHaveSameMoveEffect(AI_DATA->battlerAtkPartner, battlerDef, move, AI_DATA->partnerMove)) + score -= 10; + break; + case EFFECT_CURSE: + if (IS_BATTLER_OF_TYPE(battlerAtk, TYPE_GHOST)) + { + if (gBattleMons[battlerDef].status2 & STATUS2_CURSED + || DoesPartnerHaveSameMoveEffect(AI_DATA->battlerAtkPartner, battlerDef, move, AI_DATA->partnerMove)) + score -= 10; + else if (GetHealthPercentage(battlerAtk) <= 50) + score -= 6; + } + else // regular curse + { + if (!BattlerStatCanRise(battlerAtk, AI_DATA->atkAbility, STAT_ATK) || !HasMoveWithSplit(battlerAtk, SPLIT_PHYSICAL)) + score -= 10; + else if (!BattlerStatCanRise(battlerAtk, AI_DATA->atkAbility, STAT_DEF)) + score -= 8; + } + break; + case EFFECT_SPIKES: + if (gSideTimers[GetBattlerSide(battlerDef)].spikesAmount >= 3) + score -= 10; + else if (PartnerMoveIsSameNoTarget(AI_DATA->battlerAtkPartner, move, AI_DATA->partnerMove) + && gSideTimers[GetBattlerSide(battlerDef)].spikesAmount == 2) + score -= 10; // only one mon needs to set up the last layer of Spikes + break; + case EFFECT_STEALTH_ROCK: + if (gSideTimers[GetBattlerSide(battlerDef)].stealthRockAmount > 0 + || PartnerMoveIsSameNoTarget(AI_DATA->battlerAtkPartner, move, AI_DATA->partnerMove)) //Only one mon needs to set up Stealth Rocks + score -= 10; + break; + case EFFECT_TOXIC_SPIKES: + if (gSideTimers[GetBattlerSide(battlerDef)].toxicSpikesAmount >= 2) + score -= 10; + else if (PartnerMoveIsSameNoTarget(AI_DATA->battlerAtkPartner, move, AI_DATA->partnerMove) && gSideTimers[GetBattlerSide(battlerDef)].toxicSpikesAmount == 1) + score -= 10; // only one mon needs to set up the last layer of Toxic Spikes + break; + case EFFECT_STICKY_WEB: + if (gSideTimers[GetBattlerSide(battlerDef)].stickyWebAmount) + score -= 10; + else if (PartnerMoveIsSameNoTarget(AI_DATA->battlerAtkPartner, move, AI_DATA->partnerMove) && gSideTimers[GetBattlerSide(battlerDef)].stickyWebAmount) + score -= 10; // only one mon needs to set up Sticky Web + break; + case EFFECT_FORESIGHT: + if (gBattleMons[battlerDef].status2 & STATUS2_FORESIGHT) + score -= 10; + else if (gBattleMons[battlerDef].statStages[STAT_EVASION] <= 4 + || !(IS_BATTLER_OF_TYPE(battlerDef, TYPE_GHOST)) + || DoesPartnerHaveSameMoveEffect(AI_DATA->battlerAtkPartner, battlerDef, move, AI_DATA->partnerMove)) + score -= 9; + break; + case EFFECT_PERISH_SONG: + if (isDoubleBattle) + { + if (CountUsablePartyMons(battlerAtk) == 0 + && AI_DATA->atkAbility != ABILITY_SOUNDPROOF + && AI_DATA->atkPartnerAbility != ABILITY_SOUNDPROOF + && CountUsablePartyMons(FOE(battlerAtk)) >= 1) + { + score -= 10; //Don't wipe your team if you're going to lose + } + else if ((!IsBattlerAlive(FOE(battlerAtk)) || AI_GetAbility(FOE(battlerAtk)) == ABILITY_SOUNDPROOF + || gStatuses3[FOE(battlerAtk)] & STATUS3_PERISH_SONG) + && (!IsBattlerAlive(BATTLE_PARTNER(FOE(battlerAtk))) || AI_GetAbility(BATTLE_PARTNER(FOE(battlerAtk))) == ABILITY_SOUNDPROOF + || gStatuses3[BATTLE_PARTNER(FOE(battlerAtk))] & STATUS3_PERISH_SONG)) + { + score -= 10; //Both enemies are perish songed + } + else if (DoesPartnerHaveSameMoveEffect(AI_DATA->battlerAtkPartner, battlerDef, move, AI_DATA->partnerMove)) + { + score -= 10; + } + } + else + { + if (CountUsablePartyMons(battlerAtk) == 0 && AI_DATA->atkAbility != ABILITY_SOUNDPROOF + && CountUsablePartyMons(battlerDef) >= 1) + score -= 10; + + if (gStatuses3[FOE(battlerAtk)] & STATUS3_PERISH_SONG || AI_GetAbility(FOE(battlerAtk)) == ABILITY_SOUNDPROOF) + score -= 10; + } + break; + case EFFECT_SANDSTORM: + if (gBattleWeather & WEATHER_SANDSTORM_ANY //TODO | WEATHER_PRIMAL_ANY) + || PartnerMoveEffectIsWeather(AI_DATA->battlerAtkPartner, AI_DATA->partnerMove)) + score -= 8; + break; + case EFFECT_SUNNY_DAY: + if (gBattleWeather & WEATHER_SUN_ANY //TODO | WEATHER_PRIMAL_ANY) + || PartnerMoveEffectIsWeather(AI_DATA->battlerAtkPartner, AI_DATA->partnerMove)) + score -= 8; + break; + case EFFECT_RAIN_DANCE: + if (gBattleWeather & WEATHER_RAIN_ANY //TODO | WEATHER_PRIMAL_ANY) + || PartnerMoveEffectIsWeather(AI_DATA->battlerAtkPartner, AI_DATA->partnerMove)) + score -= 8; + break; + case EFFECT_HAIL: + if (gBattleWeather & WEATHER_HAIL_ANY //TODO | WEATHER_PRIMAL_ANY) + || PartnerMoveEffectIsWeather(AI_DATA->battlerAtkPartner, AI_DATA->partnerMove)) + score -= 8; + break; + case EFFECT_ATTRACT: + if (!AI_CanBeInfatuated(battlerAtk, battlerDef, AI_DATA->defAbility, + GetGenderFromSpeciesAndPersonality(gBattleMons[battlerAtk].species, gBattleMons[battlerAtk].personality), + GetGenderFromSpeciesAndPersonality(gBattleMons[battlerDef].species, gBattleMons[battlerDef].personality))) + score -= 10; + break; + case EFFECT_SAFEGUARD: + if (gSideStatuses[GetBattlerSide(battlerAtk)] & SIDE_STATUS_SAFEGUARD + || PartnerHasSameMoveEffectWithoutTarget(AI_DATA->battlerAtkPartner, move, AI_DATA->partnerMove)) + score -= 10; + break; + case EFFECT_MAGNITUDE: + if (AI_DATA->defAbility == ABILITY_LEVITATE) + score -= 10; + break; + case EFFECT_PARTING_SHOT: + if (CountUsablePartyMons(battlerAtk) == 0) + score -= 10; + break; + case EFFECT_BATON_PASS: + if (CountUsablePartyMons(battlerAtk) == 0) + score -= 10; + else if (gBattleMons[battlerAtk].status2 & STATUS2_SUBSTITUTE + || (gStatuses3[battlerAtk] & (STATUS3_ROOTED | STATUS3_AQUA_RING | STATUS3_MAGNET_RISE | STATUS3_POWER_TRICK)) + || AnyStatIsRaised(battlerAtk)) + break; + else + score -= 6; + break; + case EFFECT_HIT_ESCAPE: + break; + case EFFECT_RAPID_SPIN: + if ((gBattleMons[battlerAtk].status2 & STATUS2_WRAPPED) || (gStatuses3[battlerAtk] & STATUS3_LEECHSEED)) + break; // check damage/accuracy + //Spin checks + if (!(gSideStatuses[GetBattlerSide(battlerAtk)] & SIDE_STATUS_HAZARDS_ANY)) + score -= 6; + break; + case EFFECT_BELLY_DRUM: + if (AI_DATA->atkAbility == ABILITY_CONTRARY) + score -= 10; + else if (GetHealthPercentage(battlerAtk) <= 60) + score -= 10; + break; + case EFFECT_FUTURE_SIGHT: + if (gSideStatuses[GetBattlerSide(battlerDef)] & SIDE_STATUS_FUTUREATTACK + || gSideStatuses[GetBattlerSide(battlerAtk)] & SIDE_STATUS_FUTUREATTACK) + score -= 12; + else + score += 5; + break; + case EFFECT_TELEPORT: + score -= 10; + break; + case EFFECT_FAKE_OUT: + if (!gDisableStructs[battlerAtk].isFirstTurn) + { + score -= 10; + } + else if (move == MOVE_FAKE_OUT) // filter out first impression + { + if ((AI_DATA->atkHoldEffect == HOLD_EFFECT_CHOICE_BAND || AI_DATA->atkAbility == ABILITY_GORILLA_TACTICS) + && (CountUsablePartyMons(battlerDef) > 0 || !CanAttackerFaintTarget(battlerAtk, battlerDef, AI_THINKING_STRUCT->movesetIndex, 0))) + { + if (CountUsablePartyMons(battlerAtk) == 0) + score -= 10; // Don't lock the attacker into Fake Out if they can't switch out afterwards. + } + } + break; + case EFFECT_STOCKPILE: + if (gDisableStructs[battlerAtk].stockpileCounter >= 3) + score -= 10; + break; + case EFFECT_SPIT_UP: + if (gDisableStructs[battlerAtk].stockpileCounter <= 1) + score -= 10; + break; + case EFFECT_SWALLOW: + if (gDisableStructs[battlerAtk].stockpileCounter == 0) + { + score -= 10; + } + else + { + if (AtMaxHp(battlerAtk)) + score -= 10; + else if (GetHealthPercentage(battlerAtk) >= 80) + score -= 5; // do it if nothing better + } + break; + case EFFECT_TORMENT: + if (gBattleMons[battlerDef].status2 & STATUS2_TORMENT + || DoesPartnerHaveSameMoveEffect(AI_DATA->battlerAtkPartner, battlerDef, move, AI_DATA->partnerMove)) + { + score -= 10; + break; + } + + if (B_MENTAL_HERB >= GEN_5 && AI_DATA->defHoldEffect == HOLD_EFFECT_CURE_ATTRACT) + score -= 6; + break; + case EFFECT_WILL_O_WISP: + if (!AI_CanBurn(battlerAtk, battlerDef, AI_DATA->defAbility, AI_DATA->battlerAtkPartner, move, AI_DATA->partnerMove)) + score -= 10; + break; + case EFFECT_MEMENTO: + if (CountUsablePartyMons(battlerAtk) == 0 || DoesPartnerHaveSameMoveEffect(AI_DATA->battlerAtkPartner, battlerDef, move, AI_DATA->partnerMove)) + score -= 10; + else if (gBattleMons[battlerDef].statStages[STAT_ATK] == MIN_STAT_STAGE && gBattleMons[battlerDef].statStages[STAT_SPATK] == MIN_STAT_STAGE) + score -= 10; + break; + case EFFECT_FOLLOW_ME: + case EFFECT_HELPING_HAND: + if (!isDoubleBattle + || !IsBattlerAlive(AI_DATA->battlerAtkPartner) + || PartnerHasSameMoveEffectWithoutTarget(AI_DATA->battlerAtkPartner, move, AI_DATA->partnerMove) + || (AI_DATA->partnerMove != MOVE_NONE && IS_MOVE_STATUS(AI_DATA->partnerMove)) + || *(gBattleStruct->monToSwitchIntoId + AI_DATA->battlerAtkPartner) != PARTY_SIZE) //Partner is switching out. + score -= 10; + break; + case EFFECT_TRICK: + case EFFECT_KNOCK_OFF: + if (AI_DATA->defAbility == ABILITY_STICKY_HOLD) + score -= 10; + break; + case EFFECT_INGRAIN: + if (gStatuses3[battlerAtk] & STATUS3_ROOTED) + score -= 10; + break; + case EFFECT_AQUA_RING: + if (gStatuses3[battlerAtk] & STATUS3_AQUA_RING) + score -= 10; + break; + case EFFECT_RECYCLE: + if (gBattleStruct->usedHeldItems[battlerAtk] == 0 || gBattleMons[battlerAtk].item != 0) + score -= 10; + break; + case EFFECT_IMPRISON: + if (gStatuses3[battlerAtk] & STATUS3_IMPRISONED_OTHERS) + score -= 10; + break; + case EFFECT_REFRESH: + if (!(gBattleMons[battlerDef].status1 & (STATUS1_PSN_ANY | STATUS1_BURN | STATUS1_PARALYSIS))) + score -= 10; + break; + case EFFECT_PSYCHO_SHIFT: + if (gBattleMons[battlerAtk].status1 & STATUS1_PSN_ANY && !AI_CanPoison(battlerAtk, battlerDef, AI_DATA->defAbility, move, AI_DATA->partnerMove)) + score -= 10; + else if (gBattleMons[battlerAtk].status1 & STATUS1_BURN && !AI_CanBurn(battlerAtk, battlerDef, + AI_DATA->defAbility, AI_DATA->battlerAtkPartner, move, AI_DATA->partnerMove)) + score -= 10; + else if (gBattleMons[battlerAtk].status1 & STATUS1_PARALYSIS && !AI_CanParalyze(battlerAtk, battlerDef, AI_DATA->defAbility, move, AI_DATA->partnerMove)) + score -= 10; + else if (gBattleMons[battlerAtk].status1 & STATUS1_SLEEP && !AI_CanPutToSleep(battlerAtk, battlerDef, AI_DATA->defAbility, move, AI_DATA->partnerMove)) + score -= 10; + else + score -= 10; // attacker has no status to transmit + break; + case EFFECT_MUD_SPORT: + if (gFieldStatuses & STATUS_FIELD_MUDSPORT + || PartnerHasSameMoveEffectWithoutTarget(AI_DATA->battlerAtkPartner, move, AI_DATA->partnerMove)) + score -= 10; + break; + case EFFECT_WATER_SPORT: + if (gFieldStatuses & STATUS_FIELD_WATERSPORT + || PartnerHasSameMoveEffectWithoutTarget(AI_DATA->battlerAtkPartner, move, AI_DATA->partnerMove)) + score -= 10; + break; + case EFFECT_ABSORB: + if (AI_DATA->defAbility == ABILITY_LIQUID_OOZE) + score -= 6; + break; + case EFFECT_STRENGTH_SAP: + if (AI_DATA->defAbility == ABILITY_CONTRARY) + score -= 10; + else if (!ShouldLowerStat(battlerDef, AI_DATA->defAbility, STAT_ATK)) + score -= 10; + break; + case EFFECT_COPYCAT: + case EFFECT_MIRROR_MOVE: + return AI_CheckBadMove(battlerAtk, battlerDef, predictedMove, score); + case EFFECT_FLOWER_SHIELD: + if (!IS_BATTLER_OF_TYPE(battlerAtk, TYPE_GRASS) + && !(isDoubleBattle && IS_BATTLER_OF_TYPE(AI_DATA->battlerAtkPartner, TYPE_GRASS))) + score -= 10; + break; + case EFFECT_AROMATIC_MIST: + if (!isDoubleBattle || gBattleMons[AI_DATA->battlerAtkPartner].hp == 0 || !BattlerStatCanRise(AI_DATA->battlerAtkPartner, AI_DATA->atkPartnerAbility, STAT_SPDEF)) + score -= 10; + break; + case EFFECT_BIDE: + if (!HasDamagingMove(battlerDef) + || GetHealthPercentage(battlerAtk) < 30 //Close to death + || gBattleMons[battlerDef].status1 & (STATUS1_SLEEP | STATUS1_FREEZE)) //No point in biding if can't take damage + score -= 10; + break; + case EFFECT_HIT_SWITCH_TARGET: + if (DoesPartnerHaveSameMoveEffect(AI_DATA->battlerAtkPartner, battlerDef, move, AI_DATA->partnerMove)) + score -= 10; // don't scare away pokemon twice + else if (GetHealthPercentage(battlerDef) < 10 && GetBattlerSecondaryDamage(battlerDef)) + score -= 10; // don't blow away mon that will faint soon + else if (gStatuses3[battlerDef] & STATUS3_PERISH_SONG) + score -= 10; + break; + case EFFECT_CONVERSION: + //Check first move type + if (IS_BATTLER_OF_TYPE(battlerAtk, gBattleMoves[gBattleMons[battlerAtk].moves[0]].type)) + score -= 10; + break; + case EFFECT_REST: + if (!CanSleep(battlerAtk, AI_DATA->atkAbility)) + score -= 10; + //fallthrough + case EFFECT_RESTORE_HP: + case EFFECT_SOFTBOILED: + case EFFECT_ROOST: + if (AtMaxHp(battlerAtk)) + score -= 10; + else if (GetHealthPercentage(battlerAtk) >= 90) + score -= 9; //No point in healing, but should at least do it if nothing better + break; + case EFFECT_MORNING_SUN: + case EFFECT_SYNTHESIS: + case EFFECT_MOONLIGHT: + if (AI_WeatherHasEffect() && (gBattleWeather & (WEATHER_RAIN_ANY | WEATHER_SANDSTORM_ANY | WEATHER_HAIL_ANY))) + score -= 3; + else if (AtMaxHp(battlerAtk)) + score -= 10; + else if (GetHealthPercentage(battlerAtk) >= 90) + score -= 9; //No point in healing, but should at least do it if nothing better + break; + case EFFECT_PURIFY: + if (!(gBattleMons[battlerDef].status1 & STATUS1_ANY)) + score -= 10; + else if (battlerDef == AI_DATA->battlerAtkPartner) + break; //Always heal your ally + else if (AtMaxHp(battlerAtk)) + score -= 10; + else if (GetHealthPercentage(battlerAtk) >= 90) + score -= 8; //No point in healing, but should at least do it if nothing better + break; + case EFFECT_SUPER_FANG: + if (GetHealthPercentage(battlerDef) < 50) + score -= 4; + break; + case EFFECT_RECOIL_IF_MISS: + if (AI_DATA->atkAbility != ABILITY_MAGIC_GUARD && accuracy < 75) + score -= 6; + break; + case EFFECT_RECOIL_25: + if (AI_DATA->atkAbility != ABILITY_MAGIC_GUARD && AI_DATA->atkAbility != ABILITY_ROCK_HEAD) + { + u32 recoilDmg = max(1, AI_THINKING_STRUCT->simulatedDmg[battlerAtk][battlerDef][AI_THINKING_STRUCT->movesetIndex] / 4); + if (!ShouldUseRecoilMove(battlerAtk, battlerDef, recoilDmg, AI_THINKING_STRUCT->movesetIndex)) + score -= 10; + break; + } + break; + case EFFECT_RECOIL_33: + case EFFECT_RECOIL_33_STATUS: + if (AI_DATA->atkAbility != ABILITY_MAGIC_GUARD && AI_DATA->atkAbility != ABILITY_ROCK_HEAD) + { + u32 recoilDmg = max(1, AI_THINKING_STRUCT->simulatedDmg[battlerAtk][battlerDef][AI_THINKING_STRUCT->movesetIndex] / 3); + if (!ShouldUseRecoilMove(battlerAtk, battlerDef, recoilDmg, AI_THINKING_STRUCT->movesetIndex)) + score -= 10; + break; + } + break; + case EFFECT_RECOIL_50: + if (AI_DATA->atkAbility != ABILITY_MAGIC_GUARD && AI_DATA->atkAbility != ABILITY_ROCK_HEAD) + { + u32 recoilDmg = max(1, AI_THINKING_STRUCT->simulatedDmg[battlerAtk][battlerDef][AI_THINKING_STRUCT->movesetIndex] / 2); + if (!ShouldUseRecoilMove(battlerAtk, battlerDef, recoilDmg, AI_THINKING_STRUCT->movesetIndex)) + score -= 10; + break; + } + break; + case EFFECT_TEETER_DANCE: + if (((gBattleMons[battlerDef].status2 & STATUS2_CONFUSION) + || (!DoesBattlerIgnoreAbilityChecks(AI_DATA->atkAbility, move) && AI_DATA->defAbility == ABILITY_OWN_TEMPO) + || (IsBattlerGrounded(battlerDef) && (gFieldStatuses & STATUS_FIELD_MISTY_TERRAIN)) + || (DoesSubstituteBlockMove(battlerAtk, battlerDef, move))) + && ((gBattleMons[AI_DATA->battlerDefPartner].status2 & STATUS2_CONFUSION) + || (!DoesBattlerIgnoreAbilityChecks(AI_DATA->atkAbility, move) && AI_DATA->defPartnerAbility == ABILITY_OWN_TEMPO) + || (IsBattlerGrounded(AI_DATA->battlerDefPartner) && (gFieldStatuses & STATUS_FIELD_MISTY_TERRAIN)) + || (DoesSubstituteBlockMove(battlerAtk, AI_DATA->battlerDefPartner, move)))) + { + score -= 10; + } + break; + case EFFECT_TRANSFORM: + if (gBattleMons[battlerAtk].status2 & STATUS2_TRANSFORMED + || (gBattleMons[battlerDef].status2 & (STATUS2_TRANSFORMED | STATUS2_SUBSTITUTE))) //Leave out Illusion b/c AI is supposed to be fooled + score -= 10; + break; + case EFFECT_TWO_TURNS_ATTACK: + if (AI_DATA->atkHoldEffect != HOLD_EFFECT_POWER_HERB && CanTargetFaintAi(battlerDef, battlerAtk)) + score -= 6; + break; + case EFFECT_RECHARGE: + if (AI_DATA->defAbility == ABILITY_WONDER_GUARD && effectiveness < AI_EFFECTIVENESS_x2) + score -= 10; + else if (AI_DATA->atkAbility != ABILITY_TRUANT + && !CanAttackerFaintTarget(battlerAtk, battlerDef, AI_THINKING_STRUCT->movesetIndex, 0)) + score -= 2; + break; + case EFFECT_SPITE: + case EFFECT_MIMIC: + if (GetWhoStrikesFirst(battlerAtk, battlerDef, TRUE) == 0) // attacker should go first + { + if (gLastMoves[battlerDef] == MOVE_NONE + || gLastMoves[battlerDef] == 0xFFFF) + score -= 10; + } + else if (predictedMove == MOVE_NONE) + { + // TODO predicted move separate from gLastMoves + score -= 10; + } + break; + case EFFECT_METRONOME: + break; + case EFFECT_ENDEAVOR: + case EFFECT_PAIN_SPLIT: + if (gBattleMons[battlerAtk].hp > (gBattleMons[battlerAtk].hp + gBattleMons[battlerDef].hp) / 2) + score -= 10; + break; + + case EFFECT_CONVERSION_2: + //TODO + break; + case EFFECT_LOCK_ON: + if (gStatuses3[battlerDef] & STATUS3_ALWAYS_HITS + || AI_DATA->atkAbility == ABILITY_NO_GUARD + || AI_DATA->defAbility == ABILITY_NO_GUARD + || DoesPartnerHaveSameMoveEffect(AI_DATA->battlerAtkPartner, battlerDef, move, AI_DATA->partnerMove)) + score -= 10; + break; + case EFFECT_LASER_FOCUS: + if (gStatuses3[battlerAtk] & STATUS3_LASER_FOCUS) + score -= 10; + else if (AI_DATA->defAbility == ABILITY_SHELL_ARMOR || AI_DATA->defAbility == ABILITY_BATTLE_ARMOR) + score -= 8; + break; + case EFFECT_SKETCH: + if (gLastMoves[battlerDef] == MOVE_NONE) + score -= 10; + break; + case EFFECT_DESTINY_BOND: + if (gBattleMons[battlerDef].status2 & STATUS2_DESTINY_BOND) + score -= 10; + break; + case EFFECT_FALSE_SWIPE: + // TODO + break; + case EFFECT_HEAL_BELL: + if (!AnyPartyMemberStatused(battlerAtk, TestMoveFlags(move, FLAG_SOUND)) || PartnerHasSameMoveEffectWithoutTarget(AI_DATA->battlerAtkPartner, move, AI_DATA->partnerMove)) + score -= 10; + break; + case EFFECT_HIT_PREVENT_ESCAPE: + break; + case EFFECT_ENDURE: + if (gBattleMons[battlerAtk].hp == 1 || GetBattlerSecondaryDamage(battlerAtk)) //Don't use Endure if you'll die after using it + score -= 10; + break; + case EFFECT_PROTECT: + { + bool32 decreased = FALSE; + switch (move) + { + case MOVE_QUICK_GUARD: + case MOVE_WIDE_GUARD: + case MOVE_CRAFTY_SHIELD: + if (!isDoubleBattle) + { + score -= 10; + decreased = TRUE; + } + break; + case MOVE_MAT_BLOCK: + if (!gDisableStructs[battlerAtk].isFirstTurn) + { + score -= 10; + decreased = TRUE; + } + break; + } // move check + + if (decreased) + break; + if (IsBattlerIncapacitated(battlerDef, AI_DATA->defAbility)) + { + score -= 10; + break; + } + + if (move != MOVE_QUICK_GUARD + && move != MOVE_WIDE_GUARD + && move != MOVE_CRAFTY_SHIELD) //These moves have infinite usage + { + if (GetBattlerSecondaryDamage(battlerAtk) >= gBattleMons[battlerAtk].hp + && AI_DATA->defAbility != ABILITY_MOXIE + && AI_DATA->defAbility != ABILITY_BEAST_BOOST) + { + score -= 10; //Don't protect if you're going to faint after protecting + } + else if (gDisableStructs[battlerAtk].protectUses == 1 && Random() % 100 < 50) + { + if (!isDoubleBattle) + score -= 6; + else + score -= 10; //Don't try double protecting in doubles + } + else if (gDisableStructs[battlerAtk].protectUses >= 2) + { + score -= 10; + } + } + + /*if (AI_THINKING_STRUCT->aiFlags == AI_SCRIPT_CHECK_BAD_MOVE //Only basic AI + && IS_DOUBLE_BATTLE) //Make the regular AI know how to use Protect minimally in Doubles + { + u8 shouldProtect = ShouldProtect(battlerAtk, battlerDef, move); + if (shouldProtect == USE_PROTECT || shouldProtect == PROTECT_FROM_FOES) + IncreaseFoeProtectionViability(&viability, 0xFF, battlerAtk, battlerDef); + else if (shouldProtect == PROTECT_FROM_ALLIES) + IncreaseAllyProtectionViability(&viability, 0xFF); + }*/ + } + break; + case EFFECT_MIRACLE_EYE: + if (gStatuses3[battlerDef] & STATUS3_MIRACLE_EYED) + score -= 10; + + if (gBattleMons[battlerDef].statStages[STAT_EVASION] <= 4 + || !(IS_BATTLER_OF_TYPE(battlerDef, TYPE_DARK)) + || DoesPartnerHaveSameMoveEffect(AI_DATA->battlerAtkPartner, battlerDef, move, AI_DATA->partnerMove)) + score -= 9; + break; + case EFFECT_BURN_UP: + if (!IS_BATTLER_OF_TYPE(battlerAtk, TYPE_FIRE)) + score -= 10; + break; + case EFFECT_DEFOG: + if (gSideStatuses[GetBattlerSide(battlerDef)] + & (SIDE_STATUS_REFLECT | SIDE_STATUS_LIGHTSCREEN | SIDE_STATUS_AURORA_VEIL | SIDE_STATUS_SAFEGUARD | SIDE_STATUS_MIST) + || gSideTimers[GetBattlerSide(battlerDef)].auroraVeilTimer != 0 + || gSideStatuses[GetBattlerSide(battlerAtk)] & SIDE_STATUS_HAZARDS_ANY) + { + if (PartnerHasSameMoveEffectWithoutTarget(AI_DATA->battlerAtkPartner, move, AI_DATA->partnerMove)) + { + score -= 10; //Only need one hazards removal + break; + } + } + + if (gSideStatuses[GetBattlerSide(battlerDef)] & SIDE_STATUS_HAZARDS_ANY) + { + score -= 10; //Don't blow away opposing hazards + break; + } + + if (isDoubleBattle) + { + if (IsHazardMoveEffect(gBattleMoves[AI_DATA->partnerMove].effect) // partner is going to set up hazards + && GetWhoStrikesFirst(AI_DATA->battlerAtkPartner, battlerAtk, FALSE)) // partner is going to set up before the potential Defog + { + score -= 10; + break; // Don't use Defog if partner is going to set up hazards + } + } + + // evasion check + if (gBattleMons[battlerDef].statStages[STAT_EVASION] == MIN_STAT_STAGE + || ((AI_DATA->defAbility == ABILITY_CONTRARY) && !IsTargetingPartner(battlerAtk, battlerDef))) // don't want to raise target stats unless its your partner + score -= 10; + break; + + case EFFECT_PSYCH_UP: // haze stats check + { + for (i = STAT_ATK; i < NUM_BATTLE_STATS; i++) + { + if (gBattleMons[battlerAtk].statStages[i] > DEFAULT_STAT_STAGE || gBattleMons[AI_DATA->battlerAtkPartner].statStages[i] > DEFAULT_STAT_STAGE) + score -= 10; // Don't want to reset our boosted stats + } + for (i = STAT_ATK; i < NUM_BATTLE_STATS; i++) + { + if (gBattleMons[battlerDef].statStages[i] < DEFAULT_STAT_STAGE || gBattleMons[AI_DATA->battlerDefPartner].statStages[i] < DEFAULT_STAT_STAGE) + score -= 10; //Don't want to copy enemy lowered stats + } + } + break; + case EFFECT_SPECTRAL_THIEF: + break; + case EFFECT_SOLARBEAM: + if (AI_DATA->atkHoldEffect == HOLD_EFFECT_POWER_HERB + || (AI_WeatherHasEffect() && gBattleWeather & WEATHER_SUN_ANY && AI_DATA->atkHoldEffect != HOLD_EFFECT_UTILITY_UMBRELLA)) + break; + if (CanTargetFaintAi(battlerDef, battlerAtk)) //Attacker can be knocked out + score -= 4; + break; + case EFFECT_SEMI_INVULNERABLE: + if (predictedMove != MOVE_NONE + && GetWhoStrikesFirst(battlerAtk, battlerDef, TRUE) == 1 + && gBattleMoves[predictedMove].effect == EFFECT_SEMI_INVULNERABLE) + score -= 10; // Don't Fly/dig/etc if opponent is going to fly/dig/etc after you + + if (BattlerWillFaintFromWeather(battlerAtk, AI_DATA->atkAbility) + && (move == MOVE_FLY || move == MOVE_BOUNCE)) + score -= 10; // Attacker will faint while in the air + break; + case EFFECT_HEALING_WISH: //healing wish, lunar dance + if (CountUsablePartyMons(battlerAtk) == 0 || DoesPartnerHaveSameMoveEffect(AI_DATA->battlerAtkPartner, battlerDef, move, AI_DATA->partnerMove)) + score -= 10; + else if (IsPartyFullyHealedExceptBattler(battlerAtk)) + score -= 10; + break; + case EFFECT_FINAL_GAMBIT: + if (CountUsablePartyMons(battlerAtk) == 0 || DoesPartnerHaveSameMoveEffect(AI_DATA->battlerAtkPartner, battlerDef, move, AI_DATA->partnerMove)) + score -= 10; + break; + case EFFECT_NATURE_POWER: + return AI_CheckBadMove(battlerAtk, battlerDef, GetNaturePowerMove(), score); + case EFFECT_TAUNT: + if (gDisableStructs[battlerDef].tauntTimer > 0 + || DoesPartnerHaveSameMoveEffect(AI_DATA->battlerAtkPartner, battlerDef, move, AI_DATA->partnerMove)) + score--; + break; + case EFFECT_BESTOW: + if (AI_DATA->atkHoldEffect == HOLD_EFFECT_NONE + || !CanBattlerGetOrLoseItem(battlerAtk, gBattleMons[battlerAtk].item)) // AI knows its own item + score -= 10; + break; + case EFFECT_ROLE_PLAY: + if (AI_DATA->atkAbility == AI_DATA->defAbility + || AI_DATA->defAbility == ABILITY_NONE + || IsRolePlayBannedAbilityAtk(AI_DATA->atkAbility) + || IsRolePlayBannedAbility(AI_DATA->defAbility)) + score -= 10; + else if (IsAbilityOfRating(AI_DATA->atkAbility, 5)) + score -= 4; + break; + case EFFECT_WISH: + if (gWishFutureKnock.wishCounter[battlerAtk] != 0) + score -= 10; + break; + case EFFECT_ASSIST: + if (CountUsablePartyMons(battlerAtk) == 0) + score -= 10; // no teammates to assist from + break; + case EFFECT_MAGIC_COAT: + if (!TestMoveFlagsInMoveset(battlerDef, FLAG_MAGIC_COAT_AFFECTED)) + score -= 10; + break; + case EFFECT_BELCH: + if (ItemId_GetPocket(gBattleStruct->usedHeldItems[battlerAtk]) != POCKET_BERRIES) + score -= 10; // attacker has not consumed a berry + break; + case EFFECT_YAWN: + if (gStatuses3[battlerDef] & STATUS3_YAWN) + score -= 10; + else if (!AI_CanPutToSleep(battlerAtk, battlerDef, AI_DATA->defAbility, move, AI_DATA->partnerMove)) + score -= 10; + break; + case EFFECT_SKILL_SWAP: + if (AI_DATA->atkAbility == ABILITY_NONE || AI_DATA->defAbility == ABILITY_NONE + || IsSkillSwapBannedAbility(AI_DATA->atkAbility) || IsSkillSwapBannedAbility(AI_DATA->defAbility)) + score -= 10; + break; + case EFFECT_WORRY_SEED: + if (AI_DATA->defAbility == ABILITY_INSOMNIA + || IsWorrySeedBannedAbility(AI_DATA->defAbility)) + score -= 10; + break; + case EFFECT_GASTRO_ACID: + if (gStatuses3[battlerDef] & STATUS3_GASTRO_ACID + || IsGastroAcidBannedAbility(AI_DATA->defAbility)) + score -= 10; + break; + case EFFECT_ENTRAINMENT: + if (AI_DATA->atkAbility == ABILITY_NONE + || IsEntrainmentBannedAbilityAttacker(AI_DATA->atkAbility) + || IsEntrainmentTargetOrSimpleBeamBannedAbility(AI_DATA->defAbility)) + score -= 10; + break; + case EFFECT_CORE_ENFORCER: + break; + case EFFECT_SIMPLE_BEAM: + if (AI_DATA->defAbility == ABILITY_SIMPLE + || IsEntrainmentTargetOrSimpleBeamBannedAbility(AI_DATA->defAbility)) + score -= 10; + break; + case EFFECT_SNATCH: + if (!TestMoveFlagsInMoveset(battlerDef, FLAG_SNATCH_AFFECTED) + || PartnerHasSameMoveEffectWithoutTarget(AI_DATA->battlerAtkPartner, move, AI_DATA->partnerMove)) + score -= 10; + break; + case EFFECT_POWER_TRICK: + if (IsTargetingPartner(battlerAtk, battlerDef)) + score -= 10; + else if (gBattleMons[battlerAtk].defense >= gBattleMons[battlerAtk].attack && !HasMoveWithSplit(battlerAtk, SPLIT_PHYSICAL)) + score -= 10; + break; + case EFFECT_POWER_SWAP: // Don't use if attacker's stat stages are higher than opponents + if (IsTargetingPartner(battlerAtk, battlerDef)) + score -= 10; + else if (gBattleMons[battlerAtk].statStages[STAT_ATK] >= gBattleMons[battlerDef].statStages[STAT_ATK] + && gBattleMons[battlerAtk].statStages[STAT_SPATK] >= gBattleMons[battlerDef].statStages[STAT_SPATK]) + score -= 10; + break; + case EFFECT_GUARD_SWAP: // Don't use if attacker's stat stages are higher than opponents + if (IsTargetingPartner(battlerAtk, battlerDef)) + score -= 10; + else if (gBattleMons[battlerAtk].statStages[STAT_DEF] >= gBattleMons[battlerDef].statStages[STAT_DEF] + && gBattleMons[battlerAtk].statStages[STAT_SPDEF] >= gBattleMons[battlerDef].statStages[STAT_SPDEF]) + score -= 10; + break; + case EFFECT_SPEED_SWAP: + if (IsTargetingPartner(battlerAtk, battlerDef)) + { + score -= 10; + } + else + { + if (gFieldStatuses & STATUS_FIELD_TRICK_ROOM && (gBattleMons[battlerAtk].speed <= gBattleMons[battlerDef].speed)) + score -= 10; + else if (gBattleMons[battlerAtk].speed >= gBattleMons[battlerDef].speed) + score -= 10; + } + break; + case EFFECT_HEART_SWAP: + if (IsTargetingPartner(battlerAtk, battlerDef)) + { + score -= 10; + } + else + { + u32 atkPositiveStages = CountPositiveStatStages(battlerAtk); + u32 atkNegativeStages = CountNegativeStatStages(battlerAtk); + u32 defPositiveStages = CountPositiveStatStages(battlerDef); + u32 defNegativeStages = CountNegativeStatStages(battlerDef); + + if (atkPositiveStages >= defPositiveStages && atkNegativeStages <= defNegativeStages) + score -= 10; + break; + } + break; + case EFFECT_POWER_SPLIT: + if (IsTargetingPartner(battlerAtk, battlerDef)) + { + score -= 10; + } + else + { + u8 atkAttack = gBattleMons[battlerAtk].attack; + u8 defAttack = gBattleMons[battlerDef].attack; + u8 atkSpAttack = gBattleMons[battlerAtk].spAttack; + u8 defSpAttack = gBattleMons[battlerDef].spAttack; + + if (atkAttack + atkSpAttack >= defAttack + defSpAttack) // Combined attacker stats are > than combined target stats + score -= 10; + break; + } + break; + case EFFECT_GUARD_SPLIT: + if (IsTargetingPartner(battlerAtk, battlerDef)) + { + score -= 10; + } + else + { + u8 atkDefense = gBattleMons[battlerAtk].defense; + u8 defDefense = gBattleMons[battlerDef].defense; + u8 atkSpDefense = gBattleMons[battlerAtk].spDefense; + u8 defSpDefense = gBattleMons[battlerDef].spDefense; + + if (atkDefense + atkSpDefense >= defDefense + defSpDefense) //Combined attacker stats are > than combined target stats + score -= 10; + break; + } + break; + case EFFECT_ME_FIRST: + if (predictedMove != MOVE_NONE) + { + if (GetWhoStrikesFirst(battlerAtk, battlerDef, TRUE) == 1) + score -= 10; // Target is predicted to go first, Me First will fail + else + return AI_CheckBadMove(battlerAtk, battlerDef, predictedMove, score); + } + else + { + score -= 10; //Target is predicted to switch most likely + } + break; + case EFFECT_NATURAL_GIFT: + if (AI_DATA->atkAbility == ABILITY_KLUTZ + || gFieldStatuses & STATUS_FIELD_MAGIC_ROOM + || GetPocketByItemId(gBattleMons[battlerAtk].item) != POCKET_BERRIES) + score -= 10; + break; + case EFFECT_GRASSY_TERRAIN: + if (PartnerMoveEffectIsTerrain(AI_DATA->battlerAtkPartner, AI_DATA->partnerMove) || gFieldStatuses & STATUS_FIELD_GRASSY_TERRAIN) + score -= 10; + break; + case EFFECT_ELECTRIC_TERRAIN: + if (PartnerMoveEffectIsTerrain(AI_DATA->battlerAtkPartner, AI_DATA->partnerMove) || gFieldStatuses & STATUS_FIELD_ELECTRIC_TERRAIN) + score -= 10; + break; + case EFFECT_PSYCHIC_TERRAIN: + if (PartnerMoveEffectIsTerrain(AI_DATA->battlerAtkPartner, AI_DATA->partnerMove) || gFieldStatuses & STATUS_FIELD_PSYCHIC_TERRAIN) + score -= 10; + break; + case EFFECT_MISTY_TERRAIN: + if (PartnerMoveEffectIsTerrain(AI_DATA->battlerAtkPartner, AI_DATA->partnerMove) || gFieldStatuses & STATUS_FIELD_MISTY_TERRAIN) + score -= 10; + break; + case EFFECT_PLEDGE: + if (isDoubleBattle && gBattleMons[AI_DATA->battlerAtkPartner].hp > 0) + { + if (AI_DATA->partnerMove != MOVE_NONE + && gBattleMoves[AI_DATA->partnerMove].effect == EFFECT_PLEDGE + && move != AI_DATA->partnerMove) // Different pledge moves + { + if (gBattleMons[AI_DATA->battlerAtkPartner].status1 & (STATUS1_SLEEP | STATUS1_FREEZE)) + // && gBattleMons[AI_DATA->battlerAtkPartner].status1 != 1) // Will wake up this turn - how would AI know + score -= 10; // Don't use combo move if your partner will cause failure + } + } + break; + case EFFECT_TRICK_ROOM: + if (PartnerMoveIs(AI_DATA->battlerAtkPartner, AI_DATA->partnerMove, MOVE_TRICK_ROOM)) + { + score -= 10; + } + else if (gFieldStatuses & STATUS_FIELD_TRICK_ROOM) // Trick Room Up + { + if (GetBattlerSideSpeedAverage(battlerAtk) < GetBattlerSideSpeedAverage(battlerDef)) // Attacker side slower than target side + score -= 10; // Keep the Trick Room up + } + else + { + if (GetBattlerSideSpeedAverage(battlerAtk) >= GetBattlerSideSpeedAverage(battlerDef)) // Attacker side faster than target side + score -= 10; // Keep the Trick Room down + } + break; + case EFFECT_MAGIC_ROOM: + if (gFieldStatuses & STATUS_FIELD_MAGIC_ROOM || PartnerMoveIsSameNoTarget(AI_DATA->battlerAtkPartner, move, AI_DATA->partnerMove)) + score -= 10; + break; + case EFFECT_WONDER_ROOM: + if (gFieldStatuses & STATUS_FIELD_WONDER_ROOM || PartnerMoveIsSameNoTarget(AI_DATA->battlerAtkPartner, move, AI_DATA->partnerMove)) + score -= 10; + break; + case EFFECT_GRAVITY: + if ((gFieldStatuses & STATUS_FIELD_GRAVITY + && !IS_BATTLER_OF_TYPE(battlerAtk, TYPE_FLYING) + && AI_DATA->atkHoldEffect != HOLD_EFFECT_AIR_BALLOON) // Should revert Gravity in this case + || PartnerMoveIsSameNoTarget(AI_DATA->battlerAtkPartner, move, AI_DATA->partnerMove)) + score -= 10; + break; + case EFFECT_ION_DELUGE: + if (gFieldStatuses & STATUS_FIELD_ION_DELUGE + || PartnerMoveIsSameNoTarget(AI_DATA->battlerAtkPartner, move, AI_DATA->partnerMove)) + score -= 10; + break; + case EFFECT_FLING: + if (!CanFling(battlerAtk)) + { + score -= 10; + } + else + { + /* TODO Fling + u8 effect = gFlingTable[gBattleMons[battlerAtk].item].effect; + switch (effect) + { + case MOVE_EFFECT_BURN: + if (!AI_CanBurn(battlerAtk, battlerDef, AI_DATA->battlerAtkPartner, move, AI_DATA->partnerMove)) + score -= 10; + break; + case MOVE_EFFECT_PARALYSIS: + if (!AI_CanParalyze(battlerAtk, battlerDef, AI_DATA->defAbility, move, AI_DATA->partnerMove)) + score -= 10; + break; + case MOVE_EFFECT_POISON: + if (!AI_CanPoison(battlerAtk, battlerDef, AI_DATA->defAbility, move, AI_DATA->partnerMove)) + score -= 10; + break; + case MOVE_EFFECT_TOXIC: + if (!AI_CanPoison(battlerAtk, battlerDef, AI_DATA->defAbility, move, AI_DATA->partnerMove)) + score -= 10; + break; + case MOVE_EFFECT_FREEZE: + if (!CanBeFrozen(battlerDef, TRUE) + || MoveBlockedBySubstitute(move, battlerAtk, battlerDef)) + score -= 10; + break; + }*/ + } + break; + case EFFECT_EMBARGO: + if (AI_DATA->defAbility == ABILITY_KLUTZ + || gFieldStatuses & STATUS_FIELD_MAGIC_ROOM + || gDisableStructs[battlerDef].embargoTimer != 0 + || PartnerMoveIsSameAsAttacker(AI_DATA->battlerAtkPartner, battlerDef, move, AI_DATA->partnerMove)) + score -= 10; + break; + case EFFECT_POWDER: + if (!HasMoveWithType(battlerDef, TYPE_FIRE) + || PartnerMoveIsSameAsAttacker(AI_DATA->battlerAtkPartner, battlerDef, move, AI_DATA->partnerMove)) + score -= 10; + break; + case EFFECT_TELEKINESIS: + if (gStatuses3[battlerDef] & (STATUS3_TELEKINESIS | STATUS3_ROOTED | STATUS3_SMACKED_DOWN) + || gFieldStatuses & STATUS_FIELD_GRAVITY + || AI_DATA->defHoldEffect == HOLD_EFFECT_IRON_BALL + || IsTelekinesisBannedSpecies(gBattleMons[battlerDef].species) + || PartnerMoveIsSameAsAttacker(AI_DATA->battlerAtkPartner, battlerDef, move, AI_DATA->partnerMove)) + score -= 10; + break; + case EFFECT_THROAT_CHOP: + break; + case EFFECT_HEAL_BLOCK: + if (gDisableStructs[battlerDef].healBlockTimer != 0 + || PartnerMoveIsSameAsAttacker(AI_DATA->battlerAtkPartner, battlerDef, move, AI_DATA->partnerMove)) + score -= 10; + break; + case EFFECT_SOAK: + if (PartnerMoveIsSameAsAttacker(AI_DATA->battlerAtkPartner, battlerDef, move, AI_DATA->partnerMove) + || (gBattleMons[battlerDef].type1 == TYPE_WATER + && gBattleMons[battlerDef].type2 == TYPE_WATER + && gBattleMons[battlerDef].type3 == TYPE_MYSTERY)) + score -= 10; // target is already water-only + break; + case EFFECT_THIRD_TYPE: + switch (move) + { + case MOVE_TRICK_OR_TREAT: + if (IS_BATTLER_OF_TYPE(battlerDef, TYPE_GHOST) || PartnerMoveIsSameAsAttacker(AI_DATA->battlerAtkPartner, battlerDef, move, AI_DATA->partnerMove)) + score -= 10; + break; + case MOVE_FORESTS_CURSE: + if (IS_BATTLER_OF_TYPE(battlerDef, TYPE_GRASS) || PartnerMoveIsSameAsAttacker(AI_DATA->battlerAtkPartner, battlerDef, move, AI_DATA->partnerMove)) + score -= 10; + break; + } + break; + case EFFECT_HIT_ENEMY_HEAL_ALLY: // pollen puff + if (IsTargetingPartner(battlerAtk, battlerDef)) + { + if (AtMaxHp(battlerDef)) + score -= 10; + else if (gBattleMons[battlerDef].hp > gBattleMons[battlerDef].maxHP / 2) + score -= 5; + break; + } + // fallthrough + case EFFECT_HEAL_PULSE: // and floral healing + if (!IsTargetingPartner(battlerAtk, battlerDef)) // Don't heal enemies + { + score -= 10; + } + else + { + if (AtMaxHp(battlerDef)) + score -= 10; + else if (gBattleMons[battlerDef].hp > gBattleMons[battlerDef].maxHP / 2) + score -= 5; + } + break; + case EFFECT_ELECTRIFY: + if (GetWhoStrikesFirst(battlerAtk, battlerDef, TRUE) == 0 + //|| GetMoveTypeSpecial(battlerDef, predictedMove) == TYPE_ELECTRIC // Move will already be electric type + || PartnerMoveIsSameAsAttacker(AI_DATA->battlerAtkPartner, battlerDef, move, AI_DATA->partnerMove)) + score -= 10; + break; + case EFFECT_TOPSY_TURVY: + if (!IsTargetingPartner(battlerAtk, battlerDef)) + { + u8 targetPositiveStages = CountPositiveStatStages(battlerDef); + u8 targetNegativeStages = CountNegativeStatStages(battlerDef); + + if (targetPositiveStages == 0 //No good stat changes to make bad + || PartnerMoveIsSameAsAttacker(AI_DATA->battlerAtkPartner, battlerDef, move, AI_DATA->partnerMove)) + score -= 10; + + else if (targetNegativeStages < targetPositiveStages) + score -= 5; //More stages would be made positive than negative + } + break; + case EFFECT_FAIRY_LOCK: + if ((gFieldStatuses & STATUS_FIELD_FAIRY_LOCK) || PartnerMoveIsSameNoTarget(AI_DATA->battlerAtkPartner, move, AI_DATA->partnerMove)) + score -= 10; + break; + case EFFECT_DO_NOTHING: + score -= 10; + break; + case EFFECT_INSTRUCT: + { + u16 instructedMove; + if (GetWhoStrikesFirst(battlerAtk, battlerDef, TRUE) == 1) + instructedMove = predictedMove; + else + instructedMove = gLastMoves[battlerDef]; + + if (instructedMove == MOVE_NONE + || IsInstructBannedMove(instructedMove) + || MoveRequiresRecharging(instructedMove) + || MoveCallsOtherMove(instructedMove) + #ifdef ITEM_Z_RING + //|| (IsZMove(instructedMove)) + #endif + || (gLockedMoves[battlerDef] != 0 && gLockedMoves[battlerDef] != 0xFFFF) + || gBattleMons[battlerDef].status2 & STATUS2_MULTIPLETURNS + || PartnerMoveIsSameAsAttacker(AI_DATA->battlerAtkPartner, battlerDef, move, AI_DATA->partnerMove)) + { + score -= 10; + } + else if (isDoubleBattle) + { + if (!IsTargetingPartner(battlerAtk, battlerDef)) + score -= 10; + } + else + { + if (gBattleMoves[instructedMove].target & (MOVE_TARGET_SELECTED + | MOVE_TARGET_DEPENDS + | MOVE_TARGET_RANDOM + | MOVE_TARGET_BOTH + | MOVE_TARGET_FOES_AND_ALLY + | MOVE_TARGET_OPPONENTS_FIELD) + && instructedMove != MOVE_MIND_BLOWN && instructedMove != MOVE_STEEL_BEAM) + score -= 10; //Don't force the enemy to attack you again unless it can kill itself with Mind Blown + else if (instructedMove != MOVE_MIND_BLOWN) + score -= 5; //Do something better + } + } + break; + case EFFECT_QUASH: + if (!isDoubleBattle + || GetWhoStrikesFirst(battlerAtk, battlerDef, TRUE) == 1 + || PartnerMoveIsSameAsAttacker(AI_DATA->battlerAtkPartner, battlerDef, move, AI_DATA->partnerMove)) + score -= 10; + break; + case EFFECT_AFTER_YOU: + if (!IsTargetingPartner(battlerAtk, battlerDef) + || !isDoubleBattle + || GetWhoStrikesFirst(battlerAtk, battlerDef, TRUE) == 1 + || PartnerMoveIsSameAsAttacker(AI_DATA->battlerAtkPartner, battlerDef, move, AI_DATA->partnerMove)) + score -= 10; + break; + case EFFECT_SUCKER_PUNCH: + if (predictedMove != MOVE_NONE) + { + if (IS_MOVE_STATUS(predictedMove) || GetWhoStrikesFirst(battlerAtk, battlerDef, TRUE) == 1) // opponent going first + score -= 10; + } + break; + case EFFECT_TAILWIND: + if (gSideTimers[GetBattlerSide(battlerAtk)].tailwindTimer != 0 + || PartnerMoveIs(AI_DATA->battlerAtkPartner, AI_DATA->partnerMove, MOVE_TAILWIND) + || (gFieldStatuses & STATUS_FIELD_TRICK_ROOM && gFieldTimers.trickRoomTimer > 1)) // Trick Room active and not ending this turn + score -= 10; + break; + case EFFECT_LUCKY_CHANT: + if (gSideTimers[GET_BATTLER_SIDE(battlerAtk)].luckyChantTimer != 0 + || PartnerMoveIsSameNoTarget(AI_DATA->battlerAtkPartner, move, AI_DATA->partnerMove)) + score -= 10; + break; + case EFFECT_MAGNET_RISE: + if (gFieldStatuses & STATUS_FIELD_GRAVITY + || gDisableStructs[battlerAtk].magnetRiseTimer != 0 + || AI_DATA->atkHoldEffect == HOLD_EFFECT_IRON_BALL + || gStatuses3[battlerAtk] & (STATUS3_ROOTED | STATUS3_MAGNET_RISE | STATUS3_SMACKED_DOWN) + || !IsBattlerGrounded(battlerAtk)) + score -= 10; + break; + case EFFECT_CAMOUFLAGE: + if (!CanCamouflage(battlerAtk)) + score -= 10; + break; + case EFFECT_LAST_RESORT: + if (!CanUseLastResort(battlerAtk)) + score -= 10; + break; + case EFFECT_SYNCHRONOISE: + //Check holding ring target or is of same type + if (AI_DATA->defHoldEffect == HOLD_EFFECT_RING_TARGET + || IS_BATTLER_OF_TYPE(battlerDef, gBattleMons[battlerAtk].type1) + || IS_BATTLER_OF_TYPE(battlerDef, gBattleMons[battlerAtk].type2) + || IS_BATTLER_OF_TYPE(battlerDef, gBattleMons[battlerAtk].type3)) + break; + else + score -= 10; + break; + case EFFECT_ERUPTION: + if (effectiveness <= AI_EFFECTIVENESS_x0_5) + score--; + if (GetHealthPercentage(battlerDef) < 50) + score--; + break; + case EFFECT_VITAL_THROW: + if (IsAiFaster(AI_CHECK_FASTER) && GetHealthPercentage(battlerAtk) < 40) + score--; // don't want to move last + break; + case EFFECT_FLAIL: + if (GetWhoStrikesFirst(battlerAtk, battlerDef, TRUE) == 1 // opponent should go first + || GetHealthPercentage(battlerAtk) > 50) + score -= 4; + break; + //TODO + //case EFFECT_PLASMA_FISTS: + //break; + //case EFFECT_SHELL_TRAP: + //break; + //case EFFECT_BEAK_BLAST: + //break; + /*case EFFECT_SKY_DROP: + if (IS_BATTLER_OF_TYPE(battlerDef, TYPE_FLYING)) + score -= 10; + if (WillFaintFromWeather(battlerAtk) + || MoveBlockedBySubstitute(move, battlerAtk, battlerDef) + || GetSpeciesWeight(gBattleMons[battlerDef].species, AI_DATA->defAbility, AI_DATA->defHoldEffect, battlerDef, TRUE) >= 2000) //200.0 kg + score -= 10; + break; + */ + /*case EFFECT_NO_RETREAT: + if (TrappedByNoRetreat(battlerAtk)) + score -= 10; + break; + case EFFECT_EXTREME_EVOBOOST: + if (MainStatsMaxed(battlerAtk)) + score -= 10; + break; + case EFFECT_CLANGOROUS_SOUL: + if (gBattleMons[battlerAtk].hp <= gBattleMons[battlerAtk].maxHP / 3) + score -= 10; + break;*/ + } // move effect checks + + if (score < 0) + score = 0; + + return score; +} + +static s16 AI_TryToFaint(u8 battlerAtk, u8 battlerDef, u16 move, s16 score) +{ + if (IsTargetingPartner(battlerAtk, battlerDef)) + return score; + + if (gBattleMoves[move].power == 0) + return score; // can't make anything faint with no power + + if (CanAttackerFaintTarget(battlerAtk, battlerDef, AI_THINKING_STRUCT->movesetIndex, 0) && gBattleMoves[move].effect != EFFECT_EXPLOSION) + { + // this move can faint the target + if (GetWhoStrikesFirst(battlerAtk, battlerDef, TRUE) == 0 || GetMovePriority(battlerAtk, move) > 0) + score += 4; // we go first or we're using priority move + else + score += 2; + } + else + { + // this move isn't expected to faint the target + if (TestMoveFlags(move, FLAG_HIGH_CRIT)) + score += 2; // crit makes it more likely to make them faint + + if (GetMoveDamageResult(move) == MOVE_POWER_DISCOURAGED) + score--; + + switch (AI_GetMoveEffectiveness(move, battlerAtk, battlerDef)) + { + case AI_EFFECTIVENESS_x4: + score += 4; + break; + case AI_EFFECTIVENESS_x2: + if (AI_RandLessThan(176)) + score += 2; + else + score++; + break; + } + } + + //AI_TryToFaint_CheckIfDanger + if (!IsAiFaster(AI_CHECK_FASTER) && CanTargetFaintAi(battlerDef, battlerAtk)) + { // AI_TryToFaint_Danger + if (GetMoveDamageResult(move) != MOVE_POWER_BEST) + score--; + else + score++; + } + + return score; +} + +// double battle logic +static s16 AI_DoubleBattle(u8 battlerAtk, u8 battlerDef, u16 move, s16 score) +{ + // move data + u8 moveType = gBattleMoves[move].type; + u16 effect = gBattleMoves[move].effect; + u8 target = gBattleMoves[move].target; + // ally data + u8 battlerAtkPartner = AI_DATA->battlerAtkPartner; + u16 atkPartnerAbility = AI_DATA->atkPartnerAbility; + u16 atkPartnerHoldEffect = AI_DATA->atkPartnerHoldEffect; + bool32 partnerProtecting = (gBattleMoves[AI_DATA->partnerMove].effect == EFFECT_PROTECT); + bool32 attackerHasBadAbility = (GetAbilityRating(AI_DATA->atkAbility) < 0); + bool32 partnerHasBadAbility = (GetAbilityRating(atkPartnerAbility) < 0); + u16 predictedMove = gLastMoves[battlerDef]; //for now + + // check what effect partner is using + if (AI_DATA->partnerMove != 0) + { + switch (gBattleMoves[AI_DATA->partnerMove].effect) + { + case EFFECT_HELPING_HAND: + if (IS_MOVE_STATUS(move)) + score += 5; + break; + case EFFECT_PERISH_SONG: + if (!(gBattleMons[battlerDef].status2 & (STATUS2_ESCAPE_PREVENTION | STATUS2_WRAPPED))) + { + if (IsTrappingMoveEffect(effect) || predictedMove == MOVE_INGRAIN) + score++; + } + break; + case EFFECT_ALWAYS_CRIT: + // Ally decided to use Frost Breath on us. we must have Anger Point as our ability + if (AI_DATA->atkAbility == ABILITY_ANGER_POINT) + { + if (GetWhoStrikesFirst(battlerAtk, battlerAtkPartner, TRUE) == 1) // partner moving first + { + // discourage raising our attack since it's about to be maxed out + if (IsAttackBoostMoveEffect(effect)) + score -= 3; + // encourage moves hitting multiple opponents + if (!IS_MOVE_STATUS(move) && (gBattleMoves[move].target & (MOVE_TARGET_BOTH | MOVE_TARGET_FOES_AND_ALLY))) + score += 3; + } + } + break; + } + } // check partner move effect + + + // consider our move effect relative to partner state + switch (effect) + { + case EFFECT_HELPING_HAND: + if (AI_DATA->partnerMove != 0 && !HasDamagingMove(battlerAtkPartner)) + score -= 5; + break; + case EFFECT_PERISH_SONG: + if (AI_DATA->partnerMove != 0 && HasTrappingMoveEffect(battlerAtkPartner)) + score++; + break; + case EFFECT_MAGNET_RISE: + if (IsBattlerGrounded(battlerAtk) + && (HasMove(battlerAtkPartner, MOVE_EARTHQUAKE) || HasMove(battlerAtkPartner, MOVE_MAGNITUDE)) + && (AI_GetMoveEffectiveness(MOVE_EARTHQUAKE, battlerAtk, battlerAtkPartner) != AI_EFFECTIVENESS_x0)) // Doesn't resist ground move + { + RETURN_SCORE_PLUS(2); // partner has earthquake or magnitude -> good idea to use magnet rise + } + break; + } // our effect relative to partner + + + // consider global move effects + switch (effect) + { + case EFFECT_SANDSTORM: + if (ShouldSetSandstorm(battlerAtkPartner, atkPartnerAbility, atkPartnerHoldEffect)) + { + RETURN_SCORE_PLUS(1); // our partner benefits from sandstorm + } + break; + case EFFECT_RAIN_DANCE: + if (ShouldSetRain(battlerAtkPartner, atkPartnerAbility, atkPartnerHoldEffect)) + { + RETURN_SCORE_PLUS(1); // our partner benefits from rain + } + break; + case EFFECT_SUNNY_DAY: + if (ShouldSetSun(battlerAtkPartner, atkPartnerAbility, atkPartnerHoldEffect)) + { + RETURN_SCORE_PLUS(1); // our partner benefits from sun + } + break; + case EFFECT_HAIL: + if (IsBattlerAlive(battlerAtkPartner) + && ShouldSetHail(battlerAtkPartner, atkPartnerAbility, atkPartnerHoldEffect)) + { + RETURN_SCORE_PLUS(2); // our partner benefits from hail + } + break; + } // global move effect check + + + // check specific target + if (IsTargetingPartner(battlerAtk, battlerDef)) + { + if (GetMoveDamageResult(move) == MOVE_POWER_DISCOURAGED) + { + // partner ability checks + if (!partnerProtecting && gBattleMoves[move].target != MOVE_TARGET_BOTH && !DoesBattlerIgnoreAbilityChecks(AI_DATA->atkAbility, move)) + { + switch (atkPartnerAbility) + { + case ABILITY_VOLT_ABSORB: + if (!(AI_THINKING_STRUCT->aiFlags & AI_FLAG_HP_AWARE)) + { + RETURN_SCORE_MINUS(10); + } + break; // handled in AI_HPAware + case ABILITY_MOTOR_DRIVE: + if (moveType == TYPE_ELECTRIC && BattlerStatCanRise(battlerAtkPartner, atkPartnerAbility, STAT_SPEED)) + { + RETURN_SCORE_PLUS(1); + } + break; + case ABILITY_LIGHTNING_ROD: + if (moveType == TYPE_ELECTRIC + && HasMoveWithSplit(battlerAtkPartner, SPLIT_SPECIAL) + && BattlerStatCanRise(battlerAtkPartner, atkPartnerAbility, STAT_SPATK)) + { + RETURN_SCORE_PLUS(1); + } + break; + case ABILITY_WATER_ABSORB: + case ABILITY_DRY_SKIN: + if (!(AI_THINKING_STRUCT->aiFlags & AI_FLAG_HP_AWARE)) + { + RETURN_SCORE_MINUS(10); + } + break; // handled in AI_HPAware + case ABILITY_STORM_DRAIN: + if (moveType == TYPE_WATER + && HasMoveWithSplit(battlerAtkPartner, SPLIT_SPECIAL) + && BattlerStatCanRise(battlerAtkPartner, atkPartnerAbility, STAT_SPATK)) + { + RETURN_SCORE_PLUS(1); + } + break; + case ABILITY_WATER_COMPACTION: + if (moveType == TYPE_WATER && GetMoveDamageResult(move) == MOVE_POWER_WEAK) + { + RETURN_SCORE_PLUS(1); // only mon with this ability is weak to water so only make it okay if we do very little damage + } + RETURN_SCORE_MINUS(10); + break; + case ABILITY_FLASH_FIRE: + if (moveType == TYPE_FIRE + && HasMoveWithType(battlerAtkPartner, TYPE_FIRE) + && !(gBattleResources->flags->flags[battlerAtkPartner] & RESOURCE_FLAG_FLASH_FIRE)) + { + RETURN_SCORE_PLUS(1); + } + break; + case ABILITY_SAP_SIPPER: + if (moveType == TYPE_GRASS + && HasMoveWithSplit(battlerAtkPartner, SPLIT_PHYSICAL) + && BattlerStatCanRise(battlerAtkPartner, atkPartnerAbility, STAT_ATK)) + { + RETURN_SCORE_PLUS(1); + } + break; + case ABILITY_JUSTIFIED: + if (moveType == TYPE_DARK + && !IS_MOVE_STATUS(move) + && HasMoveWithSplit(battlerAtkPartner, SPLIT_PHYSICAL) + && BattlerStatCanRise(battlerAtkPartner, atkPartnerAbility, STAT_ATK) + && !CanAttackerFaintTarget(battlerAtk, battlerAtkPartner, AI_THINKING_STRUCT->movesetIndex, 1)) + { + RETURN_SCORE_PLUS(1); + } + break; + case ABILITY_RATTLED: + if (!IS_MOVE_STATUS(move) + && (moveType == TYPE_DARK || moveType == TYPE_GHOST || moveType == TYPE_BUG) + && BattlerStatCanRise(battlerAtkPartner, atkPartnerAbility, STAT_SPEED) + && !CanAttackerFaintTarget(battlerAtk, battlerAtkPartner, AI_THINKING_STRUCT->movesetIndex, 1)) + { + RETURN_SCORE_PLUS(1); + } + break; + case ABILITY_CONTRARY: + if (IsStatLoweringEffect(effect)) + { + RETURN_SCORE_PLUS(2); + } + break; + case ABILITY_DEFIANT: + if (IsStatLoweringEffect(effect) + && BattlerStatCanRise(battlerAtkPartner, atkPartnerAbility, STAT_ATK)) + { + RETURN_SCORE_PLUS(1); + } + break; + case ABILITY_COMPETITIVE: + if (IsStatLoweringEffect(effect) + && BattlerStatCanRise(battlerAtkPartner, atkPartnerAbility, STAT_SPATK)) + { + RETURN_SCORE_PLUS(1); + } + break; + } + } // ability checks + } // move power check + + // attacker move effects specifically targeting partner + if (!partnerProtecting) + { + switch (effect) + { + case EFFECT_PURIFY: + if (gBattleMons[battlerAtkPartner].status1 & STATUS1_ANY) + { + RETURN_SCORE_PLUS(1); + } + break; + case EFFECT_SWAGGER: + if (gBattleMons[battlerAtkPartner].statStages[STAT_ATK] < MAX_STAT_STAGE + && HasMoveWithSplit(battlerAtkPartner, SPLIT_PHYSICAL) + && (!CanBeConfused(battlerAtkPartner, TRUE) + || atkPartnerHoldEffect == HOLD_EFFECT_CURE_CONFUSION + || atkPartnerHoldEffect == HOLD_EFFECT_CURE_STATUS)) + { + RETURN_SCORE_PLUS(1); + } + break; + case EFFECT_FLATTER: + if (gBattleMons[battlerAtkPartner].statStages[STAT_SPATK] < MAX_STAT_STAGE + && HasMoveWithSplit(battlerAtkPartner, SPLIT_SPECIAL) + && (!CanBeConfused(battlerAtkPartner, TRUE) + || atkPartnerHoldEffect == HOLD_EFFECT_CURE_CONFUSION + || atkPartnerHoldEffect == HOLD_EFFECT_CURE_STATUS)) + { + RETURN_SCORE_PLUS(1); + } + break; + case EFFECT_BEAT_UP: + if (atkPartnerAbility == ABILITY_JUSTIFIED + && moveType == TYPE_DARK + && !IS_MOVE_STATUS(move) + && HasMoveWithSplit(battlerAtkPartner, SPLIT_PHYSICAL) + && BattlerStatCanRise(battlerAtkPartner, atkPartnerAbility, STAT_ATK) + && !CanAttackerFaintTarget(battlerAtk, battlerAtkPartner, AI_THINKING_STRUCT->movesetIndex, 0)) + { + RETURN_SCORE_PLUS(1); + } + break; + case EFFECT_SKILL_SWAP: + if (AI_DATA->atkAbility != AI_DATA->atkPartnerAbility && !attackerHasBadAbility) + { + if (AI_DATA->atkPartnerAbility == ABILITY_TRUANT) + { + RETURN_SCORE_PLUS(10); + } + else if (AI_DATA->atkAbility == ABILITY_COMPOUND_EYES + && HasMoveWithLowAccuracy(battlerAtkPartner, FOE(battlerAtkPartner), 90, TRUE, atkPartnerAbility, AI_GetAbility(FOE(battlerAtkPartner)), atkPartnerHoldEffect, AI_GetHoldEffect(FOE(battlerAtkPartner)))) + { + RETURN_SCORE_PLUS(3); + } + } + break; + case EFFECT_ROLE_PLAY: + if (attackerHasBadAbility && !partnerHasBadAbility) + { + RETURN_SCORE_PLUS(1); + } + break; + case EFFECT_WORRY_SEED: + case EFFECT_GASTRO_ACID: + case EFFECT_SIMPLE_BEAM: + if (partnerHasBadAbility) + { + RETURN_SCORE_PLUS(2); + } + break; + case EFFECT_ENTRAINMENT: + if (partnerHasBadAbility && IsAbilityOfRating(AI_DATA->atkAbility, 0)) + { + RETURN_SCORE_PLUS(1); + } + break; + case EFFECT_SOAK: + if (atkPartnerAbility == ABILITY_WONDER_GUARD + && (gBattleMons[battlerAtkPartner].type1 != TYPE_WATER + || gBattleMons[battlerAtkPartner].type2 != TYPE_WATER + || gBattleMons[battlerAtkPartner].type3 != TYPE_WATER)) + { + RETURN_SCORE_PLUS(1); + } + break; + case EFFECT_INSTRUCT: + { + u16 instructedMove; + if (GetWhoStrikesFirst(battlerAtk, battlerAtkPartner, TRUE) == 0) + instructedMove = AI_DATA->partnerMove; + else + instructedMove = gLastMoves[battlerAtkPartner]; + + if (instructedMove != MOVE_NONE + && !IS_MOVE_STATUS(instructedMove) + && gBattleMoves[instructedMove].target & (MOVE_TARGET_BOTH | MOVE_TARGET_FOES_AND_ALLY)) //Use instruct on multi-target moves + { + RETURN_SCORE_PLUS(1); + } + } + break; + case EFFECT_AFTER_YOU: + if (GetWhoStrikesFirst(battlerAtkPartner, FOE(battlerAtkPartner), TRUE) == 1 // opponent mon 1 goes before partner + || GetWhoStrikesFirst(battlerAtkPartner, BATTLE_PARTNER(FOE(battlerAtkPartner)), TRUE) == 1) // opponent mon 2 goes before partner + { + if (gBattleMoves[AI_DATA->partnerMove].effect == EFFECT_COUNTER || gBattleMoves[AI_DATA->partnerMove].effect == EFFECT_MIRROR_COAT) + break; // These moves need to go last + RETURN_SCORE_PLUS(1); + } + break; + } // attacker move effects + } // check partner protecting + + score -= 30; // otherwise, don't target partner + } + else // checking opponent + { + // these checks mostly handled in AI_CheckBadMove and AI_CheckViability + switch (effect) + { + case EFFECT_SKILL_SWAP: + if (AI_DATA->atkAbility == ABILITY_TRUANT) + score += 5; + else if (IsAbilityOfRating(AI_DATA->atkAbility, 0) || IsAbilityOfRating(AI_DATA->defAbility, 10)) + score += 2; // we want to transfer our bad ability or take their awesome ability + break; + case EFFECT_EARTHQUAKE: + case EFFECT_MAGNITUDE: + if (!IsBattlerGrounded(battlerAtkPartner) + || (GetWhoStrikesFirst(battlerAtk, battlerAtkPartner, TRUE) == 1 && IsUngroundingEffect(gBattleMoves[AI_DATA->partnerMove].effect))) + score += 2; + else if (IS_BATTLER_OF_TYPE(battlerAtkPartner, TYPE_FIRE) + || IS_BATTLER_OF_TYPE(battlerAtkPartner, TYPE_ELECTRIC) + || IS_BATTLER_OF_TYPE(battlerAtkPartner, TYPE_POISON) + || IS_BATTLER_OF_TYPE(battlerAtkPartner, TYPE_ROCK)) + score -= 10; // partner will be hit by earthquake and is weak to it + else + score -= 3; + break; + } + + // lightning rod, flash fire against enemy handled in AI_CheckBadMove + } + + return score; +} + +// AI_FLAG_CHECK_VIABILITY - a weird mix of increasing and decreasing scores +static s16 AI_CheckViability(u8 battlerAtk, u8 battlerDef, u16 move, s16 score) +{ + // move data + u16 moveEffect = gBattleMoves[move].effect; + u8 effectiveness = AI_GetMoveEffectiveness(move, battlerAtk, battlerDef); + u8 atkPriority = GetMovePriority(battlerAtk, move); + u16 predictedMove = gLastMoves[battlerDef]; //for now + bool32 isDoubleBattle = IsValidDoubleBattle(battlerAtk); + u32 i; + u8 atkHpPercent = GetHealthPercentage(battlerAtk); + u8 defHpPercent = GetHealthPercentage(battlerDef); + + // Targeting partner, check benefits of doing that instead + if (IsTargetingPartner(battlerAtk, battlerDef)) + return score; + + // check always hits + if (!IS_MOVE_STATUS(move) && gBattleMoves[move].accuracy == 0) + { + if (gBattleMons[battlerDef].statStages[STAT_EVASION] >= 10 || gBattleMons[battlerAtk].statStages[STAT_ACC] <= 2) + score++; + if (AI_RandLessThan(100) && (gBattleMons[battlerDef].statStages[STAT_EVASION] >= 8 || gBattleMons[battlerAtk].statStages[STAT_ACC] <= 4)) + score++; + } + + // check high crit + if (TestMoveFlags(move, FLAG_HIGH_CRIT) && effectiveness >= AI_EFFECTIVENESS_x2 && AI_RandLessThan(128)) + score++; + + // check already dead + if (!IsBattlerIncapacitated(battlerDef, AI_DATA->defAbility) + && CanTargetFaintAi(battlerAtk, battlerDef) + && GetWhoStrikesFirst(battlerAtk, battlerDef, TRUE) == 1) // opponent should go first + { + if (atkPriority > 0) + score++; + else + score--; + } + + // check damage + if (gBattleMoves[move].power != 0 && GetMoveDamageResult(move) == MOVE_POWER_WEAK) + score--; + + // check status move preference + if (AI_THINKING_STRUCT->aiFlags & AI_FLAG_PREFER_STATUS_MOVES && IS_MOVE_STATUS(move) && effectiveness != AI_EFFECTIVENESS_x0) + score++; + + // check thawing moves + if ((gBattleMons[battlerAtk].status1 & STATUS1_FREEZE) && IsThawingMove(battlerAtk, move)) + score += (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) ? 20 : 10; + + // check burn + if (gBattleMons[battlerAtk].status1 & STATUS1_BURN) + { + switch (AI_DATA->atkAbility) + { + case ABILITY_GUTS: + break; + case ABILITY_NATURAL_CURE: + if (AI_THINKING_STRUCT->aiFlags & AI_FLAG_SMART_SWITCHING + && HasOnlyMovesWithSplit(battlerAtk, SPLIT_PHYSICAL, TRUE)) + score = 90; // Force switch if all your attacking moves are physical and you have Natural Cure. + break; + default: + if (IS_MOVE_PHYSICAL(move) && gBattleMoves[move].effect != EFFECT_FACADE) + score -= 2; + break; + } + } + + // ability checks + switch (AI_DATA->atkAbility) + { + case ABILITY_MOXIE: + case ABILITY_BEAST_BOOST: + if (GetWhoStrikesFirst(battlerAtk, battlerDef, TRUE) == 0) // attacker should go first + { + if (CanAttackerFaintTarget(battlerAtk, battlerDef, AI_THINKING_STRUCT->movesetIndex, 0)) + score += 8; // prioritize killing target for stat boost + } + break; + case ABILITY_MAGIC_GUARD: + switch (moveEffect) + { + case EFFECT_POISON: + case EFFECT_WILL_O_WISP: + case EFFECT_TOXIC: + case EFFECT_LEECH_SEED: + score -= 5; + break; + case EFFECT_CURSE: + if (IS_BATTLER_OF_TYPE(battlerDef, TYPE_GHOST)) + score -= 5; + break; + } + break; + } // ability checks + + // move effect checks + switch (moveEffect) + { + + case EFFECT_HIT: + break; + case EFFECT_SLEEP: + case EFFECT_YAWN: + if (AI_RandLessThan(128)) + IncreaseSleepScore(battlerAtk, battlerDef, move, &score); + break; + case EFFECT_ABSORB: + if (AI_DATA->atkHoldEffect == HOLD_EFFECT_BIG_ROOT) + score++; + if (effectiveness <= AI_EFFECTIVENESS_x0_5 && AI_RandLessThan(50)) + score -= 3; + break; + case EFFECT_EXPLOSION: + case EFFECT_MEMENTO: + if (AI_THINKING_STRUCT->aiFlags & AI_FLAG_WILL_SUICIDE && gBattleMons[battlerDef].statStages[STAT_EVASION] < 7) + { + if (atkHpPercent < 50 && AI_RandLessThan(128)) + score++; + } + break; + case EFFECT_MIRROR_MOVE: + if (predictedMove != MOVE_NONE) + return AI_CheckViability(battlerAtk, battlerDef, gLastMoves[battlerDef], score); + break; +// stat raising effects + case EFFECT_ATTACK_UP: + case EFFECT_ATTACK_UP_2: + if (MovesWithSplitUnusable(battlerAtk, battlerDef, SPLIT_PHYSICAL)) + { + score -= 8; + break; + } + else if (gBattleMons[battlerAtk].statStages[STAT_ATK] < 9) + { + if (atkHpPercent > 90 && AI_RandLessThan(128)) + { + score += 2; + break; + } + } + + if (!AI_RandLessThan(100)) + { + score--; + } + break; + case EFFECT_DEFENSE_UP: + case EFFECT_DEFENSE_UP_2: + case EFFECT_DEFENSE_UP_3: + if (!HasMoveWithSplit(battlerDef, SPLIT_PHYSICAL)) + score -= 2; + if (atkHpPercent > 90 && AI_RandLessThan(128)) + score += 2; + else if (atkHpPercent > 70 && AI_RandLessThan(200)) + break; + else if (atkHpPercent < 40) + score -= 2; + break; + case EFFECT_SPEED_UP: + case EFFECT_SPEED_UP_2: + if (IsAiFaster(AI_CHECK_SLOWER)) + { + if (!AI_RandLessThan(70)) + score += 3; + } + else + { + score -= 3; + } + break; + case EFFECT_SPECIAL_ATTACK_UP: + case EFFECT_SPECIAL_ATTACK_UP_2: + case EFFECT_SPECIAL_ATTACK_UP_3: + if (MovesWithSplitUnusable(battlerAtk, battlerDef, SPLIT_SPECIAL)) + { + score -= 8; + break; + } + else if (gBattleMons[battlerAtk].statStages[STAT_SPATK] < 9) + { + if (atkHpPercent > 90 && AI_RandLessThan(128)) + { + score += 2; + break; + } + } + + if (!AI_RandLessThan(100)) + { + score--; + } + break; + case EFFECT_SPECIAL_DEFENSE_UP: + case EFFECT_SPECIAL_DEFENSE_UP_2: + if (!HasMoveWithSplit(battlerDef, SPLIT_SPECIAL)) + score -= 2; + if (atkHpPercent > 90 && AI_RandLessThan(128)) + score += 2; + else if (GetHealthPercentage(battlerAtk) > 70 && AI_RandLessThan(200)) + break; + else if (GetHealthPercentage(battlerAtk) < 40) + score -= 2; + break; + case EFFECT_ACCURACY_UP: + case EFFECT_ACCURACY_UP_2: + if (gBattleMons[battlerAtk].statStages[STAT_ACC] >= 9 && !AI_RandLessThan(50)) + score -= 2; + else if (atkHpPercent <= 70) + score -= 2; + else + score++; + break; + case EFFECT_EVASION_UP: + case EFFECT_EVASION_UP_2: + if (atkHpPercent > 90 && !AI_RandLessThan(100)) + score += 3; + if (gBattleMons[battlerAtk].statStages[STAT_EVASION] > 9 && AI_RandLessThan(128)) + score--; + if ((gBattleMons[battlerDef].status1 & STATUS1_PSN_ANY) && atkHpPercent >= 50 && !AI_RandLessThan(80)) + score += 3; + if (gStatuses3[battlerDef] & STATUS3_LEECHSEED && !AI_RandLessThan(70)) + score += 3; + if (gStatuses3[battlerAtk] & STATUS3_ROOTED && AI_RandLessThan(128)) + score += 2; + if (gBattleMons[battlerDef].status2 & STATUS2_CURSED && !AI_RandLessThan(70)) + score += 3; + if (atkHpPercent < 70 || gBattleMons[battlerAtk].statStages[STAT_EVASION] == DEFAULT_STAT_STAGE) + break; + else if (atkHpPercent < 40 || defHpPercent < 40) + score -= 2; + else if (!AI_RandLessThan(70)) + score -= 2; + break; +// stat lowering effects + case EFFECT_ATTACK_DOWN: + case EFFECT_ATTACK_DOWN_2: + if (!ShouldLowerAttack(battlerAtk, battlerDef, AI_DATA->defAbility)) + score -= 2; + if (gBattleMons[battlerDef].statStages[STAT_ATK] < DEFAULT_STAT_STAGE) + score--; + else if (atkHpPercent <= 90) + score--; + if (gBattleMons[battlerDef].statStages[STAT_ATK] > 3 && !AI_RandLessThan(50)) + score -= 2; + else if (defHpPercent < 70) + score -= 2; + break; + case EFFECT_DEFENSE_DOWN: + case EFFECT_DEFENSE_DOWN_2: + if (!ShouldLowerDefense(battlerAtk, battlerDef, AI_DATA->defAbility)) + score -= 2; + if ((atkHpPercent < 70 && !AI_RandLessThan(50)) || (gBattleMons[battlerDef].statStages[STAT_DEF] <= 3 && !AI_RandLessThan(50))) + score -= 2; + if (defHpPercent <= 70) + score -= 2; + break; + case EFFECT_SPEED_DOWN: + case EFFECT_SPEED_DOWN_2: + if (IsAiFaster(AI_CHECK_FASTER)) + score -= 3; + else if (!AI_RandLessThan(70)) + score += 2; + break; + case EFFECT_SPECIAL_ATTACK_DOWN: + case EFFECT_SPECIAL_ATTACK_DOWN_2: + if (!ShouldLowerSpAtk(battlerAtk, battlerDef, AI_DATA->defAbility)) + score -= 2; + if (gBattleMons[battlerDef].statStages[STAT_SPATK] < DEFAULT_STAT_STAGE) + score--; + else if (atkHpPercent <= 90) + score--; + if (gBattleMons[battlerDef].statStages[STAT_SPATK] > 3 && !AI_RandLessThan(50)) + score -= 2; + else if (defHpPercent < 70) + score -= 2; + break; + case EFFECT_SPECIAL_DEFENSE_DOWN: + case EFFECT_SPECIAL_DEFENSE_DOWN_2: + if (!ShouldLowerSpDef(battlerAtk, battlerDef, AI_DATA->defAbility)) + score -= 2; + if ((atkHpPercent < 70 && !AI_RandLessThan(50)) + || (gBattleMons[battlerDef].statStages[STAT_SPDEF] <= 3 && !AI_RandLessThan(50))) + score -= 2; + if (defHpPercent <= 70) + score -= 2; + break; + case EFFECT_ACCURACY_DOWN: + case EFFECT_ACCURACY_DOWN_2: + if (ShouldLowerAccuracy(battlerAtk, battlerDef, AI_DATA->defAbility)) + score -= 2; + if ((atkHpPercent < 70 || defHpPercent < 70) && AI_RandLessThan(100)) + score--; + if (gBattleMons[battlerDef].statStages[STAT_ACC] <= 4 && !AI_RandLessThan(80)) + score -= 2; + if (gBattleMons[battlerDef].status1 & STATUS1_PSN_ANY && !AI_RandLessThan(70)) + score += 2; + if (gStatuses3[battlerDef] & STATUS3_LEECHSEED && !AI_RandLessThan(70)) + score += 2; + if (gStatuses3[battlerDef] & STATUS3_ROOTED && AI_RandLessThan(128)) + score++; + if (gBattleMons[battlerDef].status2 & STATUS2_CURSED && !AI_RandLessThan(70)) + score += 2; + if (atkHpPercent > 70 || gBattleMons[battlerDef].statStages[STAT_ACC] < DEFAULT_STAT_STAGE) + break; + else if (atkHpPercent < 40 || defHpPercent < 40 || !AI_RandLessThan(70)) + score -= 2; + break; + case EFFECT_EVASION_DOWN: + case EFFECT_EVASION_DOWN_2: + if (!ShouldLowerEvasion(battlerAtk, battlerDef, AI_DATA->defAbility)) + score -= 2; + if ((atkHpPercent < 70 || gBattleMons[battlerDef].statStages[STAT_EVASION] <= 3) && !AI_RandLessThan(50)) + score -= 2; + if (defHpPercent <= 70) + score -= 2; + if (gBattleMons[battlerAtk].statStages[STAT_ACC] < DEFAULT_STAT_STAGE) + score++; + if (gBattleMons[battlerDef].statStages[STAT_EVASION] < 7 || AI_DATA->atkAbility == ABILITY_NO_GUARD) + score -= 2; + break; + case EFFECT_BIDE: + if (atkHpPercent < 90) + score -= 2; + break; + case EFFECT_DREAM_EATER: + if (!(gBattleMons[battlerDef].status1 & STATUS1_SLEEP)) + break; + score++; // if target is asleep, dream eater is a pretty good move even without draining + // fallthrough + case EFFECT_ACUPRESSURE: + break; + case EFFECT_ATTACK_ACCURACY_UP: // hone claws + IncreaseStatUpScore(battlerAtk, battlerDef, STAT_ATK, &score); + IncreaseStatUpScore(battlerAtk, battlerDef, STAT_ACC, &score); + break; + case EFFECT_GROWTH: + case EFFECT_ATTACK_SPATK_UP: // work up + if (GetHealthPercentage(battlerAtk) <= 40 || AI_DATA->atkAbility == ABILITY_CONTRARY) + break; + + if (HasMoveWithSplit(battlerAtk, SPLIT_PHYSICAL)) + IncreaseStatUpScore(battlerAtk, battlerDef, STAT_ATK, &score); + else if (HasMoveWithSplit(battlerAtk, SPLIT_SPECIAL)) + IncreaseStatUpScore(battlerAtk, battlerDef, STAT_SPATK, &score); + break; + case EFFECT_HAZE: + if (AnyStatIsRaised(AI_DATA->battlerAtkPartner) + || PartnerHasSameMoveEffectWithoutTarget(AI_DATA->battlerAtkPartner, move, AI_DATA->partnerMove)) + score -= 3; + break; + // fallthrough + case EFFECT_ROAR: + case EFFECT_CLEAR_SMOG: + if (isDoubleBattle) + score += min(CountPositiveStatStages(battlerDef) + CountPositiveStatStages(AI_DATA->battlerDefPartner), 7); + else + score += min(CountPositiveStatStages(battlerDef), 4); + break; + case EFFECT_MULTI_HIT: + case EFFECT_DOUBLE_HIT: + case EFFECT_TRIPLE_KICK: + break; + case EFFECT_CONVERSION: + if (!IS_BATTLER_OF_TYPE(battlerAtk, gBattleMoves[gBattleMons[battlerAtk].moves[0]].type)) + score++; + break; + case EFFECT_FLINCH_HIT: + score += ShouldTryToFlinch(battlerAtk, battlerDef, AI_DATA->atkAbility, AI_DATA->defAbility, move); + break; + case EFFECT_SWALLOW: + if (gDisableStructs[battlerAtk].stockpileCounter == 0) + { + break; + } + else + { + u32 healPercent = 0; + switch (gDisableStructs[battlerAtk].stockpileCounter) + { + case 1: + healPercent = 25; + break; + case 2: + healPercent = 50; + break; + case 3: + healPercent = 100; + break; + default: + break; + } + + if (ShouldRecover(battlerAtk, battlerDef, move, healPercent)) + score += 2; + } + break; + case EFFECT_RESTORE_HP: + case EFFECT_SOFTBOILED: + case EFFECT_ROOST: + case EFFECT_MORNING_SUN: + case EFFECT_SYNTHESIS: + case EFFECT_MOONLIGHT: + if (ShouldRecover(battlerAtk, battlerDef, move, 50)) + score += 3; + if (AI_DATA->atkHoldEffect == HOLD_EFFECT_BIG_ROOT) + score++; + break; + case EFFECT_TOXIC: + case EFFECT_POISON: + IncreasePoisonScore(battlerAtk, battlerDef, move, &score); + break; + case EFFECT_LIGHT_SCREEN: + case EFFECT_REFLECT: + case EFFECT_AURORA_VEIL: + if (ShouldSetScreen(battlerAtk, battlerDef, moveEffect)) + { + score += 5; + if (AI_DATA->atkHoldEffect == HOLD_EFFECT_LIGHT_CLAY) + score += 2; + if (AI_THINKING_STRUCT->aiFlags & AI_FLAG_SCREENER) + score += 2; + } + break; + case EFFECT_REST: + if (!(CanSleep(battlerAtk, AI_DATA->atkAbility))) + { + break; + } + else if (ShouldRecover(battlerAtk, battlerDef, move, 100)) + { + if (AI_DATA->atkHoldEffect == HOLD_EFFECT_CURE_SLP + || AI_DATA->atkHoldEffect == HOLD_EFFECT_CURE_STATUS + || HasMoveEffect(EFFECT_SLEEP_TALK, battlerAtk) + || HasMoveEffect(EFFECT_SNORE, battlerAtk) + || AI_DATA->atkAbility == ABILITY_SHED_SKIN + || AI_DATA->atkAbility == ABILITY_EARLY_BIRD + || (gBattleWeather & WEATHER_RAIN_ANY && gWishFutureKnock.weatherDuration != 1 && AI_DATA->atkAbility == ABILITY_HYDRATION && AI_DATA->atkHoldEffect != HOLD_EFFECT_UTILITY_UMBRELLA)) + { + score += 2; + } + else + { + score++; + } + } + break; + case EFFECT_OHKO: + if (gStatuses3[battlerAtk] & STATUS3_ALWAYS_HITS) + score += 5; + break; + case EFFECT_TRAP: + case EFFECT_MEAN_LOOK: + if (HasMoveEffect(battlerDef, EFFECT_RAPID_SPIN) + || IS_BATTLER_OF_TYPE(battlerDef, TYPE_GHOST) + || gBattleMons[battlerDef].status2 & STATUS2_WRAPPED) + { + break; // in this case its a bad attacking move + } + else if (ShouldTrap(battlerAtk, battlerDef, move)) + { + score += 5; + } + break; + case EFFECT_MIST: + if (AI_THINKING_STRUCT->aiFlags & AI_FLAG_SCREENER) + score += 2; + break; + case EFFECT_FOCUS_ENERGY: + case EFFECT_LASER_FOCUS: + if (AI_DATA->atkAbility == ABILITY_SUPER_LUCK + || AI_DATA->atkAbility == ABILITY_SNIPER + || AI_DATA->atkHoldEffect == HOLD_EFFECT_SCOPE_LENS + || TestMoveFlagsInMoveset(battlerAtk, FLAG_HIGH_CRIT)) + score += 2; + break; + case EFFECT_CONFUSE_HIT: + if (AI_DATA->atkAbility == ABILITY_SERENE_GRACE) + score++; + //fallthrough + case EFFECT_CONFUSE: + IncreaseConfusionScore(battlerAtk, battlerDef, move, &score); + break; + case EFFECT_PARALYZE: + IncreaseParalyzeScore(battlerAtk, battlerDef, move, &score); + break; + case EFFECT_ATTACK_DOWN_HIT: + case EFFECT_DEFENSE_DOWN_HIT: + case EFFECT_SPECIAL_ATTACK_DOWN_HIT: + case EFFECT_SPECIAL_DEFENSE_DOWN_HIT: + case EFFECT_ACCURACY_DOWN_HIT: + case EFFECT_EVASION_DOWN_HIT: + if (AI_DATA->atkAbility == ABILITY_SERENE_GRACE && AI_DATA->defAbility != ABILITY_CONTRARY) + score += 2; + break; + case EFFECT_SPEED_DOWN_HIT: + if (IsAiFaster(AI_CHECK_FASTER)) + score -= 2; + else if (!AI_RandLessThan(70)) + score++; + if (AI_DATA->atkAbility == ABILITY_SERENE_GRACE && AI_DATA->defAbility != ABILITY_CONTRARY) + score++; + break; + if (ShouldLowerSpeed(battlerAtk, battlerDef, AI_DATA->defAbility)) + { + if (AI_DATA->atkAbility == ABILITY_SERENE_GRACE && AI_DATA->defAbility != ABILITY_CONTRARY) + score += 4; + else + score += 2; + } + break; + case EFFECT_SUBSTITUTE: + if (gStatuses3[battlerDef] & STATUS3_PERISH_SONG) + score += 3; + if (gBattleMons[battlerDef].status1 & (STATUS1_BURN | STATUS1_PSN_ANY)) + score++; + if (HasMoveEffect(battlerDef, EFFECT_SLEEP) + || HasMoveEffect(battlerDef, EFFECT_TOXIC) + || HasMoveEffect(battlerDef, EFFECT_POISON) + || HasMoveEffect(battlerDef, EFFECT_PARALYZE) + || HasMoveEffect(battlerDef, EFFECT_WILL_O_WISP) + || HasMoveEffect(battlerDef, EFFECT_CONFUSE) + || HasMoveEffect(battlerDef, EFFECT_LEECH_SEED)) + score += 2; + if (!gBattleMons[battlerDef].status2 & (STATUS2_WRAPPED | STATUS2_ESCAPE_PREVENTION && GetHealthPercentage(battlerAtk) > 70)) + score++; + break; + case EFFECT_MIMIC: + if (GetWhoStrikesFirst(battlerAtk, battlerDef, TRUE) == 0) + { + if (gLastMoves[battlerDef] != MOVE_NONE && gLastMoves[battlerDef] != 0xFFFF) + return AI_CheckViability(battlerAtk, battlerDef, gLastMoves[battlerDef], score); + } + break; + case EFFECT_LEECH_SEED: + if (IS_BATTLER_OF_TYPE(battlerDef, TYPE_GRASS) + || gStatuses3[battlerDef] & STATUS3_LEECHSEED + || HasMoveEffect(battlerDef, EFFECT_RAPID_SPIN) + || AI_DATA->defAbility == ABILITY_LIQUID_OOZE + || AI_DATA->defAbility == ABILITY_MAGIC_GUARD) + break; + score += 3; + if (!HasDamagingMove(battlerDef) || IsBattlerTrapped(battlerDef, FALSE)) + score += 2; + break; + case EFFECT_DO_NOTHING: + //todo - check z splash, z celebrate, z happy hour (lol) + break; + case EFFECT_TELEPORT: + if (!(gBattleTypeFlags & BATTLE_TYPE_TRAINER) || GetBattlerSide(battlerAtk) != B_SIDE_PLAYER) + break; + //fallthrough + case EFFECT_HIT_ESCAPE: + case EFFECT_PARTING_SHOT: + if (!IsDoubleBattle()) + { + switch (ShouldPivot(battlerAtk, battlerDef, AI_DATA->defAbility, move, AI_THINKING_STRUCT->movesetIndex)) + { + case 0: // no + score -= 10; // technically should go in CheckBadMove, but this is easier/less computationally demanding + break; + case 1: // maybe + break; + case 2: // yes + score += 7; + break; + } + } + else //Double Battle + { + if (CountUsablePartyMons(battlerAtk) == 0) + break; // Can't switch + + //if (switchAbility == ABILITY_INTIMIDATE && PartyHasMoveSplit(battlerDef, SPLIT_PHYSICAL)) + //score += 7; + } + break; + case EFFECT_BATON_PASS: + if (ShouldSwitch() && (gBattleMons[battlerAtk].status2 & STATUS2_SUBSTITUTE + || (gStatuses3[battlerAtk] & (STATUS3_ROOTED | STATUS3_AQUA_RING | STATUS3_MAGNET_RISE | STATUS3_POWER_TRICK)) + || AnyStatIsRaised(battlerAtk))) + score += 5; + break; + case EFFECT_DISABLE: + if (gDisableStructs[battlerDef].disableTimer == 0 + && (B_MENTAL_HERB >= GEN_5 && AI_DATA->defHoldEffect != HOLD_EFFECT_CURE_ATTRACT)) // mental herb + { + if (GetWhoStrikesFirst(battlerAtk, battlerDef, TRUE) == 0) // AI goes first + { + if (gLastMoves[battlerDef] != MOVE_NONE + && gLastMoves[battlerDef] != 0xFFFF) + { + /* TODO predicted moves + if (gLastMoves[battlerDef] == predictedMove) + score += 3; + else */if (CanMoveFaintBattler(gLastMoves[battlerDef], battlerDef, battlerAtk, 1)) + score += 2;; //Disable move that can kill attacker + } + } + else if (predictedMove != MOVE_NONE && IS_MOVE_STATUS(predictedMove)) + { + score++; // Disable annoying status moves + } + } + break; + case EFFECT_ENCORE: + if (gDisableStructs[battlerDef].encoreTimer == 0 + && (B_MENTAL_HERB >= GEN_5 && AI_DATA->defHoldEffect != HOLD_EFFECT_CURE_ATTRACT)) // mental herb + { + if (IsEncoreEncouragedEffect(gBattleMoves[gLastMoves[battlerDef]].effect)) + score += 3; + } + break; + case EFFECT_PAIN_SPLIT: + { + u16 newHp = (gBattleMons[battlerAtk].hp + gBattleMons[battlerDef].hp) / 2; + u16 healthBenchmark = (gBattleMons[battlerAtk].hp * 12) / 10; + if (newHp > healthBenchmark && ShouldAbsorb(battlerAtk, battlerDef, move, AI_THINKING_STRUCT->simulatedDmg[battlerAtk][battlerDef][AI_THINKING_STRUCT->movesetIndex])) + score += 2; + } + break; + case EFFECT_SLEEP_TALK: + case EFFECT_SNORE: + if (!IsWakeupTurn(battlerAtk) && gBattleMons[battlerAtk].status1 & STATUS1_SLEEP) + score += 10; + break; + case EFFECT_LOCK_ON: + if (HasMoveEffect(battlerAtk, EFFECT_OHKO)) + score += 3; + else if (AI_DATA->atkAbility == ABILITY_COMPOUND_EYES && HasMoveWithLowAccuracy(battlerAtk, battlerDef, 80, TRUE, AI_DATA->atkAbility, AI_DATA->defAbility, AI_DATA->atkHoldEffect, AI_DATA->defHoldEffect)) + score += 3; + else if (HasMoveWithLowAccuracy(battlerAtk, battlerDef, 85, TRUE, AI_DATA->atkAbility, AI_DATA->defAbility, AI_DATA->atkHoldEffect, AI_DATA->defHoldEffect)) + score += 3; + else if (HasMoveWithLowAccuracy(battlerAtk, battlerDef, 90, TRUE, AI_DATA->atkAbility, AI_DATA->defAbility, AI_DATA->atkHoldEffect, AI_DATA->defHoldEffect)) + score++; + break; + case EFFECT_SPEED_UP_HIT: + if (AI_DATA->atkAbility == ABILITY_SERENE_GRACE && AI_DATA->defAbility != ABILITY_CONTRARY && IsAiFaster(AI_CHECK_SLOWER)) + score += 3; + break; + case EFFECT_DESTINY_BOND: + if (GetWhoStrikesFirst(battlerAtk, battlerDef, TRUE) == 0 && CanTargetFaintAi(battlerDef, battlerAtk)) + score += 3; + break; + case EFFECT_SPITE: + //TODO - predicted move + break; + case EFFECT_WISH: + case EFFECT_HEAL_BELL: + if (ShouldUseWishAromatherapy(battlerAtk, battlerDef, move)) + score += 7; + break; + case EFFECT_THIEF: + { + bool32 canSteal = FALSE; + + #if defined B_TRAINERS_KNOCK_OFF_ITEMS && B_TRAINERS_KNOCK_OFF_ITEMS == TRUE + canSteal = TRUE; + #endif + if (gBattleTypeFlags & BATTLE_TYPE_FRONTIER || GetBattlerSide(battlerAtk) == B_SIDE_PLAYER) + canSteal = TRUE; + + if (canSteal && AI_DATA->atkItem == ITEM_NONE + && AI_DATA->defItem != ITEM_NONE + && CanBattlerGetOrLoseItem(battlerDef, AI_DATA->defItem) + && CanBattlerGetOrLoseItem(battlerAtk, AI_DATA->defItem) + && !HasMoveEffect(battlerAtk, EFFECT_ACROBATICS) + && AI_DATA->defAbility != ABILITY_STICKY_HOLD) + { + switch (AI_DATA->defHoldEffect) + { + case HOLD_EFFECT_NONE: + break; + case HOLD_EFFECT_CHOICE_BAND: + case HOLD_EFFECT_CHOICE_SCARF: + case HOLD_EFFECT_CHOICE_SPECS: + score += 2; + break; + case HOLD_EFFECT_TOXIC_ORB: + if (ShouldPoisonSelf(battlerAtk, AI_DATA->atkAbility)) + score += 2; + break; + case HOLD_EFFECT_FLAME_ORB: + if (ShouldBurnSelf(battlerAtk, AI_DATA->atkAbility)) + score += 2; + break; + case HOLD_EFFECT_BLACK_SLUDGE: + if (IS_BATTLER_OF_TYPE(battlerAtk, TYPE_POISON)) + score += 2; + break; + case HOLD_EFFECT_IRON_BALL: + if (HasMoveEffect(battlerAtk, EFFECT_FLING)) + score += 2; + break; + case HOLD_EFFECT_LAGGING_TAIL: + case HOLD_EFFECT_STICKY_BARB: + break; + default: + score++; + break; + } + } + break; + } + break; + case EFFECT_NIGHTMARE: + if (AI_DATA->defAbility != ABILITY_MAGIC_GUARD + && !(gBattleMons[battlerDef].status2 & STATUS2_NIGHTMARE) + && (AI_DATA->defAbility == ABILITY_COMATOSE || gBattleMons[battlerDef].status1 & STATUS1_SLEEP)) + { + score += 5; + if (IsBattlerTrapped(battlerDef, TRUE)) + score += 3; + } + break; + case EFFECT_CURSE: + if (IS_BATTLER_OF_TYPE(battlerAtk, TYPE_GHOST)) + { + if (IsBattlerTrapped(battlerDef, TRUE)) + score += 3; + else + score++; + break; + } + else + { + if (AI_DATA->atkAbility == ABILITY_CONTRARY || AI_DATA->defAbility == ABILITY_MAGIC_GUARD) + break; + else if (gBattleMons[battlerAtk].statStages[STAT_ATK] < 8) + score += (8 - gBattleMons[battlerAtk].statStages[STAT_ATK]); + else if (gBattleMons[battlerAtk].statStages[STAT_SPEED] < 3) + break; + else if (gBattleMons[battlerAtk].statStages[STAT_DEF] < 8) + score += (8 - gBattleMons[battlerAtk].statStages[STAT_DEF]); + } + break; + case EFFECT_PROTECT: + if (predictedMove == 0xFFFF) + predictedMove = MOVE_NONE; + switch (move) + { + case MOVE_QUICK_GUARD: + if (predictedMove != MOVE_NONE && gBattleMoves[predictedMove].priority > 0) + ProtectChecks(battlerAtk, battlerDef, move, predictedMove, &score); + break; + case MOVE_WIDE_GUARD: + if (predictedMove != MOVE_NONE && gBattleMoves[predictedMove].target & (MOVE_TARGET_FOES_AND_ALLY | MOVE_TARGET_BOTH)) + { + ProtectChecks(battlerAtk, battlerDef, move, predictedMove, &score); + } + else if (isDoubleBattle && gBattleMoves[AI_DATA->partnerMove].target & MOVE_TARGET_FOES_AND_ALLY) + { + if (AI_DATA->atkAbility != ABILITY_TELEPATHY) + ProtectChecks(battlerAtk, battlerDef, move, predictedMove, &score); + } + break; + case MOVE_CRAFTY_SHIELD: + if (predictedMove != MOVE_NONE && IS_MOVE_STATUS(predictedMove) && !(gBattleMoves[predictedMove].target & MOVE_TARGET_USER)) + ProtectChecks(battlerAtk, battlerDef, move, predictedMove, &score); + break; + + case MOVE_MAT_BLOCK: + if (gDisableStructs[battlerAtk].isFirstTurn && predictedMove != MOVE_NONE + && !IS_MOVE_STATUS(predictedMove) && !(gBattleMoves[predictedMove].target & MOVE_TARGET_USER)) + ProtectChecks(battlerAtk, battlerDef, move, predictedMove, &score); + break; + case MOVE_KINGS_SHIELD: + #if (defined SPECIES_AEGISLASH && defined SPECIES_AEGISLASH_BLADE) + if (AI_DATA->atkAbility == ABILITY_STANCE_CHANGE //Special logic for Aegislash + && AI_DATA->atkSpecies == SPECIES_AEGISLASH_BLADE + && !IsBattlerIncapacitated(battlerDef, AI_DATA->defAbility)) + { + score += 3; + break; + } + #endif + //fallthrough + default: // protect + ProtectChecks(battlerAtk, battlerDef, move, predictedMove, &score); + break; + } + break; + case EFFECT_ENDURE: + if (CanTargetFaintAi(battlerDef, battlerAtk)) + { + if (gBattleMons[battlerAtk].hp > gBattleMons[battlerAtk].maxHP / 4 // Pinch berry couldn't have activated yet + && IsPinchBerryItemEffect(AI_DATA->atkHoldEffect)) + { + score += 3; + } + else if (gBattleMons[battlerAtk].hp > 1) // Only spam endure for Flail/Reversal if you're not at Min Health + { + if (HasMoveEffect(battlerAtk, EFFECT_FLAIL) || HasMoveEffect(battlerAtk, EFFECT_ENDEAVOR)) + score += 3; + } + } + break; + + case EFFECT_SPIKES: + case EFFECT_STEALTH_ROCK: + case EFFECT_STICKY_WEB: + case EFFECT_TOXIC_SPIKES: + if (AI_DATA->defAbility == ABILITY_MAGIC_BOUNCE || CountUsablePartyMons(battlerDef) == 0) + break; + if (gDisableStructs[battlerAtk].isFirstTurn) + score += 2; + //TODO - track entire opponent party data to determine hazard effectiveness + break; + case EFFECT_FORESIGHT: + if (AI_DATA->atkAbility == ABILITY_SCRAPPY) + break; + else if (gBattleMons[battlerDef].statStages[STAT_EVASION] > DEFAULT_STAT_STAGE + || (IS_BATTLER_OF_TYPE(battlerDef, TYPE_GHOST) + && (HasMoveWithType(battlerAtk, TYPE_NORMAL) + || HasMoveWithType(battlerAtk, TYPE_FIGHTING)))) + score += 2; + break; + case EFFECT_MIRACLE_EYE: + if (gBattleMons[battlerDef].statStages[STAT_EVASION] > DEFAULT_STAT_STAGE + || (IS_BATTLER_OF_TYPE(battlerDef, TYPE_DARK) && (HasMoveWithType(battlerAtk, TYPE_PSYCHIC)))) + score += 2; + break; + case EFFECT_PERISH_SONG: + if (IsBattlerTrapped(battlerDef, TRUE)) + score += 3; + break; + case EFFECT_SANDSTORM: + if (ShouldSetSandstorm(battlerAtk, AI_DATA->atkHoldEffect, AI_DATA->atkHoldEffect)) + { + score++; + if (AI_DATA->atkHoldEffect == HOLD_EFFECT_SMOOTH_ROCK) + score++; + if (HasMoveEffect(battlerDef, EFFECT_MORNING_SUN) + || HasMoveEffect(battlerDef, EFFECT_SYNTHESIS) + || HasMoveEffect(battlerDef, EFFECT_MOONLIGHT)) + score += 2; + } + break; + case EFFECT_HAIL: + if (ShouldSetHail(battlerAtk, AI_DATA->atkAbility, AI_DATA->atkHoldEffect)) + { + if ((HasMoveEffect(battlerAtk, EFFECT_AURORA_VEIL) || HasMoveEffect(AI_DATA->battlerAtkPartner, EFFECT_AURORA_VEIL)) + && ShouldSetScreen(battlerAtk, battlerDef, EFFECT_AURORA_VEIL)) + score += 3; + + score++; + if (AI_DATA->atkHoldEffect == HOLD_EFFECT_ICY_ROCK) + score++; + if (HasMoveEffect(battlerDef, EFFECT_MORNING_SUN) + || HasMoveEffect(battlerDef, EFFECT_SYNTHESIS) + || HasMoveEffect(battlerDef, EFFECT_MOONLIGHT)) + score += 2; + } + break; + case EFFECT_RAIN_DANCE: + if (ShouldSetRain(battlerAtk, AI_DATA->atkAbility, AI_DATA->atkHoldEffect)) + { + score++; + if (AI_DATA->atkHoldEffect == HOLD_EFFECT_DAMP_ROCK) + score++; + if (HasMoveEffect(battlerDef, EFFECT_MORNING_SUN) + || HasMoveEffect(battlerDef, EFFECT_SYNTHESIS) + || HasMoveEffect(battlerDef, EFFECT_MOONLIGHT)) + score += 2; + if (HasMoveWithType(battlerDef, TYPE_FIRE) || HasMoveWithType(AI_DATA->battlerDefPartner, TYPE_FIRE)) + score++; + } + break; + case EFFECT_SUNNY_DAY: + if (ShouldSetSun(battlerAtk, AI_DATA->atkAbility, AI_DATA->atkHoldEffect)) + { + score++; + if (AI_DATA->atkHoldEffect == HOLD_EFFECT_HEAT_ROCK) + score++; + if (HasMoveWithType(battlerDef, TYPE_WATER) || HasMoveWithType(AI_DATA->battlerDefPartner, TYPE_WATER)) + score++; + if (HasMoveEffect(battlerDef, EFFECT_THUNDER) || HasMoveEffect(AI_DATA->battlerDefPartner, EFFECT_THUNDER)) + score++; + } + break; + case EFFECT_ATTACK_UP_HIT: + if (AI_DATA->atkAbility == ABILITY_SERENE_GRACE) + IncreaseStatUpScore(battlerAtk, battlerDef, STAT_ATK, &score); + break; + case EFFECT_FELL_STINGER: + if (gBattleMons[battlerAtk].statStages[STAT_ATK] < MAX_STAT_STAGE + && AI_DATA->atkAbility != ABILITY_CONTRARY + && CanAttackerFaintTarget(battlerAtk, battlerDef, AI_THINKING_STRUCT->movesetIndex, 0)) + { + if (GetWhoStrikesFirst(battlerAtk, battlerDef, TRUE) == 0) // Attacker goes first + score += 9; + else + score += 3; + } + break; + case EFFECT_BELLY_DRUM: + if (!CanTargetFaintAi(battlerDef, battlerAtk) && HasMoveWithSplit(battlerAtk, SPLIT_PHYSICAL) && AI_DATA->atkAbility != ABILITY_CONTRARY) + score += (MAX_STAT_STAGE - gBattleMons[battlerAtk].statStages[STAT_ATK]); + break; + case EFFECT_PSYCH_UP: + case EFFECT_SPECTRAL_THIEF: + // Want to copy positive stat changes + for (i = STAT_ATK; i < NUM_BATTLE_STATS; i++) + { + if (gBattleMons[battlerDef].statStages[i] > gBattleMons[battlerAtk].statStages[i]) + { + switch (i) + { + case STAT_ATK: + if (HasMoveWithSplit(battlerAtk, SPLIT_PHYSICAL)) + score++; + break; + case STAT_SPATK: + if (HasMoveWithSplit(battlerAtk, SPLIT_SPECIAL)) + score++; + break; + case STAT_ACC: + case STAT_EVASION: + case STAT_SPEED: + score++; + break; + case STAT_DEF: + case STAT_SPDEF: + if (AI_THINKING_STRUCT->aiFlags & AI_FLAG_STALL) + score++; + break; + } + } + } + break; + case EFFECT_SEMI_INVULNERABLE: + score++; + if (predictedMove != MOVE_NONE && !isDoubleBattle) + { + if (GetWhoStrikesFirst(battlerAtk, battlerDef, TRUE) == 0) // Attacker goes first + { + if (gBattleMoves[predictedMove].effect == EFFECT_EXPLOSION + || gBattleMoves[predictedMove].effect == EFFECT_PROTECT) + score += 3; + } + else if (gBattleMoves[predictedMove].effect == EFFECT_SEMI_INVULNERABLE && !(gStatuses3[battlerDef] & STATUS3_SEMI_INVULNERABLE)) + { + score += 3; + } + } + break; + case EFFECT_DEFENSE_CURL: + if (HasMoveEffect(battlerAtk, EFFECT_ROLLOUT) && !(gBattleMons[battlerAtk].status2 & STATUS2_DEFENSE_CURL)) + score++; + IncreaseStatUpScore(battlerAtk, battlerDef, STAT_DEF, &score); + break; + case EFFECT_FAKE_OUT: + if (move == MOVE_FAKE_OUT // filter out first impression + && ShouldFakeOut(battlerAtk, battlerDef, move)) + score += 8; + break; + case EFFECT_STOCKPILE: + if (AI_DATA->atkAbility == ABILITY_CONTRARY) + break; + if (HasMoveEffect(battlerAtk, EFFECT_SWALLOW) + || HasMoveEffect(battlerAtk, EFFECT_SPIT_UP)) + score += 2; + + IncreaseStatUpScore(battlerAtk, battlerDef, STAT_DEF, &score); + IncreaseStatUpScore(battlerAtk, battlerDef, STAT_SPDEF, &score); + break; + case EFFECT_SPIT_UP: + if (gDisableStructs[battlerAtk].stockpileCounter >= 2) + score++; + break; + case EFFECT_ROLLOUT: + if (gBattleMons[battlerAtk].status2 & STATUS2_DEFENSE_CURL) + score += 8; + break; + case EFFECT_SWAGGER: + if (HasMoveEffect(battlerAtk, EFFECT_FOUL_PLAY) + || HasMoveEffect(battlerAtk, EFFECT_PSYCH_UP) + || HasMoveEffect(battlerAtk, EFFECT_SPECTRAL_THIEF)) + score++; + + if (AI_DATA->defAbility == ABILITY_CONTRARY) + score += 2; + + IncreaseConfusionScore(battlerAtk, battlerDef, move, &score); + break; + case EFFECT_FLATTER: + if (HasMoveEffect(battlerAtk, EFFECT_PSYCH_UP) + || HasMoveEffect(battlerAtk, EFFECT_SPECTRAL_THIEF)) + score += 2; + + if (AI_DATA->defAbility == ABILITY_CONTRARY) + score += 2; + + IncreaseConfusionScore(battlerAtk, battlerDef, move, &score); + break; + case EFFECT_FURY_CUTTER: + if (!isDoubleBattle && AI_DATA->atkHoldEffect == HOLD_EFFECT_METRONOME) + score += 3; + break; + case EFFECT_ATTRACT: + if (!isDoubleBattle && BattlerWillFaintFromSecondaryDamage(battlerDef, AI_DATA->defAbility) + && GetWhoStrikesFirst(battlerAtk, battlerDef, TRUE) == 1) // Target goes first + break; // Don't use if the attract won't have a change to activate + + if (gBattleMons[battlerDef].status1 & STATUS1_ANY + || (gBattleMons[battlerDef].status2 & STATUS2_CONFUSION) + || IsBattlerTrapped(battlerDef, TRUE)) + score += 2; + else + score++; + break; + case EFFECT_SAFEGUARD: + if (!(gFieldStatuses & STATUS_FIELD_MISTY_TERRAIN) || !IsBattlerGrounded(battlerAtk)) + score++; + //if (CountUsablePartyMons(battlerDef) != 0) + //score += 8; + break; + case EFFECT_PURSUIT: + /*TODO + if (IsPredictedToSwitch(battlerDef, battlerAtk)) + score += 3; + else if (IsPredictedToUsePursuitableMove(battlerDef, battlerAtk) && !MoveWouldHitFirst(move, battlerAtk, battlerDef)) //Pursuit against fast U-Turn + score += 3;*/ + break; + case EFFECT_RAPID_SPIN: + IncreaseStatUpScore(battlerAtk, battlerDef, STAT_SPEED, &score); // Gen 8 increases speed + //fallthrough + case EFFECT_DEFOG: + if (gSideStatuses[GetBattlerSide(battlerAtk)] & SIDE_STATUS_HAZARDS_ANY && CountUsablePartyMons(battlerAtk) != 0) + { + score += 3; + break; + } + + switch (move) + { + case MOVE_DEFOG: + if (gSideStatuses[GetBattlerSide(battlerDef)] & (SIDE_STATUS_SCREEN_ANY | SIDE_STATUS_SAFEGUARD | SIDE_STATUS_MIST)) + { + score += 3; + } + else if (!(gSideStatuses[GetBattlerSide(battlerDef)] & SIDE_STATUS_SPIKES)) //Don't blow away hazards if you set them up + { + if (isDoubleBattle) + { + if (IsHazardMoveEffect(gBattleMoves[AI_DATA->partnerMove].effect) // Partner is going to set up hazards + && GetWhoStrikesFirst(battlerAtk, AI_DATA->battlerAtkPartner, TRUE) == 1) // Partner going first + break; // Don't use Defog if partner is going to set up hazards + } + + // check defog lowering evasion + if (ShouldLowerEvasion(battlerAtk, battlerDef, AI_DATA->defAbility)) + { + if (gBattleMons[battlerDef].statStages[STAT_EVASION] > 7 + || HasMoveWithLowAccuracy(battlerAtk, battlerDef, 90, TRUE, AI_DATA->atkAbility, AI_DATA->defAbility, AI_DATA->atkHoldEffect, AI_DATA->defHoldEffect)) + score += 2; // encourage lowering evasion if they are evasive or we have a move with low accuracy + else + score++; + } + } + break; + case MOVE_RAPID_SPIN: + if (gStatuses3[battlerAtk] & STATUS3_LEECHSEED || gBattleMons[battlerAtk].status2 & STATUS2_WRAPPED) + score += 3; + break; + } + break; + case EFFECT_TORMENT: + break; + case EFFECT_WILL_O_WISP: + IncreaseBurnScore(battlerAtk, battlerDef, move, &score); + break; + case EFFECT_FOLLOW_ME: + if (isDoubleBattle + && move != MOVE_SPOTLIGHT + && !IsBattlerIncapacitated(battlerDef, AI_DATA->defAbility) + && (move != MOVE_RAGE_POWDER || IsAffectedByPowder(battlerDef, AI_DATA->defAbility, AI_DATA->defHoldEffect)) // Rage Powder doesn't affect powder immunities + && IsBattlerAlive(AI_DATA->battlerAtkPartner)) + { + u16 predictedMoveOnPartner = gLastMoves[AI_DATA->battlerAtkPartner]; + if (predictedMoveOnPartner != MOVE_NONE && !IS_MOVE_STATUS(predictedMoveOnPartner)) + score += 3; + } + break; + case EFFECT_NATURE_POWER: + return AI_CheckViability(battlerAtk, battlerDef, GetNaturePowerMove(), score); + case EFFECT_CHARGE: + if (HasDamagingMoveOfType(battlerAtk, TYPE_ELECTRIC)) + score += 2; + + IncreaseStatUpScore(battlerAtk, battlerDef, STAT_SPDEF, &score); + break; + case EFFECT_TAUNT: + if (IS_MOVE_STATUS(predictedMove)) + score += 3; + else if (HasMoveWithSplit(battlerDef, SPLIT_STATUS)) + score += 2; + break; + case EFFECT_TRICK: + case EFFECT_BESTOW: + switch (AI_DATA->atkHoldEffect) + { + case HOLD_EFFECT_CHOICE_SCARF: + score += 2; // assume its beneficial + break; + case HOLD_EFFECT_CHOICE_BAND: + if (!HasMoveWithSplit(battlerDef, SPLIT_PHYSICAL)) + score += 2; + break; + case HOLD_EFFECT_CHOICE_SPECS: + if (!HasMoveWithSplit(battlerDef, SPLIT_SPECIAL)) + score += 2; + break; + case HOLD_EFFECT_TOXIC_ORB: + if (!ShouldPoisonSelf(battlerAtk, AI_DATA->atkAbility) && CanBePoisoned(battlerDef, AI_DATA->defAbility)) + score += 2; + break; + case HOLD_EFFECT_FLAME_ORB: + if (!ShouldBurnSelf(battlerAtk, AI_DATA->atkAbility) && CanBeBurned(battlerAtk, AI_DATA->defAbility)) + score += 2; + break; + case HOLD_EFFECT_BLACK_SLUDGE: + if (!IS_BATTLER_OF_TYPE(battlerDef, TYPE_POISON) && AI_DATA->defAbility != ABILITY_MAGIC_GUARD) + score += 3; + break; + case HOLD_EFFECT_IRON_BALL: + if (!HasMoveEffect(battlerDef, EFFECT_FLING) || !IsBattlerGrounded(battlerDef)) + score += 2; + break; + case HOLD_EFFECT_LAGGING_TAIL: + case HOLD_EFFECT_STICKY_BARB: + score += 3; + break; + case HOLD_EFFECT_UTILITY_UMBRELLA: + if (AI_DATA->atkAbility != ABILITY_SOLAR_POWER && AI_DATA->atkAbility != ABILITY_DRY_SKIN && AI_WeatherHasEffect()) + { + switch (AI_DATA->defAbility) + { + case ABILITY_SWIFT_SWIM: + if (gBattleWeather & WEATHER_RAIN_ANY) + score += 3; // Slow 'em down + break; + case ABILITY_CHLOROPHYLL: + case ABILITY_FLOWER_GIFT: + if (gBattleWeather & WEATHER_SUN_ANY) + score += 3; // Slow 'em down + break; + } + } + break; + case HOLD_EFFECT_EJECT_BUTTON: + //if (!IsRaidBattle() && IsDynamaxed(battlerDef) && gNewBS->dynamaxData.timer[battlerDef] > 1 && + if (HasDamagingMove(battlerAtk) + || (isDoubleBattle && IsBattlerAlive(AI_DATA->battlerAtkPartner) && HasDamagingMove(AI_DATA->battlerAtkPartner))) + score += 2; // Force 'em out next turn + break; + default: + if (move != MOVE_BESTOW && AI_DATA->atkItem == ITEM_NONE) + { + switch (AI_DATA->defHoldEffect) + { + case HOLD_EFFECT_CHOICE_BAND: + break; + case HOLD_EFFECT_TOXIC_ORB: + if (ShouldPoisonSelf(battlerAtk, AI_DATA->atkAbility)) + score += 2; + break; + case HOLD_EFFECT_FLAME_ORB: + if (ShouldBurnSelf(battlerAtk, AI_DATA->atkAbility)) + score += 2; + break; + case HOLD_EFFECT_BLACK_SLUDGE: + if (IS_BATTLER_OF_TYPE(battlerAtk, TYPE_POISON) || AI_DATA->atkAbility == ABILITY_MAGIC_GUARD) + score += 3; + break; + case HOLD_EFFECT_IRON_BALL: + if (HasMoveEffect(battlerAtk, EFFECT_FLING)) + score += 2; + break; + case HOLD_EFFECT_LAGGING_TAIL: + case HOLD_EFFECT_STICKY_BARB: + break; + default: + score++; //other hold effects generally universally good + break; + } + } + } + break; + case EFFECT_ROLE_PLAY: + if (!IsRolePlayBannedAbilityAtk(AI_DATA->atkAbility) + && !IsRolePlayBannedAbility(AI_DATA->defAbility) + && !IsAbilityOfRating(AI_DATA->atkAbility, 5) + && IsAbilityOfRating(AI_DATA->defAbility, 5)) + score += 2; + break; + case EFFECT_INGRAIN: + if (AI_DATA->atkHoldEffect == HOLD_EFFECT_BIG_ROOT) + score += 3; + else + score++; + break; + case EFFECT_SUPERPOWER: + case EFFECT_OVERHEAT: + if (AI_DATA->atkAbility == ABILITY_CONTRARY) + score += 10; + break; + case EFFECT_MAGIC_COAT: + if (IS_MOVE_STATUS(predictedMove) && gBattleMoves[predictedMove].target & (MOVE_TARGET_SELECTED | MOVE_TARGET_OPPONENTS_FIELD | MOVE_TARGET_BOTH)) + score += 3; + break; + case EFFECT_RECYCLE: + if (gBattleStruct->usedHeldItems[battlerAtk] != ITEM_NONE) + score++; + if (IsRecycleEncouragedItem(gBattleStruct->usedHeldItems[battlerAtk])) + score++; + break; + case EFFECT_BRICK_BREAK: + if (gSideStatuses[GetBattlerSide(battlerDef)] & SIDE_STATUS_REFLECT) + score++; + if (gSideStatuses[GetBattlerSide(battlerDef)] & SIDE_STATUS_LIGHTSCREEN) + score++; + if (gSideStatuses[GetBattlerSide(battlerDef)] & SIDE_STATUS_AURORA_VEIL) + score++; + break; + case EFFECT_KNOCK_OFF: + if (CanKnockOffItem(battlerDef, AI_DATA->defItem)) + { + switch (AI_DATA->defHoldEffect) + { + case HOLD_EFFECT_IRON_BALL: + if (HasMoveEffect(battlerDef, EFFECT_FLING)) + score += 4; + break; + case HOLD_EFFECT_LAGGING_TAIL: + case HOLD_EFFECT_STICKY_BARB: + break; + default: + score += 3; + break; + } + } + break; + case EFFECT_SKILL_SWAP: + if (GetAbilityRating(AI_DATA->defAbility) > GetAbilityRating(AI_DATA->atkAbility)) + score++; + break; + case EFFECT_WORRY_SEED: + case EFFECT_GASTRO_ACID: + case EFFECT_SIMPLE_BEAM: + if (IsAbilityOfRating(AI_DATA->defAbility, 5)) + score += 2; + break; + case EFFECT_ENTRAINMENT: + if (IsAbilityOfRating(AI_DATA->defAbility, 5) || GetAbilityRating(AI_DATA->atkAbility) <= 0) + { + if (AI_DATA->defAbility != AI_DATA->atkAbility && !(gStatuses3[battlerDef] & STATUS3_GASTRO_ACID)) + score += 2; + } + break; + case EFFECT_IMPRISON: + if (predictedMove != MOVE_NONE && HasMove(battlerAtk, predictedMove)) + score += 3; + else if (gDisableStructs[battlerAtk].isFirstTurn == 0) + score++; + break; + case EFFECT_REFRESH: + if (gBattleMons[battlerAtk].status1 & STATUS1_ANY) + score += 2; + break; + case EFFECT_PSYCHO_SHIFT: + if (gBattleMons[battlerAtk].status1 & STATUS1_PSN_ANY) + IncreasePoisonScore(battlerAtk, battlerDef, move, &score); + else if (gBattleMons[battlerAtk].status1 & STATUS1_BURN) + IncreaseBurnScore(battlerAtk, battlerDef, move, &score); + else if (gBattleMons[battlerAtk].status1 & STATUS1_PARALYSIS) + IncreaseParalyzeScore(battlerAtk, battlerDef, move, &score); + else if (gBattleMons[battlerAtk].status1 & STATUS1_SLEEP) + IncreaseSleepScore(battlerAtk, battlerDef, move, &score); + break; + case EFFECT_GRUDGE: + break; + case EFFECT_SNATCH: + if (predictedMove != MOVE_NONE && TestMoveFlags(predictedMove, FLAG_SNATCH_AFFECTED)) + score += 3; // Steal move + break; + case EFFECT_MUD_SPORT: + if (!HasMoveWithType(battlerAtk, TYPE_ELECTRIC) && HasMoveWithType(battlerDef, TYPE_ELECTRIC)) + score++; + break; + case EFFECT_WATER_SPORT: + if (!HasMoveWithType(battlerAtk, TYPE_FIRE) && (HasMoveWithType(battlerDef, TYPE_FIRE))) + score++; + break; + case EFFECT_TICKLE: + if (gBattleMons[battlerDef].statStages[STAT_DEF] > 4 && HasMoveWithSplit(battlerAtk, SPLIT_PHYSICAL) + && AI_DATA->defAbility != ABILITY_CONTRARY && ShouldLowerDefense(battlerAtk, battlerDef, AI_DATA->defAbility)) + { + score += 2; + } + else if (ShouldLowerAttack(battlerAtk, battlerDef, AI_DATA->defAbility)) + { + score += 2; + } + break; + case EFFECT_COSMIC_POWER: + IncreaseStatUpScore(battlerAtk, battlerDef, STAT_DEF, &score); + IncreaseStatUpScore(battlerAtk, battlerDef, STAT_SPDEF, &score); + break; + case EFFECT_BULK_UP: + IncreaseStatUpScore(battlerAtk, battlerDef, STAT_ATK, &score); + IncreaseStatUpScore(battlerAtk, battlerDef, STAT_DEF, &score); + break; + case EFFECT_CALM_MIND: + IncreaseStatUpScore(battlerAtk, battlerDef, STAT_SPATK, &score); + IncreaseStatUpScore(battlerAtk, battlerDef, STAT_SPDEF, &score); + break; + case EFFECT_GEOMANCY: + if (AI_DATA->atkHoldEffect == HOLD_EFFECT_POWER_HERB) + score += 3; + //fallthrough + case EFFECT_QUIVER_DANCE: + IncreaseStatUpScore(battlerAtk, battlerDef, STAT_SPEED, &score); + IncreaseStatUpScore(battlerAtk, battlerDef, STAT_SPATK, &score); + IncreaseStatUpScore(battlerAtk, battlerDef, STAT_SPDEF, &score); + break; + case EFFECT_SHELL_SMASH: + if (AI_DATA->atkHoldEffect == HOLD_EFFECT_POWER_HERB) + score += 3; + + IncreaseStatUpScore(battlerAtk, battlerDef, STAT_SPEED, &score); + IncreaseStatUpScore(battlerAtk, battlerDef, STAT_SPATK, &score); + IncreaseStatUpScore(battlerAtk, battlerDef, STAT_ATK, &score); + break; + case EFFECT_DRAGON_DANCE: + case EFFECT_SHIFT_GEAR: + IncreaseStatUpScore(battlerAtk, battlerDef, STAT_SPEED, &score); + IncreaseStatUpScore(battlerAtk, battlerDef, STAT_ATK, &score); + break; + case EFFECT_GUARD_SWAP: + if (gBattleMons[battlerDef].statStages[STAT_DEF] > gBattleMons[battlerAtk].statStages[STAT_DEF] + && gBattleMons[battlerDef].statStages[STAT_SPDEF] >= gBattleMons[battlerAtk].statStages[STAT_SPDEF]) + score++; + else if (gBattleMons[battlerDef].statStages[STAT_SPDEF] > gBattleMons[battlerAtk].statStages[STAT_SPDEF] + && gBattleMons[battlerDef].statStages[STAT_DEF] >= gBattleMons[battlerAtk].statStages[STAT_DEF]) + score++; + break; + case EFFECT_POWER_SWAP: + if (gBattleMons[battlerDef].statStages[STAT_ATK] > gBattleMons[battlerAtk].statStages[STAT_ATK] + && gBattleMons[battlerDef].statStages[STAT_SPATK] >= gBattleMons[battlerAtk].statStages[STAT_SPATK]) + score++; + else if (gBattleMons[battlerDef].statStages[STAT_SPATK] > gBattleMons[battlerAtk].statStages[STAT_SPATK] + && gBattleMons[battlerDef].statStages[STAT_ATK] >= gBattleMons[battlerAtk].statStages[STAT_ATK]) + score++; + break; + case EFFECT_POWER_TRICK: + if (!(gStatuses3[battlerAtk] & STATUS3_POWER_TRICK)) + { + if (gBattleMons[battlerAtk].defense > gBattleMons[battlerAtk].attack && HasMoveWithSplit(battlerAtk, SPLIT_PHYSICAL)) + score += 2; + break; + } + break; + case EFFECT_HEART_SWAP: + { + bool32 hasHigherStat = FALSE; + //Only use if all target stats are >= attacker stats to prevent infinite loop + for (i = STAT_ATK; i < NUM_BATTLE_STATS; i++) + { + if (gBattleMons[battlerDef].statStages[i] < gBattleMons[battlerAtk].statStages[i]) + break; + if (gBattleMons[battlerDef].statStages[i] > gBattleMons[battlerAtk].statStages[i]) + hasHigherStat = TRUE; + } + if (hasHigherStat && i == NUM_BATTLE_STATS) + score++; + } + break; + case EFFECT_SPEED_SWAP: + // TODO this is cheating a bit... + if (gBattleMons[battlerDef].speed > gBattleMons[battlerAtk].speed) + score += 3; + break; + case EFFECT_GUARD_SPLIT: + { + // TODO also kind of cheating... + u16 newDefense = (gBattleMons[battlerAtk].defense + gBattleMons[battlerDef].defense) / 2; + u16 newSpDef = (gBattleMons[battlerAtk].spDefense + gBattleMons[battlerDef].spDefense) / 2; + + if ((newDefense > gBattleMons[battlerAtk].defense && newSpDef >= gBattleMons[battlerAtk].spDefense) + || (newSpDef > gBattleMons[battlerAtk].spDefense && newDefense >= gBattleMons[battlerAtk].defense)) + score++; + } + break; + case EFFECT_POWER_SPLIT: + { + u16 newAttack = (gBattleMons[battlerAtk].attack + gBattleMons[battlerDef].attack) / 2; + u16 newSpAtk = (gBattleMons[battlerAtk].spAttack + gBattleMons[battlerDef].spAttack) / 2; + + if ((newAttack > gBattleMons[battlerAtk].attack && newSpAtk >= gBattleMons[battlerAtk].spAttack) + || (newSpAtk > gBattleMons[battlerAtk].spAttack && newAttack >= gBattleMons[battlerAtk].attack)) + score++; + } + break; + case EFFECT_BUG_BITE: // And pluck + if (gBattleMons[battlerDef].status2 & STATUS2_SUBSTITUTE || AI_DATA->defAbility == ABILITY_STICKY_HOLD) + break; + else if (ItemId_GetPocket(AI_DATA->defItem) == POCKET_BERRIES) + score += 3; + break; + case EFFECT_INCINERATE: + if (gBattleMons[battlerDef].status2 & STATUS2_SUBSTITUTE || AI_DATA->defAbility == ABILITY_STICKY_HOLD) + break; + else if (ItemId_GetPocket(AI_DATA->defItem) == POCKET_BERRIES || AI_DATA->defHoldEffect == HOLD_EFFECT_GEMS) + score += 3; + break; + case EFFECT_SMACK_DOWN: + if (!IsBattlerGrounded(battlerDef)) + score += 3; + break; + case EFFECT_SLEEP_HIT: // Relic Song + #if (defined SPECIES_MELOETTA && defined SPECIES_MELOETTA_PIROUETTE) + if (AI_DATA->atkSpecies == SPECIES_MELOETTA && gBattleMons[battlerDef].defense < gBattleMons[battlerDef].spDefense) + score += 3; // Change to pirouette if can do more damage + else if (AI_DATA->atkSpecies == SPECIES_MELOETTA_PIROUETTE && gBattleMons[battlerDef].spDefense < gBattleMons[battlerDef].defense) + score += 3; // Change to Aria if can do more damage + #endif + break; + case EFFECT_ELECTRIC_TERRAIN: + case EFFECT_MISTY_TERRAIN: + if (gStatuses3[battlerAtk] & STATUS3_YAWN && IsBattlerGrounded(battlerAtk)) + score += 10; + //fallthrough + case EFFECT_GRASSY_TERRAIN: + case EFFECT_PSYCHIC_TERRAIN: + score += 2; + if (AI_DATA->atkHoldEffect == HOLD_EFFECT_TERRAIN_EXTENDER) + score += 2; + break; + case EFFECT_PLEDGE: + if (isDoubleBattle) + { + if (HasMoveEffect(AI_DATA->battlerAtkPartner, EFFECT_PLEDGE)) + score += 3; // Partner might use pledge move + } + break; + case EFFECT_TRICK_ROOM: + if (!(gFieldStatuses & STATUS_FIELD_TRICK_ROOM) && GetBattlerSideSpeedAverage(battlerAtk) < GetBattlerSideSpeedAverage(battlerDef)) + score += 3; + else if ((gFieldStatuses & STATUS_FIELD_TRICK_ROOM) && GetBattlerSideSpeedAverage(battlerAtk) >= GetBattlerSideSpeedAverage(battlerDef)) + score += 3; + break; + case EFFECT_MAGIC_ROOM: + score++; + if (AI_DATA->atkHoldEffect == HOLD_EFFECT_NONE && AI_DATA->defHoldEffect != HOLD_EFFECT_NONE) + score++; + if (isDoubleBattle && AI_DATA->atkPartnerHoldEffect == HOLD_EFFECT_NONE && AI_DATA->defPartnerHoldEffect != HOLD_EFFECT_NONE) + score++; + break; + case EFFECT_WONDER_ROOM: + if ((HasMoveWithSplit(battlerDef, SPLIT_PHYSICAL) && gBattleMons[battlerAtk].defense < gBattleMons[battlerAtk].spDefense) + || (HasMoveWithSplit(battlerDef, SPLIT_SPECIAL) && gBattleMons[battlerAtk].spDefense < gBattleMons[battlerAtk].defense)) + score += 2; + break; + case EFFECT_GRAVITY: + if (!(gFieldStatuses & STATUS_FIELD_GRAVITY)) + { + if (HasSleepMoveWithLowAccuracy(battlerAtk, battlerDef)) // Has Gravity for a move like Hypnosis + IncreaseSleepScore(battlerAtk, battlerDef, move, &score); + else if (HasMoveWithLowAccuracy(battlerAtk, battlerDef, 90, FALSE, AI_DATA->atkAbility, AI_DATA->defAbility, AI_DATA->atkHoldEffect, AI_DATA->defHoldEffect)) + score += 2; + else + score++; + } + break; + case EFFECT_ION_DELUGE: + if ((AI_DATA->atkAbility == ABILITY_VOLT_ABSORB + || AI_DATA->atkAbility == ABILITY_MOTOR_DRIVE + || AI_DATA->atkAbility == ABILITY_LIGHTNING_ROD) + && gBattleMoves[predictedMove].type == TYPE_NORMAL) + score += 2; + break; + case EFFECT_FLING: + /* TODO + switch (gFlingTable[AI_DATA->atkItem].effect) + { + case MOVE_EFFECT_BURN: + IncreaseBurnScore(battlerAtk, battlerDef, move, &score); + break; + case MOVE_EFFECT_FLINCH: + score += ShouldTryToFlinch(battlerAtk, battlerDef, AI_DATA->atkAbility, AI_DATA->defAbility, move); + break; + case MOVE_EFFECT_PARALYSIS: + IncreaseParalyzeScore(battlerAtk, battlerDef, move, &score); + break; + case MOVE_EFFECT_POISON: + case MOVE_EFFECT_TOXIC: + IncreasePoisonScore(battlerAtk, battlerDef, move, &score); + break; + case MOVE_EFFECT_FREEZE: + if (AI_CanFreeze(battlerAtk, battlerDef)) + score += 3; + break; + }*/ + break; + case EFFECT_FEINT: + if (gBattleMoves[predictedMove].effect == EFFECT_PROTECT) + score += 3; + break; + case EFFECT_EMBARGO: + if (AI_DATA->defHoldEffect != HOLD_EFFECT_NONE) + score++; + break; + case EFFECT_POWDER: + if (predictedMove != MOVE_NONE && !IS_MOVE_STATUS(predictedMove) && gBattleMoves[predictedMove].type == TYPE_FIRE) + score += 3; + break; + case EFFECT_TELEKINESIS: + if (HasMoveWithLowAccuracy(battlerAtk, battlerDef, 90, FALSE, AI_DATA->atkAbility, AI_DATA->defAbility, AI_DATA->atkHoldEffect, AI_DATA->defHoldEffect) + || !IsBattlerGrounded(battlerDef)) + score++; + break; + case EFFECT_THROAT_CHOP: + if (predictedMove != MOVE_NONE && TestMoveFlags(predictedMove, FLAG_SOUND) && GetWhoStrikesFirst(battlerAtk, battlerDef, TRUE) == 0) + score += 3; // Ai goes first and predicts the target will use a sound move + else if (TestMoveFlagsInMoveset(battlerDef, FLAG_SOUND)) + score += 3; + break; + case EFFECT_HEAL_BLOCK: + if (GetWhoStrikesFirst(battlerAtk, battlerDef, TRUE) == 0 && predictedMove != MOVE_NONE && IsHealingMoveEffect(gBattleMoves[predictedMove].effect)) + score += 3; // Try to cancel healing move + else if (HasHealingEffect(battlerDef) || AI_DATA->defHoldEffect == HOLD_EFFECT_LEFTOVERS + || (AI_DATA->defHoldEffect == HOLD_EFFECT_BLACK_SLUDGE && IS_BATTLER_OF_TYPE(battlerDef, TYPE_POISON))) + score += 2; + break; + case EFFECT_SOAK: + if (HasMoveWithType(battlerAtk, TYPE_ELECTRIC) || HasMoveWithType(battlerAtk, TYPE_GRASS) || HasMoveEffect(battlerAtk, EFFECT_FREEZE_DRY)) + score += 2; // Get some super effective moves + break; + case EFFECT_THIRD_TYPE: + if (AI_DATA->defAbility == ABILITY_WONDER_GUARD) + score += 2; // Give target more weaknesses + break; + case EFFECT_ELECTRIFY: + if (predictedMove != MOVE_NONE && gBattleMoves[predictedMove].type == TYPE_NORMAL + && (AI_DATA->atkAbility == ABILITY_VOLT_ABSORB + || AI_DATA->atkAbility == ABILITY_MOTOR_DRIVE + || AI_DATA->atkAbility == ABILITY_LIGHTNING_ROD)) + { + score += 3; + } + break; + case EFFECT_TOPSY_TURVY: + if (CountPositiveStatStages(battlerDef) > CountNegativeStatStages(battlerDef)) + score++; + break; + case EFFECT_FAIRY_LOCK: + if (!IsBattlerTrapped(battlerDef, TRUE)) + { + if (ShouldTrap(battlerAtk, battlerDef, move)) + score += 8; + } + break; + case EFFECT_QUASH: + if (isDoubleBattle + && GetWhoStrikesFirst(AI_DATA->battlerAtkPartner, battlerDef, TRUE) == 1) // Attacker partner wouldn't go before target + score++; + break; + case EFFECT_TAILWIND: + if (GetBattlerSideSpeedAverage(battlerAtk) < GetBattlerSideSpeedAverage(battlerDef)) + score += 2; + break; + case EFFECT_LUCKY_CHANT: + if (!isDoubleBattle) + { + score++; + } + else + { + if (CountUsablePartyMons(battlerDef) > 0) + score += 8; + } + break; + case EFFECT_MAGNET_RISE: + if (IsBattlerGrounded(battlerAtk) && HasDamagingMoveOfType(battlerDef, TYPE_ELECTRIC) + && !(AI_GetTypeEffectiveness(MOVE_EARTHQUAKE, battlerDef, battlerAtk) == AI_EFFECTIVENESS_x0)) // Doesn't resist ground move + { + if (GetWhoStrikesFirst(battlerAtk, battlerDef, TRUE) == 0) // Attacker goes first + { + if (gBattleMoves[predictedMove].type == TYPE_GROUND) + score += 3; // Cause the enemy's move to fail + break; + } + else // Opponent Goes First + { + if (HasDamagingMoveOfType(battlerDef, TYPE_GROUND)) + score += 2; + break; + } + } + break; + case EFFECT_CAMOUFLAGE: + if (predictedMove != MOVE_NONE && GetWhoStrikesFirst(battlerAtk, battlerDef, TRUE) == 0 // Attacker goes first + && !IS_MOVE_STATUS(move) && AI_GetTypeEffectiveness(predictedMove, battlerDef, battlerAtk) != AI_EFFECTIVENESS_x0) + score++; + break; + case EFFECT_FLAME_BURST: + if (isDoubleBattle) + { + if (IsBattlerAlive(AI_DATA->battlerDefPartner) + && GetHealthPercentage(AI_DATA->battlerDefPartner) < 12 + && AI_DATA->defPartnerAbility != ABILITY_MAGIC_GUARD + && !IS_BATTLER_OF_TYPE(AI_DATA->battlerDefPartner, TYPE_FIRE)) + score++; + } + break; + case EFFECT_TOXIC_THREAD: + IncreasePoisonScore(battlerAtk, battlerDef, move, &score); + IncreaseStatUpScore(battlerAtk, battlerDef, STAT_SPEED, &score); + break; + case EFFECT_TWO_TURNS_ATTACK: + case EFFECT_SKULL_BASH: + case EFFECT_SOLARBEAM: + if (AI_DATA->atkHoldEffect == HOLD_EFFECT_POWER_HERB) + score += 2; + break; + case EFFECT_COUNTER: + if (!IsBattlerIncapacitated(battlerDef, AI_DATA->defAbility) && predictedMove != MOVE_NONE) + { + if (gDisableStructs[battlerDef].tauntTimer != 0) + score++; // target must use damaging move + if (GetMoveDamageResult(predictedMove) >= MOVE_POWER_GOOD && GetBattleMoveSplit(predictedMove) == SPLIT_PHYSICAL) + score += 3; + } + break; + case EFFECT_MIRROR_COAT: + if (!IsBattlerIncapacitated(battlerDef, AI_DATA->defAbility) && predictedMove != MOVE_NONE) + { + if (gDisableStructs[battlerDef].tauntTimer != 0) + score++; // target must use damaging move + if (GetMoveDamageResult(predictedMove) >= MOVE_POWER_GOOD && GetBattleMoveSplit(predictedMove) == SPLIT_SPECIAL) + score += 3; + } + break; + case EFFECT_FLAIL: + if (GetWhoStrikesFirst(battlerAtk, battlerDef, TRUE) == 0) // Ai goes first + { + if (GetHealthPercentage(battlerAtk) < 20) + score++; + else if (GetHealthPercentage(battlerAtk) < 8) + score += 2; + } + break; + case EFFECT_SHORE_UP: + if (AI_WeatherHasEffect() && (gBattleWeather & WEATHER_SANDSTORM_ANY) + && ShouldRecover(battlerAtk, battlerDef, move, 67)) + score += 3; + else if (ShouldRecover(battlerAtk, battlerDef, move, 50)) + score += 2; + break; + case EFFECT_FACADE: + if (gBattleMons[battlerAtk].status1 & (STATUS1_POISON | STATUS1_BURN | STATUS1_PARALYSIS | STATUS1_TOXIC_POISON)) + score++; + break; + case EFFECT_FOCUS_PUNCH: + if (!isDoubleBattle && effectiveness > AI_EFFECTIVENESS_x0_5) + { + if (IsBattlerIncapacitated(battlerDef, AI_DATA->defAbility)) + score += 2; + else if (gBattleMons[battlerDef].status2 & (STATUS2_INFATUATION | STATUS2_CONFUSION)) + score++; + } + break; + case EFFECT_SMELLINGSALT: + if (gBattleMons[battlerDef].status1 & STATUS1_PARALYSIS) + score += 2; + break; + case EFFECT_WAKE_UP_SLAP: + if (gBattleMons[battlerDef].status1 & STATUS1_SLEEP) + score += 2; + break; + case EFFECT_REVENGE: + if (!(gBattleMons[battlerDef].status1 & STATUS1_SLEEP) + && !(gBattleMons[battlerDef].status2 & (STATUS2_INFATUATION | STATUS2_CONFUSION))) + score += 2; + break; + case EFFECT_ENDEAVOR: + if (GetWhoStrikesFirst(battlerAtk, battlerDef, TRUE) == 1) // Opponent faster + { + if (GetHealthPercentage(battlerAtk) < 40) + score++; + } + else if (GetHealthPercentage(battlerAtk) < 50) + { + score++; + } + break; + //case EFFECT_EXTREME_EVOBOOST: // TODO + //break; + //case EFFECT_CLANGOROUS_SOUL: // TODO + //break; + //case EFFECT_NO_RETREAT: // TODO + //break; + //case EFFECT_SKY_DROP + //break; + } // move effect checks + + return score; +} + +// Effects that are encouraged on the first turn of battle +static s16 AI_SetupFirstTurn(u8 battlerAtk, u8 battlerDef, u16 move, s16 score) +{ + if (IsTargetingPartner(battlerAtk, battlerDef) + || gBattleResults.battleTurnCounter != 0) + return score; + + if (AI_THINKING_STRUCT->aiFlags & AI_FLAG_SMART_SWITCHING + && GetWhoStrikesFirst(battlerAtk, battlerDef, TRUE) == 1 + && CanTargetFaintAi(battlerDef, battlerAtk) + && GetMovePriority(battlerAtk, move) == 0) + { + RETURN_SCORE_MINUS(20); // No point in setting up if you will faint. Should just switch if possible.. + } + + // check effects to prioritize first turn + switch (gBattleMoves[move].effect) + { + case EFFECT_ATTACK_UP: + case EFFECT_DEFENSE_UP: + case EFFECT_SPEED_UP: + case EFFECT_SPECIAL_ATTACK_UP: + case EFFECT_SPECIAL_DEFENSE_UP: + case EFFECT_ACCURACY_UP: + case EFFECT_EVASION_UP: + case EFFECT_ATTACK_DOWN: + case EFFECT_DEFENSE_DOWN: + case EFFECT_SPEED_DOWN: + case EFFECT_SPECIAL_ATTACK_DOWN: + case EFFECT_SPECIAL_DEFENSE_DOWN: + case EFFECT_ACCURACY_DOWN: + case EFFECT_EVASION_DOWN: + case EFFECT_CONVERSION: + case EFFECT_LIGHT_SCREEN: + case EFFECT_FOCUS_ENERGY: + case EFFECT_CONFUSE: + case EFFECT_ATTACK_UP_2: + case EFFECT_DEFENSE_UP_2: + case EFFECT_DEFENSE_UP_3: + case EFFECT_SPEED_UP_2: + case EFFECT_SPECIAL_ATTACK_UP_2: + case EFFECT_SPECIAL_ATTACK_UP_3: + case EFFECT_SPECIAL_DEFENSE_UP_2: + case EFFECT_ACCURACY_UP_2: + case EFFECT_EVASION_UP_2: + case EFFECT_ATTACK_DOWN_2: + case EFFECT_DEFENSE_DOWN_2: + case EFFECT_SPEED_DOWN_2: + case EFFECT_SPECIAL_ATTACK_DOWN_2: + case EFFECT_SPECIAL_DEFENSE_DOWN_2: + case EFFECT_ACCURACY_DOWN_2: + case EFFECT_EVASION_DOWN_2: + case EFFECT_REFLECT: + case EFFECT_POISON: + case EFFECT_PARALYZE: + case EFFECT_SUBSTITUTE: + case EFFECT_LEECH_SEED: + case EFFECT_MINIMIZE: + case EFFECT_CURSE: + case EFFECT_SWAGGER: + case EFFECT_CAMOUFLAGE: + case EFFECT_YAWN: + case EFFECT_DEFENSE_CURL: + case EFFECT_TORMENT: + case EFFECT_FLATTER: + case EFFECT_WILL_O_WISP: + case EFFECT_INGRAIN: + case EFFECT_IMPRISON: + case EFFECT_TEETER_DANCE: + case EFFECT_TICKLE: + case EFFECT_COSMIC_POWER: + case EFFECT_BULK_UP: + case EFFECT_CALM_MIND: + case EFFECT_ACUPRESSURE: + case EFFECT_AUTOTOMIZE: + case EFFECT_SHIFT_GEAR: + case EFFECT_SHELL_SMASH: + case EFFECT_GROWTH: + case EFFECT_QUIVER_DANCE: + case EFFECT_ATTACK_SPATK_UP: + case EFFECT_ATTACK_ACCURACY_UP: + case EFFECT_PSYCHIC_TERRAIN: + case EFFECT_GRASSY_TERRAIN: + case EFFECT_ELECTRIC_TERRAIN: + case EFFECT_MISTY_TERRAIN: + case EFFECT_STEALTH_ROCK: + case EFFECT_TOXIC_SPIKES: + case EFFECT_TRICK_ROOM: + case EFFECT_WONDER_ROOM: + case EFFECT_MAGIC_ROOM: + case EFFECT_TAILWIND: + case EFFECT_DRAGON_DANCE: + case EFFECT_STICKY_WEB: + case EFFECT_RAIN_DANCE: + case EFFECT_SUNNY_DAY: + case EFFECT_SANDSTORM: + case EFFECT_HAIL: + case EFFECT_GEOMANCY: + score += 2; + break; + default: + break; + } + + return score; +} + +// Adds score bonus to 'riskier' move effects and high crit moves +static s16 AI_Risky(u8 battlerAtk, u8 battlerDef, u16 move, s16 score) +{ + if (IsTargetingPartner(battlerAtk, battlerDef)) + return score; + + if (TestMoveFlags(move, FLAG_HIGH_CRIT)) + score += 2; + + switch (gBattleMoves[move].effect) + { + case EFFECT_SLEEP: + case EFFECT_EXPLOSION: + case EFFECT_MIRROR_MOVE: + case EFFECT_OHKO: + case EFFECT_CONFUSE: + case EFFECT_METRONOME: + case EFFECT_PSYWAVE: + case EFFECT_COUNTER: + case EFFECT_DESTINY_BOND: + case EFFECT_SWAGGER: + case EFFECT_ATTRACT: + case EFFECT_PRESENT: + case EFFECT_ALL_STATS_UP_HIT: + case EFFECT_BELLY_DRUM: + case EFFECT_MIRROR_COAT: + case EFFECT_FOCUS_PUNCH: + case EFFECT_REVENGE: + case EFFECT_TEETER_DANCE: + if (Random() & 1) + score += 2; + break; + default: + break; + } + + return score; +} + +// Adds score bonus to best powered move +static s16 AI_PreferStrongestMove(u8 battlerAtk, u8 battlerDef, u16 move, s16 score) +{ + if (IsTargetingPartner(battlerAtk, battlerDef)) + return score; + + if (GetMoveDamageResult(move) == MOVE_POWER_BEST) + score += 2; + + return score; +} + +// Prefers moves that are good for baton pass +static s16 AI_PreferBatonPass(u8 battlerAtk, u8 battlerDef, u16 move, s16 score) +{ + u32 i; + + if (IsTargetingPartner(battlerAtk, battlerDef) + || CountUsablePartyMons(battlerAtk) == 0 + || GetMoveDamageResult(move) != MOVE_POWER_DISCOURAGED + || !HasMoveEffect(battlerAtk, EFFECT_BATON_PASS) + || IsBattlerTrapped(battlerAtk, TRUE)) + return score; + + if (IsStatRaisingEffect(gBattleMoves[move].effect)) + { + if (gBattleResults.battleTurnCounter == 0) + score += 5; + else if (GetHealthPercentage(battlerAtk) < 60) + score -= 10; + else + score++; + } + + // other specific checks + switch (gBattleMoves[move].effect) + { + case EFFECT_INGRAIN: + if (!(gStatuses3[battlerAtk] & STATUS3_ROOTED)) + score += 2; + break; + case EFFECT_AQUA_RING: + if (!(gStatuses3[battlerAtk] & STATUS3_AQUA_RING)) + score += 2; + break; + case EFFECT_PROTECT: + if (gLastMoves[battlerAtk] == MOVE_PROTECT || gLastMoves[battlerAtk] == MOVE_DETECT) + score -= 2; + else + score += 2; + break; + case EFFECT_BATON_PASS: + for (i = STAT_ATK; i < NUM_BATTLE_STATS; i++) + { + IncreaseStatUpScore(battlerAtk, battlerDef, i, &score); + } + if (gStatuses3[battlerAtk] & (STATUS3_ROOTED | STATUS3_AQUA_RING)) + score += 2; + if (gStatuses3[battlerAtk] & STATUS3_LEECHSEED) + score -= 3; + break; + default: + break; + } + + return score; +} + +static s16 AI_HPAware(u8 battlerAtk, u8 battlerDef, u16 move, s16 score) +{ + u16 effect = gBattleMoves[move].effect; + u8 moveType = gBattleMoves[move].type; + + if (IsTargetingPartner(battlerAtk, battlerDef)) + { + if ((effect == EFFECT_HEAL_PULSE || effect == EFFECT_HIT_ENEMY_HEAL_ALLY) + || (moveType == TYPE_ELECTRIC && AI_DATA->atkPartnerAbility == ABILITY_VOLT_ABSORB) + || (moveType == TYPE_WATER && (AI_DATA->atkPartnerAbility == ABILITY_DRY_SKIN || AI_DATA->atkPartnerAbility == ABILITY_WATER_ABSORB))) + { + if (CanTargetFaintAi(FOE(battlerAtk), AI_DATA->battlerAtkPartner) + || (CanTargetFaintAi(BATTLE_PARTNER(FOE(battlerAtk)), AI_DATA->battlerAtkPartner))) + score--; + + if (GetHealthPercentage(battlerDef) <= 50) + score++; + } + } + else + { + // Consider AI HP + if (GetHealthPercentage(battlerAtk) > 70) + { + // high hp + switch (effect) + { + case EFFECT_EXPLOSION: + case EFFECT_RESTORE_HP: + case EFFECT_REST: + case EFFECT_DESTINY_BOND: + case EFFECT_FLAIL: + case EFFECT_ENDURE: + case EFFECT_MORNING_SUN: + case EFFECT_SYNTHESIS: + case EFFECT_MOONLIGHT: + case EFFECT_SHORE_UP: + case EFFECT_SOFTBOILED: + case EFFECT_ROOST: + case EFFECT_MEMENTO: + case EFFECT_GRUDGE: + case EFFECT_OVERHEAT: + score -= 2; + break; + default: + break; + } + } + else if (GetHealthPercentage(battlerAtk) > 30) + { + // med hp + if (IsStatRaisingEffect(effect) || IsStatLoweringEffect(effect)) + score -= 2; + + switch (effect) + { + case EFFECT_EXPLOSION: + case EFFECT_BIDE: + case EFFECT_CONVERSION: + case EFFECT_LIGHT_SCREEN: + case EFFECT_MIST: + case EFFECT_FOCUS_ENERGY: + case EFFECT_CONVERSION_2: + case EFFECT_SAFEGUARD: + case EFFECT_BELLY_DRUM: + score -= 2; + break; + default: + break; + } + } + else + { + // low hp + if (IsStatRaisingEffect(effect) || IsStatLoweringEffect(effect)) + score -= 2; + + // check other discouraged low hp effects + switch (effect) + { + case EFFECT_BIDE: + case EFFECT_CONVERSION: + case EFFECT_REFLECT: + case EFFECT_LIGHT_SCREEN: + case EFFECT_AURORA_VEIL: + case EFFECT_MIST: + case EFFECT_FOCUS_ENERGY: + case EFFECT_RAGE: + case EFFECT_CONVERSION_2: + case EFFECT_LOCK_ON: + case EFFECT_SAFEGUARD: + case EFFECT_BELLY_DRUM: + case EFFECT_PSYCH_UP: + case EFFECT_MIRROR_COAT: + case EFFECT_SOLARBEAM: + case EFFECT_TWO_TURNS_ATTACK: + case EFFECT_ERUPTION: + case EFFECT_TICKLE: + case EFFECT_SUNNY_DAY: + case EFFECT_SANDSTORM: + case EFFECT_HAIL: + case EFFECT_RAIN_DANCE: + score -= 2; + break; + default: + break; + } + } + } + + // consider target HP + if (CanAttackerFaintTarget(battlerAtk, battlerDef, AI_THINKING_STRUCT->movesetIndex, 0)) + { + score += 2; + } + else + { + if (GetHealthPercentage(battlerDef) > 70) + { + // high HP + ; // nothing yet + } + else if (GetHealthPercentage(battlerDef) > 30) + { + // med HP - check discouraged effects + switch (effect) + { + case EFFECT_ATTACK_UP: + case EFFECT_DEFENSE_UP: + case EFFECT_SPEED_UP: + case EFFECT_SPECIAL_ATTACK_UP: + case EFFECT_SPECIAL_DEFENSE_UP: + case EFFECT_ACCURACY_UP: + case EFFECT_EVASION_UP: + case EFFECT_ATTACK_DOWN: + case EFFECT_DEFENSE_DOWN: + case EFFECT_SPEED_DOWN: + case EFFECT_SPECIAL_ATTACK_DOWN: + case EFFECT_SPECIAL_DEFENSE_DOWN: + case EFFECT_ACCURACY_DOWN: + case EFFECT_EVASION_DOWN: + case EFFECT_MIST: + case EFFECT_FOCUS_ENERGY: + case EFFECT_ATTACK_UP_2: + case EFFECT_DEFENSE_UP_2: + case EFFECT_SPEED_UP_2: + case EFFECT_SPECIAL_ATTACK_UP_2: + case EFFECT_SPECIAL_DEFENSE_UP_2: + case EFFECT_ACCURACY_UP_2: + case EFFECT_EVASION_UP_2: + case EFFECT_ATTACK_DOWN_2: + case EFFECT_DEFENSE_DOWN_2: + case EFFECT_SPEED_DOWN_2: + case EFFECT_SPECIAL_ATTACK_DOWN_2: + case EFFECT_SPECIAL_DEFENSE_DOWN_2: + case EFFECT_ACCURACY_DOWN_2: + case EFFECT_EVASION_DOWN_2: + case EFFECT_POISON: + case EFFECT_PAIN_SPLIT: + case EFFECT_PERISH_SONG: + case EFFECT_SAFEGUARD: + case EFFECT_TICKLE: + case EFFECT_COSMIC_POWER: + case EFFECT_BULK_UP: + case EFFECT_CALM_MIND: + case EFFECT_DRAGON_DANCE: + case EFFECT_DEFENSE_UP_3: + case EFFECT_SPECIAL_ATTACK_UP_3: + score -= 2; + break; + default: + break; + } + } + else + { + // low HP + if (IS_MOVE_STATUS(move)) + score -= 2; // don't use status moves if target is at low health + } + } + + return score; +} + +static void AI_Flee(void) +{ + AI_THINKING_STRUCT->aiAction |= (AI_ACTION_DONE | AI_ACTION_FLEE | AI_ACTION_DO_NOT_ATTACK); +} + +static void AI_Watch(void) +{ + AI_THINKING_STRUCT->aiAction |= (AI_ACTION_DONE | AI_ACTION_WATCH | AI_ACTION_DO_NOT_ATTACK); +} + +// Roaming pokemon logic +static s16 AI_Roaming(u8 battlerAtk, u8 battlerDef, u16 move, s16 score) +{ + if (IsBattlerTrapped(battlerAtk, FALSE)) + return score; + + AI_Flee(); + return score; +} + +// Safari pokemon logic +static s16 AI_Safari(u8 battlerAtk, u8 battlerDef, u16 move, s16 score) +{ + u8 safariFleeRate = gBattleStruct->safariEscapeFactor * 5; // Safari flee rate, from 0-20. + + if ((Random() % 100) < safariFleeRate) + AI_Flee(); + else + AI_Watch(); + + return score; +} + +// First battle logic +static s16 AI_FirstBattle(u8 battlerAtk, u8 battlerDef, u16 move, s16 score) +{ + if (GetHealthPercentage(battlerDef) <= 20) + AI_Flee(); + + return score; +} diff --git a/src/battle_ai_script_commands.c b/src/battle_ai_script_commands.c deleted file mode 100644 index ebb33a22b..000000000 --- a/src/battle_ai_script_commands.c +++ /dev/null @@ -1,2871 +0,0 @@ -#include "global.h" -#include "malloc.h" -#include "battle.h" -#include "battle_anim.h" -#include "battle_ai_script_commands.h" -#include "battle_factory.h" -#include "battle_setup.h" -#include "data.h" -#include "item.h" -#include "pokemon.h" -#include "random.h" -#include "recorded_battle.h" -#include "util.h" -#include "constants/abilities.h" -#include "constants/battle_ai.h" -#include "constants/battle_move_effects.h" -#include "constants/hold_effects.h" -#include "constants/moves.h" - -#define AI_ACTION_DONE 0x0001 -#define AI_ACTION_FLEE 0x0002 -#define AI_ACTION_WATCH 0x0004 -#define AI_ACTION_DO_NOT_ATTACK 0x0008 -#define AI_ACTION_UNK5 0x0010 -#define AI_ACTION_UNK6 0x0020 -#define AI_ACTION_UNK7 0x0040 -#define AI_ACTION_UNK8 0x0080 - -#define AI_THINKING_STRUCT ((struct AI_ThinkingStruct *)(gBattleResources->ai)) -#define BATTLE_HISTORY ((struct BattleHistory *)(gBattleResources->battleHistory)) - -// AI states -enum -{ - AIState_SettingUp, - AIState_Processing, - AIState_FinishedProcessing, - AIState_DoNotProcess -}; - -/* -gAIScriptPtr is a pointer to the next battle AI cmd command to read. -when a command finishes processing, gAIScriptPtr is incremented by -the number of bytes that the current command had reserved for arguments -in order to read the next command correctly. refer to battle_ai_scripts.s for the -AI scripts. -*/ - -extern const u8 *const gBattleAI_ScriptsTable[]; - -static u8 ChooseMoveOrAction_Singles(void); -static u8 ChooseMoveOrAction_Doubles(void); -static void RecordLastUsedMoveByTarget(void); -static void BattleAI_DoAIProcessing(void); -static void AIStackPushVar(const u8 *); -static bool8 AIStackPop(void); -static s32 CountUsablePartyMons(u8 battlerId); -static s32 AI_GetAbility(u32 battlerId, bool32 guess); - -static void Cmd_if_random_less_than(void); -static void Cmd_if_random_greater_than(void); -static void Cmd_if_random_equal(void); -static void Cmd_if_random_not_equal(void); -static void Cmd_score(void); -static void Cmd_if_hp_less_than(void); -static void Cmd_if_hp_more_than(void); -static void Cmd_if_hp_equal(void); -static void Cmd_if_hp_not_equal(void); -static void Cmd_if_status(void); -static void Cmd_if_not_status(void); -static void Cmd_if_status2(void); -static void Cmd_if_not_status2(void); -static void Cmd_if_status3(void); -static void Cmd_if_not_status3(void); -static void Cmd_if_side_affecting(void); -static void Cmd_if_not_side_affecting(void); -static void Cmd_if_less_than(void); -static void Cmd_if_more_than(void); -static void Cmd_if_equal(void); -static void Cmd_if_not_equal(void); -static void Cmd_if_less_than_ptr(void); -static void Cmd_if_more_than_ptr(void); -static void Cmd_if_equal_ptr(void); -static void Cmd_if_not_equal_ptr(void); -static void Cmd_if_move(void); -static void Cmd_if_not_move(void); -static void Cmd_if_in_bytes(void); -static void Cmd_if_not_in_bytes(void); -static void Cmd_if_in_hwords(void); -static void Cmd_if_not_in_hwords(void); -static void Cmd_if_user_has_attacking_move(void); -static void Cmd_if_user_has_no_attacking_moves(void); -static void Cmd_get_turn_count(void); -static void Cmd_get_type(void); -static void Cmd_get_considered_move_power(void); -static void Cmd_get_how_powerful_move_is(void); -static void Cmd_get_last_used_battler_move(void); -static void Cmd_if_equal_u32(void); -static void Cmd_if_not_equal_u32(void); -static void Cmd_if_user_goes(void); -static void Cmd_if_cant_use_belch(void); -static void Cmd_nop_2A(void); -static void Cmd_nop_2B(void); -static void Cmd_count_usable_party_mons(void); -static void Cmd_get_considered_move(void); -static void Cmd_get_considered_move_effect(void); -static void Cmd_get_ability(void); -static void Cmd_get_highest_type_effectiveness(void); -static void Cmd_if_type_effectiveness(void); -static void Cmd_nop_32(void); -static void Cmd_nop_33(void); -static void Cmd_if_status_in_party(void); -static void Cmd_if_status_not_in_party(void); -static void Cmd_get_weather(void); -static void Cmd_if_effect(void); -static void Cmd_if_not_effect(void); -static void Cmd_if_stat_level_less_than(void); -static void Cmd_if_stat_level_more_than(void); -static void Cmd_if_stat_level_equal(void); -static void Cmd_if_stat_level_not_equal(void); -static void Cmd_if_can_faint(void); -static void Cmd_if_cant_faint(void); -static void Cmd_if_has_move(void); -static void Cmd_if_doesnt_have_move(void); -static void Cmd_if_has_move_with_effect(void); -static void Cmd_if_doesnt_have_move_with_effect(void); -static void Cmd_if_any_move_disabled_or_encored(void); -static void Cmd_if_curr_move_disabled_or_encored(void); -static void Cmd_flee(void); -static void Cmd_if_random_safari_flee(void); -static void Cmd_watch(void); -static void Cmd_get_hold_effect(void); -static void Cmd_get_gender(void); -static void Cmd_is_first_turn_for(void); -static void Cmd_get_stockpile_count(void); -static void Cmd_is_double_battle(void); -static void Cmd_get_used_held_item(void); -static void Cmd_get_move_type_from_result(void); -static void Cmd_get_move_power_from_result(void); -static void Cmd_get_move_effect_from_result(void); -static void Cmd_get_protect_count(void); -static void Cmd_if_move_flag(void); -static void Cmd_if_field_status(void); -static void Cmd_get_move_accuracy(void); -static void Cmd_call_if_eq(void); -static void Cmd_call_if_move_flag(void); -static void Cmd_nop_57(void); -static void Cmd_call(void); -static void Cmd_goto(void); -static void Cmd_end(void); -static void Cmd_if_level_cond(void); -static void Cmd_if_target_taunted(void); -static void Cmd_if_target_not_taunted(void); -static void Cmd_check_ability(void); -static void Cmd_is_of_type(void); -static void Cmd_if_target_is_ally(void); -static void Cmd_if_flash_fired(void); -static void Cmd_if_holds_item(void); -static void Cmd_get_ally_chosen_move(void); -static void Cmd_if_has_no_attacking_moves(void); -static void Cmd_get_hazards_count(void); -static void Cmd_if_doesnt_hold_berry(void); -static void Cmd_if_share_type(void); -static void Cmd_if_cant_use_last_resort(void); -static void Cmd_if_has_move_with_split(void); -static void Cmd_if_has_no_move_with_split(void); -static void Cmd_if_physical_moves_unusable(void); -static void Cmd_if_ai_can_go_down(void); -static void Cmd_if_has_move_with_type(void); -static void Cmd_if_no_move_used(void); -static void Cmd_if_has_move_with_flag(void); -static void Cmd_if_battler_absent(void); -static void Cmd_is_grounded(void); -static void Cmd_get_best_dmg_hp_percent(void); -static void Cmd_get_curr_dmg_hp_percent(void); -static void Cmd_get_move_split_from_result(void); -static void Cmd_get_considered_move_split(void); -static void Cmd_get_considered_move_target(void); -static void Cmd_compare_speeds(void); -static void Cmd_is_wakeup_turn(void); -static void Cmd_if_has_move_with_accuracy_lt(void); - -// ewram -EWRAM_DATA const u8 *gAIScriptPtr = NULL; -EWRAM_DATA static u8 sBattler_AI = 0; - -// const rom data -typedef void (*BattleAICmdFunc)(void); - -static const BattleAICmdFunc sBattleAICmdTable[] = -{ - Cmd_if_random_less_than, // 0x0 - Cmd_if_random_greater_than, // 0x1 - Cmd_if_random_equal, // 0x2 - Cmd_if_random_not_equal, // 0x3 - Cmd_score, // 0x4 - Cmd_if_hp_less_than, // 0x5 - Cmd_if_hp_more_than, // 0x6 - Cmd_if_hp_equal, // 0x7 - Cmd_if_hp_not_equal, // 0x8 - Cmd_if_status, // 0x9 - Cmd_if_not_status, // 0xA - Cmd_if_status2, // 0xB - Cmd_if_not_status2, // 0xC - Cmd_if_status3, // 0xD - Cmd_if_not_status3, // 0xE - Cmd_if_side_affecting, // 0xF - Cmd_if_not_side_affecting, // 0x10 - Cmd_if_less_than, // 0x11 - Cmd_if_more_than, // 0x12 - Cmd_if_equal, // 0x13 - Cmd_if_not_equal, // 0x14 - Cmd_if_less_than_ptr, // 0x15 - Cmd_if_more_than_ptr, // 0x16 - Cmd_if_equal_ptr, // 0x17 - Cmd_if_not_equal_ptr, // 0x18 - Cmd_if_move, // 0x19 - Cmd_if_not_move, // 0x1A - Cmd_if_in_bytes, // 0x1B - Cmd_if_not_in_bytes, // 0x1C - Cmd_if_in_hwords, // 0x1D - Cmd_if_not_in_hwords, // 0x1E - Cmd_if_user_has_attacking_move, // 0x1F - Cmd_if_user_has_no_attacking_moves, // 0x20 - Cmd_get_turn_count, // 0x21 - Cmd_get_type, // 0x22 - Cmd_get_considered_move_power, // 0x23 - Cmd_get_how_powerful_move_is, // 0x24 - Cmd_get_last_used_battler_move, // 0x25 - Cmd_if_equal_u32, // 0x26 - Cmd_if_not_equal_u32, // 0x27 - Cmd_if_user_goes, // 0x28 - Cmd_if_cant_use_belch, // 0x29 - Cmd_nop_2A, // 0x2A - Cmd_nop_2B, // 0x2B - Cmd_count_usable_party_mons, // 0x2C - Cmd_get_considered_move, // 0x2D - Cmd_get_considered_move_effect, // 0x2E - Cmd_get_ability, // 0x2F - Cmd_get_highest_type_effectiveness, // 0x30 - Cmd_if_type_effectiveness, // 0x31 - Cmd_nop_32, // 0x32 - Cmd_nop_33, // 0x33 - Cmd_if_status_in_party, // 0x34 - Cmd_if_status_not_in_party, // 0x35 - Cmd_get_weather, // 0x36 - Cmd_if_effect, // 0x37 - Cmd_if_not_effect, // 0x38 - Cmd_if_stat_level_less_than, // 0x39 - Cmd_if_stat_level_more_than, // 0x3A - Cmd_if_stat_level_equal, // 0x3B - Cmd_if_stat_level_not_equal, // 0x3C - Cmd_if_can_faint, // 0x3D - Cmd_if_cant_faint, // 0x3E - Cmd_if_has_move, // 0x3F - Cmd_if_doesnt_have_move, // 0x40 - Cmd_if_has_move_with_effect, // 0x41 - Cmd_if_doesnt_have_move_with_effect, // 0x42 - Cmd_if_any_move_disabled_or_encored, // 0x43 - Cmd_if_curr_move_disabled_or_encored, // 0x44 - Cmd_flee, // 0x45 - Cmd_if_random_safari_flee, // 0x46 - Cmd_watch, // 0x47 - Cmd_get_hold_effect, // 0x48 - Cmd_get_gender, // 0x49 - Cmd_is_first_turn_for, // 0x4A - Cmd_get_stockpile_count, // 0x4B - Cmd_is_double_battle, // 0x4C - Cmd_get_used_held_item, // 0x4D - Cmd_get_move_type_from_result, // 0x4E - Cmd_get_move_power_from_result, // 0x4F - Cmd_get_move_effect_from_result, // 0x50 - Cmd_get_protect_count, // 0x51 - Cmd_if_move_flag, // 0x52 - Cmd_if_field_status, // 0x53 - Cmd_get_move_accuracy, // 0x54 - Cmd_call_if_eq, // 0x55 - Cmd_call_if_move_flag, // 0x56 - Cmd_nop_57, // 0x57 - Cmd_call, // 0x58 - Cmd_goto, // 0x59 - Cmd_end, // 0x5A - Cmd_if_level_cond, // 0x5B - Cmd_if_target_taunted, // 0x5C - Cmd_if_target_not_taunted, // 0x5D - Cmd_if_target_is_ally, // 0x5E - Cmd_is_of_type, // 0x5F - Cmd_check_ability, // 0x60 - Cmd_if_flash_fired, // 0x61 - Cmd_if_holds_item, // 0x62 - Cmd_get_ally_chosen_move, // 0x63 - Cmd_if_has_no_attacking_moves, // 0x64 - Cmd_get_hazards_count, // 0x65 - Cmd_if_doesnt_hold_berry, // 0x66 - Cmd_if_share_type, // 0x67 - Cmd_if_cant_use_last_resort, // 0x68 - Cmd_if_has_move_with_split, // 0x69 - Cmd_if_has_no_move_with_split, // 0x6A - Cmd_if_physical_moves_unusable, // 0x6B - Cmd_if_ai_can_go_down, // 0x6C - Cmd_if_has_move_with_type, // 0x6D - Cmd_if_no_move_used, // 0x6E - Cmd_if_has_move_with_flag, // 0x6F - Cmd_if_battler_absent, // 0x70 - Cmd_is_grounded, // 0x71 - Cmd_get_best_dmg_hp_percent, // 0x72 - Cmd_get_curr_dmg_hp_percent, // 0x73 - Cmd_get_move_split_from_result, // 0x74 - Cmd_get_considered_move_split, // 0x75 - Cmd_get_considered_move_target, // 0x76 - Cmd_compare_speeds, // 0x77 - Cmd_is_wakeup_turn, // 0x78 - Cmd_if_has_move_with_accuracy_lt, // 0x79 -}; - -static const u16 sDiscouragedPowerfulMoveEffects[] = -{ - EFFECT_EXPLOSION, - EFFECT_DREAM_EATER, - EFFECT_RECHARGE, - EFFECT_SKULL_BASH, - EFFECT_SOLARBEAM, - EFFECT_SPIT_UP, - EFFECT_FOCUS_PUNCH, - EFFECT_SUPERPOWER, - EFFECT_ERUPTION, - EFFECT_OVERHEAT, - EFFECT_MIND_BLOWN, - 0xFFFF -}; - -// code -void BattleAI_SetupItems(void) -{ - s32 i; - u8 *data = (u8 *)BATTLE_HISTORY; - - for (i = 0; i < sizeof(struct BattleHistory); i++) - data[i] = 0; - - // Items are allowed to use in ONLY trainer battles. - if ((gBattleTypeFlags & BATTLE_TYPE_TRAINER) - && !(gBattleTypeFlags & (BATTLE_TYPE_LINK | BATTLE_TYPE_SAFARI | BATTLE_TYPE_BATTLE_TOWER - | BATTLE_TYPE_EREADER_TRAINER | BATTLE_TYPE_SECRET_BASE | BATTLE_TYPE_FRONTIER - | BATTLE_TYPE_INGAME_PARTNER | BATTLE_TYPE_RECORDED_LINK) - ) - ) - { - for (i = 0; i < MAX_TRAINER_ITEMS; i++) - { - if (gTrainers[gTrainerBattleOpponent_A].items[i] != 0) - { - BATTLE_HISTORY->trainerItems[BATTLE_HISTORY->itemsNo] = gTrainers[gTrainerBattleOpponent_A].items[i]; - BATTLE_HISTORY->itemsNo++; - } - } - } -} - -void BattleAI_SetupFlags(void) -{ - if (gBattleTypeFlags & BATTLE_TYPE_RECORDED) - AI_THINKING_STRUCT->aiFlags = GetAiScriptsInRecordedBattle(); - else if (gBattleTypeFlags & BATTLE_TYPE_SAFARI) - AI_THINKING_STRUCT->aiFlags = AI_SCRIPT_SAFARI; - else if (gBattleTypeFlags & BATTLE_TYPE_ROAMER) - AI_THINKING_STRUCT->aiFlags = AI_SCRIPT_ROAMING; - else if (gBattleTypeFlags & BATTLE_TYPE_FIRST_BATTLE) - AI_THINKING_STRUCT->aiFlags = AI_SCRIPT_FIRST_BATTLE; - else if (gBattleTypeFlags & BATTLE_TYPE_FACTORY) - AI_THINKING_STRUCT->aiFlags = GetAiScriptsInBattleFactory(); - else if (gBattleTypeFlags & (BATTLE_TYPE_FRONTIER | BATTLE_TYPE_EREADER_TRAINER | BATTLE_TYPE_TRAINER_HILL | BATTLE_TYPE_SECRET_BASE)) - AI_THINKING_STRUCT->aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_CHECK_VIABILITY | AI_SCRIPT_TRY_TO_FAINT; - else if (gBattleTypeFlags & BATTLE_TYPE_TWO_OPPONENTS) - AI_THINKING_STRUCT->aiFlags = gTrainers[gTrainerBattleOpponent_A].aiFlags | gTrainers[gTrainerBattleOpponent_B].aiFlags; - else - AI_THINKING_STRUCT->aiFlags = gTrainers[gTrainerBattleOpponent_A].aiFlags; - - if (gBattleTypeFlags & (BATTLE_TYPE_DOUBLE | BATTLE_TYPE_TWO_OPPONENTS) || gTrainers[gTrainerBattleOpponent_A].doubleBattle) - AI_THINKING_STRUCT->aiFlags |= AI_SCRIPT_DOUBLE_BATTLE; // Act smart in doubles and don't attack your partner. -} - -void BattleAI_SetupAIData(u8 defaultScoreMoves) -{ - s32 i, move, dmg; - u8 moveLimitations; - - // Clear AI data but preserve the flags. - u32 flags = AI_THINKING_STRUCT->aiFlags; - memset(AI_THINKING_STRUCT, 0, sizeof(struct AI_ThinkingStruct)); - AI_THINKING_STRUCT->aiFlags = flags; - - // Conditional score reset, unlike Ruby. - for (i = 0; i < MAX_MON_MOVES; i++) - { - if (defaultScoreMoves & 1) - AI_THINKING_STRUCT->score[i] = 100; - else - AI_THINKING_STRUCT->score[i] = 0; - - defaultScoreMoves >>= 1; - } - - moveLimitations = CheckMoveLimitations(gActiveBattler, 0, 0xFF); - - // Ignore moves that aren't possible to use. - for (i = 0; i < MAX_MON_MOVES; i++) - { - if (gBitTable[i] & moveLimitations) - AI_THINKING_STRUCT->score[i] = 0; - } - - gBattleResources->AI_ScriptsStack->size = 0; - sBattler_AI = gActiveBattler; - - // Simulate dmg for all AI moves against all opposing targets - for (gBattlerTarget = 0; gBattlerTarget < gBattlersCount; gBattlerTarget++) - { - if (GET_BATTLER_SIDE2(sBattler_AI) == GET_BATTLER_SIDE2(gBattlerTarget)) - continue; - for (i = 0; i < MAX_MON_MOVES; i++) - { - dmg = 0; - move = gBattleMons[sBattler_AI].moves[i]; - if (gBattleMoves[move].power != 0 && !(moveLimitations & gBitTable[i])) - { - dmg = AI_CalcDamage(move, sBattler_AI, gBattlerTarget) * (100 - (Random() % 10)) / 100; - if (dmg == 0) - dmg = 1; - } - - AI_THINKING_STRUCT->simulatedDmg[sBattler_AI][gBattlerTarget][i] = dmg; - } - } - - gBattlerTarget = SetRandomTarget(sBattler_AI); -} - -u8 BattleAI_ChooseMoveOrAction(void) -{ - u32 savedCurrentMove = gCurrentMove; - u8 ret; - - if (!(gBattleTypeFlags & BATTLE_TYPE_DOUBLE)) - ret = ChooseMoveOrAction_Singles(); - else - ret = ChooseMoveOrAction_Doubles(); - - gCurrentMove = savedCurrentMove; - return ret; -} - -static u32 GetTotalBaseStat(u32 species) -{ - return gBaseStats[species].baseHP - + gBaseStats[species].baseAttack - + gBaseStats[species].baseDefense - + gBaseStats[species].baseSpeed - + gBaseStats[species].baseSpAttack - + gBaseStats[species].baseSpDefense; -} - -bool32 IsTruantMonVulnerable(u32 battlerAI, u32 opposingBattler) -{ - int i; - - for (i = 0; i < MAX_MON_MOVES; i++) - { - u32 move = gBattleResources->battleHistory->usedMoves[opposingBattler][i]; - if (gBattleMoves[move].effect == EFFECT_PROTECT && move != MOVE_ENDURE) - return TRUE; - if (gBattleMoves[move].effect == EFFECT_SEMI_INVULNERABLE && GetWhoStrikesFirst(battlerAI, opposingBattler, TRUE) == 1) - return TRUE; - } - return FALSE; -} - -static u8 ChooseMoveOrAction_Singles(void) -{ - u8 currentMoveArray[MAX_MON_MOVES]; - u8 consideredMoveArray[MAX_MON_MOVES]; - u32 numOfBestMoves; - s32 i, id; - u32 flags = AI_THINKING_STRUCT->aiFlags; - - RecordLastUsedMoveByTarget(); - - while (flags != 0) - { - if (flags & 1) - { - AI_THINKING_STRUCT->aiState = AIState_SettingUp; - BattleAI_DoAIProcessing(); - } - flags >>= 1; - AI_THINKING_STRUCT->aiLogicId++; - AI_THINKING_STRUCT->movesetIndex = 0; - } - - for (i = 0; i < MAX_MON_MOVES; i++) - gBattleStruct->aiFinalScore[sBattler_AI][gBattlerTarget][i] = AI_THINKING_STRUCT->score[i]; - - // Check special AI actions. - if (AI_THINKING_STRUCT->aiAction & AI_ACTION_FLEE) - return AI_CHOICE_FLEE; - if (AI_THINKING_STRUCT->aiAction & AI_ACTION_WATCH) - return AI_CHOICE_WATCH; - - gActiveBattler = sBattler_AI; - // If can switch. - if (CountUsablePartyMons(sBattler_AI) >= 1 - && !IsAbilityPreventingEscape(sBattler_AI) - && !(gBattleMons[gActiveBattler].status2 & (STATUS2_WRAPPED | STATUS2_ESCAPE_PREVENTION)) - && !(gStatuses3[gActiveBattler] & STATUS3_ROOTED) - && !(gBattleTypeFlags & (BATTLE_TYPE_ARENA | BATTLE_TYPE_PALACE)) - && AI_THINKING_STRUCT->aiFlags & (AI_SCRIPT_CHECK_VIABILITY | AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_PREFER_BATON_PASS)) - { - // Consider switching if all moves are worthless to use. - if (GetTotalBaseStat(gBattleMons[sBattler_AI].species) >= 310 // Mon is not weak. - && gBattleMons[sBattler_AI].hp >= gBattleMons[sBattler_AI].maxHP / 2) - { - s32 cap = AI_THINKING_STRUCT->aiFlags & (AI_SCRIPT_CHECK_VIABILITY) ? 95 : 93; - for (i = 0; i < MAX_MON_MOVES; i++) - { - if (AI_THINKING_STRUCT->score[i] > cap) - break; - } - - if (i == MAX_MON_MOVES && GetMostSuitableMonToSwitchInto() != PARTY_SIZE) - { - AI_THINKING_STRUCT->switchMon = TRUE; - return AI_CHOICE_SWITCH; - } - } - - // Consider switching if your mon with truant is bodied by Protect spam. - // Or is using a double turn semi invulnerable move(such as Fly) and is faster. - if (GetBattlerAbility(sBattler_AI) == ABILITY_TRUANT - && IsTruantMonVulnerable(sBattler_AI, gBattlerTarget) - && gDisableStructs[sBattler_AI].truantCounter - && gBattleMons[sBattler_AI].hp >= gBattleMons[sBattler_AI].maxHP / 2) - { - if (GetMostSuitableMonToSwitchInto() != PARTY_SIZE) - { - AI_THINKING_STRUCT->switchMon = TRUE; - return AI_CHOICE_SWITCH; - } - } - } - - numOfBestMoves = 1; - currentMoveArray[0] = AI_THINKING_STRUCT->score[0]; - consideredMoveArray[0] = 0; - - for (i = 1; i < MAX_MON_MOVES; i++) - { - if (gBattleMons[sBattler_AI].moves[i] != MOVE_NONE) - { - // In ruby, the order of these if statements is reversed. - if (currentMoveArray[0] == AI_THINKING_STRUCT->score[i]) - { - currentMoveArray[numOfBestMoves] = AI_THINKING_STRUCT->score[i]; - consideredMoveArray[numOfBestMoves++] = i; - } - if (currentMoveArray[0] < AI_THINKING_STRUCT->score[i]) - { - numOfBestMoves = 1; - currentMoveArray[0] = AI_THINKING_STRUCT->score[i]; - consideredMoveArray[0] = i; - } - } - } - return consideredMoveArray[Random() % numOfBestMoves]; -} - -static u8 ChooseMoveOrAction_Doubles(void) -{ - s32 i, j; - u32 flags; - s16 bestMovePointsForTarget[MAX_BATTLERS_COUNT]; - s8 mostViableTargetsArray[MAX_BATTLERS_COUNT]; - u8 actionOrMoveIndex[MAX_BATTLERS_COUNT]; - u8 mostViableMovesScores[MAX_MON_MOVES]; - u8 mostViableMovesIndices[MAX_MON_MOVES]; - s32 mostViableTargetsNo; - s32 mostViableMovesNo; - s16 mostMovePoints; - - for (i = 0; i < MAX_BATTLERS_COUNT; i++) - { - if (i == sBattler_AI || gBattleMons[i].hp == 0) - { - actionOrMoveIndex[i] = 0xFF; - bestMovePointsForTarget[i] = -1; - } - else - { - if (gBattleTypeFlags & BATTLE_TYPE_PALACE) - BattleAI_SetupAIData(gBattleStruct->palaceFlags >> 4); - else - BattleAI_SetupAIData((1 << MAX_MON_MOVES) - 1); - - gBattlerTarget = i; - - if ((i & BIT_SIDE) != (sBattler_AI & BIT_SIDE)) - RecordLastUsedMoveByTarget(); - - AI_THINKING_STRUCT->aiLogicId = 0; - AI_THINKING_STRUCT->movesetIndex = 0; - flags = AI_THINKING_STRUCT->aiFlags; - while (flags != 0) - { - if (flags & 1) - { - AI_THINKING_STRUCT->aiState = AIState_SettingUp; - BattleAI_DoAIProcessing(); - } - flags >>= 1; - AI_THINKING_STRUCT->aiLogicId++; - AI_THINKING_STRUCT->movesetIndex = 0; - } - - if (AI_THINKING_STRUCT->aiAction & AI_ACTION_FLEE) - { - actionOrMoveIndex[i] = AI_CHOICE_FLEE; - } - else if (AI_THINKING_STRUCT->aiAction & AI_ACTION_WATCH) - { - actionOrMoveIndex[i] = AI_CHOICE_WATCH; - } - else - { - mostViableMovesScores[0] = AI_THINKING_STRUCT->score[0]; - mostViableMovesIndices[0] = 0; - mostViableMovesNo = 1; - for (j = 1; j < MAX_MON_MOVES; j++) - { - if (gBattleMons[sBattler_AI].moves[j] != 0) - { - if (mostViableMovesScores[0] == AI_THINKING_STRUCT->score[j]) - { - mostViableMovesScores[mostViableMovesNo] = AI_THINKING_STRUCT->score[j]; - mostViableMovesIndices[mostViableMovesNo] = j; - mostViableMovesNo++; - } - if (mostViableMovesScores[0] < AI_THINKING_STRUCT->score[j]) - { - mostViableMovesScores[0] = AI_THINKING_STRUCT->score[j]; - mostViableMovesIndices[0] = j; - mostViableMovesNo = 1; - } - } - } - actionOrMoveIndex[i] = mostViableMovesIndices[Random() % mostViableMovesNo]; - bestMovePointsForTarget[i] = mostViableMovesScores[0]; - - // Don't use a move against ally if it has less than 100 points. - if (i == (sBattler_AI ^ BIT_FLANK) && bestMovePointsForTarget[i] < 100) - { - bestMovePointsForTarget[i] = -1; - mostViableMovesScores[0] = mostViableMovesScores[0]; // Needed to match. - } - } - - for (j = 0; j < MAX_MON_MOVES; j++) - gBattleStruct->aiFinalScore[sBattler_AI][gBattlerTarget][j] = AI_THINKING_STRUCT->score[j]; - } - } - - mostMovePoints = bestMovePointsForTarget[0]; - mostViableTargetsArray[0] = 0; - mostViableTargetsNo = 1; - - for (i = 1; i < MAX_BATTLERS_COUNT; i++) - { - if (mostMovePoints == bestMovePointsForTarget[i]) - { - mostViableTargetsArray[mostViableTargetsNo] = i; - mostViableTargetsNo++; - } - if (mostMovePoints < bestMovePointsForTarget[i]) - { - mostMovePoints = bestMovePointsForTarget[i]; - mostViableTargetsArray[0] = i; - mostViableTargetsNo = 1; - } - } - - gBattlerTarget = mostViableTargetsArray[Random() % mostViableTargetsNo]; - return actionOrMoveIndex[gBattlerTarget]; -} - -static void BattleAI_DoAIProcessing(void) -{ - while (AI_THINKING_STRUCT->aiState != AIState_FinishedProcessing) - { - switch (AI_THINKING_STRUCT->aiState) - { - case AIState_DoNotProcess: // Needed to match. - break; - case AIState_SettingUp: - gAIScriptPtr = gBattleAI_ScriptsTable[AI_THINKING_STRUCT->aiLogicId]; // set AI ptr to logic ID. - if (gBattleMons[sBattler_AI].pp[AI_THINKING_STRUCT->movesetIndex] == 0) - { - AI_THINKING_STRUCT->moveConsidered = 0; - } - else - { - AI_THINKING_STRUCT->moveConsidered = gBattleMons[sBattler_AI].moves[AI_THINKING_STRUCT->movesetIndex]; - } - AI_THINKING_STRUCT->aiState++; - break; - case AIState_Processing: - if (AI_THINKING_STRUCT->moveConsidered != 0) - { - sBattleAICmdTable[*gAIScriptPtr](); // Run AI command. - } - else - { - AI_THINKING_STRUCT->score[AI_THINKING_STRUCT->movesetIndex] = 0; - AI_THINKING_STRUCT->aiAction |= AI_ACTION_DONE; - } - if (AI_THINKING_STRUCT->aiAction & AI_ACTION_DONE) - { - AI_THINKING_STRUCT->movesetIndex++; - - if (AI_THINKING_STRUCT->movesetIndex < MAX_MON_MOVES && !(AI_THINKING_STRUCT->aiAction & AI_ACTION_DO_NOT_ATTACK)) - AI_THINKING_STRUCT->aiState = AIState_SettingUp; - else - AI_THINKING_STRUCT->aiState++; - - AI_THINKING_STRUCT->aiAction &= ~(AI_ACTION_DONE); - } - break; - } - } -} - -static void RecordLastUsedMoveByTarget(void) -{ - RecordKnownMove(gBattlerTarget, gLastMoves[gBattlerTarget]); -} - -bool32 IsBattlerAIControlled(u32 battlerId) -{ - switch (GetBattlerPosition(battlerId)) - { - case B_POSITION_PLAYER_LEFT: - default: - return FALSE; - case B_POSITION_OPPONENT_LEFT: - return TRUE; - case B_POSITION_PLAYER_RIGHT: - return ((gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER) != 0); - case B_POSITION_OPPONENT_RIGHT: - return TRUE; - } -} - -void ClearBattlerMoveHistory(u8 battlerId) -{ - memset(BATTLE_HISTORY->usedMoves[battlerId], 0, sizeof(BATTLE_HISTORY->usedMoves[battlerId])); - memset(BATTLE_HISTORY->moveHistory[battlerId], 0, sizeof(BATTLE_HISTORY->moveHistory[battlerId])); - BATTLE_HISTORY->moveHistoryIndex[battlerId] = 0; -} - -void RecordLastUsedMoveBy(u32 battlerId, u32 move) -{ - u8 *index = &BATTLE_HISTORY->moveHistoryIndex[battlerId]; - - if (++(*index) >= AI_MOVE_HISTORY_COUNT) - *index = 0; - BATTLE_HISTORY->moveHistory[battlerId][*index] = move; -} - -void RecordKnownMove(u8 battlerId, u32 move) -{ - s32 i; - for (i = 0; i < MAX_MON_MOVES; i++) - { - if (BATTLE_HISTORY->usedMoves[battlerId][i] == move) - break; - if (BATTLE_HISTORY->usedMoves[battlerId][i] == MOVE_NONE) - { - BATTLE_HISTORY->usedMoves[battlerId][i] = move; - break; - } - } -} - -void RecordAbilityBattle(u8 battlerId, u16 abilityId) -{ - BATTLE_HISTORY->abilities[battlerId] = abilityId; -} - -void ClearBattlerAbilityHistory(u8 battlerId) -{ - BATTLE_HISTORY->abilities[battlerId] = ABILITY_NONE; -} - -void RecordItemEffectBattle(u8 battlerId, u8 itemEffect) -{ - BATTLE_HISTORY->itemEffects[battlerId] = itemEffect; -} - -void ClearBattlerItemEffectHistory(u8 battlerId) -{ - BATTLE_HISTORY->itemEffects[battlerId] = 0; -} - -static void SaveBattlerData(u8 battlerId) -{ - if (!IsBattlerAIControlled(battlerId)) - { - u32 i; - - AI_THINKING_STRUCT->saved[battlerId].ability = gBattleMons[battlerId].ability; - AI_THINKING_STRUCT->saved[battlerId].heldItem = gBattleMons[battlerId].item; - AI_THINKING_STRUCT->saved[battlerId].species = gBattleMons[battlerId].species; - for (i = 0; i < 4; i++) - AI_THINKING_STRUCT->saved[battlerId].moves[i] = gBattleMons[battlerId].moves[i]; - } -} - -static void SetBattlerData(u8 battlerId) -{ - if (!IsBattlerAIControlled(battlerId)) - { - struct Pokemon *illusionMon; - u32 i; - - // Use the known battler's ability. - if (BATTLE_HISTORY->abilities[battlerId] != ABILITY_NONE) - gBattleMons[battlerId].ability = BATTLE_HISTORY->abilities[battlerId]; - // Check if mon can only have one ability. - else if (gBaseStats[gBattleMons[battlerId].species].abilities[1] == ABILITY_NONE - || gBaseStats[gBattleMons[battlerId].species].abilities[1] == gBaseStats[gBattleMons[battlerId].species].abilities[0]) - gBattleMons[battlerId].ability = gBaseStats[gBattleMons[battlerId].species].abilities[0]; - // The ability is unknown. - else - gBattleMons[battlerId].ability = ABILITY_NONE; - - if (BATTLE_HISTORY->itemEffects[battlerId] == 0) - gBattleMons[battlerId].item = 0; - - for (i = 0; i < 4; i++) - { - if (BATTLE_HISTORY->usedMoves[battlerId][i] == 0) - gBattleMons[battlerId].moves[i] = 0; - } - - // Simulate Illusion - if ((illusionMon = GetIllusionMonPtr(battlerId)) != NULL) - gBattleMons[battlerId].species = GetMonData(illusionMon, MON_DATA_SPECIES2); - } -} - -static void RestoreBattlerData(u8 battlerId) -{ - if (!IsBattlerAIControlled(battlerId)) - { - u32 i; - - gBattleMons[battlerId].ability = AI_THINKING_STRUCT->saved[battlerId].ability; - gBattleMons[battlerId].item = AI_THINKING_STRUCT->saved[battlerId].heldItem; - gBattleMons[battlerId].species = AI_THINKING_STRUCT->saved[battlerId].species; - for (i = 0; i < 4; i++) - gBattleMons[battlerId].moves[i] = AI_THINKING_STRUCT->saved[battlerId].moves[i]; - } -} - -static bool32 AI_GetIfCrit(u32 move, u8 battlerAtk, u8 battlerDef) -{ - bool32 isCrit; - - switch (CalcCritChanceStage(battlerAtk, battlerDef, move, FALSE)) - { - case -1: - case 0: - default: - isCrit = FALSE; - break; - case 1: - if (gBattleMoves[move].flags & FLAG_HIGH_CRIT && (Random() % 5 == 0)) - isCrit = TRUE; - else - isCrit = FALSE; - break; - case 2: - if (gBattleMoves[move].flags & FLAG_HIGH_CRIT && (Random() % 2 == 0)) - isCrit = TRUE; - else if (!(gBattleMoves[move].flags & FLAG_HIGH_CRIT) && (Random() % 4) == 0) - isCrit = TRUE; - else - isCrit = FALSE; - break; - case -2: - case 3: - case 4: - isCrit = TRUE; - break; - } - - return isCrit; -} - -s32 AI_CalcDamage(u16 move, u8 battlerAtk, u8 battlerDef) -{ - s32 dmg, moveType; - - SaveBattlerData(battlerAtk); - SaveBattlerData(battlerDef); - - SetBattlerData(battlerAtk); - SetBattlerData(battlerDef); - - gBattleStruct->dynamicMoveType = 0; - SetTypeBeforeUsingMove(move, battlerAtk); - GET_MOVE_TYPE(move, moveType); - dmg = CalculateMoveDamage(move, battlerAtk, battlerDef, moveType, 0, AI_GetIfCrit(move, battlerAtk, battlerDef), FALSE, FALSE); - - RestoreBattlerData(battlerAtk); - RestoreBattlerData(battlerDef); - - return dmg; -} - -s32 AI_CalcPartyMonDamage(u16 move, u8 battlerAtk, u8 battlerDef, struct Pokemon *mon) -{ - s32 dmg; - u32 i; - struct BattlePokemon *battleMons = Alloc(sizeof(struct BattlePokemon) * MAX_BATTLERS_COUNT); - - for (i = 0; i < MAX_BATTLERS_COUNT; i++) - battleMons[i] = gBattleMons[i]; - - PokemonToBattleMon(mon, &gBattleMons[battlerAtk]); - dmg = AI_CalcDamage(move, battlerAtk, battlerDef); - - for (i = 0; i < MAX_BATTLERS_COUNT; i++) - gBattleMons[i] = battleMons[i]; - - Free(battleMons); - - return dmg; -} - -u16 AI_GetTypeEffectiveness(u16 move, u8 battlerAtk, u8 battlerDef) -{ - u16 typeEffectiveness, moveType; - - SaveBattlerData(battlerAtk); - SaveBattlerData(battlerDef); - - SetBattlerData(battlerAtk); - SetBattlerData(battlerDef); - - gBattleStruct->dynamicMoveType = 0; - SetTypeBeforeUsingMove(move, battlerAtk); - GET_MOVE_TYPE(move, moveType); - typeEffectiveness = CalcTypeEffectivenessMultiplier(move, moveType, battlerAtk, battlerDef, FALSE); - - RestoreBattlerData(battlerAtk); - RestoreBattlerData(battlerDef); - - return typeEffectiveness; -} - -static void Cmd_if_random_less_than(void) -{ - u16 random = Random(); - - if (random % 256 < gAIScriptPtr[1]) - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 2); - else - gAIScriptPtr += 6; -} - -static void Cmd_if_random_greater_than(void) -{ - u16 random = Random(); - - if (random % 256 > gAIScriptPtr[1]) - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 2); - else - gAIScriptPtr += 6; -} - -static void Cmd_if_random_equal(void) -{ - u16 random = Random(); - - if (random % 256 == gAIScriptPtr[1]) - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 2); - else - gAIScriptPtr += 6; -} - -static void Cmd_if_random_not_equal(void) -{ - u16 random = Random(); - - if (random % 256 != gAIScriptPtr[1]) - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 2); - else - gAIScriptPtr += 6; -} - -static void Cmd_score(void) -{ - AI_THINKING_STRUCT->score[AI_THINKING_STRUCT->movesetIndex] += gAIScriptPtr[1]; // Add the result to the array of the move consider's score. - - if (AI_THINKING_STRUCT->score[AI_THINKING_STRUCT->movesetIndex] < 0) // If the score is negative, flatten it to 0. - AI_THINKING_STRUCT->score[AI_THINKING_STRUCT->movesetIndex] = 0; - - gAIScriptPtr += 2; // AI return. -} - -static u8 BattleAI_GetWantedBattler(u8 wantedBattler) -{ - switch (wantedBattler) - { - case AI_USER: - return sBattler_AI; - case AI_TARGET: - default: - return gBattlerTarget; - case AI_USER_PARTNER: - return sBattler_AI ^ BIT_FLANK; - case AI_TARGET_PARTNER: - return gBattlerTarget ^ BIT_FLANK; - } -} - -static void Cmd_if_hp_less_than(void) -{ - u16 battlerId = BattleAI_GetWantedBattler(gAIScriptPtr[1]); - - if ((u32)(100 * gBattleMons[battlerId].hp / gBattleMons[battlerId].maxHP) < gAIScriptPtr[2]) - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 3); - else - gAIScriptPtr += 7; -} - -static void Cmd_if_hp_more_than(void) -{ - u16 battlerId = BattleAI_GetWantedBattler(gAIScriptPtr[1]); - - if ((u32)(100 * gBattleMons[battlerId].hp / gBattleMons[battlerId].maxHP) > gAIScriptPtr[2]) - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 3); - else - gAIScriptPtr += 7; -} - -static void Cmd_if_hp_equal(void) -{ - u16 battlerId = BattleAI_GetWantedBattler(gAIScriptPtr[1]); - - if ((u32)(100 * gBattleMons[battlerId].hp / gBattleMons[battlerId].maxHP) == gAIScriptPtr[2]) - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 3); - else - gAIScriptPtr += 7; -} - -static void Cmd_if_hp_not_equal(void) -{ - u16 battlerId = BattleAI_GetWantedBattler(gAIScriptPtr[1]); - - if ((u32)(100 * gBattleMons[battlerId].hp / gBattleMons[battlerId].maxHP) != gAIScriptPtr[2]) - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 3); - else - gAIScriptPtr += 7; -} - -static void Cmd_if_status(void) -{ - u16 battlerId = BattleAI_GetWantedBattler(gAIScriptPtr[1]); - u32 status = T1_READ_32(gAIScriptPtr + 2); - - if (gBattleMons[battlerId].status1 & status) - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 6); - else - gAIScriptPtr += 10; -} - -static void Cmd_if_not_status(void) -{ - u16 battlerId = BattleAI_GetWantedBattler(gAIScriptPtr[1]); - u32 status = T1_READ_32(gAIScriptPtr + 2); - - if (!(gBattleMons[battlerId].status1 & status)) - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 6); - else - gAIScriptPtr += 10; -} - -static void Cmd_if_status2(void) -{ - u16 battlerId = BattleAI_GetWantedBattler(gAIScriptPtr[1]); - u32 status = T1_READ_32(gAIScriptPtr + 2); - - if ((gBattleMons[battlerId].status2 & status)) - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 6); - else - gAIScriptPtr += 10; -} - -static void Cmd_if_not_status2(void) -{ - u16 battlerId = BattleAI_GetWantedBattler(gAIScriptPtr[1]); - u32 status = T1_READ_32(gAIScriptPtr + 2); - - if (!(gBattleMons[battlerId].status2 & status)) - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 6); - else - gAIScriptPtr += 10; -} - -static void Cmd_if_status3(void) -{ - u16 battlerId = BattleAI_GetWantedBattler(gAIScriptPtr[1]); - u32 status = T1_READ_32(gAIScriptPtr + 2); - - if (gStatuses3[battlerId] & status) - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 6); - else - gAIScriptPtr += 10; -} - -static void Cmd_if_not_status3(void) -{ - u16 battlerId = BattleAI_GetWantedBattler(gAIScriptPtr[1]); - u32 status = T1_READ_32(gAIScriptPtr + 2); - - if (!(gStatuses3[battlerId] & status)) - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 6); - else - gAIScriptPtr += 10; -} - -static void Cmd_if_side_affecting(void) -{ - u16 battlerId = BattleAI_GetWantedBattler(gAIScriptPtr[1]); - u32 status = T1_READ_32(gAIScriptPtr + 2); - u32 side = GET_BATTLER_SIDE(battlerId); - - if (gSideStatuses[side] & status) - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 6); - else - gAIScriptPtr += 10; -} - -static void Cmd_if_not_side_affecting(void) -{ - u16 battlerId = BattleAI_GetWantedBattler(gAIScriptPtr[1]); - u32 status = T1_READ_32(gAIScriptPtr + 2); - u32 side = GET_BATTLER_SIDE(battlerId); - - if (!(gSideStatuses[side] & status)) - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 6); - else - gAIScriptPtr += 10; -} - -static void Cmd_if_less_than(void) -{ - if (AI_THINKING_STRUCT->funcResult < gAIScriptPtr[1]) - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 2); - else - gAIScriptPtr += 6; -} - -static void Cmd_if_more_than(void) -{ - if (AI_THINKING_STRUCT->funcResult > gAIScriptPtr[1]) - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 2); - else - gAIScriptPtr += 6; -} - -static void Cmd_if_equal(void) -{ - if (AI_THINKING_STRUCT->funcResult == gAIScriptPtr[1]) - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 2); - else - gAIScriptPtr += 6; -} - -static void Cmd_if_not_equal(void) -{ - if (AI_THINKING_STRUCT->funcResult != gAIScriptPtr[1]) - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 2); - else - gAIScriptPtr += 6; -} - -static void Cmd_if_less_than_ptr(void) -{ - const u8 *value = T1_READ_PTR(gAIScriptPtr + 1); - - if (AI_THINKING_STRUCT->funcResult < *value) - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 5); - else - gAIScriptPtr += 9; -} - -static void Cmd_if_more_than_ptr(void) -{ - const u8 *value = T1_READ_PTR(gAIScriptPtr + 1); - - if (AI_THINKING_STRUCT->funcResult > *value) - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 5); - else - gAIScriptPtr += 9; -} - -static void Cmd_if_equal_ptr(void) -{ - const u8 *value = T1_READ_PTR(gAIScriptPtr + 1); - - if (AI_THINKING_STRUCT->funcResult == *value) - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 5); - else - gAIScriptPtr += 9; -} - -static void Cmd_if_not_equal_ptr(void) -{ - const u8 *value = T1_READ_PTR(gAIScriptPtr + 1); - - if (AI_THINKING_STRUCT->funcResult != *value) - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 5); - else - gAIScriptPtr += 9; -} - -static void Cmd_if_move(void) -{ - u16 move = T1_READ_16(gAIScriptPtr + 1); - - if (AI_THINKING_STRUCT->moveConsidered == move) - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 3); - else - gAIScriptPtr += 7; -} - -static void Cmd_if_not_move(void) -{ - u16 move = T1_READ_16(gAIScriptPtr + 1); - - if (AI_THINKING_STRUCT->moveConsidered != move) - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 3); - else - gAIScriptPtr += 7; -} - -static void Cmd_if_in_bytes(void) -{ - const u8 *ptr = T1_READ_PTR(gAIScriptPtr + 1); - - while (*ptr != 0xFF) - { - if (AI_THINKING_STRUCT->funcResult == *ptr) - { - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 5); - return; - } - ptr++; - } - gAIScriptPtr += 9; -} - -static void Cmd_if_not_in_bytes(void) -{ - const u8 *ptr = T1_READ_PTR(gAIScriptPtr + 1); - - while (*ptr != 0xFF) - { - if (AI_THINKING_STRUCT->funcResult == *ptr) - { - gAIScriptPtr += 9; - return; - } - ptr++; - } - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 5); -} - -static void Cmd_if_in_hwords(void) -{ - const u16 *ptr = (const u16 *)T1_READ_PTR(gAIScriptPtr + 1); - - while (*ptr != 0xFFFF) - { - if (AI_THINKING_STRUCT->funcResult == *ptr) - { - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 5); - return; - } - ptr++; - } - gAIScriptPtr += 9; -} - -static void Cmd_if_not_in_hwords(void) -{ - const u16 *ptr = (const u16 *)T1_READ_PTR(gAIScriptPtr + 1); - - while (*ptr != 0xFFFF) - { - if (AI_THINKING_STRUCT->funcResult == *ptr) - { - gAIScriptPtr += 9; - return; - } - ptr++; - } - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 5); -} - -static void Cmd_if_user_has_attacking_move(void) -{ - s32 i; - - for (i = 0; i < MAX_MON_MOVES; i++) - { - if (gBattleMons[sBattler_AI].moves[i] != 0 - && gBattleMoves[gBattleMons[sBattler_AI].moves[i]].power != 0) - break; - } - - if (i == MAX_MON_MOVES) - gAIScriptPtr += 5; - else - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 1); -} - -static void Cmd_if_user_has_no_attacking_moves(void) -{ - s32 i; - - for (i = 0; i < MAX_MON_MOVES; i++) - { - if (gBattleMons[sBattler_AI].moves[i] != 0 - && gBattleMoves[gBattleMons[sBattler_AI].moves[i]].power != 0) - break; - } - - if (i != MAX_MON_MOVES) - gAIScriptPtr += 5; - else - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 1); -} - -static void Cmd_get_turn_count(void) -{ - AI_THINKING_STRUCT->funcResult = gBattleResults.battleTurnCounter; - gAIScriptPtr += 1; -} - -static void Cmd_get_type(void) -{ - u8 typeVar = gAIScriptPtr[1]; - - switch (typeVar) - { - case AI_TYPE1_USER: // AI user primary type - AI_THINKING_STRUCT->funcResult = gBattleMons[sBattler_AI].type1; - break; - case AI_TYPE1_TARGET: // target primary type - AI_THINKING_STRUCT->funcResult = gBattleMons[gBattlerTarget].type1; - break; - case AI_TYPE2_USER: // AI user secondary type - AI_THINKING_STRUCT->funcResult = gBattleMons[sBattler_AI].type2; - break; - case AI_TYPE2_TARGET: // target secondary type - AI_THINKING_STRUCT->funcResult = gBattleMons[gBattlerTarget].type2; - break; - case AI_TYPE_MOVE: // type of move being pointed to - AI_THINKING_STRUCT->funcResult = gBattleMoves[AI_THINKING_STRUCT->moveConsidered].type; - break; - } - gAIScriptPtr += 2; -} - -static void Cmd_is_of_type(void) -{ - u8 battlerId = BattleAI_GetWantedBattler(gAIScriptPtr[1]); - - if (IS_BATTLER_OF_TYPE(battlerId, gAIScriptPtr[2])) - AI_THINKING_STRUCT->funcResult = TRUE; - else - AI_THINKING_STRUCT->funcResult = FALSE; - - gAIScriptPtr += 3; -} - -static void Cmd_get_considered_move_power(void) -{ - AI_THINKING_STRUCT->funcResult = gBattleMoves[AI_THINKING_STRUCT->moveConsidered].power; - gAIScriptPtr += 1; -} - -// Checks if one of the moves has side effects or perks -static u32 WhichMoveBetter(u32 move1, u32 move2) -{ - s32 defAbility = AI_GetAbility(gBattlerTarget, FALSE); - - // Check if physical moves hurt. - if (GetBattlerHoldEffect(sBattler_AI, TRUE) != HOLD_EFFECT_PROTECTIVE_PADS - && (BATTLE_HISTORY->itemEffects[gBattlerTarget] == HOLD_EFFECT_ROCKY_HELMET - || defAbility == ABILITY_IRON_BARBS || defAbility == ABILITY_ROUGH_SKIN)) - { - if (IS_MOVE_PHYSICAL(move1) && !IS_MOVE_PHYSICAL(move2)) - return 1; - if (IS_MOVE_PHYSICAL(move2) && !IS_MOVE_PHYSICAL(move1)) - return 0; - } - // Check recoil - if (GetBattlerAbility(sBattler_AI) != ABILITY_ROCK_HEAD) - { - if (((gBattleMoves[move1].effect == EFFECT_RECOIL_25 - || gBattleMoves[move1].effect == EFFECT_RECOIL_IF_MISS - || gBattleMoves[move1].effect == EFFECT_RECOIL_50 - || gBattleMoves[move1].effect == EFFECT_RECOIL_33 - || gBattleMoves[move1].effect == EFFECT_RECOIL_33_STATUS) - && (gBattleMoves[move2].effect != EFFECT_RECOIL_25 - && gBattleMoves[move2].effect != EFFECT_RECOIL_IF_MISS - && gBattleMoves[move2].effect != EFFECT_RECOIL_50 - && gBattleMoves[move2].effect != EFFECT_RECOIL_33 - && gBattleMoves[move2].effect != EFFECT_RECOIL_33_STATUS - && gBattleMoves[move2].effect != EFFECT_RECHARGE))) - return 1; - - if (((gBattleMoves[move2].effect == EFFECT_RECOIL_25 - || gBattleMoves[move2].effect == EFFECT_RECOIL_IF_MISS - || gBattleMoves[move2].effect == EFFECT_RECOIL_50 - || gBattleMoves[move2].effect == EFFECT_RECOIL_33 - || gBattleMoves[move2].effect == EFFECT_RECOIL_33_STATUS) - && (gBattleMoves[move1].effect != EFFECT_RECOIL_25 - && gBattleMoves[move1].effect != EFFECT_RECOIL_IF_MISS - && gBattleMoves[move1].effect != EFFECT_RECOIL_50 - && gBattleMoves[move1].effect != EFFECT_RECOIL_33 - && gBattleMoves[move1].effect != EFFECT_RECOIL_33_STATUS - && gBattleMoves[move1].effect != EFFECT_RECHARGE))) - return 0; - } - // Check recharge - if (gBattleMoves[move1].effect == EFFECT_RECHARGE && gBattleMoves[move2].effect != EFFECT_RECHARGE) - return 1; - if (gBattleMoves[move2].effect == EFFECT_RECHARGE && gBattleMoves[move1].effect != EFFECT_RECHARGE) - return 0; - // Check additional effect. - if (gBattleMoves[move1].effect == 0 && gBattleMoves[move2].effect != 0) - return 1; - if (gBattleMoves[move2].effect == 0 && gBattleMoves[move1].effect != 0) - return 0; - - return 2; -} - -static void Cmd_get_how_powerful_move_is(void) -{ - s32 i, checkedMove, bestId, currId, hp; - s32 moveDmgs[MAX_MON_MOVES]; - - for (i = 0; sDiscouragedPowerfulMoveEffects[i] != 0xFFFF; i++) - { - if (gBattleMoves[AI_THINKING_STRUCT->moveConsidered].effect == sDiscouragedPowerfulMoveEffects[i]) - break; - } - - if (gBattleMoves[AI_THINKING_STRUCT->moveConsidered].power != 0 - && sDiscouragedPowerfulMoveEffects[i] == 0xFFFF) - { - for (checkedMove = 0; checkedMove < MAX_MON_MOVES; checkedMove++) - { - for (i = 0; sDiscouragedPowerfulMoveEffects[i] != 0xFFFF; i++) - { - if (gBattleMoves[gBattleMons[sBattler_AI].moves[checkedMove]].effect == sDiscouragedPowerfulMoveEffects[i]) - break; - } - - if (gBattleMons[sBattler_AI].moves[checkedMove] != MOVE_NONE - && sDiscouragedPowerfulMoveEffects[i] == 0xFFFF - && gBattleMoves[gBattleMons[sBattler_AI].moves[checkedMove]].power != 0) - { - moveDmgs[checkedMove] = AI_THINKING_STRUCT->simulatedDmg[sBattler_AI][gBattlerTarget][checkedMove]; - } - else - { - moveDmgs[checkedMove] = 0; - } - } - - hp = gBattleMons[gBattlerTarget].hp + (20 * gBattleMons[gBattlerTarget].hp / 100); // 20 % add to make sure the battler is always fainted - // If a move can faint battler, it doesn't matter how much damage it does - for (i = 0; i < MAX_MON_MOVES; i++) - { - if (moveDmgs[i] > hp) - moveDmgs[i] = hp; - } - - for (bestId = 0, i = 1; i < MAX_MON_MOVES; i++) - { - if (moveDmgs[i] > moveDmgs[bestId]) - bestId = i; - if (moveDmgs[i] == moveDmgs[bestId]) - { - switch (WhichMoveBetter(gBattleMons[sBattler_AI].moves[bestId], gBattleMons[sBattler_AI].moves[i])) - { - case 2: - if (Random() & 1) - break; - case 1: - bestId = i; - break; - } - } - } - - currId = AI_THINKING_STRUCT->movesetIndex; - if (currId == bestId) - AI_THINKING_STRUCT->funcResult = MOVE_POWER_BEST; - // Compare percentage difference. - else if ((moveDmgs[currId] >= hp || moveDmgs[bestId] < hp) // If current move can faint as well, or if neither can - && (moveDmgs[bestId] * 100 / hp) - (moveDmgs[currId] * 100 / hp) <= 30 - && WhichMoveBetter(gBattleMons[sBattler_AI].moves[bestId], gBattleMons[sBattler_AI].moves[currId]) != 0) - AI_THINKING_STRUCT->funcResult = MOVE_POWER_GOOD; - else - AI_THINKING_STRUCT->funcResult = MOVE_POWER_WEAK; - } - else - { - AI_THINKING_STRUCT->funcResult = MOVE_POWER_DISCOURAGED; // Highly discouraged in terms of power. - } - - gAIScriptPtr++; -} - -static void Cmd_get_last_used_battler_move(void) -{ - AI_THINKING_STRUCT->funcResult = gLastMoves[BattleAI_GetWantedBattler(gAIScriptPtr[1])]; - gAIScriptPtr += 2; -} - -static void Cmd_if_equal_u32(void) -{ - if (T1_READ_32(&gAIScriptPtr[1]) == AI_THINKING_STRUCT->funcResult) - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 5); - else - gAIScriptPtr += 9; -} - -static void Cmd_if_not_equal_u32(void) -{ - if (T1_READ_32(&gAIScriptPtr[1]) != AI_THINKING_STRUCT->funcResult) - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 5); - else - gAIScriptPtr += 9; -} - -static void Cmd_if_user_goes(void) -{ - u32 fasterAI = 0, fasterPlayer = 0, i; - s8 prioAI, prioPlayer; - - // Check move priorities first. - prioAI = GetMovePriority(sBattler_AI, AI_THINKING_STRUCT->moveConsidered); - SaveBattlerData(gBattlerTarget); - SetBattlerData(gBattlerTarget); - for (i = 0; i < MAX_MON_MOVES; i++) - { - if (gBattleMons[gBattlerTarget].moves[i] == 0 || gBattleMons[gBattlerTarget].moves[i] == 0xFFFF) - continue; - - prioPlayer = GetMovePriority(gBattlerTarget, gBattleMons[gBattlerTarget].moves[i]); - if (prioAI > prioPlayer) - fasterAI++; - else if (prioPlayer > prioAI) - fasterPlayer++; - } - RestoreBattlerData(gBattlerTarget); - - if (fasterAI > fasterPlayer) - { - if (gAIScriptPtr[1] == 0) - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 2); - else - gAIScriptPtr += 6; - } - else if (fasterAI < fasterPlayer) - { - if (gAIScriptPtr[1] == 1) - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 2); - else - gAIScriptPtr += 6; - } - else - { - // Priorities are the same(at least comparing to moves the AI is aware of), decide by speed. - if (GetWhoStrikesFirst(sBattler_AI, gBattlerTarget, TRUE) == gAIScriptPtr[1]) - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 2); - else - gAIScriptPtr += 6; - } -} - -static void Cmd_nop_2A(void) -{ -} - -static void Cmd_nop_2B(void) -{ -} - -static s32 CountUsablePartyMons(u8 battlerId) -{ - s32 battlerOnField1, battlerOnField2, i, ret; - struct Pokemon *party; - - if (GetBattlerSide(battlerId) == B_SIDE_PLAYER) - party = gPlayerParty; - else - party = gEnemyParty; - - if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) - { - battlerOnField1 = gBattlerPartyIndexes[battlerId]; - battlerOnField2 = gBattlerPartyIndexes[GetBattlerAtPosition(GetBattlerPosition(battlerId) ^ BIT_FLANK)]; - } - else // In singles there's only one battlerId by side. - { - battlerOnField1 = gBattlerPartyIndexes[battlerId]; - battlerOnField2 = gBattlerPartyIndexes[battlerId]; - } - - ret = 0; - for (i = 0; i < PARTY_SIZE; i++) - { - if (i != battlerOnField1 && i != battlerOnField2 - && GetMonData(&party[i], MON_DATA_HP) != 0 - && GetMonData(&party[i], MON_DATA_SPECIES2) != SPECIES_NONE - && GetMonData(&party[i], MON_DATA_SPECIES2) != SPECIES_EGG) - { - ret++; - } - } - - return ret; -} - -static void Cmd_count_usable_party_mons(void) -{ - AI_THINKING_STRUCT->funcResult = CountUsablePartyMons(BattleAI_GetWantedBattler(gAIScriptPtr[1])); - gAIScriptPtr += 2; -} - -static void Cmd_get_considered_move(void) -{ - AI_THINKING_STRUCT->funcResult = AI_THINKING_STRUCT->moveConsidered; - gAIScriptPtr += 1; -} - -static void Cmd_get_considered_move_effect(void) -{ - AI_THINKING_STRUCT->funcResult = gBattleMoves[AI_THINKING_STRUCT->moveConsidered].effect; - gAIScriptPtr += 1; -} - -static s32 AI_GetAbility(u32 battlerId, bool32 guess) -{ - // The AI knows its own ability. - if (IsBattlerAIControlled(battlerId)) - return gBattleMons[battlerId].ability; - - if (BATTLE_HISTORY->abilities[battlerId] != 0) - return BATTLE_HISTORY->abilities[battlerId]; - - // Abilities that prevent fleeing. - if (gBattleMons[battlerId].ability == ABILITY_SHADOW_TAG - || gBattleMons[battlerId].ability == ABILITY_MAGNET_PULL - || gBattleMons[battlerId].ability == ABILITY_ARENA_TRAP) - return gBattleMons[battlerId].ability; - - if (gBaseStats[gBattleMons[battlerId].species].abilities[0] != ABILITY_NONE) - { - if (gBaseStats[gBattleMons[battlerId].species].abilities[1] != ABILITY_NONE) - { - // AI has no knowledge of opponent, so it guesses which ability. - if (guess) - return gBaseStats[gBattleMons[battlerId].species].abilities[Random() & 1]; - } - else - { - return gBaseStats[gBattleMons[battlerId].species].abilities[0]; // It's definitely ability 1. - } - } - return -1; // Unknown. -} - -static void Cmd_get_ability(void) -{ - AI_THINKING_STRUCT->funcResult = AI_GetAbility(BattleAI_GetWantedBattler(gAIScriptPtr[1]), TRUE); - gAIScriptPtr += 2; -} - -static void Cmd_check_ability(void) -{ - u32 battlerId = BattleAI_GetWantedBattler(gAIScriptPtr[1]); - u32 ability = AI_GetAbility(battlerId, FALSE); - - if (ability == -1) - AI_THINKING_STRUCT->funcResult = 2; // Unable to answer. - else if (ability == gAIScriptPtr[2]) - AI_THINKING_STRUCT->funcResult = 1; // Pokemon has the ability we wanted to check. - else - AI_THINKING_STRUCT->funcResult = 0; // Pokemon doesn't have the ability we wanted to check. - - gAIScriptPtr += 3; -} - -static void Cmd_get_highest_type_effectiveness(void) -{ - s32 i; - - gMoveResultFlags = 0; - AI_THINKING_STRUCT->funcResult = 0; - for (i = 0; i < MAX_MON_MOVES; i++) - { - gCurrentMove = gBattleMons[sBattler_AI].moves[i]; - if (gCurrentMove != MOVE_NONE) - { - u32 effectivenessMultiplier = AI_GetTypeEffectiveness(gCurrentMove, sBattler_AI, gBattlerTarget); - - switch (effectivenessMultiplier) - { - case UQ_4_12(0.0): - default: - gBattleMoveDamage = AI_EFFECTIVENESS_x0; - break; - case UQ_4_12(0.25): - gBattleMoveDamage = AI_EFFECTIVENESS_x0_25; - break; - case UQ_4_12(0.5): - gBattleMoveDamage = AI_EFFECTIVENESS_x0_5; - break; - case UQ_4_12(1.0): - gBattleMoveDamage = AI_EFFECTIVENESS_x1; - break; - case UQ_4_12(2.0): - gBattleMoveDamage = AI_EFFECTIVENESS_x2; - break; - case UQ_4_12(4.0): - gBattleMoveDamage = AI_EFFECTIVENESS_x4; - break; - } - - if (AI_THINKING_STRUCT->funcResult < gBattleMoveDamage) - AI_THINKING_STRUCT->funcResult = gBattleMoveDamage; - } - } - - gAIScriptPtr += 1; -} - -static void Cmd_if_type_effectiveness(void) -{ - u8 damageVar; - u32 effectivenessMultiplier; - - gMoveResultFlags = 0; - gCurrentMove = AI_THINKING_STRUCT->moveConsidered; - effectivenessMultiplier = AI_GetTypeEffectiveness(gCurrentMove, sBattler_AI, gBattlerTarget); - switch (effectivenessMultiplier) - { - case UQ_4_12(0.0): - default: - damageVar = AI_EFFECTIVENESS_x0; - break; - case UQ_4_12(0.25): - damageVar = AI_EFFECTIVENESS_x0_25; - break; - case UQ_4_12(0.5): - damageVar = AI_EFFECTIVENESS_x0_5; - break; - case UQ_4_12(1.0): - damageVar = AI_EFFECTIVENESS_x1; - break; - case UQ_4_12(2.0): - damageVar = AI_EFFECTIVENESS_x2; - break; - case UQ_4_12(4.0): - damageVar = AI_EFFECTIVENESS_x4; - break; - } - - if (damageVar == gAIScriptPtr[1]) - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 2); - else - gAIScriptPtr += 6; -} - -static void Cmd_nop_32(void) -{ -} - -static void Cmd_nop_33(void) -{ -} - -static void Cmd_if_status_in_party(void) -{ - struct Pokemon *party; - s32 i; - u32 statusToCompareTo; - u8 battlerId = BattleAI_GetWantedBattler(gAIScriptPtr[1]); - - party = (GetBattlerSide(battlerId) == B_SIDE_PLAYER) ? gPlayerParty : gEnemyParty; - - statusToCompareTo = T1_READ_32(gAIScriptPtr + 2); - - for (i = 0; i < PARTY_SIZE; i++) - { - u16 species = GetMonData(&party[i], MON_DATA_SPECIES); - u16 hp = GetMonData(&party[i], MON_DATA_HP); - u32 status = GetMonData(&party[i], MON_DATA_STATUS); - - if (species != SPECIES_NONE && species != SPECIES_EGG && hp != 0 && status == statusToCompareTo) - { - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 6); - return; - } - } - - gAIScriptPtr += 10; -} - -static void Cmd_if_status_not_in_party(void) -{ - struct Pokemon *party; - s32 i; - u32 statusToCompareTo; - u8 battlerId = BattleAI_GetWantedBattler(gAIScriptPtr[1]); - - party = (GetBattlerSide(battlerId) == B_SIDE_PLAYER) ? gPlayerParty : gEnemyParty; - - statusToCompareTo = T1_READ_32(gAIScriptPtr + 2); - - for (i = 0; i < PARTY_SIZE; i++) - { - u16 species = GetMonData(&party[i], MON_DATA_SPECIES); - u16 hp = GetMonData(&party[i], MON_DATA_HP); - u32 status = GetMonData(&party[i], MON_DATA_STATUS); - - if (species != SPECIES_NONE && species != SPECIES_EGG && hp != 0 && status == statusToCompareTo) - { - gAIScriptPtr += 10; - return; - } - } - - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 6); -} - -static void Cmd_get_weather(void) -{ - if (gBattleWeather & WEATHER_RAIN_ANY) - AI_THINKING_STRUCT->funcResult = AI_WEATHER_RAIN; - else if (gBattleWeather & WEATHER_SANDSTORM_ANY) - AI_THINKING_STRUCT->funcResult = AI_WEATHER_SANDSTORM; - else if (gBattleWeather & WEATHER_SUN_ANY) - AI_THINKING_STRUCT->funcResult = AI_WEATHER_SUN; - else if (gBattleWeather & WEATHER_HAIL_ANY) - AI_THINKING_STRUCT->funcResult = AI_WEATHER_HAIL; - else - AI_THINKING_STRUCT->funcResult = AI_WEATHER_NONE; - - gAIScriptPtr += 1; -} - -static void Cmd_if_effect(void) -{ - if (gBattleMoves[AI_THINKING_STRUCT->moveConsidered].effect == T1_READ_16(gAIScriptPtr + 1)) - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 3); - else - gAIScriptPtr += 7; -} - -static void Cmd_if_not_effect(void) -{ - if (gBattleMoves[AI_THINKING_STRUCT->moveConsidered].effect != T1_READ_16(gAIScriptPtr + 1)) - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 3); - else - gAIScriptPtr += 7; -} - -static void Cmd_if_stat_level_less_than(void) -{ - u32 battlerId; - - if (gAIScriptPtr[1] == AI_USER) - battlerId = sBattler_AI; - else - battlerId = gBattlerTarget; - - if (gBattleMons[battlerId].statStages[gAIScriptPtr[2]] < gAIScriptPtr[3]) - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 4); - else - gAIScriptPtr += 8; -} - -static void Cmd_if_stat_level_more_than(void) -{ - u32 battlerId; - - if (gAIScriptPtr[1] == AI_USER) - battlerId = sBattler_AI; - else - battlerId = gBattlerTarget; - - if (gBattleMons[battlerId].statStages[gAIScriptPtr[2]] > gAIScriptPtr[3]) - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 4); - else - gAIScriptPtr += 8; -} - -static void Cmd_if_stat_level_equal(void) -{ - u32 battlerId; - - if (gAIScriptPtr[1] == AI_USER) - battlerId = sBattler_AI; - else - battlerId = gBattlerTarget; - - if (gBattleMons[battlerId].statStages[gAIScriptPtr[2]] == gAIScriptPtr[3]) - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 4); - else - gAIScriptPtr += 8; -} - -static void Cmd_if_stat_level_not_equal(void) -{ - u32 battlerId; - - if (gAIScriptPtr[1] == AI_USER) - battlerId = sBattler_AI; - else - battlerId = gBattlerTarget; - - if (gBattleMons[battlerId].statStages[gAIScriptPtr[2]] != gAIScriptPtr[3]) - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 4); - else - gAIScriptPtr += 8; -} - -static void Cmd_if_can_faint(void) -{ - s32 dmg; - - if (gBattleMoves[AI_THINKING_STRUCT->moveConsidered].power == 0) - { - gAIScriptPtr += 5; - return; - } - - dmg = AI_THINKING_STRUCT->simulatedDmg[sBattler_AI][gBattlerTarget][AI_THINKING_STRUCT->movesetIndex]; - if (gBattleMons[gBattlerTarget].hp <= dmg) - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 1); - else - gAIScriptPtr += 5; -} - -static void Cmd_if_cant_faint(void) -{ - s32 dmg; - - if (gBattleMoves[AI_THINKING_STRUCT->moveConsidered].power < 2) - { - gAIScriptPtr += 5; - return; - } - - dmg = AI_THINKING_STRUCT->simulatedDmg[sBattler_AI][gBattlerTarget][AI_THINKING_STRUCT->movesetIndex]; - if (gBattleMons[gBattlerTarget].hp > dmg) - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 1); - else - gAIScriptPtr += 5; -} - -static void Cmd_if_has_move(void) -{ - s32 i; - const u16 *movePtr = (u16 *)(gAIScriptPtr + 2); - - switch (gAIScriptPtr[1]) - { - case AI_USER: - for (i = 0; i < MAX_MON_MOVES; i++) - { - if (gBattleMons[sBattler_AI].moves[i] == *movePtr) - break; - } - if (i == MAX_MON_MOVES) - gAIScriptPtr += 8; - else - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 4); - break; - case AI_USER_PARTNER: - if (gBattleMons[sBattler_AI ^ BIT_FLANK].hp == 0) - { - gAIScriptPtr += 8; - break; - } - else - { - for (i = 0; i < MAX_MON_MOVES; i++) - { - if (gBattleMons[sBattler_AI ^ BIT_FLANK].moves[i] == *movePtr) - break; - } - } - if (i == MAX_MON_MOVES) - gAIScriptPtr += 8; - else - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 4); - break; - case AI_TARGET: - case AI_TARGET_PARTNER: - for (i = 0; i < MAX_MON_MOVES; i++) - { - if (BATTLE_HISTORY->usedMoves[gBattlerTarget][i] == *movePtr) - break; - } - if (i == MAX_MON_MOVES) - gAIScriptPtr += 8; - else - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 4); - break; - } -} - -static void Cmd_if_doesnt_have_move(void) -{ - s32 i; - const u16 *movePtr = (u16 *)(gAIScriptPtr + 2); - - switch(gAIScriptPtr[1]) - { - case AI_USER: - case AI_USER_PARTNER: // UB: no separate check for user partner. - for (i = 0; i < MAX_MON_MOVES; i++) - { - if (gBattleMons[sBattler_AI].moves[i] == *movePtr) - break; - } - if (i != MAX_MON_MOVES) - gAIScriptPtr += 8; - else - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 4); - break; - case AI_TARGET: - case AI_TARGET_PARTNER: - for (i = 0; i < MAX_MON_MOVES; i++) - { - if (BATTLE_HISTORY->usedMoves[gBattlerTarget][i] == *movePtr) - break; - } - if (i != MAX_MON_MOVES) - gAIScriptPtr += 8; - else - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 4); - break; - } -} - -static void Cmd_if_has_move_with_effect(void) -{ - s32 i; - - switch (gAIScriptPtr[1]) - { - case AI_USER: - case AI_USER_PARTNER: - for (i = 0; i < MAX_MON_MOVES; i++) - { - if (gBattleMons[sBattler_AI].moves[i] != 0 && gBattleMoves[gBattleMons[sBattler_AI].moves[i]].effect == gAIScriptPtr[2]) - break; - } - if (i == MAX_MON_MOVES) - gAIScriptPtr += 7; - else - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 3); - break; - case AI_TARGET: - case AI_TARGET_PARTNER: - for (i = 0; i < MAX_MON_MOVES; i++) - { - if (gBattleMons[gBattlerTarget].moves[i] != 0 && gBattleMoves[BATTLE_HISTORY->usedMoves[gBattlerTarget][i]].effect == gAIScriptPtr[2]) - break; - } - if (i == MAX_MON_MOVES) - gAIScriptPtr += 7; - else - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 3); - break; - } -} - -static void Cmd_if_doesnt_have_move_with_effect(void) -{ - s32 i; - - switch (gAIScriptPtr[1]) - { - case AI_USER: - case AI_USER_PARTNER: - for (i = 0; i < MAX_MON_MOVES; i++) - { - if(gBattleMons[sBattler_AI].moves[i] != 0 && gBattleMoves[gBattleMons[sBattler_AI].moves[i]].effect == gAIScriptPtr[2]) - break; - } - if (i != MAX_MON_MOVES) - gAIScriptPtr += 7; - else - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 3); - break; - case AI_TARGET: - case AI_TARGET_PARTNER: - for (i = 0; i < MAX_MON_MOVES; i++) - { - if (BATTLE_HISTORY->usedMoves[gBattlerTarget][i] && gBattleMoves[BATTLE_HISTORY->usedMoves[gBattlerTarget][i]].effect == gAIScriptPtr[2]) - break; - } - if (i != MAX_MON_MOVES) - gAIScriptPtr += 7; - else - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 3); - break; - } -} - -static void Cmd_if_any_move_disabled_or_encored(void) -{ - u8 battlerId; - - if (gAIScriptPtr[1] == AI_USER) - battlerId = sBattler_AI; - else - battlerId = gBattlerTarget; - - if (gAIScriptPtr[2] == 0) - { - if (gDisableStructs[battlerId].disabledMove == MOVE_NONE) - gAIScriptPtr += 7; - else - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 3); - } - else if (gAIScriptPtr[2] != 1) - { - gAIScriptPtr += 7; - } - else - { - if (gDisableStructs[battlerId].encoredMove != MOVE_NONE) - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 3); - else - gAIScriptPtr += 7; - } -} - -static void Cmd_if_curr_move_disabled_or_encored(void) -{ - switch (gAIScriptPtr[1]) - { - case 0: - if (gDisableStructs[gActiveBattler].disabledMove == AI_THINKING_STRUCT->moveConsidered) - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 2); - else - gAIScriptPtr += 6; - break; - case 1: - if (gDisableStructs[gActiveBattler].encoredMove == AI_THINKING_STRUCT->moveConsidered) - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 2); - else - gAIScriptPtr += 6; - break; - default: - gAIScriptPtr += 6; - break; - } -} - -static void Cmd_flee(void) -{ - AI_THINKING_STRUCT->aiAction |= (AI_ACTION_DONE | AI_ACTION_FLEE | AI_ACTION_DO_NOT_ATTACK); -} - -static void Cmd_if_random_safari_flee(void) -{ - u8 safariFleeRate = gBattleStruct->safariEscapeFactor * 5; // Safari flee rate, from 0-20. - - if ((u8)(Random() % 100) < safariFleeRate) - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 1); - else - gAIScriptPtr += 5; -} - -static void Cmd_watch(void) -{ - AI_THINKING_STRUCT->aiAction |= (AI_ACTION_DONE | AI_ACTION_WATCH | AI_ACTION_DO_NOT_ATTACK); -} - -static void Cmd_get_hold_effect(void) -{ - u32 battlerId = BattleAI_GetWantedBattler(gAIScriptPtr[1]); - - if (!IsBattlerAIControlled(battlerId)) - AI_THINKING_STRUCT->funcResult = BATTLE_HISTORY->itemEffects[battlerId]; - else - AI_THINKING_STRUCT->funcResult = GetBattlerHoldEffect(battlerId, FALSE); - - gAIScriptPtr += 2; -} - -static void Cmd_if_holds_item(void) -{ - u8 battlerId = BattleAI_GetWantedBattler(gAIScriptPtr[1]); - u16 item; - - if ((battlerId & BIT_SIDE) == (sBattler_AI & BIT_SIDE)) - item = gBattleMons[battlerId].item; - else - item = BATTLE_HISTORY->itemEffects[battlerId]; - - if (T1_READ_16(gAIScriptPtr + 2) == item) - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 4); - else - gAIScriptPtr += 8; -} - -static void Cmd_get_gender(void) -{ - u8 battlerId; - - if (gAIScriptPtr[1] == AI_USER) - battlerId = sBattler_AI; - else - battlerId = gBattlerTarget; - - AI_THINKING_STRUCT->funcResult = GetGenderFromSpeciesAndPersonality(gBattleMons[battlerId].species, gBattleMons[battlerId].personality); - - gAIScriptPtr += 2; -} - -static void Cmd_is_first_turn_for(void) -{ - u8 battlerId; - - if (gAIScriptPtr[1] == AI_USER) - battlerId = sBattler_AI; - else - battlerId = gBattlerTarget; - - AI_THINKING_STRUCT->funcResult = gDisableStructs[battlerId].isFirstTurn; - - gAIScriptPtr += 2; -} - -static void Cmd_get_stockpile_count(void) -{ - u8 battlerId; - - if (gAIScriptPtr[1] == AI_USER) - battlerId = sBattler_AI; - else - battlerId = gBattlerTarget; - - AI_THINKING_STRUCT->funcResult = gDisableStructs[battlerId].stockpileCounter; - - gAIScriptPtr += 2; -} - -static void Cmd_is_double_battle(void) -{ - AI_THINKING_STRUCT->funcResult = gBattleTypeFlags & BATTLE_TYPE_DOUBLE; - - gAIScriptPtr += 1; -} - -static void Cmd_get_used_held_item(void) -{ - u8 battlerId; - - if (gAIScriptPtr[1] == AI_USER) - battlerId = sBattler_AI; - else - battlerId = gBattlerTarget; - - AI_THINKING_STRUCT->funcResult = gBattleStruct->usedHeldItems[battlerId]; - - gAIScriptPtr += 2; -} - -static void Cmd_get_move_type_from_result(void) -{ - AI_THINKING_STRUCT->funcResult = gBattleMoves[AI_THINKING_STRUCT->funcResult].type; - - gAIScriptPtr += 1; -} - -static void Cmd_get_move_power_from_result(void) -{ - AI_THINKING_STRUCT->funcResult = gBattleMoves[AI_THINKING_STRUCT->funcResult].power; - - gAIScriptPtr += 1; -} - -static void Cmd_get_move_effect_from_result(void) -{ - AI_THINKING_STRUCT->funcResult = gBattleMoves[AI_THINKING_STRUCT->funcResult].effect; - - gAIScriptPtr += 1; -} - -static void Cmd_get_protect_count(void) -{ - u8 battlerId; - - if (gAIScriptPtr[1] == AI_USER) - battlerId = sBattler_AI; - else - battlerId = gBattlerTarget; - - AI_THINKING_STRUCT->funcResult = gDisableStructs[battlerId].protectUses; - - gAIScriptPtr += 2; -} - -static void Cmd_if_move_flag(void) -{ - u32 flag = T1_READ_32(gAIScriptPtr + 1); - - if (gBattleMoves[AI_THINKING_STRUCT->moveConsidered].flags & flag) - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 5); - else - gAIScriptPtr += 9; -} - -static void Cmd_if_field_status(void) -{ - u32 fieldFlags = T1_READ_32(gAIScriptPtr + 1); - - if (gFieldStatuses & fieldFlags) - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 5); - else - gAIScriptPtr += 9; -} - -static void Cmd_get_move_accuracy(void) -{ - AI_THINKING_STRUCT->funcResult = gBattleMoves[AI_THINKING_STRUCT->moveConsidered].accuracy; - - gAIScriptPtr++; -} - -static void Cmd_call_if_eq(void) -{ - if (AI_THINKING_STRUCT->funcResult == T1_READ_16(gAIScriptPtr + 1)) - { - AIStackPushVar(gAIScriptPtr + 7); - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 3); - } - else - { - gAIScriptPtr += 7; - } -} - -static void Cmd_call_if_move_flag(void) -{ - u32 flag = T1_READ_32(gAIScriptPtr + 1); - - if (gBattleMoves[AI_THINKING_STRUCT->moveConsidered].flags & flag) - { - AIStackPushVar(gAIScriptPtr + 9); - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 5); - } - else - { - gAIScriptPtr += 9; - } -} - -static void Cmd_nop_57(void) -{ -} - -static void Cmd_call(void) -{ - AIStackPushVar(gAIScriptPtr + 5); - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 1); -} - -static void Cmd_goto(void) -{ - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 1); -} - -static void Cmd_end(void) -{ - if (AIStackPop() == 0) - AI_THINKING_STRUCT->aiAction |= AI_ACTION_DONE; -} - -static void Cmd_if_level_cond(void) -{ - switch (gAIScriptPtr[1]) - { - case 0: // greater than - if (gBattleMons[sBattler_AI].level > gBattleMons[gBattlerTarget].level) - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 2); - else - gAIScriptPtr += 6; - break; - case 1: // less than - if (gBattleMons[sBattler_AI].level < gBattleMons[gBattlerTarget].level) - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 2); - else - gAIScriptPtr += 6; - break; - case 2: // equal - if (gBattleMons[sBattler_AI].level == gBattleMons[gBattlerTarget].level) - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 2); - else - gAIScriptPtr += 6; - break; - } -} - -static void Cmd_if_target_taunted(void) -{ - if (gDisableStructs[gBattlerTarget].tauntTimer != 0) - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 1); - else - gAIScriptPtr += 5; -} - -static void Cmd_if_target_not_taunted(void) -{ - if (gDisableStructs[gBattlerTarget].tauntTimer == 0) - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 1); - else - gAIScriptPtr += 5; -} - -static void Cmd_if_target_is_ally(void) -{ - if ((sBattler_AI & BIT_SIDE) == (gBattlerTarget & BIT_SIDE)) - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 1); - else - gAIScriptPtr += 5; -} - -static void Cmd_if_flash_fired(void) -{ - u8 battlerId = BattleAI_GetWantedBattler(gAIScriptPtr[1]); - - if (gBattleResources->flags->flags[battlerId] & RESOURCE_FLAG_FLASH_FIRE) - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 2); - else - gAIScriptPtr += 6; -} - -static void AIStackPushVar(const u8 *var) -{ - gBattleResources->AI_ScriptsStack->ptr[gBattleResources->AI_ScriptsStack->size++] = var; -} - -static void AIStackPushVar_cursor(void) -{ - gBattleResources->AI_ScriptsStack->ptr[gBattleResources->AI_ScriptsStack->size++] = gAIScriptPtr; -} - -static bool8 AIStackPop(void) -{ - if (gBattleResources->AI_ScriptsStack->size != 0) - { - --gBattleResources->AI_ScriptsStack->size; - gAIScriptPtr = gBattleResources->AI_ScriptsStack->ptr[gBattleResources->AI_ScriptsStack->size]; - return TRUE; - } - else - { - return FALSE; - } -} - -static void Cmd_get_ally_chosen_move(void) -{ - u8 partnerBattler = BATTLE_PARTNER(sBattler_AI); - if (!IsBattlerAlive(partnerBattler) || !IsBattlerAIControlled(partnerBattler)) - AI_THINKING_STRUCT->funcResult = 0; - else if (partnerBattler > sBattler_AI) // Battler with the lower id chooses the move first. - AI_THINKING_STRUCT->funcResult = 0; - else - AI_THINKING_STRUCT->funcResult = gBattleMons[partnerBattler].moves[gBattleStruct->chosenMovePositions[partnerBattler]]; - - gAIScriptPtr++; -} - -static void Cmd_if_has_no_attacking_moves(void) -{ - s32 i; - u8 battlerId = BattleAI_GetWantedBattler(gAIScriptPtr[1]); - if (IsBattlerAIControlled(battlerId)) - { - for (i = 0; i < 4; i++) - { - if (gBattleMons[battlerId].moves[i] != 0 && gBattleMoves[gBattleMons[battlerId].moves[i]].power != 0) - break; - } - } - else - { - for (i = 0; i < 4; i++) - { - if (BATTLE_HISTORY->usedMoves[battlerId][i] != 0 && gBattleMoves[BATTLE_HISTORY->usedMoves[battlerId][i]].power != 0) - break; - } - } - - if (i == 4) - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 2); - else - gAIScriptPtr += 6; -} - -static void Cmd_get_hazards_count(void) -{ - u8 battlerId = BattleAI_GetWantedBattler(gAIScriptPtr[1]); - u8 side = GetBattlerSide(battlerId); - - switch (T1_READ_16(gAIScriptPtr + 2)) - { - case EFFECT_SPIKES: - AI_THINKING_STRUCT->funcResult = gSideTimers[side].spikesAmount; - break; - case EFFECT_TOXIC_SPIKES: - AI_THINKING_STRUCT->funcResult = gSideTimers[side].toxicSpikesAmount; - break; - } - - gAIScriptPtr += 4; -} - -static void Cmd_if_doesnt_hold_berry(void) -{ - u8 battlerId = BattleAI_GetWantedBattler(gAIScriptPtr[1]); - u16 item; - - if (IsBattlerAIControlled(battlerId)) - item = gBattleMons[battlerId].item; - else - item = BATTLE_HISTORY->itemEffects[battlerId]; - - if (ItemId_GetPocket(item) == POCKET_BERRIES) - gAIScriptPtr += 6; - else - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 2); -} - -static void Cmd_if_share_type(void) -{ - u8 battler1 = BattleAI_GetWantedBattler(gAIScriptPtr[1]); - u8 battler2 = BattleAI_GetWantedBattler(gAIScriptPtr[2]); - - if (DoBattlersShareType(battler1, battler2)) - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 3); - else - gAIScriptPtr += 7; -} - -static void Cmd_if_cant_use_last_resort(void) -{ - u8 battler = BattleAI_GetWantedBattler(gAIScriptPtr[1]); - - if (CanUseLastResort(battler)) - gAIScriptPtr += 6; - else - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 2); -} - -static u16 *GetMovesArray(u32 battler) -{ - if (IsBattlerAIControlled(battler) || IsBattlerAIControlled(BATTLE_PARTNER(battler))) - return gBattleMons[battler].moves; - else - return gBattleResources->battleHistory->usedMoves[battler]; -} - -static bool32 HasMoveWithSplit(u32 battler, u32 split) -{ - s32 i; - u16 *moves = GetMovesArray(battler); - - for (i = 0; i < MAX_MON_MOVES; i++) - { - if (moves[i] != MOVE_NONE && moves[i] != 0xFFFF && GetBattleMoveSplit(moves[i]) == split) - return TRUE; - } - - return FALSE; -} - -static void Cmd_if_has_move_with_split(void) -{ - if (HasMoveWithSplit(BattleAI_GetWantedBattler(gAIScriptPtr[1]), gAIScriptPtr[2])) - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 3); - else - gAIScriptPtr += 7; -} - -static void Cmd_if_has_no_move_with_split(void) -{ - if (!HasMoveWithSplit(BattleAI_GetWantedBattler(gAIScriptPtr[1]), gAIScriptPtr[2])) - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 3); - else - gAIScriptPtr += 7; -} - -// This function checks if all physical/special moves are either unusable or unreasonable to use. -// Consider a pokemon boosting their attack against a ghost pokemon having only normal-type physical attacks. -static bool32 MovesWithSplitUnusable(u32 attacker, u32 target, u32 split) -{ - s32 i, moveType; - u32 usable = 0; - u32 unusable = CheckMoveLimitations(attacker, 0, 0xFF); - u16 *moves = GetMovesArray(attacker); - - for (i = 0; i < MAX_MON_MOVES; i++) - { - if (moves[i] != MOVE_NONE - && moves[i] != 0xFFFF - && GetBattleMoveSplit(moves[i]) == split - && !(unusable & gBitTable[i])) - { - SetTypeBeforeUsingMove(moves[i], attacker); - GET_MOVE_TYPE(moves[i], moveType); - if (CalcTypeEffectivenessMultiplier(moves[i], moveType, attacker, target, FALSE) != 0) - usable |= gBitTable[i]; - } - } - - return (usable == 0); -} - -static void Cmd_if_physical_moves_unusable(void) -{ - if (MovesWithSplitUnusable(BattleAI_GetWantedBattler(gAIScriptPtr[1]), BattleAI_GetWantedBattler(gAIScriptPtr[2]), SPLIT_PHYSICAL)) - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 3); - else - gAIScriptPtr += 7; -} - -// Check if target has means to faint ai mon. -static void Cmd_if_ai_can_go_down(void) -{ - s32 i, dmg; - u32 unusable = CheckMoveLimitations(gBattlerTarget, 0, 0xFF & ~MOVE_LIMITATION_PP); - u16 *moves = gBattleResources->battleHistory->usedMoves[gBattlerTarget]; - - for (i = 0; i < MAX_MON_MOVES; i++) - { - if (moves[i] != MOVE_NONE && moves[i] != 0xFFFF && !(unusable & gBitTable[i]) - && AI_CalcDamage(moves[i], gBattlerTarget, sBattler_AI) >= gBattleMons[sBattler_AI].hp) - { - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 1); - return; - } - } - - gAIScriptPtr += 5; -} - -static void Cmd_if_cant_use_belch(void) -{ - u32 battler = BattleAI_GetWantedBattler(gAIScriptPtr[1]); - - if (gBattleStruct->ateBerry[battler & BIT_SIDE] & gBitTable[gBattlerPartyIndexes[battler]]) - gAIScriptPtr += 6; - else - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 2); -} - -static void Cmd_if_has_move_with_type(void) -{ - u32 i, moveType, battler = BattleAI_GetWantedBattler(gAIScriptPtr[1]); - u16 *moves = GetMovesArray(battler); - - for (i = 0; i < 4; i++) - { - if (moves[i] == MOVE_NONE) - continue; - - SetTypeBeforeUsingMove(moves[i], battler); - GET_MOVE_TYPE(moves[i], moveType); - if (moveType == gAIScriptPtr[2]) - break; - } - - if (i == 4) - gAIScriptPtr += 7; - else - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 3); -} - -static void Cmd_if_has_move_with_flag(void) -{ - u32 i, flag, battler = BattleAI_GetWantedBattler(gAIScriptPtr[1]); - u16 *moves = GetMovesArray(battler); - - flag = T1_READ_32(gAIScriptPtr + 2); - for (i = 0; i < 4; i++) - { - if (moves[i] != MOVE_NONE && gBattleMoves[moves[i]].flags & flag) - { - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 6); - return; - } - } - - gAIScriptPtr += 10; -} - -static void Cmd_if_no_move_used(void) -{ - u32 i, battler = BattleAI_GetWantedBattler(gAIScriptPtr[1]); - - if (!IsBattlerAIControlled(battler)) - { - for (i = 0; i < 4; i++) - { - if (BATTLE_HISTORY->usedMoves[battler][i] != 0 && BATTLE_HISTORY->usedMoves[battler][i] != 0xFFFF) - { - gAIScriptPtr += 6; - return; - } - } - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 2); - } - else - { - gAIScriptPtr += 6; - } -} - -static void Cmd_if_battler_absent(void) -{ - u32 battler = BattleAI_GetWantedBattler(gAIScriptPtr[1]); - - if (!IsBattlerAlive(battler)) - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 2); - else - gAIScriptPtr += 6; -} - -static void Cmd_is_grounded(void) -{ - u32 battler = BattleAI_GetWantedBattler(gAIScriptPtr[1]); - - if (IsBattlerGrounded(battler)) - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 2); - else - gAIScriptPtr += 6; -} - -static void Cmd_get_best_dmg_hp_percent(void) -{ - int i, bestDmg; - - bestDmg = 0; - for (i = 0; i < MAX_MON_MOVES; i++) - { - if (gBattleResources->ai->simulatedDmg[sBattler_AI][gBattlerTarget][i] > bestDmg) - bestDmg = gBattleResources->ai->simulatedDmg[sBattler_AI][gBattlerTarget][i]; - } - - gBattleResources->ai->funcResult = (bestDmg * 100) / gBattleMons[gBattlerTarget].maxHP; - gAIScriptPtr++; -} - -static void Cmd_get_curr_dmg_hp_percent(void) -{ - int bestDmg = gBattleResources->ai->simulatedDmg[sBattler_AI][gBattlerTarget][AI_THINKING_STRUCT->movesetIndex]; - - gBattleResources->ai->funcResult = (bestDmg * 100) / gBattleMons[gBattlerTarget].maxHP; - gAIScriptPtr++; -} - -static void Cmd_get_move_split_from_result(void) -{ - AI_THINKING_STRUCT->funcResult = GetBattleMoveSplit(AI_THINKING_STRUCT->funcResult); - gAIScriptPtr += 1; -} - -static void Cmd_get_considered_move_split(void) -{ - AI_THINKING_STRUCT->funcResult = GetBattleMoveSplit(AI_THINKING_STRUCT->moveConsidered); - gAIScriptPtr += 1; -} - -static void Cmd_get_considered_move_target(void) -{ - AI_THINKING_STRUCT->funcResult = gBattleMoves[AI_THINKING_STRUCT->moveConsidered].target; - gAIScriptPtr += 1; -} - -static void Cmd_compare_speeds(void) -{ - u8 battler1 = BattleAI_GetWantedBattler(gAIScriptPtr[1]); - u8 battler2 = BattleAI_GetWantedBattler(gAIScriptPtr[2]); - AI_THINKING_STRUCT->funcResult = GetWhoStrikesFirst(battler1, battler2, TRUE); - gAIScriptPtr += 3; -} - -static u32 FindMoveUsedXTurnsAgo(u32 battlerId, u32 x) -{ - s32 i, index = BATTLE_HISTORY->moveHistoryIndex[battlerId]; - for (i = 0; i < x; i++) - { - if (--index < 0) - index = AI_MOVE_HISTORY_COUNT - 1; - } - return BATTLE_HISTORY->moveHistory[battlerId][index]; -} - -static void Cmd_is_wakeup_turn(void) -{ - u32 battler = BattleAI_GetWantedBattler(gAIScriptPtr[1]); - // Check if rest was used 2 turns ago - if ((gBattleMons[battler].status1 & STATUS1_SLEEP) == 1 && FindMoveUsedXTurnsAgo(battler, 2) == MOVE_REST) - AI_THINKING_STRUCT->funcResult = TRUE; - else - AI_THINKING_STRUCT->funcResult = FALSE; - - gAIScriptPtr += 2; -} - -static void Cmd_if_has_move_with_accuracy_lt(void) -{ - u32 i; - u32 battler = BattleAI_GetWantedBattler(gAIScriptPtr[1]); - u32 toCmp = gAIScriptPtr[2]; - u16 *moves = GetMovesArray(battler); - - for (i = 0; i < MAX_MON_MOVES; i++) - { - if (moves[i] != MOVE_NONE - && gBattleMoves[moves[i]].effect != EFFECT_OHKO - && gBattleMoves[moves[i]].accuracy > 1 - && gBattleMoves[moves[i]].accuracy < toCmp) - break; - } - - if (i == MAX_MON_MOVES) - gAIScriptPtr += 7; - else - gAIScriptPtr = T1_READ_PTR(gAIScriptPtr + 3); -} diff --git a/src/battle_ai_switch_items.c b/src/battle_ai_switch_items.c index cef425d3a..565c0f261 100644 --- a/src/battle_ai_switch_items.c +++ b/src/battle_ai_switch_items.c @@ -1,6 +1,7 @@ #include "global.h" #include "battle.h" -#include "battle_ai_script_commands.h" +#include "battle_ai_main.h" +#include "battle_ai_util.h" #include "battle_anim.h" #include "battle_controllers.h" #include "battle_setup.h" @@ -416,7 +417,7 @@ static bool8 FindMonWithFlagsAndSuperEffective(u16 flags, u8 moduloPercent) return FALSE; } -static bool8 ShouldSwitch(void) +bool32 ShouldSwitch(void) { u8 battlerIn1, battlerIn2; s32 firstId; diff --git a/src/battle_ai_util.c b/src/battle_ai_util.c new file mode 100644 index 000000000..caabc7519 --- /dev/null +++ b/src/battle_ai_util.c @@ -0,0 +1,3463 @@ +#include "global.h" +#include "malloc.h" +#include "battle.h" +#include "battle_anim.h" +#include "battle_ai_util.h" +#include "battle_ai_main.h" +#include "battle_ai_switch_items.h" +#include "battle_factory.h" +#include "battle_setup.h" +#include "data.h" +#include "item.h" +#include "pokemon.h" +#include "random.h" +#include "recorded_battle.h" +#include "util.h" +#include "constants/abilities.h" +#include "constants/battle_ai.h" +#include "constants/battle_move_effects.h" +#include "constants/hold_effects.h" +#include "constants/moves.h" +#include "constants/items.h" + +// Const Data +static const s8 sAiAbilityRatings[ABILITIES_COUNT] = +{ + [ABILITY_ADAPTABILITY] = 8, + [ABILITY_AFTERMATH] = 5, + [ABILITY_AERILATE] = 8, + [ABILITY_AIR_LOCK] = 5, + [ABILITY_ANALYTIC] = 5, + [ABILITY_ANGER_POINT] = 4, + [ABILITY_ANTICIPATION] = 2, + [ABILITY_ARENA_TRAP] = 9, + [ABILITY_AROMA_VEIL] = 3, + [ABILITY_AURA_BREAK] = 3, + [ABILITY_BAD_DREAMS] = 4, + [ABILITY_BATTERY] = 0, + [ABILITY_BATTLE_ARMOR] = 2, + [ABILITY_BATTLE_BOND] = 6, + [ABILITY_BEAST_BOOST] = 7, + [ABILITY_BERSERK] = 5, + [ABILITY_BIG_PECKS] = 1, + [ABILITY_BLAZE] = 5, + [ABILITY_BULLETPROOF] = 7, + [ABILITY_CHEEK_POUCH] = 4, + [ABILITY_CHLOROPHYLL] = 6, + [ABILITY_CLEAR_BODY] = 4, + [ABILITY_CLOUD_NINE] = 5, + [ABILITY_COLOR_CHANGE] = 2, + [ABILITY_COMATOSE] = 6, + [ABILITY_COMPETITIVE] = 5, + [ABILITY_COMPOUND_EYES] = 7, + [ABILITY_CONTRARY] = 8, + [ABILITY_CORROSION] = 5, + [ABILITY_CURSED_BODY] = 4, + [ABILITY_CUTE_CHARM] = 2, + [ABILITY_DAMP] = 2, + [ABILITY_DANCER] = 5, + [ABILITY_DARK_AURA] = 6, + [ABILITY_DAZZLING] = 5, + [ABILITY_DEFEATIST] = -1, + [ABILITY_DEFIANT] = 5, + [ABILITY_DELTA_STREAM] = 10, + [ABILITY_DESOLATE_LAND] = 10, + [ABILITY_DISGUISE] = 8, + [ABILITY_DOWNLOAD] = 7, + [ABILITY_DRIZZLE] = 9, + [ABILITY_DROUGHT] = 9, + [ABILITY_DRY_SKIN] = 6, + [ABILITY_EARLY_BIRD] = 4, + [ABILITY_EFFECT_SPORE] = 4, + [ABILITY_ELECTRIC_SURGE] = 8, + [ABILITY_EMERGENCY_EXIT] = 3, + [ABILITY_FAIRY_AURA] = 6, + [ABILITY_FILTER] = 6, + [ABILITY_FLAME_BODY] = 4, + [ABILITY_FLARE_BOOST] = 5, + [ABILITY_FLASH_FIRE] = 6, + [ABILITY_FLOWER_GIFT] = 4, + [ABILITY_FLOWER_VEIL] = 0, + [ABILITY_FLUFFY] = 5, + [ABILITY_FORECAST] = 6, + [ABILITY_FOREWARN] = 2, + [ABILITY_FRIEND_GUARD] = 0, + [ABILITY_FRISK] = 3, + [ABILITY_FULL_METAL_BODY] = 4, + [ABILITY_FUR_COAT] = 7, + [ABILITY_GALE_WINGS] = 6, + [ABILITY_GALVANIZE] = 8, + [ABILITY_GLUTTONY] = 3, + [ABILITY_GOOEY] = 5, + [ABILITY_GRASS_PELT] = 2, + [ABILITY_GRASSY_SURGE] = 8, + [ABILITY_GUTS] = 6, + [ABILITY_HARVEST] = 5, + [ABILITY_HEALER] = 0, + [ABILITY_HEATPROOF] = 5, + [ABILITY_HEAVY_METAL] = -1, + [ABILITY_HONEY_GATHER] = 0, + [ABILITY_HUGE_POWER] = 10, + [ABILITY_HUSTLE] = 7, + [ABILITY_HYDRATION] = 4, + [ABILITY_HYPER_CUTTER] = 3, + [ABILITY_ICE_BODY] = 3, + [ABILITY_ILLUMINATE] = 0, + [ABILITY_ILLUSION] = 8, + [ABILITY_IMMUNITY] = 4, + [ABILITY_IMPOSTER] = 9, + [ABILITY_INFILTRATOR] = 6, + [ABILITY_INNARDS_OUT] = 5, + [ABILITY_INNER_FOCUS] = 2, + [ABILITY_INSOMNIA] = 4, + [ABILITY_INTIMIDATE] = 7, + [ABILITY_IRON_BARBS] = 6, + [ABILITY_IRON_FIST] = 6, + [ABILITY_JUSTIFIED] = 4, + [ABILITY_KEEN_EYE] = 1, + [ABILITY_KLUTZ] = -1, + [ABILITY_LEAF_GUARD] = 2, + [ABILITY_LEVITATE] = 7, + [ABILITY_LIGHT_METAL] = 2, + [ABILITY_LIGHTNING_ROD] = 7, + [ABILITY_LIMBER] = 3, + [ABILITY_LIQUID_OOZE] = 3, + [ABILITY_LIQUID_VOICE] = 5, + [ABILITY_LONG_REACH] = 3, + [ABILITY_MAGIC_BOUNCE] = 9, + [ABILITY_MAGIC_GUARD] = 9, + [ABILITY_MAGICIAN] = 3, + [ABILITY_MAGMA_ARMOR] = 1, + [ABILITY_MAGNET_PULL] = 9, + [ABILITY_MARVEL_SCALE] = 5, + [ABILITY_MEGA_LAUNCHER] = 7, + [ABILITY_MERCILESS] = 4, + [ABILITY_MINUS] = 0, + [ABILITY_MISTY_SURGE] = 8, + [ABILITY_MOLD_BREAKER] = 7, + [ABILITY_MOODY] = 10, + [ABILITY_MOTOR_DRIVE] = 6, + [ABILITY_MOXIE] = 7, + [ABILITY_MULTISCALE] = 8, + [ABILITY_MULTITYPE] = 8, + [ABILITY_MUMMY] = 5, + [ABILITY_NATURAL_CURE] = 7, + [ABILITY_NEUROFORCE] = 6, + [ABILITY_NO_GUARD] = 8, + [ABILITY_NORMALIZE] = -1, + [ABILITY_OBLIVIOUS] = 2, + [ABILITY_OVERCOAT] = 5, + [ABILITY_OVERGROW] = 5, + [ABILITY_OWN_TEMPO] = 3, + [ABILITY_PARENTAL_BOND] = 10, + [ABILITY_PICKUP] = 1, + [ABILITY_PICKPOCKET] = 3, + [ABILITY_PIXILATE] = 8, + [ABILITY_PLUS] = 0, + [ABILITY_POISON_HEAL] = 8, + [ABILITY_POISON_POINT] = 4, + [ABILITY_POISON_TOUCH] = 4, + //[ABILITY_PORTAL_POWER] = 8, + [ABILITY_POWER_CONSTRUCT] = 10, + [ABILITY_POWER_OF_ALCHEMY] = 0, + [ABILITY_PRANKSTER] = 8, + [ABILITY_PRESSURE] = 5, + [ABILITY_PRIMORDIAL_SEA] = 10, + [ABILITY_PRISM_ARMOR] = 6, + [ABILITY_PROTEAN] = 8, + [ABILITY_PSYCHIC_SURGE] = 8, + [ABILITY_PURE_POWER] = 10, + [ABILITY_QUEENLY_MAJESTY] = 6, + [ABILITY_QUICK_FEET] = 5, + [ABILITY_RAIN_DISH] = 3, + [ABILITY_RATTLED] = 3, + [ABILITY_RECEIVER] = 0, + [ABILITY_RECKLESS] = 6, + [ABILITY_REFRIGERATE] = 8, + [ABILITY_REGENERATOR] = 8, + [ABILITY_RIVALRY] = 1, + [ABILITY_RKS_SYSTEM] = 8, + [ABILITY_ROCK_HEAD] = 5, + [ABILITY_ROUGH_SKIN] = 6, + [ABILITY_RUN_AWAY] = 0, + [ABILITY_SAND_FORCE] = 4, + [ABILITY_SAND_RUSH] = 6, + [ABILITY_SAND_STREAM] = 9, + [ABILITY_SAND_VEIL] = 3, + [ABILITY_SAP_SIPPER] = 7, + [ABILITY_SCHOOLING] = 6, + [ABILITY_SCRAPPY] = 6, + [ABILITY_SERENE_GRACE] = 8, + [ABILITY_SHADOW_SHIELD] = 8, + [ABILITY_SHADOW_TAG] = 10, + [ABILITY_SHED_SKIN] = 7, + [ABILITY_SHEER_FORCE] = 8, + [ABILITY_SHELL_ARMOR] = 2, + [ABILITY_SHIELD_DUST] = 5, + [ABILITY_SHIELDS_DOWN] = 6, + [ABILITY_SIMPLE] = 8, + [ABILITY_SKILL_LINK] = 7, + [ABILITY_SLOW_START] = -2, + [ABILITY_SLUSH_RUSH] = 5, + [ABILITY_SNIPER] = 3, + [ABILITY_SNOW_CLOAK] = 3, + [ABILITY_SNOW_WARNING] = 8, + [ABILITY_SOLAR_POWER] = 3, + [ABILITY_SOLID_ROCK] = 6, + [ABILITY_SOUL_HEART] = 7, + [ABILITY_SOUNDPROOF] = 4, + [ABILITY_SPEED_BOOST] = 9, + [ABILITY_STAKEOUT] = 6, + [ABILITY_STALL] = -1, + [ABILITY_STAMINA] = 6, + [ABILITY_STANCE_CHANGE] = 10, + [ABILITY_STATIC] = 4, + [ABILITY_STEADFAST] = 2, + [ABILITY_STEELWORKER] = 6, + [ABILITY_STENCH] = 1, + [ABILITY_STICKY_HOLD] = 3, + [ABILITY_STORM_DRAIN] = 7, + [ABILITY_STRONG_JAW] = 6, + [ABILITY_STURDY] = 6, + [ABILITY_SUCTION_CUPS] = 2, + [ABILITY_SUPER_LUCK] = 3, + [ABILITY_SURGE_SURFER] = 4, + [ABILITY_SWARM] = 5, + [ABILITY_SWEET_VEIL] = 4, + [ABILITY_SWIFT_SWIM] = 6, + [ABILITY_SYMBIOSIS] = 0, + [ABILITY_SYNCHRONIZE] = 4, + [ABILITY_TANGLED_FEET] = 2, + [ABILITY_TANGLING_HAIR] = 5, + [ABILITY_TECHNICIAN] = 8, + [ABILITY_TELEPATHY] = 0, + [ABILITY_TERAVOLT] = 7, + [ABILITY_THICK_FAT] = 7, + [ABILITY_TINTED_LENS] = 7, + [ABILITY_TORRENT] = 5, + [ABILITY_TOXIC_BOOST] = 6, + [ABILITY_TOUGH_CLAWS] = 7, + [ABILITY_TRACE] = 6, + [ABILITY_TRIAGE] = 7, + [ABILITY_TRUANT] = -2, + [ABILITY_TURBOBLAZE] = 7, + [ABILITY_UNAWARE] = 6, + [ABILITY_UNBURDEN] = 7, + [ABILITY_UNNERVE] = 3, + [ABILITY_VICTORY_STAR] = 6, + [ABILITY_VITAL_SPIRIT] = 4, + [ABILITY_VOLT_ABSORB] = 7, + [ABILITY_WATER_ABSORB] = 7, + [ABILITY_WATER_BUBBLE] = 8, + [ABILITY_WATER_COMPACTION] = 4, + [ABILITY_WATER_VEIL] = 4, + [ABILITY_WEAK_ARMOR] = 2, + [ABILITY_WHITE_SMOKE] = 4, + [ABILITY_WIMP_OUT] = 3, + [ABILITY_WONDER_GUARD] = 10, + [ABILITY_WONDER_SKIN] = 4, + [ABILITY_ZEN_MODE] = -1, + [ABILITY_INTREPID_SWORD] = 3, + [ABILITY_DAUNTLESS_SHIELD] = 3, + [ABILITY_BALL_FETCH] = 0, + [ABILITY_COTTON_DOWN] = 3, + [ABILITY_MIRROR_ARMOR] = 6, + [ABILITY_GULP_MISSILE] = 3, + [ABILITY_STALWART] = 2, + [ABILITY_PROPELLER_TAIL] = 2, + [ABILITY_STEAM_ENGINE] = 3, + [ABILITY_PUNK_ROCK] = 2, + [ABILITY_SAND_SPIT] = 5, + [ABILITY_ICE_SCALES] = 7, + [ABILITY_RIPEN] = 4, + [ABILITY_ICE_FACE] = 4, + [ABILITY_POWER_SPOT] = 2, + [ABILITY_MIMICRY] = 2, + [ABILITY_SCREEN_CLEANER] = 3, + [ABILITY_NEUTRALIZING_GAS] = 5, + [ABILITY_HUNGER_SWITCH] = 2, + [ABILITY_PASTEL_VEIL] = 4, + [ABILITY_STEELY_SPIRIT] = 2, + [ABILITY_PERISH_BODY] = -1, + [ABILITY_WANDERING_SPIRIT] = 2, + [ABILITY_GORILLA_TACTICS] = 4, +}; + +static const u16 sEncouragedEncoreEffects[] = +{ + EFFECT_DREAM_EATER, + EFFECT_ATTACK_UP, + EFFECT_DEFENSE_UP, + EFFECT_SPEED_UP, + EFFECT_SPECIAL_ATTACK_UP, + EFFECT_HAZE, + EFFECT_ROAR, + EFFECT_CONVERSION, + EFFECT_TOXIC, + EFFECT_LIGHT_SCREEN, + EFFECT_REST, + EFFECT_SUPER_FANG, + EFFECT_SPECIAL_DEFENSE_UP_2, + EFFECT_CONFUSE, + EFFECT_POISON, + EFFECT_PARALYZE, + EFFECT_LEECH_SEED, + EFFECT_DO_NOTHING, + EFFECT_ATTACK_UP_2, + EFFECT_ENCORE, + EFFECT_CONVERSION_2, + EFFECT_LOCK_ON, + EFFECT_HEAL_BELL, + EFFECT_MEAN_LOOK, + EFFECT_NIGHTMARE, + EFFECT_PROTECT, + EFFECT_SKILL_SWAP, + EFFECT_FORESIGHT, + EFFECT_PERISH_SONG, + EFFECT_SANDSTORM, + EFFECT_ENDURE, + EFFECT_SWAGGER, + EFFECT_ATTRACT, + EFFECT_SAFEGUARD, + EFFECT_RAIN_DANCE, + EFFECT_SUNNY_DAY, + EFFECT_BELLY_DRUM, + EFFECT_PSYCH_UP, + EFFECT_FUTURE_SIGHT, + EFFECT_FAKE_OUT, + EFFECT_STOCKPILE, + EFFECT_SPIT_UP, + EFFECT_SWALLOW, + EFFECT_HAIL, + EFFECT_TORMENT, + EFFECT_WILL_O_WISP, + EFFECT_FOLLOW_ME, + EFFECT_CHARGE, + EFFECT_TRICK, + EFFECT_ROLE_PLAY, + EFFECT_INGRAIN, + EFFECT_RECYCLE, + EFFECT_KNOCK_OFF, + EFFECT_SKILL_SWAP, + EFFECT_IMPRISON, + EFFECT_REFRESH, + EFFECT_GRUDGE, + EFFECT_TEETER_DANCE, + EFFECT_MUD_SPORT, + EFFECT_WATER_SPORT, + EFFECT_DRAGON_DANCE, + EFFECT_CAMOUFLAGE, +}; + +static const u16 sDiscouragedPowerfulMoveEffects[] = +{ + EFFECT_EXPLOSION, + EFFECT_DREAM_EATER, + EFFECT_RECHARGE, + EFFECT_SKULL_BASH, + EFFECT_SOLARBEAM, + EFFECT_SPIT_UP, + EFFECT_FOCUS_PUNCH, + EFFECT_SUPERPOWER, + EFFECT_ERUPTION, + EFFECT_OVERHEAT, + EFFECT_MIND_BLOWN, + 0xFFFF +}; + +static const u16 sIgnoreMoldBreakerMoves[] = +{ + MOVE_MOONGEIST_BEAM, + MOVE_SUNSTEEL_STRIKE, + MOVE_PHOTON_GEYSER, + #ifdef MOVE_LIGHT_THAT_BURNS_THE_SKY + MOVE_LIGHT_THAT_BURNS_THE_SKY, + #endif + #ifdef MOVE_MENACING_MOONRAZE_MAELSTROM + MOVE_MENACING_MOONRAZE_MAELSTROM, + #endif + #ifdef MOVE_SEARING_SUNRAZE_SMASH + MOVE_SEARING_SUNRAZE_SMASH, + #endif +}; + +static const u16 sInstructBannedMoves[] = +{ + MOVE_INSTRUCT, + MOVE_BIDE, + MOVE_FOCUS_PUNCH, + MOVE_BEAK_BLAST, + MOVE_SHELL_TRAP, + MOVE_SKETCH, + MOVE_TRANSFORM, + MOVE_MIMIC, + MOVE_KINGS_SHIELD, + MOVE_STRUGGLE, + MOVE_BOUNCE, + MOVE_DIG, + MOVE_DIVE, + MOVE_FLY, + MOVE_FREEZE_SHOCK, + MOVE_GEOMANCY, + MOVE_ICE_BURN, + MOVE_PHANTOM_FORCE, + MOVE_RAZOR_WIND, + MOVE_SHADOW_FORCE, + MOVE_SKULL_BASH, + MOVE_SKY_ATTACK, + MOVE_SKY_DROP, + MOVE_SOLAR_BEAM, + MOVE_SOLAR_BLADE, +}; + +static const u16 sRechargeMoves[] = +{ + MOVE_HYPER_BEAM, + MOVE_BLAST_BURN, + MOVE_HYDRO_CANNON, + MOVE_FRENZY_PLANT, + MOVE_GIGA_IMPACT, + MOVE_ROCK_WRECKER, + MOVE_ROAR_OF_TIME, + MOVE_PRISMATIC_LASER, + MOVE_METEOR_ASSAULT, + MOVE_ETERNABEAM, +}; + +static const u16 sOtherMoveCallingMoves[] = +{ + MOVE_ASSIST, + MOVE_COPYCAT, + MOVE_ME_FIRST, + MOVE_METRONOME, + MOVE_MIRROR_MOVE, + MOVE_NATURE_POWER, + MOVE_SLEEP_TALK, +}; + +// Functions +bool32 AI_RandLessThan(u8 val) +{ + if ((Random() % 0xFF) < val) + return TRUE; + return FALSE; +} + +void RecordLastUsedMoveByTarget(void) +{ + RecordKnownMove(gBattlerTarget, gLastMoves[gBattlerTarget]); +} + +bool32 IsBattlerAIControlled(u32 battlerId) +{ + switch (GetBattlerPosition(battlerId)) + { + case B_POSITION_PLAYER_LEFT: + default: + return FALSE; + case B_POSITION_OPPONENT_LEFT: + return TRUE; + case B_POSITION_PLAYER_RIGHT: + return ((gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER) != 0); + case B_POSITION_OPPONENT_RIGHT: + return TRUE; + } +} + +void ClearBattlerMoveHistory(u8 battlerId) +{ + memset(BATTLE_HISTORY->usedMoves[battlerId], 0, sizeof(BATTLE_HISTORY->usedMoves[battlerId])); + memset(BATTLE_HISTORY->moveHistory[battlerId], 0, sizeof(BATTLE_HISTORY->moveHistory[battlerId])); + BATTLE_HISTORY->moveHistoryIndex[battlerId] = 0; +} + +void RecordLastUsedMoveBy(u32 battlerId, u32 move) +{ + u8 *index = &BATTLE_HISTORY->moveHistoryIndex[battlerId]; + + if (++(*index) >= AI_MOVE_HISTORY_COUNT) + *index = 0; + BATTLE_HISTORY->moveHistory[battlerId][*index] = move; +} + +void RecordKnownMove(u8 battlerId, u32 move) +{ + s32 i; + for (i = 0; i < MAX_MON_MOVES; i++) + { + if (BATTLE_HISTORY->usedMoves[battlerId][i] == move) + break; + if (BATTLE_HISTORY->usedMoves[battlerId][i] == MOVE_NONE) + { + BATTLE_HISTORY->usedMoves[battlerId][i] = move; + break; + } + } +} + +void RecordAbilityBattle(u8 battlerId, u16 abilityId) +{ + BATTLE_HISTORY->abilities[battlerId] = abilityId; +} + +void ClearBattlerAbilityHistory(u8 battlerId) +{ + BATTLE_HISTORY->abilities[battlerId] = ABILITY_NONE; +} + +void RecordItemEffectBattle(u8 battlerId, u8 itemEffect) +{ + BATTLE_HISTORY->itemEffects[battlerId] = itemEffect; +} + +void ClearBattlerItemEffectHistory(u8 battlerId) +{ + BATTLE_HISTORY->itemEffects[battlerId] = 0; +} + +void SaveBattlerData(u8 battlerId) +{ + if (!IsBattlerAIControlled(battlerId)) + { + u32 i; + + AI_THINKING_STRUCT->saved[battlerId].ability = gBattleMons[battlerId].ability; + AI_THINKING_STRUCT->saved[battlerId].heldItem = gBattleMons[battlerId].item; + AI_THINKING_STRUCT->saved[battlerId].species = gBattleMons[battlerId].species; + for (i = 0; i < 4; i++) + AI_THINKING_STRUCT->saved[battlerId].moves[i] = gBattleMons[battlerId].moves[i]; + } +} + +void SetBattlerData(u8 battlerId) +{ + if (!IsBattlerAIControlled(battlerId)) + { + struct Pokemon *illusionMon; + u32 i; + + // Use the known battler's ability. + if (BATTLE_HISTORY->abilities[battlerId] != ABILITY_NONE) + gBattleMons[battlerId].ability = BATTLE_HISTORY->abilities[battlerId]; + // Check if mon can only have one ability. + else if (gBaseStats[gBattleMons[battlerId].species].abilities[1] == ABILITY_NONE + || gBaseStats[gBattleMons[battlerId].species].abilities[1] == gBaseStats[gBattleMons[battlerId].species].abilities[0]) + gBattleMons[battlerId].ability = gBaseStats[gBattleMons[battlerId].species].abilities[0]; + // The ability is unknown. + else + gBattleMons[battlerId].ability = ABILITY_NONE; + + if (BATTLE_HISTORY->itemEffects[battlerId] == 0) + gBattleMons[battlerId].item = 0; + + for (i = 0; i < 4; i++) + { + if (BATTLE_HISTORY->usedMoves[battlerId][i] == 0) + gBattleMons[battlerId].moves[i] = 0; + } + + // Simulate Illusion + if ((illusionMon = GetIllusionMonPtr(battlerId)) != NULL) + gBattleMons[battlerId].species = GetMonData(illusionMon, MON_DATA_SPECIES2); + } +} + +void RestoreBattlerData(u8 battlerId) +{ + if (!IsBattlerAIControlled(battlerId)) + { + u32 i; + + gBattleMons[battlerId].ability = AI_THINKING_STRUCT->saved[battlerId].ability; + gBattleMons[battlerId].item = AI_THINKING_STRUCT->saved[battlerId].heldItem; + gBattleMons[battlerId].species = AI_THINKING_STRUCT->saved[battlerId].species; + for (i = 0; i < 4; i++) + gBattleMons[battlerId].moves[i] = AI_THINKING_STRUCT->saved[battlerId].moves[i]; + } +} + +u32 GetHealthPercentage(u8 battlerId) +{ + return (u32)((100 * gBattleMons[battlerId].hp) / gBattleMons[battlerId].maxHP); +} + +bool32 AtMaxHp(u8 battlerId) +{ + if (GetHealthPercentage(battlerId) == 100) + return TRUE; + return FALSE; +} + +bool32 IsBattlerTrapped(u8 battler, bool8 checkSwitch) +{ + u8 holdEffect = AI_GetHoldEffect(battler); + if (IS_BATTLER_OF_TYPE(battler, TYPE_GHOST) + || (checkSwitch && holdEffect == HOLD_EFFECT_SHED_SHELL) + || (!checkSwitch && GetBattlerAbility(battler) == ABILITY_RUN_AWAY) + || (!checkSwitch && holdEffect == HOLD_EFFECT_CAN_ALWAYS_RUN)) + { + return FALSE; + } + else + { + if (gBattleMons[battler].status2 & (STATUS2_ESCAPE_PREVENTION | STATUS2_WRAPPED) + || IsAbilityPreventingEscape(battler) + || gStatuses3[battler] & (STATUS3_ROOTED) // TODO: sky drop target in air + || (gFieldStatuses & STATUS_FIELD_FAIRY_LOCK)) + return TRUE; + } + + return FALSE; +} + +u32 GetTotalBaseStat(u32 species) +{ + return gBaseStats[species].baseHP + + gBaseStats[species].baseAttack + + gBaseStats[species].baseDefense + + gBaseStats[species].baseSpeed + + gBaseStats[species].baseSpAttack + + gBaseStats[species].baseSpDefense; +} + +bool32 IsTruantMonVulnerable(u32 battlerAI, u32 opposingBattler) +{ + int i; + + for (i = 0; i < MAX_MON_MOVES; i++) + { + u32 move = gBattleResources->battleHistory->usedMoves[opposingBattler][i]; + if (gBattleMoves[move].effect == EFFECT_PROTECT && move != MOVE_ENDURE) + return TRUE; + if (gBattleMoves[move].effect == EFFECT_SEMI_INVULNERABLE && GetWhoStrikesFirst(battlerAI, opposingBattler, TRUE) == 1) + return TRUE; + } + return FALSE; +} + +// move checks +bool32 IsAffectedByPowder(u8 battler, u16 ability, u16 holdEffect) +{ + if ((B_POWDER_GRASS >= GEN_6 && IS_BATTLER_OF_TYPE(battler, TYPE_GRASS)) + || ability == ABILITY_OVERCOAT + || GetBattlerHoldEffect(battler, TRUE) == HOLD_EFFECT_SAFETY_GOOGLES) + return FALSE; + return TRUE; +} + +// This function checks if all physical/special moves are either unusable or unreasonable to use. +// Consider a pokemon boosting their attack against a ghost pokemon having only normal-type physical attacks. +bool32 MovesWithSplitUnusable(u32 attacker, u32 target, u32 split) +{ + s32 i, moveType; + u32 usable = 0; + u32 unusable = CheckMoveLimitations(attacker, 0, 0xFF); + u16 *moves = GetMovesArray(attacker); + + for (i = 0; i < MAX_MON_MOVES; i++) + { + if (moves[i] != MOVE_NONE + && moves[i] != 0xFFFF + && GetBattleMoveSplit(moves[i]) == split + && !(unusable & gBitTable[i])) + { + SetTypeBeforeUsingMove(moves[i], attacker); + GET_MOVE_TYPE(moves[i], moveType); + if (CalcTypeEffectivenessMultiplier(moves[i], moveType, attacker, target, FALSE) != 0) + usable |= gBitTable[i]; + } + } + + return (usable == 0); +} + +static bool32 AI_GetIfCrit(u32 move, u8 battlerAtk, u8 battlerDef) +{ + bool32 isCrit; + + switch (CalcCritChanceStage(battlerAtk, battlerDef, move, FALSE)) + { + case -1: + case 0: + default: + isCrit = FALSE; + break; + case 1: + if (gBattleMoves[move].flags & FLAG_HIGH_CRIT && (Random() % 5 == 0)) + isCrit = TRUE; + else + isCrit = FALSE; + break; + case 2: + if (gBattleMoves[move].flags & FLAG_HIGH_CRIT && (Random() % 2 == 0)) + isCrit = TRUE; + else if (!(gBattleMoves[move].flags & FLAG_HIGH_CRIT) && (Random() % 4) == 0) + isCrit = TRUE; + else + isCrit = FALSE; + break; + case -2: + case 3: + case 4: + isCrit = TRUE; + break; + } + + return isCrit; +} + +s32 AI_CalcDamage(u16 move, u8 battlerAtk, u8 battlerDef) +{ + s32 dmg, moveType; + + SaveBattlerData(battlerAtk); + SaveBattlerData(battlerDef); + + SetBattlerData(battlerAtk); + SetBattlerData(battlerDef); + + gBattleStruct->dynamicMoveType = 0; + SetTypeBeforeUsingMove(move, battlerAtk); + GET_MOVE_TYPE(move, moveType); + dmg = CalculateMoveDamage(move, battlerAtk, battlerDef, moveType, 0, AI_GetIfCrit(move, battlerAtk, battlerDef), FALSE, FALSE); + + // handle dynamic move damage + switch (gBattleMoves[move].effect) + { + case EFFECT_LEVEL_DAMAGE: + dmg = gBattleMons[battlerAtk].level; + break; + case EFFECT_DRAGON_RAGE: + dmg = 40; + break; + case EFFECT_SONICBOOM: + dmg = 20; + break; + case EFFECT_PSYWAVE: + { + u32 randDamage; + if (B_PSYWAVE_DMG >= GEN_6) + randDamage = (Random() % 101); + else + randDamage = (Random() % 11) * 10; + dmg = gBattleMons[battlerAtk].level * (randDamage + 50) / 100; + } + break; + //case EFFECT_METAL_BURST: + //case EFFECT_COUNTER: + default: + dmg *= (100 - (Random() % 10)) / 100; // add random factor + break; + } + + RestoreBattlerData(battlerAtk); + RestoreBattlerData(battlerDef); + + return dmg; +} + +// Checks if one of the moves has side effects or perks +static u32 WhichMoveBetter(u32 move1, u32 move2) +{ + s32 defAbility = AI_GetAbility(gBattlerTarget); + + // Check if physical moves hurt. + if (AI_GetHoldEffect(sBattler_AI) != HOLD_EFFECT_PROTECTIVE_PADS + && (BATTLE_HISTORY->itemEffects[gBattlerTarget] == HOLD_EFFECT_ROCKY_HELMET + || defAbility == ABILITY_IRON_BARBS || defAbility == ABILITY_ROUGH_SKIN)) + { + if (IS_MOVE_PHYSICAL(move1) && !IS_MOVE_PHYSICAL(move2)) + return 1; + if (IS_MOVE_PHYSICAL(move2) && !IS_MOVE_PHYSICAL(move1)) + return 0; + } + // Check recoil + if (GetBattlerAbility(sBattler_AI) != ABILITY_ROCK_HEAD) + { + if (((gBattleMoves[move1].effect == EFFECT_RECOIL_25 + || gBattleMoves[move1].effect == EFFECT_RECOIL_IF_MISS + || gBattleMoves[move1].effect == EFFECT_RECOIL_50 + || gBattleMoves[move1].effect == EFFECT_RECOIL_33 + || gBattleMoves[move1].effect == EFFECT_RECOIL_33_STATUS) + && (gBattleMoves[move2].effect != EFFECT_RECOIL_25 + && gBattleMoves[move2].effect != EFFECT_RECOIL_IF_MISS + && gBattleMoves[move2].effect != EFFECT_RECOIL_50 + && gBattleMoves[move2].effect != EFFECT_RECOIL_33 + && gBattleMoves[move2].effect != EFFECT_RECOIL_33_STATUS + && gBattleMoves[move2].effect != EFFECT_RECHARGE))) + return 1; + + if (((gBattleMoves[move2].effect == EFFECT_RECOIL_25 + || gBattleMoves[move2].effect == EFFECT_RECOIL_IF_MISS + || gBattleMoves[move2].effect == EFFECT_RECOIL_50 + || gBattleMoves[move2].effect == EFFECT_RECOIL_33 + || gBattleMoves[move2].effect == EFFECT_RECOIL_33_STATUS) + && (gBattleMoves[move1].effect != EFFECT_RECOIL_25 + && gBattleMoves[move1].effect != EFFECT_RECOIL_IF_MISS + && gBattleMoves[move1].effect != EFFECT_RECOIL_50 + && gBattleMoves[move1].effect != EFFECT_RECOIL_33 + && gBattleMoves[move1].effect != EFFECT_RECOIL_33_STATUS + && gBattleMoves[move1].effect != EFFECT_RECHARGE))) + return 0; + } + // Check recharge + if (gBattleMoves[move1].effect == EFFECT_RECHARGE && gBattleMoves[move2].effect != EFFECT_RECHARGE) + return 1; + if (gBattleMoves[move2].effect == EFFECT_RECHARGE && gBattleMoves[move1].effect != EFFECT_RECHARGE) + return 0; + // Check additional effect. + if (gBattleMoves[move1].effect == 0 && gBattleMoves[move2].effect != 0) + return 1; + if (gBattleMoves[move2].effect == 0 && gBattleMoves[move1].effect != 0) + return 0; + + return 2; +} + +u8 GetMoveDamageResult(u16 move) +{ + s32 i, checkedMove, bestId, currId, hp; + s32 moveDmgs[MAX_MON_MOVES]; + u8 result; + + for (i = 0; sDiscouragedPowerfulMoveEffects[i] != 0xFFFF; i++) + { + if (gBattleMoves[move].effect == sDiscouragedPowerfulMoveEffects[i]) + break; + } + + if (gBattleMoves[move].power != 0 && sDiscouragedPowerfulMoveEffects[i] == 0xFFFF) + { + for (checkedMove = 0; checkedMove < MAX_MON_MOVES; checkedMove++) + { + for (i = 0; sDiscouragedPowerfulMoveEffects[i] != 0xFFFF; i++) + { + if (gBattleMoves[gBattleMons[sBattler_AI].moves[checkedMove]].effect == sDiscouragedPowerfulMoveEffects[i]) + break; + } + + if (gBattleMons[sBattler_AI].moves[checkedMove] != MOVE_NONE + && sDiscouragedPowerfulMoveEffects[i] == 0xFFFF + && gBattleMoves[gBattleMons[sBattler_AI].moves[checkedMove]].power != 0) + { + moveDmgs[checkedMove] = AI_THINKING_STRUCT->simulatedDmg[sBattler_AI][gBattlerTarget][checkedMove]; + } + else + { + moveDmgs[checkedMove] = 0; + } + } + + hp = gBattleMons[gBattlerTarget].hp + (20 * gBattleMons[gBattlerTarget].hp / 100); // 20 % add to make sure the battler is always fainted + // If a move can faint battler, it doesn't matter how much damage it does + for (i = 0; i < MAX_MON_MOVES; i++) + { + if (moveDmgs[i] > hp) + moveDmgs[i] = hp; + } + + for (bestId = 0, i = 1; i < MAX_MON_MOVES; i++) + { + if (moveDmgs[i] > moveDmgs[bestId]) + bestId = i; + if (moveDmgs[i] == moveDmgs[bestId]) + { + switch (WhichMoveBetter(gBattleMons[sBattler_AI].moves[bestId], gBattleMons[sBattler_AI].moves[i])) + { + case 2: + if (Random() & 1) + break; + case 1: + bestId = i; + break; + } + } + } + + currId = AI_THINKING_STRUCT->movesetIndex; + if (currId == bestId) + AI_THINKING_STRUCT->funcResult = MOVE_POWER_BEST; + // Compare percentage difference. + else if ((moveDmgs[currId] >= hp || moveDmgs[bestId] < hp) // If current move can faint as well, or if neither can + && (moveDmgs[bestId] * 100 / hp) - (moveDmgs[currId] * 100 / hp) <= 30 + && WhichMoveBetter(gBattleMons[sBattler_AI].moves[bestId], gBattleMons[sBattler_AI].moves[currId]) != 0) + AI_THINKING_STRUCT->funcResult = MOVE_POWER_GOOD; + else + AI_THINKING_STRUCT->funcResult = MOVE_POWER_WEAK; + } + else + { + AI_THINKING_STRUCT->funcResult = MOVE_POWER_DISCOURAGED; // Highly discouraged in terms of power. + } + + return AI_THINKING_STRUCT->funcResult; +} + +u32 GetCurrDamageHpPercent(u8 battlerAtk, u8 battlerDef) +{ + int bestDmg = AI_THINKING_STRUCT->simulatedDmg[battlerAtk][battlerDef][AI_THINKING_STRUCT->movesetIndex]; + + return (bestDmg * 100) / gBattleMons[battlerDef].maxHP; +} + +u16 AI_GetTypeEffectiveness(u16 move, u8 battlerAtk, u8 battlerDef) +{ + u16 typeEffectiveness, moveType; + + SaveBattlerData(battlerAtk); + SaveBattlerData(battlerDef); + + SetBattlerData(battlerAtk); + SetBattlerData(battlerDef); + + gBattleStruct->dynamicMoveType = 0; + SetTypeBeforeUsingMove(move, battlerAtk); + GET_MOVE_TYPE(move, moveType); + typeEffectiveness = CalcTypeEffectivenessMultiplier(move, moveType, battlerAtk, battlerDef, FALSE); + + RestoreBattlerData(battlerAtk); + RestoreBattlerData(battlerDef); + + return typeEffectiveness; +} + +u8 AI_GetMoveEffectiveness(u16 move, u8 battlerAtk, u8 battlerDef) +{ + u8 damageVar; + u32 effectivenessMultiplier; + + gMoveResultFlags = 0; + gCurrentMove = move; + effectivenessMultiplier = AI_GetTypeEffectiveness(gCurrentMove, battlerAtk, battlerDef); + + switch (effectivenessMultiplier) + { + case UQ_4_12(0.0): + default: + damageVar = AI_EFFECTIVENESS_x0; + break; + case UQ_4_12(0.25): + damageVar = AI_EFFECTIVENESS_x0_25; + break; + case UQ_4_12(0.5): + damageVar = AI_EFFECTIVENESS_x0_5; + break; + case UQ_4_12(1.0): + damageVar = AI_EFFECTIVENESS_x1; + break; + case UQ_4_12(2.0): + damageVar = AI_EFFECTIVENESS_x2; + break; + case UQ_4_12(4.0): + damageVar = AI_EFFECTIVENESS_x4; + break; + } + + return damageVar; +} + +// AI_CHECK_FASTER: is user(ai) faster +// AI_CHECK_SLOWER: is target faster +bool32 IsAiFaster(u8 battler) +{ + u32 fasterAI = 0, fasterPlayer = 0, i; + s8 prioAI, prioPlayer; + + // Check move priorities first. + prioAI = GetMovePriority(sBattler_AI, AI_THINKING_STRUCT->moveConsidered); + SaveBattlerData(gBattlerTarget); + SetBattlerData(gBattlerTarget); + for (i = 0; i < MAX_MON_MOVES; i++) + { + if (gBattleMons[gBattlerTarget].moves[i] == 0 || gBattleMons[gBattlerTarget].moves[i] == 0xFFFF) + continue; + + prioPlayer = GetMovePriority(gBattlerTarget, gBattleMons[gBattlerTarget].moves[i]); + if (prioAI > prioPlayer) + fasterAI++; + else if (prioPlayer > prioAI) + fasterPlayer++; + } + RestoreBattlerData(gBattlerTarget); + + if (fasterAI > fasterPlayer) + { + if (battler == 0) // is user (ai) faster + return TRUE; + else + return FALSE; + } + else if (fasterAI < fasterPlayer) + { + if (battler == 1) // is target (player) faster + return TRUE; + else + return FALSE; + } + else + { + // Priorities are the same(at least comparing to moves the AI is aware of), decide by speed. + if (GetWhoStrikesFirst(sBattler_AI, gBattlerTarget, TRUE) == battler) + return TRUE; + else + return FALSE; + } +} + +// Check if target has means to faint ai mon. +bool32 CanTargetFaintAi(u8 battlerDef, u8 battlerAtk) +{ + s32 i, dmg; + u32 unusable = CheckMoveLimitations(battlerDef, 0, 0xFF & ~MOVE_LIMITATION_PP); + u16 *moves = gBattleResources->battleHistory->usedMoves[battlerDef]; + + for (i = 0; i < MAX_MON_MOVES; i++) + { + if (moves[i] != MOVE_NONE && moves[i] != 0xFFFF && !(unusable & gBitTable[i]) + && AI_CalcDamage(moves[i], battlerDef, battlerAtk) >= gBattleMons[battlerAtk].hp) + { + return TRUE; + } + } + + return FALSE; +} + +bool32 CanMoveFaintBattler(u16 move, u8 battlerDef, u8 battlerAtk, u8 nHits) +{ + s32 i, dmg; + u32 unusable = CheckMoveLimitations(battlerDef, 0, 0xFF & ~MOVE_LIMITATION_PP); + + if (move != MOVE_NONE && move != 0xFFFF && !(unusable & gBitTable[i]) && AI_CalcDamage(move, battlerDef, battlerAtk) >= gBattleMons[battlerAtk].hp) + return TRUE; + + return FALSE; +} + +// Check if target has means to faint ai mon after modding hp/dmg +bool32 CanTargetFaintAiWithMod(u8 battlerDef, u8 battlerAtk, s32 hpMod, s32 dmgMod) +{ + u32 i; + u32 unusable = CheckMoveLimitations(battlerDef, 0, 0xFF & ~MOVE_LIMITATION_PP); + u16 *moves = gBattleResources->battleHistory->usedMoves[battlerDef]; + + for (i = 0; i < MAX_MON_MOVES; i++) + { + u32 dmg = AI_CalcDamage(moves[i], battlerDef, battlerAtk); + u32 hpCheck = gBattleMons[battlerAtk].hp + hpMod; + if (dmgMod) + dmg *= dmgMod; + + if (moves[i] != MOVE_NONE && moves[i] != 0xFFFF && !(unusable & gBitTable[i]) && dmg >= hpCheck) + { + return TRUE; + } + } + + return FALSE; +} + +// does NOT include ability suppression checks +s32 AI_GetAbility(u32 battlerId) +{ + // The AI knows its own ability. + if (IsBattlerAIControlled(battlerId)) + return gBattleMons[battlerId].ability; + + if (BATTLE_HISTORY->abilities[battlerId] != ABILITY_NONE) + return BATTLE_HISTORY->abilities[battlerId]; + + // Abilities that prevent fleeing. + if (gBattleMons[battlerId].ability == ABILITY_SHADOW_TAG + || gBattleMons[battlerId].ability == ABILITY_MAGNET_PULL + || gBattleMons[battlerId].ability == ABILITY_ARENA_TRAP) + return gBattleMons[battlerId].ability; + + if (gBaseStats[gBattleMons[battlerId].species].abilities[0] != ABILITY_NONE) + { + if (gBaseStats[gBattleMons[battlerId].species].abilities[1] != ABILITY_NONE) + { + // AI has no knowledge of opponent, so it guesses which ability. + return gBaseStats[gBattleMons[battlerId].species].abilities[Random() & 1]; + } + else + { + return gBaseStats[gBattleMons[battlerId].species].abilities[0]; // It's definitely ability 1. + } + } + return ABILITY_NONE; // Unknown. +} + +u16 AI_GetHoldEffect(u32 battlerId) +{ + u32 holdEffect; + + if (!IsBattlerAIControlled(battlerId)) + holdEffect = BATTLE_HISTORY->itemEffects[battlerId]; + else + holdEffect = GetBattlerHoldEffect(battlerId, FALSE); + + if (AI_THINKING_STRUCT->aiFlags & AI_FLAG_NEGATE_UNAWARE) + return holdEffect; + + if (gStatuses3[battlerId] & STATUS3_EMBARGO) + return HOLD_EFFECT_NONE; + if (gFieldStatuses & STATUS_FIELD_MAGIC_ROOM) + return HOLD_EFFECT_NONE; + if (AI_GetAbility(battlerId) == ABILITY_KLUTZ && !(gStatuses3[battlerId] & STATUS3_GASTRO_ACID)) + return HOLD_EFFECT_NONE; + + return holdEffect; +} + +// different from IsBattlerGrounded in that we don't always know battler's hold effect or ability +bool32 AI_IsBattlerGrounded(u8 battlerId) +{ + u32 holdEffect = AI_GetHoldEffect(battlerId); + + if (holdEffect == HOLD_EFFECT_IRON_BALL) + return TRUE; + else if (gFieldStatuses & STATUS_FIELD_GRAVITY) + return TRUE; + else if (gStatuses3[battlerId] & STATUS3_ROOTED) + return TRUE; + else if (gStatuses3[battlerId] & STATUS3_SMACKED_DOWN) + return TRUE; + else if (gStatuses3[battlerId] & STATUS3_TELEKINESIS) + return FALSE; + else if (gStatuses3[battlerId] & STATUS3_MAGNET_RISE) + return FALSE; + else if (holdEffect == HOLD_EFFECT_AIR_BALLOON) + return FALSE; + else if (AI_GetAbility(battlerId) == ABILITY_LEVITATE) + return FALSE; + else if (IS_BATTLER_OF_TYPE(battlerId, TYPE_FLYING)) + return FALSE; + else + return TRUE; +} + +bool32 DoesBattlerIgnoreAbilityChecks(u16 atkAbility, u16 move) +{ + u32 i; + + if (AI_THINKING_STRUCT->aiFlags & AI_FLAG_NEGATE_UNAWARE) + return FALSE; // AI handicap flag: doesn't understand ability suppression concept + + for (i = 0; i < ARRAY_COUNT(sIgnoreMoldBreakerMoves); i++) + { + if (move == sIgnoreMoldBreakerMoves[i]) + return TRUE; + } + + if (atkAbility == ABILITY_MOLD_BREAKER + || atkAbility == ABILITY_TERAVOLT + || atkAbility == ABILITY_TURBOBLAZE) + return TRUE; + + return FALSE; +} + +bool32 AI_WeatherHasEffect(void) +{ + u32 i; + if (AI_THINKING_STRUCT->aiFlags & AI_FLAG_NEGATE_UNAWARE) + return TRUE; // AI doesn't understand weather supression (handicap) + + // need to manually check since we don't necessarily know opponent ability + for (i = 0; i < gBattlersCount; i++) + { + if (IsBattlerAlive(i) + && (AI_GetAbility(i) == ABILITY_AIR_LOCK || AI_GetAbility(i) == ABILITY_CLOUD_NINE)) + return FALSE; + } + return TRUE; +} + +bool32 IsAromaVeilProtectedMove(u16 move) +{ + u32 i; + + switch (move) + { + case MOVE_DISABLE: + case MOVE_ATTRACT: + case MOVE_ENCORE: + case MOVE_TORMENT: + case MOVE_TAUNT: + case MOVE_HEAL_BLOCK: + return TRUE; + default: + return FALSE; + } +} + +bool32 IsNonVolatileStatusMoveEffect(u16 moveEffect) +{ + switch (moveEffect) + { + case EFFECT_SLEEP: + case EFFECT_TOXIC: + case EFFECT_POISON: + case EFFECT_PARALYZE: + case EFFECT_WILL_O_WISP: + case EFFECT_YAWN: + return TRUE; + default: + return FALSE; + } +} + +bool32 IsConfusionMoveEffect(u16 moveEffect) +{ + switch (moveEffect) + { + case EFFECT_CONFUSE_HIT: + case EFFECT_SWAGGER: + case EFFECT_FLATTER: + case EFFECT_TEETER_DANCE: + return TRUE; + default: + return FALSE; + } +} + +bool32 IsStatLoweringMoveEffect(u16 moveEffect) +{ + switch (moveEffect) + { + case EFFECT_ATTACK_DOWN: + case EFFECT_DEFENSE_DOWN: + case EFFECT_SPEED_DOWN: + case EFFECT_SPECIAL_ATTACK_DOWN: + case EFFECT_SPECIAL_DEFENSE_DOWN: + case EFFECT_ACCURACY_DOWN: + case EFFECT_EVASION_DOWN: + case EFFECT_ATTACK_DOWN_2: + case EFFECT_DEFENSE_DOWN_2: + case EFFECT_SPEED_DOWN_2: + case EFFECT_SPECIAL_ATTACK_DOWN_2: + case EFFECT_SPECIAL_DEFENSE_DOWN_2: + case EFFECT_ACCURACY_DOWN_2: + case EFFECT_EVASION_DOWN_2: + return TRUE; + default: + return FALSE; + } +} + +bool32 IsHazardMoveEffect(u16 moveEffect) +{ + switch (moveEffect) + { + case EFFECT_SPIKES: + case EFFECT_TOXIC_SPIKES: + case EFFECT_STICKY_WEB: + case EFFECT_STEALTH_ROCK: + return TRUE; + default: + return FALSE; + } +} + +bool32 IsMoveRedirectionPrevented(u16 move, u16 atkAbility) +{ + if (AI_THINKING_STRUCT->aiFlags & AI_FLAG_NEGATE_UNAWARE) + return FALSE; + + if (move == MOVE_SKY_DROP + || move == MOVE_SNIPE_SHOT + || atkAbility == ABILITY_PROPELLER_TAIL + || atkAbility == ABILITY_STALWART) + return TRUE; + return FALSE; +} + +// differs from GetTotalAccuracy in that we need to check AI history for item, ability, etc +u32 AI_GetMoveAccuracy(u8 battlerAtk, u8 battlerDef, u16 atkAbility, u16 defAbility, u8 atkHoldEffect, u8 defHoldEffect, u16 move) +{ + u32 calc, moveAcc, atkParam, defParam; + s8 buff, accStage, evasionStage; + + gPotentialItemEffectBattler = battlerDef; + accStage = gBattleMons[battlerAtk].statStages[STAT_ACC]; + evasionStage = gBattleMons[battlerDef].statStages[STAT_EVASION]; + if (atkAbility == ABILITY_UNAWARE) + evasionStage = DEFAULT_STAT_STAGE; + if (gBattleMoves[move].flags & FLAG_STAT_STAGES_IGNORED) + evasionStage = DEFAULT_STAT_STAGE; + if (defAbility == ABILITY_UNAWARE) + accStage = DEFAULT_STAT_STAGE; + + if (gBattleMons[battlerDef].status2 & STATUS2_FORESIGHT || gStatuses3[battlerDef] & STATUS3_MIRACLE_EYED) + buff = accStage; + else + buff = accStage + DEFAULT_STAT_STAGE - evasionStage; + + if (buff < MIN_STAT_STAGE) + buff = MIN_STAT_STAGE; + if (buff > MAX_STAT_STAGE) + buff = MAX_STAT_STAGE; + + moveAcc = gBattleMoves[move].accuracy; + // Check Thunder and Hurricane on sunny weather. + if (WEATHER_HAS_EFFECT && gBattleWeather & WEATHER_SUN_ANY + && (gBattleMoves[move].effect == EFFECT_THUNDER || gBattleMoves[move].effect == EFFECT_HURRICANE)) + moveAcc = 50; + // Check Wonder Skin. + if (defAbility == ABILITY_WONDER_SKIN && gBattleMoves[move].power == 0) + moveAcc = 50; + + calc = gAccuracyStageRatios[buff].dividend * moveAcc; + calc /= gAccuracyStageRatios[buff].divisor; + + if (atkAbility == ABILITY_COMPOUND_EYES) + calc = (calc * 130) / 100; // 1.3 compound eyes boost + else if (atkAbility == ABILITY_VICTORY_STAR) + calc = (calc * 110) / 100; // 1.1 victory star boost + if (IsBattlerAlive(BATTLE_PARTNER(battlerAtk)) && GetBattlerAbility(BATTLE_PARTNER(battlerAtk)) == ABILITY_VICTORY_STAR) + calc = (calc * 110) / 100; // 1.1 ally's victory star boost + + if (defAbility == ABILITY_SAND_VEIL && WEATHER_HAS_EFFECT && gBattleWeather & WEATHER_SANDSTORM_ANY) + calc = (calc * 80) / 100; // 1.2 sand veil loss + else if (defAbility == ABILITY_SNOW_CLOAK && WEATHER_HAS_EFFECT && gBattleWeather & WEATHER_HAIL_ANY) + calc = (calc * 80) / 100; // 1.2 snow cloak loss + else if (defAbility == ABILITY_TANGLED_FEET && gBattleMons[battlerDef].status2 & STATUS2_CONFUSION) + calc = (calc * 50) / 100; // 1.5 tangled feet loss + + if (atkAbility == ABILITY_HUSTLE && IS_MOVE_PHYSICAL(move)) + calc = (calc * 80) / 100; // 1.2 hustle loss + + if (defHoldEffect == HOLD_EFFECT_EVASION_UP) + calc = (calc * (100 - defParam)) / 100; + + if (atkHoldEffect == HOLD_EFFECT_WIDE_LENS) + calc = (calc * (100 + atkParam)) / 100; + else if (atkHoldEffect == HOLD_EFFECT_ZOOM_LENS && GetBattlerTurnOrderNum(battlerAtk) > GetBattlerTurnOrderNum(battlerDef)); + calc = (calc * (100 + atkParam)) / 100; + + return calc; +} + +bool32 IsSemiInvulnerable(u8 battlerDef, u16 move) +{ + if (gStatuses3[battlerDef] & STATUS3_PHANTOM_FORCE) + return TRUE; + else if (!TestMoveFlags(move, FLAG_DMG_IN_AIR) && gStatuses3[battlerDef] & STATUS3_ON_AIR) + return TRUE; + else if (!TestMoveFlags(move, FLAG_DMG_UNDERWATER) && gStatuses3[battlerDef] & STATUS3_UNDERWATER) + return TRUE; + else if (!TestMoveFlags(move, FLAG_DMG_UNDERGROUND) && gStatuses3[battlerDef] & STATUS3_UNDERGROUND) + return TRUE; + else + return FALSE; +} + +bool32 IsMoveEncouragedToHit(u8 battlerAtk, u8 battlerDef, u16 move) +{ + if (IsSemiInvulnerable(battlerDef, move)) + return FALSE; + + //TODO - anticipate protect move? + + // always hits + if (gStatuses3[battlerDef] & STATUS3_ALWAYS_HITS || gDisableStructs[battlerDef].battlerWithSureHit == battlerAtk) + return TRUE; + + if (AI_GetAbility(battlerDef) == ABILITY_NO_GUARD || AI_GetAbility(battlerAtk) == ABILITY_NO_GUARD) + return TRUE; + + if (B_TOXIC_NEVER_MISS >= GEN_6 && gBattleMoves[move].effect == EFFECT_TOXIC && IS_BATTLER_OF_TYPE(battlerAtk, TYPE_POISON)) + return TRUE; + + // discouraged from hitting + if (AI_WeatherHasEffect() && (gBattleWeather & WEATHER_SUN_ANY) + && (gBattleMoves[move].effect == EFFECT_THUNDER || gBattleMoves[move].effect == EFFECT_HURRICANE)) + return FALSE; + + // increased accuracy but don't always hit + if ((AI_WeatherHasEffect() && + (((gBattleWeather & WEATHER_RAIN_ANY) && (gBattleMoves[move].effect == EFFECT_THUNDER || gBattleMoves[move].effect == EFFECT_HURRICANE)) + || (((gBattleWeather & WEATHER_HAIL_ANY) && move == MOVE_BLIZZARD)))) + || (gBattleMoves[move].effect == EFFECT_VITAL_THROW) + || (gBattleMoves[move].accuracy == 0) + || ((B_MINIMIZE_DMG_ACC >= GEN_6) && (gStatuses3[battlerDef] & STATUS3_MINIMIZED) && (gBattleMoves[move].flags & FLAG_DMG_MINIMIZE))) + { + return TRUE; + } + + return FALSE; +} + +bool32 ShouldTryOHKO(u8 battlerAtk, u8 battlerDef, u16 atkAbility, u16 defAbility, u32 accuracy, u16 move) +{ + u32 holdEffect = AI_GetHoldEffect(battlerDef); + + gPotentialItemEffectBattler = battlerDef; + if (holdEffect == HOLD_EFFECT_FOCUS_BAND && (Random() % 100) < GetBattlerHoldEffectParam(battlerDef)) + return FALSE; //probabilistically speaking, focus band should activate so dont OHKO + else if (holdEffect == HOLD_EFFECT_FOCUS_SASH && AtMaxHp(battlerDef)) + return FALSE; + + if (!DoesBattlerIgnoreAbilityChecks(atkAbility, move) && defAbility == ABILITY_STURDY) + return FALSE; + + if ((((gStatuses3[battlerDef] & STATUS3_ALWAYS_HITS) + && gDisableStructs[battlerDef].battlerWithSureHit == battlerAtk) + || atkAbility == ABILITY_NO_GUARD || defAbility == ABILITY_NO_GUARD) + && gBattleMons[battlerAtk].level >= gBattleMons[battlerDef].level) + { + return TRUE; + } + else // test the odds + { + u16 odds = accuracy + (gBattleMons[battlerAtk].level - gBattleMons[battlerDef].level); + if (Random() % 100 + 1 < odds && gBattleMons[battlerAtk].level >= gBattleMons[battlerDef].level) + return TRUE; + } + return FALSE; +} + +bool32 ShouldSetSandstorm(u8 battler, u16 ability, u16 holdEffect) +{ + if (!AI_WeatherHasEffect()) + return FALSE; + else if (gBattleWeather & WEATHER_SANDSTORM_ANY) + return FALSE; + + if (ability == ABILITY_SAND_VEIL + || ability == ABILITY_SAND_RUSH + || ability == ABILITY_SAND_FORCE + || ability == ABILITY_SAND_FORCE + || ability == ABILITY_OVERCOAT + || ability == ABILITY_MAGIC_GUARD + || holdEffect == HOLD_EFFECT_SAFETY_GOOGLES + || IS_BATTLER_OF_TYPE(battler, TYPE_ROCK) + || IS_BATTLER_OF_TYPE(battler, TYPE_STEEL) + || IS_BATTLER_OF_TYPE(battler, TYPE_GROUND) + || HasMoveEffect(battler, EFFECT_SHORE_UP) + || HasMoveEffect(battler, EFFECT_WEATHER_BALL)) + { + return TRUE; + } + return FALSE; +} + +bool32 ShouldSetHail(u8 battler, u16 ability, u16 holdEffect) +{ + if (!AI_WeatherHasEffect()) + return FALSE; + else if (gBattleWeather & WEATHER_HAIL_ANY) + return FALSE; + + if (ability == ABILITY_SNOW_CLOAK + || ability == ABILITY_ICE_BODY + || ability == ABILITY_FORECAST + || ability == ABILITY_SLUSH_RUSH + || ability == ABILITY_MAGIC_GUARD + || ability == ABILITY_OVERCOAT + || holdEffect == HOLD_EFFECT_SAFETY_GOOGLES + || IS_BATTLER_OF_TYPE(battler, TYPE_ICE) + || HasMove(battler, MOVE_BLIZZARD) + || HasMoveEffect(battler, EFFECT_AURORA_VEIL) + || HasMoveEffect(battler, EFFECT_WEATHER_BALL)) + { + return TRUE; + } + return FALSE; +} + +bool32 ShouldSetRain(u8 battlerAtk, u16 atkAbility, u16 holdEffect) +{ + if (!AI_WeatherHasEffect()) + return FALSE; + else if (gBattleWeather & WEATHER_RAIN_ANY) + return FALSE; + + if (holdEffect != HOLD_EFFECT_UTILITY_UMBRELLA + && (atkAbility == ABILITY_SWIFT_SWIM + || atkAbility == ABILITY_FORECAST + || atkAbility == ABILITY_HYDRATION + || atkAbility == ABILITY_RAIN_DISH + || atkAbility == ABILITY_DRY_SKIN + || HasMoveEffect(battlerAtk, EFFECT_THUNDER) + || HasMoveEffect(battlerAtk, EFFECT_HURRICANE) + || HasMoveEffect(battlerAtk, EFFECT_WEATHER_BALL) + || HasMoveWithType(battlerAtk, TYPE_WATER))) + { + return TRUE; + } + return FALSE; +} + +bool32 ShouldSetSun(u8 battlerAtk, u16 atkAbility, u16 holdEffect) +{ + if (!AI_WeatherHasEffect()) + return FALSE; + else if (gBattleWeather & WEATHER_SUN_ANY) + return FALSE; + + if (holdEffect != HOLD_EFFECT_UTILITY_UMBRELLA + && (atkAbility == ABILITY_CHLOROPHYLL + || atkAbility == ABILITY_FLOWER_GIFT + || atkAbility == ABILITY_FORECAST + || atkAbility == ABILITY_LEAF_GUARD + || atkAbility == ABILITY_SOLAR_POWER + || atkAbility == ABILITY_HARVEST + || HasMoveEffect(battlerAtk, EFFECT_SOLARBEAM) + || HasMoveEffect(battlerAtk, EFFECT_MORNING_SUN) + || HasMoveEffect(battlerAtk, EFFECT_SYNTHESIS) + || HasMoveEffect(battlerAtk, EFFECT_MOONLIGHT) + || HasMoveEffect(battlerAtk, EFFECT_WEATHER_BALL) + || HasMoveEffect(battlerAtk, EFFECT_GROWTH) + || HasMoveWithType(battlerAtk, TYPE_FIRE))) + { + return TRUE; + } + return FALSE; +} + + +void ProtectChecks(u8 battlerAtk, u8 battlerDef, u16 move, u16 predictedMove, s16 *score) +{ + // TODO more sophisticated logic + u16 predictedEffect = gBattleMoves[predictedMove].effect; + u8 defAbility = AI_GetAbility(battlerDef); + u32 uses = gDisableStructs[battlerAtk].protectUses; + + /*if (GetMoveResultFlags(predictedMove) & (MOVE_RESULT_NO_EFFECT | MOVE_RESULT_MISSED)) + { + (*score) -= 5; + return; + }*/ + + if (uses == 0) + { + if (predictedMove != MOVE_NONE && predictedMove != 0xFFFF && !IS_MOVE_STATUS(predictedMove)) + (*score) += 2; + else if (Random() % 256 < 100) + (*score)++; + } + else + { + if (IsDoubleBattle()) + (*score) -= 2 * min(uses, 3); + else + (*score) -= min(uses, 3); + } + + if (gBattleMons[battlerAtk].status1 & (STATUS1_PSN_ANY | STATUS1_BURN) + || gBattleMons[battlerAtk].status2 & (STATUS2_CURSED | STATUS2_INFATUATION) + || gStatuses3[battlerAtk] & (STATUS3_PERISH_SONG | STATUS3_LEECHSEED | STATUS3_YAWN)) + { + (*score)--; + } + + if (gBattleMons[battlerDef].status1 & STATUS1_TOXIC_POISON + || gBattleMons[battlerDef].status2 & (STATUS2_CURSED | STATUS2_INFATUATION) + || gStatuses3[battlerDef] & (STATUS3_PERISH_SONG | STATUS3_LEECHSEED | STATUS3_YAWN)) + (*score) += 2; +} + +// stat stages +bool32 ShouldLowerStat(u8 battler, u16 battlerAbility, u8 stat) +{ + if ((gBattleMons[battler].statStages[stat] > MIN_STAT_STAGE && battlerAbility != ABILITY_CONTRARY) + || (battlerAbility == ABILITY_CONTRARY && gBattleMons[battler].statStages[stat] < MAX_STAT_STAGE)) + { + if (battlerAbility == ABILITY_CLEAR_BODY + || battlerAbility == ABILITY_WHITE_SMOKE + || battlerAbility == ABILITY_FULL_METAL_BODY) + return FALSE; + + return TRUE; + } + + return FALSE; +} + +bool32 BattlerStatCanRise(u8 battler, u16 battlerAbility, u8 stat) +{ + if ((gBattleMons[battler].statStages[stat] < MAX_STAT_STAGE && battlerAbility != ABILITY_CONTRARY) + || (battlerAbility == ABILITY_CONTRARY && gBattleMons[battler].statStages[stat] > MIN_STAT_STAGE)) + return TRUE; + return FALSE; +} + +bool32 AreBattlersStatsMaxed(u8 battlerId) +{ + u32 i; + for (i = STAT_ATK; i < NUM_BATTLE_STATS; i++) + { + if (gBattleMons[battlerId].statStages[i] < MAX_STAT_STAGE) + return FALSE; + } + return TRUE; +} + +bool32 AnyStatIsRaised(u8 battlerId) +{ + u32 i; + + for (i = STAT_ATK; i < NUM_BATTLE_STATS; i++) + { + if (gBattleMons[battlerId].statStages[i] > DEFAULT_STAT_STAGE) + return TRUE; + } + return FALSE; +} + +u32 CountPositiveStatStages(u8 battlerId) +{ + u32 count = 0; + u32 i; + for (i = STAT_ATK; i < NUM_BATTLE_STATS; i++) + { + if (gBattleMons[battlerId].statStages[i] > DEFAULT_STAT_STAGE) + count++; + } + return count; +} + +u32 CountNegativeStatStages(u8 battlerId) +{ + u32 count = 0; + u32 i; + for (i = STAT_ATK; i < NUM_BATTLE_STATS; i++) + { + if (gBattleMons[battlerId].statStages[i] < DEFAULT_STAT_STAGE) + count++; + } + return count; +} + +bool32 ShouldLowerAttack(u8 battlerAtk, u8 battlerDef, u16 defAbility) +{ + if (IsAiFaster(AI_CHECK_FASTER) && CanAttackerFaintTarget(battlerAtk, battlerDef, AI_THINKING_STRUCT->movesetIndex, 0)) + return FALSE; // Don't bother lowering stats if can kill enemy. + + if (gBattleMons[battlerDef].statStages[STAT_ATK] > 4 + && HasMoveWithSplit(battlerDef, SPLIT_PHYSICAL) + && defAbility != ABILITY_CONTRARY + && defAbility != ABILITY_CLEAR_BODY + && defAbility != ABILITY_WHITE_SMOKE + //&& defAbility != ABILITY_FULL_METAL_BODY + && defAbility != ABILITY_HYPER_CUTTER) + return TRUE; + return FALSE; +} + +bool32 ShouldLowerDefense(u8 battlerAtk, u8 battlerDef, u16 defAbility) +{ + if (IsAiFaster(AI_CHECK_FASTER) && CanAttackerFaintTarget(battlerAtk, battlerDef, AI_THINKING_STRUCT->movesetIndex, 0)) + return FALSE; // Don't bother lowering stats if can kill enemy. + + if (gBattleMons[battlerDef].statStages[STAT_DEF] > 4 + && HasMoveWithSplit(battlerAtk, SPLIT_PHYSICAL) + && defAbility != ABILITY_CONTRARY + && defAbility != ABILITY_CLEAR_BODY + && defAbility != ABILITY_WHITE_SMOKE + //&& defAbility != ABILITY_FULL_METAL_BODY + && defAbility != ABILITY_BIG_PECKS) + return TRUE; + return FALSE; +} + +bool32 ShouldLowerSpeed(u8 battlerAtk, u8 battlerDef, u16 defAbility) +{ + if (IsAiFaster(AI_CHECK_FASTER) && CanAttackerFaintTarget(battlerAtk, battlerDef, AI_THINKING_STRUCT->movesetIndex, 0)) + return FALSE; // Don't bother lowering stats if can kill enemy. + + if (IsAiFaster(AI_CHECK_SLOWER) + && defAbility != ABILITY_CONTRARY + && defAbility != ABILITY_CLEAR_BODY + //&& defAbility != ABILITY_FULL_METAL_BODY + && defAbility != ABILITY_WHITE_SMOKE) + return TRUE; + return FALSE; +} + +bool32 ShouldLowerSpAtk(u8 battlerAtk, u8 battlerDef, u16 defAbility) +{ + if (IsAiFaster(AI_CHECK_FASTER) && CanAttackerFaintTarget(battlerAtk, battlerDef, AI_THINKING_STRUCT->movesetIndex, 0)) + return FALSE; // Don't bother lowering stats if can kill enemy. + + if (gBattleMons[battlerDef].statStages[STAT_SPATK] > 4 + && HasMoveWithSplit(battlerDef, SPLIT_SPECIAL) + && defAbility != ABILITY_CONTRARY + && defAbility != ABILITY_CLEAR_BODY + //&& defAbility != ABILITY_FULL_METAL_BODY + && defAbility != ABILITY_WHITE_SMOKE) + return TRUE; + return FALSE; +} + +bool32 ShouldLowerSpDef(u8 battlerAtk, u8 battlerDef, u16 defAbility) +{ + if (IsAiFaster(AI_CHECK_FASTER) && CanAttackerFaintTarget(battlerAtk, battlerDef, AI_THINKING_STRUCT->movesetIndex, 0)) + return FALSE; // Don't bother lowering stats if can kill enemy. + + if (gBattleMons[battlerDef].statStages[STAT_SPDEF] > 4 + && HasMoveWithSplit(battlerAtk, SPLIT_SPECIAL) + && defAbility != ABILITY_CONTRARY + && defAbility != ABILITY_CLEAR_BODY + //&& defAbility != ABILITY_FULL_METAL_BODY + && defAbility != ABILITY_WHITE_SMOKE) + return TRUE; + return FALSE; +} + +bool32 ShouldLowerAccuracy(u8 battlerAtk, u8 battlerDef, u16 defAbility) +{ + if (IsAiFaster(AI_CHECK_FASTER) && CanAttackerFaintTarget(battlerAtk, battlerDef, AI_THINKING_STRUCT->movesetIndex, 0)) + return FALSE; // Don't bother lowering stats if can kill enemy. + + if (defAbility != ABILITY_CONTRARY + && defAbility != ABILITY_CLEAR_BODY + && defAbility != ABILITY_WHITE_SMOKE + //&& defAbility != ABILITY_FULL_METAL_BODY + && defAbility != ABILITY_KEEN_EYE) + return TRUE; + return FALSE; +} + +bool32 ShouldLowerEvasion(u8 battlerAtk, u8 battlerDef, u16 defAbility) +{ + if (IsAiFaster(AI_CHECK_FASTER) && CanAttackerFaintTarget(battlerAtk, battlerDef, AI_THINKING_STRUCT->movesetIndex, 0)) + return FALSE; // Don't bother lowering stats if can kill enemy. + + if (gBattleMons[battlerDef].statStages[STAT_EVASION] > DEFAULT_STAT_STAGE + && defAbility != ABILITY_CONTRARY + && defAbility != ABILITY_CLEAR_BODY + //&& defAbility != ABILITY_FULL_METAL_BODY + && defAbility != ABILITY_WHITE_SMOKE) + return TRUE; + return FALSE; +} + +bool32 CanAttackerFaintTarget(u8 battlerAtk, u8 battlerDef, u8 index, u8 numHits) +{ + s32 dmg = AI_THINKING_STRUCT->simulatedDmg[battlerAtk][battlerDef][index]; + + if (numHits) + dmg *= numHits; + + if (gBattleMons[battlerDef].hp <= dmg) + return TRUE; + return FALSE; +} + +u16 *GetMovesArray(u32 battler) +{ + if (IsBattlerAIControlled(battler) || IsBattlerAIControlled(BATTLE_PARTNER(battler))) + return gBattleMons[battler].moves; + else + return gBattleResources->battleHistory->usedMoves[battler]; +} + +bool32 HasOnlyMovesWithSplit(u32 battlerId, u32 split, bool32 onlyOffensive) +{ + u32 i; + u16 *moves = GetMovesArray(battlerId); + + for (i = 0; i < MAX_MON_MOVES; i++) + { + if (onlyOffensive && IS_MOVE_STATUS(moves[i])) + continue; + if (moves[i] != MOVE_NONE && moves[i] != 0xFFFF && GetBattleMoveSplit(moves[i]) != split) + return FALSE; + } + + return TRUE; +} + +bool32 HasMoveWithSplit(u32 battler, u32 split) +{ + u32 i; + u16 *moves = GetMovesArray(battler); + + for (i = 0; i < MAX_MON_MOVES; i++) + { + if (moves[i] != MOVE_NONE && moves[i] != 0xFFFF && GetBattleMoveSplit(moves[i]) == split) + return TRUE; + } + + return FALSE; +} + +bool32 HasMoveWithType(u32 battler, u8 type) +{ + s32 i; + u16 *moves = GetMovesArray(battler); + + for (i = 0; i < MAX_MON_MOVES; i++) + { + if (moves[i] != MOVE_NONE && moves[i] != 0xFFFF && gBattleMoves[moves[i]].type == type) + return TRUE; + } + + return FALSE; +} + +bool32 HasMoveEffect(u32 battlerId, u16 moveEffect) +{ + s32 i; + u16 *moves = GetMovesArray(battlerId); + + for (i = 0; i < MAX_MON_MOVES; i++) + { + if (moves[i] != MOVE_NONE && moves[i] != 0xFFFF && gBattleMoves[moves[i]].effect == moveEffect) + return TRUE; + } + + return FALSE; +} + +bool32 HasMove(u32 battlerId, u32 move) +{ + s32 i; + u16 *moves = GetMovesArray(battlerId); + + for (i = 0; i < MAX_MON_MOVES; i++) + { + if (moves[i] != MOVE_NONE && moves[i] != 0xFFFF && moves[i] == move) + return TRUE; + } + + return FALSE; +} + +bool32 HasMoveWithLowAccuracy(u8 battlerAtk, u8 battlerDef, u8 accCheck, bool32 ignoreStatus, u16 atkAbility, u16 defAbility, u16 atkHoldEffect, u16 defHoldEffect) +{ + s32 i; + u16 *moves = GetMovesArray(battlerAtk); + u8 moveLimitations = CheckMoveLimitations(battlerAtk, 0, 0xFF); + + for (i = 0; i < MAX_MON_MOVES; i++) + { + if (moves[i] == MOVE_NONE || moves[i] == 0xFFFF) + continue; + + if (!(gBitTable[i] & moveLimitations)) + { + if (ignoreStatus && IS_MOVE_STATUS(moves[i])) + continue; + else if ((!IS_MOVE_STATUS(moves[i]) && gBattleMoves[moves[i]].accuracy == 0) + || gBattleMoves[moves[i]].target & (MOVE_TARGET_USER | MOVE_TARGET_OPPONENTS_FIELD)) + continue; + + if (AI_GetMoveAccuracy(battlerAtk, battlerDef, atkAbility, defAbility, atkHoldEffect, defHoldEffect, moves[i]) <= accCheck) + return TRUE; + } + } + + return FALSE; +} + +bool32 HasSleepMoveWithLowAccuracy(u8 battlerAtk, u8 battlerDef) +{ + u8 moveLimitations = CheckMoveLimitations(battlerAtk, 0, 0xFF); + u32 i; + u16 *moves = GetMovesArray(battlerAtk); + + for (i = 0; i < MAX_MON_MOVES; i++) + { + if (moves[i] == MOVE_NONE) + break; + if (!(gBitTable[i] & moveLimitations)) + { + if (gBattleMoves[moves[i]].effect == EFFECT_SLEEP + && AI_GetMoveAccuracy(battlerAtk, battlerDef, AI_DATA->atkAbility, AI_DATA->defAbility, AI_DATA->atkHoldEffect, AI_DATA->defHoldEffect, moves[i]) < 85) + return TRUE; + } + } + return FALSE; +} + +bool32 IsHealingMoveEffect(u16 effect) +{ + switch (effect) + { + case EFFECT_RESTORE_HP: + case EFFECT_MORNING_SUN: + case EFFECT_SYNTHESIS: + case EFFECT_MOONLIGHT: + case EFFECT_SOFTBOILED: + case EFFECT_ROOST: + case EFFECT_SWALLOW: + case EFFECT_WISH: + case EFFECT_HEALING_WISH: + case EFFECT_HEAL_PULSE: + case EFFECT_REST: + return TRUE; + default: + return FALSE; + } +} + +bool32 HasHealingEffect(u32 battlerId) +{ + s32 i; + u16 *moves = GetMovesArray(battlerId); + + for (i = 0; i < MAX_MON_MOVES; i++) + { + if (moves[i] != MOVE_NONE && moves[i] != 0xFFFF && IsHealingMoveEffect(gBattleMoves[moves[i]].effect)) + return TRUE; + } + + return FALSE; +} + +bool32 IsTrappingMoveEffect(u16 effect) +{ + switch (effect) + { + case EFFECT_MEAN_LOOK: + case EFFECT_TRAP: + case EFFECT_HIT_PREVENT_ESCAPE: + case EFFECT_FAIRY_LOCK: + //case EFFECT_NO_RETREAT: // TODO + return TRUE; + default: + return FALSE; + } +} + +bool32 HasTrappingMoveEffect(u8 battler) +{ + s32 i; + u16 *moves = GetMovesArray(battler); + + for (i = 0; i < MAX_MON_MOVES; i++) + { + if (moves[i] != MOVE_NONE && moves[i] != 0xFFFF && IsTrappingMoveEffect(gBattleMoves[moves[i]].effect)) + return TRUE; + } + + return FALSE; +} + +bool32 HasThawingMove(u8 battlerId) +{ + s32 i; + u16 *moves = GetMovesArray(battlerId); + + for (i = 0; i < MAX_MON_MOVES; i++) + { + if (moves[i] != MOVE_NONE && moves[i] != 0xFFFF && IsThawingMove(battlerId, moves[i])) + return TRUE; + } + + return FALSE; +} + +bool32 IsUngroundingEffect(u16 effect) +{ + switch (effect) + { + case EFFECT_MAGNET_RISE: + return TRUE; + default: + return FALSE; + } +} + +// for anger point +bool32 IsAttackBoostMoveEffect(u16 effect) +{ + switch (effect) + { + case EFFECT_ATTACK_UP: + case EFFECT_ATTACK_UP_2: + case EFFECT_ATTACK_ACCURACY_UP: + case EFFECT_ATTACK_SPATK_UP: + case EFFECT_DRAGON_DANCE: + case EFFECT_COIL: + case EFFECT_BELLY_DRUM: + case EFFECT_BULK_UP: + case EFFECT_GROWTH: + return TRUE; + default: + return FALSE; + } +} + +bool32 IsStatRaisingEffect(u16 effect) +{ + switch (effect) + { + case EFFECT_ATTACK_UP: + case EFFECT_ATTACK_UP_2: + case EFFECT_DEFENSE_UP: + case EFFECT_DEFENSE_UP_2: + case EFFECT_DEFENSE_UP_3: + case EFFECT_SPEED_UP: + case EFFECT_SPEED_UP_2: + case EFFECT_SPECIAL_ATTACK_UP: + case EFFECT_SPECIAL_ATTACK_UP_2: + case EFFECT_SPECIAL_ATTACK_UP_3: + case EFFECT_SPECIAL_DEFENSE_UP: + case EFFECT_SPECIAL_DEFENSE_UP_2: + case EFFECT_ACCURACY_UP: + case EFFECT_ACCURACY_UP_2: + case EFFECT_EVASION_UP: + case EFFECT_EVASION_UP_2: + case EFFECT_MINIMIZE: + case EFFECT_DEFENSE_CURL: + case EFFECT_CHARGE: + case EFFECT_CALM_MIND: + case EFFECT_COSMIC_POWER: + case EFFECT_DRAGON_DANCE: + case EFFECT_ACUPRESSURE: + case EFFECT_SHELL_SMASH: + case EFFECT_SHIFT_GEAR: + case EFFECT_ATTACK_ACCURACY_UP: + case EFFECT_ATTACK_SPATK_UP: + case EFFECT_GROWTH: + case EFFECT_COIL: + case EFFECT_QUIVER_DANCE: + case EFFECT_BULK_UP: + case EFFECT_GEOMANCY: + case EFFECT_STOCKPILE: + return TRUE; + default: + return FALSE; + } +} + +bool32 IsStatLoweringEffect(u16 effect) +{ + // ignore other potentially-beneficial effects like defog, gravity + switch (effect) + { + case EFFECT_ATTACK_DOWN: + case EFFECT_DEFENSE_DOWN: + case EFFECT_SPEED_DOWN: + case EFFECT_SPECIAL_ATTACK_DOWN: + case EFFECT_SPECIAL_DEFENSE_DOWN: + case EFFECT_ACCURACY_DOWN: + case EFFECT_EVASION_DOWN: + case EFFECT_ATTACK_DOWN_2: + case EFFECT_DEFENSE_DOWN_2: + case EFFECT_SPEED_DOWN_2: + case EFFECT_SPECIAL_ATTACK_DOWN_2: + case EFFECT_SPECIAL_DEFENSE_DOWN_2: + case EFFECT_ACCURACY_DOWN_2: + case EFFECT_EVASION_DOWN_2: + case EFFECT_TICKLE: + case EFFECT_CAPTIVATE: + case EFFECT_NOBLE_ROAR: + return TRUE; + default: + return FALSE; + } +} + +bool32 HasDamagingMove(u8 battlerId) +{ + u32 i; + u16 *moves = GetMovesArray(battlerId); + + for (i = 0; i < MAX_MON_MOVES; i++) + { + if (moves[i] != MOVE_NONE && moves[i] != 0xFFFF && gBattleMoves[moves[i]].power != 0) + return TRUE; + } + + return FALSE; +} + +bool32 HasDamagingMoveOfType(u8 battlerId, u8 type) +{ + s32 i; + u16 *moves = GetMovesArray(battlerId); + + for (i = 0; i < MAX_MON_MOVES; i++) + { + if (moves[i] != MOVE_NONE && moves[i] != 0xFFFF + && gBattleMoves[moves[i]].type == type && gBattleMoves[moves[i]].power != 0) + return TRUE; + } + + return FALSE; +} + +bool32 IsInstructBannedMove(u16 move) +{ + u32 i; + for (i = 0; i < ARRAY_COUNT(sInstructBannedMoves); i++) + { + if (move == sInstructBannedMoves[i]) + return TRUE; + } + return FALSE; +} + +bool32 IsEncoreEncouragedEffect(u16 moveEffect) +{ + u32 i; + + for (i = 0; i < ARRAY_COUNT(sEncouragedEncoreEffects); i++) + { + if (moveEffect == sEncouragedEncoreEffects[i]) + return TRUE; + } + return FALSE; +} + +bool32 MoveRequiresRecharging(u16 move) +{ + u32 i; + for (i = 0; i < ARRAY_COUNT(sRechargeMoves); i++) + { + if (move == sRechargeMoves[i]) + return TRUE; + } + return FALSE; +} + +bool32 MoveCallsOtherMove(u16 move) +{ + u32 i; + for (i = 0; i < ARRAY_COUNT(sOtherMoveCallingMoves); i++) + { + if (move == sOtherMoveCallingMoves[i]) + return TRUE; + } + return FALSE; +} + +bool32 TestMoveFlagsInMoveset(u8 battler, u32 flags) +{ + s32 i; + u16 *moves = GetMovesArray(battler); + + for (i = 0; i < MAX_MON_MOVES; i++) + { + if (moves[i] != MOVE_NONE && moves[i] != 0xFFFF && TestMoveFlags(moves[i], flags)) + return TRUE; + } + return FALSE; +} + +static u32 GetLeechSeedDamage(u8 battlerId) +{ + u32 damage = 0; + if ((gStatuses3[battlerId] & STATUS3_LEECHSEED) + && gBattleMons[gStatuses3[battlerId] & STATUS3_LEECHSEED_BATTLER].hp != 0) + { + damage = gBattleMons[battlerId].maxHP / 8; + if (damage == 0) + damage = 1; + } + return damage; +} + +static u32 GetNightmareDamage(u8 battlerId) +{ + u32 damage = 0; + if ((gBattleMons[battlerId].status2 & STATUS2_NIGHTMARE) && gBattleMons[battlerId].status1 & STATUS1_SLEEP) + { + damage = gBattleMons[battlerId].maxHP / 4; + if (damage == 0) + damage = 1; + } + return damage; +} + +static u32 GetCurseDamage(u8 battlerId) +{ + u32 damage = 0; + if (gBattleMons[battlerId].status2 & STATUS2_CURSED) + { + damage = gBattleMons[battlerId].maxHP / 4; + if (damage == 0) + damage = 1; + } + return damage; +} + +static u32 GetTrapDamage(u8 battlerId) +{ + // ai has no knowledge about turns remaining + u32 damage = 0; + u32 holdEffect = AI_GetHoldEffect(gBattleStruct->wrappedBy[battlerId]); + if (gBattleMons[battlerId].status2 & STATUS2_WRAPPED) + { + if (holdEffect == HOLD_EFFECT_BINDING_BAND) + damage = gBattleMons[battlerId].maxHP / (B_BINDING_DAMAGE >= GEN_6) ? 6 : 8; + else + damage = gBattleMons[battlerId].maxHP / (B_BINDING_DAMAGE >= GEN_6) ? 8 : 16; + + if (damage == 0) + damage = 1; + } + return damage; +} + +static u32 GetPoisonDamage(u8 battlerId) +{ + u32 damage = 0; + + if (AI_GetAbility(battlerId) == ABILITY_POISON_HEAL) + return damage; + + if (gBattleMons[battlerId].status1 & STATUS1_POISON) + { + damage = gBattleMons[battlerId].maxHP / 8; + if (damage == 0) + damage = 1; + } + else if (gBattleMons[battlerId].status1 & STATUS1_TOXIC_POISON) + { + damage = gBattleMons[battlerId].maxHP / 16; + if (damage == 0) + damage = 1; + if ((gBattleMons[battlerId].status1 & STATUS1_TOXIC_COUNTER) != STATUS1_TOXIC_TURN(15)) // not 16 turns + gBattleMons[battlerId].status1 += STATUS1_TOXIC_TURN(1); + damage *= (gBattleMons[battlerId].status1 & STATUS1_TOXIC_COUNTER) >> 8; + } + return damage; +} + +static bool32 BattlerAffectedBySandstorm(u8 battlerId, u16 ability) +{ + if (!IS_BATTLER_OF_TYPE(battlerId, TYPE_ROCK) + && !IS_BATTLER_OF_TYPE(battlerId, TYPE_GROUND) + && !IS_BATTLER_OF_TYPE(battlerId, TYPE_STEEL) + && ability != ABILITY_SAND_VEIL + && ability != ABILITY_SAND_FORCE + && ability != ABILITY_SAND_RUSH + && ability != ABILITY_OVERCOAT) + return TRUE; + return FALSE; +} + +static bool32 BattlerAffectedByHail(u8 battlerId, u16 ability) +{ + if (!IS_BATTLER_OF_TYPE(battlerId, TYPE_ICE) + && ability != ABILITY_SNOW_CLOAK + && ability != ABILITY_OVERCOAT + && ability != ABILITY_ICE_BODY) + return TRUE; + return FALSE; +} + +static u32 GetWeatherDamage(u8 battlerId) +{ + u32 ability = AI_GetAbility(battlerId); + u32 holdEffect = AI_GetHoldEffect(battlerId); + u32 damage = 0; + if (!AI_WeatherHasEffect()) + return 0; + + if (gBattleWeather & WEATHER_SANDSTORM_ANY) + { + if (BattlerAffectedBySandstorm(battlerId, ability) + && !(gStatuses3[battlerId] & (STATUS3_UNDERGROUND | STATUS3_UNDERWATER)) + && holdEffect != HOLD_EFFECT_SAFETY_GOOGLES) + { + damage = gBattleMons[battlerId].maxHP / 16; + if (damage == 0) + damage = 1; + } + } + if ((gBattleWeather & WEATHER_HAIL_ANY) && ability != ABILITY_ICE_BODY) + { + if (BattlerAffectedByHail(battlerId, ability) + && !(gStatuses3[battlerId] & (STATUS3_UNDERGROUND | STATUS3_UNDERWATER)) + && holdEffect != HOLD_EFFECT_SAFETY_GOOGLES) + { + damage = gBattleMons[battlerId].maxHP / 16; + if (damage == 0) + damage = 1; + } + } + return damage; +} + +u32 GetBattlerSecondaryDamage(u8 battlerId) +{ + u32 secondaryDamage; + + if (AI_GetAbility(battlerId) == ABILITY_MAGIC_GUARD) + return FALSE; + + secondaryDamage = GetLeechSeedDamage(battlerId) + + GetNightmareDamage(battlerId) + + GetCurseDamage(battlerId) + + GetTrapDamage(battlerId) + + GetPoisonDamage(battlerId) + + GetWeatherDamage(battlerId); + + return secondaryDamage; +} + +bool32 BattlerWillFaintFromWeather(u8 battler, u16 ability) +{ + if ((BattlerAffectedBySandstorm(battler, ability) || BattlerAffectedByHail(battler, ability)) + && gBattleMons[battler].hp <= gBattleMons[battler].maxHP / 16) + return TRUE; + + return FALSE; +} + +bool32 BattlerWillFaintFromSecondaryDamage(u8 battler, u16 ability) +{ + if (GetBattlerSecondaryDamage(battler) != 0 + && gBattleMons[battler].hp <= gBattleMons[battler].maxHP / 16) + return TRUE; + return FALSE; +} + +static bool32 AnyUsefulStatIsRaised(u8 battler) +{ + u8 statId; + + for (statId = STAT_ATK; statId < NUM_BATTLE_STATS; statId++) + { + if (gBattleMons[battler].statStages[statId] > DEFAULT_STAT_STAGE) + { + switch (statId) + { + case STAT_ATK: + if (HasMoveWithSplit(battler, SPLIT_PHYSICAL)) + return TRUE; + break; + case STAT_SPATK: + if (HasMoveWithSplit(battler, SPLIT_SPECIAL)) + return TRUE; + break; + case STAT_SPEED: + return TRUE; + } + } + } + + return FALSE; +} + +static bool32 PartyBattlerShouldAvoidHazards(u8 currBattler, u8 switchBattler) +{ + struct Pokemon *mon = GetBattlerPartyData(switchBattler); + u16 ability = GetMonAbility(mon); // we know our own party data + u16 holdEffect = GetBattlerHoldEffect(GetMonData(mon, MON_DATA_HELD_ITEM), TRUE); + u32 flags = gSideStatuses[GetBattlerSide(currBattler)] & (SIDE_STATUS_SPIKES | SIDE_STATUS_STEALTH_ROCK | SIDE_STATUS_STICKY_WEB | SIDE_STATUS_TOXIC_SPIKES); + + if (flags == 0) + return FALSE; + + if (ability == ABILITY_MAGIC_GUARD || ability == ABILITY_LEVITATE + || holdEffect == HOLD_EFFECT_HEAVY_DUTY_BOOTS) + return FALSE; + + if (flags & (SIDE_STATUS_SPIKES | SIDE_STATUS_STEALTH_ROCK) && GetMonData(mon, MON_DATA_HP) < (GetMonData(mon, MON_DATA_MAX_HP) / 8)) + return TRUE; + + return FALSE; +} + +enum { + DONT_PIVOT, + CAN_TRY_PIVOT, + PIVOT, +}; +bool32 ShouldPivot(u8 battlerAtk, u8 battlerDef, u16 defAbility, u16 move, u8 moveIndex) +{ + bool8 hasStatBoost = AnyUsefulStatIsRaised(battlerAtk) || gBattleMons[battlerDef].statStages[STAT_EVASION] >= 9; //Significant boost in evasion for any class + u8 backupBattler = gActiveBattler; + bool32 shouldSwitch; + u8 battlerToSwitch; + + gActiveBattler = battlerAtk; + shouldSwitch = ShouldSwitch(); + battlerToSwitch = *(gBattleStruct->AI_monToSwitchIntoId + gActiveBattler); + gActiveBattler = backupBattler; + + if (PartyBattlerShouldAvoidHazards(battlerAtk, battlerToSwitch)) + return DONT_PIVOT; + + if (!IsDoubleBattle()) + { + if (CountUsablePartyMons(battlerAtk) == 0) + return CAN_TRY_PIVOT; // can't switch, but attack might still be useful + + //TODO - predict opponent switching + /*if (IsPredictedToSwitch(battlerDef, battlerAtk) && !hasStatBoost) + return PIVOT; // Try pivoting so you can switch to a better matchup to counter your new opponent*/ + + if (GetWhoStrikesFirst(battlerAtk, battlerDef, TRUE) == 0) // Attacker goes first + { + if (!CanAttackerFaintTarget(battlerAtk, battlerDef, moveIndex, 0)) // Can't KO foe otherwise + { + if (CanAttackerFaintTarget(battlerAtk, battlerDef, moveIndex, 2)) + { + // attacker can kill target in two hits (theoretically) + if (CanTargetFaintAi(battlerDef, battlerAtk)) + return PIVOT; // Won't get the two turns, pivot + + if (!IS_MOVE_STATUS(move) && (shouldSwitch + || (AtMaxHp(battlerDef) && (AI_DATA->defHoldEffect == HOLD_EFFECT_FOCUS_SASH + || defAbility == ABILITY_STURDY || defAbility == ABILITY_MULTISCALE || defAbility == ABILITY_SHADOW_SHIELD)))) + return PIVOT; // pivot to break sash/sturdy/multiscale + } + else if (!hasStatBoost) + { + if (!IS_MOVE_STATUS(move) && (AtMaxHp(battlerDef) && (AI_DATA->defHoldEffect == HOLD_EFFECT_FOCUS_SASH + || defAbility == ABILITY_STURDY || defAbility == ABILITY_MULTISCALE || defAbility == ABILITY_SHADOW_SHIELD))) + return PIVOT; // pivot to break sash/sturdy/multiscale + + if (shouldSwitch) + return PIVOT; + + /* TODO - check if switchable mon unafffected by/will remove hazards + if (gSideStatuses[battlerAtk] & SIDE_STATUS_SPIKES && switchScore >= SWITCHING_INCREASE_CAN_REMOVE_HAZARDS) + return PIVOT;*/ + + /*if (BattlerWillFaintFromSecondaryDamage(battlerAtk, AI_DATA->atkAbility) && switchScore >= SWITCHING_INCREASE_WALLS_FOE) + return PIVOT;*/ + + /*if (IsClassDamager(class) && switchScore >= SWITCHING_INCREASE_HAS_SUPER_EFFECTIVE_MOVE) + { + bool8 physMoveInMoveset = PhysicalMoveInMoveset(battlerAtk); + bool8 specMoveInMoveset = SpecialMoveInMoveset(battlerAtk); + + //Pivot if attacking stats are bad + if (physMoveInMoveset && !specMoveInMoveset) + { + if (STAT_STAGE_ATK < 6) + return PIVOT; + } + else if (!physMoveInMoveset && specMoveInMoveset) + { + if (STAT_STAGE_SPATK < 6) + return PIVOT; + } + else if (physMoveInMoveset && specMoveInMoveset) + { + if (STAT_STAGE_ATK < 6 && STAT_STAGE_SPATK < 6) + return PIVOT; + } + + return CAN_TRY_PIVOT; + }*/ + } + } + } + else // Opponent Goes First + { + if (CanTargetFaintAi(battlerDef, battlerAtk)) + { + if (gBattleMoves[move].effect == EFFECT_TELEPORT) + return DONT_PIVOT; // If you're going to faint because you'll go second, use a different move + else + return CAN_TRY_PIVOT; // You're probably going to faint anyways so if for some reason you don't, better switch + } + else if (CanTargetFaintAiWithMod(battlerDef, battlerAtk, 0, 2)) // Foe can 2HKO AI + { + if (CanAttackerFaintTarget(battlerAtk, battlerDef, moveIndex, 0)) + { + if (!BattlerWillFaintFromSecondaryDamage(battlerAtk, AI_DATA->atkAbility)) + return CAN_TRY_PIVOT; // Use this move to KO if you must + } + else // Can't KO the foe + { + return PIVOT; + } + } + else // Foe can 3HKO+ AI + { + if (CanAttackerFaintTarget(battlerAtk, battlerDef, moveIndex, 0)) + { + if (!BattlerWillFaintFromSecondaryDamage(battlerAtk, AI_DATA->atkAbility) // This is the only move that can KO + && !hasStatBoost) //You're not wasting a valuable stat boost + { + return CAN_TRY_PIVOT; + } + } + else if (CanAttackerFaintTarget(battlerAtk, battlerDef, moveIndex, 2)) + { + // can knock out foe in 2 hits + if (IS_MOVE_STATUS(move) && (shouldSwitch //Damaging move + //&& (switchScore >= SWITCHING_INCREASE_RESIST_ALL_MOVES + SWITCHING_INCREASE_KO_FOE //remove hazards + || (AI_DATA->defHoldEffect == HOLD_EFFECT_FOCUS_SASH && AtMaxHp(battlerDef)))) + return DONT_PIVOT; // Pivot to break the sash + else + return CAN_TRY_PIVOT; + } + else + { + //if (IsClassDamager(class) && switchScore >= SWITCHING_INCREASE_KO_FOE) + //return PIVOT; //Only switch if way better matchup + + if (!hasStatBoost) + { + // TODO - check if switching prevents/removes hazards + //if (gSideStatuses[battlerAtk] & SIDE_STATUS_SPIKES && switchScore >= SWITCHING_INCREASE_CAN_REMOVE_HAZARDS) + //return PIVOT; + + // TODO - not always a good idea + //if (BattlerWillFaintFromSecondaryDamage(battlerAtk) && switchScore >= SWITCHING_INCREASE_HAS_SUPER_EFFECTIVE_MOVE) + //return PIVOT; + + /*if (IsClassDamager(class) && switchScore >= SWITCHING_INCREASE_HAS_SUPER_EFFECTIVE_MOVE) + { + bool8 physMoveInMoveset = PhysicalMoveInMoveset(battlerAtk); + bool8 specMoveInMoveset = SpecialMoveInMoveset(battlerAtk); + + //Pivot if attacking stats are bad + if (physMoveInMoveset && !specMoveInMoveset) + { + if (STAT_STAGE_ATK < 6) + return PIVOT; + } + else if (!physMoveInMoveset && specMoveInMoveset) + { + if (STAT_STAGE_SPATK < 6) + return PIVOT; + } + else if (physMoveInMoveset && specMoveInMoveset) + { + if (STAT_STAGE_ATK < 6 && STAT_STAGE_SPATK < 6) + return PIVOT; + } + }*/ + + return CAN_TRY_PIVOT; + } + } + } + } + } + + return DONT_PIVOT; +} + +bool32 CanKnockOffItem(u8 battler, u16 item) +{ + if (item == ITEM_NONE) + return FALSE; + + if (!(gBattleTypeFlags & (BATTLE_TYPE_EREADER_TRAINER + | BATTLE_TYPE_FRONTIER + | BATTLE_TYPE_LINK + | BATTLE_TYPE_RECORDED_LINK + | BATTLE_TYPE_SECRET_BASE + #if defined B_TRAINERS_KNOCK_OFF_ITEMS + | BATTLE_TYPE_TRAINER + #endif + )) && GetBattlerSide(battler) == B_SIDE_PLAYER) + return FALSE; + + if (AI_GetAbility(battler) == ABILITY_STICKY_HOLD) + return FALSE; + + if (!CanBattlerGetOrLoseItem(battler, item)) + return FALSE; + + return TRUE; +} + +// status checks +bool32 IsBattlerIncapacitated(u8 battler, u16 ability) +{ + if ((gBattleMons[battler].status1 & STATUS1_FREEZE) && !HasThawingMove(battler)) + return TRUE; // if battler has thawing move we assume they will definitely use it, and thus being frozen should be neglected + + if (gBattleMons[battler].status1 & STATUS1_SLEEP) + return TRUE; + + if (gBattleMons[battler].status2 & STATUS2_RECHARGE || (ability == ABILITY_TRUANT && gDisableStructs[battler].truantCounter != 0)) + return TRUE; + + return FALSE; +} + +bool32 CanSleep(u8 battler, u16 ability) +{ + if (ability == ABILITY_INSOMNIA + || ability == ABILITY_VITAL_SPIRIT + || gBattleMons[battler].status1 & STATUS1_ANY + || gSideStatuses[GetBattlerSide(battler)] & SIDE_STATUS_SAFEGUARD + || (gFieldStatuses & (STATUS_FIELD_MISTY_TERRAIN | STATUS_FIELD_ELECTRIC_TERRAIN)) + || IsAbilityStatusProtected(battler)) + return FALSE; + return TRUE; +} + +bool32 AI_CanPutToSleep(u8 battlerAtk, u8 battlerDef, u16 defAbility, u16 move, u16 partnerMove) +{ + if (!CanSleep(battlerDef, defAbility) + || AI_GetMoveEffectiveness(move, battlerAtk, battlerDef) == AI_EFFECTIVENESS_x0 + || DoesSubstituteBlockMove(battlerAtk, battlerDef, move) + || PartnerMoveEffectIsStatusSameTarget(BATTLE_PARTNER(battlerAtk), battlerDef, partnerMove)) // shouldn't try to sleep mon that partner is trying to make sleep + return FALSE; + return TRUE; +} + +bool32 CanBePoisoned(u8 battler, u16 ability) +{ + if (ability == ABILITY_IMMUNITY + || ability == ABILITY_PASTEL_VEIL + || gBattleMons[battler].status1 & STATUS1_ANY + || IsAbilityStatusProtected(battler) + || gSideStatuses[GetBattlerSide(battler)] & SIDE_STATUS_SAFEGUARD) + return FALSE; + return TRUE; +} + +bool32 ShouldPoisonSelf(u8 battler, u16 ability) +{ + if (CanBePoisoned(battler, ability) && ( + ability == ABILITY_MARVEL_SCALE + || ability == ABILITY_POISON_HEAL + || ability == ABILITY_QUICK_FEET + || ability == ABILITY_MAGIC_GUARD + || (ability == ABILITY_TOXIC_BOOST && HasMoveWithSplit(battler, SPLIT_PHYSICAL)) + || (ability == ABILITY_GUTS && HasMoveWithSplit(battler, SPLIT_PHYSICAL)) + || HasMoveEffect(battler, EFFECT_FACADE) + || HasMoveEffect(battler, EFFECT_PSYCHO_SHIFT))) + return TRUE; // battler can be poisoned and has move/ability that synergizes with being poisoned + return FALSE; +} + +bool32 AI_CanPoison(u8 battlerAtk, u8 battlerDef, u16 defAbility, u16 move, u16 partnerMove) +{ + if (!CanBePoisoned(battlerDef, defAbility) + || AI_GetMoveEffectiveness(move, battlerAtk, battlerDef) == AI_EFFECTIVENESS_x0 + || DoesSubstituteBlockMove(battlerAtk, battlerDef, move) + || PartnerMoveEffectIsStatusSameTarget(BATTLE_PARTNER(battlerAtk), battlerDef, partnerMove)) + return FALSE; + else if (defAbility != ABILITY_CORROSION && (IS_BATTLER_OF_TYPE(battlerDef, TYPE_POISON) || IS_BATTLER_OF_TYPE(battlerDef, TYPE_STEEL))) + return FALSE; + else if (IsValidDoubleBattle(battlerAtk) && AI_GetAbility(BATTLE_PARTNER(battlerDef)) == ABILITY_PASTEL_VEIL) + return FALSE; + + return TRUE; +} + +static bool32 CanBeParayzed(u8 battler, u16 ability) +{ + if (ability == ABILITY_LIMBER + || IS_BATTLER_OF_TYPE(battler, TYPE_ELECTRIC) + || gBattleMons[battler].status1 & STATUS1_ANY + || IsAbilityStatusProtected(battler)) + return FALSE; + return TRUE; +} + +bool32 AI_CanParalyze(u8 battlerAtk, u8 battlerDef, u16 defAbility, u16 move, u16 partnerMove) +{ + if (!CanBeParayzed(battlerDef, defAbility) + || AI_GetMoveEffectiveness(move, battlerAtk, battlerDef) == AI_EFFECTIVENESS_x0 + || gSideStatuses[GetBattlerSide(battlerDef)] & SIDE_STATUS_SAFEGUARD + || DoesSubstituteBlockMove(battlerAtk, battlerDef, move) + || PartnerMoveEffectIsStatusSameTarget(BATTLE_PARTNER(battlerAtk), battlerDef, partnerMove)) + return FALSE; + return TRUE; +} + +bool32 CanBeConfused(u8 battler, u16 ability) +{ + if ((gBattleMons[battler].status2 & STATUS2_CONFUSION) + || (ability == ABILITY_OWN_TEMPO) + || (IsBattlerGrounded(battler) && (gFieldStatuses & STATUS_FIELD_MISTY_TERRAIN))) + return FALSE; + return TRUE; +} + +bool32 AI_CanConfuse(u8 battlerAtk, u8 battlerDef, u16 defAbility, u8 battlerAtkPartner, u16 move, u16 partnerMove) +{ + if (!CanBeConfused(battlerDef, defAbility) + || AI_GetMoveEffectiveness(move, battlerAtk, battlerDef) == AI_EFFECTIVENESS_x0 + || gSideStatuses[GetBattlerSide(battlerDef)] & SIDE_STATUS_SAFEGUARD + || DoesSubstituteBlockMove(battlerAtk, battlerDef, move) + || DoesPartnerHaveSameMoveEffect(battlerAtkPartner, battlerDef, move, partnerMove)) + { + return FALSE; + } + + return TRUE; +} + +bool32 CanBeBurned(u8 battler, u16 ability) +{ + if (ability == ABILITY_WATER_VEIL + || ability == ABILITY_WATER_BUBBLE + || IS_BATTLER_OF_TYPE(battler, TYPE_FIRE) + || gBattleMons[battler].status1 & STATUS1_ANY + || IsAbilityStatusProtected(battler) + || gSideStatuses[GetBattlerSide(battler)] & SIDE_STATUS_SAFEGUARD) + return FALSE; + return TRUE; +} + +bool32 ShouldBurnSelf(u8 battler, u16 ability) +{ + if (CanBeBurned(battler, ability) && ( + ability == ABILITY_QUICK_FEET + || ability == ABILITY_HEATPROOF + || ability == ABILITY_MAGIC_GUARD + || (ability == ABILITY_FLARE_BOOST && HasMoveWithSplit(battler, SPLIT_SPECIAL)) + || (ability == ABILITY_GUTS && HasMoveWithSplit(battler, SPLIT_PHYSICAL)) + || HasMoveEffect(battler, EFFECT_FACADE) + || HasMoveEffect(battler, EFFECT_PSYCHO_SHIFT))) + return TRUE; + return FALSE; +} + +bool32 AI_CanBurn(u8 battlerAtk, u8 battlerDef, u16 defAbility, u8 battlerAtkPartner, u16 move, u16 partnerMove) +{ + if (!CanBeBurned(battlerDef, defAbility) + || AI_GetMoveEffectiveness(move, battlerAtk, battlerDef) == AI_EFFECTIVENESS_x0 + || DoesSubstituteBlockMove(battlerAtk, battlerDef, move) + || PartnerMoveEffectIsStatusSameTarget(battlerAtkPartner, battlerDef, partnerMove)) + { + return FALSE; + } + return TRUE; +} + +bool32 AI_CanBeInfatuated(u8 battlerAtk, u8 battlerDef, u16 defAbility, u8 atkGender, u8 defGender) +{ + if ((gBattleMons[battlerDef].status2 & STATUS2_INFATUATION) + || AI_GetMoveEffectiveness(AI_THINKING_STRUCT->moveConsidered, battlerAtk, battlerDef) == AI_EFFECTIVENESS_x0 + || defAbility == ABILITY_OBLIVIOUS + || atkGender == defGender + || atkGender == MON_GENDERLESS + || defGender == MON_GENDERLESS + || IsAbilityOnSide(battlerDef, ABILITY_AROMA_VEIL)) + return FALSE; + return TRUE; +} + +u32 ShouldTryToFlinch(u8 battlerAtk, u8 battlerDef, u16 atkAbility, u16 defAbility, u16 move) +{ + if (defAbility == ABILITY_INNER_FOCUS + || DoesSubstituteBlockMove(battlerAtk, battlerDef, move) + || GetWhoStrikesFirst(battlerAtk, battlerDef, TRUE) == 1) // opponent goes first + { + return 0; // don't try to flinch + } + else if ((gBattleMons[battlerDef].status1 & STATUS1_SLEEP) && !HasMoveEffect(battlerDef, EFFECT_SLEEP_TALK) && !HasMoveEffect(battlerDef, EFFECT_SNORE)) + { + return 0; // don't try to flinch sleeping pokemon + } + else if (atkAbility == ABILITY_SERENE_GRACE + || gBattleMons[battlerDef].status1 & STATUS1_PARALYSIS + || gBattleMons[battlerDef].status2 & STATUS2_INFATUATION + || gBattleMons[battlerDef].status2 & STATUS2_CONFUSION) + { + return 2; // good idea to flinch + } + return 1; // decent idea to flinch +} + +bool32 ShouldTrap(u8 battlerAtk, u8 battlerDef, u16 move) +{ + if (BattlerWillFaintFromSecondaryDamage(battlerDef, AI_DATA->defAbility)) + return TRUE; // battler is taking secondary damage with low HP + + if (AI_THINKING_STRUCT->aiFlags & AI_FLAG_STALL) + { + if (!CanTargetFaintAi(battlerDef, battlerAtk)) + return TRUE; // attacker goes first and opponent can't kill us + } + + return FALSE; +} + +bool32 ShouldFakeOut(u8 battlerAtk, u8 battlerDef, u16 move) +{ + if (AI_DATA->atkHoldEffect == HOLD_EFFECT_CHOICE_BAND && CountUsablePartyMons(battlerAtk) == 0) + return FALSE; // don't lock attacker into fake out if can't switch out + + if (gDisableStructs[battlerAtk].isFirstTurn + && ShouldTryToFlinch(battlerAtk, battlerDef, AI_DATA->atkAbility, AI_DATA->defAbility, move) + && !DoesSubstituteBlockMove(battlerAtk, battlerDef, move)) + return TRUE; + + return FALSE; +} + +static u32 FindMoveUsedXTurnsAgo(u32 battlerId, u32 x) +{ + s32 i, index = BATTLE_HISTORY->moveHistoryIndex[battlerId]; + for (i = 0; i < x; i++) + { + if (--index < 0) + index = AI_MOVE_HISTORY_COUNT - 1; + } + return BATTLE_HISTORY->moveHistory[battlerId][index]; +} + +bool32 IsWakeupTurn(u8 battler) +{ + // Check if rest was used 2 turns ago + if ((gBattleMons[battler].status1 & STATUS1_SLEEP) == 1 && FindMoveUsedXTurnsAgo(battler, 2) == MOVE_REST) + return TRUE; + else // no way to know + return FALSE; +} + +bool32 AnyPartyMemberStatused(u8 battlerId, bool32 checkSoundproof) +{ + struct Pokemon *party; + u32 i; + + if (GetBattlerSide(battlerId) == B_SIDE_PLAYER) + party = gPlayerParty; + else + party = gEnemyParty; + + for (i = 0; i < PARTY_SIZE; i++) + { + if (checkSoundproof && GetMonAbility(&party[i]) == ABILITY_SOUNDPROOF) + continue; + + if (GetMonData(&party[i], MON_DATA_STATUS) != STATUS1_NONE) + return TRUE; + } + + return FALSE; +} + +u16 GetBattlerSideSpeedAverage(u8 battler) +{ + u16 speed1 = 0; + u16 speed2 = 0; + u8 numBattlersAlive = 0; + + if (IsBattlerAlive(battler)) + { + speed1 = GetBattlerTotalSpeedStat(battler); + numBattlersAlive++; + } + + if (IsDoubleBattle() && IsBattlerAlive(BATTLE_PARTNER(battler))) + { + speed2 = GetBattlerTotalSpeedStat(BATTLE_PARTNER(battler)); + numBattlersAlive++; + } + + return (speed1 + speed2) / numBattlersAlive; +} + +bool32 ShouldUseRecoilMove(u8 battlerAtk, u8 battlerDef, u32 recoilDmg, u8 moveIndex) +{ + if (recoilDmg >= gBattleMons[battlerAtk].hp //Recoil kills attacker + && CountUsablePartyMons(battlerDef) != 0) //Foe has more than 1 target left + { + if (recoilDmg >= gBattleMons[battlerDef].hp && !CanAttackerFaintTarget(battlerAtk, battlerDef, moveIndex, 0)) + return TRUE; //If it's the only KO move then just use it + else + return FALSE; //Not as good to use move if you'll faint and not win + } + + return TRUE; +} + +bool32 ShouldAbsorb(u8 battlerAtk, u8 battlerDef, u16 move, s32 damage) +{ + if (move == 0xFFFF || GetWhoStrikesFirst(battlerAtk, gBattlerTarget, TRUE) == 0) + { + // using item or user goes first + u8 healPercent = (gBattleMoves[move].argument == 0) ? 50 : gBattleMoves[move].argument; + s32 healDmg = (healPercent * damage) / 100; + + if (gStatuses3[battlerAtk] & STATUS3_HEAL_BLOCK) + healDmg = 0; + + if (CanTargetFaintAi(battlerDef, battlerAtk) + && !CanTargetFaintAiWithMod(battlerDef, battlerAtk, healDmg, 0)) + return TRUE; // target can faint attacker unless they heal + else if (!CanTargetFaintAi(battlerDef, battlerAtk) && GetHealthPercentage(battlerAtk) < 60 && (Random() % 3)) + return TRUE; // target can't faint attacker at all, attacker health is about half, 2/3rds rate of encouraging healing + } + else + { + // opponent goes first + if (!CanTargetFaintAi(battlerDef, battlerAtk)) + return TRUE; + } + + return FALSE; +} + +bool32 ShouldRecover(u8 battlerAtk, u8 battlerDef, u16 move, u8 healPercent) +{ + if (move == 0xFFFF || GetWhoStrikesFirst(battlerAtk, gBattlerTarget, TRUE) == 0) + { + // using item or user going first + s32 damage = AI_THINKING_STRUCT->simulatedDmg[battlerAtk][battlerDef][AI_THINKING_STRUCT->movesetIndex]; + s32 healAmount = (healPercent * damage) / 100; + if (gStatuses3[battlerAtk] & STATUS3_HEAL_BLOCK) + healAmount = 0; + + if (CanTargetFaintAi(battlerDef, battlerAtk) + && !CanTargetFaintAiWithMod(battlerDef, battlerAtk, healAmount, 0)) + return TRUE; // target can faint attacker unless they heal + else if (!CanTargetFaintAi(battlerDef, battlerAtk) && GetHealthPercentage(battlerAtk) < 60 && (Random() % 3)) + return TRUE; // target can't faint attacker at all, attacker health is about half, 2/3rds rate of encouraging healing + } + return FALSE; +} + +bool32 ShouldSetScreen(u8 battlerAtk, u8 battlerDef, u16 moveEffect) +{ + u8 atkSide = GetBattlerSide(battlerAtk); + switch (moveEffect) + { + case EFFECT_AURORA_VEIL: + // Use only in Hail and only if AI doesn't already have Reflect, Light Screen or Aurora Veil itself active. + if (gBattleWeather & WEATHER_HAIL_ANY + && !(gSideStatuses[atkSide] & (SIDE_STATUS_REFLECT | SIDE_STATUS_LIGHTSCREEN | SIDE_STATUS_AURORA_VEIL))) + return TRUE; + break; + case EFFECT_REFLECT: + // Use only if the player has a physical move and AI doesn't already have Reflect itself active. + if (HasMoveWithSplit(battlerDef, SPLIT_PHYSICAL) + && !(gSideStatuses[atkSide] & SIDE_STATUS_REFLECT)) + return TRUE; + break; + case EFFECT_LIGHT_SCREEN: + // Use only if the player has a special move and AI doesn't already have Light Screen itself active. + if (HasMoveWithSplit(battlerDef, SPLIT_SPECIAL) + && !(gSideStatuses[atkSide] & SIDE_STATUS_LIGHTSCREEN)) + return TRUE; + break; + } + + return FALSE; +} + +// Partner Logic +bool32 IsValidDoubleBattle(u8 battlerAtk) +{ + if (IsDoubleBattle() + && ((IsBattlerAlive(BATTLE_OPPOSITE(battlerAtk)) && IsBattlerAlive(BATTLE_PARTNER(BATTLE_OPPOSITE(battlerAtk)))) || IsBattlerAlive(BATTLE_PARTNER(battlerAtk)))) + return TRUE; + return FALSE; +} + +u16 GetAllyChosenMove(void) +{ + u8 partnerBattler = BATTLE_PARTNER(sBattler_AI); + + if (!IsBattlerAlive(partnerBattler) || !IsBattlerAIControlled(partnerBattler)) + return MOVE_NONE; // TODO: prediction? + else if (partnerBattler > sBattler_AI) // Battler with the lower id chooses the move first. + return MOVE_NONE; + else + return gBattleMons[partnerBattler].moves[gBattleStruct->chosenMovePositions[partnerBattler]]; +} + +bool32 IsTargetingPartner(u8 battlerAtk, u8 battlerDef) +{ + if ((battlerAtk & BIT_SIDE) == (battlerDef & BIT_SIDE)) + return TRUE; + + return FALSE; +} + +//PARTNER_MOVE_EFFECT_IS_SAME +bool32 DoesPartnerHaveSameMoveEffect(u8 battlerAtkPartner, u8 battlerDef, u16 move, u16 partnerMove) +{ + if (!IsDoubleBattle()) + return FALSE; + + if (gBattleMoves[move].effect == gBattleMoves[partnerMove].effect + && gChosenMoveByBattler[battlerAtkPartner] != MOVE_NONE + && gBattleStruct->moveTarget[battlerAtkPartner] == battlerDef) + { + return TRUE; + } + return FALSE; +} + +//PARTNER_MOVE_EFFECT_IS_SAME_NO_TARGET +bool32 PartnerHasSameMoveEffectWithoutTarget(u8 battlerAtkPartner, u16 move, u16 partnerMove) +{ + if (!IsDoubleBattle()) + return FALSE; + + if (gBattleMoves[move].effect == gBattleMoves[partnerMove].effect + && gChosenMoveByBattler[battlerAtkPartner] != MOVE_NONE) + return TRUE; + return FALSE; +} + +//PARTNER_MOVE_EFFECT_IS_STATUS_SAME_TARGET +bool32 PartnerMoveEffectIsStatusSameTarget(u8 battlerAtkPartner, u8 battlerDef, u16 partnerMove) +{ + if (!IsDoubleBattle()) + return FALSE; + + if (gChosenMoveByBattler[battlerAtkPartner] != MOVE_NONE + && gBattleStruct->moveTarget[battlerAtkPartner] == battlerDef + && (gBattleMoves[partnerMove].effect == EFFECT_SLEEP + || gBattleMoves[partnerMove].effect == EFFECT_POISON + || gBattleMoves[partnerMove].effect == EFFECT_TOXIC + || gBattleMoves[partnerMove].effect == EFFECT_PARALYZE + || gBattleMoves[partnerMove].effect == EFFECT_WILL_O_WISP + || gBattleMoves[partnerMove].effect == EFFECT_YAWN)) + return TRUE; + return FALSE; +} + +//PARTNER_MOVE_EFFECT_IS_WEATHER +bool32 PartnerMoveEffectIsWeather(u8 battlerAtkPartner, u16 partnerMove) +{ + if (!IsDoubleBattle()) + return FALSE; + + if (gChosenMoveByBattler[battlerAtkPartner] != MOVE_NONE + && (gBattleMoves[partnerMove].effect == EFFECT_SUNNY_DAY + || gBattleMoves[partnerMove].effect == EFFECT_RAIN_DANCE + || gBattleMoves[partnerMove].effect == EFFECT_SANDSTORM + || gBattleMoves[partnerMove].effect == EFFECT_HAIL)) + return TRUE; + + return FALSE; +} + +//PARTNER_MOVE_EFFECT_IS_TERRAIN +bool32 PartnerMoveEffectIsTerrain(u8 battlerAtkPartner, u16 partnerMove) +{ + if (!IsDoubleBattle()) + return FALSE; + + if (gChosenMoveByBattler[battlerAtkPartner] != MOVE_NONE + && (gBattleMoves[partnerMove].effect == EFFECT_GRASSY_TERRAIN + || gBattleMoves[partnerMove].effect == EFFECT_MISTY_TERRAIN + || gBattleMoves[partnerMove].effect == EFFECT_ELECTRIC_TERRAIN + || gBattleMoves[partnerMove].effect == EFFECT_PSYCHIC_TERRAIN)) + return TRUE; + + return FALSE; +} + +//PARTNER_MOVE_IS_TAILWIND_TRICKROOM +bool32 PartnerMoveIs(u8 battlerAtkPartner, u16 partnerMove, u16 moveCheck) +{ + if (!IsDoubleBattle()) + return FALSE; + + if (gChosenMoveByBattler[battlerAtkPartner] != MOVE_NONE && partnerMove == moveCheck) + return TRUE; + return FALSE; +} + +//PARTNER_MOVE_IS_SAME +bool32 PartnerMoveIsSameAsAttacker(u8 battlerAtkPartner, u8 battlerDef, u16 move, u16 partnerMove) +{ + if (!IsDoubleBattle()) + return FALSE; + + if (gChosenMoveByBattler[battlerAtkPartner] != MOVE_NONE && move == partnerMove && gBattleStruct->moveTarget[battlerAtkPartner] == battlerDef) + return TRUE; + return FALSE; +} + +//PARTNER_MOVE_IS_SAME_NO_TARGET +bool32 PartnerMoveIsSameNoTarget(u8 battlerAtkPartner, u16 move, u16 partnerMove) +{ + if (!IsDoubleBattle()) + return FALSE; + if (gChosenMoveByBattler[battlerAtkPartner] != MOVE_NONE && move == partnerMove) + return TRUE; + return FALSE; +} + +bool32 ShouldUseWishAromatherapy(u8 battlerAtk, u8 battlerDef, u16 move) +{ + u32 i; + u32 firstId, lastId; + struct Pokemon* party; + bool32 hasStatus = FALSE; + bool32 needHealing = FALSE; + + GetAIPartyIndexes(battlerAtk, &firstId, &lastId); + + if (GetBattlerSide(gActiveBattler) == B_SIDE_PLAYER) + party = gPlayerParty; + else + party = gEnemyParty; + + if (CountUsablePartyMons(battlerAtk) == 0 + && (CanTargetFaintAi(battlerDef, battlerAtk) || BattlerWillFaintFromSecondaryDamage(battlerAtk, AI_DATA->atkAbility))) + return FALSE; // Don't heal if last mon and will faint + + for (i = 0; i < PARTY_SIZE; i++) + { + u16 currHp = GetMonData(&party[i], MON_DATA_HP); + u16 maxHp = GetMonData(&party[i], MON_DATA_MAX_HP); + + if (!GetMonData(&party[i], MON_DATA_IS_EGG, NULL) && currHp > 0) + { + if ((currHp * 100) / maxHp < 65 // Less than 65% health remaining + && i >= firstId && i < lastId) // Can only switch to mon on your team + { + needHealing = TRUE; + } + + if (GetMonData(&party[i], MON_DATA_STATUS, NULL) != STATUS1_NONE) + { + if (move != MOVE_HEAL_BELL || GetMonAbility(&party[i]) != ABILITY_SOUNDPROOF) + hasStatus = TRUE; + } + } + } + + if (!IsDoubleBattle()) + { + switch (gBattleMoves[move].effect) + { + case EFFECT_WISH: + if (needHealing) + return TRUE; + break; + case EFFECT_HEAL_BELL: + if (hasStatus) + return TRUE; + } + } + else + { + switch (gBattleMoves[move].effect) + { + case EFFECT_WISH: + return ShouldRecover(battlerAtk, battlerDef, move, 50); // Switch recovery isn't good idea in doubles + case EFFECT_HEAL_BELL: + if (hasStatus) + return TRUE; + } + } + + return FALSE; +} + +// party logic +s32 AI_CalcPartyMonDamage(u16 move, u8 battlerAtk, u8 battlerDef, struct Pokemon *mon) +{ + s32 dmg; + u32 i; + struct BattlePokemon *battleMons = Alloc(sizeof(struct BattlePokemon) * MAX_BATTLERS_COUNT); + + for (i = 0; i < MAX_BATTLERS_COUNT; i++) + battleMons[i] = gBattleMons[i]; + + PokemonToBattleMon(mon, &gBattleMons[battlerAtk]); + dmg = AI_CalcDamage(move, battlerAtk, battlerDef); + + for (i = 0; i < MAX_BATTLERS_COUNT; i++) + gBattleMons[i] = battleMons[i]; + + Free(battleMons); + + return dmg; +} + +s32 CountUsablePartyMons(u8 battlerId) +{ + s32 battlerOnField1, battlerOnField2, i, ret; + struct Pokemon *party; + + if (GetBattlerSide(battlerId) == B_SIDE_PLAYER) + party = gPlayerParty; + else + party = gEnemyParty; + + if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) + { + battlerOnField1 = gBattlerPartyIndexes[battlerId]; + battlerOnField2 = gBattlerPartyIndexes[GetBattlerAtPosition(GetBattlerPosition(battlerId) ^ BIT_FLANK)]; + } + else // In singles there's only one battlerId by side. + { + battlerOnField1 = gBattlerPartyIndexes[battlerId]; + battlerOnField2 = gBattlerPartyIndexes[battlerId]; + } + + ret = 0; + for (i = 0; i < PARTY_SIZE; i++) + { + if (i != battlerOnField1 && i != battlerOnField2 + && GetMonData(&party[i], MON_DATA_HP) != 0 + && GetMonData(&party[i], MON_DATA_SPECIES2) != SPECIES_NONE + && GetMonData(&party[i], MON_DATA_SPECIES2) != SPECIES_EGG) + { + ret++; + } + } + + return ret; +} + +bool32 IsPartyFullyHealedExceptBattler(u8 battlerId) +{ + struct Pokemon *party; + u32 i; + + if (GetBattlerSide(battlerId) == B_SIDE_PLAYER) + party = gPlayerParty; + else + party = gEnemyParty; + + for (i = 0; i < PARTY_SIZE; i++) + { + if (i != gBattlerPartyIndexes[battlerId] + && GetMonData(&party[i], MON_DATA_HP) != 0 + && GetMonData(&party[i], MON_DATA_SPECIES2) != SPECIES_NONE + && GetMonData(&party[i], MON_DATA_SPECIES2) != SPECIES_EGG + && GetMonData(&party[i], MON_DATA_HP) < GetMonData(&party[i], MON_DATA_MAX_HP)) + return FALSE; + } + return TRUE; +} + +bool32 PartyHasMoveSplit(u8 battlerId, u8 split) +{ + u8 firstId, lastId; + struct Pokemon* party = GetBattlerPartyData(battlerId); + u32 i, j; + + for (i = 0; i < PARTY_SIZE; i++) + { + if (GetMonData(&party[i], MON_DATA_HP, NULL) == 0) + continue; + + for (j = 0; j < MAX_MON_MOVES; j++) + { + u16 move = GetMonData(&party[i], MON_DATA_MOVE1 + j, NULL); + u16 pp = GetMonData(&party[i], MON_DATA_PP1 + j, NULL); + + if (pp > 0 && move != MOVE_NONE) + { + //TODO - handle photon geyser, light that burns the sky + if (gBattleMoves[move].split == split) + return TRUE; + } + } + } + + return FALSE; +} + +bool32 SideHasMoveSplit(u8 battlerId, u8 split) +{ + if (IsDoubleBattle()) + { + if (HasMoveWithSplit(battlerId, split) || HasMoveWithSplit(BATTLE_PARTNER(battlerId), split)) + return TRUE; + } + else + { + if (HasMoveWithSplit(battlerId, split)) + return TRUE; + } + return FALSE; +} + +bool32 IsAbilityOfRating(u16 ability, s8 rating) +{ + if (sAiAbilityRatings[ability] >= rating) + return TRUE; + return FALSE; +} + +s8 GetAbilityRating(u16 ability) +{ + return sAiAbilityRatings[ability]; +} + +static const u16 sRecycleEncouragedItems[] = +{ + ITEM_CHESTO_BERRY, + ITEM_LUM_BERRY, + ITEM_STARF_BERRY, + ITEM_SITRUS_BERRY, + ITEM_MICLE_BERRY, + ITEM_CUSTAP_BERRY, + ITEM_MENTAL_HERB, + #ifdef ITEM_EXPANSION + ITEM_FOCUS_SASH, + #endif + // TODO expand this +}; + +bool32 IsRecycleEncouragedItem(u16 item) +{ + u32 i; + for (i = 0; i < ARRAY_COUNT(sRecycleEncouragedItems); i++) + { + if (item == sRecycleEncouragedItems[i]) + return TRUE; + } + return FALSE; +} + +// score increases +#define STAT_UP_2_STAGE 8 +#define STAT_UP_STAGE 10 +void IncreaseStatUpScore(u8 battlerAtk, u8 battlerDef, u8 statId, s16 *score) +{ + if (AI_DATA->atkAbility == ABILITY_CONTRARY) + return; + + if (GetHealthPercentage(battlerAtk) < 80 && AI_RandLessThan(128)) + return; + + switch (statId) + { + case STAT_ATK: + if (HasMoveWithSplit(battlerAtk, SPLIT_PHYSICAL) && GetHealthPercentage(battlerAtk) > 40) + { + if (gBattleMons[battlerAtk].statStages[STAT_ATK] < STAT_UP_2_STAGE) + *score += 2; + else if (gBattleMons[battlerAtk].statStages[STAT_ATK] < STAT_UP_STAGE) + *(score)++; + } + if (HasMoveEffect(battlerAtk, EFFECT_FOUL_PLAY)) + *(score)++; + break; + case STAT_DEF: + if ((HasMoveWithSplit(battlerDef, SPLIT_PHYSICAL)|| IS_MOVE_PHYSICAL(gLastMoves[battlerDef])) + && GetHealthPercentage(battlerAtk) > 70) + { + if (gBattleMons[battlerAtk].statStages[STAT_DEF] < STAT_UP_2_STAGE) + *score += 2; // seems better to raise def at higher HP + else if (gBattleMons[battlerAtk].statStages[STAT_DEF] < STAT_UP_STAGE) + *(score)++; + } + break; + case STAT_SPEED: + if (IsAiFaster(AI_CHECK_SLOWER)) + { + if (gBattleMons[battlerAtk].statStages[STAT_SPEED] < STAT_UP_2_STAGE) + *score += 2; + else if (gBattleMons[battlerAtk].statStages[STAT_SPEED] < STAT_UP_STAGE) + *(score)++; + } + break; + case STAT_SPATK: + if (HasMoveWithSplit(battlerAtk, SPLIT_SPECIAL) && GetHealthPercentage(battlerAtk) > 40) + { + if (gBattleMons[battlerAtk].statStages[STAT_SPATK] < STAT_UP_2_STAGE) + *score += 2; + else if (gBattleMons[battlerAtk].statStages[STAT_SPATK] < STAT_UP_STAGE) + *(score)++; + } + break; + case STAT_SPDEF: + if ((HasMoveWithSplit(battlerDef, SPLIT_SPECIAL) || IS_MOVE_SPECIAL(gLastMoves[battlerDef])) + && GetHealthPercentage(battlerAtk) > 70) + { + if (gBattleMons[battlerAtk].statStages[STAT_SPDEF] < STAT_UP_2_STAGE) + *score += 2; // seems better to raise spdef at higher HP + else if (gBattleMons[battlerAtk].statStages[STAT_SPDEF] < STAT_UP_STAGE) + *(score)++; + } + break; + case STAT_ACC: + if (HasMoveWithLowAccuracy(battlerAtk, battlerDef, 80, TRUE, AI_DATA->atkAbility, AI_DATA->defAbility, AI_DATA->atkHoldEffect, AI_DATA->defHoldEffect)) + *score += 2; // has moves with less than 80% accuracy + else if (HasMoveWithLowAccuracy(battlerAtk, battlerDef, 90, TRUE, AI_DATA->atkAbility, AI_DATA->defAbility, AI_DATA->atkHoldEffect, AI_DATA->defHoldEffect)) + *(score)++; + break; + case STAT_EVASION: + if (!BattlerWillFaintFromWeather(battlerAtk, AI_DATA->atkAbility)) + { + if (!GetBattlerSecondaryDamage(battlerAtk) && !(gStatuses3[battlerAtk] & STATUS3_ROOTED)) + *score += 2; + else + *(score)++; + } + break; + } +} + +void IncreasePoisonScore(u8 battlerAtk, u8 battlerDef, u16 move, s16 *score) +{ + if (AI_CanPoison(battlerAtk, battlerDef, AI_DATA->defAbility, move, AI_DATA->partnerMove) && GetHealthPercentage(battlerDef) > 20) + { + if (!HasDamagingMove(battlerDef)) + *score += 2; + + if (AI_THINKING_STRUCT->aiFlags & AI_FLAG_STALL && HasMoveEffect(battlerAtk, EFFECT_PROTECT)) + (*score)++; // stall tactic + + if (HasMoveEffect(battlerAtk, EFFECT_VENOSHOCK) + || HasMoveEffect(battlerAtk, EFFECT_HEX) + || HasMoveEffect(battlerAtk, EFFECT_VENOM_DRENCH) + || AI_DATA->atkAbility == ABILITY_MERCILESS) + *(score) += 2; + else + *(score)++; + } +} + +void IncreaseBurnScore(u8 battlerAtk, u8 battlerDef, u16 move, s16 *score) +{ + if (AI_CanBurn(battlerAtk, battlerDef, AI_DATA->defAbility, AI_DATA->battlerAtkPartner, move, AI_DATA->partnerMove)) + { + (*score)++; // burning is good + if (HasMoveWithSplit(battlerDef, SPLIT_PHYSICAL)) + { + if (CanTargetFaintAi(battlerDef, battlerAtk)) + *score += 2; // burning the target to stay alive is cool + } + + if (HasMoveEffect(battlerAtk, EFFECT_HEX) || HasMoveEffect(AI_DATA->battlerAtkPartner, EFFECT_HEX)) + (*score)++; + } +} + +void IncreaseParalyzeScore(u8 battlerAtk, u8 battlerDef, u16 move, s16 *score) +{ + if (AI_CanParalyze(battlerAtk, battlerDef, AI_DATA->defAbility, move, AI_DATA->partnerMove)) + { + u8 atkSpeed = GetBattlerTotalSpeedStat(battlerAtk); + u8 defSpeed = GetBattlerTotalSpeedStat(battlerDef); + + if ((defSpeed >= atkSpeed && defSpeed / 2 < atkSpeed) // You'll go first after paralyzing foe + || HasMoveEffect(battlerAtk, EFFECT_HEX) + || HasMoveEffect(battlerAtk, EFFECT_FLINCH_HIT) + || gBattleMons[battlerDef].status2 & STATUS2_INFATUATION + || gBattleMons[battlerDef].status2 & STATUS2_CONFUSION) + *score += 4; + else + *score += 2; + } +} + +void IncreaseSleepScore(u8 battlerAtk, u8 battlerDef, u16 move, s16 *score) +{ + if (AI_CanPutToSleep(battlerAtk, battlerDef, AI_DATA->defAbility, move, AI_DATA->partnerMove)) + *score += 2; + else + return; + + if ((HasMoveEffect(battlerAtk, EFFECT_DREAM_EATER) || HasMoveEffect(battlerAtk, EFFECT_NIGHTMARE)) + && !(HasMoveEffect(battlerDef, EFFECT_SNORE) || HasMoveEffect(battlerDef, EFFECT_SLEEP_TALK))) + (*score)++; + + if (HasMoveEffect(battlerAtk, EFFECT_HEX) || HasMoveEffect(AI_DATA->battlerAtkPartner, EFFECT_HEX)) + (*score)++; +} + +void IncreaseConfusionScore(u8 battlerAtk, u8 battlerDef, u16 move, s16 *score) +{ + if (AI_CanConfuse(battlerAtk, battlerDef, AI_DATA->defAbility, AI_DATA->battlerAtkPartner, move, AI_DATA->partnerMove) + && AI_DATA->defHoldEffect != HOLD_EFFECT_CURE_CONFUSION + && AI_DATA->defHoldEffect != HOLD_EFFECT_CURE_STATUS) + { + if (gBattleMons[battlerDef].status1 & STATUS1_PARALYSIS + || gBattleMons[battlerDef].status2 & STATUS2_INFATUATION + || (AI_DATA->atkAbility == ABILITY_SERENE_GRACE && HasMoveEffect(battlerAtk, EFFECT_FLINCH_HIT))) + *score += 3; + else + *score += 2; + } +} diff --git a/src/battle_controller_link_opponent.c b/src/battle_controller_link_opponent.c index 91c00c879..556264aa2 100644 --- a/src/battle_controller_link_opponent.c +++ b/src/battle_controller_link_opponent.c @@ -1,6 +1,6 @@ #include "global.h" #include "battle.h" -#include "battle_ai_script_commands.h" +#include "battle_ai_main.h" #include "battle_anim.h" #include "battle_controllers.h" #include "battle_interface.h" diff --git a/src/battle_controller_link_partner.c b/src/battle_controller_link_partner.c index 011b319df..5ca15f5d7 100644 --- a/src/battle_controller_link_partner.c +++ b/src/battle_controller_link_partner.c @@ -1,6 +1,6 @@ #include "global.h" #include "battle.h" -#include "battle_ai_script_commands.h" +#include "battle_ai_main.h" #include "battle_anim.h" #include "battle_controllers.h" #include "battle_interface.h" diff --git a/src/battle_controller_opponent.c b/src/battle_controller_opponent.c index 71fd9616d..4eeef55c3 100644 --- a/src/battle_controller_opponent.c +++ b/src/battle_controller_opponent.c @@ -1,6 +1,6 @@ #include "global.h" #include "battle.h" -#include "battle_ai_script_commands.h" +#include "battle_ai_main.h" #include "battle_anim.h" #include "battle_arena.h" #include "battle_controllers.h" diff --git a/src/battle_controller_player_partner.c b/src/battle_controller_player_partner.c index 6a07d7d37..a846e3632 100644 --- a/src/battle_controller_player_partner.c +++ b/src/battle_controller_player_partner.c @@ -1,6 +1,6 @@ #include "global.h" #include "battle.h" -#include "battle_ai_script_commands.h" +#include "battle_ai_main.h" #include "battle_anim.h" #include "battle_controllers.h" #include "battle_message.h" diff --git a/src/battle_controller_recorded_opponent.c b/src/battle_controller_recorded_opponent.c index 6bee257c5..3ff74ecda 100644 --- a/src/battle_controller_recorded_opponent.c +++ b/src/battle_controller_recorded_opponent.c @@ -1,6 +1,6 @@ #include "global.h" #include "battle.h" -#include "battle_ai_script_commands.h" +#include "battle_ai_main.h" #include "battle_anim.h" #include "battle_controllers.h" #include "battle_interface.h" diff --git a/src/battle_controller_recorded_player.c b/src/battle_controller_recorded_player.c index 2b5cdc788..4a725119c 100644 --- a/src/battle_controller_recorded_player.c +++ b/src/battle_controller_recorded_player.c @@ -1,6 +1,6 @@ #include "global.h" #include "battle.h" -#include "battle_ai_script_commands.h" +#include "battle_ai_main.h" #include "battle_anim.h" #include "battle_controllers.h" #include "battle_message.h" diff --git a/src/battle_controllers.c b/src/battle_controllers.c index 9c08a7470..fe597d730 100644 --- a/src/battle_controllers.c +++ b/src/battle_controllers.c @@ -1,6 +1,6 @@ #include "global.h" #include "battle.h" -#include "battle_ai_script_commands.h" +#include "battle_ai_main.h" #include "battle_anim.h" #include "battle_controllers.h" #include "battle_message.h" diff --git a/src/battle_debug.c b/src/battle_debug.c index 461f84158..d75ba8471 100644 --- a/src/battle_debug.c +++ b/src/battle_debug.c @@ -18,7 +18,8 @@ #include "text_window.h" #include "international_string_util.h" #include "strings.h" -#include "battle_ai_script_commands.h" +#include "battle_ai_main.h" +#include "battle_ai_util.h" #include "list_menu.h" #include "decompress.h" #include "trainer_pokemon_sprites.h" @@ -32,6 +33,7 @@ #include "constants/moves.h" #include "constants/items.h" #include "constants/rgb.h" +#include "constants/hold_effects.h" #define MAX_MODIFY_DIGITS 4 @@ -98,6 +100,7 @@ enum LIST_ITEM_SIDE_STATUS, LIST_ITEM_AI, LIST_ITEM_AI_MOVES_PTS, + LIST_ITEM_AI_INFO, LIST_ITEM_VARIOUS, LIST_ITEM_COUNT }; @@ -149,7 +152,11 @@ enum VARIOUS_IN_LOVE, }; +// Static Declarations +static const u8 *GetHoldEffectName(u16 holdEffect); + // const rom data +static const u8 sText_HoldEffect[] = _("Hold Effect"); static const u8 sText_Ability[] = _("Ability"); static const u8 sText_Moves[] = _("Moves"); static const u8 sText_Stats[] = _("Stats"); @@ -222,6 +229,7 @@ static const u8 sText_HpAware[] = _("HP aware"); static const u8 sText_Unknown[] = _("Unknown"); static const u8 sText_InLove[] = _("In Love"); static const u8 sText_AIMovePts[] = _("AI Move Pts"); +static const u8 sText_AiKnowledge[] = _("AI Info"); static const u8 sText_EffectOverride[] = _("Effect Override"); static const u8 sText_EmptyString[] = _(""); @@ -319,6 +327,7 @@ static const struct ListMenuItem sMainListItems[] = {sText_SideStatus, LIST_ITEM_SIDE_STATUS}, {sText_AI, LIST_ITEM_AI}, {sText_AIMovePts, LIST_ITEM_AI_MOVES_PTS}, + {sText_AiKnowledge, LIST_ITEM_AI_INFO}, {sText_Various, LIST_ITEM_VARIOUS}, }; @@ -737,9 +746,15 @@ static void Task_ShowAiPoints(u8 taskId) { if (i != data->aiBattlerId && IsBattlerAlive(i)) { + #ifndef POKEMON_EXPANSION data->aiIconSpriteIds[i] = CreateMonIcon(gBattleMons[i].species, SpriteCallbackDummy, 95 + (count * 60), 17, 0, 0, FALSE); + #else + data->aiIconSpriteIds[i] = CreateMonIcon(gBattleMons[i].species, + SpriteCallbackDummy, + 95 + (count * 60), 17, 0, 0); + #endif gSprites[data->aiIconSpriteIds[i]].data[0] = i; // battler id count++; } @@ -748,11 +763,19 @@ static void Task_ShowAiPoints(u8 taskId) data->aiIconSpriteIds[i] = 0xFF; } } + #ifndef POKEMON_EXPANSION data->aiMonSpriteId = CreateMonPicSprite_HandleDeoxys(gBattleMons[data->aiBattlerId].species, gBattleMons[data->aiBattlerId].otId, gBattleMons[data->aiBattlerId].personality, TRUE, 39, 130, 15, 0xFFFF); + #else + data->aiMonSpriteId = CreateMonPicSprite(gBattleMons[data->aiBattlerId].species, + gBattleMons[data->aiBattlerId].otId, + gBattleMons[data->aiBattlerId].personality, + TRUE, + 39, 130, 15, 0xFFFF); + #endif data->aiViewState++; break; // Put text @@ -783,6 +806,128 @@ static void SwitchToAiPointsView(u8 taskId) GetStructPtr(taskId)->aiViewState = 0; } +static const u8 *const sAiInfoItemNames[] = +{ + sText_Ability, + sText_HeldItem, + sText_HoldEffect, +}; +static void PutAiInfoText(struct BattleDebugMenu *data) +{ + u32 i, j, count; + u8 *text = malloc(0x50); + + FillWindowPixelBuffer(data->aiMovesWindowId, 0x11); + + // item names + for (i = 0; i < ARRAY_COUNT(sAiInfoItemNames); i++) + { + AddTextPrinterParameterized(data->aiMovesWindowId, 1, sAiInfoItemNames[i], 3, i * 15, 0, NULL); + } + + // items info + for (i = 0; i < gBattlersCount; i++) + { + if (GET_BATTLER_SIDE(i) == B_SIDE_PLAYER && IsBattlerAlive(i)) + { + u16 ability = AI_GetAbility(i); + u16 holdEffect = AI_GetHoldEffect(i); + u16 item = gBattleMons[i].item; + u8 x = (i == B_POSITION_PLAYER_LEFT) ? 83 + (i) * 75 : 83 + (i-1) * 75; + AddTextPrinterParameterized(data->aiMovesWindowId, 0, gAbilityNames[ability], x, 0, 0, NULL); + AddTextPrinterParameterized(data->aiMovesWindowId, 0, ItemId_GetName(item), x, 15, 0, NULL); + AddTextPrinterParameterized(data->aiMovesWindowId, 0, GetHoldEffectName(holdEffect), x, 30, 0, NULL); + } + } + + CopyWindowToVram(data->aiMovesWindowId, 3); + free(text); +} + +static void Task_ShowAiKnowledge(u8 taskId) +{ + u32 i, count; + struct WindowTemplate winTemplate; + struct BattleDebugMenu *data = GetStructPtr(taskId); + + switch (data->aiViewState) + { + case 0: + HideBg(0); + ShowBg(1); + + // Swap battler if it's player mon + data->aiBattlerId = data->battlerId; + while (!IsBattlerAIControlled(data->aiBattlerId)) + { + if (++data->aiBattlerId >= gBattlersCount) + data->aiBattlerId = 0; + } + + LoadMonIconPalettes(); + for (count = 0, i = 0; i < MAX_BATTLERS_COUNT; i++) + { + if (GET_BATTLER_SIDE(i) == B_SIDE_PLAYER && IsBattlerAlive(i)) + { + #ifndef POKEMON_EXPANSION + data->aiIconSpriteIds[i] = CreateMonIcon(gBattleMons[i].species, + SpriteCallbackDummy, + 95 + (count * 80), 17, 0, 0, FALSE); + #else + data->aiIconSpriteIds[i] = CreateMonIcon(gBattleMons[i].species, + SpriteCallbackDummy, + 95 + (count * 80), 17, 0, 0); + #endif + gSprites[data->aiIconSpriteIds[i]].data[0] = i; // battler id + count++; + } + else + { + data->aiIconSpriteIds[i] = 0xFF; + } + } + #ifndef POKEMON_EXPANSION + data->aiMonSpriteId = CreateMonPicSprite_HandleDeoxys(gBattleMons[data->aiBattlerId].species, + gBattleMons[data->aiBattlerId].otId, + gBattleMons[data->aiBattlerId].personality, + TRUE, + 39, 130, 15, 0xFFFF); + #else + data->aiMonSpriteId = CreateMonPicSprite(gBattleMons[data->aiBattlerId].species, + gBattleMons[data->aiBattlerId].otId, + gBattleMons[data->aiBattlerId].personality, + TRUE, + 39, 130, 15, 0xFFFF); + #endif + data->aiViewState++; + break; + // Put text + case 1: + winTemplate = CreateWindowTemplate(1, 0, 4, 27, 14, 15, 0x200); + data->aiMovesWindowId = AddWindow(&winTemplate); + PutWindowTilemap(data->aiMovesWindowId); + PutAiInfoText(data); + data->aiViewState++; + break; + // Input + case 2: + if (gMain.newKeys & (SELECT_BUTTON | B_BUTTON)) + { + SwitchToDebugView(taskId); + HideBg(1); + ShowBg(0); + return; + } + break; + } +} + +static void SwitchToAiInfoView(u8 taskId) +{ + gTasks[taskId].func = Task_ShowAiKnowledge; + GetStructPtr(taskId)->aiViewState = 0; +} + static void SwitchToDebugView(u8 taskId) { u32 i; @@ -844,6 +989,11 @@ static void Task_DebugMenuProcessInput(u8 taskId) SwitchToAiPointsView(taskId); return; } + else if (listItemId == LIST_ITEM_AI_INFO && gMain.newKeys & A_BUTTON) + { + SwitchToAiInfoView(taskId); + return; + } data->currentMainListItemId = listItemId; // Create the secondary menu list. @@ -1040,6 +1190,7 @@ static void CreateSecondaryListMenu(struct BattleDebugMenu *data) itemsCount = ARRAY_COUNT(sSideStatusListItems); break; case LIST_ITEM_AI_MOVES_PTS: + case LIST_ITEM_AI_INFO: return; } @@ -1677,3 +1828,289 @@ static void UpdateMonData(struct BattleDebugMenu *data) } } } + +static const u8 sText_HoldEffectNone[] = _("????????"); +static const u8 sText_HoldEffectRestoreHp[] = _("Restore Hp"); +static const u8 sText_HoldEffectCurePar[] = _("Cure Par"); +static const u8 sText_HoldEffectCureSlp[] = _("Cure Slp"); +static const u8 sText_HoldEffectCurePsn[] = _("Cure Psn"); +static const u8 sText_HoldEffectCureBrn[] = _("Cure Brn"); +static const u8 sText_HoldEffectCureFrz[] = _("Cure Frz"); +static const u8 sText_HoldEffectRestorePp[] = _("Restore Pp"); +static const u8 sText_HoldEffectCureConfusion[] = _("Cure Confusion"); +static const u8 sText_HoldEffectCureStatus[] = _("Cure Status"); +static const u8 sText_HoldEffectConfuseSpicy[] = _("Confuse Spicy"); +static const u8 sText_HoldEffectConfuseDry[] = _("Confuse Dry"); +static const u8 sText_HoldEffectConfuseSweet[] = _("Confuse Sweet"); +static const u8 sText_HoldEffectConfuseBitter[] = _("Confuse Bitter"); +static const u8 sText_HoldEffectConfuseSour[] = _("Confuse Sour"); +static const u8 sText_HoldEffectAttackUp[] = _("Attack Up"); +static const u8 sText_HoldEffectDefenseUp[] = _("Defense Up"); +static const u8 sText_HoldEffectSpeedUp[] = _("Speed Up"); +static const u8 sText_HoldEffectSpAttackUp[] = _("Sp Attack Up"); +static const u8 sText_HoldEffectSpDefenseUp[] = _("Sp Defense Up"); +static const u8 sText_HoldEffectCriticalUp[] = _("Critical Up"); +static const u8 sText_HoldEffectRandomStatUp[] = _("Random Stat Up"); +static const u8 sText_HoldEffectEvasionUp[] = _("Evasion Up"); +static const u8 sText_HoldEffectRestoreStats[] = _("Restore Stats"); +static const u8 sText_HoldEffectMachoBrace[] = _("Macho Brace"); +static const u8 sText_HoldEffectExpShare[] = _("Exp Share"); +static const u8 sText_HoldEffectQuickClaw[] = _("Quick Claw"); +static const u8 sText_HoldEffectFriendshipUp[] = _("Friendship Up"); +static const u8 sText_HoldEffectMentalHerb[] = _("Mental Herb"); +static const u8 sText_HoldEffectChoiceBand[] = _("Choice Band"); +static const u8 sText_HoldEffectFlinch[] = _("Flinch"); +static const u8 sText_HoldEffectBugPower[] = _("Bug Power"); +static const u8 sText_HoldEffectDoublePrize[] = _("Double Prize"); +static const u8 sText_HoldEffectRepel[] = _("Repel"); +static const u8 sText_HoldEffectSoulDew[] = _("Soul Dew"); +static const u8 sText_HoldEffectDeepSeaTooth[] = _("Deep Sea Tooth"); +static const u8 sText_HoldEffectDeepSeaScale[] = _("Deep Sea Scale"); +static const u8 sText_HoldEffectCanAlwaysRun[] = _("Can Always Run"); +static const u8 sText_HoldEffectPreventEvolve[] = _("Prevent Evolve"); +static const u8 sText_HoldEffectFocusBand[] = _("Focus Band"); +static const u8 sText_HoldEffectLuckyEgg[] = _("Lucky Egg"); +static const u8 sText_HoldEffectScopeLens[] = _("Scope Lens"); +static const u8 sText_HoldEffectSteelPower[] = _("Steel Power"); +static const u8 sText_HoldEffectLeftovers[] = _("Leftovers"); +static const u8 sText_HoldEffectDragonScale[] = _("Dragon Scale"); +static const u8 sText_HoldEffectLightBall[] = _("Light Ball"); +static const u8 sText_HoldEffectGroundPower[] = _("Ground Power"); +static const u8 sText_HoldEffectRockPower[] = _("Rock Power"); +static const u8 sText_HoldEffectGrassPower[] = _("Grass Power"); +static const u8 sText_HoldEffectDarkPower[] = _("Dark Power"); +static const u8 sText_HoldEffectFightingPower[] = _("Fighting Power"); +static const u8 sText_HoldEffectElectricPower[] = _("Electric Power"); +static const u8 sText_HoldEffectWaterPower[] = _("Water Power"); +static const u8 sText_HoldEffectFlyingPower[] = _("Flying Power"); +static const u8 sText_HoldEffectPoisonPower[] = _("Poison Power"); +static const u8 sText_HoldEffectIcePower[] = _("Ice Power"); +static const u8 sText_HoldEffectGhostPower[] = _("Ghost Power"); +static const u8 sText_HoldEffectPsychicPower[] = _("Psychic Power"); +static const u8 sText_HoldEffectFirePower[] = _("Fire Power"); +static const u8 sText_HoldEffectDragonPower[] = _("Dragon Power"); +static const u8 sText_HoldEffectNormalPower[] = _("Normal Power"); +static const u8 sText_HoldEffectUpGrade[] = _("Up Grade"); +static const u8 sText_HoldEffectShellBell[] = _("Shell Bell"); +static const u8 sText_HoldEffectLuckyPunch[] = _("Lucky Punch"); +static const u8 sText_HoldEffectMetalPowder[] = _("Metal Powder"); +static const u8 sText_HoldEffectThickClub[] = _("Thick Club"); +static const u8 sText_HoldEffectStick[] = _("Stick"); +static const u8 sText_HoldEffectChoiceScarf[] = _("Choice Scarf"); +static const u8 sText_HoldEffectChoiceSpecs[] = _("Choice Specs"); +static const u8 sText_HoldEffectDampRock[] = _("Damp Rock"); +static const u8 sText_HoldEffectGripClaw[] = _("Grip Claw"); +static const u8 sText_HoldEffectHeatRock[] = _("Heat Rock"); +static const u8 sText_HoldEffectIcyRock[] = _("Icy Rock"); +static const u8 sText_HoldEffectLightClay[] = _("Light Clay"); +static const u8 sText_HoldEffectSmoothRock[] = _("Smooth Rock"); +static const u8 sText_HoldEffectPowerHerb[] = _("Power Herb"); +static const u8 sText_HoldEffectBigRoot[] = _("Big Root"); +static const u8 sText_HoldEffectExpertBelt[] = _("Expert Belt"); +static const u8 sText_HoldEffectLifeOrb[] = _("Life Orb"); +static const u8 sText_HoldEffectMetronome[] = _("Metronome"); +static const u8 sText_HoldEffectMuscleBand[] = _("Muscle Band"); +static const u8 sText_HoldEffectWideLens[] = _("Wide Lens"); +static const u8 sText_HoldEffectWiseGlasses[] = _("Wise Glasses"); +static const u8 sText_HoldEffectZoomLens[] = _("Zoom Lens"); +static const u8 sText_HoldEffectLaggingTail[] = _("Lagging Tail"); +static const u8 sText_HoldEffectFocusSash[] = _("Focus Sash"); +static const u8 sText_HoldEffectFlameOrb[] = _("Flame Orb"); +static const u8 sText_HoldEffectToxicOrb[] = _("Toxic Orb"); +static const u8 sText_HoldEffectStickyBarb[] = _("Sticky Barb"); +static const u8 sText_HoldEffectIronBall[] = _("Iron Ball"); +static const u8 sText_HoldEffectBlackSludge[] = _("Black Sludge"); +static const u8 sText_HoldEffectDestinyKnot[] = _("Destiny Knot"); +static const u8 sText_HoldEffectShedShell[] = _("Shed Shell"); +static const u8 sText_HoldEffectQuickPowder[] = _("Quick Powder"); +static const u8 sText_HoldEffectAdamantOrb[] = _("Adamant Orb"); +static const u8 sText_HoldEffectLustrousOrb[] = _("Lustrous Orb"); +static const u8 sText_HoldEffectGriseousOrb[] = _("Griseous Orb"); +static const u8 sText_HoldEffectGracidea[] = _("Gracidea"); +static const u8 sText_HoldEffectResistBerry[] = _("Resist Berry"); +static const u8 sText_HoldEffectPowerItem[] = _("Power Item"); +static const u8 sText_HoldEffectRestorePctHp[] = _("Restore Pct Hp"); +static const u8 sText_HoldEffectMicleBerry[] = _("Micle Berry"); +static const u8 sText_HoldEffectCustapBerry[] = _("Custap Berry"); +static const u8 sText_HoldEffectJabocaBerry[] = _("Jaboca Berry"); +static const u8 sText_HoldEffectRowapBerry[] = _("Rowap Berry"); +static const u8 sText_HoldEffectKeeBerry[] = _("Kee Berry"); +static const u8 sText_HoldEffectMarangaBerry[] = _("Maranga Berry"); +static const u8 sText_HoldEffectFloatStone[] = _("Float Stone"); +static const u8 sText_HoldEffectEviolite[] = _("Eviolite"); +static const u8 sText_HoldEffectAssaultVest[] = _("Assault Vest"); +static const u8 sText_HoldEffectDrive[] = _("Drive"); +static const u8 sText_HoldEffectGems[] = _("Gems"); +static const u8 sText_HoldEffectRockyHelmet[] = _("Rocky Helmet"); +static const u8 sText_HoldEffectAirBalloon[] = _("Air Balloon"); +static const u8 sText_HoldEffectRedCard[] = _("Red Card"); +static const u8 sText_HoldEffectRingTarget[] = _("Ring Target"); +static const u8 sText_HoldEffectBindingBand[] = _("Binding Band"); +static const u8 sText_HoldEffectEjectButton[] = _("Eject Button"); +static const u8 sText_HoldEffectAbsorbBulb[] = _("Absorb Bulb"); +static const u8 sText_HoldEffectCellBattery[] = _("Cell Battery"); +static const u8 sText_HoldEffectFairyPower[] = _("Fairy Power"); +static const u8 sText_HoldEffectMegaStone[] = _("Mega Stone"); +static const u8 sText_HoldEffectSafetyGoogles[] = _("Safety Googles"); +static const u8 sText_HoldEffectLuminousMoss[] = _("Luminous Moss"); +static const u8 sText_HoldEffectSnowball[] = _("Snowball"); +static const u8 sText_HoldEffectWeaknessPolicy[] = _("Weakness Policy"); +static const u8 sText_HoldEffectProtectivePads[] = _("Protective Pads"); +static const u8 sText_HoldEffectTerrainExtender[] = _("Terrain Extender"); +static const u8 sText_HoldEffectSeeds[] = _("Seeds"); +static const u8 sText_HoldEffectAdrenalineOrb[] = _("Adrenaline Orb"); +static const u8 sText_HoldEffectMemory[] = _("Memory"); +static const u8 sText_HoldEffectPlate[] = _("Plate"); +static const u8 sText_HoldEffectUtilityUmbrella[] = _("Utility Umbrella"); +static const u8 sText_HoldEffectEjectPack[] = _("Eject Pack"); +static const u8 sText_HoldEffectRoomService[] = _("Room Service"); +static const u8 sText_HoldEffectBlunderPolicy[] = _("Blunder Policy"); +static const u8 sText_HoldEffectHeavyDutyBoots[] = _("Heavy Duty Boots"); +static const u8 sText_HoldEffectThroatSpray[] = _("Throat Spray"); +static const u8 *const sHoldEffectNames[] = +{ + [HOLD_EFFECT_NONE] = sText_HoldEffectNone, + [HOLD_EFFECT_RESTORE_HP] = sText_HoldEffectRestoreHp, + [HOLD_EFFECT_CURE_PAR] = sText_HoldEffectCurePar, + [HOLD_EFFECT_CURE_SLP] = sText_HoldEffectCureSlp, + [HOLD_EFFECT_CURE_PSN] = sText_HoldEffectCurePsn, + [HOLD_EFFECT_CURE_BRN] = sText_HoldEffectCureBrn, + [HOLD_EFFECT_CURE_FRZ] = sText_HoldEffectCureFrz, + [HOLD_EFFECT_RESTORE_PP] = sText_HoldEffectRestorePp, + [HOLD_EFFECT_CURE_CONFUSION] = sText_HoldEffectCureConfusion, + [HOLD_EFFECT_CURE_STATUS] = sText_HoldEffectCureStatus, + [HOLD_EFFECT_CONFUSE_SPICY] = sText_HoldEffectConfuseSpicy, + [HOLD_EFFECT_CONFUSE_DRY] = sText_HoldEffectConfuseDry, + [HOLD_EFFECT_CONFUSE_SWEET] = sText_HoldEffectConfuseSweet, + [HOLD_EFFECT_CONFUSE_BITTER] = sText_HoldEffectConfuseBitter, + [HOLD_EFFECT_CONFUSE_SOUR] = sText_HoldEffectConfuseSour, + [HOLD_EFFECT_ATTACK_UP] = sText_HoldEffectAttackUp, + [HOLD_EFFECT_DEFENSE_UP] = sText_HoldEffectDefenseUp, + [HOLD_EFFECT_SPEED_UP] = sText_HoldEffectSpeedUp, + [HOLD_EFFECT_SP_ATTACK_UP] = sText_HoldEffectSpAttackUp, + [HOLD_EFFECT_SP_DEFENSE_UP] = sText_HoldEffectSpDefenseUp, + [HOLD_EFFECT_CRITICAL_UP] = sText_HoldEffectCriticalUp, + [HOLD_EFFECT_RANDOM_STAT_UP] = sText_HoldEffectRandomStatUp, + [HOLD_EFFECT_EVASION_UP] = sText_HoldEffectEvasionUp, + [HOLD_EFFECT_RESTORE_STATS] = sText_HoldEffectRestoreStats, + [HOLD_EFFECT_MACHO_BRACE] = sText_HoldEffectMachoBrace, + [HOLD_EFFECT_EXP_SHARE] = sText_HoldEffectExpShare, + [HOLD_EFFECT_QUICK_CLAW] = sText_HoldEffectQuickClaw, + [HOLD_EFFECT_FRIENDSHIP_UP] = sText_HoldEffectFriendshipUp, + //[HOLD_EFFECT_MENTAL_HERB] = sText_HoldEffectMentalHerb, + [HOLD_EFFECT_CHOICE_BAND] = sText_HoldEffectChoiceBand, + [HOLD_EFFECT_FLINCH] = sText_HoldEffectFlinch, + [HOLD_EFFECT_BUG_POWER] = sText_HoldEffectBugPower, + [HOLD_EFFECT_DOUBLE_PRIZE] = sText_HoldEffectDoublePrize, + [HOLD_EFFECT_REPEL] = sText_HoldEffectRepel, + [HOLD_EFFECT_SOUL_DEW] = sText_HoldEffectSoulDew, + [HOLD_EFFECT_DEEP_SEA_TOOTH] = sText_HoldEffectDeepSeaTooth, + [HOLD_EFFECT_DEEP_SEA_SCALE] = sText_HoldEffectDeepSeaScale, + [HOLD_EFFECT_CAN_ALWAYS_RUN] = sText_HoldEffectCanAlwaysRun, + [HOLD_EFFECT_PREVENT_EVOLVE] = sText_HoldEffectPreventEvolve, + [HOLD_EFFECT_FOCUS_BAND] = sText_HoldEffectFocusBand, + [HOLD_EFFECT_LUCKY_EGG] = sText_HoldEffectLuckyEgg, + [HOLD_EFFECT_SCOPE_LENS] = sText_HoldEffectScopeLens, + [HOLD_EFFECT_STEEL_POWER] = sText_HoldEffectSteelPower, + [HOLD_EFFECT_LEFTOVERS] = sText_HoldEffectLeftovers, + [HOLD_EFFECT_DRAGON_SCALE] = sText_HoldEffectDragonScale, + [HOLD_EFFECT_LIGHT_BALL] = sText_HoldEffectLightBall, + [HOLD_EFFECT_GROUND_POWER] = sText_HoldEffectGroundPower, + [HOLD_EFFECT_ROCK_POWER] = sText_HoldEffectRockPower, + [HOLD_EFFECT_GRASS_POWER] = sText_HoldEffectGrassPower, + [HOLD_EFFECT_DARK_POWER] = sText_HoldEffectDarkPower, + [HOLD_EFFECT_FIGHTING_POWER] = sText_HoldEffectFightingPower, + [HOLD_EFFECT_ELECTRIC_POWER] = sText_HoldEffectElectricPower, + [HOLD_EFFECT_WATER_POWER] = sText_HoldEffectWaterPower, + [HOLD_EFFECT_FLYING_POWER] = sText_HoldEffectFlyingPower, + [HOLD_EFFECT_POISON_POWER] = sText_HoldEffectPoisonPower, + [HOLD_EFFECT_ICE_POWER] = sText_HoldEffectIcePower, + [HOLD_EFFECT_GHOST_POWER] = sText_HoldEffectGhostPower, + [HOLD_EFFECT_PSYCHIC_POWER] = sText_HoldEffectPsychicPower, + [HOLD_EFFECT_FIRE_POWER] = sText_HoldEffectFirePower, + [HOLD_EFFECT_DRAGON_POWER] = sText_HoldEffectDragonPower, + [HOLD_EFFECT_NORMAL_POWER] = sText_HoldEffectNormalPower, + [HOLD_EFFECT_UP_GRADE] = sText_HoldEffectUpGrade, + [HOLD_EFFECT_SHELL_BELL] = sText_HoldEffectShellBell, + [HOLD_EFFECT_LUCKY_PUNCH] = sText_HoldEffectLuckyPunch, + [HOLD_EFFECT_METAL_POWDER] = sText_HoldEffectMetalPowder, + [HOLD_EFFECT_THICK_CLUB] = sText_HoldEffectThickClub, + [HOLD_EFFECT_STICK] = sText_HoldEffectStick, + [HOLD_EFFECT_CHOICE_SCARF] = sText_HoldEffectChoiceScarf, + [HOLD_EFFECT_CHOICE_SPECS] = sText_HoldEffectChoiceSpecs, + [HOLD_EFFECT_DAMP_ROCK] = sText_HoldEffectDampRock, + [HOLD_EFFECT_GRIP_CLAW] = sText_HoldEffectGripClaw, + [HOLD_EFFECT_HEAT_ROCK] = sText_HoldEffectHeatRock, + [HOLD_EFFECT_ICY_ROCK] = sText_HoldEffectIcyRock, + [HOLD_EFFECT_LIGHT_CLAY] = sText_HoldEffectLightClay, + [HOLD_EFFECT_SMOOTH_ROCK] = sText_HoldEffectSmoothRock, + [HOLD_EFFECT_POWER_HERB] = sText_HoldEffectPowerHerb, + [HOLD_EFFECT_BIG_ROOT] = sText_HoldEffectBigRoot, + [HOLD_EFFECT_EXPERT_BELT] = sText_HoldEffectExpertBelt, + [HOLD_EFFECT_LIFE_ORB] = sText_HoldEffectLifeOrb, + [HOLD_EFFECT_METRONOME] = sText_HoldEffectMetronome, + [HOLD_EFFECT_MUSCLE_BAND] = sText_HoldEffectMuscleBand, + [HOLD_EFFECT_WIDE_LENS] = sText_HoldEffectWideLens, + [HOLD_EFFECT_WISE_GLASSES] = sText_HoldEffectWiseGlasses, + [HOLD_EFFECT_ZOOM_LENS] = sText_HoldEffectZoomLens, + [HOLD_EFFECT_LAGGING_TAIL] = sText_HoldEffectLaggingTail, + [HOLD_EFFECT_FOCUS_SASH] = sText_HoldEffectFocusSash, + [HOLD_EFFECT_FLAME_ORB] = sText_HoldEffectFlameOrb, + [HOLD_EFFECT_TOXIC_ORB] = sText_HoldEffectToxicOrb, + [HOLD_EFFECT_STICKY_BARB] = sText_HoldEffectStickyBarb, + [HOLD_EFFECT_IRON_BALL] = sText_HoldEffectIronBall, + [HOLD_EFFECT_BLACK_SLUDGE] = sText_HoldEffectBlackSludge, + [HOLD_EFFECT_DESTINY_KNOT] = sText_HoldEffectDestinyKnot, + [HOLD_EFFECT_SHED_SHELL] = sText_HoldEffectShedShell, + [HOLD_EFFECT_QUICK_POWDER] = sText_HoldEffectQuickPowder, + [HOLD_EFFECT_ADAMANT_ORB] = sText_HoldEffectAdamantOrb, + [HOLD_EFFECT_LUSTROUS_ORB] = sText_HoldEffectLustrousOrb, + [HOLD_EFFECT_GRISEOUS_ORB] = sText_HoldEffectGriseousOrb, + [HOLD_EFFECT_GRACIDEA] = sText_HoldEffectGracidea, + [HOLD_EFFECT_RESIST_BERRY] = sText_HoldEffectResistBerry, + [HOLD_EFFECT_POWER_ITEM] = sText_HoldEffectPowerItem, + [HOLD_EFFECT_RESTORE_PCT_HP] = sText_HoldEffectRestorePctHp, + //[HOLD_EFFECT_MICLE_BERRY] = sText_HoldEffectMicleBerry, + //[HOLD_EFFECT_CUSTAP_BERRY] = sText_HoldEffectCustapBerry, + //[HOLD_EFFECT_JABOCA_BERRY] = sText_HoldEffectJabocaBerry, + //[HOLD_EFFECT_ROWAP_BERRY] = sText_HoldEffectRowapBerry, + //[HOLD_EFFECT_KEE_BERRY] = sText_HoldEffectKeeBerry, + //[HOLD_EFFECT_MARANGA_BERRY] = sText_HoldEffectMarangaBerry, + [HOLD_EFFECT_FLOAT_STONE] = sText_HoldEffectFloatStone, + [HOLD_EFFECT_EVIOLITE] = sText_HoldEffectEviolite, + [HOLD_EFFECT_ASSAULT_VEST] = sText_HoldEffectAssaultVest, + [HOLD_EFFECT_DRIVE] = sText_HoldEffectDrive, + [HOLD_EFFECT_GEMS] = sText_HoldEffectGems, + [HOLD_EFFECT_ROCKY_HELMET] = sText_HoldEffectRockyHelmet, + [HOLD_EFFECT_AIR_BALLOON] = sText_HoldEffectAirBalloon, + [HOLD_EFFECT_RED_CARD] = sText_HoldEffectRedCard, + [HOLD_EFFECT_RING_TARGET] = sText_HoldEffectRingTarget, + [HOLD_EFFECT_BINDING_BAND] = sText_HoldEffectBindingBand, + [HOLD_EFFECT_EJECT_BUTTON] = sText_HoldEffectEjectButton, + [HOLD_EFFECT_ABSORB_BULB] = sText_HoldEffectAbsorbBulb, + [HOLD_EFFECT_CELL_BATTERY] = sText_HoldEffectCellBattery, + [HOLD_EFFECT_FAIRY_POWER] = sText_HoldEffectFairyPower, + [HOLD_EFFECT_MEGA_STONE] = sText_HoldEffectMegaStone, + [HOLD_EFFECT_SAFETY_GOOGLES] = sText_HoldEffectSafetyGoogles, + [HOLD_EFFECT_LUMINOUS_MOSS] = sText_HoldEffectLuminousMoss, + [HOLD_EFFECT_SNOWBALL] = sText_HoldEffectSnowball, + [HOLD_EFFECT_WEAKNESS_POLICY] = sText_HoldEffectWeaknessPolicy, + [HOLD_EFFECT_PROTECTIVE_PADS] = sText_HoldEffectProtectivePads, + [HOLD_EFFECT_TERRAIN_EXTENDER] = sText_HoldEffectTerrainExtender, + [HOLD_EFFECT_SEEDS] = sText_HoldEffectSeeds, + [HOLD_EFFECT_ADRENALINE_ORB] = sText_HoldEffectAdrenalineOrb, + [HOLD_EFFECT_MEMORY] = sText_HoldEffectMemory, + [HOLD_EFFECT_PLATE] = sText_HoldEffectPlate, + [HOLD_EFFECT_UTILITY_UMBRELLA] = sText_HoldEffectUtilityUmbrella, + [HOLD_EFFECT_EJECT_PACK] = sText_HoldEffectEjectPack, + [HOLD_EFFECT_ROOM_SERVICE] = sText_HoldEffectRoomService, + [HOLD_EFFECT_BLUNDER_POLICY] = sText_HoldEffectBlunderPolicy, + [HOLD_EFFECT_HEAVY_DUTY_BOOTS] = sText_HoldEffectHeavyDutyBoots, + [HOLD_EFFECT_THROAT_SPRAY] = sText_HoldEffectThroatSpray, +}; +static const u8 *GetHoldEffectName(u16 holdEffect) +{ + if (holdEffect > ARRAY_COUNT(sHoldEffectNames)) + return sHoldEffectNames[0]; + return sHoldEffectNames[holdEffect]; +} diff --git a/src/battle_factory.c b/src/battle_factory.c index 72772929a..a76bdcff6 100644 --- a/src/battle_factory.c +++ b/src/battle_factory.c @@ -877,13 +877,13 @@ u32 GetAiScriptsInBattleFactory(void) int challengeNum = gSaveBlock2Ptr->frontier.factoryWinStreaks[battleMode][lvlMode] / 7; if (gTrainerBattleOpponent_A == TRAINER_FRONTIER_BRAIN) - return AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY; + return AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY; else if (challengeNum < 2) return 0; else if (challengeNum < 4) - return AI_SCRIPT_CHECK_BAD_MOVE; + return AI_FLAG_CHECK_BAD_MOVE; else - return AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY; + return AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY; } } diff --git a/src/battle_gfx_sfx_util.c b/src/battle_gfx_sfx_util.c index 81df4dd0b..c1fe271ca 100644 --- a/src/battle_gfx_sfx_util.c +++ b/src/battle_gfx_sfx_util.c @@ -1,7 +1,7 @@ #include "global.h" #include "battle.h" #include "battle_controllers.h" -#include "battle_ai_script_commands.h" +#include "battle_ai_main.h" #include "battle_anim.h" #include "constants/battle_anim.h" #include "battle_interface.h" diff --git a/src/battle_main.c b/src/battle_main.c index 739d33a3e..aa61ab60f 100644 --- a/src/battle_main.c +++ b/src/battle_main.c @@ -1,7 +1,8 @@ #include "global.h" #include "battle.h" #include "battle_anim.h" -#include "battle_ai_script_commands.h" +#include "battle_ai_main.h" +#include "battle_ai_util.h" #include "battle_arena.h" #include "battle_controllers.h" #include "battle_interface.h" @@ -3034,6 +3035,7 @@ void SwitchInClearSetData(void) ClearBattlerMoveHistory(gActiveBattler); ClearBattlerAbilityHistory(gActiveBattler); + ClearBattlerItemEffectHistory(gActiveBattler); } void FaintClearSetData(void) @@ -3122,6 +3124,7 @@ void FaintClearSetData(void) ClearBattlerMoveHistory(gActiveBattler); ClearBattlerAbilityHistory(gActiveBattler); + ClearBattlerItemEffectHistory(gActiveBattler); UndoFormChange(gBattlerPartyIndexes[gActiveBattler], GET_BATTLER_SIDE(gActiveBattler)); if (GetBattlerSide(gActiveBattler) == B_SIDE_PLAYER) UndoMegaEvolution(gBattlerPartyIndexes[gActiveBattler]); diff --git a/src/battle_message.c b/src/battle_message.c index c7464b70c..d4d5756f9 100644 --- a/src/battle_message.c +++ b/src/battle_message.c @@ -694,9 +694,13 @@ static const u8 sText_AsOneEnters[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX} has two static const u8 sText_CuriousMedicineEnters[] = _("{B_EFF_NAME_WITH_PREFIX}'s\nstat changes were reset!"); static const u8 sText_CanActFaster[] = _("{B_ATK_NAME_WITH_PREFIX} can act faster,\nthanks to {B_LAST_ITEM}!"); static const u8 sText_MicleBerryActivates[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX} boosted the accuracy of its\nnext move using {B_LAST_ITEM}!"); +static const u8 sText_PkmnShookOffTheTaunt[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX} shook off\nthe taunt!"); +static const u8 sText_PkmnGotOverItsInfatuation[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX} got over\nits infatuation!"); const u8 *const gBattleStringsTable[BATTLESTRINGS_COUNT] = { + [STRINGID_PKMNGOTOVERITSINFATUATION - 12] = sText_PkmnGotOverItsInfatuation, + [STRINGID_PKMNSHOOKOFFTHETAUNT - 12] = sText_PkmnShookOffTheTaunt, [STRINGID_MICLEBERRYACTIVATES - 12] = sText_MicleBerryActivates, [STRINGID_CANACTFASTERTHANKSTO - 12] = sText_CanActFaster, [STRINGID_CURIOUSMEDICINEENTERS - 12] = sText_CuriousMedicineEnters, diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index bb81b2cbc..1dadeadb1 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -4,7 +4,8 @@ #include "constants/battle_script_commands.h" #include "battle_message.h" #include "battle_anim.h" -#include "battle_ai_script_commands.h" +#include "battle_ai_main.h" +#include "battle_ai_util.h" #include "battle_scripts.h" #include "constants/moves.h" #include "constants/abilities.h" @@ -814,13 +815,7 @@ void (* const gBattleScriptingCommandsTable[])(void) = Cmd_metalburstdamagecalculator, //0xFF }; -struct StatFractions -{ - u8 dividend; - u8 divisor; -}; - -static const struct StatFractions sAccuracyStageRatios[] = +const struct StatFractions gAccuracyStageRatios[] = { { 33, 100}, // -6 { 36, 100}, // -5 @@ -922,92 +917,167 @@ static const u8 sForbiddenMoves[MOVES_COUNT] = [MOVE_NONE] = 0xFF, // Can't use a non-move lol [MOVE_STRUGGLE] = 0xFF, // Neither Struggle [MOVE_AFTER_YOU] = FORBIDDEN_METRONOME, + [MOVE_APPLE_ACID] = FORBIDDEN_METRONOME, [MOVE_ASSIST] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT | FORBIDDEN_SLEEP_TALK, + [MOVE_ASTRAL_BARRAGE] = FORBIDDEN_METRONOME, + [MOVE_AURA_WHEEL] = FORBIDDEN_METRONOME, + [MOVE_BADDY_BAD] = FORBIDDEN_METRONOME, [MOVE_BANEFUL_BUNKER] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT, [MOVE_BEAK_BLAST] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT | FORBIDDEN_SLEEP_TALK, + [MOVE_BEHEMOTH_BASH] = FORBIDDEN_METRONOME | FORBIDDEN_COPYCAT, + [MOVE_BEHEMOTH_BLADE] = FORBIDDEN_METRONOME | FORBIDDEN_COPYCAT, [MOVE_BELCH] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT | FORBIDDEN_SLEEP_TALK, [MOVE_BESTOW] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT, [MOVE_BIDE] = FORBIDDEN_SLEEP_TALK, + [MOVE_BODY_PRESS] = FORBIDDEN_METRONOME, + [MOVE_BOUNCE] = FORBIDDEN_ASSIST | FORBIDDEN_SLEEP_TALK, + [MOVE_BOUNCY_BUBBLE] = FORBIDDEN_METRONOME, + [MOVE_BRANCH_POKE] = FORBIDDEN_METRONOME, + [MOVE_BREAKING_SWIPE] = FORBIDDEN_METRONOME, + [MOVE_BUZZY_BUZZ] = FORBIDDEN_METRONOME, [MOVE_CELEBRATE] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT | FORBIDDEN_SLEEP_TALK, [MOVE_CHATTER] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT | FORBIDDEN_MIMIC | FORBIDDEN_SLEEP_TALK, [MOVE_CIRCLE_THROW] = FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT, + [MOVE_CLANGOROUS_SOUL] = FORBIDDEN_METRONOME, [MOVE_COPYCAT] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT | FORBIDDEN_SLEEP_TALK, [MOVE_COUNTER] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT, [MOVE_COVET] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT, - [MOVE_CRAFTY_SHIELD] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT, + [MOVE_CRAFTY_SHIELD] = FORBIDDEN_METRONOME, + [MOVE_DECORATE] = FORBIDDEN_METRONOME, [MOVE_DESTINY_BOND] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT, [MOVE_DETECT] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT, - [MOVE_DIG] = FORBIDDEN_ASSIST, - [MOVE_DIVE] = FORBIDDEN_ASSIST, - [MOVE_DRAGON_TAIL] = FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT, [MOVE_DIAMOND_STORM] = FORBIDDEN_METRONOME, + [MOVE_DIG] = FORBIDDEN_ASSIST | FORBIDDEN_SLEEP_TALK, + [MOVE_DIVE] = FORBIDDEN_ASSIST | FORBIDDEN_SLEEP_TALK, + [MOVE_DOUBLE_IRON_BASH] = FORBIDDEN_METRONOME, + [MOVE_DRAGON_ASCENT] = FORBIDDEN_METRONOME, + [MOVE_DRAGON_ENERGY] = FORBIDDEN_METRONOME, + [MOVE_DRAGON_TAIL] = FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT, + [MOVE_DRUM_BEATING] = FORBIDDEN_METRONOME, + [MOVE_DYNAMAX_CANNON] = FORBIDDEN_METRONOME | FORBIDDEN_COPYCAT | FORBIDDEN_SLEEP_TALK, [MOVE_ENDURE] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT, + [MOVE_ETERNABEAM] = FORBIDDEN_METRONOME, + [MOVE_FALSE_SURRENDER] = FORBIDDEN_METRONOME, [MOVE_FEINT] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT, + [MOVE_FIERY_WRATH] = FORBIDDEN_METRONOME, [MOVE_FLEUR_CANNON] = FORBIDDEN_METRONOME, - [MOVE_FLY] = FORBIDDEN_ASSIST, + [MOVE_FLOATY_FALL] = FORBIDDEN_METRONOME, + [MOVE_FLY] = FORBIDDEN_ASSIST | FORBIDDEN_SLEEP_TALK, [MOVE_FOCUS_PUNCH] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT | FORBIDDEN_SLEEP_TALK, [MOVE_FOLLOW_ME] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT, - [MOVE_FREEZE_SHOCK] = FORBIDDEN_METRONOME, + [MOVE_FREEZE_SHOCK] = FORBIDDEN_METRONOME | FORBIDDEN_SLEEP_TALK, + [MOVE_FREEZING_GLARE] = FORBIDDEN_METRONOME, + [MOVE_FREEZY_FROST] = FORBIDDEN_METRONOME, + [MOVE_GEOMANCY] = FORBIDDEN_SLEEP_TALK, + [MOVE_GLACIAL_LANCE] = FORBIDDEN_METRONOME, + [MOVE_GLITZY_GLOW] = FORBIDDEN_METRONOME, + [MOVE_GRAV_APPLE] = FORBIDDEN_METRONOME, [MOVE_HELPING_HAND] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT, [MOVE_HOLD_HANDS] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT | FORBIDDEN_SLEEP_TALK, [MOVE_HYPERSPACE_FURY] = FORBIDDEN_METRONOME, [MOVE_HYPERSPACE_HOLE] = FORBIDDEN_METRONOME, - [MOVE_ICE_BURN] = FORBIDDEN_METRONOME, + [MOVE_ICE_BURN] = FORBIDDEN_METRONOME | FORBIDDEN_SLEEP_TALK, [MOVE_INSTRUCT] = FORBIDDEN_METRONOME, + [MOVE_JUNGLE_HEALING] = FORBIDDEN_METRONOME, [MOVE_KINGS_SHIELD] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT, + [MOVE_LIFE_DEW] = FORBIDDEN_METRONOME, [MOVE_LIGHT_OF_RUIN] = FORBIDDEN_METRONOME, [MOVE_MAT_BLOCK] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT, [MOVE_ME_FIRST] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT | FORBIDDEN_SLEEP_TALK, + [MOVE_METEOR_ASSAULT] = FORBIDDEN_METRONOME, [MOVE_METRONOME] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT | FORBIDDEN_SLEEP_TALK, [MOVE_MIMIC] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT | FORBIDDEN_MIMIC | FORBIDDEN_SLEEP_TALK, + [MOVE_MIND_BLOWN] = FORBIDDEN_METRONOME, [MOVE_MIRROR_COAT] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT, [MOVE_MIRROR_MOVE] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT | FORBIDDEN_SLEEP_TALK, + [MOVE_MOONGEIST_BEAM] = FORBIDDEN_METRONOME, [MOVE_NATURE_POWER] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT | FORBIDDEN_SLEEP_TALK, + [MOVE_NATURES_MADNESS] = FORBIDDEN_METRONOME, + [MOVE_OBSTRUCT] = FORBIDDEN_METRONOME | FORBIDDEN_COPYCAT, [MOVE_ORIGIN_PULSE] = FORBIDDEN_METRONOME, + [MOVE_OVERDRIVE] = FORBIDDEN_METRONOME, + [MOVE_PHANTOM_FORCE] = FORBIDDEN_ASSIST | FORBIDDEN_SLEEP_TALK, + [MOVE_PHOTON_GEYSER] = FORBIDDEN_METRONOME, + [MOVE_PIKA_PAPOW] = FORBIDDEN_METRONOME, + [MOVE_PLASMA_FISTS] = FORBIDDEN_METRONOME, [MOVE_PRECIPICE_BLADES] = FORBIDDEN_METRONOME, [MOVE_PROTECT] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT, + [MOVE_PYRO_BALL] = FORBIDDEN_METRONOME, [MOVE_QUASH] = FORBIDDEN_METRONOME, [MOVE_QUICK_GUARD] = FORBIDDEN_METRONOME, [MOVE_RAGE_POWDER] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT, + [MOVE_RAZOR_WIND] = FORBIDDEN_SLEEP_TALK, [MOVE_RELIC_SONG] = FORBIDDEN_METRONOME, [MOVE_ROAR] = FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT, + [MOVE_SAPPY_SEED] = FORBIDDEN_METRONOME, [MOVE_SECRET_SWORD] = FORBIDDEN_METRONOME, + [MOVE_SHADOW_FORCE] = FORBIDDEN_ASSIST | FORBIDDEN_SLEEP_TALK, [MOVE_SHELL_TRAP] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT | FORBIDDEN_SLEEP_TALK, - [MOVE_SKETCH] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT | FORBIDDEN_SLEEP_TALK, + [MOVE_SIZZLY_SLIDE] = FORBIDDEN_METRONOME, + [MOVE_SKETCH] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT | FORBIDDEN_MIMIC | FORBIDDEN_SLEEP_TALK, + [MOVE_SKULL_BASH] = FORBIDDEN_SLEEP_TALK, + [MOVE_SKY_ATTACK] = FORBIDDEN_SLEEP_TALK, + [MOVE_SKY_DROP] = FORBIDDEN_ASSIST | FORBIDDEN_SLEEP_TALK, [MOVE_SLEEP_TALK] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT | FORBIDDEN_SLEEP_TALK, + [MOVE_SNAP_TRAP] = FORBIDDEN_METRONOME, [MOVE_SNARL] = FORBIDDEN_METRONOME, [MOVE_SNATCH] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT, [MOVE_SNORE] = FORBIDDEN_METRONOME, + [MOVE_SOLAR_BEAM] = FORBIDDEN_SLEEP_TALK, + [MOVE_SOLAR_BLADE] = FORBIDDEN_SLEEP_TALK, + [MOVE_SPARKLY_SWIRL] = FORBIDDEN_METRONOME, [MOVE_SPECTRAL_THIEF] = FORBIDDEN_METRONOME, [MOVE_SPIKY_SHIELD] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT, - [MOVE_SPOTLIGHT] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST, + [MOVE_SPIRIT_BREAK] = FORBIDDEN_METRONOME, + [MOVE_SPLISHY_SPLASH] = FORBIDDEN_METRONOME, + [MOVE_SPOTLIGHT] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT, [MOVE_STEAM_ERUPTION] = FORBIDDEN_METRONOME, + [MOVE_STEEL_BEAM] = FORBIDDEN_METRONOME, + [MOVE_STRANGE_STEAM] = FORBIDDEN_METRONOME, + [MOVE_SUNSTEEL_STRIKE] = FORBIDDEN_METRONOME, + [MOVE_SURGING_STRIKES] = FORBIDDEN_METRONOME, [MOVE_SWITCHEROO] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT, [MOVE_TECHNO_BLAST] = FORBIDDEN_METRONOME, [MOVE_THIEF] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT, [MOVE_THOUSAND_ARROWS] = FORBIDDEN_METRONOME, [MOVE_THOUSAND_WAVES] = FORBIDDEN_METRONOME, + [MOVE_THUNDER_CAGE] = FORBIDDEN_METRONOME, + [MOVE_THUNDEROUS_KICK] = FORBIDDEN_METRONOME, [MOVE_TRANSFORM] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT | FORBIDDEN_MIMIC, [MOVE_TRICK] = FORBIDDEN_METRONOME | FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT, - [MOVE_V_CREATE] = FORBIDDEN_METRONOME, - [MOVE_WIDE_GUARD] = FORBIDDEN_METRONOME, - [MOVE_WHIRLWIND] = FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT, [MOVE_UPROAR] = FORBIDDEN_SLEEP_TALK, + [MOVE_V_CREATE] = FORBIDDEN_METRONOME, + [MOVE_VEEVEE_VOLLEY] = FORBIDDEN_METRONOME, + [MOVE_WHIRLWIND] = FORBIDDEN_ASSIST | FORBIDDEN_COPYCAT, + [MOVE_WICKED_BLOW] = FORBIDDEN_METRONOME, + [MOVE_WIDE_GUARD] = FORBIDDEN_METRONOME, + [MOVE_ZIPPY_ZAP] = FORBIDDEN_METRONOME, }; static const u16 sMoveEffectsForbiddenToInstruct[] = { EFFECT_ASSIST, //EFFECT_BEAK_BLAST, + EFFECT_BELCH, EFFECT_BIDE, + //EFFECT_CELEBRATE, + //EFFECT_CHATTER, + EFFECT_COPYCAT, + //EFFECT_DYNAMAX_CANNON, EFFECT_FOCUS_PUNCH, - //EFFECT_GEOMANCY, + EFFECT_GEOMANCY, + //EFFECT_HOLD_HANDS, EFFECT_INSTRUCT, EFFECT_ME_FIRST, EFFECT_METRONOME, + EFFECT_MIMIC, EFFECT_MIRROR_MOVE, EFFECT_NATURE_POWER, + //EFFECT_OBSTRUCT, + EFFECT_RAMPAGE, EFFECT_RECHARGE, + EFFECT_RECOIL_25, + EFFECT_ROLLOUT, EFFECT_SEMI_INVULNERABLE, //EFFECT_SHELL_TRAP, EFFECT_SKETCH, @@ -1017,21 +1087,22 @@ static const u16 sMoveEffectsForbiddenToInstruct[] = EFFECT_SOLARBEAM, EFFECT_TRANSFORM, EFFECT_TWO_TURNS_ATTACK, + EFFECT_UPROAR, FORBIDDEN_INSTRUCT_END }; static const u16 sNaturePowerMoves[] = { - [BATTLE_TERRAIN_GRASS] = MOVE_STUN_SPORE, - [BATTLE_TERRAIN_LONG_GRASS] = MOVE_RAZOR_LEAF, - [BATTLE_TERRAIN_SAND] = MOVE_EARTHQUAKE, + [BATTLE_TERRAIN_GRASS] = MOVE_ENERGY_BALL, + [BATTLE_TERRAIN_LONG_GRASS] = MOVE_ENERGY_BALL, + [BATTLE_TERRAIN_SAND] = MOVE_EARTH_POWER, [BATTLE_TERRAIN_UNDERWATER] = MOVE_HYDRO_PUMP, - [BATTLE_TERRAIN_WATER] = MOVE_SURF, - [BATTLE_TERRAIN_POND] = MOVE_BUBBLE_BEAM, - [BATTLE_TERRAIN_MOUNTAIN] = MOVE_ROCK_SLIDE, - [BATTLE_TERRAIN_CAVE] = MOVE_SHADOW_BALL, - [BATTLE_TERRAIN_BUILDING] = MOVE_SWIFT, - [BATTLE_TERRAIN_PLAIN] = MOVE_SWIFT + [BATTLE_TERRAIN_WATER] = MOVE_HYDRO_PUMP, + [BATTLE_TERRAIN_POND] = MOVE_HYDRO_PUMP, + [BATTLE_TERRAIN_MOUNTAIN] = MOVE_EARTH_POWER, + [BATTLE_TERRAIN_CAVE] = MOVE_POWER_GEM, + [BATTLE_TERRAIN_BUILDING] = MOVE_TRI_ATTACK, + [BATTLE_TERRAIN_PLAIN] = MOVE_TRI_ATTACK }; static const u16 sPickupItems[] = @@ -1084,7 +1155,7 @@ static const u8 sTerrainToType[] = [BATTLE_TERRAIN_UNDERWATER] = TYPE_WATER, [BATTLE_TERRAIN_WATER] = TYPE_WATER, [BATTLE_TERRAIN_POND] = TYPE_WATER, - [BATTLE_TERRAIN_MOUNTAIN] = TYPE_ROCK, + [BATTLE_TERRAIN_MOUNTAIN] = TYPE_GROUND, [BATTLE_TERRAIN_CAVE] = TYPE_ROCK, [BATTLE_TERRAIN_BUILDING] = TYPE_NORMAL, [BATTLE_TERRAIN_PLAIN] = TYPE_NORMAL, @@ -1471,7 +1542,8 @@ static bool32 AccuracyCalcHelper(u16 move) } if ((gStatuses3[gBattlerTarget] & STATUS3_PHANTOM_FORCE) - || (!(gBattleMoves[move].flags & FLAG_HIT_IN_AIR) && gStatuses3[gBattlerTarget] & STATUS3_ON_AIR) + || (!(gBattleMoves[move].flags & FLAG_DMG_IN_AIR) && gStatuses3[gBattlerTarget] & STATUS3_ON_AIR) + || (!(gBattleMoves[move].flags & FLAG_DMG_2X_IN_AIR) && gStatuses3[gBattlerTarget] & STATUS3_ON_AIR) || (!(gBattleMoves[move].flags & FLAG_DMG_UNDERGROUND) && gStatuses3[gBattlerTarget] & STATUS3_UNDERGROUND) || (!(gBattleMoves[move].flags & FLAG_DMG_UNDERWATER) && gStatuses3[gBattlerTarget] & STATUS3_UNDERWATER)) { @@ -1536,8 +1608,8 @@ u32 GetTotalAccuracy(u32 battlerAtk, u32 battlerDef, u32 move) if (defAbility == ABILITY_WONDER_SKIN && gBattleMoves[move].power == 0) moveAcc = 50; - calc = sAccuracyStageRatios[buff].dividend * moveAcc; - calc /= sAccuracyStageRatios[buff].divisor; + calc = gAccuracyStageRatios[buff].dividend * moveAcc; + calc /= gAccuracyStageRatios[buff].divisor; if (atkAbility == ABILITY_COMPOUND_EYES) calc = (calc * 130) / 100; // 1.3 compound eyes boost @@ -1563,7 +1635,7 @@ u32 GetTotalAccuracy(u32 battlerAtk, u32 battlerDef, u32 move) calc = (calc * (100 + atkParam)) / 100; else if (atkHoldEffect == HOLD_EFFECT_ZOOM_LENS && GetBattlerTurnOrderNum(battlerAtk) > GetBattlerTurnOrderNum(battlerDef)); calc = (calc * (100 + atkParam)) / 100; - + if (gProtectStructs[battlerAtk].micle) { gProtectStructs[battlerAtk].micle = FALSE; @@ -3119,7 +3191,7 @@ void SetMoveEffect(bool32 primary, u32 certain) case MOVE_EFFECT_FLAME_BURST: if (IsBattlerAlive(BATTLE_PARTNER(gBattlerTarget)) && GetBattlerAbility(BATTLE_PARTNER(gBattlerTarget)) != ABILITY_MAGIC_GUARD) { - gBattleScripting.battler = BATTLE_PARTNER(gBattlerTarget); + gBattleScripting.savedBattler = BATTLE_PARTNER(gBattlerTarget); gBattleMoveDamage = gBattleMons[BATTLE_PARTNER(gBattlerTarget)].hp / 16; if (gBattleMoveDamage == 0) gBattleMoveDamage = 1; @@ -4415,7 +4487,7 @@ static void Cmd_playanimation(void) gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]); argumentPtr = T2_READ_PTR(gBattlescriptCurrInstr + 3); - + #if B_TERRAIN_BG_CHANGE == FALSE if (gBattlescriptCurrInstr[2] == B_ANIM_RESTORE_BG) { @@ -7689,51 +7761,25 @@ static void Cmd_various(void) gBattlescriptCurrInstr += 7; return; case VARIOUS_SET_SIMPLE_BEAM: - switch (gBattleMons[gActiveBattler].ability) + if (IsEntrainmentTargetOrSimpleBeamBannedAbility(gBattleMons[gActiveBattler].ability)) { - case ABILITY_SIMPLE: - case ABILITY_TRUANT: - case ABILITY_STANCE_CHANGE: - case ABILITY_DISGUISE: - case ABILITY_MULTITYPE: gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); - break; - default: + } + else + { gBattleMons[gActiveBattler].ability = ABILITY_SIMPLE; gBattlescriptCurrInstr += 7; break; } return; case VARIOUS_TRY_ENTRAINMENT: - switch (gBattleMons[gBattlerTarget].ability) + if (IsEntrainmentBannedAbilityAttacker(gBattleMons[gBattlerAttacker].ability) + || IsEntrainmentTargetOrSimpleBeamBannedAbility(gBattleMons[gBattlerTarget].ability)) { - case ABILITY_TRUANT: - case ABILITY_MULTITYPE: - case ABILITY_STANCE_CHANGE: - case ABILITY_SCHOOLING: - case ABILITY_COMATOSE: - case ABILITY_SHIELDS_DOWN: - case ABILITY_DISGUISE: - case ABILITY_RKS_SYSTEM: - case ABILITY_BATTLE_BOND: - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); - return; - } - switch (gBattleMons[gBattlerAttacker].ability) - { - case ABILITY_TRACE: - case ABILITY_FORECAST: - case ABILITY_FLOWER_GIFT: - case ABILITY_ZEN_MODE: - case ABILITY_ILLUSION: - case ABILITY_IMPOSTER: - case ABILITY_POWER_OF_ALCHEMY: - case ABILITY_RECEIVER: - case ABILITY_DISGUISE: - case ABILITY_POWER_CONSTRUCT: gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); return; } + if (gBattleMons[gBattlerTarget].ability == gBattleMons[gBattlerAttacker].ability) { gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); @@ -9191,17 +9237,17 @@ bool32 TryResetBattlerStatChanges(u8 battler) { u32 j; bool32 ret = FALSE; - + gDisableStructs[battler].stockpileDef = 0; gDisableStructs[battler].stockpileSpDef = 0; for (j = 0; j < NUM_BATTLE_STATS; j++) { if (gBattleMons[battler].statStages[j] != DEFAULT_STAT_STAGE) ret = TRUE; // returns TRUE if any stat was reset - + gBattleMons[battler].statStages[j] = DEFAULT_STAT_STAGE; } - + return ret; } @@ -9746,7 +9792,7 @@ static void Cmd_tryinfatuating(void) if (GetBattlerAbility(gBattlerTarget) == ABILITY_OBLIVIOUS) { - gBattlescriptCurrInstr = BattleScript_ObliviousPreventsAttraction; + gBattlescriptCurrInstr = BattleScript_NotAffectedAbilityPopUp; gLastUsedAbility = ABILITY_OBLIVIOUS; RecordAbilityBattle(gBattlerTarget, ABILITY_OBLIVIOUS); } @@ -11114,6 +11160,12 @@ static void Cmd_callterrainattack(void) // nature power gBattlescriptCurrInstr++; } +u16 GetNaturePowerMove(void) +{ + //TODO terrain + return sNaturePowerMoves[gBattleTerrain]; +} + static void Cmd_cureifburnedparalysedorpoisoned(void) // refresh { if (gBattleMons[gBattlerAttacker].status1 & (STATUS1_POISON | STATUS1_BURN | STATUS1_PARALYSIS | STATUS1_TOXIC_POISON)) @@ -11153,7 +11205,13 @@ static void Cmd_jumpifnodamage(void) static void Cmd_settaunt(void) { - if (gDisableStructs[gBattlerTarget].tauntTimer == 0) + if (GetBattlerAbility(gBattlerTarget) == ABILITY_OBLIVIOUS) + { + gBattlescriptCurrInstr = BattleScript_NotAffectedAbilityPopUp; + gLastUsedAbility = ABILITY_OBLIVIOUS; + RecordAbilityBattle(gBattlerTarget, ABILITY_OBLIVIOUS); + } + else if (gDisableStructs[gBattlerTarget].tauntTimer == 0) { u8 turns = 4; if (GetBattlerTurnOrderNum(gBattlerTarget) > GetBattlerTurnOrderNum(gBattlerAttacker)) @@ -11280,18 +11338,20 @@ static void Cmd_tryswapitems(void) // trick static void Cmd_trycopyability(void) // role play { - switch (gBattleMons[gBattlerTarget].ability) + u16 defAbility = gBattleMons[gBattlerTarget].ability; + + if (gBattleMons[gBattlerAttacker].ability == defAbility + || defAbility == ABILITY_NONE + || IsRolePlayBannedAbilityAtk(gBattleMons[gBattlerAttacker].ability) + || IsRolePlayBannedAbility(defAbility)) { - case ABILITY_NONE: - case ABILITY_WONDER_GUARD: - case ABILITY_DISGUISE: - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); - break; - default: - gBattleMons[gBattlerAttacker].ability = gBattleMons[gBattlerTarget].ability; - gLastUsedAbility = gBattleMons[gBattlerTarget].ability; - gBattlescriptCurrInstr += 5; - break; + gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); + } + else + { + gBattleMons[gBattlerAttacker].ability = defAbility; + gLastUsedAbility = defAbility; + gBattlescriptCurrInstr += 5; } } @@ -11345,28 +11405,14 @@ static void Cmd_settoxicspikes(void) static void Cmd_setgastroacid(void) { - switch (gBattleMons[gBattlerTarget].ability) + if (IsGastroAcidBannedAbility(gBattleMons[gBattlerTarget].ability)) { - case ABILITY_AS_ONE_ICE_RIDER: - case ABILITY_AS_ONE_SHADOW_RIDER: - case ABILITY_BATTLE_BOND: - case ABILITY_COMATOSE: - case ABILITY_DISGUISE: - case ABILITY_GULP_MISSILE: - case ABILITY_ICE_FACE: - case ABILITY_MULTITYPE: - case ABILITY_POWER_CONSTRUCT: - case ABILITY_RKS_SYSTEM: - case ABILITY_SCHOOLING: - case ABILITY_SHIELDS_DOWN: - case ABILITY_STANCE_CHANGE: - case ABILITY_ZEN_MODE: gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); - break; - default: + } + else + { gStatuses3[gBattlerTarget] |= STATUS3_GASTRO_ACID; gBattlescriptCurrInstr += 5; - break; } } @@ -11435,20 +11481,9 @@ static void Cmd_setroom(void) static void Cmd_tryswapabilities(void) // skill swap { - switch (gBattleMons[gBattlerAttacker].ability) + if (IsSkillSwapBannedAbility(gBattleMons[gBattlerAttacker].ability) + || IsSkillSwapBannedAbility(gBattleMons[gBattlerTarget].ability)) { - case ABILITY_NONE: - case ABILITY_WONDER_GUARD: - case ABILITY_DISGUISE: - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); - return; - } - - switch (gBattleMons[gBattlerTarget].ability) - { - case ABILITY_NONE: - case ABILITY_WONDER_GUARD: - case ABILITY_DISGUISE: gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); return; } @@ -11680,7 +11715,7 @@ static void Cmd_getsecretpowereffect(void) switch (gBattleTerrain) { case BATTLE_TERRAIN_GRASS: - gBattleScripting.moveEffect = MOVE_EFFECT_POISON; + gBattleScripting.moveEffect = MOVE_EFFECT_SLEEP; break; case BATTLE_TERRAIN_LONG_GRASS: gBattleScripting.moveEffect = MOVE_EFFECT_SLEEP; @@ -11689,16 +11724,16 @@ static void Cmd_getsecretpowereffect(void) gBattleScripting.moveEffect = MOVE_EFFECT_ACC_MINUS_1; break; case BATTLE_TERRAIN_UNDERWATER: - gBattleScripting.moveEffect = MOVE_EFFECT_DEF_MINUS_1; + gBattleScripting.moveEffect = MOVE_EFFECT_ATK_MINUS_1; break; case BATTLE_TERRAIN_WATER: gBattleScripting.moveEffect = MOVE_EFFECT_ATK_MINUS_1; break; case BATTLE_TERRAIN_POND: - gBattleScripting.moveEffect = MOVE_EFFECT_SPD_MINUS_1; + gBattleScripting.moveEffect = MOVE_EFFECT_ATK_MINUS_1; break; case BATTLE_TERRAIN_MOUNTAIN: - gBattleScripting.moveEffect = MOVE_EFFECT_CONFUSION; + gBattleScripting.moveEffect = MOVE_EFFECT_ACC_MINUS_1; break; case BATTLE_TERRAIN_CAVE: gBattleScripting.moveEffect = MOVE_EFFECT_FLINCH; @@ -11925,6 +11960,13 @@ static void Cmd_tryrecycleitem(void) } } +bool32 CanCamouflage(u8 battlerId) +{ + if (IS_BATTLER_OF_TYPE(battlerId, sTerrainToType[gBattleTerrain])) + return FALSE; + return TRUE; +} + static void Cmd_settypetoterrain(void) { if (!IS_BATTLER_OF_TYPE(gBattlerAttacker, sTerrainToType[gBattleTerrain])) @@ -12449,11 +12491,36 @@ static void Cmd_trainerslideout(void) gBattlescriptCurrInstr += 2; } +static const u16 sTelekinesisBanList[] = +{ + SPECIES_DIGLETT, + SPECIES_DUGTRIO, + #ifdef POKEMON_EXPANSION + SPECIES_DIGLETT_ALOLAN, + SPECIES_DUGTRIO_ALOLAN, + SPECIES_SANDYGAST, + SPECIES_PALOSSAND, + SPECIES_GENGAR_MEGA, + #endif +}; + +bool32 IsTelekinesisBannedSpecies(u16 species) +{ + u32 i; + + for (i = 0; i < ARRAY_COUNT(sTelekinesisBanList); i++) + { + if (species == sTelekinesisBanList[i]) + return TRUE; + } + return FALSE; +} + static void Cmd_settelekinesis(void) { if (gStatuses3[gBattlerTarget] & (STATUS3_TELEKINESIS | STATUS3_ROOTED | STATUS3_SMACKED_DOWN) || gFieldStatuses & STATUS_FIELD_GRAVITY - || (gBattleMons[gBattlerTarget].species == SPECIES_DIGLETT || gBattleMons[gBattlerTarget].species == SPECIES_DUGTRIO)) + || IsTelekinesisBannedSpecies(gBattleMons[gBattlerTarget].species)) { gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); } @@ -12521,19 +12588,14 @@ static void Cmd_trygetbaddreamstarget(void) static void Cmd_tryworryseed(void) { - switch (gBattleMons[gBattlerTarget].ability) + if (IsWorrySeedBannedAbility(gBattleMons[gBattlerTarget].ability)) { - case ABILITY_INSOMNIA: - case ABILITY_MULTITYPE: - case ABILITY_TRUANT: - case ABILITY_STANCE_CHANGE: - case ABILITY_DISGUISE: gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); - break; - default: + } + else + { gBattleMons[gBattlerTarget].ability = ABILITY_INSOMNIA; gBattlescriptCurrInstr += 5; - break; } } diff --git a/src/battle_util.c b/src/battle_util.c index 0d4a7f18a..fb95bd272 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -23,7 +23,8 @@ #include "trig.h" #include "window.h" #include "battle_message.h" -#include "battle_ai_script_commands.h" +#include "battle_ai_main.h" +#include "battle_ai_util.h" #include "event_data.h" #include "link.h" #include "malloc.h" @@ -87,6 +88,134 @@ static const u8 sPkblToEscapeFactor[][3] = { static const u8 sGoNearCounterToCatchFactor[] = {4, 3, 2, 1}; static const u8 sGoNearCounterToEscapeFactor[] = {4, 4, 4, 4}; +static const u16 sSkillSwapBannedAbilities[] = +{ + ABILITY_WONDER_GUARD, + ABILITY_MULTITYPE, + ABILITY_ILLUSION, + ABILITY_STANCE_CHANGE, + ABILITY_SCHOOLING, + ABILITY_COMATOSE, + ABILITY_SHIELDS_DOWN, + ABILITY_DISGUISE, + ABILITY_RKS_SYSTEM, + ABILITY_BATTLE_BOND, + ABILITY_POWER_CONSTRUCT, + ABILITY_NEUTRALIZING_GAS, + ABILITY_ICE_FACE, + ABILITY_HUNGER_SWITCH, + ABILITY_GULP_MISSILE, +}; + +static const u16 sRolePlayBannedAbilities[] = +{ + ABILITY_TRACE, + ABILITY_WONDER_GUARD, + ABILITY_FORECAST, + ABILITY_FLOWER_GIFT, + ABILITY_MULTITYPE, + ABILITY_ILLUSION, + ABILITY_ZEN_MODE, + ABILITY_IMPOSTER, + ABILITY_STANCE_CHANGE, + ABILITY_POWER_OF_ALCHEMY, + ABILITY_RECEIVER, + ABILITY_SCHOOLING, + ABILITY_COMATOSE, + ABILITY_SHIELDS_DOWN, + ABILITY_DISGUISE, + ABILITY_RKS_SYSTEM, + ABILITY_BATTLE_BOND, + ABILITY_POWER_CONSTRUCT, + ABILITY_ICE_FACE, + ABILITY_HUNGER_SWITCH, + ABILITY_GULP_MISSILE, +}; + +static const u16 sRolePlayBannedAttackerAbilities[] = +{ + ABILITY_MULTITYPE, + ABILITY_ZEN_MODE, + ABILITY_STANCE_CHANGE, + ABILITY_SCHOOLING, + ABILITY_COMATOSE, + ABILITY_SHIELDS_DOWN, + ABILITY_DISGUISE, + ABILITY_RKS_SYSTEM, + ABILITY_BATTLE_BOND, + ABILITY_POWER_CONSTRUCT, + ABILITY_ICE_FACE, + ABILITY_GULP_MISSILE, +}; + +static const u16 sWorrySeedBannedAbilities[] = +{ + ABILITY_MULTITYPE, + ABILITY_STANCE_CHANGE, + ABILITY_SCHOOLING, + ABILITY_COMATOSE, + ABILITY_SHIELDS_DOWN, + ABILITY_DISGUISE, + ABILITY_RKS_SYSTEM, + ABILITY_BATTLE_BOND, + ABILITY_POWER_CONSTRUCT, + ABILITY_TRUANT, + ABILITY_ICE_FACE, + ABILITY_GULP_MISSILE, +}; + +static const u16 sGastroAcidBannedAbilities[] = +{ + ABILITY_AS_ONE_ICE_RIDER, + ABILITY_AS_ONE_SHADOW_RIDER, + ABILITY_BATTLE_BOND, + ABILITY_COMATOSE, + ABILITY_DISGUISE, + ABILITY_GULP_MISSILE, + ABILITY_ICE_FACE, + ABILITY_MULTITYPE, + ABILITY_POWER_CONSTRUCT, + ABILITY_RKS_SYSTEM, + ABILITY_SCHOOLING, + ABILITY_SHIELDS_DOWN, + ABILITY_STANCE_CHANGE, + ABILITY_ZEN_MODE, +}; + +static const u16 sEntrainmentBannedAttackerAbilities[] = +{ + ABILITY_TRACE, + ABILITY_FORECAST, + ABILITY_FLOWER_GIFT, + ABILITY_ZEN_MODE, + ABILITY_ILLUSION, + ABILITY_IMPOSTER, + ABILITY_POWER_OF_ALCHEMY, + ABILITY_RECEIVER, + ABILITY_DISGUISE, + ABILITY_POWER_CONSTRUCT, + ABILITY_NEUTRALIZING_GAS, + ABILITY_ICE_FACE, + ABILITY_HUNGER_SWITCH, + ABILITY_GULP_MISSILE, +}; + +static const u16 sEntrainmentTargetSimpleBeamBannedAbilities[] = +{ + ABILITY_TRUANT, + ABILITY_MULTITYPE, + ABILITY_STANCE_CHANGE, + ABILITY_SCHOOLING, + ABILITY_COMATOSE, + ABILITY_SHIELDS_DOWN, + ABILITY_DISGUISE, + ABILITY_RKS_SYSTEM, + ABILITY_BATTLE_BOND, + ABILITY_ICE_FACE, + ABILITY_GULP_MISSILE, +}; + +// Functions void HandleAction_UseMove(void) { u32 i, side, moveType, var = 4; @@ -1407,11 +1536,11 @@ static bool32 IsGravityPreventingMove(u32 move) } } -static bool32 IsHealBlockPreventingMove(u32 battler, u32 move) +bool32 IsHealBlockPreventingMove(u32 battler, u32 move) { if (!(gStatuses3[battler] & STATUS3_HEAL_BLOCK)) return FALSE; - + switch (gBattleMoves[move].effect) { case EFFECT_ABSORB: @@ -2909,7 +3038,7 @@ void TryClearRageAndFuryCutter(void) } } -static bool32 IsThawingMove(u8 battlerId, u16 move) +bool32 IsThawingMove(u8 battlerId, u16 move) { switch (move) { @@ -4971,10 +5100,9 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move break; case ABILITY_OBLIVIOUS: if (gBattleMons[battler].status2 & STATUS2_INFATUATION) - { - StringCopy(gBattleTextBuff1, gStatusConditionString_LoveJpn); effect = 3; - } + else if (gDisableStructs[battler].tauntTimer != 0) + effect = 4; break; } if (effect) @@ -4983,17 +5111,26 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move { case 1: // status cleared gBattleMons[battler].status1 = 0; + BattleScriptPushCursor(); + gBattlescriptCurrInstr = BattleScript_AbilityCuredStatus; break; case 2: // get rid of confusion gBattleMons[battler].status2 &= ~(STATUS2_CONFUSION); + BattleScriptPushCursor(); + gBattlescriptCurrInstr = BattleScript_AbilityCuredStatus; break; case 3: // get rid of infatuation gBattleMons[battler].status2 &= ~(STATUS2_INFATUATION); + BattleScriptPushCursor(); + gBattlescriptCurrInstr = BattleScript_BattlerGotOverItsInfatuation; + break; + case 4: // get rid of taunt + gDisableStructs[battler].tauntTimer = 0; + BattleScriptPushCursor(); + gBattlescriptCurrInstr = BattleScript_BattlerShookOffTaunt; break; } - BattleScriptPushCursor(); - gBattlescriptCurrInstr = BattleScript_AbilityCuredStatus; gBattleScripting.battler = gActiveBattler = gBattlerAbility = battler; BtlController_EmitSetMonData(0, REQUEST_STATUS_BATTLE, 0, 4, &gBattleMons[gActiveBattler].status1); MarkBattlerForControllerExec(gActiveBattler); @@ -5716,10 +5853,7 @@ u8 ItemBattleEffects(u8 caseID, u8 battlerId, bool8 moveTurn) u8 ppBonuses; u16 move; - if (GetBattlerSide(battlerId) == B_SIDE_PLAYER) - mon = &gPlayerParty[gBattlerPartyIndexes[battlerId]]; - else - mon = &gEnemyParty[gBattlerPartyIndexes[battlerId]]; + mon = GetBattlerPartyData(battlerId); for (i = 0; i < MAX_MON_MOVES; i++) { move = GetMonData(mon, MON_DATA_MOVE1 + i); @@ -7401,6 +7535,11 @@ static u32 CalcAttackStat(u16 move, u8 battlerAtk, u8 battlerDef, u8 moveType, b atkStage = gBattleMons[battlerDef].statStages[STAT_SPATK]; } } + if (gBattleMoves[move].effect == EFFECT_BODY_PRESS) + { + atkStat = gBattleMons[battlerAtk].defense; + atkStage = gBattleMons[battlerAtk].statStages[STAT_DEF]; + } else { if (IS_MOVE_PHYSICAL(move)) @@ -7518,7 +7657,7 @@ static u32 CalcAttackStat(u16 move, u8 battlerAtk, u8 battlerDef, u8 moveType, b switch (GetBattlerAbility(BATTLE_PARTNER(battlerAtk))) { case ABILITY_FLOWER_GIFT: - if (gBattleMons[BATTLE_PARTNER(battlerAtk)].species == SPECIES_CHERRIM && IS_MOVE_PHYSICAL(move)) + if (gBattleMons[BATTLE_PARTNER(battlerAtk)].species == SPECIES_CHERRIM && WEATHER_HAS_EFFECT && (gBattleWeather & WEATHER_SUN_ANY) && IS_MOVE_PHYSICAL(move)) MulModifier(&modifier, UQ_4_12(1.5)); break; } @@ -7663,7 +7802,7 @@ static u32 CalcDefenseStat(u16 move, u8 battlerAtk, u8 battlerDef, u8 moveType, switch (GetBattlerAbility(BATTLE_PARTNER(battlerDef))) { case ABILITY_FLOWER_GIFT: - if (gBattleMons[BATTLE_PARTNER(battlerDef)].species == SPECIES_CHERRIM && !usesDefStat) + if (gBattleMons[BATTLE_PARTNER(battlerDef)].species == SPECIES_CHERRIM && WEATHER_HAS_EFFECT && gBattleWeather & WEATHER_SUN_ANY && !usesDefStat) MulModifier(&modifier, UQ_4_12(1.5)); break; } @@ -7849,7 +7988,7 @@ static u32 CalcFinalDmg(u32 dmg, u16 move, u8 battlerAtk, u8 battlerDef, u8 move MulModifier(&finalModifier, UQ_4_12(2.0)); if (gBattleMoves[move].flags & FLAG_DMG_UNDERWATER && gStatuses3[battlerDef] & STATUS3_UNDERWATER) MulModifier(&finalModifier, UQ_4_12(2.0)); - if (gBattleMoves[move].flags & FLAG_DMG_IN_AIR && gStatuses3[battlerDef] & STATUS3_ON_AIR) + if (gBattleMoves[move].flags & FLAG_DMG_2X_IN_AIR && gStatuses3[battlerDef] & STATUS3_ON_AIR) MulModifier(&finalModifier, UQ_4_12(2.0)); dmg = ApplyModifier(finalModifier, dmg); @@ -7964,7 +8103,7 @@ static u16 CalcTypeEffectivenessMultiplierInternal(u16 move, u8 moveType, u8 bat && gBattleMons[battlerDef].type3 != gBattleMons[battlerDef].type1) MulByTypeEffectiveness(&modifier, move, moveType, battlerDef, gBattleMons[battlerDef].type3, battlerAtk, recordAbilities); - if (moveType == TYPE_GROUND && !IsBattlerGrounded(battlerDef) && !(gBattleMoves[move].flags & FLAG_DAMAGE_AIRBORNE)) + if (moveType == TYPE_GROUND && !IsBattlerGrounded(battlerDef) && !(gBattleMoves[move].flags & FLAG_DMG_UNGROUNDED_IGNORE_TYPE_IF_FLYING)) { modifier = UQ_4_12(0.0); if (recordAbilities && GetBattlerAbility(battlerDef) == ABILITY_LEVITATE) @@ -7978,7 +8117,7 @@ static u16 CalcTypeEffectivenessMultiplierInternal(u16 move, u8 moveType, u8 bat } // Thousand Arrows ignores type modifiers for flying mons - if (!IsBattlerGrounded(battlerDef) && (gBattleMoves[move].flags & FLAG_DAMAGE_AIRBORNE) + if (!IsBattlerGrounded(battlerDef) && (gBattleMoves[move].flags & FLAG_DMG_UNGROUNDED_IGNORE_TYPE_IF_FLYING) && (gBattleMons[battlerDef].type1 == TYPE_FLYING || gBattleMons[battlerDef].type2 == TYPE_FLYING || gBattleMons[battlerDef].type3 == TYPE_FLYING)) { modifier = UQ_4_12(1.0); @@ -8416,3 +8555,122 @@ static bool32 IsUnnerveAbilityOnOpposingSide(u8 battlerId) return TRUE; return FALSE; } + +bool32 TestMoveFlags(u16 move, u32 flag) +{ + if (gBattleMoves[move].flags & flag) + return TRUE; + return FALSE; +} + +struct Pokemon *GetBattlerPartyData(u8 battlerId) +{ + struct Pokemon *mon; + if (GetBattlerSide(battlerId) == B_SIDE_PLAYER) + mon = &gPlayerParty[gBattlerPartyIndexes[battlerId]]; + else + mon = &gEnemyParty[gBattlerPartyIndexes[battlerId]]; + + return mon; +} + +//Make sure the input bank is any bank on the specific mon's side +bool32 CanFling(u8 battlerId) +{ + u16 item = gBattleMons[battlerId].item; + u16 itemEffect = ItemId_GetHoldEffect(item); + + if (item == ITEM_NONE + || GetBattlerAbility(battlerId) == ABILITY_KLUTZ + || gFieldStatuses & STATUS_FIELD_MAGIC_ROOM + || gDisableStructs[battlerId].embargoTimer != 0 + || !CanBattlerGetOrLoseItem(battlerId, item) + //|| itemEffect == HOLD_EFFECT_PRIMAL_ORB + || itemEffect == HOLD_EFFECT_GEMS + #ifdef ITEM_ABILITY_CAPSULE + || item == ITEM_ABILITY_CAPSULE + #endif + || (ItemId_GetPocket(item) == POCKET_BERRIES && IsAbilityOnSide(battlerId, ABILITY_UNNERVE)) + || GetPocketByItemId(item) == POCKET_POKE_BALLS) + return FALSE; + + return TRUE; +} + +// ability checks +bool32 IsRolePlayBannedAbilityAtk(u16 ability) +{ + u32 i; + for (i = 0; i < ARRAY_COUNT(sRolePlayBannedAttackerAbilities); i++) + { + if (ability == sRolePlayBannedAttackerAbilities[i]) + return TRUE; + } + return FALSE; +} + +bool32 IsRolePlayBannedAbility(u16 ability) +{ + u32 i; + for (i = 0; i < ARRAY_COUNT(sRolePlayBannedAbilities); i++) + { + if (ability == sRolePlayBannedAbilities[i]) + return TRUE; + } + return FALSE; +} + +bool32 IsSkillSwapBannedAbility(u16 ability) +{ + u32 i; + for (i = 0; i < ARRAY_COUNT(sSkillSwapBannedAbilities); i++) + { + if (ability == sSkillSwapBannedAbilities[i]) + return TRUE; + } + return FALSE; +} + +bool32 IsWorrySeedBannedAbility(u16 ability) +{ + u32 i; + for (i = 0; i < ARRAY_COUNT(sWorrySeedBannedAbilities); i++) + { + if (ability == sWorrySeedBannedAbilities[i]) + return TRUE; + } + return FALSE; +} + +bool32 IsGastroAcidBannedAbility(u16 ability) +{ + u32 i; + for (i = 0; i < ARRAY_COUNT(sGastroAcidBannedAbilities); i++) + { + if (ability == sGastroAcidBannedAbilities[i]) + return TRUE; + } + return FALSE; +} + +bool32 IsEntrainmentBannedAbilityAttacker(u16 ability) +{ + u32 i; + for (i = 0; i < ARRAY_COUNT(sEntrainmentBannedAttackerAbilities); i++) + { + if (ability == sEntrainmentBannedAttackerAbilities[i]) + return TRUE; + } + return FALSE; +} + +bool32 IsEntrainmentTargetOrSimpleBeamBannedAbility(u16 ability) +{ + u32 i; + for (i = 0; i < ARRAY_COUNT(sEntrainmentTargetSimpleBeamBannedAbilities); i++) + { + if (ability == sEntrainmentTargetSimpleBeamBannedAbilities[i]) + return TRUE; + } + return FALSE; +} diff --git a/src/battle_util2.c b/src/battle_util2.c index 6d93aadbc..d15700706 100644 --- a/src/battle_util2.c +++ b/src/battle_util2.c @@ -27,7 +27,6 @@ void AllocateBattleResources(void) gBattleResources->beforeLvlUp = AllocZeroed(sizeof(*gBattleResources->beforeLvlUp)); gBattleResources->ai = AllocZeroed(sizeof(*gBattleResources->ai)); gBattleResources->battleHistory = AllocZeroed(sizeof(*gBattleResources->battleHistory)); - gBattleResources->AI_ScriptsStack = AllocZeroed(sizeof(*gBattleResources->AI_ScriptsStack)); gLinkBattleSendBuffer = AllocZeroed(BATTLE_BUFFER_LINK_SIZE); gLinkBattleRecvBuffer = AllocZeroed(BATTLE_BUFFER_LINK_SIZE); @@ -59,7 +58,6 @@ void FreeBattleResources(void) FREE_AND_SET_NULL(gBattleResources->beforeLvlUp); FREE_AND_SET_NULL(gBattleResources->ai); FREE_AND_SET_NULL(gBattleResources->battleHistory); - FREE_AND_SET_NULL(gBattleResources->AI_ScriptsStack); FREE_AND_SET_NULL(gBattleResources); FREE_AND_SET_NULL(gLinkBattleSendBuffer); diff --git a/src/data/battle_moves.h b/src/data/battle_moves.h index 89b2e29aa..39ff44379 100644 --- a/src/data/battle_moves.h +++ b/src/data/battle_moves.h @@ -242,7 +242,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = .secondaryEffectChance = 0, .target = MOVE_TARGET_SELECTED, .priority = 0, - .flags = FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED | FLAG_DMG_IN_AIR, + .flags = FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED | FLAG_DMG_2X_IN_AIR, .split = SPLIT_SPECIAL, }, @@ -265,12 +265,12 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = #if B_UPDATED_MOVE_DATA >= GEN_6 .accuracy = 0, .flags = FLAG_MAGIC_COAT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED, - #elif B_UPDATED_MOVE_DATA >= GEN_5 + #elif B_UPDATED_MOVE_DATA == GEN_5 .accuracy = 100, - .flags = FLAG_MAGIC_COAT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED, + .flags = FLAG_PROTECT_AFFECTED | FLAG_MAGIC_COAT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED, #else .accuracy = 100, - .flags = FLAG_MIRROR_MOVE_AFFECTED, + .flags = FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED, #endif .effect = EFFECT_ROAR, .power = 0, @@ -337,7 +337,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = #if B_UPDATED_MOVE_DATA >= GEN_6 .power = 45, .pp = 25, - #elif B_UPDATED_MOVE_DATA >= GEN_4 + #elif B_UPDATED_MOVE_DATA == GEN_4 || B_UPDATED_MOVE_DATA == GEN_5 .power = 35, .pp = 15, #else @@ -420,6 +420,11 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = [MOVE_ROLLING_KICK] = { + #if B_UPDATED_MOVE_DATA >= GEN_5 + .flags = FLAG_MAKES_CONTACT | FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_SHEER_FORCE_BOOST, + #else + .flags = FLAG_MAKES_CONTACT | FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED | FLAG_SHEER_FORCE_BOOST, + #endif .effect = EFFECT_FLINCH_HIT, .power = 60, .type = TYPE_FIGHTING, @@ -428,7 +433,6 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = .secondaryEffectChance = 30, .target = MOVE_TARGET_SELECTED, .priority = 0, - .flags = FLAG_MAKES_CONTACT | FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED | FLAG_SHEER_FORCE_BOOST, .split = SPLIT_PHYSICAL, }, @@ -507,7 +511,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = #if B_UPDATED_MOVE_DATA >= GEN_7 .power = 40, .accuracy = 100, - #elif B_UPDATED_MOVE_DATA >= GEN_5 + #elif B_UPDATED_MOVE_DATA == GEN_5 || B_UPDATED_MOVE_DATA == GEN_6 .power = 50, .accuracy = 100, #else @@ -715,12 +719,12 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = #if B_UPDATED_MOVE_DATA >= GEN_6 .accuracy = 0, .flags = FLAG_MIRROR_MOVE_AFFECTED | FLAG_SOUND | FLAG_MAGIC_COAT_AFFECTED, - #elif B_UPDATED_MOVE_DATA >= GEN_5 + #elif B_UPDATED_MOVE_DATA == GEN_5 .accuracy = 100, - .flags = FLAG_MIRROR_MOVE_AFFECTED | FLAG_SOUND | FLAG_MAGIC_COAT_AFFECTED, + .flags = FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_SOUND | FLAG_MAGIC_COAT_AFFECTED, #else .accuracy = 100, - .flags = FLAG_MIRROR_MOVE_AFFECTED | FLAG_SOUND, + .flags = FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_SOUND, #endif .effect = EFFECT_ROAR, .power = 0, @@ -897,7 +901,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = #if B_UPDATED_MOVE_DATA >= GEN_6 .power = 90, .target = MOVE_TARGET_FOES_AND_ALLY, - #elif B_UPDATED_MOVE_DATA >= GEN_4 + #elif B_UPDATED_MOVE_DATA == GEN_4 || B_UPDATED_MOVE_DATA == GEN_5 .power = 95, .target = MOVE_TARGET_FOES_AND_ALLY, #else @@ -1068,8 +1072,10 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = [MOVE_COUNTER] = { - #if B_UPDATED_MOVE_DATA >= GEN_4 + #if B_UPDATED_MOVE_DATA >= GEN_5 .flags = FLAG_MAKES_CONTACT | FLAG_PROTECT_AFFECTED, + #elif B_UPDATED_MOVE_DATA == GEN_4 + .flags = FLAG_MAKES_CONTACT, #else .flags = FLAG_MAKES_CONTACT | FLAG_MIRROR_MOVE_AFFECTED, #endif @@ -1274,7 +1280,11 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = [MOVE_STRING_SHOT] = { - .effect = EFFECT_SPEED_DOWN_2, + #if B_UPDATED_MOVE_DATA >= GEN_6 + .effect = EFFECT_SPEED_DOWN_2, + #else + .effect = EFFECT_SPEED_DOWN, + #endif .power = 0, .type = TYPE_BUG, .accuracy = 95, @@ -1383,7 +1393,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = .secondaryEffectChance = 30, .target = MOVE_TARGET_SELECTED, .priority = 0, - .flags = FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_SHEER_FORCE_BOOST | FLAG_HIT_IN_AIR, + .flags = FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_SHEER_FORCE_BOOST | FLAG_DMG_IN_AIR, .split = SPLIT_SPECIAL, }, @@ -1972,10 +1982,15 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = [MOVE_WATERFALL] = { - #if B_UPDATED_MOVE_DATA >= GEN_4 + #if B_UPDATED_MOVE_DATA >= GEN_5 .effect = EFFECT_FLINCH_HIT, + .flags = FLAG_MAKES_CONTACT | FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_SHEER_FORCE_BOOST, + #elif B_UPDATED_MOVE_DATA == GEN_4 + .effect = EFFECT_FLINCH_HIT, + .flags = FLAG_MAKES_CONTACT | FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED | FLAG_SHEER_FORCE_BOOST, #else .effect = EFFECT_HIT, + .flags = FLAG_MAKES_CONTACT | FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED | FLAG_SHEER_FORCE_BOOST, #endif .power = 80, .type = TYPE_WATER, @@ -1984,7 +1999,6 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = .secondaryEffectChance = 20, .target = MOVE_TARGET_SELECTED, .priority = 0, - .flags = FLAG_MAKES_CONTACT | FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED | FLAG_SHEER_FORCE_BOOST, .split = SPLIT_PHYSICAL, }, @@ -2174,13 +2188,13 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = { #if B_UPDATED_MOVE_DATA >= GEN_6 .accuracy = 90, - .target = MOVE_TARGET_FOES_AND_ALLY, + .target = MOVE_TARGET_BOTH, #elif B_UPDATED_MOVE_DATA == GEN_5 .accuracy = 80, - .target = MOVE_TARGET_FOES_AND_ALLY, + .target = MOVE_TARGET_BOTH, #else .accuracy = 55, - .target = MOVE_TARGET_BOTH, + .target = MOVE_TARGET_SELECTED, #endif .effect = EFFECT_POISON, .power = 0, @@ -2241,6 +2255,11 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = [MOVE_SKY_ATTACK] = { + #if B_UPDATED_MOVE_DATA >= GEN_5 + .flags = FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_SHEER_FORCE_BOOST, + #else + .flags = FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED | FLAG_SHEER_FORCE_BOOST, + #endif .effect = EFFECT_TWO_TURNS_ATTACK, .power = 140, .type = TYPE_FLYING, @@ -2249,7 +2268,6 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = .secondaryEffectChance = 30, .target = MOVE_TARGET_SELECTED, .priority = 0, - .flags = FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED | FLAG_SHEER_FORCE_BOOST, .split = SPLIT_PHYSICAL, .argument = MOVE_EFFECT_FLINCH, }, @@ -2714,8 +2732,13 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = { #if B_UPDATED_MOVE_DATA >= GEN_6 .power = 50, + .flags = FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_SHEER_FORCE_BOOST | FLAG_SOUND, + #elif B_UPDATED_MOVE_DATA == GEN_5 + .power = 40, + .flags = FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_SHEER_FORCE_BOOST | FLAG_SOUND, #else .power = 40, + .flags = FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED | FLAG_SHEER_FORCE_BOOST | FLAG_SOUND, #endif .effect = EFFECT_SNORE, .type = TYPE_NORMAL, @@ -2724,7 +2747,6 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = .secondaryEffectChance = 30, .target = MOVE_TARGET_SELECTED, .priority = 0, - .flags = FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED | FLAG_SHEER_FORCE_BOOST | FLAG_SOUND, .split = SPLIT_SPECIAL, }, @@ -2762,17 +2784,13 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = [MOVE_CONVERSION_2] = { - #if B_UPDATED_MOVE_DATA >= GEN_5 - .target = MOVE_TARGET_USER, - #else - .target = MOVE_TARGET_FOES_AND_ALLY, - #endif .effect = EFFECT_CONVERSION_2, .power = 0, .type = TYPE_NORMAL, - .accuracy = 100, + .accuracy = 0, .pp = 30, .secondaryEffectChance = 0, + .target = MOVE_TARGET_USER, .priority = 0, .flags = 0, .split = SPLIT_STATUS, @@ -2799,10 +2817,10 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = .target = MOVE_TARGET_BOTH, #elif B_UPDATED_MOVE_DATA == GEN_5 .accuracy = 100, - .target = MOVE_TARGET_FOES_AND_ALLY, + .target = MOVE_TARGET_SELECTED, #else .accuracy = 85, - .target = MOVE_TARGET_FOES_AND_ALLY, + .target = MOVE_TARGET_SELECTED, #endif .effect = EFFECT_SPEED_DOWN_2, .power = 0, @@ -2862,6 +2880,11 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = [MOVE_PROTECT] = { + #if B_UPDATED_MOVE_DATA >= GEN_5 + .priority = 4, + #else + .priority = 3, + #endif .effect = EFFECT_PROTECT, .power = 0, .type = TYPE_NORMAL, @@ -2869,7 +2892,6 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = .pp = 10, .secondaryEffectChance = 0, .target = MOVE_TARGET_USER, - .priority = 4, .flags = FLAG_PROTECTION_MOVE, .split = SPLIT_STATUS, }, @@ -3039,7 +3061,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = #if B_UPDATED_MOVE_DATA >= GEN_5 .accuracy = 0, .flags = FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_MAGIC_COAT_AFFECTED, - #elif B_UPDATED_MOVE_DATA >= GEN_4 + #elif B_UPDATED_MOVE_DATA == GEN_4 .accuracy = 0, .flags = FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED, #else @@ -3100,6 +3122,11 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = [MOVE_DETECT] = { + #if B_UPDATED_MOVE_DATA >= GEN_5 + .priority = 4, + #else + .priority = 3, + #endif .effect = EFFECT_PROTECT, .power = 0, .type = TYPE_FIGHTING, @@ -3107,7 +3134,6 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = .pp = 5, .secondaryEffectChance = 0, .target = MOVE_TARGET_USER, - .priority = 4, .flags = FLAG_PROTECTION_MOVE, .split = SPLIT_STATUS, }, @@ -3133,9 +3159,9 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = [MOVE_LOCK_ON] = { #if B_UPDATED_MOVE_DATA >= GEN_4 - .accuracy = 100, - #else .accuracy = 0, + #else + .accuracy = 100, #endif .effect = EFFECT_LOCK_ON, .power = 0, @@ -3208,6 +3234,11 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = [MOVE_ENDURE] = { + #if B_UPDATED_MOVE_DATA >= GEN_5 + .priority = 4, + #else + .priority = 3, + #endif .effect = EFFECT_ENDURE, .power = 0, .type = TYPE_NORMAL, @@ -3215,7 +3246,6 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = .pp = 10, .secondaryEffectChance = 0, .target = MOVE_TARGET_USER, - .priority = 4, .flags = FLAG_PROTECTION_MOVE, .split = SPLIT_STATUS, }, @@ -3594,7 +3624,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = [MOVE_RAPID_SPIN] = { - #if B_UPDATED_MOVE_DATA >= GEN_4 + #if B_UPDATED_MOVE_DATA >= GEN_8 .power = 50, #else .power = 20, @@ -3612,7 +3642,11 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = [MOVE_SWEET_SCENT] = { - .effect = EFFECT_EVASION_DOWN_2, + #if B_UPDATED_MOVE_DATA >= GEN_6 + .effect = EFFECT_EVASION_DOWN_2, + #else + .effect = EFFECT_EVASION_DOWN, + #endif .power = 0, .type = TYPE_NORMAL, .accuracy = 100, @@ -3714,8 +3748,12 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = [MOVE_HIDDEN_POWER] = { + #if B_UPDATED_MOVE_DATA >= GEN_6 + .power = 60, + #else + .power = 1, + #endif .effect = EFFECT_HIDDEN_POWER, - .power = 60, .type = TYPE_NORMAL, .accuracy = 100, .pp = 15, @@ -3742,6 +3780,11 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = [MOVE_TWISTER] = { + #if B_UPDATED_MOVE_DATA >= GEN_5 + .flags = FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_SHEER_FORCE_BOOST | FLAG_DMG_2X_IN_AIR, + #else + .flags = FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED | FLAG_SHEER_FORCE_BOOST | FLAG_DMG_2X_IN_AIR, + #endif .effect = EFFECT_TWISTER, .power = 40, .type = TYPE_DRAGON, @@ -3750,7 +3793,6 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = .secondaryEffectChance = 20, .target = MOVE_TARGET_BOTH, .priority = 0, - .flags = FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED | FLAG_SHEER_FORCE_BOOST | FLAG_DMG_IN_AIR, .split = SPLIT_SPECIAL, }, @@ -3802,8 +3844,10 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = [MOVE_MIRROR_COAT] = { - #if B_UPDATED_MOVE_DATA >= GEN_4 + #if B_UPDATED_MOVE_DATA >= GEN_5 .flags = FLAG_PROTECT_AFFECTED, + #elif B_UPDATED_MOVE_DATA == GEN_4 + .flags = 0, #else .flags = FLAG_MIRROR_MOVE_AFFECTED, #endif @@ -3821,9 +3865,9 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = [MOVE_PSYCH_UP] = { #if B_UPDATED_MOVE_DATA >= GEN_5 - .flags = FLAG_SNATCH_AFFECTED, - #else .flags = 0, + #else + .flags = FLAG_SNATCH_AFFECTED, #endif .effect = EFFECT_PSYCH_UP, .power = 0, @@ -3949,12 +3993,12 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = [MOVE_BEAT_UP] = { - .effect = EFFECT_BEAT_UP, - #if B_BEAT_UP_DMG >= GEN_5 + #if B_UPDATED_MOVE_DATA >= GEN_5 .power = 1, #else .power = 10, #endif + .effect = EFFECT_BEAT_UP, .type = TYPE_DARK, .accuracy = 100, .pp = 10, @@ -3967,9 +4011,14 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = [MOVE_FAKE_OUT] = { - #if B_UPDATED_MOVE_DATA >= GEN_4 + #if B_UPDATED_MOVE_DATA >= GEN_5 + .priority = 3, + .flags = FLAG_MAKES_CONTACT | FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_SHEER_FORCE_BOOST, + #elif B_UPDATED_MOVE_DATA == GEN_4 + .priority = 1, .flags = FLAG_MAKES_CONTACT | FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_SHEER_FORCE_BOOST, #else + .priority = 1, .flags = FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_SHEER_FORCE_BOOST, #endif .effect = EFFECT_FAKE_OUT, @@ -3979,7 +4028,6 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = .pp = 10, .secondaryEffectChance = 100, .target = MOVE_TARGET_SELECTED, - .priority = 3, .split = SPLIT_PHYSICAL, }, @@ -4196,6 +4244,11 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = [MOVE_FOLLOW_ME] = { + #if B_UPDATED_MOVE_DATA >= GEN_6 + .priority = 2, + #else + .priority = 3, + #endif .effect = EFFECT_FOLLOW_ME, .power = 0, .type = TYPE_NORMAL, @@ -4203,7 +4256,6 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = .pp = 20, .secondaryEffectChance = 0, .target = MOVE_TARGET_USER, - .priority = 2, .flags = 0, .split = SPLIT_STATUS, }, @@ -4213,7 +4265,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = .effect = EFFECT_NATURE_POWER, .power = 0, .type = TYPE_NORMAL, - .accuracy = 95, + .accuracy = 0, .pp = 20, .secondaryEffectChance = 0, .target = MOVE_TARGET_DEPENDS, @@ -4240,6 +4292,8 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = { #if B_UPDATED_MOVE_DATA >= GEN_5 .flags = FLAG_PROTECT_AFFECTED | FLAG_MAGIC_COAT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED, + #elif B_UPDATED_MOVE_DATA == GEN_4 + .flags = FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED, #else .flags = FLAG_PROTECT_AFFECTED, #endif @@ -4310,7 +4364,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = .effect = EFFECT_WISH, .power = 0, .type = TYPE_NORMAL, - .accuracy = 100, + .accuracy = 0, .pp = 10, .secondaryEffectChance = 0, .target = MOVE_TARGET_USER, @@ -4616,10 +4670,14 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = [MOVE_TAIL_GLOW] = { - .effect = EFFECT_SPECIAL_ATTACK_UP_3, + #if B_UPDATED_MOVE_DATA >= GEN_5 + .effect = EFFECT_SPECIAL_ATTACK_UP_3, + #else + .effect = EFFECT_SPECIAL_ATTACK_UP_2, + #endif .power = 0, .type = TYPE_BUG, - .accuracy = 100, + .accuracy = 0, .pp = 20, .secondaryEffectChance = 0, .target = MOVE_TARGET_USER, @@ -4778,7 +4836,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = [MOVE_POISON_FANG] = { - #if B_UPDATED_MOVE_DATA >= GEN_4 + #if B_UPDATED_MOVE_DATA >= GEN_6 .secondaryEffectChance = 50, #else .secondaryEffectChance = 30, @@ -4938,7 +4996,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = #if B_UPDATED_MOVE_DATA >= GEN_6 .power = 130, .flags = FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED, - #elif B_UPDATED_MOVE_DATA >= GEN_4 + #elif B_UPDATED_MOVE_DATA == GEN_4 || B_UPDATED_MOVE_DATA == GEN_5 .power = 140, .flags = FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED, #else @@ -4957,9 +5015,12 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = [MOVE_ODOR_SLEUTH] = { - #if B_UPDATED_MOVE_DATA >= GEN_4 + #if B_UPDATED_MOVE_DATA >= GEN_5 .accuracy = 0, .flags = FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_MAGIC_COAT_AFFECTED, + #elif B_UPDATED_MOVE_DATA == GEN_4 + .accuracy = 0, + .flags = FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED, #else .accuracy = 100, .flags = FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED, @@ -5138,7 +5199,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = .secondaryEffectChance = 0, .target = MOVE_TARGET_SELECTED, .priority = 0, - .flags = FLAG_MAKES_CONTACT | FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED | FLAG_IRON_FIST_BOOST | FLAG_HIT_IN_AIR, + .flags = FLAG_MAKES_CONTACT | FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED | FLAG_IRON_FIST_BOOST | FLAG_DMG_IN_AIR, .split = SPLIT_PHYSICAL, }, @@ -5497,10 +5558,15 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = [MOVE_ROCK_BLAST] = { - #if B_UPDATED_MOVE_DATA >= GEN_5 + #if B_UPDATED_MOVE_DATA >= GEN_7 .accuracy = 90, + .flags = FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED | FLAG_BALLISTIC, + #elif B_UPDATED_MOVE_DATA == GEN_5 || B_UPDATED_MOVE_DATA == GEN_6 + .accuracy = 90, + .flags = FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED, #else .accuracy = 80, + .flags = FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED, #endif .effect = EFFECT_MULTI_HIT, .power = 25, @@ -5509,7 +5575,6 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = .secondaryEffectChance = 0, .target = MOVE_TARGET_SELECTED, .priority = 0, - .flags = FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED | FLAG_BALLISTIC, .split = SPLIT_PHYSICAL, }, @@ -6274,6 +6339,11 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = [MOVE_DARK_PULSE] = { + #if B_UPDATED_MOVE_DATA >= GEN_5 + .flags = FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_SHEER_FORCE_BOOST | FLAG_MEGA_LAUNCHER_BOOST, + #else + .flags = FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED | FLAG_SHEER_FORCE_BOOST | FLAG_MEGA_LAUNCHER_BOOST, + #endif .effect = EFFECT_FLINCH_HIT, .power = 80, .type = TYPE_DARK, @@ -6282,7 +6352,6 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = .secondaryEffectChance = 20, .target = MOVE_TARGET_SELECTED, .priority = 0, - .flags = FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_SHEER_FORCE_BOOST | FLAG_MEGA_LAUNCHER_BOOST, .split = SPLIT_SPECIAL, }, @@ -6332,8 +6401,13 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = { #if B_UPDATED_MOVE_DATA >= GEN_6 .pp = 15, + .flags = FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_SHEER_FORCE_BOOST, + #elif B_UPDATED_MOVE_DATA == GEN_5 + .pp = 20, + .flags = FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_SHEER_FORCE_BOOST, #else .pp = 20, + .flags = FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED | FLAG_SHEER_FORCE_BOOST, #endif .effect = EFFECT_FLINCH_HIT, .power = 75, @@ -6342,7 +6416,6 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = .secondaryEffectChance = 30, .target = MOVE_TARGET_SELECTED, .priority = 0, - .flags = FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_SHEER_FORCE_BOOST, .split = SPLIT_SPECIAL, }, @@ -6396,8 +6469,10 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = { #if B_UPDATED_MOVE_DATA >= GEN_6 .flags = FLAG_MAKES_CONTACT | FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_SHEER_FORCE_BOOST | FLAG_DMG_MINIMIZE, - #else + #elif B_UPDATED_MOVE_DATA == GEN_5 .flags = FLAG_MAKES_CONTACT | FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_SHEER_FORCE_BOOST, + #else + .flags = FLAG_MAKES_CONTACT | FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED | FLAG_SHEER_FORCE_BOOST, #endif .effect = EFFECT_FLINCH_HIT, .power = 100, @@ -6621,6 +6696,11 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = [MOVE_THUNDER_FANG] = { + #if B_UPDATED_MOVE_DATA >= GEN_5 + .flags = FLAG_MAKES_CONTACT | FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_SHEER_FORCE_BOOST | FLAG_STRONG_JAW_BOOST, + #else + .flags = FLAG_MAKES_CONTACT | FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED | FLAG_SHEER_FORCE_BOOST | FLAG_STRONG_JAW_BOOST, + #endif .effect = EFFECT_FLINCH_STATUS, .power = 65, .type = TYPE_ELECTRIC, @@ -6629,13 +6709,17 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = .secondaryEffectChance = 10, .target = MOVE_TARGET_SELECTED, .priority = 0, - .flags = FLAG_MAKES_CONTACT | FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED | FLAG_SHEER_FORCE_BOOST | FLAG_STRONG_JAW_BOOST, .split = SPLIT_PHYSICAL, .argument = STATUS1_PARALYSIS, }, [MOVE_ICE_FANG] = { + #if B_UPDATED_MOVE_DATA >= GEN_5 + .flags = FLAG_MAKES_CONTACT | FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_SHEER_FORCE_BOOST | FLAG_STRONG_JAW_BOOST, + #else + .flags = FLAG_MAKES_CONTACT | FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED | FLAG_SHEER_FORCE_BOOST | FLAG_STRONG_JAW_BOOST, + #endif .effect = EFFECT_FLINCH_STATUS, .power = 65, .type = TYPE_ICE, @@ -6644,13 +6728,17 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = .secondaryEffectChance = 10, .target = MOVE_TARGET_SELECTED, .priority = 0, - .flags = FLAG_MAKES_CONTACT | FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED | FLAG_SHEER_FORCE_BOOST | FLAG_STRONG_JAW_BOOST, .split = SPLIT_PHYSICAL, .argument = STATUS1_FREEZE, }, [MOVE_FIRE_FANG] = { + #if B_UPDATED_MOVE_DATA >= GEN_5 + .flags = FLAG_MAKES_CONTACT | FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_SHEER_FORCE_BOOST | FLAG_STRONG_JAW_BOOST, + #else + .flags = FLAG_MAKES_CONTACT | FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED | FLAG_SHEER_FORCE_BOOST | FLAG_STRONG_JAW_BOOST, + #endif .effect = EFFECT_FLINCH_STATUS, .power = 65, .type = TYPE_FIRE, @@ -6659,7 +6747,6 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = .secondaryEffectChance = 10, .target = MOVE_TARGET_SELECTED, .priority = 0, - .flags = FLAG_MAKES_CONTACT | FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED | FLAG_SHEER_FORCE_BOOST | FLAG_STRONG_JAW_BOOST, .split = SPLIT_PHYSICAL, .argument = STATUS1_BURN, }, @@ -6790,7 +6877,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = .secondaryEffectChance = 0, .target = MOVE_TARGET_USER, .priority = -7, - .flags = 0, + .flags = FLAG_MIRROR_MOVE_AFFECTED, .split = SPLIT_STATUS, }, @@ -6920,6 +7007,11 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = [MOVE_IRON_HEAD] = { + #if B_UPDATED_MOVE_DATA >= GEN_5 + .flags = FLAG_MAKES_CONTACT | FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_SHEER_FORCE_BOOST, + #else + .flags = FLAG_MAKES_CONTACT | FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED | FLAG_SHEER_FORCE_BOOST, + #endif .effect = EFFECT_FLINCH_HIT, .power = 80, .type = TYPE_STEEL, @@ -6928,7 +7020,6 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = .secondaryEffectChance = 30, .target = MOVE_TARGET_SELECTED, .priority = 0, - .flags = FLAG_MAKES_CONTACT | FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_SHEER_FORCE_BOOST, .split = SPLIT_PHYSICAL, }, @@ -7010,17 +7101,23 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = { #if B_UPDATED_MOVE_DATA >= GEN_6 .power = 65, + .secondaryEffectChance = 100, + .flags = FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_SOUND | FLAG_SHEER_FORCE_BOOST, + #elif B_UPDATED_MOVE_DATA == GEN_5 + .power = 60, + .secondaryEffectChance = 10, + .flags = FLAG_PROTECT_AFFECTED | FLAG_SOUND | FLAG_SHEER_FORCE_BOOST, #else .power = 60, + .secondaryEffectChance = 31, + .flags = FLAG_PROTECT_AFFECTED | FLAG_SOUND | FLAG_SHEER_FORCE_BOOST, #endif .effect = EFFECT_CONFUSE_HIT, .type = TYPE_FLYING, .accuracy = 100, .pp = 20, - .secondaryEffectChance = 100, .target = MOVE_TARGET_SELECTED, .priority = 0, - .flags = FLAG_PROTECT_AFFECTED | FLAG_SOUND | FLAG_SHEER_FORCE_BOOST, .split = SPLIT_SPECIAL, }, @@ -7382,7 +7479,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = .pp = 10, .secondaryEffectChance = 0, .target = MOVE_TARGET_USER, - .flags = 0, + .flags = FLAG_MIRROR_MOVE_AFFECTED, .split = SPLIT_STATUS, }, @@ -7474,7 +7571,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = .pp = 10, .secondaryEffectChance = 0, .target = MOVE_TARGET_USER, - .flags = 0, + .flags = FLAG_MIRROR_MOVE_AFFECTED, .split = SPLIT_STATUS, }, @@ -7488,7 +7585,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = .secondaryEffectChance = 100, .target = MOVE_TARGET_SELECTED, .priority = 0, - .flags = FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED | FLAG_HIT_IN_AIR, + .flags = FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED | FLAG_DMG_IN_AIR, .split = SPLIT_PHYSICAL, }, @@ -7874,7 +7971,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = .secondaryEffectChance = 0, .target = MOVE_TARGET_SELECTED, .priority = 0, - .flags = FLAG_PROTECT_AFFECTED | FLAG_MAGIC_COAT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_MEGA_LAUNCHER_BOOST, + .flags = FLAG_PROTECT_AFFECTED | FLAG_MAGIC_COAT_AFFECTED | FLAG_MEGA_LAUNCHER_BOOST, .split = SPLIT_STATUS, }, @@ -8436,7 +8533,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = .secondaryEffectChance = 30, .target = MOVE_TARGET_SELECTED, .priority = 0, - .flags = FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED | FLAG_SHEER_FORCE_BOOST | FLAG_HIT_IN_AIR, + .flags = FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED | FLAG_SHEER_FORCE_BOOST | FLAG_DMG_IN_AIR, .split = SPLIT_SPECIAL, }, @@ -8855,7 +8952,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = .secondaryEffectChance = 0, .target = MOVE_TARGET_FOES_AND_ALLY, .priority = 0, - .flags = FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED, + .flags = FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED, .split = SPLIT_SPECIAL, }, @@ -8898,7 +8995,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = .secondaryEffectChance = 10, .target = MOVE_TARGET_SELECTED, .priority = 0, - .flags = FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_SHEER_FORCE_BOOST, + .flags = FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED | FLAG_SHEER_FORCE_BOOST, .split = SPLIT_SPECIAL, }, @@ -9100,7 +9197,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = .secondaryEffectChance = 0, .target = MOVE_TARGET_USER, .priority = 0, - .flags = 0, + .flags = FLAG_MIRROR_MOVE_AFFECTED, .split = SPLIT_STATUS, }, @@ -9194,7 +9291,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = [MOVE_WATER_SHURIKEN] = { - #if B_WATER_SHURIKEN_SPLIT >= GEN_7 + #if B_UPDATED_MOVE_DATA >= GEN_7 .split = SPLIT_SPECIAL, #else .split = SPLIT_PHYSICAL, @@ -9491,7 +9588,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = .secondaryEffectChance = 100, .target = MOVE_TARGET_BOTH, .priority = 0, - .flags = FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED | FLAG_HIT_IN_AIR | FLAG_DAMAGE_AIRBORNE, + .flags = FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED | FLAG_DMG_IN_AIR | FLAG_DMG_UNGROUNDED_IGNORE_TYPE_IF_FLYING, .split = SPLIT_PHYSICAL, }, @@ -9659,7 +9756,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = .secondaryEffectChance = 0, .target = MOVE_TARGET_SELECTED, .priority = 0, - .flags = FLAG_MAKES_CONTACT | FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_STAT_STAGES_IGNORED, + .flags = FLAG_MAKES_CONTACT | FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED | FLAG_STAT_STAGES_IGNORED, .split = SPLIT_PHYSICAL, }, @@ -9688,7 +9785,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = .secondaryEffectChance = 0, .target = MOVE_TARGET_SELECTED, .priority = 0, - .flags = FLAG_MAKES_CONTACT | FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_IRON_FIST_BOOST, + .flags = FLAG_MAKES_CONTACT | FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED | FLAG_IRON_FIST_BOOST, .split = SPLIT_PHYSICAL, }, @@ -9856,7 +9953,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = .secondaryEffectChance = 0, .target = MOVE_TARGET_SELECTED, .priority = 0, - .flags = FLAG_MAKES_CONTACT | FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_SHEER_FORCE_BOOST, + .flags = FLAG_MAKES_CONTACT | FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED | FLAG_SHEER_FORCE_BOOST, .split = SPLIT_PHYSICAL, }, @@ -9996,7 +10093,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = .secondaryEffectChance = 0, .target = MOVE_TARGET_SELECTED, .priority = 0, - .flags = FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED, + .flags = FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED, .split = SPLIT_SPECIAL, }, @@ -10038,21 +10135,21 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = .secondaryEffectChance = 0, .target = MOVE_TARGET_SELECTED, .priority = -3, - .flags = FLAG_PROTECT_AFFECTED | FLAG_BALLISTIC, + .flags = FLAG_PROTECT_AFFECTED | FLAG_KINGS_ROCK_AFFECTED | FLAG_BALLISTIC, .split = SPLIT_PHYSICAL, }, [MOVE_CLANGING_SCALES] = { - .effect = EFFECT_DEFENSE_DOWN_HIT, + .effect = EFFECT_ATTACKER_DEFENSE_DOWN_HIT, .power = 110, .type = TYPE_DRAGON, .accuracy = 100, .pp = 5, - .secondaryEffectChance = 100, + .secondaryEffectChance = 0, .target = MOVE_TARGET_SELECTED, .priority = 0, - .flags = FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_SOUND, + .flags = FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED | FLAG_SOUND, .split = SPLIT_SPECIAL, }, @@ -10066,7 +10163,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = .secondaryEffectChance = 0, .target = MOVE_TARGET_SELECTED, .priority = 0, - .flags = FLAG_MAKES_CONTACT | FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED, + .flags = FLAG_MAKES_CONTACT | FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED, .split = SPLIT_PHYSICAL, }, @@ -10122,7 +10219,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = .secondaryEffectChance = 100, .target = MOVE_TARGET_SELECTED, .priority = 0, - .flags = FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED, + .flags = FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED, .split = SPLIT_SPECIAL, }, @@ -10178,7 +10275,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = .secondaryEffectChance = 0, .target = MOVE_TARGET_SELECTED, .priority = 1, - .flags = FLAG_MAKES_CONTACT | FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED, + .flags = FLAG_MAKES_CONTACT | FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED, .split = SPLIT_PHYSICAL, }, @@ -10359,17 +10456,18 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = { #if B_UPDATED_MOVE_DATA >= GEN_8 .power = 80, + .effect = EFFECT_PLACEHOLDER, // TODO: EFFECT_EVASION_UP_HIT .pp = 10, - .flags = FLAG_MAKES_CONTACT | FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED, + .flags = FLAG_MAKES_CONTACT | FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED | FLAG_SHEER_FORCE_BOOST, #else + .effect = EFFECT_ALWAYS_CRIT, .power = 50, .pp = 15, .flags = FLAG_MAKES_CONTACT | FLAG_PROTECT_AFFECTED | FLAG_KINGS_ROCK_AFFECTED, #endif - .effect = EFFECT_ALWAYS_CRIT, .type = TYPE_ELECTRIC, .accuracy = 100, - .secondaryEffectChance = 0, + .secondaryEffectChance = 100, .target = MOVE_TARGET_SELECTED, .priority = 2, .split = SPLIT_PHYSICAL, @@ -10378,9 +10476,9 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = [MOVE_SPLISHY_SPLASH] = { #if B_UPDATED_MOVE_DATA >= GEN_8 - .flags = FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED, + .flags = FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED | FLAG_SHEER_FORCE_BOOST, #else - .flags = FLAG_PROTECT_AFFECTED | FLAG_KINGS_ROCK_AFFECTED, + .flags = FLAG_PROTECT_AFFECTED | FLAG_KINGS_ROCK_AFFECTED | FLAG_SHEER_FORCE_BOOST, #endif .effect = EFFECT_PARALYZE_HIT, .power = 90, @@ -10396,9 +10494,9 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = [MOVE_FLOATY_FALL] = { #if B_UPDATED_MOVE_DATA >= GEN_8 - .flags = FLAG_MAKES_CONTACT | FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED, + .flags = FLAG_MAKES_CONTACT | FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_SHEER_FORCE_BOOST, #else - .flags = FLAG_MAKES_CONTACT | FLAG_PROTECT_AFFECTED, + .flags = FLAG_MAKES_CONTACT | FLAG_PROTECT_AFFECTED | FLAG_SHEER_FORCE_BOOST, #endif .effect = EFFECT_FLINCH_HIT, .power = 90, @@ -10614,9 +10712,9 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = [MOVE_DOUBLE_IRON_BASH] = { #if B_UPDATED_MOVE_DATA >= GEN_8 - .flags = FLAG_MAKES_CONTACT | FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_IRON_FIST_BOOST, + .flags = FLAG_MAKES_CONTACT | FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_IRON_FIST_BOOST | FLAG_SHEER_FORCE_BOOST, #else - .flags = FLAG_MAKES_CONTACT | FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_DMG_MINIMIZE | FLAG_IRON_FIST_BOOST, + .flags = FLAG_MAKES_CONTACT | FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_DMG_MINIMIZE | FLAG_IRON_FIST_BOOST | FLAG_SHEER_FORCE_BOOST, #endif .effect = EFFECT_PLACEHOLDER, //TODO (EFFECT_FLINCH_HIT + EFFECT_DOUBLE_HIT) .power = 60, @@ -10828,7 +10926,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = [MOVE_BODY_PRESS] = { - .effect = EFFECT_PLACEHOLDER, //TODO + .effect = EFFECT_BODY_PRESS, .power = 80, .type = TYPE_FIGHTING, .accuracy = 100, @@ -10864,7 +10962,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = .secondaryEffectChance = 100, .target = MOVE_TARGET_SELECTED, .priority = 0, - .flags = FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED, + .flags = FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED | FLAG_SHEER_FORCE_BOOST, .split = SPLIT_PHYSICAL, }, @@ -10892,7 +10990,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = .secondaryEffectChance = 10, .target = MOVE_TARGET_SELECTED, .priority = 0, - .flags = FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED | FLAG_BALLISTIC, + .flags = FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED | FLAG_BALLISTIC | FLAG_SHEER_FORCE_BOOST, .split = SPLIT_PHYSICAL, }, @@ -10948,7 +11046,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = .secondaryEffectChance = 100, .target = MOVE_TARGET_BOTH, .priority = 0, - .flags = FLAG_MAKES_CONTACT | FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED, + .flags = FLAG_MAKES_CONTACT | FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED | FLAG_SHEER_FORCE_BOOST, .split = SPLIT_PHYSICAL, }, @@ -10990,7 +11088,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = .secondaryEffectChance = 100, .target = MOVE_TARGET_SELECTED, .priority = 0, - .flags = FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED, + .flags = FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED | FLAG_SHEER_FORCE_BOOST, .split = SPLIT_SPECIAL, }, @@ -11004,7 +11102,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = .secondaryEffectChance = 100, .target = MOVE_TARGET_SELECTED, .priority = 0, - .flags = FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED, + .flags = FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED | FLAG_SHEER_FORCE_BOOST, .split = SPLIT_PHYSICAL, }, @@ -11018,7 +11116,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = .secondaryEffectChance = 100, .target = MOVE_TARGET_SELECTED, .priority = 0, - .flags = FLAG_MAKES_CONTACT | FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED, + .flags = FLAG_MAKES_CONTACT | FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED | FLAG_SHEER_FORCE_BOOST, .split = SPLIT_PHYSICAL, }, @@ -11032,7 +11130,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = .secondaryEffectChance = 20, .target = MOVE_TARGET_SELECTED, .priority = 0, - .flags = FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED, + .flags = FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED | FLAG_SHEER_FORCE_BOOST, .split = SPLIT_SPECIAL, }, @@ -11186,7 +11284,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = .secondaryEffectChance = 20, .target = MOVE_TARGET_SELECTED, .priority = 0, - .flags = FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED, + .flags = FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED | FLAG_SHEER_FORCE_BOOST, .split = SPLIT_SPECIAL, }, @@ -11256,7 +11354,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = .secondaryEffectChance = 100, .target = MOVE_TARGET_SELECTED, .priority = 0, - .flags = FLAG_MAKES_CONTACT | FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED, + .flags = FLAG_MAKES_CONTACT | FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED | FLAG_SHEER_FORCE_BOOST, .split = SPLIT_PHYSICAL, }, @@ -11270,7 +11368,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = .secondaryEffectChance = 0, .target = MOVE_TARGET_BOTH, .priority = 0, - .flags = FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED, + .flags = FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED | FLAG_SHEER_FORCE_BOOST, .split = SPLIT_SPECIAL, }, @@ -11382,7 +11480,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = .secondaryEffectChance = 30, .target = MOVE_TARGET_SELECTED, .priority = 0, - .flags = FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED, + .flags = FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED | FLAG_SHEER_FORCE_BOOST, .split = SPLIT_SPECIAL, }, @@ -11465,7 +11563,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = .secondaryEffectChance = 10, .target = MOVE_TARGET_SELECTED, .priority = 0, - .flags = FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED, + .flags = FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED | FLAG_SHEER_FORCE_BOOST, .split = SPLIT_SPECIAL, }, @@ -11493,7 +11591,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = .secondaryEffectChance = 100, .target = MOVE_TARGET_SELECTED, .priority = 0, - .flags = FLAG_MAKES_CONTACT | FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED, + .flags = FLAG_MAKES_CONTACT | FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED | FLAG_SHEER_FORCE_BOOST, .split = SPLIT_PHYSICAL, }, @@ -11535,7 +11633,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT] = .secondaryEffectChance = 0, .target = MOVE_TARGET_SELECTED, .priority = 0, - .flags = FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED | FLAG_SOUND, + .flags = FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED | FLAG_SHEER_FORCE_BOOST | FLAG_SOUND, .split = SPLIT_SPECIAL, }, }; diff --git a/src/data/text/abilities.h b/src/data/text/abilities.h index a9f8ba7ab..c2c17b737 100644 --- a/src/data/text/abilities.h +++ b/src/data/text/abilities.h @@ -40,7 +40,7 @@ static const u8 sPoisonPointDescription[] = _("Poisons foe on contact."); static const u8 sInnerFocusDescription[] = _("Prevents flinching."); static const u8 sMagmaArmorDescription[] = _("Prevents freezing."); static const u8 sWaterVeilDescription[] = _("Prevents burns."); -static const u8 sMagnetPullDescription[] = _("Traps Steel-type POKéMON."); +static const u8 sMagnetPullDescription[] = _("Traps Steel-type Pokémon."); static const u8 sSoundproofDescription[] = _("Avoids sound-based moves."); static const u8 sRainDishDescription[] = _("Slight HP recovery in rain."); static const u8 sSandStreamDescription[] = _("Summons a sandstorm."); @@ -255,7 +255,7 @@ static const u8 sGrimNeighDescription[] = _("KOs boost Sp. Atk stat."); static const u8 sAsOneIceRiderDescription[] = _("Unnerve and Chilling Neigh."); static const u8 sAsOneShadowRiderDescription[] = _("Unnerve and Grim Neigh."); -const u8 gAbilityNames[ABILITIES_COUNT_GEN8][ABILITY_NAME_LENGTH + 1] = +const u8 gAbilityNames[ABILITIES_COUNT][ABILITY_NAME_LENGTH + 1] = { [ABILITY_NONE] = _("-------"), [ABILITY_STENCH] = _("Stench"), @@ -527,7 +527,7 @@ const u8 gAbilityNames[ABILITIES_COUNT_GEN8][ABILITY_NAME_LENGTH + 1] = [ABILITY_AS_ONE_SHADOW_RIDER] = _("As One"), }; -const u8 *const gAbilityDescriptionPointers[ABILITIES_COUNT_GEN8] = +const u8 *const gAbilityDescriptionPointers[ABILITIES_COUNT] = { [ABILITY_NONE] = sNoneDescription, [ABILITY_STENCH] = sStenchDescription, diff --git a/src/data/text/move_descriptions.h b/src/data/text/move_descriptions.h index d1d52f97c..e204fb196 100644 --- a/src/data/text/move_descriptions.h +++ b/src/data/text/move_descriptions.h @@ -55,7 +55,7 @@ static const u8 sRazorWindDescription[] = _( static const u8 sSwordsDanceDescription[] = _( "A fighting dance that\n" - "sharply raises ATTACK."); + "sharply raises Attack."); static const u8 sCutDescription[] = _( "Cuts the foe with sharp\n" @@ -155,7 +155,7 @@ static const u8 sDoubleEdgeDescription[] = _( static const u8 sTailWhipDescription[] = _( "Wags the tail to lower the\n" - "foe's DEFENSE."); + "foe's Defense."); static const u8 sPoisonStingDescription[] = _( "A toxic attack with barbs,\n" @@ -171,7 +171,7 @@ static const u8 sPinMissileDescription[] = _( static const u8 sLeerDescription[] = _( "Frightens the foe with a\n" - "leer to lower DEFENSE."); + "leer to lower Defense."); static const u8 sBiteDescription[] = _( "Bites with vicious fangs.\n" @@ -179,7 +179,7 @@ static const u8 sBiteDescription[] = _( static const u8 sGrowlDescription[] = _( "Growls cutely to reduce the\n" - "foe's ATTACK."); + "foe's Attack."); static const u8 sRoarDescription[] = _( "Makes the foe flee to end\n" @@ -203,7 +203,7 @@ static const u8 sDisableDescription[] = _( static const u8 sAcidDescription[] = _( "Sprays a hide-melting acid.\n" - "May lower DEFENSE."); + "May lower Defense."); static const u8 sEmberDescription[] = _( "A weak fire attack that may\n" @@ -243,11 +243,11 @@ static const u8 sPsybeamDescription[] = _( static const u8 sBubbleBeamDescription[] = _( "Forcefully sprays bubbles\n" - "that may lower SPEED."); + "that may lower Speed."); static const u8 sAuroraBeamDescription[] = _( "Fires a rainbow-colored\n" - "beam that may lower ATTACK."); + "beam that may lower Attack."); static const u8 sHyperBeamDescription[] = _( "Powerful, but leaves the\n" @@ -295,7 +295,7 @@ static const u8 sLeechSeedDescription[] = _( static const u8 sGrowthDescription[] = _( "Forces the body to grow\n" - "and heightens SP. ATK."); + "and heightens Sp. Atk."); static const u8 sRazorLeafDescription[] = _( "Cuts the enemy with leaves.\n" @@ -323,7 +323,7 @@ static const u8 sPetalDanceDescription[] = _( static const u8 sStringShotDescription[] = _( "Binds the foe with string\n" - "to reduce its SPEED."); + "to reduce its Speed."); static const u8 sDragonRageDescription[] = _( "Launches shock waves that\n" @@ -375,7 +375,7 @@ static const u8 sConfusionDescription[] = _( static const u8 sPsychicDescription[] = _( "A powerful psychic attack\n" - "that may lower SP. DEF."); + "that may lower Sp. Def."); static const u8 sHypnosisDescription[] = _( "A hypnotizing move that\n" @@ -383,18 +383,18 @@ static const u8 sHypnosisDescription[] = _( static const u8 sMeditateDescription[] = _( "Meditates in a peaceful\n" - "fashion to raise ATTACK."); + "fashion to raise Attack."); static const u8 sAgilityDescription[] = _( "Relaxes the body to sharply\n" - "boost SPEED."); + "boost Speed."); static const u8 sQuickAttackDescription[] = _( "An extremely fast attack\n" "that always strikes first."); static const u8 sRageDescription[] = _( - "Raises the user's ATTACK\n" + "Raises the user's Attack\n" "every time it is hit."); static const u8 sTeleportDescription[] = _( @@ -411,7 +411,7 @@ static const u8 sMimicDescription[] = _( static const u8 sScreechDescription[] = _( "Emits a screech to sharply\n" - "reduce the foe's DEFENSE."); + "reduce the foe's Defense."); static const u8 sDoubleTeamDescription[] = _( "Creates illusory copies to\n" @@ -423,7 +423,7 @@ static const u8 sRecoverDescription[] = _( static const u8 sHardenDescription[] = _( "Stiffens the body's \n" - "muscles to raise DEFENSE."); + "muscles to raise Defense."); static const u8 sMinimizeDescription[] = _( "Minimizes the user's size\n" @@ -439,19 +439,19 @@ static const u8 sConfuseRayDescription[] = _( static const u8 sWithdrawDescription[] = _( "Withdraws the body into its\n" - "hard shell to raise DEFENSE."); + "hard shell to raise Defense."); static const u8 sDefenseCurlDescription[] = _( "Curls up to conceal weak\n" - "spots and raise DEFENSE."); + "spots and raise Defense."); static const u8 sBarrierDescription[] = _( "Creates a barrier that\n" - "sharply raises DEFENSE."); + "sharply raises Defense."); static const u8 sLightScreenDescription[] = _( "Creates a wall of light that\n" - "lowers SP. ATK damage."); + "lowers Sp. Atk damage."); static const u8 sHazeDescription[] = _( "Creates a black haze that\n" @@ -471,7 +471,7 @@ static const u8 sBideDescription[] = _( static const u8 sMetronomeDescription[] = _( "Waggles a finger to use any\n" - "POKéMON move at random."); + "Pokémon move at random."); static const u8 sMirrorMoveDescription[] = _( "Counters the foe's attack\n" @@ -527,11 +527,11 @@ static const u8 sSpikeCannonDescription[] = _( static const u8 sConstrictDescription[] = _( "Constricts to inflict pain.\n" - "May lower SPEED."); + "May lower Speed."); static const u8 sAmnesiaDescription[] = _( "Forgets about something\n" - "and sharply raises SP. DEF."); + "and sharply raises Sp. Def."); static const u8 sKinesisDescription[] = _( "Distracts the foe.\n" @@ -579,7 +579,7 @@ static const u8 sTransformDescription[] = _( static const u8 sBubbleDescription[] = _( "An attack using bubbles.\n" - "May lower the foe's SPEED."); + "May lower the foe's Speed."); static const u8 sDizzyPunchDescription[] = _( "A rhythmic punch that may\n" @@ -603,7 +603,7 @@ static const u8 sSplashDescription[] = _( static const u8 sAcidArmorDescription[] = _( "Liquifies the user's body\n" - "to sharply raise DEFENSE."); + "to sharply raise Defense."); static const u8 sCrabhammerDescription[] = _( "Hammers with a pincer. Has a\n" @@ -635,7 +635,7 @@ static const u8 sHyperFangDescription[] = _( static const u8 sSharpenDescription[] = _( "Reduces the polygon count\n" - "and raises ATTACK."); + "and raises Attack."); static const u8 sConversionDescription[] = _( "Changes the user's type\n" @@ -711,7 +711,7 @@ static const u8 sAeroblastDescription[] = _( static const u8 sCottonSporeDescription[] = _( "Spores cling to the foe,\n" - "sharply reducing SPEED."); + "sharply reducing Speed."); static const u8 sReversalDescription[] = _( "Inflicts more damage when\n" @@ -735,7 +735,7 @@ static const u8 sMachPunchDescription[] = _( static const u8 sScaryFaceDescription[] = _( "Frightens with a scary face\n" - "to sharply reduce SPEED."); + "to sharply reduce Speed."); static const u8 sFeintAttackDescription[] = _( "Draws the foe close, then\n" @@ -746,7 +746,7 @@ static const u8 sSweetKissDescription[] = _( "look. May cause confusion."); static const u8 sBellyDrumDescription[] = _( - "Maximizes ATTACK while\n" + "Maximizes Attack while\n" "sacrificing HP."); static const u8 sSludgeBombDescription[] = _( @@ -778,12 +778,12 @@ static const u8 sDestinyBondDescription[] = _( "is also made to faint."); static const u8 sPerishSongDescription[] = _( - "Any POKéMON hearing this\n" + "Any Pokémon hearing this\n" "song faints in 3 turns."); static const u8 sIcyWindDescription[] = _( "A chilling attack that\n" - "lowers the foe's SPEED."); + "lowers the foe's Speed."); static const u8 sDetectDescription[] = _( "Evades attack, but may fail\n" @@ -815,7 +815,7 @@ static const u8 sEndureDescription[] = _( static const u8 sCharmDescription[] = _( "Charms the foe and sharply\n" - "reduces its ATTACK."); + "reduces its Attack."); static const u8 sRolloutDescription[] = _( "An attack lasting 5 turns\n" @@ -827,7 +827,7 @@ static const u8 sFalseSwipeDescription[] = _( static const u8 sSwaggerDescription[] = _( "Confuses the foe, but also\n" - "sharply raises ATTACK."); + "sharply raises Attack."); static const u8 sMilkDrinkDescription[] = _( "Recovers up to half the\n" @@ -871,7 +871,7 @@ static const u8 sPresentDescription[] = _( static const u8 sFrustrationDescription[] = _( "An attack that is stronger\n" - "if the TRAINER is disliked."); + "if the Trainer is disliked."); static const u8 sSafeguardDescription[] = _( "A mystical force prevents\n" @@ -923,11 +923,11 @@ static const u8 sSweetScentDescription[] = _( static const u8 sIronTailDescription[] = _( "Attacks with a rock-hard\n" - "tail. May lower DEFENSE."); + "tail. May lower Defense."); static const u8 sMetalClawDescription[] = _( "A claw attack that may\n" - "raise the user's ATTACK."); + "raise the user's Attack."); static const u8 sVitalThrowDescription[] = _( "Makes the user's move last,\n" @@ -958,16 +958,16 @@ static const u8 sTwisterDescription[] = _( "to tear at the foe."); static const u8 sRainDanceDescription[] = _( - "Boosts the power of WATER-\n" + "Boosts the power of Water-\n" "type moves for 5 turns."); static const u8 sSunnyDayDescription[] = _( - "Boosts the power of FIRE-\n" + "Boosts the power of Fire-\n" "type moves for 5 turns."); static const u8 sCrunchDescription[] = _( "Crunches with sharp fangs.\n" - "May lower DEFENSE."); + "May lower Defense."); static const u8 sMirrorCoatDescription[] = _( "Counters the foe's special\n" @@ -987,7 +987,7 @@ static const u8 sAncientPowerDescription[] = _( static const u8 sShadowBallDescription[] = _( "Hurls a black blob that may\n" - "lower the foe's SP. DEF."); + "lower the foe's Sp. Def."); static const u8 sFutureSightDescription[] = _( "Heightens inner power to\n" @@ -995,14 +995,14 @@ static const u8 sFutureSightDescription[] = _( static const u8 sRockSmashDescription[] = _( "A rock-crushing attack\n" - "that may lower DEFENSE."); + "that may lower Defense."); static const u8 sWhirlpoolDescription[] = _( "Traps and hurts the foe in\n" "a whirlpool for 2 to 5 turns."); static const u8 sBeatUpDescription[] = _( - "Summons party POKéMON to\n" + "Summons party Pokémon to\n" "join in the attack."); static const u8 sFakeOutDescription[] = _( @@ -1039,7 +1039,7 @@ static const u8 sTormentDescription[] = _( static const u8 sFlatterDescription[] = _( "Confuses the foe, but\n" - "raises its SP. ATK."); + "raises its Sp. Atk."); static const u8 sWillOWispDescription[] = _( "Inflicts a burn on the foe\n" @@ -1050,7 +1050,7 @@ static const u8 sMementoDescription[] = _( "the foe's abilities."); static const u8 sFacadeDescription[] = _( - "Boosts ATTACK when burned,\n" + "Boosts Attack when burned,\n" "paralyzed, or poisoned."); static const u8 sFocusPunchDescription[] = _( @@ -1170,27 +1170,27 @@ static const u8 sArmThrustDescription[] = _( "strike the foe 2 to 5 times."); static const u8 sCamouflageDescription[] = _( - "Alters the POKéMON's type\n" + "Alters the Pokémon's type\n" "depending on the location."); static const u8 sTailGlowDescription[] = _( "Flashes a light that sharply\n" - "raises SP. ATK."); + "raises Sp. Atk."); static const u8 sLusterPurgeDescription[] = _( "Attacks with a burst of\n" - "light. May lower SP. DEF."); + "light. May lower Sp. Def."); static const u8 sMistBallDescription[] = _( "Attacks with a flurry of\n" - "down. May lower SP. ATK."); + "down. May lower Sp. Atk."); static const u8 sFeatherDanceDescription[] = _( "Envelops the foe with down\n" - "to sharply reduce ATTACK."); + "to sharply reduce Attack."); static const u8 sTeeterDanceDescription[] = _( - "Confuses all POKéMON on\n" + "Confuses all Pokémon on\n" "the scene."); static const u8 sBlazeKickDescription[] = _( @@ -1223,7 +1223,7 @@ static const u8 sPoisonFangDescription[] = _( static const u8 sCrushClawDescription[] = _( "Tears at the foe with sharp\n" - "claws. May lower DEFENSE."); + "claws. May lower Defense."); static const u8 sBlastBurnDescription[] = _( "Powerful, but leaves the\n" @@ -1235,7 +1235,7 @@ static const u8 sHydroCannonDescription[] = _( static const u8 sMeteorMashDescription[] = _( "Fires a meteor-like punch.\n" - "May raise ATTACK."); + "May raise Attack."); static const u8 sAstonishDescription[] = _( "An attack that may shock\n" @@ -1251,7 +1251,7 @@ static const u8 sAromatherapyDescription[] = _( static const u8 sFakeTearsDescription[] = _( "Feigns crying to sharply\n" - "lower the foe's SP. DEF."); + "lower the foe's Sp. Def."); static const u8 sAirCutterDescription[] = _( "Hacks with razorlike wind.\n" @@ -1259,7 +1259,7 @@ static const u8 sAirCutterDescription[] = _( static const u8 sOverheatDescription[] = _( "Allows a full-power attack,\n" - "but sharply lowers SP. ATK."); + "but sharply lowers Sp. Atk."); static const u8 sOdorSleuthDescription[] = _( "Negates the foe's efforts\n" @@ -1267,7 +1267,7 @@ static const u8 sOdorSleuthDescription[] = _( static const u8 sRockTombDescription[] = _( "Stops the foe from moving\n" - "with rocks and cuts SPEED."); + "with rocks and cuts Speed."); static const u8 sSilverWindDescription[] = _( "A powdery attack that may\n" @@ -1275,7 +1275,7 @@ static const u8 sSilverWindDescription[] = _( static const u8 sMetalSoundDescription[] = _( "Emits a horrible screech\n" - "that sharply lowers SP. DEF."); + "that sharply lowers Sp. Def."); static const u8 sGrassWhistleDescription[] = _( "Lulls the foe into sleep\n" @@ -1283,10 +1283,10 @@ static const u8 sGrassWhistleDescription[] = _( static const u8 sTickleDescription[] = _( "Makes the foe laugh to\n" - "lower ATTACK and DEFENSE."); + "lower Attack and Defense."); static const u8 sCosmicPowerDescription[] = _( - "Raises DEFENSE and SP. DEF\n" + "Raises Defense and Sp. Def\n" "with a mystic power."); static const u8 sWaterSpoutDescription[] = _( @@ -1335,7 +1335,7 @@ static const u8 sIcicleSpearDescription[] = _( static const u8 sIronDefenseDescription[] = _( "Hardens the body's surface\n" - "to sharply raise DEFENSE."); + "to sharply raise Defense."); static const u8 sBlockDescription[] = _( "Blocks the foe's way to\n" @@ -1343,7 +1343,7 @@ static const u8 sBlockDescription[] = _( static const u8 sHowlDescription[] = _( "Howls to raise the spirit\n" - "and boosts ATTACK."); + "and boosts Attack."); static const u8 sDragonClawDescription[] = _( "Slashes the foe with sharp\n" @@ -1355,7 +1355,7 @@ static const u8 sFrenzyPlantDescription[] = _( static const u8 sBulkUpDescription[] = _( "Bulks up the body to boost\n" - "both ATTACK and DEFENSE."); + "both Attack and Defense."); static const u8 sBounceDescription[] = _( "Bounces up, then down the\n" @@ -1363,7 +1363,7 @@ static const u8 sBounceDescription[] = _( static const u8 sMudShotDescription[] = _( "Hurls mud at the foe and\n" - "reduces SPEED."); + "reduces Speed."); static const u8 sPoisonTailDescription[] = _( "Has a high critical-hit\n" @@ -1386,7 +1386,7 @@ static const u8 sWaterSportDescription[] = _( "raise resistance to fire."); static const u8 sCalmMindDescription[] = _( - "Raises SP. ATK and SP. DEF\n" + "Raises Sp. Atk and Sp. Def\n" "by focusing the mind."); static const u8 sLeafBladeDescription[] = _( @@ -1395,7 +1395,7 @@ static const u8 sLeafBladeDescription[] = _( static const u8 sDragonDanceDescription[] = _( "A mystical dance that ups\n" - "ATTACK and SPEED."); + "Attack and Speed."); static const u8 sRockBlastDescription[] = _( "Hurls boulders at the foe\n" @@ -1415,7 +1415,7 @@ static const u8 sDoomDesireDescription[] = _( static const u8 sPsychoBoostDescription[] = _( "Allows a full-power attack,\n" - "but sharply lowers SP. ATK."); + "but sharply lowers Sp. Atk."); static const u8 sROOSTDescription[] = _( "Restores the user's HP by\n" @@ -1426,8 +1426,8 @@ static const u8 sGRAVITYDescription[] = _( "negating levitation."); static const u8 sMIRACLE_EYEDescription[] = _( - "Makes GHOSTS and evasive\n" - "foes easier to hit."); + "Negate evasiveness and\n" + "Dark-type's immunities."); static const u8 sWAKE_UP_SLAPDescription[] = _( "Powerful against sleeping\n" @@ -1718,7 +1718,7 @@ static const u8 sDEFOGDescription[] = _( "lowers evasion."); static const u8 sTRICK_ROOMDescription[] = _( - "Slower POKéMON get to move\n" + "Slower Pokémon get to move\n" "first for 5 turns."); static const u8 sDRACO_METEORDescription[] = _( @@ -2183,7 +2183,7 @@ static const u8 sBELCHDescription[] = _( static const u8 sROTOTILLERDescription[] = _( "Ups the Attack and Sp. Atk\n" - "of Grass-type POKéMON."); + "of Grass-type Pokémon."); static const u8 sSTICKY_WEBDescription[] = _( "Weaves a sticky net that\n" @@ -2243,7 +2243,7 @@ static const u8 sCRAFTY_SHIELDDescription[] = _( static const u8 sFLOWER_SHIELDDescription[] = _( "Raises the Defense of\n" - "Grass-type POKéMON."); + "Grass-type Pokémon."); static const u8 sGRASSY_TERRAINDescription[] = _( "The ground turns to grass\n" @@ -2315,7 +2315,7 @@ static const u8 sSPIKY_SHIELDDescription[] = _( static const u8 sAROMATIC_MISTDescription[] = _( "Raises the Sp. Def of a\n" - "partner POKéMON."); + "partner Pokémon."); static const u8 sEERIE_IMPULSEDescription[] = _( "Exposes the foe to a pulse\n" @@ -2431,7 +2431,7 @@ static const u8 sSPARKLING_ARIADescription[] = _( static const u8 sICE_HAMMERDescription[] = _( "Swings the fist to strike.\n" - "Lowers the user's SPEED."); + "Lowers the user's Speed."); static const u8 sFLORAL_HEALINGDescription[] = _( "Restores an ally's HP.\n" @@ -2455,7 +2455,7 @@ static const u8 sLEAFAGEDescription[] = _( static const u8 sSPOTLIGHTDescription[] = _( "Makes the foe attack the\n" - "spotlighted POKéMON."); + "spotlighted Pokémon."); static const u8 sTOXIC_THREADDescription[] = _( "Attacks with a thread that\n" diff --git a/src/data/trainers.h b/src/data/trainers.h index 163a8296d..619763ea1 100644 --- a/src/data/trainers.h +++ b/src/data/trainers.h @@ -22,7 +22,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("SAWYER"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_Sawyer1), .party = {.NoItemDefaultMoves = sParty_Sawyer1}, }, @@ -36,7 +36,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("GRUNT"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_GruntAquaHideout1), .party = {.NoItemDefaultMoves = sParty_GruntAquaHideout1}, }, @@ -50,7 +50,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("GRUNT"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_GruntAquaHideout2), .party = {.NoItemDefaultMoves = sParty_GruntAquaHideout2}, }, @@ -64,7 +64,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("GRUNT"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_GruntAquaHideout3), .party = {.NoItemDefaultMoves = sParty_GruntAquaHideout3}, }, @@ -78,7 +78,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("GRUNT"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_GruntAquaHideout4), .party = {.NoItemDefaultMoves = sParty_GruntAquaHideout4}, }, @@ -92,7 +92,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("GRUNT"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_GruntSeafloorCavern1), .party = {.NoItemDefaultMoves = sParty_GruntSeafloorCavern1}, }, @@ -106,7 +106,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("GRUNT"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_GruntSeafloorCavern2), .party = {.NoItemDefaultMoves = sParty_GruntSeafloorCavern2}, }, @@ -120,7 +120,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("GRUNT"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_GruntSeafloorCavern3), .party = {.NoItemDefaultMoves = sParty_GruntSeafloorCavern3}, }, @@ -134,7 +134,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("GABRIELLE"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Gabrielle1), .party = {.NoItemDefaultMoves = sParty_Gabrielle1}, }, @@ -148,7 +148,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("GRUNT"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_GruntPetalburgWoods), .party = {.NoItemDefaultMoves = sParty_GruntPetalburgWoods}, }, @@ -162,7 +162,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("MARCEL"), .items = {ITEM_HYPER_POTION, ITEM_NONE, ITEM_NONE, ITEM_NONE}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_Marcel), .party = {.NoItemDefaultMoves = sParty_Marcel}, }, @@ -176,7 +176,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("ALBERTO"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Alberto), .party = {.NoItemDefaultMoves = sParty_Alberto}, }, @@ -190,7 +190,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("ED"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Ed), .party = {.NoItemDefaultMoves = sParty_Ed}, }, @@ -204,7 +204,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("GRUNT"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_GruntSeafloorCavern4), .party = {.NoItemDefaultMoves = sParty_GruntSeafloorCavern4}, }, @@ -218,7 +218,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("DECLAN"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Declan), .party = {.NoItemDefaultMoves = sParty_Declan}, }, @@ -232,7 +232,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("GRUNT"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_GruntRusturfTunnel), .party = {.NoItemDefaultMoves = sParty_GruntRusturfTunnel}, }, @@ -246,7 +246,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("GRUNT"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_GruntWeatherInst1), .party = {.NoItemDefaultMoves = sParty_GruntWeatherInst1}, }, @@ -260,7 +260,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("GRUNT"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_GruntWeatherInst2), .party = {.NoItemDefaultMoves = sParty_GruntWeatherInst2}, }, @@ -274,7 +274,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("GRUNT"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_GruntWeatherInst3), .party = {.NoItemDefaultMoves = sParty_GruntWeatherInst3}, }, @@ -288,7 +288,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("GRUNT"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_GruntMuseum1), .party = {.NoItemDefaultMoves = sParty_GruntMuseum1}, }, @@ -302,7 +302,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("GRUNT"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_GruntMuseum2), .party = {.NoItemDefaultMoves = sParty_GruntMuseum2}, }, @@ -316,7 +316,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("GRUNT"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_GruntSpaceCenter1), .party = {.NoItemDefaultMoves = sParty_GruntSpaceCenter1}, }, @@ -330,7 +330,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("GRUNT"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_GruntMtPyre1), .party = {.NoItemDefaultMoves = sParty_GruntMtPyre1}, }, @@ -344,7 +344,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("GRUNT"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_GruntMtPyre2), .party = {.NoItemDefaultMoves = sParty_GruntMtPyre2}, }, @@ -358,7 +358,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("GRUNT"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_GruntMtPyre3), .party = {.NoItemDefaultMoves = sParty_GruntMtPyre3}, }, @@ -372,7 +372,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("GRUNT"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_GruntWeatherInst4), .party = {.NoItemDefaultMoves = sParty_GruntWeatherInst4}, }, @@ -386,7 +386,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("GRUNT"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_GruntAquaHideout5), .party = {.NoItemDefaultMoves = sParty_GruntAquaHideout5}, }, @@ -400,7 +400,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("GRUNT"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_GruntAquaHideout6), .party = {.NoItemDefaultMoves = sParty_GruntAquaHideout6}, }, @@ -414,7 +414,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("FREDRICK"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_Fredrick), .party = {.NoItemDefaultMoves = sParty_Fredrick}, }, @@ -428,7 +428,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("MATT"), .items = {ITEM_SUPER_POTION, ITEM_NONE, ITEM_NONE, ITEM_NONE}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_Matt), .party = {.NoItemDefaultMoves = sParty_Matt}, }, @@ -442,7 +442,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("ZANDER"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Zander), .party = {.NoItemDefaultMoves = sParty_Zander}, }, @@ -456,7 +456,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("SHELLY"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_ShellyWeatherInstitute), .party = {.NoItemDefaultMoves = sParty_ShellyWeatherInstitute}, }, @@ -470,7 +470,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("SHELLY"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_ShellySeafloorCavern), .party = {.NoItemDefaultMoves = sParty_ShellySeafloorCavern}, }, @@ -484,7 +484,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("ARCHIE"), .items = {ITEM_SUPER_POTION, ITEM_SUPER_POTION, ITEM_NONE, ITEM_NONE}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_Archie), .party = {.NoItemDefaultMoves = sParty_Archie}, }, @@ -498,7 +498,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("LEAH"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Leah), .party = {.NoItemDefaultMoves = sParty_Leah}, }, @@ -512,7 +512,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("DAISY"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Daisy), .party = {.NoItemDefaultMoves = sParty_Daisy}, }, @@ -526,7 +526,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("ROSE"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Rose1), .party = {.NoItemDefaultMoves = sParty_Rose1}, }, @@ -540,7 +540,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("FELIX"), .items = {ITEM_FULL_RESTORE, ITEM_NONE, ITEM_NONE, ITEM_NONE}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_Felix), .party = {.NoItemCustomMoves = sParty_Felix}, }, @@ -554,7 +554,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("VIOLET"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Violet), .party = {.NoItemDefaultMoves = sParty_Violet}, }, @@ -568,7 +568,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("ROSE"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Rose2), .party = {.NoItemDefaultMoves = sParty_Rose2}, }, @@ -582,7 +582,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("ROSE"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Rose3), .party = {.NoItemDefaultMoves = sParty_Rose3}, }, @@ -596,7 +596,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("ROSE"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Rose4), .party = {.NoItemDefaultMoves = sParty_Rose4}, }, @@ -610,7 +610,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("ROSE"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Rose5), .party = {.NoItemDefaultMoves = sParty_Rose5}, }, @@ -624,7 +624,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("DUSTY"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Dusty1), .party = {.NoItemCustomMoves = sParty_Dusty1}, }, @@ -638,7 +638,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("CHIP"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Chip), .party = {.NoItemCustomMoves = sParty_Chip}, }, @@ -652,7 +652,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("FOSTER"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Foster), .party = {.NoItemCustomMoves = sParty_Foster}, }, @@ -666,7 +666,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("DUSTY"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Dusty2), .party = {.NoItemCustomMoves = sParty_Dusty2}, }, @@ -680,7 +680,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("DUSTY"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Dusty3), .party = {.NoItemCustomMoves = sParty_Dusty3}, }, @@ -694,7 +694,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("DUSTY"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Dusty4), .party = {.NoItemCustomMoves = sParty_Dusty4}, }, @@ -708,7 +708,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("DUSTY"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Dusty5), .party = {.NoItemCustomMoves = sParty_Dusty5}, }, @@ -722,7 +722,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("GABBY & TY"), .items = {}, .doubleBattle = TRUE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_GabbyAndTy1), .party = {.NoItemDefaultMoves = sParty_GabbyAndTy1}, }, @@ -736,7 +736,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("GABBY & TY"), .items = {}, .doubleBattle = TRUE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_GabbyAndTy2), .party = {.NoItemDefaultMoves = sParty_GabbyAndTy2}, }, @@ -750,7 +750,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("GABBY & TY"), .items = {}, .doubleBattle = TRUE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_GabbyAndTy3), .party = {.NoItemDefaultMoves = sParty_GabbyAndTy3}, }, @@ -764,7 +764,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("GABBY & TY"), .items = {}, .doubleBattle = TRUE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_GabbyAndTy4), .party = {.NoItemDefaultMoves = sParty_GabbyAndTy4}, }, @@ -778,7 +778,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("GABBY & TY"), .items = {}, .doubleBattle = TRUE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_GabbyAndTy5), .party = {.NoItemDefaultMoves = sParty_GabbyAndTy5}, }, @@ -792,7 +792,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("GABBY & TY"), .items = {}, .doubleBattle = TRUE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_GabbyAndTy6), .party = {.NoItemCustomMoves = sParty_GabbyAndTy6}, }, @@ -806,7 +806,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("LOLA"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Lola1), .party = {.NoItemDefaultMoves = sParty_Lola1}, }, @@ -820,7 +820,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("AUSTINA"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Austina), .party = {.NoItemDefaultMoves = sParty_Austina}, }, @@ -834,7 +834,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("GWEN"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Gwen), .party = {.NoItemDefaultMoves = sParty_Gwen}, }, @@ -848,7 +848,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("LOLA"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Lola2), .party = {.NoItemDefaultMoves = sParty_Lola2}, }, @@ -862,7 +862,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("LOLA"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Lola3), .party = {.NoItemDefaultMoves = sParty_Lola3}, }, @@ -876,7 +876,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("LOLA"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Lola4), .party = {.NoItemDefaultMoves = sParty_Lola4}, }, @@ -890,7 +890,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("LOLA"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Lola5), .party = {.NoItemDefaultMoves = sParty_Lola5}, }, @@ -904,7 +904,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("RICKY"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Ricky1), .party = {.NoItemCustomMoves = sParty_Ricky1}, }, @@ -918,7 +918,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("SIMON"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Simon), .party = {.NoItemDefaultMoves = sParty_Simon}, }, @@ -932,7 +932,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("CHARLIE"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Charlie), .party = {.NoItemDefaultMoves = sParty_Charlie}, }, @@ -946,7 +946,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("RICKY"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Ricky2), .party = {.NoItemCustomMoves = sParty_Ricky2}, }, @@ -960,7 +960,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("RICKY"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Ricky3), .party = {.NoItemCustomMoves = sParty_Ricky3}, }, @@ -974,7 +974,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("RICKY"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Ricky4), .party = {.NoItemCustomMoves = sParty_Ricky4}, }, @@ -988,7 +988,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("RICKY"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Ricky5), .party = {.NoItemCustomMoves = sParty_Ricky5}, }, @@ -1002,7 +1002,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("RANDALL"), .items = {ITEM_HYPER_POTION, ITEM_NONE, ITEM_NONE, ITEM_NONE}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_Randall), .party = {.ItemCustomMoves = sParty_Randall}, }, @@ -1016,7 +1016,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("PARKER"), .items = {ITEM_HYPER_POTION, ITEM_NONE, ITEM_NONE, ITEM_NONE}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_Parker), .party = {.ItemCustomMoves = sParty_Parker}, }, @@ -1030,7 +1030,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("GEORGE"), .items = {ITEM_HYPER_POTION, ITEM_NONE, ITEM_NONE, ITEM_NONE}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_George), .party = {.ItemCustomMoves = sParty_George}, }, @@ -1044,7 +1044,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("BERKE"), .items = {ITEM_HYPER_POTION, ITEM_NONE, ITEM_NONE, ITEM_NONE}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_Berke), .party = {.ItemCustomMoves = sParty_Berke}, }, @@ -1058,7 +1058,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("BRAXTON"), .items = {ITEM_HYPER_POTION, ITEM_NONE, ITEM_NONE, ITEM_NONE}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_Braxton), .party = {.NoItemCustomMoves = sParty_Braxton}, }, @@ -1072,7 +1072,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("VINCENT"), .items = {ITEM_FULL_RESTORE, ITEM_NONE, ITEM_NONE, ITEM_NONE}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_Vincent), .party = {.NoItemDefaultMoves = sParty_Vincent}, }, @@ -1086,7 +1086,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("LEROY"), .items = {ITEM_FULL_RESTORE, ITEM_NONE, ITEM_NONE, ITEM_NONE}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_Leroy), .party = {.NoItemDefaultMoves = sParty_Leroy}, }, @@ -1100,7 +1100,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("WILTON"), .items = {ITEM_SUPER_POTION, ITEM_NONE, ITEM_NONE, ITEM_NONE}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_Wilton1), .party = {.NoItemDefaultMoves = sParty_Wilton1}, }, @@ -1114,7 +1114,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("EDGAR"), .items = {ITEM_FULL_RESTORE, ITEM_NONE, ITEM_NONE, ITEM_NONE}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_Edgar), .party = {.NoItemDefaultMoves = sParty_Edgar}, }, @@ -1128,7 +1128,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("ALBERT"), .items = {ITEM_FULL_RESTORE, ITEM_NONE, ITEM_NONE, ITEM_NONE}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_Albert), .party = {.NoItemDefaultMoves = sParty_Albert}, }, @@ -1142,7 +1142,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("SAMUEL"), .items = {ITEM_FULL_RESTORE, ITEM_NONE, ITEM_NONE, ITEM_NONE}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_Samuel), .party = {.NoItemDefaultMoves = sParty_Samuel}, }, @@ -1156,7 +1156,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("VITO"), .items = {ITEM_FULL_RESTORE, ITEM_NONE, ITEM_NONE, ITEM_NONE}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_Vito), .party = {.NoItemDefaultMoves = sParty_Vito}, }, @@ -1170,7 +1170,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("OWEN"), .items = {ITEM_FULL_RESTORE, ITEM_NONE, ITEM_NONE, ITEM_NONE}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_Owen), .party = {.NoItemDefaultMoves = sParty_Owen}, }, @@ -1184,7 +1184,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("WILTON"), .items = {ITEM_HYPER_POTION, ITEM_NONE, ITEM_NONE, ITEM_NONE}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_Wilton2), .party = {.NoItemDefaultMoves = sParty_Wilton2}, }, @@ -1198,7 +1198,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("WILTON"), .items = {ITEM_HYPER_POTION, ITEM_NONE, ITEM_NONE, ITEM_NONE}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_Wilton3), .party = {.NoItemDefaultMoves = sParty_Wilton3}, }, @@ -1212,7 +1212,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("WILTON"), .items = {ITEM_FULL_RESTORE, ITEM_NONE, ITEM_NONE, ITEM_NONE}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_Wilton4), .party = {.NoItemDefaultMoves = sParty_Wilton4}, }, @@ -1226,7 +1226,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("WILTON"), .items = {ITEM_FULL_RESTORE, ITEM_NONE, ITEM_NONE, ITEM_NONE}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_Wilton5), .party = {.NoItemDefaultMoves = sParty_Wilton5}, }, @@ -1240,7 +1240,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("WARREN"), .items = {ITEM_FULL_RESTORE, ITEM_NONE, ITEM_NONE, ITEM_NONE}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_Warren), .party = {.NoItemDefaultMoves = sParty_Warren}, }, @@ -1254,7 +1254,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("MARY"), .items = {ITEM_HYPER_POTION, ITEM_NONE, ITEM_NONE, ITEM_NONE}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_Mary), .party = {.ItemCustomMoves = sParty_Mary}, }, @@ -1268,7 +1268,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("ALEXIA"), .items = {ITEM_HYPER_POTION, ITEM_NONE, ITEM_NONE, ITEM_NONE}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_Alexia), .party = {.ItemCustomMoves = sParty_Alexia}, }, @@ -1282,7 +1282,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("JODY"), .items = {ITEM_HYPER_POTION, ITEM_NONE, ITEM_NONE, ITEM_NONE}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_SETUP_FIRST_TURN, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_SETUP_FIRST_TURN, .partySize = ARRAY_COUNT(sParty_Jody), .party = {.ItemCustomMoves = sParty_Jody}, }, @@ -1296,7 +1296,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("WENDY"), .items = {ITEM_FULL_RESTORE, ITEM_NONE, ITEM_NONE, ITEM_NONE}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_SETUP_FIRST_TURN, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_SETUP_FIRST_TURN, .partySize = ARRAY_COUNT(sParty_Wendy), .party = {.NoItemCustomMoves = sParty_Wendy}, }, @@ -1310,7 +1310,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("KEIRA"), .items = {ITEM_FULL_RESTORE, ITEM_NONE, ITEM_NONE, ITEM_NONE}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_SETUP_FIRST_TURN, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_SETUP_FIRST_TURN, .partySize = ARRAY_COUNT(sParty_Keira), .party = {.NoItemDefaultMoves = sParty_Keira}, }, @@ -1324,7 +1324,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("BROOKE"), .items = {ITEM_SUPER_POTION, ITEM_NONE, ITEM_NONE, ITEM_NONE}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_Brooke1), .party = {.NoItemDefaultMoves = sParty_Brooke1}, }, @@ -1338,7 +1338,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("JENNIFER"), .items = {ITEM_FULL_RESTORE, ITEM_NONE, ITEM_NONE, ITEM_NONE}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_Jennifer), .party = {.NoItemDefaultMoves = sParty_Jennifer}, }, @@ -1352,7 +1352,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("HOPE"), .items = {ITEM_FULL_RESTORE, ITEM_NONE, ITEM_NONE, ITEM_NONE}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_Hope), .party = {.NoItemDefaultMoves = sParty_Hope}, }, @@ -1366,7 +1366,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("SHANNON"), .items = {ITEM_FULL_RESTORE, ITEM_NONE, ITEM_NONE, ITEM_NONE}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_Shannon), .party = {.NoItemDefaultMoves = sParty_Shannon}, }, @@ -1380,7 +1380,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("MICHELLE"), .items = {ITEM_FULL_RESTORE, ITEM_NONE, ITEM_NONE, ITEM_NONE}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_Michelle), .party = {.NoItemDefaultMoves = sParty_Michelle}, }, @@ -1394,7 +1394,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("CAROLINE"), .items = {ITEM_FULL_RESTORE, ITEM_NONE, ITEM_NONE, ITEM_NONE}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_Caroline), .party = {.NoItemDefaultMoves = sParty_Caroline}, }, @@ -1408,7 +1408,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("JULIE"), .items = {ITEM_FULL_RESTORE, ITEM_NONE, ITEM_NONE, ITEM_NONE}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_Julie), .party = {.NoItemDefaultMoves = sParty_Julie}, }, @@ -1422,7 +1422,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("BROOKE"), .items = {ITEM_HYPER_POTION, ITEM_NONE, ITEM_NONE, ITEM_NONE}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_Brooke2), .party = {.NoItemDefaultMoves = sParty_Brooke2}, }, @@ -1436,7 +1436,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("BROOKE"), .items = {ITEM_HYPER_POTION, ITEM_NONE, ITEM_NONE, ITEM_NONE}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_Brooke3), .party = {.NoItemDefaultMoves = sParty_Brooke3}, }, @@ -1450,7 +1450,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("BROOKE"), .items = {ITEM_FULL_RESTORE, ITEM_NONE, ITEM_NONE, ITEM_NONE}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_Brooke4), .party = {.NoItemDefaultMoves = sParty_Brooke4}, }, @@ -1464,7 +1464,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("BROOKE"), .items = {ITEM_FULL_RESTORE, ITEM_NONE, ITEM_NONE, ITEM_NONE}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_Brooke5), .party = {.NoItemDefaultMoves = sParty_Brooke5}, }, @@ -1478,7 +1478,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("PATRICIA"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Patricia), .party = {.NoItemDefaultMoves = sParty_Patricia}, }, @@ -1492,7 +1492,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("KINDRA"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Kindra), .party = {.NoItemDefaultMoves = sParty_Kindra}, }, @@ -1506,7 +1506,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("TAMMY"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Tammy), .party = {.NoItemDefaultMoves = sParty_Tammy}, }, @@ -1520,7 +1520,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("VALERIE"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Valerie1), .party = {.NoItemDefaultMoves = sParty_Valerie1}, }, @@ -1534,7 +1534,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("TASHA"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Tasha), .party = {.NoItemDefaultMoves = sParty_Tasha}, }, @@ -1548,7 +1548,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("VALERIE"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Valerie2), .party = {.NoItemDefaultMoves = sParty_Valerie2}, }, @@ -1562,7 +1562,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("VALERIE"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Valerie3), .party = {.NoItemDefaultMoves = sParty_Valerie3}, }, @@ -1576,7 +1576,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("VALERIE"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Valerie4), .party = {.NoItemDefaultMoves = sParty_Valerie4}, }, @@ -1590,7 +1590,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("VALERIE"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Valerie5), .party = {.NoItemDefaultMoves = sParty_Valerie5}, }, @@ -1604,7 +1604,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("CINDY"), .items = {ITEM_FULL_RESTORE, ITEM_NONE, ITEM_NONE, ITEM_NONE}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Cindy1), .party = {.ItemDefaultMoves = sParty_Cindy1}, }, @@ -1618,7 +1618,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("DAPHNE"), .items = {ITEM_FULL_RESTORE, ITEM_NONE, ITEM_NONE, ITEM_NONE}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Daphne), .party = {.ItemCustomMoves = sParty_Daphne}, }, @@ -1632,7 +1632,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("GRUNT"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_GruntSpaceCenter2), .party = {.NoItemDefaultMoves = sParty_GruntSpaceCenter2}, }, @@ -1646,7 +1646,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("CINDY"), .items = {ITEM_FULL_RESTORE, ITEM_NONE, ITEM_NONE, ITEM_NONE}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Cindy2), .party = {.ItemCustomMoves = sParty_Cindy2}, }, @@ -1660,7 +1660,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("BRIANNA"), .items = {ITEM_FULL_RESTORE, ITEM_NONE, ITEM_NONE, ITEM_NONE}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Brianna), .party = {.ItemDefaultMoves = sParty_Brianna}, }, @@ -1674,7 +1674,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("NAOMI"), .items = {ITEM_FULL_RESTORE, ITEM_NONE, ITEM_NONE, ITEM_NONE}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Naomi), .party = {.ItemDefaultMoves = sParty_Naomi}, }, @@ -1688,7 +1688,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("CINDY"), .items = {ITEM_FULL_RESTORE, ITEM_NONE, ITEM_NONE, ITEM_NONE}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Cindy3), .party = {.ItemDefaultMoves = sParty_Cindy3}, }, @@ -1702,7 +1702,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("CINDY"), .items = {ITEM_FULL_RESTORE, ITEM_NONE, ITEM_NONE, ITEM_NONE}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Cindy4), .party = {.ItemDefaultMoves = sParty_Cindy4}, }, @@ -1716,7 +1716,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("CINDY"), .items = {ITEM_FULL_RESTORE, ITEM_NONE, ITEM_NONE, ITEM_NONE}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Cindy5), .party = {.ItemDefaultMoves = sParty_Cindy5}, }, @@ -1730,7 +1730,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("CINDY"), .items = {ITEM_FULL_RESTORE, ITEM_NONE, ITEM_NONE, ITEM_NONE}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Cindy6), .party = {.ItemCustomMoves = sParty_Cindy6}, }, @@ -1744,7 +1744,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("MELISSA"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Melissa), .party = {.NoItemDefaultMoves = sParty_Melissa}, }, @@ -1758,7 +1758,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("SHEILA"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Sheila), .party = {.NoItemDefaultMoves = sParty_Sheila}, }, @@ -1772,7 +1772,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("SHIRLEY"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Shirley), .party = {.NoItemDefaultMoves = sParty_Shirley}, }, @@ -1786,7 +1786,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("JESSICA"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Jessica1), .party = {.NoItemCustomMoves = sParty_Jessica1}, }, @@ -1800,7 +1800,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("CONNIE"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Connie), .party = {.NoItemDefaultMoves = sParty_Connie}, }, @@ -1814,7 +1814,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("BRIDGET"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Bridget), .party = {.NoItemDefaultMoves = sParty_Bridget}, }, @@ -1828,7 +1828,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("OLIVIA"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Olivia), .party = {.NoItemCustomMoves = sParty_Olivia}, }, @@ -1842,7 +1842,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("TIFFANY"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Tiffany), .party = {.NoItemDefaultMoves = sParty_Tiffany}, }, @@ -1856,7 +1856,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("JESSICA"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Jessica2), .party = {.NoItemCustomMoves = sParty_Jessica2}, }, @@ -1870,7 +1870,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("JESSICA"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Jessica3), .party = {.NoItemCustomMoves = sParty_Jessica3}, }, @@ -1884,7 +1884,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("JESSICA"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Jessica4), .party = {.NoItemCustomMoves = sParty_Jessica4}, }, @@ -1898,7 +1898,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("JESSICA"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Jessica5), .party = {.NoItemCustomMoves = sParty_Jessica5}, }, @@ -1912,7 +1912,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("WINSTON"), .items = {ITEM_FULL_RESTORE, ITEM_NONE, ITEM_NONE, ITEM_NONE}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Winston1), .party = {.ItemDefaultMoves = sParty_Winston1}, }, @@ -1926,7 +1926,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("MOLLIE"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Mollie), .party = {.NoItemDefaultMoves = sParty_Mollie}, }, @@ -1940,7 +1940,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("GARRET"), .items = {ITEM_FULL_RESTORE, ITEM_NONE, ITEM_NONE, ITEM_NONE}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Garret), .party = {.ItemDefaultMoves = sParty_Garret}, }, @@ -1954,7 +1954,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("WINSTON"), .items = {ITEM_FULL_RESTORE, ITEM_NONE, ITEM_NONE, ITEM_NONE}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Winston2), .party = {.ItemDefaultMoves = sParty_Winston2}, }, @@ -1968,7 +1968,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("WINSTON"), .items = {ITEM_FULL_RESTORE, ITEM_NONE, ITEM_NONE, ITEM_NONE}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Winston3), .party = {.ItemDefaultMoves = sParty_Winston3}, }, @@ -1982,7 +1982,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("WINSTON"), .items = {ITEM_FULL_RESTORE, ITEM_NONE, ITEM_NONE, ITEM_NONE}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Winston4), .party = {.ItemDefaultMoves = sParty_Winston4}, }, @@ -1996,7 +1996,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("WINSTON"), .items = {ITEM_FULL_RESTORE, ITEM_NONE, ITEM_NONE, ITEM_NONE}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Winston5), .party = {.ItemCustomMoves = sParty_Winston5}, }, @@ -2010,7 +2010,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("STEVE"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Steve1), .party = {.NoItemDefaultMoves = sParty_Steve1}, }, @@ -2024,7 +2024,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("THALIA"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Thalia1), .party = {.NoItemDefaultMoves = sParty_Thalia1}, }, @@ -2038,7 +2038,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("MARK"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Mark), .party = {.NoItemDefaultMoves = sParty_Mark}, }, @@ -2052,7 +2052,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("GRUNT"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_GruntMtChimney1), .party = {.NoItemDefaultMoves = sParty_GruntMtChimney1}, }, @@ -2066,7 +2066,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("STEVE"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Steve2), .party = {.NoItemDefaultMoves = sParty_Steve2}, }, @@ -2080,7 +2080,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("STEVE"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Steve3), .party = {.NoItemDefaultMoves = sParty_Steve3}, }, @@ -2094,7 +2094,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("STEVE"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Steve4), .party = {.NoItemDefaultMoves = sParty_Steve4}, }, @@ -2108,7 +2108,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("STEVE"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Steve5), .party = {.NoItemDefaultMoves = sParty_Steve5}, }, @@ -2122,7 +2122,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("LUIS"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Luis), .party = {.NoItemDefaultMoves = sParty_Luis}, }, @@ -2136,7 +2136,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("DOMINIK"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Dominik), .party = {.NoItemDefaultMoves = sParty_Dominik}, }, @@ -2150,7 +2150,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("DOUGLAS"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Douglas), .party = {.NoItemDefaultMoves = sParty_Douglas}, }, @@ -2164,7 +2164,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("DARRIN"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Darrin), .party = {.NoItemDefaultMoves = sParty_Darrin}, }, @@ -2178,7 +2178,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("TONY"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Tony1), .party = {.NoItemDefaultMoves = sParty_Tony1}, }, @@ -2192,7 +2192,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("JEROME"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Jerome), .party = {.NoItemDefaultMoves = sParty_Jerome}, }, @@ -2206,7 +2206,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("MATTHEW"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Matthew), .party = {.NoItemDefaultMoves = sParty_Matthew}, }, @@ -2220,7 +2220,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("DAVID"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_David), .party = {.NoItemDefaultMoves = sParty_David}, }, @@ -2234,7 +2234,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("SPENCER"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Spencer), .party = {.NoItemDefaultMoves = sParty_Spencer}, }, @@ -2248,7 +2248,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("ROLAND"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Roland), .party = {.NoItemDefaultMoves = sParty_Roland}, }, @@ -2262,7 +2262,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("NOLEN"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Nolen), .party = {.NoItemDefaultMoves = sParty_Nolen}, }, @@ -2276,7 +2276,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("STAN"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Stan), .party = {.NoItemDefaultMoves = sParty_Stan}, }, @@ -2290,7 +2290,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("BARRY"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Barry), .party = {.NoItemDefaultMoves = sParty_Barry}, }, @@ -2304,7 +2304,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("DEAN"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Dean), .party = {.NoItemDefaultMoves = sParty_Dean}, }, @@ -2318,7 +2318,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("RODNEY"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Rodney), .party = {.NoItemDefaultMoves = sParty_Rodney}, }, @@ -2332,7 +2332,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("RICHARD"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Richard), .party = {.NoItemDefaultMoves = sParty_Richard}, }, @@ -2346,7 +2346,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("HERMAN"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Herman), .party = {.NoItemDefaultMoves = sParty_Herman}, }, @@ -2360,7 +2360,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("SANTIAGO"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Santiago), .party = {.NoItemDefaultMoves = sParty_Santiago}, }, @@ -2374,7 +2374,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("GILBERT"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Gilbert), .party = {.NoItemDefaultMoves = sParty_Gilbert}, }, @@ -2388,7 +2388,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("FRANKLIN"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Franklin), .party = {.NoItemDefaultMoves = sParty_Franklin}, }, @@ -2402,7 +2402,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("KEVIN"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Kevin), .party = {.NoItemDefaultMoves = sParty_Kevin}, }, @@ -2416,7 +2416,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("JACK"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Jack), .party = {.NoItemDefaultMoves = sParty_Jack}, }, @@ -2430,7 +2430,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("DUDLEY"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Dudley), .party = {.NoItemDefaultMoves = sParty_Dudley}, }, @@ -2444,7 +2444,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("CHAD"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Chad), .party = {.NoItemDefaultMoves = sParty_Chad}, }, @@ -2458,7 +2458,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("TONY"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Tony2), .party = {.NoItemDefaultMoves = sParty_Tony2}, }, @@ -2472,7 +2472,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("TONY"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Tony3), .party = {.NoItemDefaultMoves = sParty_Tony3}, }, @@ -2486,7 +2486,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("TONY"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Tony4), .party = {.NoItemDefaultMoves = sParty_Tony4}, }, @@ -2500,7 +2500,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("TONY"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Tony5), .party = {.NoItemDefaultMoves = sParty_Tony5}, }, @@ -2514,7 +2514,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("TAKAO"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Takao), .party = {.NoItemDefaultMoves = sParty_Takao}, }, @@ -2528,7 +2528,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("HITOSHI"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Hitoshi), .party = {.NoItemDefaultMoves = sParty_Hitoshi}, }, @@ -2542,7 +2542,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("KIYO"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Kiyo), .party = {.NoItemDefaultMoves = sParty_Kiyo}, }, @@ -2556,7 +2556,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("KOICHI"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Koichi), .party = {.NoItemDefaultMoves = sParty_Koichi}, }, @@ -2570,7 +2570,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("NOB"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Nob1), .party = {.NoItemDefaultMoves = sParty_Nob1}, }, @@ -2584,7 +2584,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("NOB"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Nob2), .party = {.NoItemDefaultMoves = sParty_Nob2}, }, @@ -2598,7 +2598,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("NOB"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Nob3), .party = {.NoItemDefaultMoves = sParty_Nob3}, }, @@ -2612,7 +2612,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("NOB"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Nob4), .party = {.NoItemDefaultMoves = sParty_Nob4}, }, @@ -2626,7 +2626,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("NOB"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Nob5), .party = {.ItemDefaultMoves = sParty_Nob5}, }, @@ -2640,7 +2640,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("YUJI"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Yuji), .party = {.NoItemDefaultMoves = sParty_Yuji}, }, @@ -2654,7 +2654,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("DAISUKE"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Daisuke), .party = {.NoItemDefaultMoves = sParty_Daisuke}, }, @@ -2668,7 +2668,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("ATSUSHI"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Atsushi), .party = {.NoItemDefaultMoves = sParty_Atsushi}, }, @@ -2682,7 +2682,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("KIRK"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Kirk), .party = {.NoItemCustomMoves = sParty_Kirk}, }, @@ -2696,7 +2696,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("GRUNT"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_GruntAquaHideout7), .party = {.NoItemDefaultMoves = sParty_GruntAquaHideout7}, }, @@ -2710,7 +2710,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("GRUNT"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_GruntAquaHideout8), .party = {.NoItemDefaultMoves = sParty_GruntAquaHideout8}, }, @@ -2724,7 +2724,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("SHAWN"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Shawn), .party = {.NoItemDefaultMoves = sParty_Shawn}, }, @@ -2738,7 +2738,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("FERNANDO"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Fernando1), .party = {.NoItemDefaultMoves = sParty_Fernando1}, }, @@ -2752,7 +2752,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("DALTON"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Dalton1), .party = {.NoItemDefaultMoves = sParty_Dalton1}, }, @@ -2766,7 +2766,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("DALTON"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Dalton2), .party = {.NoItemDefaultMoves = sParty_Dalton2}, }, @@ -2780,7 +2780,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("DALTON"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Dalton3), .party = {.NoItemDefaultMoves = sParty_Dalton3}, }, @@ -2794,7 +2794,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("DALTON"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Dalton4), .party = {.NoItemDefaultMoves = sParty_Dalton4}, }, @@ -2808,7 +2808,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("DALTON"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Dalton5), .party = {.NoItemDefaultMoves = sParty_Dalton5}, }, @@ -2822,7 +2822,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("COLE"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Cole), .party = {.NoItemDefaultMoves = sParty_Cole}, }, @@ -2836,7 +2836,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("JEFF"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Jeff), .party = {.NoItemDefaultMoves = sParty_Jeff}, }, @@ -2850,7 +2850,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("AXLE"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Axle), .party = {.NoItemDefaultMoves = sParty_Axle}, }, @@ -2864,7 +2864,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("JACE"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Jace), .party = {.NoItemDefaultMoves = sParty_Jace}, }, @@ -2878,7 +2878,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("KEEGAN"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Keegan), .party = {.NoItemDefaultMoves = sParty_Keegan}, }, @@ -2892,7 +2892,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("BERNIE"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Bernie1), .party = {.NoItemDefaultMoves = sParty_Bernie1}, }, @@ -2906,7 +2906,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("BERNIE"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Bernie2), .party = {.NoItemDefaultMoves = sParty_Bernie2}, }, @@ -2920,7 +2920,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("BERNIE"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Bernie3), .party = {.NoItemDefaultMoves = sParty_Bernie3}, }, @@ -2934,7 +2934,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("BERNIE"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Bernie4), .party = {.NoItemDefaultMoves = sParty_Bernie4}, }, @@ -2948,7 +2948,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("BERNIE"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Bernie5), .party = {.NoItemDefaultMoves = sParty_Bernie5}, }, @@ -2962,7 +2962,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("DREW"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Drew), .party = {.NoItemCustomMoves = sParty_Drew}, }, @@ -2976,7 +2976,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("BEAU"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Beau), .party = {.NoItemCustomMoves = sParty_Beau}, }, @@ -2990,7 +2990,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("LARRY"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Larry), .party = {.NoItemDefaultMoves = sParty_Larry}, }, @@ -3004,7 +3004,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("SHANE"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Shane), .party = {.NoItemDefaultMoves = sParty_Shane}, }, @@ -3018,7 +3018,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("JUSTIN"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Justin), .party = {.NoItemDefaultMoves = sParty_Justin}, }, @@ -3032,7 +3032,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("ETHAN"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Ethan1), .party = {.NoItemDefaultMoves = sParty_Ethan1}, }, @@ -3046,7 +3046,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("AUTUMN"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Autumn), .party = {.NoItemDefaultMoves = sParty_Autumn}, }, @@ -3060,7 +3060,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("TRAVIS"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Travis), .party = {.NoItemDefaultMoves = sParty_Travis}, }, @@ -3074,7 +3074,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("ETHAN"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Ethan2), .party = {.NoItemDefaultMoves = sParty_Ethan2}, }, @@ -3088,7 +3088,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("ETHAN"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Ethan3), .party = {.NoItemDefaultMoves = sParty_Ethan3}, }, @@ -3102,7 +3102,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("ETHAN"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Ethan4), .party = {.NoItemDefaultMoves = sParty_Ethan4}, }, @@ -3116,7 +3116,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("ETHAN"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Ethan5), .party = {.NoItemDefaultMoves = sParty_Ethan5}, }, @@ -3130,7 +3130,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("BRENT"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Brent), .party = {.NoItemDefaultMoves = sParty_Brent}, }, @@ -3144,7 +3144,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("DONALD"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Donald), .party = {.NoItemDefaultMoves = sParty_Donald}, }, @@ -3158,7 +3158,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("TAYLOR"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Taylor), .party = {.NoItemDefaultMoves = sParty_Taylor}, }, @@ -3172,7 +3172,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("JEFFREY"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Jeffrey1), .party = {.NoItemDefaultMoves = sParty_Jeffrey1}, }, @@ -3186,7 +3186,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("DEREK"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Derek), .party = {.NoItemDefaultMoves = sParty_Derek}, }, @@ -3200,7 +3200,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("JEFFREY"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Jeffrey2), .party = {.NoItemDefaultMoves = sParty_Jeffrey2}, }, @@ -3214,7 +3214,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("JEFFREY"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Jeffrey3), .party = {.NoItemDefaultMoves = sParty_Jeffrey3}, }, @@ -3228,7 +3228,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("JEFFREY"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Jeffrey4), .party = {.NoItemDefaultMoves = sParty_Jeffrey4}, }, @@ -3242,7 +3242,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("JEFFREY"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Jeffrey5), .party = {.ItemDefaultMoves = sParty_Jeffrey5}, }, @@ -3256,7 +3256,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("EDWARD"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Edward), .party = {.NoItemCustomMoves = sParty_Edward}, }, @@ -3270,7 +3270,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("PRESTON"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Preston), .party = {.NoItemDefaultMoves = sParty_Preston}, }, @@ -3284,7 +3284,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("VIRGIL"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Virgil), .party = {.NoItemDefaultMoves = sParty_Virgil}, }, @@ -3298,7 +3298,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("BLAKE"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Blake), .party = {.NoItemDefaultMoves = sParty_Blake}, }, @@ -3312,7 +3312,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("WILLIAM"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_William), .party = {.NoItemDefaultMoves = sParty_William}, }, @@ -3326,7 +3326,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("JOSHUA"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Joshua), .party = {.NoItemDefaultMoves = sParty_Joshua}, }, @@ -3340,7 +3340,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("CAMERON"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Cameron1), .party = {.NoItemDefaultMoves = sParty_Cameron1}, }, @@ -3354,7 +3354,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("CAMERON"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Cameron2), .party = {.NoItemDefaultMoves = sParty_Cameron2}, }, @@ -3368,7 +3368,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("CAMERON"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Cameron3), .party = {.NoItemDefaultMoves = sParty_Cameron3}, }, @@ -3382,7 +3382,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("CAMERON"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Cameron4), .party = {.NoItemDefaultMoves = sParty_Cameron4}, }, @@ -3396,7 +3396,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("CAMERON"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Cameron5), .party = {.NoItemDefaultMoves = sParty_Cameron5}, }, @@ -3410,7 +3410,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("JACLYN"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Jaclyn), .party = {.NoItemCustomMoves = sParty_Jaclyn}, }, @@ -3424,7 +3424,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("HANNAH"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Hannah), .party = {.NoItemDefaultMoves = sParty_Hannah}, }, @@ -3438,7 +3438,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("SAMANTHA"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Samantha), .party = {.NoItemDefaultMoves = sParty_Samantha}, }, @@ -3452,7 +3452,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("MAURA"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Maura), .party = {.NoItemDefaultMoves = sParty_Maura}, }, @@ -3466,7 +3466,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("KAYLA"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Kayla), .party = {.NoItemDefaultMoves = sParty_Kayla}, }, @@ -3480,7 +3480,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("ALEXIS"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Alexis), .party = {.NoItemDefaultMoves = sParty_Alexis}, }, @@ -3494,7 +3494,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("JACKI"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Jacki1), .party = {.NoItemDefaultMoves = sParty_Jacki1}, }, @@ -3508,7 +3508,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("JACKI"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Jacki2), .party = {.NoItemDefaultMoves = sParty_Jacki2}, }, @@ -3522,7 +3522,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("JACKI"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Jacki3), .party = {.NoItemDefaultMoves = sParty_Jacki3}, }, @@ -3536,7 +3536,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("JACKI"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Jacki4), .party = {.NoItemDefaultMoves = sParty_Jacki4}, }, @@ -3550,7 +3550,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("JACKI"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Jacki5), .party = {.NoItemDefaultMoves = sParty_Jacki5}, }, @@ -3564,7 +3564,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("WALTER"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Walter1), .party = {.NoItemDefaultMoves = sParty_Walter1}, }, @@ -3578,7 +3578,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("MICAH"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Micah), .party = {.NoItemDefaultMoves = sParty_Micah}, }, @@ -3592,7 +3592,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("THOMAS"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Thomas), .party = {.NoItemDefaultMoves = sParty_Thomas}, }, @@ -3606,7 +3606,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("WALTER"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Walter2), .party = {.NoItemDefaultMoves = sParty_Walter2}, }, @@ -3620,7 +3620,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("WALTER"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Walter3), .party = {.NoItemCustomMoves = sParty_Walter3}, }, @@ -3634,7 +3634,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("WALTER"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Walter4), .party = {.NoItemCustomMoves = sParty_Walter4}, }, @@ -3648,7 +3648,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("WALTER"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Walter5), .party = {.NoItemCustomMoves = sParty_Walter5}, }, @@ -3662,7 +3662,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("SIDNEY"), .items = {ITEM_FULL_RESTORE, ITEM_FULL_RESTORE, ITEM_NONE, ITEM_NONE}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY | AI_SCRIPT_SETUP_FIRST_TURN, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY | AI_FLAG_SETUP_FIRST_TURN, .partySize = ARRAY_COUNT(sParty_Sidney), .party = {.ItemCustomMoves = sParty_Sidney}, }, @@ -3676,7 +3676,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("PHOEBE"), .items = {ITEM_FULL_RESTORE, ITEM_FULL_RESTORE, ITEM_NONE, ITEM_NONE}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_Phoebe), .party = {.ItemCustomMoves = sParty_Phoebe}, }, @@ -3690,7 +3690,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("GLACIA"), .items = {ITEM_FULL_RESTORE, ITEM_FULL_RESTORE, ITEM_NONE, ITEM_NONE}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_Glacia), .party = {.ItemCustomMoves = sParty_Glacia}, }, @@ -3704,7 +3704,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("DRAKE"), .items = {ITEM_FULL_RESTORE, ITEM_FULL_RESTORE, ITEM_NONE, ITEM_NONE}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_Drake), .party = {.ItemCustomMoves = sParty_Drake}, }, @@ -3718,7 +3718,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("ROXANNE"), .items = {ITEM_POTION, ITEM_POTION, ITEM_NONE, ITEM_NONE}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_Roxanne1), .party = {.ItemCustomMoves = sParty_Roxanne1}, }, @@ -3732,7 +3732,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("BRAWLY"), .items = {ITEM_SUPER_POTION, ITEM_SUPER_POTION, ITEM_NONE, ITEM_NONE}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_Brawly1), .party = {.ItemCustomMoves = sParty_Brawly1}, }, @@ -3746,7 +3746,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("WATTSON"), .items = {ITEM_SUPER_POTION, ITEM_SUPER_POTION, ITEM_NONE, ITEM_NONE}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_Wattson1), .party = {.ItemCustomMoves = sParty_Wattson1}, }, @@ -3760,7 +3760,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("FLANNERY"), .items = {ITEM_HYPER_POTION, ITEM_HYPER_POTION, ITEM_NONE, ITEM_NONE}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_Flannery1), .party = {.ItemCustomMoves = sParty_Flannery1}, }, @@ -3774,7 +3774,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("NORMAN"), .items = {ITEM_HYPER_POTION, ITEM_HYPER_POTION, ITEM_NONE, ITEM_NONE}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_Norman1), .party = {.ItemCustomMoves = sParty_Norman1}, }, @@ -3788,7 +3788,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("WINONA"), .items = {ITEM_HYPER_POTION, ITEM_HYPER_POTION, ITEM_NONE, ITEM_NONE}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY | AI_SCRIPT_RISKY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY | AI_FLAG_RISKY, .partySize = ARRAY_COUNT(sParty_Winona1), .party = {.ItemCustomMoves = sParty_Winona1}, }, @@ -3802,7 +3802,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("TATE&LIZA"), .items = {ITEM_HYPER_POTION, ITEM_HYPER_POTION, ITEM_HYPER_POTION, ITEM_HYPER_POTION}, .doubleBattle = TRUE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_TateAndLiza1), .party = {.ItemCustomMoves = sParty_TateAndLiza1}, }, @@ -3816,7 +3816,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("JUAN"), .items = {ITEM_HYPER_POTION, ITEM_HYPER_POTION, ITEM_NONE, ITEM_NONE}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_Juan1), .party = {.ItemCustomMoves = sParty_Juan1}, }, @@ -3830,7 +3830,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("JERRY"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Jerry1), .party = {.NoItemDefaultMoves = sParty_Jerry1}, }, @@ -3844,7 +3844,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("TED"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Ted), .party = {.NoItemDefaultMoves = sParty_Ted}, }, @@ -3858,7 +3858,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("PAUL"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Paul), .party = {.NoItemDefaultMoves = sParty_Paul}, }, @@ -3872,7 +3872,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("JERRY"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Jerry2), .party = {.NoItemDefaultMoves = sParty_Jerry2}, }, @@ -3886,7 +3886,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("JERRY"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Jerry3), .party = {.NoItemDefaultMoves = sParty_Jerry3}, }, @@ -3900,7 +3900,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("JERRY"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Jerry4), .party = {.NoItemDefaultMoves = sParty_Jerry4}, }, @@ -3914,7 +3914,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("JERRY"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Jerry5), .party = {.NoItemDefaultMoves = sParty_Jerry5}, }, @@ -3928,7 +3928,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("KAREN"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Karen1), .party = {.NoItemDefaultMoves = sParty_Karen1}, }, @@ -3942,7 +3942,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("GEORGIA"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Georgia), .party = {.NoItemDefaultMoves = sParty_Georgia}, }, @@ -3956,7 +3956,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("KAREN"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Karen2), .party = {.NoItemDefaultMoves = sParty_Karen2}, }, @@ -3970,7 +3970,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("KAREN"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Karen3), .party = {.NoItemDefaultMoves = sParty_Karen3}, }, @@ -3984,7 +3984,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("KAREN"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Karen4), .party = {.NoItemDefaultMoves = sParty_Karen4}, }, @@ -3998,7 +3998,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("KAREN"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Karen5), .party = {.NoItemDefaultMoves = sParty_Karen5}, }, @@ -4012,7 +4012,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("KATE & JOY"), .items = {}, .doubleBattle = TRUE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_KateAndJoy), .party = {.NoItemCustomMoves = sParty_KateAndJoy}, }, @@ -4026,7 +4026,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("ANNA & MEG"), .items = {}, .doubleBattle = TRUE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_AnnaAndMeg1), .party = {.NoItemCustomMoves = sParty_AnnaAndMeg1}, }, @@ -4040,7 +4040,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("ANNA & MEG"), .items = {}, .doubleBattle = TRUE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_AnnaAndMeg2), .party = {.NoItemCustomMoves = sParty_AnnaAndMeg2}, }, @@ -4054,7 +4054,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("ANNA & MEG"), .items = {}, .doubleBattle = TRUE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_AnnaAndMeg3), .party = {.NoItemCustomMoves = sParty_AnnaAndMeg3}, }, @@ -4068,7 +4068,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("ANNA & MEG"), .items = {}, .doubleBattle = TRUE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_AnnaAndMeg4), .party = {.NoItemCustomMoves = sParty_AnnaAndMeg4}, }, @@ -4082,7 +4082,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("ANNA & MEG"), .items = {}, .doubleBattle = TRUE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_AnnaAndMeg5), .party = {.NoItemCustomMoves = sParty_AnnaAndMeg5}, }, @@ -4096,7 +4096,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("VICTOR"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Victor), .party = {.ItemDefaultMoves = sParty_Victor}, }, @@ -4110,7 +4110,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("MIGUEL"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Miguel1), .party = {.ItemDefaultMoves = sParty_Miguel1}, }, @@ -4124,7 +4124,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("COLTON"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Colton), .party = {.ItemCustomMoves = sParty_Colton}, }, @@ -4138,7 +4138,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("MIGUEL"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Miguel2), .party = {.ItemDefaultMoves = sParty_Miguel2}, }, @@ -4152,7 +4152,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("MIGUEL"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Miguel3), .party = {.ItemDefaultMoves = sParty_Miguel3}, }, @@ -4166,7 +4166,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("MIGUEL"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Miguel4), .party = {.ItemDefaultMoves = sParty_Miguel4}, }, @@ -4180,7 +4180,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("MIGUEL"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Miguel5), .party = {.ItemDefaultMoves = sParty_Miguel5}, }, @@ -4194,7 +4194,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("VICTORIA"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT, .partySize = ARRAY_COUNT(sParty_Victoria), .party = {.ItemDefaultMoves = sParty_Victoria}, }, @@ -4208,7 +4208,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("VANESSA"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Vanessa), .party = {.ItemDefaultMoves = sParty_Vanessa}, }, @@ -4222,7 +4222,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("BETHANY"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Bethany), .party = {.ItemDefaultMoves = sParty_Bethany}, }, @@ -4236,7 +4236,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("ISABEL"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Isabel1), .party = {.ItemDefaultMoves = sParty_Isabel1}, }, @@ -4250,7 +4250,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("ISABEL"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Isabel2), .party = {.ItemDefaultMoves = sParty_Isabel2}, }, @@ -4264,7 +4264,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("ISABEL"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Isabel3), .party = {.ItemDefaultMoves = sParty_Isabel3}, }, @@ -4278,7 +4278,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("ISABEL"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Isabel4), .party = {.ItemDefaultMoves = sParty_Isabel4}, }, @@ -4292,7 +4292,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("ISABEL"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Isabel5), .party = {.ItemDefaultMoves = sParty_Isabel5}, }, @@ -4306,7 +4306,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("TIMOTHY"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_Timothy1), .party = {.NoItemDefaultMoves = sParty_Timothy1}, }, @@ -4320,7 +4320,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("TIMOTHY"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_Timothy2), .party = {.NoItemCustomMoves = sParty_Timothy2}, }, @@ -4334,7 +4334,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("TIMOTHY"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_Timothy3), .party = {.NoItemCustomMoves = sParty_Timothy3}, }, @@ -4348,7 +4348,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("TIMOTHY"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_Timothy4), .party = {.NoItemCustomMoves = sParty_Timothy4}, }, @@ -4362,7 +4362,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("TIMOTHY"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_Timothy5), .party = {.NoItemCustomMoves = sParty_Timothy5}, }, @@ -4376,7 +4376,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("VICKY"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_Vicky), .party = {.NoItemCustomMoves = sParty_Vicky}, }, @@ -4390,7 +4390,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("SHELBY"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_Shelby1), .party = {.NoItemDefaultMoves = sParty_Shelby1}, }, @@ -4404,7 +4404,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("SHELBY"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_Shelby2), .party = {.NoItemDefaultMoves = sParty_Shelby2}, }, @@ -4418,7 +4418,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("SHELBY"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_Shelby3), .party = {.NoItemDefaultMoves = sParty_Shelby3}, }, @@ -4432,7 +4432,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("SHELBY"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_Shelby4), .party = {.NoItemDefaultMoves = sParty_Shelby4}, }, @@ -4446,7 +4446,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("SHELBY"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_Shelby5), .party = {.NoItemDefaultMoves = sParty_Shelby5}, }, @@ -4460,7 +4460,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("CALVIN"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Calvin1), .party = {.NoItemDefaultMoves = sParty_Calvin1}, }, @@ -4474,7 +4474,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("BILLY"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Billy), .party = {.NoItemDefaultMoves = sParty_Billy}, }, @@ -4488,7 +4488,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("JOSH"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Josh), .party = {.NoItemCustomMoves = sParty_Josh}, }, @@ -4502,7 +4502,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("TOMMY"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Tommy), .party = {.NoItemDefaultMoves = sParty_Tommy}, }, @@ -4516,7 +4516,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("JOEY"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Joey), .party = {.NoItemDefaultMoves = sParty_Joey}, }, @@ -4530,7 +4530,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("BEN"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Ben), .party = {.NoItemCustomMoves = sParty_Ben}, }, @@ -4544,7 +4544,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("QUINCY"), .items = {ITEM_FULL_RESTORE, ITEM_NONE, ITEM_NONE, ITEM_NONE}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_Quincy), .party = {.NoItemCustomMoves = sParty_Quincy}, }, @@ -4558,7 +4558,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("KATELYNN"), .items = {ITEM_FULL_RESTORE, ITEM_NONE, ITEM_NONE, ITEM_NONE}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_Katelynn), .party = {.NoItemCustomMoves = sParty_Katelynn}, }, @@ -4572,7 +4572,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("JAYLEN"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Jaylen), .party = {.NoItemDefaultMoves = sParty_Jaylen}, }, @@ -4586,7 +4586,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("DILLON"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Dillon), .party = {.NoItemDefaultMoves = sParty_Dillon}, }, @@ -4600,7 +4600,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("CALVIN"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Calvin2), .party = {.NoItemDefaultMoves = sParty_Calvin2}, }, @@ -4614,7 +4614,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("CALVIN"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Calvin3), .party = {.NoItemDefaultMoves = sParty_Calvin3}, }, @@ -4628,7 +4628,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("CALVIN"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Calvin4), .party = {.NoItemDefaultMoves = sParty_Calvin4}, }, @@ -4642,7 +4642,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("CALVIN"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Calvin5), .party = {.NoItemDefaultMoves = sParty_Calvin5}, }, @@ -4656,7 +4656,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("EDDIE"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Eddie), .party = {.NoItemDefaultMoves = sParty_Eddie}, }, @@ -4670,7 +4670,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("ALLEN"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Allen), .party = {.NoItemDefaultMoves = sParty_Allen}, }, @@ -4684,7 +4684,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("TIMMY"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Timmy), .party = {.NoItemDefaultMoves = sParty_Timmy}, }, @@ -4698,7 +4698,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("WALLACE"), .items = {ITEM_FULL_RESTORE, ITEM_FULL_RESTORE, ITEM_FULL_RESTORE, ITEM_FULL_RESTORE}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_Wallace), .party = {.ItemCustomMoves = sParty_Wallace}, }, @@ -4712,7 +4712,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("ANDREW"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Andrew), .party = {.NoItemDefaultMoves = sParty_Andrew}, }, @@ -4726,7 +4726,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("IVAN"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Ivan), .party = {.NoItemDefaultMoves = sParty_Ivan}, }, @@ -4740,7 +4740,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("CLAUDE"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Claude), .party = {.NoItemDefaultMoves = sParty_Claude}, }, @@ -4754,7 +4754,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("ELLIOT"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Elliot1), .party = {.NoItemDefaultMoves = sParty_Elliot1}, }, @@ -4768,7 +4768,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("NED"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Ned), .party = {.NoItemDefaultMoves = sParty_Ned}, }, @@ -4782,7 +4782,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("DALE"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Dale), .party = {.NoItemDefaultMoves = sParty_Dale}, }, @@ -4796,7 +4796,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("NOLAN"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Nolan), .party = {.NoItemDefaultMoves = sParty_Nolan}, }, @@ -4810,7 +4810,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("BARNY"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Barny), .party = {.NoItemDefaultMoves = sParty_Barny}, }, @@ -4824,7 +4824,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("WADE"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Wade), .party = {.NoItemDefaultMoves = sParty_Wade}, }, @@ -4838,7 +4838,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("CARTER"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Carter), .party = {.NoItemDefaultMoves = sParty_Carter}, }, @@ -4852,7 +4852,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("ELLIOT"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Elliot2), .party = {.NoItemDefaultMoves = sParty_Elliot2}, }, @@ -4866,7 +4866,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("ELLIOT"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Elliot3), .party = {.NoItemDefaultMoves = sParty_Elliot3}, }, @@ -4880,7 +4880,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("ELLIOT"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Elliot4), .party = {.NoItemDefaultMoves = sParty_Elliot4}, }, @@ -4894,7 +4894,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("ELLIOT"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT, .partySize = ARRAY_COUNT(sParty_Elliot5), .party = {.NoItemDefaultMoves = sParty_Elliot5}, }, @@ -4908,7 +4908,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("RONALD"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Ronald), .party = {.NoItemDefaultMoves = sParty_Ronald}, }, @@ -4922,7 +4922,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("JACOB"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Jacob), .party = {.NoItemDefaultMoves = sParty_Jacob}, }, @@ -4936,7 +4936,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("ANTHONY"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Anthony), .party = {.NoItemDefaultMoves = sParty_Anthony}, }, @@ -4950,7 +4950,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("BENJAMIN"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Benjamin1), .party = {.NoItemDefaultMoves = sParty_Benjamin1}, }, @@ -4964,7 +4964,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("BENJAMIN"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Benjamin2), .party = {.NoItemDefaultMoves = sParty_Benjamin2}, }, @@ -4978,7 +4978,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("BENJAMIN"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Benjamin3), .party = {.NoItemDefaultMoves = sParty_Benjamin3}, }, @@ -4992,7 +4992,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("BENJAMIN"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Benjamin4), .party = {.NoItemDefaultMoves = sParty_Benjamin4}, }, @@ -5006,7 +5006,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("BENJAMIN"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Benjamin5), .party = {.NoItemDefaultMoves = sParty_Benjamin5}, }, @@ -5020,7 +5020,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("ABIGAIL"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Abigail1), .party = {.NoItemDefaultMoves = sParty_Abigail1}, }, @@ -5034,7 +5034,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("JASMINE"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Jasmine), .party = {.NoItemDefaultMoves = sParty_Jasmine}, }, @@ -5048,7 +5048,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("ABIGAIL"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Abigail2), .party = {.NoItemDefaultMoves = sParty_Abigail2}, }, @@ -5062,7 +5062,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("ABIGAIL"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Abigail3), .party = {.NoItemDefaultMoves = sParty_Abigail3}, }, @@ -5076,7 +5076,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("ABIGAIL"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Abigail4), .party = {.NoItemDefaultMoves = sParty_Abigail4}, }, @@ -5090,7 +5090,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("ABIGAIL"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Abigail5), .party = {.NoItemDefaultMoves = sParty_Abigail5}, }, @@ -5104,7 +5104,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("DYLAN"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Dylan1), .party = {.NoItemDefaultMoves = sParty_Dylan1}, }, @@ -5118,7 +5118,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("DYLAN"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Dylan2), .party = {.NoItemDefaultMoves = sParty_Dylan2}, }, @@ -5132,7 +5132,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("DYLAN"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Dylan3), .party = {.NoItemDefaultMoves = sParty_Dylan3}, }, @@ -5146,7 +5146,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("DYLAN"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Dylan4), .party = {.NoItemDefaultMoves = sParty_Dylan4}, }, @@ -5160,7 +5160,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("DYLAN"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Dylan5), .party = {.NoItemDefaultMoves = sParty_Dylan5}, }, @@ -5174,7 +5174,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("MARIA"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Maria1), .party = {.NoItemDefaultMoves = sParty_Maria1}, }, @@ -5188,7 +5188,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("MARIA"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Maria2), .party = {.NoItemDefaultMoves = sParty_Maria2}, }, @@ -5202,7 +5202,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("MARIA"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Maria3), .party = {.NoItemDefaultMoves = sParty_Maria3}, }, @@ -5216,7 +5216,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("MARIA"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Maria4), .party = {.NoItemDefaultMoves = sParty_Maria4}, }, @@ -5230,7 +5230,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("MARIA"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Maria5), .party = {.NoItemDefaultMoves = sParty_Maria5}, }, @@ -5244,7 +5244,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("CAMDEN"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Camden), .party = {.NoItemDefaultMoves = sParty_Camden}, }, @@ -5258,7 +5258,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("DEMETRIUS"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Demetrius), .party = {.NoItemDefaultMoves = sParty_Demetrius}, }, @@ -5272,7 +5272,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("ISAIAH"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Isaiah1), .party = {.NoItemDefaultMoves = sParty_Isaiah1}, }, @@ -5286,7 +5286,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("PABLO"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Pablo1), .party = {.NoItemDefaultMoves = sParty_Pablo1}, }, @@ -5300,7 +5300,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("CHASE"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Chase), .party = {.NoItemDefaultMoves = sParty_Chase}, }, @@ -5314,7 +5314,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("ISAIAH"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Isaiah2), .party = {.NoItemDefaultMoves = sParty_Isaiah2}, }, @@ -5328,7 +5328,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("ISAIAH"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Isaiah3), .party = {.NoItemDefaultMoves = sParty_Isaiah3}, }, @@ -5342,7 +5342,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("ISAIAH"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Isaiah4), .party = {.NoItemDefaultMoves = sParty_Isaiah4}, }, @@ -5356,7 +5356,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("ISAIAH"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Isaiah5), .party = {.NoItemDefaultMoves = sParty_Isaiah5}, }, @@ -5370,7 +5370,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("ISOBEL"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Isobel), .party = {.NoItemDefaultMoves = sParty_Isobel}, }, @@ -5384,7 +5384,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("DONNY"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Donny), .party = {.NoItemDefaultMoves = sParty_Donny}, }, @@ -5398,7 +5398,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("TALIA"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Talia), .party = {.NoItemDefaultMoves = sParty_Talia}, }, @@ -5412,7 +5412,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("KATELYN"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Katelyn1), .party = {.NoItemDefaultMoves = sParty_Katelyn1}, }, @@ -5426,7 +5426,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("ALLISON"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Allison), .party = {.NoItemDefaultMoves = sParty_Allison}, }, @@ -5440,7 +5440,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("KATELYN"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Katelyn2), .party = {.NoItemDefaultMoves = sParty_Katelyn2}, }, @@ -5454,7 +5454,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("KATELYN"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Katelyn3), .party = {.NoItemDefaultMoves = sParty_Katelyn3}, }, @@ -5468,7 +5468,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("KATELYN"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Katelyn4), .party = {.NoItemDefaultMoves = sParty_Katelyn4}, }, @@ -5482,7 +5482,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("KATELYN"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Katelyn5), .party = {.NoItemDefaultMoves = sParty_Katelyn5}, }, @@ -5496,7 +5496,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("NICOLAS"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Nicolas1), .party = {.NoItemDefaultMoves = sParty_Nicolas1}, }, @@ -5510,7 +5510,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("NICOLAS"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Nicolas2), .party = {.NoItemDefaultMoves = sParty_Nicolas2}, }, @@ -5524,7 +5524,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("NICOLAS"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Nicolas3), .party = {.NoItemDefaultMoves = sParty_Nicolas3}, }, @@ -5538,7 +5538,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("NICOLAS"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Nicolas4), .party = {.NoItemDefaultMoves = sParty_Nicolas4}, }, @@ -5552,7 +5552,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("NICOLAS"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Nicolas5), .party = {.ItemDefaultMoves = sParty_Nicolas5}, }, @@ -5566,7 +5566,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("AARON"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Aaron), .party = {.NoItemCustomMoves = sParty_Aaron}, }, @@ -5580,7 +5580,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("PERRY"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Perry), .party = {.NoItemDefaultMoves = sParty_Perry}, }, @@ -5594,7 +5594,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("HUGH"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Hugh), .party = {.NoItemDefaultMoves = sParty_Hugh}, }, @@ -5608,7 +5608,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("PHIL"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Phil), .party = {.NoItemDefaultMoves = sParty_Phil}, }, @@ -5622,7 +5622,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("JARED"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Jared), .party = {.NoItemDefaultMoves = sParty_Jared}, }, @@ -5636,7 +5636,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("HUMBERTO"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Humberto), .party = {.NoItemDefaultMoves = sParty_Humberto}, }, @@ -5650,7 +5650,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("PRESLEY"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Presley), .party = {.NoItemDefaultMoves = sParty_Presley}, }, @@ -5664,7 +5664,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("EDWARDO"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Edwardo), .party = {.NoItemDefaultMoves = sParty_Edwardo}, }, @@ -5678,7 +5678,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("COLIN"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Colin), .party = {.NoItemDefaultMoves = sParty_Colin}, }, @@ -5692,7 +5692,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("ROBERT"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Robert1), .party = {.NoItemDefaultMoves = sParty_Robert1}, }, @@ -5706,7 +5706,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("BENNY"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Benny), .party = {.NoItemDefaultMoves = sParty_Benny}, }, @@ -5720,7 +5720,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("CHESTER"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Chester), .party = {.NoItemDefaultMoves = sParty_Chester}, }, @@ -5734,7 +5734,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("ROBERT"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Robert2), .party = {.NoItemDefaultMoves = sParty_Robert2}, }, @@ -5748,7 +5748,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("ROBERT"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Robert3), .party = {.NoItemDefaultMoves = sParty_Robert3}, }, @@ -5762,7 +5762,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("ROBERT"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Robert4), .party = {.NoItemDefaultMoves = sParty_Robert4}, }, @@ -5776,7 +5776,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("ROBERT"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Robert5), .party = {.NoItemDefaultMoves = sParty_Robert5}, }, @@ -5790,7 +5790,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("ALEX"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Alex), .party = {.NoItemDefaultMoves = sParty_Alex}, }, @@ -5804,7 +5804,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("BECK"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Beck), .party = {.NoItemDefaultMoves = sParty_Beck}, }, @@ -5818,7 +5818,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("YASU"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT, .partySize = ARRAY_COUNT(sParty_Yasu), .party = {.NoItemDefaultMoves = sParty_Yasu}, }, @@ -5832,7 +5832,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("TAKASHI"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT, .partySize = ARRAY_COUNT(sParty_Takashi), .party = {.NoItemDefaultMoves = sParty_Takashi}, }, @@ -5958,7 +5958,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("JOCELYN"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Jocelyn), .party = {.NoItemDefaultMoves = sParty_Jocelyn}, }, @@ -5972,7 +5972,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("LAURA"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Laura), .party = {.NoItemDefaultMoves = sParty_Laura}, }, @@ -5986,7 +5986,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("CYNDY"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Cyndy1), .party = {.NoItemDefaultMoves = sParty_Cyndy1}, }, @@ -6000,7 +6000,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("CORA"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Cora), .party = {.NoItemDefaultMoves = sParty_Cora}, }, @@ -6014,7 +6014,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("PAULA"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Paula), .party = {.NoItemDefaultMoves = sParty_Paula}, }, @@ -6028,7 +6028,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("CYNDY"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Cyndy2), .party = {.NoItemDefaultMoves = sParty_Cyndy2}, }, @@ -6042,7 +6042,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("CYNDY"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Cyndy3), .party = {.NoItemDefaultMoves = sParty_Cyndy3}, }, @@ -6056,7 +6056,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("CYNDY"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Cyndy4), .party = {.NoItemDefaultMoves = sParty_Cyndy4}, }, @@ -6070,7 +6070,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("CYNDY"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Cyndy5), .party = {.NoItemDefaultMoves = sParty_Cyndy5}, }, @@ -6084,7 +6084,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("MADELINE"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Madeline1), .party = {.NoItemCustomMoves = sParty_Madeline1}, }, @@ -6098,7 +6098,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("CLARISSA"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Clarissa), .party = {.NoItemDefaultMoves = sParty_Clarissa}, }, @@ -6112,7 +6112,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("ANGELICA"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Angelica), .party = {.NoItemCustomMoves = sParty_Angelica}, }, @@ -6126,7 +6126,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("MADELINE"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Madeline2), .party = {.NoItemCustomMoves = sParty_Madeline2}, }, @@ -6140,7 +6140,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("MADELINE"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Madeline3), .party = {.NoItemCustomMoves = sParty_Madeline3}, }, @@ -6154,7 +6154,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("MADELINE"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Madeline4), .party = {.NoItemCustomMoves = sParty_Madeline4}, }, @@ -6168,7 +6168,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("MADELINE"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Madeline5), .party = {.NoItemCustomMoves = sParty_Madeline5}, }, @@ -6182,7 +6182,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("BEVERLY"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Beverly), .party = {.NoItemDefaultMoves = sParty_Beverly}, }, @@ -6196,7 +6196,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("IMANI"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Imani), .party = {.NoItemDefaultMoves = sParty_Imani}, }, @@ -6210,7 +6210,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("KYLA"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Kyla), .party = {.NoItemDefaultMoves = sParty_Kyla}, }, @@ -6224,7 +6224,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("DENISE"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Denise), .party = {.NoItemDefaultMoves = sParty_Denise}, }, @@ -6238,7 +6238,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("BETH"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Beth), .party = {.NoItemDefaultMoves = sParty_Beth}, }, @@ -6252,7 +6252,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("TARA"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Tara), .party = {.NoItemDefaultMoves = sParty_Tara}, }, @@ -6266,7 +6266,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("MISSY"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Missy), .party = {.NoItemDefaultMoves = sParty_Missy}, }, @@ -6280,7 +6280,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("ALICE"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Alice), .party = {.NoItemDefaultMoves = sParty_Alice}, }, @@ -6294,7 +6294,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("JENNY"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Jenny1), .party = {.NoItemDefaultMoves = sParty_Jenny1}, }, @@ -6308,7 +6308,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("GRACE"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Grace), .party = {.NoItemDefaultMoves = sParty_Grace}, }, @@ -6322,7 +6322,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("TANYA"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Tanya), .party = {.NoItemDefaultMoves = sParty_Tanya}, }, @@ -6336,7 +6336,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("SHARON"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Sharon), .party = {.NoItemDefaultMoves = sParty_Sharon}, }, @@ -6350,7 +6350,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("NIKKI"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Nikki), .party = {.NoItemDefaultMoves = sParty_Nikki}, }, @@ -6364,7 +6364,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("BRENDA"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Brenda), .party = {.NoItemDefaultMoves = sParty_Brenda}, }, @@ -6378,7 +6378,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("KATIE"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Katie), .party = {.NoItemDefaultMoves = sParty_Katie}, }, @@ -6392,7 +6392,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("SUSIE"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Susie), .party = {.NoItemDefaultMoves = sParty_Susie}, }, @@ -6406,7 +6406,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("KARA"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Kara), .party = {.NoItemDefaultMoves = sParty_Kara}, }, @@ -6420,7 +6420,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("DANA"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Dana), .party = {.NoItemDefaultMoves = sParty_Dana}, }, @@ -6434,7 +6434,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("SIENNA"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Sienna), .party = {.NoItemDefaultMoves = sParty_Sienna}, }, @@ -6448,7 +6448,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("DEBRA"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Debra), .party = {.NoItemDefaultMoves = sParty_Debra}, }, @@ -6462,7 +6462,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("LINDA"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Linda), .party = {.NoItemDefaultMoves = sParty_Linda}, }, @@ -6476,7 +6476,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("KAYLEE"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Kaylee), .party = {.NoItemDefaultMoves = sParty_Kaylee}, }, @@ -6490,7 +6490,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("LAUREL"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Laurel), .party = {.NoItemDefaultMoves = sParty_Laurel}, }, @@ -6504,7 +6504,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("CARLEE"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Carlee), .party = {.NoItemDefaultMoves = sParty_Carlee}, }, @@ -6518,7 +6518,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("JENNY"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Jenny2), .party = {.NoItemDefaultMoves = sParty_Jenny2}, }, @@ -6532,7 +6532,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("JENNY"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Jenny3), .party = {.NoItemDefaultMoves = sParty_Jenny3}, }, @@ -6546,7 +6546,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("JENNY"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Jenny4), .party = {.NoItemDefaultMoves = sParty_Jenny4}, }, @@ -6560,7 +6560,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("JENNY"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Jenny5), .party = {.NoItemDefaultMoves = sParty_Jenny5}, }, @@ -6574,7 +6574,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("HEIDI"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Heidi), .party = {.NoItemCustomMoves = sParty_Heidi}, }, @@ -6588,7 +6588,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("BECKY"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Becky), .party = {.NoItemCustomMoves = sParty_Becky}, }, @@ -6602,7 +6602,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("CAROL"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Carol), .party = {.NoItemDefaultMoves = sParty_Carol}, }, @@ -6616,7 +6616,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("NANCY"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Nancy), .party = {.NoItemDefaultMoves = sParty_Nancy}, }, @@ -6630,7 +6630,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("MARTHA"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Martha), .party = {.NoItemDefaultMoves = sParty_Martha}, }, @@ -6644,7 +6644,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("DIANA"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Diana1), .party = {.NoItemDefaultMoves = sParty_Diana1}, }, @@ -6658,7 +6658,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("CEDRIC"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Cedric), .party = {.NoItemCustomMoves = sParty_Cedric}, }, @@ -6672,7 +6672,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("IRENE"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Irene), .party = {.NoItemDefaultMoves = sParty_Irene}, }, @@ -6686,7 +6686,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("DIANA"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Diana2), .party = {.NoItemDefaultMoves = sParty_Diana2}, }, @@ -6700,7 +6700,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("DIANA"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Diana3), .party = {.NoItemDefaultMoves = sParty_Diana3}, }, @@ -6714,7 +6714,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("DIANA"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Diana4), .party = {.NoItemDefaultMoves = sParty_Diana4}, }, @@ -6728,7 +6728,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("DIANA"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Diana5), .party = {.NoItemDefaultMoves = sParty_Diana5}, }, @@ -6742,7 +6742,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("AMY & LIV"), .items = {}, .doubleBattle = TRUE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_AmyAndLiv1), .party = {.NoItemDefaultMoves = sParty_AmyAndLiv1}, }, @@ -6756,7 +6756,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("AMY & LIV"), .items = {}, .doubleBattle = TRUE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_AmyAndLiv2), .party = {.NoItemDefaultMoves = sParty_AmyAndLiv2}, }, @@ -6770,7 +6770,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("GINA & MIA"), .items = {}, .doubleBattle = TRUE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_GinaAndMia1), .party = {.NoItemDefaultMoves = sParty_GinaAndMia1}, }, @@ -6784,7 +6784,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("MIU & YUKI"), .items = {}, .doubleBattle = TRUE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_MiuAndYuki), .party = {.NoItemDefaultMoves = sParty_MiuAndYuki}, }, @@ -6798,7 +6798,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("AMY & LIV"), .items = {}, .doubleBattle = TRUE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_AmyAndLiv3), .party = {.NoItemDefaultMoves = sParty_AmyAndLiv3}, }, @@ -6812,7 +6812,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("GINA & MIA"), .items = {}, .doubleBattle = TRUE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_GinaAndMia2), .party = {.NoItemCustomMoves = sParty_GinaAndMia2}, }, @@ -6826,7 +6826,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("AMY & LIV"), .items = {}, .doubleBattle = TRUE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_AmyAndLiv4), .party = {.NoItemDefaultMoves = sParty_AmyAndLiv4}, }, @@ -6840,7 +6840,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("AMY & LIV"), .items = {}, .doubleBattle = TRUE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_AmyAndLiv5), .party = {.NoItemCustomMoves = sParty_AmyAndLiv5}, }, @@ -6854,7 +6854,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("AMY & LIV"), .items = {}, .doubleBattle = TRUE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_AmyAndLiv6), .party = {.NoItemCustomMoves = sParty_AmyAndLiv6}, }, @@ -6868,7 +6868,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("HUEY"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Huey), .party = {.NoItemDefaultMoves = sParty_Huey}, }, @@ -6882,7 +6882,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("EDMOND"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Edmond), .party = {.NoItemDefaultMoves = sParty_Edmond}, }, @@ -6896,7 +6896,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("ERNEST"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Ernest1), .party = {.NoItemDefaultMoves = sParty_Ernest1}, }, @@ -6910,7 +6910,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("DWAYNE"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Dwayne), .party = {.NoItemDefaultMoves = sParty_Dwayne}, }, @@ -6924,7 +6924,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("PHILLIP"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Phillip), .party = {.NoItemDefaultMoves = sParty_Phillip}, }, @@ -6938,7 +6938,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("LEONARD"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Leonard), .party = {.NoItemDefaultMoves = sParty_Leonard}, }, @@ -6952,7 +6952,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("DUNCAN"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Duncan), .party = {.NoItemDefaultMoves = sParty_Duncan}, }, @@ -6966,7 +6966,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("ERNEST"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Ernest2), .party = {.NoItemDefaultMoves = sParty_Ernest2}, }, @@ -6980,7 +6980,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("ERNEST"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Ernest3), .party = {.NoItemDefaultMoves = sParty_Ernest3}, }, @@ -6994,7 +6994,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("ERNEST"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Ernest4), .party = {.NoItemDefaultMoves = sParty_Ernest4}, }, @@ -7008,7 +7008,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("ERNEST"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Ernest5), .party = {.NoItemDefaultMoves = sParty_Ernest5}, }, @@ -7022,7 +7022,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("ELI"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Eli), .party = {.NoItemDefaultMoves = sParty_Eli}, }, @@ -7036,7 +7036,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("ANNIKA"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Annika), .party = {.ItemCustomMoves = sParty_Annika}, }, @@ -7050,7 +7050,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("JAZMYN"), .items = {ITEM_HYPER_POTION, ITEM_NONE, ITEM_NONE, ITEM_NONE}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_Jazmyn), .party = {.NoItemDefaultMoves = sParty_Jazmyn}, }, @@ -7064,7 +7064,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("JONAS"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_Jonas), .party = {.NoItemCustomMoves = sParty_Jonas}, }, @@ -7078,7 +7078,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("KAYLEY"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Kayley), .party = {.NoItemCustomMoves = sParty_Kayley}, }, @@ -7092,7 +7092,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("AURON"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Auron), .party = {.NoItemDefaultMoves = sParty_Auron}, }, @@ -7106,7 +7106,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("KELVIN"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Kelvin), .party = {.NoItemDefaultMoves = sParty_Kelvin}, }, @@ -7120,7 +7120,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("MARLEY"), .items = {ITEM_HYPER_POTION, ITEM_NONE, ITEM_NONE, ITEM_NONE}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_Marley), .party = {.ItemCustomMoves = sParty_Marley}, }, @@ -7134,7 +7134,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("REYNA"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Reyna), .party = {.NoItemDefaultMoves = sParty_Reyna}, }, @@ -7148,7 +7148,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("HUDSON"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Hudson), .party = {.NoItemDefaultMoves = sParty_Hudson}, }, @@ -7162,7 +7162,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("CONOR"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Conor), .party = {.NoItemDefaultMoves = sParty_Conor}, }, @@ -7176,7 +7176,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("EDWIN"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Edwin1), .party = {.NoItemDefaultMoves = sParty_Edwin1}, }, @@ -7190,7 +7190,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("HECTOR"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Hector), .party = {.NoItemDefaultMoves = sParty_Hector}, }, @@ -7204,7 +7204,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("TABITHA"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_TabithaMossdeep), .party = {.NoItemDefaultMoves = sParty_TabithaMossdeep}, }, @@ -7218,7 +7218,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("EDWIN"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Edwin2), .party = {.NoItemDefaultMoves = sParty_Edwin2}, }, @@ -7232,7 +7232,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("EDWIN"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Edwin3), .party = {.NoItemDefaultMoves = sParty_Edwin3}, }, @@ -7246,7 +7246,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("EDWIN"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Edwin4), .party = {.NoItemDefaultMoves = sParty_Edwin4}, }, @@ -7260,7 +7260,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("EDWIN"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Edwin5), .party = {.NoItemDefaultMoves = sParty_Edwin5}, }, @@ -7274,7 +7274,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("WALLY"), .items = {ITEM_FULL_RESTORE, ITEM_FULL_RESTORE, ITEM_NONE, ITEM_NONE}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_WallyVR1), .party = {.NoItemCustomMoves = sParty_WallyVR1}, }, @@ -7288,7 +7288,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("BRENDAN"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_BrendanRoute103Mudkip), .party = {.NoItemDefaultMoves = sParty_BrendanRoute103Mudkip}, }, @@ -7302,7 +7302,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("BRENDAN"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_BrendanRoute110Mudkip), .party = {.NoItemDefaultMoves = sParty_BrendanRoute110Mudkip}, }, @@ -7316,7 +7316,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("BRENDAN"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_BrendanRoute119Mudkip), .party = {.NoItemDefaultMoves = sParty_BrendanRoute119Mudkip}, }, @@ -7330,7 +7330,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("BRENDAN"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_SETUP_FIRST_TURN, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_SETUP_FIRST_TURN, .partySize = ARRAY_COUNT(sParty_BrendanRoute103Treecko), .party = {.NoItemDefaultMoves = sParty_BrendanRoute103Treecko}, }, @@ -7344,7 +7344,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("BRENDAN"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_BrendanRoute110Treecko), .party = {.NoItemDefaultMoves = sParty_BrendanRoute110Treecko}, }, @@ -7358,7 +7358,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("BRENDAN"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_BrendanRoute119Treecko), .party = {.NoItemDefaultMoves = sParty_BrendanRoute119Treecko}, }, @@ -7372,7 +7372,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("BRENDAN"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_BrendanRoute103Torchic), .party = {.NoItemDefaultMoves = sParty_BrendanRoute103Torchic}, }, @@ -7386,7 +7386,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("BRENDAN"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_BrendanRoute110Torchic), .party = {.NoItemDefaultMoves = sParty_BrendanRoute110Torchic}, }, @@ -7400,7 +7400,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("BRENDAN"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_BrendanRoute119Torchic), .party = {.NoItemDefaultMoves = sParty_BrendanRoute119Torchic}, }, @@ -7414,7 +7414,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("MAY"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_MayRoute103Mudkip), .party = {.NoItemDefaultMoves = sParty_MayRoute103Mudkip}, }, @@ -7428,7 +7428,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("MAY"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_MayRoute110Mudkip), .party = {.NoItemDefaultMoves = sParty_MayRoute110Mudkip}, }, @@ -7442,7 +7442,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("MAY"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_MayRoute119Mudkip), .party = {.NoItemDefaultMoves = sParty_MayRoute119Mudkip}, }, @@ -7456,7 +7456,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("MAY"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_MayRoute103Treecko), .party = {.NoItemDefaultMoves = sParty_MayRoute103Treecko}, }, @@ -7470,7 +7470,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("MAY"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_MayRoute110Treecko), .party = {.NoItemDefaultMoves = sParty_MayRoute110Treecko}, }, @@ -7484,7 +7484,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("MAY"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_MayRoute119Treecko), .party = {.NoItemDefaultMoves = sParty_MayRoute119Treecko}, }, @@ -7498,7 +7498,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("MAY"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_MayRoute103Torchic), .party = {.NoItemDefaultMoves = sParty_MayRoute103Torchic}, }, @@ -7512,7 +7512,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("MAY"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_MayRoute110Torchic), .party = {.NoItemDefaultMoves = sParty_MayRoute110Torchic}, }, @@ -7526,7 +7526,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("MAY"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_MayRoute119Torchic), .party = {.NoItemDefaultMoves = sParty_MayRoute119Torchic}, }, @@ -7540,7 +7540,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("ISAAC"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Isaac1), .party = {.NoItemDefaultMoves = sParty_Isaac1}, }, @@ -7554,7 +7554,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("DAVIS"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Davis), .party = {.NoItemDefaultMoves = sParty_Davis}, }, @@ -7568,7 +7568,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("MITCHELL"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_Mitchell), .party = {.NoItemCustomMoves = sParty_Mitchell}, }, @@ -7582,7 +7582,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("ISAAC"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Isaac2), .party = {.NoItemDefaultMoves = sParty_Isaac2}, }, @@ -7596,7 +7596,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("ISAAC"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Isaac3), .party = {.NoItemDefaultMoves = sParty_Isaac3}, }, @@ -7610,7 +7610,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("ISAAC"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Isaac4), .party = {.NoItemDefaultMoves = sParty_Isaac4}, }, @@ -7624,7 +7624,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("ISAAC"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Isaac5), .party = {.NoItemDefaultMoves = sParty_Isaac5}, }, @@ -7638,7 +7638,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("LYDIA"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Lydia1), .party = {.NoItemDefaultMoves = sParty_Lydia1}, }, @@ -7652,7 +7652,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("HALLE"), .items = {ITEM_FULL_RESTORE, ITEM_NONE, ITEM_NONE, ITEM_NONE}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_Halle), .party = {.NoItemDefaultMoves = sParty_Halle}, }, @@ -7666,7 +7666,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("GARRISON"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Garrison), .party = {.NoItemDefaultMoves = sParty_Garrison}, }, @@ -7680,7 +7680,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("LYDIA"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Lydia2), .party = {.NoItemDefaultMoves = sParty_Lydia2}, }, @@ -7694,7 +7694,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("LYDIA"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Lydia3), .party = {.NoItemDefaultMoves = sParty_Lydia3}, }, @@ -7708,7 +7708,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("LYDIA"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Lydia4), .party = {.NoItemDefaultMoves = sParty_Lydia4}, }, @@ -7722,7 +7722,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("LYDIA"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Lydia5), .party = {.NoItemDefaultMoves = sParty_Lydia5}, }, @@ -7736,7 +7736,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("JACKSON"), .items = {ITEM_FULL_RESTORE, ITEM_NONE, ITEM_NONE, ITEM_NONE}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_Jackson1), .party = {.NoItemDefaultMoves = sParty_Jackson1}, }, @@ -7750,7 +7750,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("LORENZO"), .items = {ITEM_FULL_RESTORE, ITEM_NONE, ITEM_NONE, ITEM_NONE}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_Lorenzo), .party = {.NoItemDefaultMoves = sParty_Lorenzo}, }, @@ -7764,7 +7764,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("SEBASTIAN"), .items = {ITEM_FULL_RESTORE, ITEM_NONE, ITEM_NONE, ITEM_NONE}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_Sebastian), .party = {.NoItemDefaultMoves = sParty_Sebastian}, }, @@ -7778,7 +7778,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("JACKSON"), .items = {ITEM_FULL_RESTORE, ITEM_NONE, ITEM_NONE, ITEM_NONE}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_SETUP_FIRST_TURN, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_SETUP_FIRST_TURN, .partySize = ARRAY_COUNT(sParty_Jackson2), .party = {.NoItemDefaultMoves = sParty_Jackson2}, }, @@ -7792,7 +7792,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("JACKSON"), .items = {ITEM_FULL_RESTORE, ITEM_NONE, ITEM_NONE, ITEM_NONE}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_Jackson3), .party = {.NoItemDefaultMoves = sParty_Jackson3}, }, @@ -7806,7 +7806,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("JACKSON"), .items = {ITEM_FULL_RESTORE, ITEM_NONE, ITEM_NONE, ITEM_NONE}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_SETUP_FIRST_TURN, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_SETUP_FIRST_TURN, .partySize = ARRAY_COUNT(sParty_Jackson4), .party = {.NoItemDefaultMoves = sParty_Jackson4}, }, @@ -7820,7 +7820,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("JACKSON"), .items = {ITEM_FULL_RESTORE, ITEM_NONE, ITEM_NONE, ITEM_NONE}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_Jackson5), .party = {.NoItemDefaultMoves = sParty_Jackson5}, }, @@ -7834,7 +7834,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("CATHERINE"), .items = {ITEM_FULL_RESTORE, ITEM_NONE, ITEM_NONE, ITEM_NONE}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_SETUP_FIRST_TURN, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_SETUP_FIRST_TURN, .partySize = ARRAY_COUNT(sParty_Catherine1), .party = {.NoItemDefaultMoves = sParty_Catherine1}, }, @@ -7848,7 +7848,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("JENNA"), .items = {ITEM_FULL_RESTORE, ITEM_NONE, ITEM_NONE, ITEM_NONE}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_SETUP_FIRST_TURN, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_SETUP_FIRST_TURN, .partySize = ARRAY_COUNT(sParty_Jenna), .party = {.NoItemDefaultMoves = sParty_Jenna}, }, @@ -7862,7 +7862,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("SOPHIA"), .items = {ITEM_FULL_RESTORE, ITEM_NONE, ITEM_NONE, ITEM_NONE}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_Sophia), .party = {.NoItemDefaultMoves = sParty_Sophia}, }, @@ -7876,7 +7876,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("CATHERINE"), .items = {ITEM_FULL_RESTORE, ITEM_NONE, ITEM_NONE, ITEM_NONE}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_SETUP_FIRST_TURN, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_SETUP_FIRST_TURN, .partySize = ARRAY_COUNT(sParty_Catherine2), .party = {.NoItemDefaultMoves = sParty_Catherine2}, }, @@ -7890,7 +7890,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("CATHERINE"), .items = {ITEM_FULL_RESTORE, ITEM_NONE, ITEM_NONE, ITEM_NONE}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_Catherine3), .party = {.NoItemDefaultMoves = sParty_Catherine3}, }, @@ -7904,7 +7904,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("CATHERINE"), .items = {ITEM_FULL_RESTORE, ITEM_NONE, ITEM_NONE, ITEM_NONE}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_SETUP_FIRST_TURN, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_SETUP_FIRST_TURN, .partySize = ARRAY_COUNT(sParty_Catherine4), .party = {.NoItemDefaultMoves = sParty_Catherine4}, }, @@ -7918,7 +7918,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("CATHERINE"), .items = {ITEM_FULL_RESTORE, ITEM_NONE, ITEM_NONE, ITEM_NONE}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_Catherine5), .party = {.NoItemDefaultMoves = sParty_Catherine5}, }, @@ -7932,7 +7932,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("JULIO"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Julio), .party = {.NoItemDefaultMoves = sParty_Julio}, }, @@ -7946,7 +7946,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("GRUNT"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_GruntSeafloorCavern5), .party = {.NoItemDefaultMoves = sParty_GruntSeafloorCavern5}, }, @@ -7960,7 +7960,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("GRUNT"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_GruntUnused), .party = {.NoItemDefaultMoves = sParty_GruntUnused}, }, @@ -7974,7 +7974,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("GRUNT"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_GruntMtPyre4), .party = {.NoItemDefaultMoves = sParty_GruntMtPyre4}, }, @@ -7988,7 +7988,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("GRUNT"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_GruntJaggedPass), .party = {.NoItemDefaultMoves = sParty_GruntJaggedPass}, }, @@ -8002,7 +8002,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("MARC"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Marc), .party = {.NoItemDefaultMoves = sParty_Marc}, }, @@ -8016,7 +8016,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("BRENDEN"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Brenden), .party = {.NoItemDefaultMoves = sParty_Brenden}, }, @@ -8030,7 +8030,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("LILITH"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Lilith), .party = {.NoItemDefaultMoves = sParty_Lilith}, }, @@ -8044,7 +8044,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("CRISTIAN"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Cristian), .party = {.NoItemDefaultMoves = sParty_Cristian}, }, @@ -8058,7 +8058,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("SYLVIA"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Sylvia), .party = {.NoItemDefaultMoves = sParty_Sylvia}, }, @@ -8072,7 +8072,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("LEONARDO"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Leonardo), .party = {.NoItemDefaultMoves = sParty_Leonardo}, }, @@ -8086,7 +8086,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("ATHENA"), .items = {ITEM_HYPER_POTION, ITEM_NONE, ITEM_NONE, ITEM_NONE}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_Athena), .party = {.ItemCustomMoves = sParty_Athena}, }, @@ -8100,7 +8100,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("HARRISON"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Harrison), .party = {.NoItemDefaultMoves = sParty_Harrison}, }, @@ -8114,7 +8114,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("GRUNT"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_GruntMtChimney2), .party = {.NoItemDefaultMoves = sParty_GruntMtChimney2}, }, @@ -8128,7 +8128,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("CLARENCE"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Clarence), .party = {.NoItemDefaultMoves = sParty_Clarence}, }, @@ -8142,7 +8142,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("TERRY"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Terry), .party = {.NoItemDefaultMoves = sParty_Terry}, }, @@ -8156,7 +8156,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("NATE"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Nate), .party = {.NoItemDefaultMoves = sParty_Nate}, }, @@ -8170,7 +8170,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("KATHLEEN"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Kathleen), .party = {.NoItemDefaultMoves = sParty_Kathleen}, }, @@ -8184,7 +8184,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("CLIFFORD"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Clifford), .party = {.NoItemDefaultMoves = sParty_Clifford}, }, @@ -8198,7 +8198,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("NICHOLAS"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Nicholas), .party = {.NoItemDefaultMoves = sParty_Nicholas}, }, @@ -8212,7 +8212,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("GRUNT"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_GruntSpaceCenter3), .party = {.NoItemDefaultMoves = sParty_GruntSpaceCenter3}, }, @@ -8226,7 +8226,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("GRUNT"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_GruntSpaceCenter4), .party = {.NoItemDefaultMoves = sParty_GruntSpaceCenter4}, }, @@ -8240,7 +8240,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("GRUNT"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_GruntSpaceCenter5), .party = {.NoItemDefaultMoves = sParty_GruntSpaceCenter5}, }, @@ -8254,7 +8254,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("GRUNT"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_GruntSpaceCenter6), .party = {.NoItemDefaultMoves = sParty_GruntSpaceCenter6}, }, @@ -8268,7 +8268,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("GRUNT"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_GruntSpaceCenter7), .party = {.NoItemDefaultMoves = sParty_GruntSpaceCenter7}, }, @@ -8282,7 +8282,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("MACEY"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Macey), .party = {.NoItemDefaultMoves = sParty_Macey}, }, @@ -8296,7 +8296,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("BRENDAN"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_BrendanRustboroTreecko), .party = {.NoItemDefaultMoves = sParty_BrendanRustboroTreecko}, }, @@ -8310,7 +8310,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("BRENDAN"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_BrendanRustboroMudkip), .party = {.NoItemDefaultMoves = sParty_BrendanRustboroMudkip}, }, @@ -8324,7 +8324,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("PAXTON"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_Paxton), .party = {.NoItemDefaultMoves = sParty_Paxton}, }, @@ -8338,7 +8338,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("ISABELLA"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Isabella), .party = {.NoItemDefaultMoves = sParty_Isabella}, }, @@ -8352,7 +8352,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("GRUNT"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_GruntWeatherInst5), .party = {.NoItemDefaultMoves = sParty_GruntWeatherInst5}, }, @@ -8366,7 +8366,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("TABITHA"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_TabithaMtChimney), .party = {.NoItemDefaultMoves = sParty_TabithaMtChimney}, }, @@ -8380,7 +8380,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("JONATHAN"), .items = {ITEM_HYPER_POTION, ITEM_NONE, ITEM_NONE, ITEM_NONE}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_SETUP_FIRST_TURN, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_SETUP_FIRST_TURN, .partySize = ARRAY_COUNT(sParty_Jonathan), .party = {.NoItemDefaultMoves = sParty_Jonathan}, }, @@ -8394,7 +8394,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("BRENDAN"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_BrendanRustboroTorchic), .party = {.NoItemDefaultMoves = sParty_BrendanRustboroTorchic}, }, @@ -8408,7 +8408,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("MAY"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_SETUP_FIRST_TURN, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_SETUP_FIRST_TURN, .partySize = ARRAY_COUNT(sParty_MayRustboroMudkip), .party = {.NoItemDefaultMoves = sParty_MayRustboroMudkip}, }, @@ -8422,7 +8422,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("MAXIE"), .items = {ITEM_SUPER_POTION, ITEM_SUPER_POTION, ITEM_NONE, ITEM_NONE}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_MaxieMagmaHideout), .party = {.NoItemDefaultMoves = sParty_MaxieMagmaHideout}, }, @@ -8436,7 +8436,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("MAXIE"), .items = {ITEM_SUPER_POTION, ITEM_SUPER_POTION, ITEM_NONE, ITEM_NONE}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_MaxieMtChimney), .party = {.NoItemDefaultMoves = sParty_MaxieMtChimney}, }, @@ -8450,7 +8450,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("TIANA"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Tiana), .party = {.NoItemDefaultMoves = sParty_Tiana}, }, @@ -8464,7 +8464,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("HALEY"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Haley1), .party = {.NoItemDefaultMoves = sParty_Haley1}, }, @@ -8478,7 +8478,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("JANICE"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Janice), .party = {.NoItemDefaultMoves = sParty_Janice}, }, @@ -8492,7 +8492,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("VIVI"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_Vivi), .party = {.NoItemDefaultMoves = sParty_Vivi}, }, @@ -8506,7 +8506,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("HALEY"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Haley2), .party = {.NoItemDefaultMoves = sParty_Haley2}, }, @@ -8520,7 +8520,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("HALEY"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Haley3), .party = {.NoItemDefaultMoves = sParty_Haley3}, }, @@ -8534,7 +8534,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("HALEY"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Haley4), .party = {.NoItemDefaultMoves = sParty_Haley4}, }, @@ -8548,7 +8548,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("HALEY"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Haley5), .party = {.NoItemDefaultMoves = sParty_Haley5}, }, @@ -8562,7 +8562,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("SALLY"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Sally), .party = {.NoItemDefaultMoves = sParty_Sally}, }, @@ -8576,7 +8576,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("ROBIN"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Robin), .party = {.NoItemDefaultMoves = sParty_Robin}, }, @@ -8590,7 +8590,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("ANDREA"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Andrea), .party = {.NoItemDefaultMoves = sParty_Andrea}, }, @@ -8604,7 +8604,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("CRISSY"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Crissy), .party = {.NoItemDefaultMoves = sParty_Crissy}, }, @@ -8618,7 +8618,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("RICK"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Rick), .party = {.NoItemDefaultMoves = sParty_Rick}, }, @@ -8632,7 +8632,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("LYLE"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Lyle), .party = {.NoItemDefaultMoves = sParty_Lyle}, }, @@ -8646,7 +8646,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("JOSE"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Jose), .party = {.NoItemDefaultMoves = sParty_Jose}, }, @@ -8660,7 +8660,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("DOUG"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Doug), .party = {.NoItemDefaultMoves = sParty_Doug}, }, @@ -8674,7 +8674,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("GREG"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Greg), .party = {.NoItemDefaultMoves = sParty_Greg}, }, @@ -8688,7 +8688,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("KENT"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Kent), .party = {.NoItemDefaultMoves = sParty_Kent}, }, @@ -8702,7 +8702,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("JAMES"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_James1), .party = {.NoItemDefaultMoves = sParty_James1}, }, @@ -8716,7 +8716,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("JAMES"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_James2), .party = {.NoItemDefaultMoves = sParty_James2}, }, @@ -8730,7 +8730,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("JAMES"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_James3), .party = {.NoItemDefaultMoves = sParty_James3}, }, @@ -8744,7 +8744,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("JAMES"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_James4), .party = {.NoItemDefaultMoves = sParty_James4}, }, @@ -8758,7 +8758,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("JAMES"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_James5), .party = {.NoItemDefaultMoves = sParty_James5}, }, @@ -8772,7 +8772,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("BRICE"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Brice), .party = {.NoItemDefaultMoves = sParty_Brice}, }, @@ -8786,7 +8786,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("TRENT"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Trent1), .party = {.NoItemDefaultMoves = sParty_Trent1}, }, @@ -8800,7 +8800,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("LENNY"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Lenny), .party = {.NoItemDefaultMoves = sParty_Lenny}, }, @@ -8814,7 +8814,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("LUCAS"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Lucas1), .party = {.NoItemDefaultMoves = sParty_Lucas1}, }, @@ -8828,7 +8828,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("ALAN"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Alan), .party = {.NoItemDefaultMoves = sParty_Alan}, }, @@ -8842,7 +8842,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("CLARK"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Clark), .party = {.NoItemDefaultMoves = sParty_Clark}, }, @@ -8856,7 +8856,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("ERIC"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Eric), .party = {.NoItemDefaultMoves = sParty_Eric}, }, @@ -8870,7 +8870,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("LUCAS"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Lucas2), .party = {.NoItemCustomMoves = sParty_Lucas2}, }, @@ -8884,7 +8884,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("MIKE"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Mike1), .party = {.NoItemCustomMoves = sParty_Mike1}, }, @@ -8898,7 +8898,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("MIKE"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Mike2), .party = {.NoItemDefaultMoves = sParty_Mike2}, }, @@ -8912,7 +8912,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("TRENT"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Trent2), .party = {.NoItemDefaultMoves = sParty_Trent2}, }, @@ -8926,7 +8926,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("TRENT"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Trent3), .party = {.NoItemDefaultMoves = sParty_Trent3}, }, @@ -8940,7 +8940,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("TRENT"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Trent4), .party = {.NoItemDefaultMoves = sParty_Trent4}, }, @@ -8954,7 +8954,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("TRENT"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Trent5), .party = {.NoItemDefaultMoves = sParty_Trent5}, }, @@ -8968,7 +8968,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("DEZ & LUKE"), .items = {}, .doubleBattle = TRUE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_DezAndLuke), .party = {.NoItemDefaultMoves = sParty_DezAndLuke}, }, @@ -8982,7 +8982,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("LEA & JED"), .items = {}, .doubleBattle = TRUE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_LeaAndJed), .party = {.NoItemDefaultMoves = sParty_LeaAndJed}, }, @@ -8996,7 +8996,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("KIRA & DAN"), .items = {}, .doubleBattle = TRUE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_KiraAndDan1), .party = {.NoItemDefaultMoves = sParty_KiraAndDan1}, }, @@ -9010,7 +9010,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("KIRA & DAN"), .items = {}, .doubleBattle = TRUE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_KiraAndDan2), .party = {.NoItemDefaultMoves = sParty_KiraAndDan2}, }, @@ -9024,7 +9024,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("KIRA & DAN"), .items = {}, .doubleBattle = TRUE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_KiraAndDan3), .party = {.NoItemDefaultMoves = sParty_KiraAndDan3}, }, @@ -9038,7 +9038,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("KIRA & DAN"), .items = {}, .doubleBattle = TRUE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_KiraAndDan4), .party = {.NoItemDefaultMoves = sParty_KiraAndDan4}, }, @@ -9052,7 +9052,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("KIRA & DAN"), .items = {}, .doubleBattle = TRUE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_KiraAndDan5), .party = {.NoItemDefaultMoves = sParty_KiraAndDan5}, }, @@ -9066,7 +9066,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("JOHANNA"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Johanna), .party = {.NoItemDefaultMoves = sParty_Johanna}, }, @@ -9080,7 +9080,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("GERALD"), .items = {ITEM_HYPER_POTION, ITEM_NONE, ITEM_NONE, ITEM_NONE}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_Gerald), .party = {.NoItemCustomMoves = sParty_Gerald}, }, @@ -9094,7 +9094,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("VIVIAN"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Vivian), .party = {.NoItemCustomMoves = sParty_Vivian}, }, @@ -9108,7 +9108,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("DANIELLE"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Danielle), .party = {.NoItemCustomMoves = sParty_Danielle}, }, @@ -9122,7 +9122,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("HIDEO"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT, .partySize = ARRAY_COUNT(sParty_Hideo), .party = {.NoItemCustomMoves = sParty_Hideo}, }, @@ -9136,7 +9136,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("KEIGO"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT, .partySize = ARRAY_COUNT(sParty_Keigo), .party = {.NoItemCustomMoves = sParty_Keigo}, }, @@ -9150,7 +9150,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("RILEY"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT, .partySize = ARRAY_COUNT(sParty_Riley), .party = {.NoItemCustomMoves = sParty_Riley}, }, @@ -9164,7 +9164,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("FLINT"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Flint), .party = {.NoItemDefaultMoves = sParty_Flint}, }, @@ -9178,7 +9178,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("ASHLEY"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Ashley), .party = {.NoItemDefaultMoves = sParty_Ashley}, }, @@ -9192,7 +9192,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("WALLY"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_WallyMauville), .party = {.NoItemDefaultMoves = sParty_WallyMauville}, }, @@ -9206,7 +9206,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("WALLY"), .items = {ITEM_FULL_RESTORE, ITEM_FULL_RESTORE, ITEM_NONE, ITEM_NONE}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_WallyVR2), .party = {.NoItemCustomMoves = sParty_WallyVR2}, }, @@ -9220,7 +9220,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("WALLY"), .items = {ITEM_FULL_RESTORE, ITEM_FULL_RESTORE, ITEM_NONE, ITEM_NONE}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_WallyVR3), .party = {.NoItemCustomMoves = sParty_WallyVR3}, }, @@ -9234,7 +9234,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("WALLY"), .items = {ITEM_FULL_RESTORE, ITEM_FULL_RESTORE, ITEM_NONE, ITEM_NONE}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_WallyVR4), .party = {.NoItemCustomMoves = sParty_WallyVR4}, }, @@ -9248,7 +9248,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("WALLY"), .items = {ITEM_FULL_RESTORE, ITEM_FULL_RESTORE, ITEM_NONE, ITEM_NONE}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_WallyVR5), .party = {.NoItemCustomMoves = sParty_WallyVR5}, }, @@ -9262,7 +9262,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("BRENDAN"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_BrendanLilycoveMudkip), .party = {.NoItemDefaultMoves = sParty_BrendanLilycoveMudkip}, }, @@ -9276,7 +9276,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("BRENDAN"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_BrendanLilycoveTreecko), .party = {.NoItemDefaultMoves = sParty_BrendanLilycoveTreecko}, }, @@ -9290,7 +9290,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("BRENDAN"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_BrendanLilycoveTorchic), .party = {.NoItemDefaultMoves = sParty_BrendanLilycoveTorchic}, }, @@ -9304,7 +9304,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("MAY"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_MayLilycoveMudkip), .party = {.NoItemDefaultMoves = sParty_MayLilycoveMudkip}, }, @@ -9318,7 +9318,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("MAY"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_MayLilycoveTreecko), .party = {.NoItemDefaultMoves = sParty_MayLilycoveTreecko}, }, @@ -9332,7 +9332,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("MAY"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_MayLilycoveTorchic), .party = {.NoItemDefaultMoves = sParty_MayLilycoveTorchic}, }, @@ -9346,7 +9346,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("JONAH"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Jonah), .party = {.NoItemDefaultMoves = sParty_Jonah}, }, @@ -9360,7 +9360,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("HENRY"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Henry), .party = {.NoItemDefaultMoves = sParty_Henry}, }, @@ -9374,7 +9374,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("ROGER"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Roger), .party = {.NoItemDefaultMoves = sParty_Roger}, }, @@ -9388,7 +9388,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("ALEXA"), .items = {ITEM_FULL_RESTORE, ITEM_NONE, ITEM_NONE, ITEM_NONE}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_Alexa), .party = {.NoItemDefaultMoves = sParty_Alexa}, }, @@ -9402,7 +9402,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("RUBEN"), .items = {ITEM_HYPER_POTION, ITEM_NONE, ITEM_NONE, ITEM_NONE}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_Ruben), .party = {.NoItemDefaultMoves = sParty_Ruben}, }, @@ -9416,7 +9416,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("KOJI"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Koji1), .party = {.NoItemDefaultMoves = sParty_Koji1}, }, @@ -9430,7 +9430,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("WAYNE"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Wayne), .party = {.NoItemDefaultMoves = sParty_Wayne}, }, @@ -9444,7 +9444,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("AIDAN"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Aidan), .party = {.NoItemDefaultMoves = sParty_Aidan}, }, @@ -9458,7 +9458,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("REED"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Reed), .party = {.NoItemDefaultMoves = sParty_Reed}, }, @@ -9472,7 +9472,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("TISHA"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Tisha), .party = {.NoItemDefaultMoves = sParty_Tisha}, }, @@ -9486,7 +9486,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("TORI & TIA"), .items = {}, .doubleBattle = TRUE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_ToriAndTia), .party = {.NoItemDefaultMoves = sParty_ToriAndTia}, }, @@ -9500,7 +9500,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("KIM & IRIS"), .items = {}, .doubleBattle = TRUE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_KimAndIris), .party = {.NoItemCustomMoves = sParty_KimAndIris}, }, @@ -9514,7 +9514,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("TYRA & IVY"), .items = {}, .doubleBattle = TRUE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_TyraAndIvy), .party = {.NoItemCustomMoves = sParty_TyraAndIvy}, }, @@ -9528,7 +9528,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("MEL & PAUL"), .items = {}, .doubleBattle = TRUE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_MelAndPaul), .party = {.NoItemCustomMoves = sParty_MelAndPaul}, }, @@ -9542,7 +9542,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("JOHN & JAY"), .items = {}, .doubleBattle = TRUE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_JohnAndJay1), .party = {.NoItemCustomMoves = sParty_JohnAndJay1}, }, @@ -9556,7 +9556,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("JOHN & JAY"), .items = {}, .doubleBattle = TRUE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_JohnAndJay2), .party = {.NoItemCustomMoves = sParty_JohnAndJay2}, }, @@ -9570,7 +9570,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("JOHN & JAY"), .items = {}, .doubleBattle = TRUE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_JohnAndJay3), .party = {.NoItemCustomMoves = sParty_JohnAndJay3}, }, @@ -9584,7 +9584,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("JOHN & JAY"), .items = {}, .doubleBattle = TRUE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_SETUP_FIRST_TURN, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_SETUP_FIRST_TURN, .partySize = ARRAY_COUNT(sParty_JohnAndJay4), .party = {.NoItemCustomMoves = sParty_JohnAndJay4}, }, @@ -9598,7 +9598,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("JOHN & JAY"), .items = {}, .doubleBattle = TRUE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_JohnAndJay5), .party = {.NoItemCustomMoves = sParty_JohnAndJay5}, }, @@ -9612,7 +9612,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("RELI & IAN"), .items = {}, .doubleBattle = TRUE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_ReliAndIan), .party = {.NoItemDefaultMoves = sParty_ReliAndIan}, }, @@ -9626,7 +9626,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("LILA & ROY"), .items = {}, .doubleBattle = TRUE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_LilaAndRoy1), .party = {.NoItemDefaultMoves = sParty_LilaAndRoy1}, }, @@ -9640,7 +9640,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("LILA & ROY"), .items = {}, .doubleBattle = TRUE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_LilaAndRoy2), .party = {.NoItemDefaultMoves = sParty_LilaAndRoy2}, }, @@ -9654,7 +9654,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("LILA & ROY"), .items = {}, .doubleBattle = TRUE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_LilaAndRoy3), .party = {.NoItemDefaultMoves = sParty_LilaAndRoy3}, }, @@ -9668,7 +9668,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("LILA & ROY"), .items = {}, .doubleBattle = TRUE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_LilaAndRoy4), .party = {.NoItemDefaultMoves = sParty_LilaAndRoy4}, }, @@ -9682,7 +9682,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("LILA & ROY"), .items = {}, .doubleBattle = TRUE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_LilaAndRoy5), .party = {.NoItemDefaultMoves = sParty_LilaAndRoy5}, }, @@ -9696,7 +9696,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("LISA & RAY"), .items = {}, .doubleBattle = TRUE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_LisaAndRay), .party = {.NoItemDefaultMoves = sParty_LisaAndRay}, }, @@ -9710,7 +9710,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("CHRIS"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Chris), .party = {.NoItemDefaultMoves = sParty_Chris}, }, @@ -9724,7 +9724,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("DAWSON"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Dawson), .party = {.ItemDefaultMoves = sParty_Dawson}, }, @@ -9738,7 +9738,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("SARAH"), .items = {ITEM_FULL_RESTORE, ITEM_NONE, ITEM_NONE, ITEM_NONE}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Sarah), .party = {.ItemDefaultMoves = sParty_Sarah}, }, @@ -9752,7 +9752,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("DARIAN"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Darian), .party = {.NoItemDefaultMoves = sParty_Darian}, }, @@ -9766,7 +9766,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("HAILEY"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Hailey), .party = {.NoItemDefaultMoves = sParty_Hailey}, }, @@ -9780,7 +9780,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("CHANDLER"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Chandler), .party = {.NoItemDefaultMoves = sParty_Chandler}, }, @@ -9794,7 +9794,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("KALEB"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Kaleb), .party = {.ItemDefaultMoves = sParty_Kaleb}, }, @@ -9808,7 +9808,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("JOSEPH"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Joseph), .party = {.NoItemDefaultMoves = sParty_Joseph}, }, @@ -9822,7 +9822,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("ALYSSA"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Alyssa), .party = {.NoItemDefaultMoves = sParty_Alyssa}, }, @@ -9836,7 +9836,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("MARCOS"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Marcos), .party = {.NoItemDefaultMoves = sParty_Marcos}, }, @@ -9850,7 +9850,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("RHETT"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Rhett), .party = {.NoItemDefaultMoves = sParty_Rhett}, }, @@ -9864,7 +9864,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("TYRON"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Tyron), .party = {.NoItemDefaultMoves = sParty_Tyron}, }, @@ -9878,7 +9878,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("CELINA"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Celina), .party = {.NoItemDefaultMoves = sParty_Celina}, }, @@ -9892,7 +9892,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("BIANCA"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Bianca), .party = {.NoItemDefaultMoves = sParty_Bianca}, }, @@ -9906,7 +9906,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("HAYDEN"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Hayden), .party = {.NoItemDefaultMoves = sParty_Hayden}, }, @@ -9920,7 +9920,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("SOPHIE"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Sophie), .party = {.NoItemDefaultMoves = sParty_Sophie}, }, @@ -9934,7 +9934,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("COBY"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Coby), .party = {.NoItemDefaultMoves = sParty_Coby}, }, @@ -9948,7 +9948,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("LAWRENCE"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Lawrence), .party = {.NoItemDefaultMoves = sParty_Lawrence}, }, @@ -9962,7 +9962,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("WYATT"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Wyatt), .party = {.NoItemDefaultMoves = sParty_Wyatt}, }, @@ -9976,7 +9976,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("ANGELINA"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Angelina), .party = {.NoItemDefaultMoves = sParty_Angelina}, }, @@ -9990,7 +9990,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("KAI"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Kai), .party = {.NoItemDefaultMoves = sParty_Kai}, }, @@ -10004,7 +10004,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("CHARLOTTE"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Charlotte), .party = {.NoItemDefaultMoves = sParty_Charlotte}, }, @@ -10018,7 +10018,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("DEANDRE"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Deandre), .party = {.NoItemDefaultMoves = sParty_Deandre}, }, @@ -10032,7 +10032,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("GRUNT"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_GruntMagmaHideout1), .party = {.NoItemDefaultMoves = sParty_GruntMagmaHideout1}, }, @@ -10046,7 +10046,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("GRUNT"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_GruntMagmaHideout2), .party = {.NoItemDefaultMoves = sParty_GruntMagmaHideout2}, }, @@ -10060,7 +10060,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("GRUNT"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_GruntMagmaHideout3), .party = {.NoItemDefaultMoves = sParty_GruntMagmaHideout3}, }, @@ -10074,7 +10074,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("GRUNT"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_GruntMagmaHideout4), .party = {.NoItemDefaultMoves = sParty_GruntMagmaHideout4}, }, @@ -10088,7 +10088,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("GRUNT"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_GruntMagmaHideout5), .party = {.NoItemDefaultMoves = sParty_GruntMagmaHideout5}, }, @@ -10102,7 +10102,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("GRUNT"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_GruntMagmaHideout6), .party = {.NoItemDefaultMoves = sParty_GruntMagmaHideout6}, }, @@ -10116,7 +10116,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("GRUNT"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_GruntMagmaHideout7), .party = {.NoItemDefaultMoves = sParty_GruntMagmaHideout7}, }, @@ -10130,7 +10130,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("GRUNT"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_GruntMagmaHideout8), .party = {.NoItemDefaultMoves = sParty_GruntMagmaHideout8}, }, @@ -10144,7 +10144,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("GRUNT"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_GruntMagmaHideout9), .party = {.NoItemDefaultMoves = sParty_GruntMagmaHideout9}, }, @@ -10158,7 +10158,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("GRUNT"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_GruntMagmaHideout10), .party = {.NoItemDefaultMoves = sParty_GruntMagmaHideout10}, }, @@ -10172,7 +10172,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("GRUNT"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_GruntMagmaHideout11), .party = {.NoItemDefaultMoves = sParty_GruntMagmaHideout11}, }, @@ -10186,7 +10186,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("GRUNT"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_GruntMagmaHideout12), .party = {.NoItemDefaultMoves = sParty_GruntMagmaHideout12}, }, @@ -10200,7 +10200,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("GRUNT"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_GruntMagmaHideout13), .party = {.NoItemDefaultMoves = sParty_GruntMagmaHideout13}, }, @@ -10214,7 +10214,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("GRUNT"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_GruntMagmaHideout14), .party = {.NoItemDefaultMoves = sParty_GruntMagmaHideout14}, }, @@ -10228,7 +10228,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("GRUNT"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_GruntMagmaHideout15), .party = {.NoItemDefaultMoves = sParty_GruntMagmaHideout15}, }, @@ -10242,7 +10242,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("GRUNT"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_GruntMagmaHideout16), .party = {.NoItemDefaultMoves = sParty_GruntMagmaHideout16}, }, @@ -10256,7 +10256,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("TABITHA"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_TabithaMagmaHideout), .party = {.NoItemDefaultMoves = sParty_TabithaMagmaHideout}, }, @@ -10270,7 +10270,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("DARCY"), .items = {ITEM_HYPER_POTION, ITEM_NONE, ITEM_NONE, ITEM_NONE}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_Darcy), .party = {.NoItemDefaultMoves = sParty_Darcy}, }, @@ -10284,7 +10284,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("MAXIE"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_MaxieMossdeep), .party = {.NoItemDefaultMoves = sParty_MaxieMossdeep}, }, @@ -10298,7 +10298,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("PETE"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Pete), .party = {.NoItemDefaultMoves = sParty_Pete}, }, @@ -10312,7 +10312,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("ISABELLE"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Isabelle), .party = {.NoItemDefaultMoves = sParty_Isabelle}, }, @@ -10326,7 +10326,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("ANDRES"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Andres1), .party = {.NoItemDefaultMoves = sParty_Andres1}, }, @@ -10340,7 +10340,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("JOSUE"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Josue), .party = {.NoItemDefaultMoves = sParty_Josue}, }, @@ -10354,7 +10354,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("CAMRON"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Camron), .party = {.NoItemDefaultMoves = sParty_Camron}, }, @@ -10368,7 +10368,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("CORY"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Cory1), .party = {.NoItemDefaultMoves = sParty_Cory1}, }, @@ -10382,7 +10382,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("CAROLINA"), .items = {ITEM_HYPER_POTION, ITEM_NONE, ITEM_NONE, ITEM_NONE}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_Carolina), .party = {.NoItemDefaultMoves = sParty_Carolina}, }, @@ -10396,7 +10396,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("ELIJAH"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Elijah), .party = {.NoItemDefaultMoves = sParty_Elijah}, }, @@ -10410,7 +10410,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("CELIA"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Celia), .party = {.NoItemDefaultMoves = sParty_Celia}, }, @@ -10424,7 +10424,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("BRYAN"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Bryan), .party = {.NoItemDefaultMoves = sParty_Bryan}, }, @@ -10438,7 +10438,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("BRANDEN"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Branden), .party = {.NoItemDefaultMoves = sParty_Branden}, }, @@ -10452,7 +10452,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("BRYANT"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Bryant), .party = {.NoItemDefaultMoves = sParty_Bryant}, }, @@ -10466,7 +10466,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("SHAYLA"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Shayla), .party = {.NoItemDefaultMoves = sParty_Shayla}, }, @@ -10480,7 +10480,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("KYRA"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Kyra), .party = {.NoItemDefaultMoves = sParty_Kyra}, }, @@ -10494,7 +10494,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("JAIDEN"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Jaiden), .party = {.NoItemDefaultMoves = sParty_Jaiden}, }, @@ -10508,7 +10508,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("ALIX"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Alix), .party = {.NoItemDefaultMoves = sParty_Alix}, }, @@ -10522,7 +10522,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("HELENE"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Helene), .party = {.NoItemDefaultMoves = sParty_Helene}, }, @@ -10536,7 +10536,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("MARLENE"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Marlene), .party = {.NoItemDefaultMoves = sParty_Marlene}, }, @@ -10550,7 +10550,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("DEVAN"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Devan), .party = {.NoItemDefaultMoves = sParty_Devan}, }, @@ -10564,7 +10564,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("JOHNSON"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Johnson), .party = {.NoItemDefaultMoves = sParty_Johnson}, }, @@ -10578,7 +10578,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("MELINA"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Melina), .party = {.NoItemDefaultMoves = sParty_Melina}, }, @@ -10592,7 +10592,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("BRANDI"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Brandi), .party = {.NoItemDefaultMoves = sParty_Brandi}, }, @@ -10606,7 +10606,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("AISHA"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Aisha), .party = {.NoItemDefaultMoves = sParty_Aisha}, }, @@ -10620,7 +10620,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("MAKAYLA"), .items = {ITEM_HYPER_POTION, ITEM_NONE, ITEM_NONE, ITEM_NONE}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_Makayla), .party = {.NoItemDefaultMoves = sParty_Makayla}, }, @@ -10634,7 +10634,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("FABIAN"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Fabian), .party = {.NoItemDefaultMoves = sParty_Fabian}, }, @@ -10648,7 +10648,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("DAYTON"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Dayton), .party = {.NoItemDefaultMoves = sParty_Dayton}, }, @@ -10662,7 +10662,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("RACHEL"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Rachel), .party = {.NoItemDefaultMoves = sParty_Rachel}, }, @@ -10676,7 +10676,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("LEONEL"), .items = {ITEM_HYPER_POTION, ITEM_NONE, ITEM_NONE, ITEM_NONE}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_Leonel), .party = {.NoItemCustomMoves = sParty_Leonel}, }, @@ -10690,7 +10690,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("CALLIE"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Callie), .party = {.NoItemDefaultMoves = sParty_Callie}, }, @@ -10704,7 +10704,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("CALE"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Cale), .party = {.NoItemDefaultMoves = sParty_Cale}, }, @@ -10718,7 +10718,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("MYLES"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Myles), .party = {.NoItemDefaultMoves = sParty_Myles}, }, @@ -10732,7 +10732,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("PAT"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Pat), .party = {.NoItemDefaultMoves = sParty_Pat}, }, @@ -10746,7 +10746,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("CRISTIN"), .items = {ITEM_HYPER_POTION, ITEM_NONE, ITEM_NONE, ITEM_NONE}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_Cristin1), .party = {.NoItemDefaultMoves = sParty_Cristin1}, }, @@ -10760,7 +10760,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("MAY"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_MayRustboroTreecko), .party = {.NoItemDefaultMoves = sParty_MayRustboroTreecko}, }, @@ -10774,7 +10774,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("MAY"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_MayRustboroTorchic), .party = {.NoItemDefaultMoves = sParty_MayRustboroTorchic}, }, @@ -10788,7 +10788,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("ROXANNE"), .items = {ITEM_FULL_RESTORE, ITEM_FULL_RESTORE, ITEM_FULL_RESTORE, ITEM_NONE}, .doubleBattle = TRUE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_Roxanne2), .party = {.ItemCustomMoves = sParty_Roxanne2}, }, @@ -10802,7 +10802,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("ROXANNE"), .items = {ITEM_FULL_RESTORE, ITEM_FULL_RESTORE, ITEM_FULL_RESTORE, ITEM_NONE}, .doubleBattle = TRUE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_Roxanne3), .party = {.ItemCustomMoves = sParty_Roxanne3}, }, @@ -10816,7 +10816,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("ROXANNE"), .items = {ITEM_FULL_RESTORE, ITEM_FULL_RESTORE, ITEM_FULL_RESTORE, ITEM_NONE}, .doubleBattle = TRUE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_Roxanne4), .party = {.ItemCustomMoves = sParty_Roxanne4}, }, @@ -10830,7 +10830,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("ROXANNE"), .items = {ITEM_FULL_RESTORE, ITEM_FULL_RESTORE, ITEM_FULL_RESTORE, ITEM_NONE}, .doubleBattle = TRUE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_Roxanne5), .party = {.ItemCustomMoves = sParty_Roxanne5}, }, @@ -10844,7 +10844,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("BRAWLY"), .items = {ITEM_FULL_RESTORE, ITEM_FULL_RESTORE, ITEM_FULL_RESTORE, ITEM_NONE}, .doubleBattle = TRUE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_Brawly2), .party = {.ItemCustomMoves = sParty_Brawly2}, }, @@ -10858,7 +10858,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("BRAWLY"), .items = {ITEM_FULL_RESTORE, ITEM_FULL_RESTORE, ITEM_FULL_RESTORE, ITEM_NONE}, .doubleBattle = TRUE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_Brawly3), .party = {.ItemCustomMoves = sParty_Brawly3}, }, @@ -10872,7 +10872,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("BRAWLY"), .items = {ITEM_FULL_RESTORE, ITEM_FULL_RESTORE, ITEM_FULL_RESTORE, ITEM_NONE}, .doubleBattle = TRUE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_Brawly4), .party = {.ItemCustomMoves = sParty_Brawly4}, }, @@ -10886,7 +10886,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("BRAWLY"), .items = {ITEM_FULL_RESTORE, ITEM_FULL_RESTORE, ITEM_FULL_RESTORE, ITEM_NONE}, .doubleBattle = TRUE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_Brawly5), .party = {.ItemCustomMoves = sParty_Brawly5}, }, @@ -10900,7 +10900,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("WATTSON"), .items = {ITEM_FULL_RESTORE, ITEM_FULL_RESTORE, ITEM_FULL_RESTORE, ITEM_NONE}, .doubleBattle = TRUE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_Wattson2), .party = {.ItemCustomMoves = sParty_Wattson2}, }, @@ -10914,7 +10914,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("WATTSON"), .items = {ITEM_FULL_RESTORE, ITEM_FULL_RESTORE, ITEM_FULL_RESTORE, ITEM_NONE}, .doubleBattle = TRUE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_Wattson3), .party = {.ItemCustomMoves = sParty_Wattson3}, }, @@ -10928,7 +10928,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("WATTSON"), .items = {ITEM_FULL_RESTORE, ITEM_FULL_RESTORE, ITEM_FULL_RESTORE, ITEM_NONE}, .doubleBattle = TRUE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_Wattson4), .party = {.ItemCustomMoves = sParty_Wattson4}, }, @@ -10942,7 +10942,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("WATTSON"), .items = {ITEM_FULL_RESTORE, ITEM_FULL_RESTORE, ITEM_FULL_RESTORE, ITEM_NONE}, .doubleBattle = TRUE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_Wattson5), .party = {.ItemCustomMoves = sParty_Wattson5}, }, @@ -10956,7 +10956,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("FLANNERY"), .items = {ITEM_FULL_RESTORE, ITEM_FULL_RESTORE, ITEM_FULL_RESTORE, ITEM_NONE}, .doubleBattle = TRUE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_Flannery2), .party = {.ItemCustomMoves = sParty_Flannery2}, }, @@ -10970,7 +10970,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("FLANNERY"), .items = {ITEM_FULL_RESTORE, ITEM_FULL_RESTORE, ITEM_FULL_RESTORE, ITEM_NONE}, .doubleBattle = TRUE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_Flannery3), .party = {.ItemCustomMoves = sParty_Flannery3}, }, @@ -10984,7 +10984,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("FLANNERY"), .items = {ITEM_FULL_RESTORE, ITEM_FULL_RESTORE, ITEM_FULL_RESTORE, ITEM_NONE}, .doubleBattle = TRUE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_Flannery4), .party = {.ItemCustomMoves = sParty_Flannery4}, }, @@ -10998,7 +10998,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("FLANNERY"), .items = {ITEM_FULL_RESTORE, ITEM_FULL_RESTORE, ITEM_FULL_RESTORE, ITEM_NONE}, .doubleBattle = TRUE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_Flannery5), .party = {.ItemCustomMoves = sParty_Flannery5}, }, @@ -11012,7 +11012,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("NORMAN"), .items = {ITEM_FULL_RESTORE, ITEM_FULL_RESTORE, ITEM_FULL_RESTORE, ITEM_NONE}, .doubleBattle = TRUE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_Norman2), .party = {.ItemCustomMoves = sParty_Norman2}, }, @@ -11026,7 +11026,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("NORMAN"), .items = {ITEM_FULL_RESTORE, ITEM_FULL_RESTORE, ITEM_FULL_RESTORE, ITEM_NONE}, .doubleBattle = TRUE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_Norman3), .party = {.ItemCustomMoves = sParty_Norman3}, }, @@ -11040,7 +11040,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("NORMAN"), .items = {ITEM_FULL_RESTORE, ITEM_FULL_RESTORE, ITEM_FULL_RESTORE, ITEM_NONE}, .doubleBattle = TRUE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_Norman4), .party = {.ItemCustomMoves = sParty_Norman4}, }, @@ -11054,7 +11054,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("NORMAN"), .items = {ITEM_FULL_RESTORE, ITEM_FULL_RESTORE, ITEM_FULL_RESTORE, ITEM_NONE}, .doubleBattle = TRUE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_Norman5), .party = {.ItemCustomMoves = sParty_Norman5}, }, @@ -11068,7 +11068,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("WINONA"), .items = {ITEM_FULL_RESTORE, ITEM_FULL_RESTORE, ITEM_FULL_RESTORE, ITEM_NONE}, .doubleBattle = TRUE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY | AI_SCRIPT_RISKY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY | AI_FLAG_RISKY, .partySize = ARRAY_COUNT(sParty_Winona2), .party = {.ItemCustomMoves = sParty_Winona2}, }, @@ -11082,7 +11082,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("WINONA"), .items = {ITEM_FULL_RESTORE, ITEM_FULL_RESTORE, ITEM_FULL_RESTORE, ITEM_NONE}, .doubleBattle = TRUE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY | AI_SCRIPT_RISKY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY | AI_FLAG_RISKY, .partySize = ARRAY_COUNT(sParty_Winona3), .party = {.ItemCustomMoves = sParty_Winona3}, }, @@ -11096,7 +11096,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("WINONA"), .items = {ITEM_FULL_RESTORE, ITEM_FULL_RESTORE, ITEM_FULL_RESTORE, ITEM_NONE}, .doubleBattle = TRUE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY | AI_SCRIPT_RISKY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY | AI_FLAG_RISKY, .partySize = ARRAY_COUNT(sParty_Winona4), .party = {.ItemCustomMoves = sParty_Winona4}, }, @@ -11110,7 +11110,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("WINONA"), .items = {ITEM_FULL_RESTORE, ITEM_FULL_RESTORE, ITEM_FULL_RESTORE, ITEM_NONE}, .doubleBattle = TRUE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY | AI_SCRIPT_RISKY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY | AI_FLAG_RISKY, .partySize = ARRAY_COUNT(sParty_Winona5), .party = {.ItemCustomMoves = sParty_Winona5}, }, @@ -11124,7 +11124,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("TATE&LIZA"), .items = {ITEM_FULL_RESTORE, ITEM_FULL_RESTORE, ITEM_FULL_RESTORE, ITEM_NONE}, .doubleBattle = TRUE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_TateAndLiza2), .party = {.ItemCustomMoves = sParty_TateAndLiza2}, }, @@ -11138,7 +11138,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("TATE&LIZA"), .items = {ITEM_FULL_RESTORE, ITEM_FULL_RESTORE, ITEM_FULL_RESTORE, ITEM_NONE}, .doubleBattle = TRUE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_TateAndLiza3), .party = {.ItemCustomMoves = sParty_TateAndLiza3}, }, @@ -11152,7 +11152,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("TATE&LIZA"), .items = {ITEM_FULL_RESTORE, ITEM_FULL_RESTORE, ITEM_FULL_RESTORE, ITEM_NONE}, .doubleBattle = TRUE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_TateAndLiza4), .party = {.ItemCustomMoves = sParty_TateAndLiza4}, }, @@ -11166,7 +11166,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("TATE&LIZA"), .items = {ITEM_FULL_RESTORE, ITEM_FULL_RESTORE, ITEM_FULL_RESTORE, ITEM_NONE}, .doubleBattle = TRUE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_TateAndLiza5), .party = {.ItemCustomMoves = sParty_TateAndLiza5}, }, @@ -11180,7 +11180,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("JUAN"), .items = {ITEM_FULL_RESTORE, ITEM_FULL_RESTORE, ITEM_FULL_RESTORE, ITEM_NONE}, .doubleBattle = TRUE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_Juan2), .party = {.ItemCustomMoves = sParty_Juan2}, }, @@ -11194,7 +11194,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("JUAN"), .items = {ITEM_FULL_RESTORE, ITEM_FULL_RESTORE, ITEM_FULL_RESTORE, ITEM_NONE}, .doubleBattle = TRUE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_Juan3), .party = {.ItemCustomMoves = sParty_Juan3}, }, @@ -11208,7 +11208,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("JUAN"), .items = {ITEM_FULL_RESTORE, ITEM_FULL_RESTORE, ITEM_FULL_RESTORE, ITEM_NONE}, .doubleBattle = TRUE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_Juan4), .party = {.ItemCustomMoves = sParty_Juan4}, }, @@ -11222,7 +11222,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("JUAN"), .items = {ITEM_FULL_RESTORE, ITEM_FULL_RESTORE, ITEM_FULL_RESTORE, ITEM_NONE}, .doubleBattle = TRUE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_Juan5), .party = {.ItemCustomMoves = sParty_Juan5}, }, @@ -11236,7 +11236,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("ANGELO"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_Angelo), .party = {.ItemCustomMoves = sParty_Angelo}, }, @@ -11250,7 +11250,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("DARIUS"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_Darius), .party = {.NoItemDefaultMoves = sParty_Darius}, }, @@ -11264,7 +11264,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("STEVEN"), .items = {ITEM_FULL_RESTORE, ITEM_FULL_RESTORE, ITEM_FULL_RESTORE, ITEM_FULL_RESTORE}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_Steven), .party = {.ItemCustomMoves = sParty_Steven}, }, @@ -11278,7 +11278,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("ANABEL"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_Anabel), .party = {.NoItemDefaultMoves = sParty_Anabel}, }, @@ -11292,7 +11292,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("TUCKER"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_Tucker), .party = {.NoItemDefaultMoves = sParty_Tucker}, }, @@ -11306,7 +11306,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("SPENSER"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_Spenser), .party = {.NoItemDefaultMoves = sParty_Spenser}, }, @@ -11320,7 +11320,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("GRETA"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_Greta), .party = {.NoItemDefaultMoves = sParty_Greta}, }, @@ -11334,7 +11334,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("NOLAND"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_Noland), .party = {.NoItemDefaultMoves = sParty_Noland}, }, @@ -11348,7 +11348,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("LUCY"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_Lucy), .party = {.NoItemDefaultMoves = sParty_Lucy}, }, @@ -11362,7 +11362,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("BRANDON"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_Brandon), .party = {.NoItemDefaultMoves = sParty_Brandon}, }, @@ -11376,7 +11376,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("ANDRES"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Andres2), .party = {.NoItemDefaultMoves = sParty_Andres2}, }, @@ -11390,7 +11390,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("ANDRES"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Andres3), .party = {.NoItemDefaultMoves = sParty_Andres3}, }, @@ -11404,7 +11404,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("ANDRES"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Andres4), .party = {.NoItemDefaultMoves = sParty_Andres4}, }, @@ -11418,7 +11418,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("ANDRES"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Andres5), .party = {.NoItemDefaultMoves = sParty_Andres5}, }, @@ -11432,7 +11432,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("CORY"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Cory2), .party = {.NoItemDefaultMoves = sParty_Cory2}, }, @@ -11446,7 +11446,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("CORY"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Cory3), .party = {.NoItemDefaultMoves = sParty_Cory3}, }, @@ -11460,7 +11460,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("CORY"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Cory4), .party = {.NoItemDefaultMoves = sParty_Cory4}, }, @@ -11474,7 +11474,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("CORY"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Cory5), .party = {.NoItemDefaultMoves = sParty_Cory5}, }, @@ -11488,7 +11488,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("PABLO"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Pablo2), .party = {.NoItemDefaultMoves = sParty_Pablo2}, }, @@ -11502,7 +11502,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("PABLO"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Pablo3), .party = {.NoItemDefaultMoves = sParty_Pablo3}, }, @@ -11516,7 +11516,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("PABLO"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Pablo4), .party = {.NoItemDefaultMoves = sParty_Pablo4}, }, @@ -11530,7 +11530,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("PABLO"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Pablo5), .party = {.NoItemDefaultMoves = sParty_Pablo5}, }, @@ -11544,7 +11544,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("KOJI"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Koji2), .party = {.NoItemDefaultMoves = sParty_Koji2}, }, @@ -11558,7 +11558,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("KOJI"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Koji3), .party = {.NoItemDefaultMoves = sParty_Koji3}, }, @@ -11572,7 +11572,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("KOJI"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Koji4), .party = {.NoItemDefaultMoves = sParty_Koji4}, }, @@ -11586,7 +11586,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("KOJI"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Koji5), .party = {.NoItemDefaultMoves = sParty_Koji5}, }, @@ -11600,7 +11600,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("CRISTIN"), .items = {ITEM_HYPER_POTION, ITEM_NONE, ITEM_NONE, ITEM_NONE}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_Cristin2), .party = {.NoItemDefaultMoves = sParty_Cristin2}, }, @@ -11614,7 +11614,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("CRISTIN"), .items = {ITEM_HYPER_POTION, ITEM_NONE, ITEM_NONE, ITEM_NONE}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_Cristin3), .party = {.NoItemDefaultMoves = sParty_Cristin3}, }, @@ -11628,7 +11628,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("CRISTIN"), .items = {ITEM_HYPER_POTION, ITEM_NONE, ITEM_NONE, ITEM_NONE}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_Cristin4), .party = {.NoItemDefaultMoves = sParty_Cristin4}, }, @@ -11642,7 +11642,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("CRISTIN"), .items = {ITEM_HYPER_POTION, ITEM_NONE, ITEM_NONE, ITEM_NONE}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_Cristin5), .party = {.NoItemDefaultMoves = sParty_Cristin5}, }, @@ -11656,7 +11656,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("FERNANDO"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Fernando2), .party = {.NoItemDefaultMoves = sParty_Fernando2}, }, @@ -11670,7 +11670,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("FERNANDO"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Fernando3), .party = {.NoItemDefaultMoves = sParty_Fernando3}, }, @@ -11684,7 +11684,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("FERNANDO"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Fernando4), .party = {.NoItemDefaultMoves = sParty_Fernando4}, }, @@ -11698,7 +11698,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("FERNANDO"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Fernando5), .party = {.NoItemDefaultMoves = sParty_Fernando5}, }, @@ -11712,7 +11712,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("SAWYER"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_Sawyer2), .party = {.NoItemDefaultMoves = sParty_Sawyer2}, }, @@ -11726,7 +11726,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("SAWYER"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_Sawyer3), .party = {.NoItemDefaultMoves = sParty_Sawyer3}, }, @@ -11740,7 +11740,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("SAWYER"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_Sawyer4), .party = {.NoItemDefaultMoves = sParty_Sawyer4}, }, @@ -11754,7 +11754,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("SAWYER"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY, .partySize = ARRAY_COUNT(sParty_Sawyer5), .party = {.NoItemDefaultMoves = sParty_Sawyer5}, }, @@ -11768,7 +11768,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("GABRIELLE"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Gabrielle2), .party = {.NoItemDefaultMoves = sParty_Gabrielle2}, }, @@ -11782,7 +11782,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("GABRIELLE"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Gabrielle3), .party = {.NoItemDefaultMoves = sParty_Gabrielle3}, }, @@ -11796,7 +11796,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("GABRIELLE"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Gabrielle4), .party = {.NoItemDefaultMoves = sParty_Gabrielle4}, }, @@ -11810,7 +11810,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("GABRIELLE"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Gabrielle5), .party = {.NoItemDefaultMoves = sParty_Gabrielle5}, }, @@ -11824,7 +11824,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("THALIA"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Thalia2), .party = {.NoItemDefaultMoves = sParty_Thalia2}, }, @@ -11838,7 +11838,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("THALIA"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Thalia3), .party = {.NoItemDefaultMoves = sParty_Thalia3}, }, @@ -11852,7 +11852,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("THALIA"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Thalia4), .party = {.NoItemDefaultMoves = sParty_Thalia4}, }, @@ -11866,7 +11866,7 @@ const struct Trainer gTrainers[] = { .trainerName = _("THALIA"), .items = {}, .doubleBattle = FALSE, - .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE, + .aiFlags = AI_FLAG_CHECK_BAD_MOVE, .partySize = ARRAY_COUNT(sParty_Thalia5), .party = {.NoItemDefaultMoves = sParty_Thalia5}, }, diff --git a/src/item.c b/src/item.c index cc9a09ee0..701783927 100644 --- a/src/item.c +++ b/src/item.c @@ -953,3 +953,26 @@ u8 ItemId_GetSecondaryId(u16 itemId) { return gItems[SanitizeItemId(itemId)].secondaryId; } + +bool32 IsPinchBerryItemEffect(u16 holdEffect) +{ + switch (holdEffect) + { + case HOLD_EFFECT_ATTACK_UP: + case HOLD_EFFECT_DEFENSE_UP: + case HOLD_EFFECT_SPEED_UP: + case HOLD_EFFECT_SP_ATTACK_UP: + case HOLD_EFFECT_SP_DEFENSE_UP: + case HOLD_EFFECT_CRITICAL_UP: + case HOLD_EFFECT_RANDOM_STAT_UP: + #ifdef HOLD_EFFECT_CUSTAP_BERRY + case HOLD_EFFECT_CUSTAP_BERRY: + #endif + #ifdef HOLD_EFFECT_MICLE_BERRY + case HOLD_EFFECT_MICLE_BERRY: + #endif + return TRUE; + } + + return FALSE; +} diff --git a/src/pokemon.c b/src/pokemon.c index 6640d6e31..566e117e7 100644 --- a/src/pokemon.c +++ b/src/pokemon.c @@ -4454,7 +4454,7 @@ bool8 PokemonUseItemEffects(struct Pokemon *mon, u16 item, u8 partyIndex, u8 mov if ((itemEffect[i] & ITEM0_X_ATTACK) && gBattleMons[gActiveBattler].statStages[STAT_ATK] < MAX_STAT_STAGE) { - if (B_X_ITEMS_BUFF == GEN_7) + if (B_X_ITEMS_BUFF >= GEN_7) gBattleMons[gActiveBattler].statStages[STAT_ATK] += 2; else gBattleMons[gActiveBattler].statStages[STAT_ATK] += itemEffect[i] & ITEM0_X_ATTACK; @@ -4472,7 +4472,7 @@ bool8 PokemonUseItemEffects(struct Pokemon *mon, u16 item, u8 partyIndex, u8 mov if ((itemEffect[i] & ITEM1_X_DEFEND) && gBattleMons[gActiveBattler].statStages[STAT_DEF] < MAX_STAT_STAGE) { - if (B_X_ITEMS_BUFF == GEN_7) + if (B_X_ITEMS_BUFF >= GEN_7) gBattleMons[gActiveBattler].statStages[STAT_DEF] += 2; else gBattleMons[gActiveBattler].statStages[STAT_DEF] += (itemEffect[i] & ITEM1_X_DEFEND) >> 4; @@ -4485,7 +4485,7 @@ bool8 PokemonUseItemEffects(struct Pokemon *mon, u16 item, u8 partyIndex, u8 mov if ((itemEffect[i] & ITEM1_X_SPEED) && gBattleMons[gActiveBattler].statStages[STAT_SPEED] < MAX_STAT_STAGE) { - if (B_X_ITEMS_BUFF == GEN_7) + if (B_X_ITEMS_BUFF >= GEN_7) gBattleMons[gActiveBattler].statStages[STAT_SPEED] += 2; else gBattleMons[gActiveBattler].statStages[STAT_SPEED] += itemEffect[i] & ITEM1_X_SPEED; @@ -4500,7 +4500,7 @@ bool8 PokemonUseItemEffects(struct Pokemon *mon, u16 item, u8 partyIndex, u8 mov if ((itemEffect[i] & ITEM2_X_ACCURACY) && gBattleMons[gActiveBattler].statStages[STAT_ACC] < MAX_STAT_STAGE) { - if (B_X_ITEMS_BUFF == GEN_7) + if (B_X_ITEMS_BUFF >= GEN_7) gBattleMons[gActiveBattler].statStages[STAT_ACC] += 2; else gBattleMons[gActiveBattler].statStages[STAT_ACC] += (itemEffect[i] & ITEM2_X_ACCURACY) >> 4; @@ -4513,7 +4513,7 @@ bool8 PokemonUseItemEffects(struct Pokemon *mon, u16 item, u8 partyIndex, u8 mov if ((itemEffect[i] & ITEM2_X_SPATK) && gBattleMons[gActiveBattler].statStages[STAT_SPATK] < MAX_STAT_STAGE) { - if (B_X_ITEMS_BUFF == GEN_7) + if (B_X_ITEMS_BUFF >= GEN_7) gBattleMons[gActiveBattler].statStages[STAT_SPATK] += 2; else gBattleMons[gActiveBattler].statStages[STAT_SPATK] += itemEffect[i] & ITEM2_X_SPATK; @@ -4529,7 +4529,7 @@ bool8 PokemonUseItemEffects(struct Pokemon *mon, u16 item, u8 partyIndex, u8 mov if ((itemEffect[i] & ITEM1_X_ATTACK) && gBattleMons[gActiveBattler].statStages[STAT_ATK] < MAX_STAT_STAGE) { - if (B_X_ITEMS_BUFF == GEN_7) + if (B_X_ITEMS_BUFF >= GEN_7) gBattleMons[gActiveBattler].statStages[STAT_ATK] += 2; else gBattleMons[gActiveBattler].statStages[STAT_ATK] += 1; @@ -4542,7 +4542,7 @@ bool8 PokemonUseItemEffects(struct Pokemon *mon, u16 item, u8 partyIndex, u8 mov if ((itemEffect[i] & ITEM1_X_DEFENSE) && gBattleMons[gActiveBattler].statStages[STAT_DEF] < MAX_STAT_STAGE) { - if (B_X_ITEMS_BUFF == GEN_7) + if (B_X_ITEMS_BUFF >= GEN_7) gBattleMons[gActiveBattler].statStages[STAT_DEF] += 2; else gBattleMons[gActiveBattler].statStages[STAT_DEF] += 1; @@ -4555,7 +4555,7 @@ bool8 PokemonUseItemEffects(struct Pokemon *mon, u16 item, u8 partyIndex, u8 mov if ((itemEffect[i] & ITEM1_X_SPEED) && gBattleMons[gActiveBattler].statStages[STAT_SPEED] < MAX_STAT_STAGE) { - if (B_X_ITEMS_BUFF == GEN_7) + if (B_X_ITEMS_BUFF >= GEN_7) gBattleMons[gActiveBattler].statStages[STAT_SPEED] += 2; else gBattleMons[gActiveBattler].statStages[STAT_SPEED] += 1; @@ -4568,7 +4568,7 @@ bool8 PokemonUseItemEffects(struct Pokemon *mon, u16 item, u8 partyIndex, u8 mov if ((itemEffect[i] & ITEM1_X_SPATK) && gBattleMons[gActiveBattler].statStages[STAT_SPATK] < MAX_STAT_STAGE) { - if (B_X_ITEMS_BUFF == GEN_7) + if (B_X_ITEMS_BUFF >= GEN_7) gBattleMons[gActiveBattler].statStages[STAT_SPATK] += 2; else gBattleMons[gActiveBattler].statStages[STAT_SPATK] += 1; @@ -4581,7 +4581,7 @@ bool8 PokemonUseItemEffects(struct Pokemon *mon, u16 item, u8 partyIndex, u8 mov if ((itemEffect[i] & ITEM1_X_SPDEF) && gBattleMons[gActiveBattler].statStages[STAT_SPDEF] < MAX_STAT_STAGE) { - if (B_X_ITEMS_BUFF == GEN_7) + if (B_X_ITEMS_BUFF >= GEN_7) gBattleMons[gActiveBattler].statStages[STAT_SPDEF] += 2; else gBattleMons[gActiveBattler].statStages[STAT_SPDEF] += 1; @@ -4594,7 +4594,7 @@ bool8 PokemonUseItemEffects(struct Pokemon *mon, u16 item, u8 partyIndex, u8 mov if ((itemEffect[i] & ITEM1_X_ACCURACY) && gBattleMons[gActiveBattler].statStages[STAT_ACC] < MAX_STAT_STAGE) { - if (B_X_ITEMS_BUFF == GEN_7) + if (B_X_ITEMS_BUFF >= GEN_7) gBattleMons[gActiveBattler].statStages[STAT_ACC] += 2; else gBattleMons[gActiveBattler].statStages[STAT_ACC] += 1; @@ -5148,7 +5148,7 @@ static void BufferStatRoseMessage(s32 arg0) { gBattlerTarget = gBattlerInMenuId; StringCopy(gBattleTextBuff1, gStatNamesTable[sStatsToRaise[arg0]]); - if (B_X_ITEMS_BUFF == GEN_7) + if (B_X_ITEMS_BUFF >= GEN_7) { StringCopy(gBattleTextBuff2, gText_StatSharply); StringAppend(gBattleTextBuff2, gText_StatRose); diff --git a/src/trainer_hill.c b/src/trainer_hill.c index 059773a0b..de65c218e 100644 --- a/src/trainer_hill.c +++ b/src/trainer_hill.c @@ -897,7 +897,7 @@ void FillHillTrainersParties(void) // hill trainers. u32 GetTrainerHillAIFlags(void) { - return (AI_SCRIPT_CHECK_BAD_MOVE | AI_SCRIPT_TRY_TO_FAINT | AI_SCRIPT_CHECK_VIABILITY); + return (AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY); } u8 GetTrainerEncounterMusicIdInTrainerHill(u16 trainerId) diff --git a/sym_ewram.txt b/sym_ewram.txt index 88c4461cb..59829eff4 100644 --- a/sym_ewram.txt +++ b/sym_ewram.txt @@ -91,7 +91,7 @@ .include "src/region_map.o" .include "src/decoration.o" .include "src/slot_machine.o" - .include "src/battle_ai_script_commands.o" + .include "src/battle_ai_main.o" .include "src/fldeff_misc.o" .include "src/pokeblock.o" .include "src/field_specials.o"