mirror of
https://github.com/infinitefusion/infinitefusion-e18.git
synced 2025-12-06 06:01:46 +00:00
More AI function code rewrites
This commit is contained in:
@@ -281,7 +281,8 @@ class Battle::Battler
|
||||
# NOTE: A Pokémon using Bug Bite/Pluck, and a Pokémon having an item thrown at
|
||||
# it via Fling, will gain the effect of the item even if the Pokémon is
|
||||
# affected by item-negating effects.
|
||||
# item_to_use is an item ID for Bug Bite/Pluck and Fling, and nil otherwise.
|
||||
# item_to_use is an item ID for Stuff Cheeks, Teatime, Bug Bite/Pluck and
|
||||
# Fling, and nil otherwise.
|
||||
# fling is for Fling only.
|
||||
def pbHeldItemTriggerCheck(item_to_use = nil, fling = false)
|
||||
return if fainted?
|
||||
|
||||
@@ -1035,6 +1035,92 @@ class Battle::AI
|
||||
return ret
|
||||
end
|
||||
|
||||
#=============================================================================
|
||||
# Items can be consumed by Stuff Cheeks, Teatime, Bug Bite/Pluck and Fling.
|
||||
#=============================================================================
|
||||
def get_score_change_for_consuming_item(battler, item)
|
||||
ret = 0
|
||||
case item
|
||||
when :ORANBERRY, :BERRYJUICE, :ENIGMABERRY, :SITRUSBERRY
|
||||
# Healing
|
||||
ret += (battler.hp > battler.totalhp * 3 / 4) ? -8 : 8
|
||||
ret = ret * 3 / 2 if GameData::Item.get(item).is_berry? && battler.has_active_ability?(:RIPEN)
|
||||
when :AGUAVBERRY, :FIGYBERRY, :IAPAPABERRY, :MAGOBERRY, :WIKIBERRY
|
||||
# Healing with confusion
|
||||
fraction_to_heal = 8 # Gens 6 and lower
|
||||
if Settings::MECHANICS_GENERATION == 7
|
||||
fraction_to_heal = 2
|
||||
elsif Settings::MECHANICS_GENERATION >= 8
|
||||
fraction_to_heal = 3
|
||||
end
|
||||
ret += (battler.hp > battler.totalhp * (1 - (1 / fraction_to_heal))) ? -8 : 8
|
||||
ret = ret * 3 / 2 if GameData::Item.get(item).is_berry? && battler.has_active_ability?(:RIPEN)
|
||||
# TODO: Check whether the item will cause confusion?
|
||||
when :ASPEARBERRY, :CHERIBERRY, :CHESTOBERRY, :PECHABERRY, :RAWSTBERRY
|
||||
# Status cure
|
||||
status = {
|
||||
:ASPEAR => :FROZEN,
|
||||
:CHERIBERRY => :PARALYSIS,
|
||||
:CHESTOBERRY => :SLEEP,
|
||||
:PECHABERRY => :POISON,
|
||||
:RAWSTBERRY => :BURN
|
||||
}[item]
|
||||
ret += (status && battler.status == status) ? 8 : -8
|
||||
when :PERSIMBERRY
|
||||
# Confusion cure
|
||||
ret += (battler.effects[PBEffects::Confusion] > 1) ? 8 : -8
|
||||
when :LUMBERRY
|
||||
# Any status/confusion cure
|
||||
ret += (battler.status != :NONE || battler.effects[PBEffects::Confusion] > 1) ? 8 : -8
|
||||
when :MENTALHERB
|
||||
# Cure mental effects
|
||||
ret += 8 if battler.effects[PBEffects::Attract] >= 0 ||
|
||||
battler.effects[PBEffects::Taunt] > 1 ||
|
||||
battler.effects[PBEffects::Encore] > 1 ||
|
||||
battler.effects[PBEffects::Torment] ||
|
||||
battler.effects[PBEffects::Disable] > 1 ||
|
||||
battler.effects[PBEffects::HealBlock] > 1
|
||||
when :APICOTBERRY, :GANLONBERRY, :LIECHIBERRY, :PETAYABERRY, :SALACBERRY,
|
||||
:KEEBERRY, :MARANGABERRY
|
||||
# Stat raise
|
||||
stat = {
|
||||
:APICOTBERRY => :SPECIAL_DEFENSE,
|
||||
:GANLONBERRY => :DEFENSE,
|
||||
:LIECHIBERRY => :ATTACK,
|
||||
:PETAYABERRY => :SPECIAL_ATTACK,
|
||||
:SALACBERRY => :SPEED,
|
||||
:KEEBERRY => :DEFENSE,
|
||||
:MARANGABERRY => :SPECIAL_DEFENSE
|
||||
}[item]
|
||||
ret += 8 if stat && ai.stat_raise_worthwhile?(battler, stat)
|
||||
ret = ret * 3 / 2 if GameData::Item.get(item).is_berry? && battler.has_active_ability?(:RIPEN)
|
||||
when :STARFBERRY
|
||||
# Random stat raise
|
||||
ret += 8
|
||||
ret = ret * 3 / 2 if GameData::Item.get(item).is_berry? && battler.has_active_ability?(:RIPEN)
|
||||
when :WHITEHERB
|
||||
# Resets lowered stats
|
||||
reduced_stats = false
|
||||
GameData::Stat.each_battle do |s|
|
||||
next if battler.stages[s.id] >= 0
|
||||
reduced_stats = true
|
||||
break
|
||||
end
|
||||
ret += 8 if reduced_stats
|
||||
when :MICLEBERRY
|
||||
# Raises accuracy of next move
|
||||
ret += 8
|
||||
when :LANSATBERRY
|
||||
# Focus energy
|
||||
ret += 8 if battler.effects[PBEffects::FocusEnergy] < 2
|
||||
when :LEPPABERRY
|
||||
# Restore PP
|
||||
ret += 8
|
||||
ret = ret * 3 / 2 if GameData::Item.get(item).is_berry? && battler.has_active_ability?(:RIPEN)
|
||||
end
|
||||
return ret
|
||||
end
|
||||
|
||||
#=============================================================================
|
||||
# Returns a value indicating how beneficial the given ability will be to the
|
||||
# given battler if it has it.
|
||||
|
||||
@@ -148,13 +148,21 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("CorrodeTargetItem",
|
||||
)
|
||||
|
||||
#===============================================================================
|
||||
# TODO: Review score modifiers.
|
||||
#
|
||||
#===============================================================================
|
||||
Battle::AI::Handlers::MoveFailureAgainstTargetCheck.add("StartTargetCannotUseItem",
|
||||
proc { |move, user, target, ai, battle|
|
||||
next target.effects[PBEffects::Embargo] > 0
|
||||
}
|
||||
)
|
||||
Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("StartTargetCannotUseItem",
|
||||
proc { |score, move, user, target, ai, battle|
|
||||
next Battle::AI::MOVE_USELESS_SCORE if !target.item || !target.item_active?
|
||||
item_score = ai.battler_wants_item?(target, target.item_id)
|
||||
score += item_score * 5
|
||||
next score
|
||||
}
|
||||
)
|
||||
|
||||
#===============================================================================
|
||||
# TODO: Review score modifiers.
|
||||
@@ -169,7 +177,7 @@ Battle::AI::Handlers::MoveEffectScore.add("StartNegateHeldItems",
|
||||
)
|
||||
|
||||
#===============================================================================
|
||||
# TODO: Review score modifiers.
|
||||
#
|
||||
#===============================================================================
|
||||
Battle::AI::Handlers::MoveFailureCheck.add("UserConsumeBerryRaiseDefense2",
|
||||
proc { |move, user, ai, battle|
|
||||
@@ -179,31 +187,28 @@ Battle::AI::Handlers::MoveFailureCheck.add("UserConsumeBerryRaiseDefense2",
|
||||
)
|
||||
Battle::AI::Handlers::MoveEffectScore.add("UserConsumeBerryRaiseDefense2",
|
||||
proc { |score, move, user, ai, battle|
|
||||
if ai.trainer.high_skill?
|
||||
useful_berries = [
|
||||
:ORANBERRY, :SITRUSBERRY, :AGUAVBERRY, :APICOTBERRY, :CHERIBERRY,
|
||||
:CHESTOBERRY, :FIGYBERRY, :GANLONBERRY, :IAPAPABERRY, :KEEBERRY,
|
||||
:LANSATBERRY, :LEPPABERRY, :LIECHIBERRY, :LUMBERRY, :MAGOBERRY,
|
||||
:MARANGABERRY, :PECHABERRY, :PERSIMBERRY, :PETAYABERRY, :RAWSTBERRY,
|
||||
:SALACBERRY, :STARFBERRY, :WIKIBERRY
|
||||
]
|
||||
score += 30 if useful_berries.include?(user.item_id)
|
||||
end
|
||||
# Score for raising the user's stat
|
||||
score = Battle::AI::Handlers.apply_move_effect_score("RaiseUserDefense2",
|
||||
score, move, user, ai, battle)
|
||||
# Score for the consumed berry's effect
|
||||
score += ai.get_score_change_for_consuming_item(user, user.item_id)
|
||||
# Score for other results of consuming the berry
|
||||
if ai.trainer.medium_skill?
|
||||
score += 20 if user.battler.canHeal? && user.hp < user.totalhp / 3 &&
|
||||
# Prefer if user will heal itself with Cheek Pouch
|
||||
score += 5 if user.battler.canHeal? && user.hp < user.totalhp / 2 &&
|
||||
user.has_active_ability?(:CHEEKPOUCH)
|
||||
score += 20 if user.has_active_ability?([:HARVEST, :RIPEN]) ||
|
||||
user.battler.pbHasMoveFunction?("RestoreUserConsumedItem") # Recycle
|
||||
score += 20 if !user.battler.canConsumeBerry?
|
||||
# Prefer if target can recover the consumed berry
|
||||
score += 8 if user.has_active_ability?(:HARVEST) ||
|
||||
user.has_move_with_function?("RestoreUserConsumedItem")
|
||||
# Prefer if user couldn't normally consume the berry
|
||||
score += 4 if !user.battler.canConsumeBerry?
|
||||
end
|
||||
score -= user.stages[:DEFENSE] * 20
|
||||
next score
|
||||
}
|
||||
)
|
||||
|
||||
#===============================================================================
|
||||
# TODO: Review score modifiers.
|
||||
# TODO: This code should be for a single battler (each is checked in turn).
|
||||
#
|
||||
#===============================================================================
|
||||
Battle::AI::Handlers::MoveFailureAgainstTargetCheck.add("AllBattlersConsumeBerry",
|
||||
proc { |move, user, target, ai, battle|
|
||||
@@ -212,36 +217,20 @@ Battle::AI::Handlers::MoveFailureAgainstTargetCheck.add("AllBattlersConsumeBerry
|
||||
)
|
||||
Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("AllBattlersConsumeBerry",
|
||||
proc { |score, move, user, target, ai, battle|
|
||||
useful_berries = [
|
||||
:ORANBERRY, :SITRUSBERRY, :AGUAVBERRY, :APICOTBERRY, :CHERIBERRY,
|
||||
:CHESTOBERRY, :FIGYBERRY, :GANLONBERRY, :IAPAPABERRY, :KEEBERRY,
|
||||
:LANSATBERRY, :LEPPABERRY, :LIECHIBERRY, :LUMBERRY, :MAGOBERRY,
|
||||
:MARANGABERRY, :PECHABERRY, :PERSIMBERRY, :PETAYABERRY,
|
||||
:RAWSTBERRY, :SALACBERRY, :STARFBERRY, :WIKIBERRY
|
||||
]
|
||||
battle.allSameSideBattlers(user.index).each do |b|
|
||||
if ai.trainer.high_skill?
|
||||
amt = 30 / battle.pbSideSize(user.index)
|
||||
score += amt if useful_berries.include?(b.item_id)
|
||||
end
|
||||
# Score for the consumed berry's effect
|
||||
score_change = ai.get_score_change_for_consuming_item(target, target.item_id)
|
||||
# Score for other results of consuming the berry
|
||||
if ai.trainer.medium_skill?
|
||||
amt = 20 / battle.pbSideSize(user.index)
|
||||
score += amt if b.canHeal? && b.hp < b.totalhp / 3 && b.hasActiveAbility?(:CHEEKPOUCH)
|
||||
score += amt if b.hasActiveAbility?([:HARVEST, :RIPEN]) ||
|
||||
b.pbHasMoveFunction?("RestoreUserConsumedItem") # Recycle
|
||||
score += amt if !b.canConsumeBerry?
|
||||
end
|
||||
end
|
||||
if ai.trainer.high_skill?
|
||||
battle.allOtherSideBattlers(user.index).each do |b|
|
||||
amt = 10 / battle.pbSideSize(target.index)
|
||||
score -= amt if b.hasActiveItem?(useful_berries)
|
||||
score -= amt if b.canHeal? && b.hp < b.totalhp / 3 && b.hasActiveAbility?(:CHEEKPOUCH)
|
||||
score -= amt if b.hasActiveAbility?([:HARVEST, :RIPEN]) ||
|
||||
b.pbHasMoveFunction?("RestoreUserConsumedItem") # Recycle
|
||||
score -= amt if !b.canConsumeBerry?
|
||||
end
|
||||
# Prefer if target will heal itself with Cheek Pouch
|
||||
score_change += 5 if target.battler.canHeal? && target.hp < target.totalhp / 2 &&
|
||||
target.has_active_ability?(:CHEEKPOUCH)
|
||||
# Prefer if target can recover the consumed berry
|
||||
score_change += 8 if target.has_active_ability?(:HARVEST) ||
|
||||
target.has_move_with_function?("RestoreUserConsumedItem")
|
||||
# Prefer if target couldn't normally consume the berry
|
||||
score_change += 4 if !target.battler.canConsumeBerry?
|
||||
end
|
||||
score += (target.opposes?(user)) ? -score_change : score_change
|
||||
next score
|
||||
}
|
||||
)
|
||||
@@ -255,7 +244,15 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("UserConsumeTargetBerry",
|
||||
next score if user.battler.unlosableItem?(target.item)
|
||||
next score if target.effects[PBEffects::Substitute] > 0
|
||||
next score if target.has_active_ability?(:STICKYHOLD) && !battle.moldBreaker
|
||||
# User can consume the target's berry; score it
|
||||
# Score the user gaining the item's effect
|
||||
score += ai.get_score_change_for_consuming_item(user, target.item_id)
|
||||
# Score for other results of consuming the berry
|
||||
if ai.trainer.medium_skill?
|
||||
# Prefer if user will heal itself with Cheek Pouch
|
||||
score += 5 if user.battler.canHeal? && user.hp < user.totalhp / 2 &&
|
||||
user.has_active_ability?(:CHEEKPOUCH)
|
||||
end
|
||||
# Score the target no longer having the item
|
||||
target_item_preference = ai.battler_wants_item?(target, target.item_id)
|
||||
target_no_item_preference = ai.battler_wants_item?(target, :NONE)
|
||||
score += (target_item_preference - target_no_item_preference) * 4
|
||||
@@ -296,16 +293,7 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("ThrowUserItemAtTarget",
|
||||
score = Battle::AI::Handlers.apply_move_effect_against_target_score("FlinchTarget",
|
||||
score, move, user, target, ai, battle)
|
||||
else
|
||||
# TODO: Berries/Berry Juice/Mental Herb/White Herb also have Fling
|
||||
# effects. Should they be accounted for individually, or is it okay
|
||||
# to consider it bad to Fling these in general? Note that they all
|
||||
# do minimal damage so this move probably won't be used anyway.
|
||||
if Battle::ItemEffects::HPHeal[user.item_id] ||
|
||||
Battle::ItemEffects::StatusCure[user.item_id] ||
|
||||
Battle::ItemEffects::OnEndOfUsingMove[user.item_id] ||
|
||||
Battle::ItemEffects::OnEndOfUsingMoveStatRestore[user.item_id]
|
||||
score -= 8
|
||||
end
|
||||
score -= ai.get_score_change_for_consuming_item(target, user.item_id)
|
||||
end
|
||||
# Prefer if the user doesn't want its held item/don't prefer if it wants to
|
||||
# keep its held item
|
||||
|
||||
@@ -439,9 +439,23 @@ Battle::AI::Handlers::MoveFailureAgainstTargetCheck.add("UseLastMoveUsedByTarget
|
||||
)
|
||||
|
||||
#===============================================================================
|
||||
# TODO: Review score modifiers.
|
||||
#
|
||||
#===============================================================================
|
||||
# UseMoveTargetIsAboutToUse
|
||||
Battle::AI::Handlers::MoveFailureAgainstTargetCheck.add("UseMoveTargetIsAboutToUse",
|
||||
proc { |move, user, target, ai, battle|
|
||||
next !target.check_for_move { |m| m.damagingMove? && !move.move.moveBlacklist.include?(m.function_code) }
|
||||
}
|
||||
)
|
||||
Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("UseMoveTargetIsAboutToUse",
|
||||
proc { |score, move, user, target, ai, battle|
|
||||
next Battle::AI::MOVE_USELESS_SCORE if target.faster_than?(user)
|
||||
# Don't prefer if target knows any moves that can't be copied
|
||||
if target.check_for_move { |m| m.statusMove? || move.move.moveBlacklist.include?(m.function_code) }
|
||||
score -= 8
|
||||
end
|
||||
next score
|
||||
}
|
||||
)
|
||||
|
||||
#===============================================================================
|
||||
# NOTE: The move that this move will become is determined in def
|
||||
@@ -455,7 +469,7 @@ Battle::AI::Handlers::MoveFailureAgainstTargetCheck.add("UseLastMoveUsedByTarget
|
||||
# UseRandomMove
|
||||
|
||||
#===============================================================================
|
||||
# TODO: Review score modifiers.
|
||||
#
|
||||
#===============================================================================
|
||||
Battle::AI::Handlers::MoveFailureCheck.add("UseRandomMoveFromUserParty",
|
||||
proc { |move, user, ai, battle|
|
||||
@@ -492,16 +506,47 @@ Battle::AI::Handlers::MoveFailureCheck.add("UseRandomUserMoveIfAsleep",
|
||||
)
|
||||
|
||||
#===============================================================================
|
||||
# TODO: Review score modifiers.
|
||||
# TODO: This code shouldn't make use of target.
|
||||
#
|
||||
#===============================================================================
|
||||
# BounceBackProblemCausingStatusMoves
|
||||
Battle::AI::Handlers::MoveEffectScore.add("BounceBackProblemCausingStatusMoves",
|
||||
proc { |score, move, user, ai, battle|
|
||||
next Battle::AI::MOVE_USELESS_SCORE if user.has_active_ability?(:MAGICBOUNCE)
|
||||
useless = true
|
||||
ai.each_foe_battler(user.side) do |b, i|
|
||||
next if !b.can_attack?
|
||||
next if !b.check_for_move { |m| m.statusMove? && m.canMagicCoat? }
|
||||
score += 4
|
||||
useless = false
|
||||
end
|
||||
next Battle::AI::MOVE_USELESS_SCORE if useless
|
||||
# Don't prefer the lower the user's HP is (better to try something else)
|
||||
if user.hp < user.totalhp / 2
|
||||
score -= 20 * (0.75 - (user.hp.to_f / user.totalhp)) # -5 to -15
|
||||
end
|
||||
next score
|
||||
}
|
||||
)
|
||||
|
||||
#===============================================================================
|
||||
# TODO: Review score modifiers.
|
||||
# TODO: This code shouldn't make use of target.
|
||||
#
|
||||
#===============================================================================
|
||||
# StealAndUseBeneficialStatusMove
|
||||
Battle::AI::Handlers::MoveEffectScore.add("StealAndUseBeneficialStatusMove",
|
||||
proc { |score, move, user, ai, battle|
|
||||
useless = true
|
||||
ai.each_foe_battler(user.side) do |b, i|
|
||||
next if !b.can_attack?
|
||||
next if !b.check_for_move { |m| m.statusMove? && m.canSnatch? }
|
||||
score += 4
|
||||
useless = false
|
||||
end
|
||||
next Battle::AI::MOVE_USELESS_SCORE if useless
|
||||
# Don't prefer the lower the user's HP is (better to try something else)
|
||||
if user.hp < user.totalhp / 2
|
||||
score -= 20 * (0.75 - (user.hp.to_f / user.totalhp)) # -5 to -15
|
||||
end
|
||||
next score
|
||||
}
|
||||
)
|
||||
|
||||
#===============================================================================
|
||||
#
|
||||
|
||||
@@ -1,11 +1,17 @@
|
||||
#===============================================================================
|
||||
# TODO: Review score modifiers.
|
||||
#
|
||||
#===============================================================================
|
||||
Battle::AI::Handlers::MoveFailureCheck.add("FleeFromBattle",
|
||||
proc { |move, user, ai, battle|
|
||||
next !battle.pbCanRun?(user.index)
|
||||
}
|
||||
)
|
||||
Battle::AI::Handlers::MoveEffectScore.add("FleeFromBattle",
|
||||
proc { |score, move, user, ai, battle|
|
||||
# Generally don't prefer (don't want to end the battle too easily)
|
||||
next score - 15
|
||||
}
|
||||
)
|
||||
|
||||
#===============================================================================
|
||||
# TODO: Review score modifiers.
|
||||
@@ -258,32 +264,50 @@ Battle::AI::Handlers::MoveFailureCheck.add("TrapAllBattlersInBattleForOneTurn",
|
||||
# PursueSwitchingFoe
|
||||
|
||||
#===============================================================================
|
||||
# TODO: Review score modifiers.
|
||||
#
|
||||
#===============================================================================
|
||||
Battle::AI::Handlers::MoveEffectScore.add("UsedAfterUserTakesPhysicalDamage",
|
||||
proc { |score, move, user, ai, battle|
|
||||
Battle::AI::Handlers::MoveFailureCheck.add("UsedAfterUserTakesPhysicalDamage",
|
||||
proc { |move, user, ai, battle|
|
||||
found_physical_move = false
|
||||
ai.each_foe_battler(user.side) do |b, i|
|
||||
next if !b.check_for_move { |m| m.physicalMove?(m.type) }
|
||||
found_physical_move = true
|
||||
break
|
||||
end
|
||||
next Battle::AI::MOVE_USELESS_SCORE if !found_physical_move
|
||||
next score
|
||||
next !found_physical_move
|
||||
}
|
||||
)
|
||||
Battle::AI::Handlers::MoveEffectScore.add("UsedAfterUserTakesPhysicalDamage",
|
||||
proc { |score, move, user, ai, battle|
|
||||
next Battle::AI::MOVE_USELESS_SCORE if user.effects[PBEffects::Substitute] > 0
|
||||
# Prefer if foes don't know any special moves
|
||||
found_special_move = false
|
||||
ai.each_foe_battler(user.side) do |b, i|
|
||||
next if !b.check_for_move { |m| m.specialMove?(m.type) }
|
||||
found_special_move = true
|
||||
break
|
||||
end
|
||||
score += 10 if !found_special_move
|
||||
# Generally not worth using
|
||||
next score - 10
|
||||
}
|
||||
)
|
||||
|
||||
#===============================================================================
|
||||
# TODO: Review score modifiers.
|
||||
#
|
||||
#===============================================================================
|
||||
Battle::AI::Handlers::MoveEffectScore.add("UsedAfterAllyRoundWithDoublePower",
|
||||
proc { |score, move, user, ai, battle|
|
||||
if ai.trainer.medium_skill?
|
||||
user.battler.allAllies.each do |b|
|
||||
next if !b.pbHasMove?(move.id)
|
||||
score += 20
|
||||
end
|
||||
# No score change if no allies know this move
|
||||
ally_has_move = false
|
||||
ai.each_same_side_battler(user.side) do |b, i|
|
||||
next if !b.has_move_with_function?(move.function)
|
||||
ally_has_move = true
|
||||
break
|
||||
end
|
||||
next score if !ally_has_move
|
||||
# Prefer for the sake of doubling in power
|
||||
score += 5
|
||||
next score
|
||||
}
|
||||
)
|
||||
@@ -297,7 +321,7 @@ Battle::AI::Handlers::MoveEffectScore.add("TargetActsNext",
|
||||
next Battle::AI::MOVE_USELESS_SCORE if target.opposes?(user)
|
||||
# Compare the speeds of all battlers
|
||||
speeds = []
|
||||
ai.each_battler { |b, i| speeds.push([i, rough_stat(:SPEED)]) }
|
||||
ai.each_battler { |b, i| speeds.push([i, b.rough_stat(:SPEED)]) }
|
||||
if battle.field.effects[PBEffects::TrickRoom] > 0
|
||||
speeds.sort! { |a, b| a[1] <=> b[1] }
|
||||
else
|
||||
@@ -332,7 +356,7 @@ Battle::AI::Handlers::MoveEffectScore.add("TargetActsLast",
|
||||
next Battle::AI::MOVE_USELESS_SCORE if !has_ally
|
||||
# Compare the speeds of all battlers
|
||||
speeds = []
|
||||
ai.each_battler { |b, i| speeds.push([i, rough_stat(:SPEED)]) }
|
||||
ai.each_battler { |b, i| speeds.push([i, b.rough_stat(:SPEED)]) }
|
||||
if battle.field.effects[PBEffects::TrickRoom] > 0
|
||||
speeds.sort! { |a, b| a[1] <=> b[1] }
|
||||
else
|
||||
@@ -354,35 +378,77 @@ Battle::AI::Handlers::MoveEffectScore.add("TargetActsLast",
|
||||
)
|
||||
|
||||
#===============================================================================
|
||||
# TODO: Review score modifiers.
|
||||
#
|
||||
#===============================================================================
|
||||
Battle::AI::Handlers::MoveFailureAgainstTargetCheck.add("TargetUsesItsLastUsedMoveAgain",
|
||||
proc { |move, user, target, ai, battle|
|
||||
next true if !target.battler.lastRegularMoveUsed ||
|
||||
!target.battler.pbHasMove?(target.battler.lastRegularMoveUsed)
|
||||
next true if target.battler.usingMultiTurnAttack?
|
||||
next true if move.move.moveBlacklist.include?(GameData::Move.get(target.battler.lastRegularMoveUsed).function_code)
|
||||
idxMove = -1
|
||||
target.battler.eachMoveWithIndex do |m, i|
|
||||
idxMove = i if m.id == target.battler.lastRegularMoveUsed
|
||||
end
|
||||
next true if target.battler.moves[idxMove].pp == 0 && target.battler.moves[idxMove].total_pp > 0
|
||||
next false
|
||||
next target.battler.usingMultiTurnAttack?
|
||||
}
|
||||
)
|
||||
Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("TargetUsesItsLastUsedMoveAgain",
|
||||
proc { |score, move, user, target, ai, battle|
|
||||
# Without lots of code here to determine good/bad moves and relative
|
||||
# speeds, using this move is likely to just be a waste of a turn
|
||||
next Battle::AI::MOVE_USELESS_SCORE
|
||||
# We don't ever want to make a foe act again
|
||||
next Battle::AI::MOVE_USELESS_SCORE if target.opposes?(user)
|
||||
# Useless if target will act before the user, as we don't know what move
|
||||
# will be instructed
|
||||
next Battle::AI::MOVE_USELESS_SCORE if target.faster_than?(user)
|
||||
next Battle::AI::MOVE_USELESS_SCORE if !target.battler.lastRegularMoveUsed
|
||||
mov = nil
|
||||
target.battler.eachMove do |m|
|
||||
mov = m if m.id == target.battler.lastRegularMoveUsed
|
||||
break if mov
|
||||
end
|
||||
next Battle::AI::MOVE_USELESS_SCORE if mov.nil? || (mov.pp == 0 && mov.total_pp > 0)
|
||||
next Battle::AI::MOVE_USELESS_SCORE if move.move.moveBlacklist.include?(mov.function)
|
||||
# Without lots of code here to determine good/bad moves, using this move is
|
||||
# likely to just be a waste of a turn
|
||||
# NOTE: Because this move can be used against a foe but is being used on an
|
||||
# ally (since we're here in this code), this move's score will be
|
||||
# inverted later. A higher score here means this move will be less
|
||||
# preferred, which is the result we want.
|
||||
score += 20
|
||||
next score
|
||||
}
|
||||
)
|
||||
|
||||
#===============================================================================
|
||||
# TODO: Review score modifiers.
|
||||
# TODO: This code shouldn't make use of target.
|
||||
#
|
||||
#===============================================================================
|
||||
# StartSlowerBattlersActFirst
|
||||
Battle::AI::Handlers::MoveEffectScore.add("StartSlowerBattlersActFirst",
|
||||
proc { |score, move, user, ai, battle|
|
||||
# Get the speeds of all battlers
|
||||
ally_speeds = []
|
||||
foe_speeds = []
|
||||
ai.each_battler do |b, i|
|
||||
if b.opposes?(user)
|
||||
foe_speeds.push(rough_stat(:SPEED))
|
||||
foe_speeds.last *= 2 if user.pbOpposingSide.effects[PBEffects::Tailwind] > 1
|
||||
foe_speeds.last /= 2 if user.pbOpposingSide.effects[PBEffects::Swamp] > 1
|
||||
else
|
||||
ally_speeds.push(rough_stat(:SPEED))
|
||||
ally_speeds.last *= 2 if user.pbOwnSide.effects[PBEffects::Tailwind] > 1
|
||||
ally_speeds.last /= 2 if user.pbOwnSide.effects[PBEffects::Swamp] > 1
|
||||
end
|
||||
end
|
||||
# Just in case a side has no battlers
|
||||
next Battle::AI::MOVE_USELESS_SCORE if ally_speeds.length == 0 || foe_speeds.length == 0
|
||||
# Invert the speeds if Trick Room applies (and will last longer than this round)
|
||||
if battle.field.effects[PBEffects::TrickRoom] > 1
|
||||
foe_speeds.map! { |val| 100_000 - val } # 100_000 is higher than speed can
|
||||
ally_speeds.map! { |val| 100_000 - val } # possibly be; only order matters
|
||||
end
|
||||
# Score based on the relative speeds
|
||||
next Battle::AI::MOVE_USELESS_SCORE if ally_speeds.min > foe_speeds.max
|
||||
if foe_speeds.min > ally_speeds.max
|
||||
score += 20
|
||||
elsif ally_speeds.sum / ally_speeds.length < foe_speeds.sum / foe_speeds.length
|
||||
score += 10
|
||||
else
|
||||
score -= 10
|
||||
end
|
||||
next score
|
||||
}
|
||||
)
|
||||
|
||||
#===============================================================================
|
||||
#
|
||||
|
||||
Reference in New Issue
Block a user