mirror of
https://github.com/infinitefusion/infinitefusion-e18.git
synced 2025-12-07 21:24:59 +00:00
Rewrote AI calculations for move effects relating to healing the user, added calculation to add predicted damage to a move's score
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
#===============================================================================
|
#===============================================================================
|
||||||
# TODO: Review score modifiers.
|
#
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
Battle::AI::Handlers::MoveFailureCheck.add("HealUserFullyAndFallAsleep",
|
Battle::AI::Handlers::MoveFailureCheck.add("HealUserFullyAndFallAsleep",
|
||||||
proc { |move, user, target, ai, battle|
|
proc { |move, user, target, ai, battle|
|
||||||
@@ -10,15 +10,28 @@ Battle::AI::Handlers::MoveFailureCheck.add("HealUserFullyAndFallAsleep",
|
|||||||
)
|
)
|
||||||
Battle::AI::Handlers::MoveEffectScore.add("HealUserFullyAndFallAsleep",
|
Battle::AI::Handlers::MoveEffectScore.add("HealUserFullyAndFallAsleep",
|
||||||
proc { |score, move, user, target, ai, battle|
|
proc { |score, move, user, target, ai, battle|
|
||||||
score += 70
|
# Consider how much HP will be restored
|
||||||
score -= user.hp * 140 / user.totalhp
|
if user.hp >= user.totalhp * 0.5
|
||||||
score += 30 if user.status != :NONE
|
score -= 10
|
||||||
|
else
|
||||||
|
score += 20 * (user.totalhp - user.hp) / user.totalhp
|
||||||
|
end
|
||||||
|
# Check whether an existing status problem will be removed
|
||||||
|
score += 10 if user.status != :NONE
|
||||||
|
# Check if user will be able to act while asleep
|
||||||
|
if ai.trainer.medium_skill?
|
||||||
|
if user.check_for_move { |move| move.usableWhenAsleep? }
|
||||||
|
score += 10
|
||||||
|
else
|
||||||
|
score -= 10
|
||||||
|
end
|
||||||
|
end
|
||||||
next score
|
next score
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
# TODO: Review score modifiers.
|
#
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
Battle::AI::Handlers::MoveFailureCheck.add("HealUserHalfOfTotalHP",
|
Battle::AI::Handlers::MoveFailureCheck.add("HealUserHalfOfTotalHP",
|
||||||
proc { |move, user, target, ai, battle|
|
proc { |move, user, target, ai, battle|
|
||||||
@@ -27,61 +40,82 @@ Battle::AI::Handlers::MoveFailureCheck.add("HealUserHalfOfTotalHP",
|
|||||||
)
|
)
|
||||||
Battle::AI::Handlers::MoveEffectScore.add("HealUserHalfOfTotalHP",
|
Battle::AI::Handlers::MoveEffectScore.add("HealUserHalfOfTotalHP",
|
||||||
proc { |score, move, user, target, ai, battle|
|
proc { |score, move, user, target, ai, battle|
|
||||||
score += 50
|
# Consider how much HP will be restored
|
||||||
score -= user.hp * 100 / user.totalhp
|
if user.hp >= user.totalhp * 0.5
|
||||||
|
score -= 10
|
||||||
|
else
|
||||||
|
score += 20 * (user.totalhp - user.hp) / user.totalhp
|
||||||
|
end
|
||||||
next score
|
next score
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
# TODO: Review score modifiers.
|
#
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
Battle::AI::Handlers::MoveFailureCheck.copy("HealUserHalfOfTotalHP",
|
Battle::AI::Handlers::MoveFailureCheck.copy("HealUserHalfOfTotalHP",
|
||||||
"HealUserDependingOnWeather")
|
"HealUserDependingOnWeather")
|
||||||
Battle::AI::Handlers::MoveEffectScore.add("HealUserDependingOnWeather",
|
Battle::AI::Handlers::MoveEffectScore.add("HealUserDependingOnWeather",
|
||||||
proc { |score, move, user, target, ai, battle|
|
proc { |score, move, user, target, ai, battle|
|
||||||
case user.battler.effectiveWeather
|
# Consider how much HP will be restored
|
||||||
when :Sun, :HarshSun
|
if user.hp >= user.totalhp * 0.5
|
||||||
score += 30
|
score -= 10
|
||||||
when :None
|
|
||||||
else
|
else
|
||||||
score -= 30
|
case user.battler.effectiveWeather
|
||||||
|
when :Sun, :HarshSun
|
||||||
|
score += 5
|
||||||
|
when :None, :StrongWinds
|
||||||
|
else
|
||||||
|
score -= 10
|
||||||
|
end
|
||||||
|
score += 20 * (user.totalhp - user.hp) / user.totalhp
|
||||||
end
|
end
|
||||||
score += 50
|
|
||||||
score -= user.hp * 100 / user.totalhp
|
|
||||||
next score
|
next score
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
# TODO: Review score modifiers.
|
#
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
Battle::AI::Handlers::MoveFailureCheck.copy("HealUserHalfOfTotalHP",
|
Battle::AI::Handlers::MoveFailureCheck.copy("HealUserHalfOfTotalHP",
|
||||||
"HealUserDependingOnSandstorm")
|
"HealUserDependingOnSandstorm")
|
||||||
Battle::AI::Handlers::MoveEffectScore.add("HealUserDependingOnSandstorm",
|
Battle::AI::Handlers::MoveEffectScore.add("HealUserDependingOnSandstorm",
|
||||||
proc { |score, move, user, target, ai, battle|
|
proc { |score, move, user, target, ai, battle|
|
||||||
score += 50
|
# Consider how much HP will be restored
|
||||||
score -= user.hp * 100 / user.totalhp
|
if user.hp >= user.totalhp * 0.5
|
||||||
score += 30 if user.battler.effectiveWeather == :Sandstorm
|
score -= 10
|
||||||
|
else
|
||||||
|
score += 5 if user.battler.effectiveWeather == :Sandstorm
|
||||||
|
score += 20 * (user.totalhp - user.hp) / user.totalhp
|
||||||
|
end
|
||||||
next score
|
next score
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
# TODO: Review score modifiers.
|
#
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
Battle::AI::Handlers::MoveFailureCheck.copy("HealUserHalfOfTotalHP",
|
Battle::AI::Handlers::MoveFailureCheck.copy("HealUserHalfOfTotalHP",
|
||||||
"HealUserHalfOfTotalHPLoseFlyingTypeThisTurn")
|
"HealUserHalfOfTotalHPLoseFlyingTypeThisTurn")
|
||||||
Battle::AI::Handlers::MoveEffectScore.add("HealUserHalfOfTotalHPLoseFlyingTypeThisTurn",
|
Battle::AI::Handlers::MoveEffectScore.add("HealUserHalfOfTotalHPLoseFlyingTypeThisTurn",
|
||||||
proc { |score, move, user, target, ai, battle|
|
proc { |score, move, user, target, ai, battle|
|
||||||
score += 50
|
# Consider how much HP will be restored
|
||||||
score -= user.hp * 100 / user.totalhp
|
if user.hp >= user.totalhp * 0.5
|
||||||
|
score -= 10
|
||||||
|
else
|
||||||
|
score += 20 * (user.totalhp - user.hp) / user.totalhp
|
||||||
|
end
|
||||||
|
if user.has_type?(:FLYING)
|
||||||
|
# TODO: Decide whether losing the Flying type is good or bad. Look at
|
||||||
|
# type effectiveness changes against the user, and for foes' Ground
|
||||||
|
# moves. Anything else?
|
||||||
|
end
|
||||||
next score
|
next score
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
# TODO: Review score modifiers.
|
#
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
Battle::AI::Handlers::MoveFailureCheck.add("CureTargetStatusHealUserHalfOfTotalHP",
|
Battle::AI::Handlers::MoveFailureCheck.add("CureTargetStatusHealUserHalfOfTotalHP",
|
||||||
proc { |move, user, target, ai, battle|
|
proc { |move, user, target, ai, battle|
|
||||||
@@ -91,14 +125,25 @@ Battle::AI::Handlers::MoveFailureCheck.add("CureTargetStatusHealUserHalfOfTotalH
|
|||||||
)
|
)
|
||||||
Battle::AI::Handlers::MoveEffectScore.add("CureTargetStatusHealUserHalfOfTotalHP",
|
Battle::AI::Handlers::MoveEffectScore.add("CureTargetStatusHealUserHalfOfTotalHP",
|
||||||
proc { |score, move, user, target, ai, battle|
|
proc { |score, move, user, target, ai, battle|
|
||||||
score += (user.totalhp - user.hp) * 50 / user.totalhp
|
# TODO: Add high level checks for whether the target wants to lose their
|
||||||
score -= 30 if target.opposes?(user)
|
# status problem, and change the score accordingly.
|
||||||
|
if target.opposes?(user)
|
||||||
|
score -= 10
|
||||||
|
else
|
||||||
|
score += 15
|
||||||
|
end
|
||||||
|
# Consider how much HP will be restored
|
||||||
|
if user.hp >= user.totalhp * 0.5
|
||||||
|
score -= 10
|
||||||
|
else
|
||||||
|
score += 20 * (user.totalhp - user.hp) / user.totalhp
|
||||||
|
end
|
||||||
next score
|
next score
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
# TODO: Review score modifiers.
|
#
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
Battle::AI::Handlers::MoveFailureCheck.add("HealUserByTargetAttackLowerTargetAttack1",
|
Battle::AI::Handlers::MoveFailureCheck.add("HealUserByTargetAttackLowerTargetAttack1",
|
||||||
proc { |move, user, target, ai, battle|
|
proc { |move, user, target, ai, battle|
|
||||||
@@ -111,69 +156,87 @@ Battle::AI::Handlers::MoveFailureCheck.add("HealUserByTargetAttackLowerTargetAtt
|
|||||||
)
|
)
|
||||||
Battle::AI::Handlers::MoveEffectScore.add("HealUserByTargetAttackLowerTargetAttack1",
|
Battle::AI::Handlers::MoveEffectScore.add("HealUserByTargetAttackLowerTargetAttack1",
|
||||||
proc { |score, move, user, target, ai, battle|
|
proc { |score, move, user, target, ai, battle|
|
||||||
if target.battler.pbCanLowerStatStage?(:ATTACK, user.battler)
|
# Check whether lowering the target's Attack will have any impact
|
||||||
score += target.stages[:ATTACK] * 20
|
if ai.trainer.medium_skill?
|
||||||
if ai.trainer.medium_skill?
|
if target.battler.pbCanLowerStatStage?(:ATTACK, user.battler, move.move) &&
|
||||||
hasPhysicalAttack = false
|
target.check_for_move { |move| move.physicalMove?(move.type) }
|
||||||
target.battler.eachMove do |m|
|
score += target.stages[:ATTACK] * 10
|
||||||
next if !m.physicalMove?(m.type)
|
|
||||||
hasPhysicalAttack = true
|
|
||||||
break
|
|
||||||
end
|
|
||||||
if hasPhysicalAttack
|
|
||||||
score += 20
|
|
||||||
elsif ai.trainer.high_skill?
|
|
||||||
score -= 90
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
score += (user.totalhp - user.hp) * 50 / user.totalhp
|
# Consider how much HP will be restored
|
||||||
|
heal_amt = target.rough_stat(:ATTACK)
|
||||||
|
if heal_amt > user.totalhp * 0.3 # Only modify the score if it'll heal a decent amount
|
||||||
|
# Things that affect healing caused by draining
|
||||||
|
if target.has_active_ability?(:LIQUIDOOZE)
|
||||||
|
score -= 20
|
||||||
|
elsif user.battler.canHeal?
|
||||||
|
if user.hp >= user.totalhp * 0.5
|
||||||
|
score -= 10
|
||||||
|
else
|
||||||
|
heal_amt *= 1.3 if user.has_active_item?(:BIGROOT)
|
||||||
|
heal_fraction = [user.totalhp - user.hp, heal_amt].min.to_f / user.totalhp
|
||||||
|
score += 40 * heal_fraction * (user.totalhp - user.hp) / user.totalhp
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
score -= 10 if target.has_active_ability?(:LIQUIDOOZE)
|
||||||
|
end
|
||||||
next score
|
next score
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
# TODO: Review score modifiers.
|
#
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
Battle::AI::Handlers::MoveEffectScore.add("HealUserByHalfOfDamageDone",
|
Battle::AI::Handlers::MoveEffectScore.add("HealUserByHalfOfDamageDone",
|
||||||
proc { |score, move, user, target, ai, battle|
|
proc { |score, move, user, target, ai, battle|
|
||||||
if target.has_active_ability?(:LIQUIDOOZE)
|
# Consider how much HP will be restored
|
||||||
score -= 70
|
heal_amt = move.rough_damage / 2
|
||||||
elsif user.hp <= user.totalhp / 2
|
if heal_amt > user.totalhp * 0.3 # Only modify the score if it'll heal a decent amount
|
||||||
score += 20
|
# Things that affect healing caused by draining
|
||||||
|
if target.has_active_ability?(:LIQUIDOOZE)
|
||||||
|
score -= 20
|
||||||
|
elsif user.battler.canHeal?
|
||||||
|
heal_amt *= 1.3 if user.has_active_item?(:BIGROOT)
|
||||||
|
heal_fraction = [user.totalhp - user.hp, heal_amt].min.to_f / user.totalhp
|
||||||
|
score += 40 * heal_fraction * (user.totalhp - user.hp) / user.totalhp
|
||||||
|
end
|
||||||
|
else
|
||||||
|
score -= 10 if target.has_active_ability?(:LIQUIDOOZE)
|
||||||
end
|
end
|
||||||
next score
|
next score
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
# TODO: Review score modifiers.
|
#
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
Battle::AI::Handlers::MoveFailureCheck.add("HealUserByHalfOfDamageDoneIfTargetAsleep",
|
Battle::AI::Handlers::MoveFailureCheck.add("HealUserByHalfOfDamageDoneIfTargetAsleep",
|
||||||
proc { |move, user, target, ai, battle|
|
proc { |move, user, target, ai, battle|
|
||||||
next true if !target.battler.asleep?
|
next true if !target.battler.asleep?
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
Battle::AI::Handlers::MoveEffectScore.add("HealUserByHalfOfDamageDoneIfTargetAsleep",
|
Battle::AI::Handlers::MoveEffectScore.copy("HealUserByHalfOfDamageDone",
|
||||||
proc { |score, move, user, target, ai, battle|
|
"HealUserByHalfOfDamageDoneIfTargetAsleep")
|
||||||
if target.has_active_ability?(:LIQUIDOOZE)
|
|
||||||
score -= 70
|
|
||||||
elsif user.hp <= user.totalhp / 2
|
|
||||||
score += 20
|
|
||||||
end
|
|
||||||
next score
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
# TODO: Review score modifiers.
|
#
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
Battle::AI::Handlers::MoveEffectScore.add("HealUserByThreeQuartersOfDamageDone",
|
Battle::AI::Handlers::MoveEffectScore.add("HealUserByThreeQuartersOfDamageDone",
|
||||||
proc { |score, move, user, target, ai, battle|
|
proc { |score, move, user, target, ai, battle|
|
||||||
if target.has_active_ability?(:LIQUIDOOZE)
|
# Consider how much HP will be restored
|
||||||
score -= 80
|
heal_amt = move.rough_damage * 0.75
|
||||||
elsif user.hp <= user.totalhp / 2
|
if heal_amt > user.totalhp * 0.3 # Only modify the score if it'll heal a decent amount
|
||||||
score += 40
|
# Things that affect healing caused by draining
|
||||||
|
if target.has_active_ability?(:LIQUIDOOZE)
|
||||||
|
score -= 20
|
||||||
|
elsif user.battler.canHeal?
|
||||||
|
heal_amt *= 1.3 if user.has_active_item?(:BIGROOT)
|
||||||
|
heal_fraction = [user.totalhp - user.hp, heal_amt].min.to_f / user.totalhp
|
||||||
|
score += 40 * heal_fraction * (user.totalhp - user.hp) / user.totalhp
|
||||||
|
end
|
||||||
|
else
|
||||||
|
score -= 10 if target.has_active_ability?(:LIQUIDOOZE)
|
||||||
end
|
end
|
||||||
next score
|
next score
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -258,14 +258,19 @@ Battle::AI::Handlers::GeneralMoveScore.add(:flinching_effects,
|
|||||||
# Adjust score based on how much damage it can deal.
|
# Adjust score based on how much damage it can deal.
|
||||||
# TODO: Review score modifier.
|
# TODO: Review score modifier.
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
# Battle::AI::Handlers::GeneralMoveScore.add(:add_predicted_damage,
|
Battle::AI::Handlers::GeneralMoveScore.add(:add_predicted_damage,
|
||||||
# proc { |score, move, user, target, ai, battle|
|
proc { |score, move, user, target, ai, battle|
|
||||||
# if move.damagingMove?
|
if move.damagingMove?
|
||||||
# dmg = move.rough_damage
|
dmg = move.rough_damage
|
||||||
# next score + [30.0 * dmg / target.hp, 40].min
|
score += [15.0 * dmg / target.hp, 20].min
|
||||||
# else # Status moves
|
score += 10 if dmg > target.hp * 1.1 # Predicted to KO the target
|
||||||
# # Don't prefer attacks which don't deal damage
|
next score
|
||||||
# next score - 10
|
end
|
||||||
# end
|
}
|
||||||
# }
|
)
|
||||||
# )
|
|
||||||
|
#===============================================================================
|
||||||
|
# TODO: Review score modifier.
|
||||||
|
#===============================================================================
|
||||||
|
# TODO: Prefer a damaging move if it's predicted to KO the target. Maybe include
|
||||||
|
# EOR damage in the prediction?
|
||||||
|
|||||||
@@ -57,6 +57,18 @@ class Battle::AI::AIBattler
|
|||||||
|
|
||||||
#=============================================================================
|
#=============================================================================
|
||||||
|
|
||||||
|
def check_for_move
|
||||||
|
ret = false
|
||||||
|
@battler.eachMove do |move|
|
||||||
|
next unless yield move
|
||||||
|
ret = true
|
||||||
|
break
|
||||||
|
end
|
||||||
|
return ret
|
||||||
|
end
|
||||||
|
|
||||||
|
#=============================================================================
|
||||||
|
|
||||||
def speed; return @battler.speed; end
|
def speed; return @battler.speed; end
|
||||||
|
|
||||||
# TODO: Cache calculated rough stats? Forget them in def refresh_battler.
|
# TODO: Cache calculated rough stats? Forget them in def refresh_battler.
|
||||||
|
|||||||
Reference in New Issue
Block a user