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
|
# 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
|
# it via Fling, will gain the effect of the item even if the Pokémon is
|
||||||
# affected by item-negating effects.
|
# 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.
|
# fling is for Fling only.
|
||||||
def pbHeldItemTriggerCheck(item_to_use = nil, fling = false)
|
def pbHeldItemTriggerCheck(item_to_use = nil, fling = false)
|
||||||
return if fainted?
|
return if fainted?
|
||||||
|
|||||||
@@ -1035,6 +1035,92 @@ class Battle::AI
|
|||||||
return ret
|
return ret
|
||||||
end
|
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
|
# Returns a value indicating how beneficial the given ability will be to the
|
||||||
# given battler if it has it.
|
# 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",
|
Battle::AI::Handlers::MoveFailureAgainstTargetCheck.add("StartTargetCannotUseItem",
|
||||||
proc { |move, user, target, ai, battle|
|
proc { |move, user, target, ai, battle|
|
||||||
next target.effects[PBEffects::Embargo] > 0
|
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.
|
# TODO: Review score modifiers.
|
||||||
@@ -169,7 +177,7 @@ Battle::AI::Handlers::MoveEffectScore.add("StartNegateHeldItems",
|
|||||||
)
|
)
|
||||||
|
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
# TODO: Review score modifiers.
|
#
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
Battle::AI::Handlers::MoveFailureCheck.add("UserConsumeBerryRaiseDefense2",
|
Battle::AI::Handlers::MoveFailureCheck.add("UserConsumeBerryRaiseDefense2",
|
||||||
proc { |move, user, ai, battle|
|
proc { |move, user, ai, battle|
|
||||||
@@ -179,31 +187,28 @@ Battle::AI::Handlers::MoveFailureCheck.add("UserConsumeBerryRaiseDefense2",
|
|||||||
)
|
)
|
||||||
Battle::AI::Handlers::MoveEffectScore.add("UserConsumeBerryRaiseDefense2",
|
Battle::AI::Handlers::MoveEffectScore.add("UserConsumeBerryRaiseDefense2",
|
||||||
proc { |score, move, user, ai, battle|
|
proc { |score, move, user, ai, battle|
|
||||||
if ai.trainer.high_skill?
|
# Score for raising the user's stat
|
||||||
useful_berries = [
|
score = Battle::AI::Handlers.apply_move_effect_score("RaiseUserDefense2",
|
||||||
:ORANBERRY, :SITRUSBERRY, :AGUAVBERRY, :APICOTBERRY, :CHERIBERRY,
|
score, move, user, ai, battle)
|
||||||
:CHESTOBERRY, :FIGYBERRY, :GANLONBERRY, :IAPAPABERRY, :KEEBERRY,
|
# Score for the consumed berry's effect
|
||||||
:LANSATBERRY, :LEPPABERRY, :LIECHIBERRY, :LUMBERRY, :MAGOBERRY,
|
score += ai.get_score_change_for_consuming_item(user, user.item_id)
|
||||||
:MARANGABERRY, :PECHABERRY, :PERSIMBERRY, :PETAYABERRY, :RAWSTBERRY,
|
# Score for other results of consuming the berry
|
||||||
:SALACBERRY, :STARFBERRY, :WIKIBERRY
|
|
||||||
]
|
|
||||||
score += 30 if useful_berries.include?(user.item_id)
|
|
||||||
end
|
|
||||||
if ai.trainer.medium_skill?
|
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
|
||||||
user.has_active_ability?(:CHEEKPOUCH)
|
score += 5 if user.battler.canHeal? && user.hp < user.totalhp / 2 &&
|
||||||
score += 20 if user.has_active_ability?([:HARVEST, :RIPEN]) ||
|
user.has_active_ability?(:CHEEKPOUCH)
|
||||||
user.battler.pbHasMoveFunction?("RestoreUserConsumedItem") # Recycle
|
# Prefer if target can recover the consumed berry
|
||||||
score += 20 if !user.battler.canConsumeBerry?
|
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
|
end
|
||||||
score -= user.stages[:DEFENSE] * 20
|
|
||||||
next score
|
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",
|
Battle::AI::Handlers::MoveFailureAgainstTargetCheck.add("AllBattlersConsumeBerry",
|
||||||
proc { |move, user, target, ai, battle|
|
proc { |move, user, target, ai, battle|
|
||||||
@@ -212,36 +217,20 @@ Battle::AI::Handlers::MoveFailureAgainstTargetCheck.add("AllBattlersConsumeBerry
|
|||||||
)
|
)
|
||||||
Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("AllBattlersConsumeBerry",
|
Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("AllBattlersConsumeBerry",
|
||||||
proc { |score, move, user, target, ai, battle|
|
proc { |score, move, user, target, ai, battle|
|
||||||
useful_berries = [
|
# Score for the consumed berry's effect
|
||||||
:ORANBERRY, :SITRUSBERRY, :AGUAVBERRY, :APICOTBERRY, :CHERIBERRY,
|
score_change = ai.get_score_change_for_consuming_item(target, target.item_id)
|
||||||
:CHESTOBERRY, :FIGYBERRY, :GANLONBERRY, :IAPAPABERRY, :KEEBERRY,
|
# Score for other results of consuming the berry
|
||||||
:LANSATBERRY, :LEPPABERRY, :LIECHIBERRY, :LUMBERRY, :MAGOBERRY,
|
if ai.trainer.medium_skill?
|
||||||
:MARANGABERRY, :PECHABERRY, :PERSIMBERRY, :PETAYABERRY,
|
# Prefer if target will heal itself with Cheek Pouch
|
||||||
:RAWSTBERRY, :SALACBERRY, :STARFBERRY, :WIKIBERRY
|
score_change += 5 if target.battler.canHeal? && target.hp < target.totalhp / 2 &&
|
||||||
]
|
target.has_active_ability?(:CHEEKPOUCH)
|
||||||
battle.allSameSideBattlers(user.index).each do |b|
|
# Prefer if target can recover the consumed berry
|
||||||
if ai.trainer.high_skill?
|
score_change += 8 if target.has_active_ability?(:HARVEST) ||
|
||||||
amt = 30 / battle.pbSideSize(user.index)
|
target.has_move_with_function?("RestoreUserConsumedItem")
|
||||||
score += amt if useful_berries.include?(b.item_id)
|
# Prefer if target couldn't normally consume the berry
|
||||||
end
|
score_change += 4 if !target.battler.canConsumeBerry?
|
||||||
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
|
|
||||||
end
|
end
|
||||||
|
score += (target.opposes?(user)) ? -score_change : score_change
|
||||||
next score
|
next score
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@@ -255,7 +244,15 @@ Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("UserConsumeTargetBerry",
|
|||||||
next score if user.battler.unlosableItem?(target.item)
|
next score if user.battler.unlosableItem?(target.item)
|
||||||
next score if target.effects[PBEffects::Substitute] > 0
|
next score if target.effects[PBEffects::Substitute] > 0
|
||||||
next score if target.has_active_ability?(:STICKYHOLD) && !battle.moldBreaker
|
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_item_preference = ai.battler_wants_item?(target, target.item_id)
|
||||||
target_no_item_preference = ai.battler_wants_item?(target, :NONE)
|
target_no_item_preference = ai.battler_wants_item?(target, :NONE)
|
||||||
score += (target_item_preference - target_no_item_preference) * 4
|
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 = Battle::AI::Handlers.apply_move_effect_against_target_score("FlinchTarget",
|
||||||
score, move, user, target, ai, battle)
|
score, move, user, target, ai, battle)
|
||||||
else
|
else
|
||||||
# TODO: Berries/Berry Juice/Mental Herb/White Herb also have Fling
|
score -= ai.get_score_change_for_consuming_item(target, user.item_id)
|
||||||
# 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
|
|
||||||
end
|
end
|
||||||
# Prefer if the user doesn't want its held item/don't prefer if it wants to
|
# Prefer if the user doesn't want its held item/don't prefer if it wants to
|
||||||
# keep its held item
|
# 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
|
# NOTE: The move that this move will become is determined in def
|
||||||
@@ -455,7 +469,7 @@ Battle::AI::Handlers::MoveFailureAgainstTargetCheck.add("UseLastMoveUsedByTarget
|
|||||||
# UseRandomMove
|
# UseRandomMove
|
||||||
|
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
# TODO: Review score modifiers.
|
#
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
Battle::AI::Handlers::MoveFailureCheck.add("UseRandomMoveFromUserParty",
|
Battle::AI::Handlers::MoveFailureCheck.add("UseRandomMoveFromUserParty",
|
||||||
proc { |move, user, ai, battle|
|
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",
|
Battle::AI::Handlers::MoveFailureCheck.add("FleeFromBattle",
|
||||||
proc { |move, user, ai, battle|
|
proc { |move, user, ai, battle|
|
||||||
next !battle.pbCanRun?(user.index)
|
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.
|
# TODO: Review score modifiers.
|
||||||
@@ -258,32 +264,50 @@ Battle::AI::Handlers::MoveFailureCheck.add("TrapAllBattlersInBattleForOneTurn",
|
|||||||
# PursueSwitchingFoe
|
# PursueSwitchingFoe
|
||||||
|
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
# TODO: Review score modifiers.
|
#
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
Battle::AI::Handlers::MoveEffectScore.add("UsedAfterUserTakesPhysicalDamage",
|
Battle::AI::Handlers::MoveFailureCheck.add("UsedAfterUserTakesPhysicalDamage",
|
||||||
proc { |score, move, user, ai, battle|
|
proc { |move, user, ai, battle|
|
||||||
found_physical_move = false
|
found_physical_move = false
|
||||||
ai.each_foe_battler(user.side) do |b, i|
|
ai.each_foe_battler(user.side) do |b, i|
|
||||||
next if !b.check_for_move { |m| m.physicalMove?(m.type) }
|
next if !b.check_for_move { |m| m.physicalMove?(m.type) }
|
||||||
found_physical_move = true
|
found_physical_move = true
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
next Battle::AI::MOVE_USELESS_SCORE if !found_physical_move
|
next !found_physical_move
|
||||||
next score
|
}
|
||||||
|
)
|
||||||
|
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",
|
Battle::AI::Handlers::MoveEffectScore.add("UsedAfterAllyRoundWithDoublePower",
|
||||||
proc { |score, move, user, ai, battle|
|
proc { |score, move, user, ai, battle|
|
||||||
if ai.trainer.medium_skill?
|
# No score change if no allies know this move
|
||||||
user.battler.allAllies.each do |b|
|
ally_has_move = false
|
||||||
next if !b.pbHasMove?(move.id)
|
ai.each_same_side_battler(user.side) do |b, i|
|
||||||
score += 20
|
next if !b.has_move_with_function?(move.function)
|
||||||
end
|
ally_has_move = true
|
||||||
|
break
|
||||||
end
|
end
|
||||||
|
next score if !ally_has_move
|
||||||
|
# Prefer for the sake of doubling in power
|
||||||
|
score += 5
|
||||||
next score
|
next score
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@@ -297,7 +321,7 @@ Battle::AI::Handlers::MoveEffectScore.add("TargetActsNext",
|
|||||||
next Battle::AI::MOVE_USELESS_SCORE if target.opposes?(user)
|
next Battle::AI::MOVE_USELESS_SCORE if target.opposes?(user)
|
||||||
# Compare the speeds of all battlers
|
# Compare the speeds of all battlers
|
||||||
speeds = []
|
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
|
if battle.field.effects[PBEffects::TrickRoom] > 0
|
||||||
speeds.sort! { |a, b| a[1] <=> b[1] }
|
speeds.sort! { |a, b| a[1] <=> b[1] }
|
||||||
else
|
else
|
||||||
@@ -332,7 +356,7 @@ Battle::AI::Handlers::MoveEffectScore.add("TargetActsLast",
|
|||||||
next Battle::AI::MOVE_USELESS_SCORE if !has_ally
|
next Battle::AI::MOVE_USELESS_SCORE if !has_ally
|
||||||
# Compare the speeds of all battlers
|
# Compare the speeds of all battlers
|
||||||
speeds = []
|
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
|
if battle.field.effects[PBEffects::TrickRoom] > 0
|
||||||
speeds.sort! { |a, b| a[1] <=> b[1] }
|
speeds.sort! { |a, b| a[1] <=> b[1] }
|
||||||
else
|
else
|
||||||
@@ -354,35 +378,77 @@ Battle::AI::Handlers::MoveEffectScore.add("TargetActsLast",
|
|||||||
)
|
)
|
||||||
|
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
# TODO: Review score modifiers.
|
#
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
Battle::AI::Handlers::MoveFailureAgainstTargetCheck.add("TargetUsesItsLastUsedMoveAgain",
|
Battle::AI::Handlers::MoveFailureAgainstTargetCheck.add("TargetUsesItsLastUsedMoveAgain",
|
||||||
proc { |move, user, target, ai, battle|
|
proc { |move, user, target, ai, battle|
|
||||||
next true if !target.battler.lastRegularMoveUsed ||
|
next target.battler.usingMultiTurnAttack?
|
||||||
!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
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("TargetUsesItsLastUsedMoveAgain",
|
Battle::AI::Handlers::MoveEffectAgainstTargetScore.add("TargetUsesItsLastUsedMoveAgain",
|
||||||
proc { |score, move, user, target, ai, battle|
|
proc { |score, move, user, target, ai, battle|
|
||||||
# Without lots of code here to determine good/bad moves and relative
|
# We don't ever want to make a foe act again
|
||||||
# speeds, using this move is likely to just be a waste of a turn
|
next Battle::AI::MOVE_USELESS_SCORE if target.opposes?(user)
|
||||||
next Battle::AI::MOVE_USELESS_SCORE
|
# 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