mirror of
https://github.com/infinitefusion/infinitefusion-e18.git
synced 2025-12-12 23:44:58 +00:00
Waged war against TODO comments in the AI, some refactoring of AI
This commit is contained in:
@@ -1,43 +1,37 @@
|
||||
#===============================================================================
|
||||
#
|
||||
#===============================================================================
|
||||
class Battle::AI
|
||||
#=============================================================================
|
||||
#
|
||||
#=============================================================================
|
||||
# TODO: Reborn has the REVENGEKILLER role which compares mon's speed with
|
||||
# opponent (only when deciding whether to switch mon in) - this
|
||||
# comparison should be calculated when needed instead of being a role.
|
||||
module BattleRole
|
||||
PHAZER = 0
|
||||
CLERIC = 1
|
||||
STALL_BREAKER = 2
|
||||
STATUS_ABSORBER = 3
|
||||
BATON_PASSER = 4
|
||||
SPINNER = 5
|
||||
FIELD_SETTER = 6
|
||||
WEATHER_SETTER = 7
|
||||
SWEEPER = 8
|
||||
PIVOT = 9
|
||||
PHYSICAL_WALL = 10
|
||||
SPECIAL_WALL = 11
|
||||
TANK = 12
|
||||
TRAPPER = 13
|
||||
SCREENER = 14
|
||||
ACE = 15
|
||||
LEAD = 16
|
||||
SECOND = 17
|
||||
end
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
# Determine the roles filled by a Pokémon on a given side at a given party
|
||||
# index.
|
||||
# Roles are:
|
||||
# :ace
|
||||
# :baton_passer
|
||||
# :cleric
|
||||
# :field_setter
|
||||
# :lead
|
||||
# :phazer
|
||||
# :physical_wall
|
||||
# :pivot
|
||||
# :screener
|
||||
# :second
|
||||
# :special_wall
|
||||
# :spinner
|
||||
# :stall_breaker
|
||||
# :status_absorber
|
||||
# :sweeper
|
||||
# :tank
|
||||
# :trapper
|
||||
# :weather_setter
|
||||
# NOTE: Reborn has the REVENGEKILLER role which compares mon's speed with
|
||||
# opponent (only when deciding whether to switch mon in) - this
|
||||
# comparison should be calculated when needed instead of being a role.
|
||||
def determine_roles(side, index)
|
||||
pkmn = @battle.pbParty(side)[index]
|
||||
ret = []
|
||||
return ret if !pkmn || pkmn.egg?
|
||||
|
||||
# Check for moves indicative of particular roles
|
||||
hasHealMove = false
|
||||
hasPivotMove = false
|
||||
hasHealMove = false
|
||||
pkmn.moves.each do |m|
|
||||
next if !m
|
||||
move = Battle::Move.from_pokemon_move(@battle, m)
|
||||
@@ -47,92 +41,87 @@ class Battle::AI
|
||||
"StartPerishCountsForAllBattlers", # Perish Song
|
||||
"SwitchOutTargetStatusMove", # Roar
|
||||
"SwitchOutTargetDamagingMove" # Circle Throw
|
||||
ret.push(BattleRole::PHAZER)
|
||||
ret.push(:phazer)
|
||||
when "CureUserPartyStatus" # Aromatherapy/Heal Bell
|
||||
ret.push(BattleRole::CLERIC)
|
||||
ret.push(:cleric)
|
||||
when "DisableTargetStatusMoves" # Taunt
|
||||
ret.push(BattleRole::STALL_BREAKER)
|
||||
ret.push(:stall_breaker)
|
||||
when "HealUserPositionNextTurn" # Wish
|
||||
ret.push(BattleRole::CLERIC) if pkmn.ev[:HP] == Pokemon::EV_STAT_LIMIT
|
||||
ret.push(:cleric) if pkmn.ev[:HP] == Pokemon::EV_STAT_LIMIT
|
||||
when "HealUserFullyAndFallAsleep" # Rest
|
||||
ret.push(BattleRole::STATUS_ABSORBER)
|
||||
ret.push(:status_absorber)
|
||||
when "SwitchOutUserPassOnEffects" # Baton Pass
|
||||
ret.push(BattleRole::BATON_PASSER)
|
||||
ret.push(:baton_passer)
|
||||
when "SwitchOutUserStatusMove", "SwitchOutUserDamagingMove" # Teleport (Gen 8+), U-turn
|
||||
hasPivotMove = true
|
||||
ret.push(:pivot) if hasHealMove
|
||||
when "RemoveUserBindingAndEntryHazards" # Rapid Spin
|
||||
ret.push(BattleRole::SPINNER)
|
||||
ret.push(:spinner)
|
||||
when "StartElectricTerrain", "StartGrassyTerrain",
|
||||
"StartMistyTerrain", "StartPsychicTerrain" # Terrain moves
|
||||
ret.push(BattleRole::FIELD_SETTER)
|
||||
ret.push(:field_setter)
|
||||
else
|
||||
ret.push(BattleRole::WEATHER_SETTER) if move.is_a?(Battle::Move::WeatherMove)
|
||||
ret.push(:weather_setter) if move.is_a?(Battle::Move::WeatherMove)
|
||||
end
|
||||
end
|
||||
|
||||
# Check EVs, nature and moves for combinations indicative of particular roles
|
||||
if pkmn.ev[:SPEED] == Pokemon::EV_STAT_LIMIT
|
||||
if [:MODEST, :ADAMANT, # SpAtk+ Atk-, Atk+ SpAtk-
|
||||
:TIMID, :JOLLY].include?(pkmn.nature) # Spd+ Atk-, Spd+ SpAtk-
|
||||
ret.push(BattleRole::SWEEPER)
|
||||
ret.push(:sweeper)
|
||||
end
|
||||
end
|
||||
if hasHealMove
|
||||
ret.push(BattleRole::PIVOT) if hasPivotMove
|
||||
if pkmn.nature.stat_changes.any? { |change| change[0] == :DEFENSE && change[1] > 0 } &&
|
||||
!pkmn.nature.stat_changes.any? { |change| change[0] == :DEFENSE && change[1] < 0 }
|
||||
ret.push(BattleRole::PHYSICAL_WALL) if pkmn.ev[:DEFENSE] == Pokemon::EV_STAT_LIMIT
|
||||
ret.push(:physical_wall) if pkmn.ev[:DEFENSE] == Pokemon::EV_STAT_LIMIT
|
||||
elsif pkmn.nature.stat_changes.any? { |change| change[0] == :SPECIAL_DEFENSE && change[1] > 0 } &&
|
||||
!pkmn.nature.stat_changes.any? { |change| change[0] == :SPECIAL_DEFENSE && change[1] < 0 }
|
||||
ret.push(BattleRole::SPECIAL_WALL) if pkmn.ev[:SPECIAL_DEFENSE] == Pokemon::EV_STAT_LIMIT
|
||||
ret.push(:special_wall) if pkmn.ev[:SPECIAL_DEFENSE] == Pokemon::EV_STAT_LIMIT
|
||||
end
|
||||
else
|
||||
ret.push(BattleRole::TANK) if pkmn.ev[:HP] == Pokemon::EV_STAT_LIMIT
|
||||
ret.push(:tank) if pkmn.ev[:HP] == Pokemon::EV_STAT_LIMIT
|
||||
end
|
||||
|
||||
# Check for abilities indicative of particular roles
|
||||
case pkmn.ability_id
|
||||
when :REGENERATOR
|
||||
ret.push(BattleRole::PIVOT)
|
||||
ret.push(:pivot)
|
||||
when :GUTS, :QUICKFEET, :FLAREBOOST, :TOXICBOOST, :NATURALCURE, :MAGICGUARD,
|
||||
:MAGICBOUNCE, :HYDRATION
|
||||
ret.push(BattleRole::STATUS_ABSORBER)
|
||||
ret.push(:status_absorber)
|
||||
when :SHADOWTAG, :ARENATRAP, :MAGNETPULL
|
||||
ret.push(BattleRole::TRAPPER)
|
||||
ret.push(:trapper)
|
||||
when :DROUGHT, :DRIZZLE, :SANDSTREAM, :SNOWWARNING, :PRIMORDIALSEA,
|
||||
:DESOLATELAND, :DELTASTREAM
|
||||
ret.push(BattleRole::WEATHER_SETTER)
|
||||
ret.push(:weather_setter)
|
||||
when :GRASSYSURGE, :ELECTRICSURGE, :MISTYSURGE, :PSYCHICSURGE
|
||||
ret.push(BattleRole::FIELD_SETTER)
|
||||
ret.push(:field_setter)
|
||||
end
|
||||
|
||||
# Check for items indicative of particular roles
|
||||
case pkmn.item_id
|
||||
when :LIGHTCLAY
|
||||
ret.push(BattleRole::SCREENER)
|
||||
ret.push(:screener)
|
||||
when :ASSAULTVEST
|
||||
ret.push(BattleRole::TANK)
|
||||
ret.push(:tank)
|
||||
when :CHOICEBAND, :CHOICESPECS
|
||||
ret.push(BattleRole::STALL_BREAKER)
|
||||
ret.push(BattleRole::SWEEPER) if pkmn.ev[:SPEED] == Pokemon::EV_STAT_LIMIT
|
||||
ret.push(:stall_breaker)
|
||||
ret.push(:sweeper) if pkmn.ev[:SPEED] == Pokemon::EV_STAT_LIMIT
|
||||
when :CHOICESCARF
|
||||
ret.push(BattleRole::SWEEPER) if pkmn.ev[:SPEED] == Pokemon::EV_STAT_LIMIT
|
||||
ret.push(:sweeper) if pkmn.ev[:SPEED] == Pokemon::EV_STAT_LIMIT
|
||||
when :TOXICORB, :FLAMEORB
|
||||
ret.push(BattleRole::STATUS_ABSORBER)
|
||||
ret.push(:status_absorber)
|
||||
when :TERRAINEXTENDER
|
||||
ret.push(BattleRole::FIELD_SETTER)
|
||||
ret.push(:field_setter)
|
||||
end
|
||||
|
||||
# Check for position in team, level relative to other levels in team
|
||||
partyStarts = @battle.pbPartyStarts(side)
|
||||
if partyStarts.include?(index + 1) || index == @battle.pbParty(side).length - 1
|
||||
ret.push(BattleRole::ACE)
|
||||
ret.push(:ace) # Last in party, assumed to be the best Pokémon
|
||||
else
|
||||
ret.push(BattleRole::LEAD) if partyStarts.include?(index)
|
||||
ret.push(:lead) if partyStarts.include?(index) # First in party
|
||||
idxTrainer = @battle.pbGetOwnerIndexFromPartyIndex(side, index)
|
||||
maxLevel = @battle.pbMaxLevelInTeam(side, idxTrainer)
|
||||
if pkmn.level >= maxLevel
|
||||
ret.push(BattleRole::SECOND)
|
||||
ret.push(:second)
|
||||
else
|
||||
secondHighest = true
|
||||
seenHigherLevel = false
|
||||
@@ -146,10 +135,9 @@ class Battle::AI
|
||||
end
|
||||
# NOTE: There can be multiple "second"s if all their levels are equal
|
||||
# and the highest in the team (and none are the ace).
|
||||
ret.push(BattleRole::SECOND) if secondHighest
|
||||
ret.push(:second) if secondHighest
|
||||
end
|
||||
end
|
||||
|
||||
return ret
|
||||
end
|
||||
|
||||
|
||||
Reference in New Issue
Block a user