mirror of
https://github.com/2revoemag/PSF-BotServer.git
synced 2026-07-12 23:14:42 +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
5 changed files with 36 additions and 18 deletions
|
|
@ -79,9 +79,10 @@ object MountableBehavior {
|
||||||
val dismountBehavior : Receive = {
|
val dismountBehavior : Receive = {
|
||||||
case Mountable.TryDismount(user, seat_num) =>
|
case Mountable.TryDismount(user, seat_num) =>
|
||||||
val obj = MountableObject
|
val obj = MountableObject
|
||||||
|
val velocity = obj.Velocity.getOrElse(Vector3.Zero)
|
||||||
obj.Seat(seat_num) match {
|
obj.Seat(seat_num) match {
|
||||||
case Some(seat) =>
|
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
|
seat.Occupant = None
|
||||||
user.VehicleSeated = None
|
user.VehicleSeated = None
|
||||||
sender ! Mountable.MountMessages(user, Mountable.CanDismount(obj, seat_num))
|
sender ! Mountable.MountMessages(user, Mountable.CanDismount(obj, seat_num))
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ object InfantrySplashResistance extends ResistanceCalculations[PlayerSource](
|
||||||
|
|
||||||
object InfantryLashResistance extends ResistanceCalculations[PlayerSource](
|
object InfantryLashResistance extends ResistanceCalculations[PlayerSource](
|
||||||
ResistanceCalculations.ValidInfantryTarget,
|
ResistanceCalculations.ValidInfantryTarget,
|
||||||
ResistanceCalculations.ExoSuitDirectExtractor
|
ResistanceCalculations.MaximumResistance
|
||||||
)
|
)
|
||||||
|
|
||||||
object InfantryAggravatedResistance extends ResistanceCalculations[PlayerSource](
|
object InfantryAggravatedResistance extends ResistanceCalculations[PlayerSource](
|
||||||
|
|
|
||||||
|
|
@ -46,7 +46,7 @@ object DamageCalculations {
|
||||||
//types
|
//types
|
||||||
type DamagesType = (Projectile, Int, Float)=>Int
|
type DamagesType = (Projectile, Int, Float)=>Int
|
||||||
type DamageWithModifiersType = (DamageProfile, List[DamageProfile])=>Int
|
type DamageWithModifiersType = (DamageProfile, List[DamageProfile])=>Int
|
||||||
type DistanceType = (ResolvedProjectile)=>Float
|
type DistanceType = ResolvedProjectile=>Float
|
||||||
|
|
||||||
//raw damage selectors
|
//raw damage selectors
|
||||||
def NoDamageAgainst(profile : DamageProfile) : Int = 0
|
def NoDamageAgainst(profile : DamageProfile) : Int = 0
|
||||||
|
|
@ -70,7 +70,7 @@ object DamageCalculations {
|
||||||
* @return the accumulated damage value
|
* @return the accumulated damage value
|
||||||
*/
|
*/
|
||||||
//TODO modifiers come from various sources; expand this part of the calculation model in the future
|
//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(_))
|
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.
|
* 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 projectile information about the weapon discharge (itself)
|
||||||
* @param rawDamage the accumulated amount of damage
|
* @param rawDamage the accumulated amount of damage
|
||||||
* @param distance how far the source was from the target
|
* @param distance how far the source was from the target
|
||||||
* @return the modified damage value
|
* @return the modified damage value
|
||||||
*/
|
*/
|
||||||
def LashDamage(projectile : Projectile, rawDamage : Int, distance : Float) : Int = {
|
def LashDamage(projectile : Projectile, rawDamage : Int, distance : Float) : Int = {
|
||||||
val profile = projectile.profile
|
if(distance > 5) {
|
||||||
if(distance > 5 || distance <= profile.DistanceMax) {
|
(DirectHitDamageWithDegrade(projectile, rawDamage, math.max(distance - 5, 0f)) * 0.2f) toInt
|
||||||
(rawDamage * 0.2f) toInt
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
0
|
0
|
||||||
|
|
@ -156,10 +157,16 @@ object DamageCalculations {
|
||||||
def TooFar(data : ResolvedProjectile) : Float = Float.MaxValue
|
def TooFar(data : ResolvedProjectile) : Float = Float.MaxValue
|
||||||
|
|
||||||
def DistanceBetweenTargetandSource(data : ResolvedProjectile) : Float = {
|
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 = {
|
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;
|
* 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
|
* never has to be defined explicitly, but will be checked upon object definition
|
||||||
*/
|
*/
|
||||||
abstract class ResistanceCalculations[TargetType](validate : (ResolvedProjectile)=>Try[TargetType],
|
abstract class ResistanceCalculations[TargetType](validate : ResolvedProjectile=>Try[TargetType],
|
||||||
extractor : (TargetType)=>Int) extends ProjectileCalculations {
|
extractor : TargetType=>Int) extends ProjectileCalculations {
|
||||||
/**
|
/**
|
||||||
* Get resistance valuess.
|
* Get resistance valuess.
|
||||||
* @param data the historical `ResolvedProjectile` information
|
* @param data the historical `ResolvedProjectile` information
|
||||||
|
|
@ -121,4 +121,6 @@ object ResistanceCalculations {
|
||||||
def VehicleAggravatedExtractor(target : VehicleSource) : Int = target.Definition.ResistanceAggravated
|
def VehicleAggravatedExtractor(target : VehicleSource) : Int = target.Definition.ResistanceAggravated
|
||||||
|
|
||||||
def VehicleRadiationExtractor(target : VehicleSource) : Float = target.Definition.RadiationShielding
|
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}")
|
log.trace(s"WeaponFireMessage: overwriting unresolved projectile ${projectile_guid.guid}")
|
||||||
}
|
}
|
||||||
val (angle, attribution) = obj match {
|
val (angle, attribution, acceptableDistanceToOwner) = obj match {
|
||||||
case p : Player =>
|
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 =>
|
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 _ =>
|
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 _ => ;
|
case _ => ;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue