mirror of
https://github.com/2revoemag/PSF-BotServer.git
synced 2026-01-20 02:24:45 +00:00
Degraded Lash Damage (#257)
* formulas to calculate consistent distance between origin and impact; lash damage degrades as a function of distance * clamped the degrade value for lashing damage; clamped the distance value; implemented a rudimentary and unsophisticated shot origin to shot owner distance validation test; fixed a mounting bug * lashing damage is primarily targeted at exo-suit armor; lashing calculates damage starting at the same distance at which it starts being detected * clarifying the weapon fired in the warning message
This commit is contained in:
parent
78eb7906c9
commit
fca14e6b1b
|
|
@ -79,9 +79,10 @@ object MountableBehavior {
|
|||
val dismountBehavior : Receive = {
|
||||
case Mountable.TryDismount(user, seat_num) =>
|
||||
val obj = MountableObject
|
||||
val velocity = obj.Velocity.getOrElse(Vector3.Zero)
|
||||
obj.Seat(seat_num) match {
|
||||
case Some(seat) =>
|
||||
if(seat.Bailable || obj.Velocity.isEmpty || Vector3.MagnitudeSquared(obj.Velocity.get).toInt == 0) {
|
||||
if(seat.Bailable || velocity == Vector3.Zero || Vector3.MagnitudeSquared(velocity).toInt == 0) {
|
||||
seat.Occupant = None
|
||||
user.VehicleSeated = None
|
||||
sender ! Mountable.MountMessages(user, Mountable.CanDismount(obj, seat_num))
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ object InfantrySplashResistance extends ResistanceCalculations[PlayerSource](
|
|||
|
||||
object InfantryLashResistance extends ResistanceCalculations[PlayerSource](
|
||||
ResistanceCalculations.ValidInfantryTarget,
|
||||
ResistanceCalculations.ExoSuitDirectExtractor
|
||||
ResistanceCalculations.MaximumResistance
|
||||
)
|
||||
|
||||
object InfantryAggravatedResistance extends ResistanceCalculations[PlayerSource](
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ object DamageCalculations {
|
|||
//types
|
||||
type DamagesType = (Projectile, Int, Float)=>Int
|
||||
type DamageWithModifiersType = (DamageProfile, List[DamageProfile])=>Int
|
||||
type DistanceType = (ResolvedProjectile)=>Float
|
||||
type DistanceType = ResolvedProjectile=>Float
|
||||
|
||||
//raw damage selectors
|
||||
def NoDamageAgainst(profile : DamageProfile) : Int = 0
|
||||
|
|
@ -70,7 +70,7 @@ object DamageCalculations {
|
|||
* @return the accumulated damage value
|
||||
*/
|
||||
//TODO modifiers come from various sources; expand this part of the calculation model in the future
|
||||
def DamageWithModifiers(extractor : (DamageProfile)=>Int)(base : DamageProfile, modifiers : List[DamageProfile]) : Int = {
|
||||
def DamageWithModifiers(extractor : DamageProfile=>Int)(base : DamageProfile, modifiers : List[DamageProfile]) : Int = {
|
||||
extractor(base) + modifiers.foldLeft(0)(_ + extractor(_))
|
||||
}
|
||||
|
||||
|
|
@ -133,17 +133,18 @@ object DamageCalculations {
|
|||
}
|
||||
|
||||
/**
|
||||
* Calculate a flat lash damage value.
|
||||
* Calculate a lash damage value.
|
||||
* The target needs to be more than five meters away.
|
||||
* Since lash damage occurs after the direct hit projectile's damage begins to degrade,
|
||||
* the minimum of five less than distance or zero is calculated.
|
||||
* @param projectile information about the weapon discharge (itself)
|
||||
* @param rawDamage the accumulated amount of damage
|
||||
* @param distance how far the source was from the target
|
||||
* @return the modified damage value
|
||||
*/
|
||||
def LashDamage(projectile : Projectile, rawDamage : Int, distance : Float) : Int = {
|
||||
val profile = projectile.profile
|
||||
if(distance > 5 || distance <= profile.DistanceMax) {
|
||||
(rawDamage * 0.2f) toInt
|
||||
if(distance > 5) {
|
||||
(DirectHitDamageWithDegrade(projectile, rawDamage, math.max(distance - 5, 0f)) * 0.2f) toInt
|
||||
}
|
||||
else {
|
||||
0
|
||||
|
|
@ -156,10 +157,16 @@ object DamageCalculations {
|
|||
def TooFar(data : ResolvedProjectile) : Float = Float.MaxValue
|
||||
|
||||
def DistanceBetweenTargetandSource(data : ResolvedProjectile) : Float = {
|
||||
Vector3.Distance(data.target.Position, data.projectile.owner.Position)
|
||||
//Vector3.Distance(data.target.Position, data.projectile.owner.Position)
|
||||
DistanceBetweenOriginAndImpact(data)
|
||||
}
|
||||
|
||||
def DistanceFromExplosionToTarget(data : ResolvedProjectile) : Float = {
|
||||
Vector3.Distance(data.target.Position, data.hit_pos)
|
||||
math.max(Vector3.Distance(data.target.Position, data.hit_pos) - 1, 0)
|
||||
//DistanceBetweenOriginAndImpact(data)
|
||||
}
|
||||
|
||||
def DistanceBetweenOriginAndImpact(data : ResolvedProjectile) : Float = {
|
||||
math.max(Vector3.Distance(data.projectile.shot_origin, data.hit_pos) - 0.5f, 0)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,8 +24,8 @@ import scala.util.{Failure, Success, Try}
|
|||
* in essence, should match the type of object container to which these resistances belong;
|
||||
* never has to be defined explicitly, but will be checked upon object definition
|
||||
*/
|
||||
abstract class ResistanceCalculations[TargetType](validate : (ResolvedProjectile)=>Try[TargetType],
|
||||
extractor : (TargetType)=>Int) extends ProjectileCalculations {
|
||||
abstract class ResistanceCalculations[TargetType](validate : ResolvedProjectile=>Try[TargetType],
|
||||
extractor : TargetType=>Int) extends ProjectileCalculations {
|
||||
/**
|
||||
* Get resistance valuess.
|
||||
* @param data the historical `ResolvedProjectile` information
|
||||
|
|
@ -121,4 +121,6 @@ object ResistanceCalculations {
|
|||
def VehicleAggravatedExtractor(target : VehicleSource) : Int = target.Definition.ResistanceAggravated
|
||||
|
||||
def VehicleRadiationExtractor(target : VehicleSource) : Float = target.Definition.RadiationShielding
|
||||
|
||||
def MaximumResistance(target : SourceEntry) : Int = Integer.MAX_VALUE
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4427,16 +4427,24 @@ class WorldSessionActor extends Actor with MDCContextAware {
|
|||
}) {
|
||||
log.trace(s"WeaponFireMessage: overwriting unresolved projectile ${projectile_guid.guid}")
|
||||
}
|
||||
val (angle, attribution) = obj match {
|
||||
val (angle, attribution, acceptableDistanceToOwner) = obj match {
|
||||
case p : Player =>
|
||||
(p.Orientation, tool.Definition.ObjectId) //TODO upper body facing
|
||||
(p.Orientation, tool.Definition.ObjectId, 10f) //TODO upper body facing
|
||||
case v : Vehicle if v.Definition.CanFly =>
|
||||
(tool.Orientation, obj.Definition.ObjectId, 1000f) //TODO this is too simplistic to find proper angle
|
||||
case _ : Vehicle =>
|
||||
(tool.Orientation, obj.Definition.ObjectId) //TODO this is too simplistic to find proper angle
|
||||
(tool.Orientation, obj.Definition.ObjectId, 225f) //TODO this is too simplistic to find proper angle
|
||||
case _ =>
|
||||
(obj.Orientation, obj.Definition.ObjectId)
|
||||
(obj.Orientation, obj.Definition.ObjectId, 300f)
|
||||
}
|
||||
val distanceToOwner = Vector3.DistanceSquared(shot_origin, player.Position)
|
||||
if(distanceToOwner <= acceptableDistanceToOwner) {
|
||||
projectiles(projectileIndex) =
|
||||
Some(Projectile(tool.Projectile, tool.Definition, tool.FireMode, player, attribution, shot_origin, angle))
|
||||
}
|
||||
else {
|
||||
log.warn(s"WeaponFireMessage: $player's ${tool.Definition.Name} projectile is too far from owner position at time of discharge ($distanceToOwner > $acceptableDistanceToOwner); suspect")
|
||||
}
|
||||
projectiles(projectileIndex) =
|
||||
Some(Projectile(tool.Projectile, tool.Definition, tool.FireMode, player, attribution, shot_origin, angle))
|
||||
}
|
||||
case _ => ;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue