mirror of
https://github.com/2revoemag/PSF-BotServer.git
synced 2026-01-20 02:24:45 +00:00
modifiers for flak burst (#579)
This commit is contained in:
parent
d67119b255
commit
d70d23deb8
|
|
@ -2356,7 +2356,11 @@ object GlobalDefinitions {
|
|||
burster_projectile.InitialVelocity = 125
|
||||
burster_projectile.Lifespan = 4f
|
||||
ProjectileDefinition.CalculateDerivedFields(burster_projectile)
|
||||
//TODO burster_projectile.Modifiers = DamageModifiers.RadialDegrade?
|
||||
burster_projectile.Modifiers = List(
|
||||
//DamageModifiers.FlakHit,
|
||||
DamageModifiers.FlakBurst,
|
||||
DamageModifiers.MaxDistanceCutoff
|
||||
)
|
||||
|
||||
chainblade_projectile.Name = "chainblade_projectile"
|
||||
// TODO for later, maybe : set_resource_parent chainblade_projectile game_objects melee_ammo_projectile
|
||||
|
|
@ -2396,7 +2400,11 @@ object GlobalDefinitions {
|
|||
colossus_burster_projectile.InitialVelocity = 175
|
||||
colossus_burster_projectile.Lifespan = 2.5f
|
||||
ProjectileDefinition.CalculateDerivedFields(colossus_burster_projectile)
|
||||
//TODO colossus_burster_projectile.Modifiers = DamageModifiers.RadialDegrade?
|
||||
colossus_burster_projectile.Modifiers = List(
|
||||
//DamageModifiers.FlakHit,
|
||||
DamageModifiers.FlakBurst,
|
||||
DamageModifiers.MaxDistanceCutoff
|
||||
)
|
||||
|
||||
colossus_chaingun_projectile.Name = "colossus_chaingun_projectile"
|
||||
// TODO for later, maybe : set_resource_parent colossus_chaingun_projectile game_objects 35mmbullet_projectile
|
||||
|
|
@ -3448,7 +3456,11 @@ object GlobalDefinitions {
|
|||
phalanx_flak_projectile.InitialVelocity = 100
|
||||
phalanx_flak_projectile.Lifespan = 5f
|
||||
ProjectileDefinition.CalculateDerivedFields(phalanx_flak_projectile)
|
||||
//TODO phalanx_flak_projectile.Modifiers = DamageModifiers.RadialDegrade?
|
||||
phalanx_flak_projectile.Modifiers = List(
|
||||
//DamageModifiers.FlakHit,
|
||||
DamageModifiers.FlakBurst,
|
||||
DamageModifiers.MaxDistanceCutoff
|
||||
)
|
||||
|
||||
phalanx_projectile.Name = "phalanx_projectile"
|
||||
phalanx_projectile.Damage0 = 20
|
||||
|
|
@ -3747,7 +3759,11 @@ object GlobalDefinitions {
|
|||
rocklet_flak_projectile.InitialVelocity = 60
|
||||
rocklet_flak_projectile.Lifespan = 3.2f
|
||||
ProjectileDefinition.CalculateDerivedFields(rocklet_flak_projectile)
|
||||
//TODO rocklet_flak_projectile.Modifiers = DamageModifiers.RadialDegrade?
|
||||
rocklet_flak_projectile.Modifiers = List(
|
||||
//DamageModifiers.FlakHit,
|
||||
DamageModifiers.FlakBurst,
|
||||
DamageModifiers.MaxDistanceCutoff
|
||||
)
|
||||
|
||||
rocklet_jammer_projectile.Name = "rocklet_jammer_projectile"
|
||||
rocklet_jammer_projectile.Damage0 = 0
|
||||
|
|
@ -3826,7 +3842,11 @@ object GlobalDefinitions {
|
|||
skyguard_flak_cannon_projectile.InitialVelocity = 100
|
||||
skyguard_flak_cannon_projectile.Lifespan = 5f
|
||||
ProjectileDefinition.CalculateDerivedFields(skyguard_flak_cannon_projectile)
|
||||
//TODO skyguard_flak_cannon_projectile.Modifiers = DamageModifiers.RadialDegrade?
|
||||
skyguard_flak_cannon_projectile.Modifiers = List(
|
||||
//DamageModifiers.FlakHit,
|
||||
DamageModifiers.FlakBurst,
|
||||
DamageModifiers.MaxDistanceCutoff
|
||||
)
|
||||
|
||||
sparrow_projectile.Name = "sparrow_projectile"
|
||||
sparrow_projectile.Damage0 = 35
|
||||
|
|
@ -3894,7 +3914,11 @@ object GlobalDefinitions {
|
|||
spitfire_aa_ammo_projectile.InitialVelocity = 100
|
||||
spitfire_aa_ammo_projectile.Lifespan = 5f
|
||||
ProjectileDefinition.CalculateDerivedFields(spitfire_aa_ammo_projectile)
|
||||
//TODO spitfire_aa_ammo_projectile.Modifiers = DamageModifiers.RadialDegrade?
|
||||
spitfire_aa_ammo_projectile.Modifiers = List(
|
||||
//DamageModifiers.FlakHit,
|
||||
DamageModifiers.FlakBurst,
|
||||
DamageModifiers.MaxDistanceCutoff
|
||||
)
|
||||
|
||||
spitfire_ammo_projectile.Name = "spitfire_ammo_projectile"
|
||||
spitfire_ammo_projectile.Damage0 = 15
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@ object DamageModifiers {
|
|||
private def function(damage: Int, data: ResolvedProjectile): Int = damage
|
||||
}
|
||||
|
||||
/** If the calculated distance is greater than the maximum distance of the projectile, damage is zero'd. */
|
||||
case object MaxDistanceCutoff extends Mod {
|
||||
def Calculate: DamageModifiers.Format = function
|
||||
|
||||
|
|
@ -62,6 +63,21 @@ object DamageModifiers {
|
|||
}
|
||||
}
|
||||
|
||||
/** If the calculated distance is greater than a custom distance, damage is zero'd. */
|
||||
case class CustomDistanceCutoff(cutoff: Float) extends Mod {
|
||||
def Calculate: DamageModifiers.Format = function
|
||||
|
||||
private def function(damage: Int, data: ResolvedProjectile): Int = {
|
||||
val projectile = data.projectile
|
||||
val distance = Vector3.Distance(data.hit_pos, projectile.shot_origin)
|
||||
if (distance <= cutoff) {
|
||||
damage
|
||||
} else {
|
||||
0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The input value degrades (lessens)
|
||||
* the further the distance between the point of origin (`shot_origin`)
|
||||
|
|
@ -70,22 +86,7 @@ object DamageModifiers {
|
|||
* If the value is encountered beyond its maximum distance, the value is zero'd.
|
||||
*/
|
||||
case object DistanceDegrade extends Mod {
|
||||
def Calculate: DamageModifiers.Format = function
|
||||
|
||||
private def function(damage: Int, data: ResolvedProjectile): Int = {
|
||||
val projectile = data.projectile
|
||||
val profile = projectile.profile
|
||||
val distance = Vector3.Distance(data.hit_pos, projectile.shot_origin)
|
||||
if (distance <= profile.DistanceMax) {
|
||||
if (profile.DistanceNoDegrade == profile.DistanceMax || distance <= profile.DistanceNoDegrade) {
|
||||
damage
|
||||
} else {
|
||||
damage - ((damage - profile.DegradeMultiplier * damage) * ((distance - profile.DistanceNoDegrade) / (profile.DistanceMax - profile.DistanceNoDegrade))).toInt
|
||||
}
|
||||
} else {
|
||||
0
|
||||
}
|
||||
}
|
||||
def Calculate: DamageModifiers.Format = distanceDegradeFunction
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -95,24 +96,7 @@ object DamageModifiers {
|
|||
* If the value is encountered beyond its maximum radial distance, the value is zero'd.
|
||||
*/
|
||||
case object RadialDegrade extends Mod {
|
||||
def Calculate: DamageModifiers.Format = function
|
||||
|
||||
private def function(damage: Int, data: ResolvedProjectile): Int = {
|
||||
val profile = data.projectile.profile
|
||||
val distance = Vector3.Distance(data.hit_pos, data.target.Position)
|
||||
val radius = profile.DamageRadius
|
||||
val radiusMin = profile.DamageRadiusMin
|
||||
if (distance <= radiusMin) {
|
||||
damage
|
||||
} else if (distance <= radius) {
|
||||
//damage - (damage * profile.DamageAtEdge * (distance - radiusMin) / (radius - radiusMin)).toInt
|
||||
val base = profile.DamageAtEdge
|
||||
val radi = radius - radiusMin
|
||||
(damage * ((1 - base) * ((radi - (distance - radiusMin)) / radi) + base)).toInt
|
||||
} else {
|
||||
0
|
||||
}
|
||||
}
|
||||
def Calculate: DamageModifiers.Format = radialDegradeFunction
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -139,7 +123,7 @@ object DamageModifiers {
|
|||
}
|
||||
|
||||
/*
|
||||
Below this point are the calculations for sources of aggravated damage.
|
||||
Aggravated damage.
|
||||
For the most part, these calculations are individualistic and arbitrary.
|
||||
They exist in their current form to satisfy observed shots to kill (STK) of specific weapon systems
|
||||
according to 2012 standards of the Youtube video series by TheLegendaryNarwhal.
|
||||
|
|
@ -150,7 +134,7 @@ object DamageModifiers {
|
|||
*/
|
||||
case object InfantryAggravatedDirect extends Mod {
|
||||
def Calculate: DamageModifiers.Format =
|
||||
BaseAggravatedFormula(ProjectileResolution.AggravatedDirect, DamageType.Direct)
|
||||
baseAggravatedFormula(ProjectileResolution.AggravatedDirect, DamageType.Direct)
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -159,7 +143,7 @@ object DamageModifiers {
|
|||
*/
|
||||
case object InfantryAggravatedSplash extends Mod {
|
||||
def Calculate: DamageModifiers.Format =
|
||||
BaseAggravatedFormula(ProjectileResolution.AggravatedSplash, DamageType.Splash)
|
||||
baseAggravatedFormula(ProjectileResolution.AggravatedSplash, DamageType.Splash)
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -169,7 +153,7 @@ object DamageModifiers {
|
|||
*/
|
||||
case object InfantryAggravatedDirectBurn extends Mod {
|
||||
def Calculate: DamageModifiers.Format =
|
||||
BaseAggravatedBurnFormula(ProjectileResolution.AggravatedDirectBurn, DamageType.Direct)
|
||||
baseAggravatedBurnFormula(ProjectileResolution.AggravatedDirectBurn, DamageType.Direct)
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -179,110 +163,7 @@ object DamageModifiers {
|
|||
*/
|
||||
case object InfantryAggravatedSplashBurn extends Mod {
|
||||
def Calculate: DamageModifiers.Format =
|
||||
BaseAggravatedBurnFormula(ProjectileResolution.AggravatedSplashBurn, DamageType.Splash)
|
||||
}
|
||||
|
||||
/**
|
||||
* For damage application that involves aggravation of a particular damage type,
|
||||
* calculate that initial damage application for infantry targets
|
||||
* and produce the modified damage value.
|
||||
* Infantry wearing mechanized assault exo-suits (MAX) incorporate an additional modifier.
|
||||
* @see `AggravatedDamage`
|
||||
* @see `ExoSuitType`
|
||||
* @see `InfantryAggravatedDirect`
|
||||
* @see `InfantryAggravatedSplash`
|
||||
* @see `PlayerSource`
|
||||
* @see `ProjectileTarget.AggravatesTarget`
|
||||
* @see `ResolvedProjectile`
|
||||
* @param resolution the projectile resolution to match against
|
||||
* @param damageType the damage type to find in as a component of aggravated information
|
||||
* @param damage the base damage value
|
||||
* @param data historical information related to the damage interaction
|
||||
* @return the modified damage
|
||||
*/
|
||||
private def BaseAggravatedFormula(
|
||||
resolution: ProjectileResolution.Value,
|
||||
damageType : DamageType.Value
|
||||
)
|
||||
(
|
||||
damage: Int,
|
||||
data: ResolvedProjectile
|
||||
): Int = {
|
||||
if (data.resolution == resolution &&
|
||||
data.projectile.quality == ProjectileQuality.AggravatesTarget) {
|
||||
(data.projectile.profile.Aggravated, data.target) match {
|
||||
case (Some(aggravation), p: PlayerSource) =>
|
||||
val aggravatedDamage = aggravation.info.find(_.damage_type == damageType) match {
|
||||
case Some(infos) =>
|
||||
damage * infos.degradation_percentage + damage
|
||||
case _ =>
|
||||
damage toFloat
|
||||
}
|
||||
if(p.ExoSuit == ExoSuitType.MAX) {
|
||||
(aggravatedDamage * aggravation.max_factor) toInt
|
||||
} else {
|
||||
aggravatedDamage toInt
|
||||
}
|
||||
case _ =>
|
||||
damage
|
||||
}
|
||||
} else {
|
||||
damage
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* For damage application that involves aggravation of a particular damage type,
|
||||
* calculate that damage application burn for each tick for infantry targets
|
||||
* and produce the modified damage value.
|
||||
* Infantry wearing mechanized assault exo-suits (MAX) incorporate an additional modifier.
|
||||
* Vanilla infantry incorporate their resistance value into a slightly different calculation than usual.
|
||||
* @see `AggravatedDamage`
|
||||
* @see `ExoSuitType`
|
||||
* @see `InfantryAggravatedDirectBurn`
|
||||
* @see `InfantryAggravatedSplashBurn`
|
||||
* @see `PlayerSource`
|
||||
* @see `ResolvedProjectile`
|
||||
* @param resolution the projectile resolution to match against
|
||||
* @param damageType the damage type to find in as a component of aggravated information
|
||||
* @param damage the base damage value
|
||||
* @param data historical information related to the damage interaction
|
||||
* @return the modified damage
|
||||
*/
|
||||
private def BaseAggravatedBurnFormula(
|
||||
resolution: ProjectileResolution.Value,
|
||||
damageType : DamageType.Value
|
||||
)
|
||||
(
|
||||
damage: Int,
|
||||
data: ResolvedProjectile
|
||||
): Int = {
|
||||
if (data.resolution == resolution) {
|
||||
(data.projectile.profile.Aggravated, data.target) match {
|
||||
case (Some(aggravation), p: PlayerSource) =>
|
||||
val degradation = aggravation.info.find(_.damage_type == damageType) match {
|
||||
case Some(info) =>
|
||||
info.degradation_percentage
|
||||
case _ =>
|
||||
1f
|
||||
}
|
||||
if (p.exosuit == ExoSuitType.MAX) {
|
||||
(damage * degradation * aggravation.max_factor) toInt
|
||||
} else {
|
||||
val resist = data.damage_model.ResistUsing(data)(data)
|
||||
//add resist to offset resist subtraction later
|
||||
if (damage > resist) {
|
||||
((damage - resist) * degradation).toInt + resist
|
||||
} else {
|
||||
(damage * degradation).toInt + resist
|
||||
}
|
||||
}
|
||||
case _ =>
|
||||
0
|
||||
}
|
||||
} else {
|
||||
damage
|
||||
}
|
||||
baseAggravatedBurnFormula(ProjectileResolution.AggravatedSplashBurn, DamageType.Splash)
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -295,8 +176,8 @@ object DamageModifiers {
|
|||
|
||||
private def formula(damage: Int, data: ResolvedProjectile): Int = {
|
||||
if (damage > 0 &&
|
||||
data.resolution == ProjectileResolution.AggravatedDirectBurn ||
|
||||
data.resolution == ProjectileResolution.AggravatedSplashBurn) {
|
||||
(data.resolution == ProjectileResolution.AggravatedDirectBurn ||
|
||||
data.resolution == ProjectileResolution.AggravatedSplashBurn)) {
|
||||
//add resist to offset resist subtraction later
|
||||
1 + data.damage_model.ResistUsing(data)(data)
|
||||
} else {
|
||||
|
|
@ -425,6 +306,17 @@ object DamageModifiers {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If the projectile has charging properties,
|
||||
* and the weapon that produced the projectile has charging mechanics,
|
||||
* calculate the current value of the damage as a sum
|
||||
* of some minimum damage and scaled normal damage.
|
||||
* The projectile quality has information about the "factor" of damage scaling.
|
||||
* @see `ChargeDamage`
|
||||
* @see `ChargeFireModeDefinition`
|
||||
* @see `ProjectileQuality`
|
||||
* @see `ResolvedProjectile`
|
||||
*/
|
||||
case object SpikerChargeDamage extends Mod {
|
||||
def Calculate: DamageModifiers.Format = formula
|
||||
|
||||
|
|
@ -439,4 +331,193 @@ object DamageModifiers {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If the damage is resolved through a `HitDamage` packet,
|
||||
* calculate the damage as a function of its degrading value over distance traveled by its carrier projectile.
|
||||
* @see `distanceDegradeFunction`
|
||||
* @see `ProjectileQuality`
|
||||
* @see `ResolvedProjectile`
|
||||
*/
|
||||
case object FlakHit extends Mod {
|
||||
def Calculate: DamageModifiers.Format = formula
|
||||
|
||||
private def formula(damage: Int, data: ResolvedProjectile): Int = {
|
||||
if(data.resolution == ProjectileResolution.Hit) {
|
||||
distanceDegradeFunction(damage, data)
|
||||
} else {
|
||||
damage
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If the damage is resolved through a `SplashHitDamage` packet,
|
||||
* calculate the damage as a function of its degrading value over distance
|
||||
* between the hit position of the projectile and the position of the target.
|
||||
* @see `radialDegradeFunction`
|
||||
* @see `ProjectileQuality`
|
||||
* @see `ResolvedProjectile`
|
||||
*/
|
||||
case object FlakBurst extends Mod {
|
||||
def Calculate: DamageModifiers.Format = formula
|
||||
|
||||
private def formula(damage: Int, data: ResolvedProjectile): Int = {
|
||||
if(data.resolution == ProjectileResolution.Splash) {
|
||||
radialDegradeFunction(damage, data)
|
||||
} else {
|
||||
damage
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Functions */
|
||||
|
||||
/**
|
||||
* The input value degrades (lessens)
|
||||
* the further the distance between the point of origin (`shot_origin`)
|
||||
* and the point of encounter (`hit_pos`) of its vector (projectile).
|
||||
* If the value is not set to degrade over any distance within its maximum distance, the value goes unmodified.
|
||||
* If the value is encountered beyond its maximum distance, the value is zero'd.
|
||||
*/
|
||||
private def distanceDegradeFunction(damage: Int, data: ResolvedProjectile): Int = {
|
||||
val projectile = data.projectile
|
||||
val profile = projectile.profile
|
||||
val distance = Vector3.Distance(data.hit_pos, projectile.shot_origin)
|
||||
if (distance <= profile.DistanceMax) {
|
||||
if (profile.DistanceNoDegrade == profile.DistanceMax || distance <= profile.DistanceNoDegrade) {
|
||||
damage
|
||||
} else {
|
||||
damage - ((damage - profile.DegradeMultiplier * damage) * ((distance - profile.DistanceNoDegrade) / (profile.DistanceMax - profile.DistanceNoDegrade))).toInt
|
||||
}
|
||||
} else {
|
||||
0
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The input value degrades (lessens)
|
||||
* the further the distance between the point of origin (target position)
|
||||
* and the point of encounter (`hit_pos`) of its vector (projectile).
|
||||
* If the value is encountered beyond its maximum radial distance, the value is zero'd.
|
||||
*/
|
||||
private def radialDegradeFunction(damage: Int, data: ResolvedProjectile): Int = {
|
||||
val profile = data.projectile.profile
|
||||
val distance = Vector3.Distance(data.hit_pos, data.target.Position)
|
||||
val radius = profile.DamageRadius
|
||||
val radiusMin = profile.DamageRadiusMin
|
||||
if (distance <= radiusMin) {
|
||||
damage
|
||||
} else if (distance <= radius) {
|
||||
//damage - (damage * profile.DamageAtEdge * (distance - radiusMin) / (radius - radiusMin)).toInt
|
||||
val base = profile.DamageAtEdge
|
||||
val radi = radius - radiusMin
|
||||
(damage * ((1 - base) * ((radi - (distance - radiusMin)) / radi) + base)).toInt
|
||||
} else {
|
||||
0
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* For damage application that involves aggravation of a particular damage type,
|
||||
* calculate that initial damage application for infantry targets
|
||||
* and produce the modified damage value.
|
||||
* Infantry wearing mechanized assault exo-suits (MAX) incorporate an additional modifier.
|
||||
* @see `AggravatedDamage`
|
||||
* @see `ExoSuitType`
|
||||
* @see `InfantryAggravatedDirect`
|
||||
* @see `InfantryAggravatedSplash`
|
||||
* @see `PlayerSource`
|
||||
* @see `ProjectileTarget.AggravatesTarget`
|
||||
* @see `ResolvedProjectile`
|
||||
* @param resolution the projectile resolution to match against
|
||||
* @param damageType the damage type to find in as a component of aggravated information
|
||||
* @param damage the base damage value
|
||||
* @param data historical information related to the damage interaction
|
||||
* @return the modified damage
|
||||
*/
|
||||
private def baseAggravatedFormula(
|
||||
resolution: ProjectileResolution.Value,
|
||||
damageType : DamageType.Value
|
||||
)
|
||||
(
|
||||
damage: Int,
|
||||
data: ResolvedProjectile
|
||||
): Int = {
|
||||
if (data.resolution == resolution &&
|
||||
data.projectile.quality == ProjectileQuality.AggravatesTarget) {
|
||||
(data.projectile.profile.Aggravated, data.target) match {
|
||||
case (Some(aggravation), p: PlayerSource) =>
|
||||
val aggravatedDamage = aggravation.info.find(_.damage_type == damageType) match {
|
||||
case Some(infos) =>
|
||||
damage * infos.degradation_percentage + damage
|
||||
case _ =>
|
||||
damage toFloat
|
||||
}
|
||||
if(p.ExoSuit == ExoSuitType.MAX) {
|
||||
(aggravatedDamage * aggravation.max_factor) toInt
|
||||
} else {
|
||||
aggravatedDamage toInt
|
||||
}
|
||||
case _ =>
|
||||
damage
|
||||
}
|
||||
} else {
|
||||
damage
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* For damage application that involves aggravation of a particular damage type,
|
||||
* calculate that damage application burn for each tick for infantry targets
|
||||
* and produce the modified damage value.
|
||||
* Infantry wearing mechanized assault exo-suits (MAX) incorporate an additional modifier.
|
||||
* Vanilla infantry incorporate their resistance value into a slightly different calculation than usual.
|
||||
* @see `AggravatedDamage`
|
||||
* @see `ExoSuitType`
|
||||
* @see `InfantryAggravatedDirectBurn`
|
||||
* @see `InfantryAggravatedSplashBurn`
|
||||
* @see `PlayerSource`
|
||||
* @see `ResolvedProjectile`
|
||||
* @param resolution the projectile resolution to match against
|
||||
* @param damageType the damage type to find in as a component of aggravated information
|
||||
* @param damage the base damage value
|
||||
* @param data historical information related to the damage interaction
|
||||
* @return the modified damage
|
||||
*/
|
||||
private def baseAggravatedBurnFormula(
|
||||
resolution: ProjectileResolution.Value,
|
||||
damageType : DamageType.Value
|
||||
)
|
||||
(
|
||||
damage: Int,
|
||||
data: ResolvedProjectile
|
||||
): Int = {
|
||||
if (data.resolution == resolution) {
|
||||
(data.projectile.profile.Aggravated, data.target) match {
|
||||
case (Some(aggravation), p: PlayerSource) =>
|
||||
val degradation = aggravation.info.find(_.damage_type == damageType) match {
|
||||
case Some(info) =>
|
||||
info.degradation_percentage
|
||||
case _ =>
|
||||
1f
|
||||
}
|
||||
if (p.exosuit == ExoSuitType.MAX) {
|
||||
(damage * degradation * aggravation.max_factor) toInt
|
||||
} else {
|
||||
val resist = data.damage_model.ResistUsing(data)(data)
|
||||
//add resist to offset resist subtraction later
|
||||
if (damage > resist) {
|
||||
((damage - resist) * degradation).toInt + resist
|
||||
} else {
|
||||
(damage * degradation).toInt + resist
|
||||
}
|
||||
}
|
||||
case _ =>
|
||||
0
|
||||
}
|
||||
} else {
|
||||
damage
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -67,6 +67,36 @@ class DamageCalculationsTests extends Specification {
|
|||
DamageModifiers.DistanceDegrade.Calculate(100, resprojectile) == 100 mustEqual true
|
||||
}
|
||||
|
||||
"cut off damage at max distance (no cutoff)" in {
|
||||
DamageModifiers.MaxDistanceCutoff.Calculate(100, resprojectile) == 100 mustEqual true
|
||||
}
|
||||
|
||||
"cut off damage at max distance (cutoff)" in {
|
||||
val cutoffprojectile = ResolvedProjectile(
|
||||
ProjectileResolution.Hit,
|
||||
projectile,
|
||||
SourceEntry(target),
|
||||
target.DamageModel,
|
||||
Vector3(1500, 0, 0)
|
||||
)
|
||||
DamageModifiers.MaxDistanceCutoff.Calculate(100, cutoffprojectile) == 0 mustEqual true
|
||||
}
|
||||
|
||||
"cut off damage at custom distance (no cutoff)" in {
|
||||
DamageModifiers.CustomDistanceCutoff(10).Calculate(100, resprojectile) == 0 mustEqual true
|
||||
}
|
||||
|
||||
"cut off damage at custom distance (cutoff)" in {
|
||||
val coffprojectile = ResolvedProjectile(
|
||||
ProjectileResolution.Splash,
|
||||
projectile,
|
||||
SourceEntry(target),
|
||||
target.DamageModel,
|
||||
Vector3(10, 0, 0)
|
||||
)
|
||||
DamageModifiers.CustomDistanceCutoff(2).Calculate(100, coffprojectile) == 0 mustEqual true
|
||||
}
|
||||
|
||||
"degrade over distance damage modifier (some degrade)" in {
|
||||
val resprojectile2 = ResolvedProjectile(
|
||||
ProjectileResolution.Splash,
|
||||
|
|
@ -158,6 +188,171 @@ class DamageCalculationsTests extends Specification {
|
|||
DamageModifiers.Lash.Calculate(100, resprojectile2) == 0 mustEqual true
|
||||
}
|
||||
|
||||
"fireball aggravated damage (aggravated splash burn" in {
|
||||
val burnWeapon = Tool(GlobalDefinitions.flamethrower)
|
||||
val burnProjectile = Projectile(
|
||||
burnWeapon.Projectile,
|
||||
burnWeapon.Definition,
|
||||
burnWeapon.FireMode,
|
||||
player,
|
||||
Vector3(2, 2, 0),
|
||||
Vector3.Zero
|
||||
)
|
||||
val burnRes = ResolvedProjectile(
|
||||
ProjectileResolution.AggravatedSplashBurn,
|
||||
projectile,
|
||||
SourceEntry(target),
|
||||
target.DamageModel,
|
||||
Vector3(15, 0, 0)
|
||||
)
|
||||
val resistance = burnRes.damage_model.ResistUsing(burnRes)(burnRes)
|
||||
DamageModifiers.FireballAggravatedBurn.Calculate(100, burnRes) == (1 + resistance) mustEqual true
|
||||
}
|
||||
|
||||
"fireball aggravated damage (noral splash, no modification)" in {
|
||||
val burnWeapon = Tool(GlobalDefinitions.flamethrower)
|
||||
val burnProjectile = Projectile(
|
||||
burnWeapon.Projectile,
|
||||
burnWeapon.Definition,
|
||||
burnWeapon.FireMode,
|
||||
player,
|
||||
Vector3(2, 2, 0),
|
||||
Vector3.Zero
|
||||
)
|
||||
val burnRes = ResolvedProjectile(
|
||||
ProjectileResolution.Splash,
|
||||
projectile,
|
||||
SourceEntry(target),
|
||||
target.DamageModel,
|
||||
Vector3(15, 0, 0)
|
||||
)
|
||||
DamageModifiers.FireballAggravatedBurn.Calculate(100, burnRes) == 100 mustEqual true
|
||||
}
|
||||
|
||||
val charge_weapon = Tool(GlobalDefinitions.spiker)
|
||||
val charge_projectile = Projectile(
|
||||
charge_weapon.Projectile,
|
||||
charge_weapon.Definition,
|
||||
charge_weapon.FireMode,
|
||||
player,
|
||||
Vector3(2, 2, 0),
|
||||
Vector3.Zero
|
||||
)
|
||||
val minDamageBase = charge_weapon.Projectile.Charging.get.min.Damage0
|
||||
val chargeBaseDamage = charge_weapon.Projectile.Damage0
|
||||
|
||||
"charge (none)" in {
|
||||
val cprojectile = charge_projectile.quality(ProjectileQuality.Modified(0))
|
||||
val rescprojectile = ResolvedProjectile(
|
||||
ProjectileResolution.Hit,
|
||||
cprojectile,
|
||||
SourceEntry(target),
|
||||
target.DamageModel,
|
||||
Vector3(15, 0, 0)
|
||||
)
|
||||
val damage = DamageModifiers.SpikerChargeDamage.Calculate(chargeBaseDamage, rescprojectile)
|
||||
val calcDam = minDamageBase + math.floor(chargeBaseDamage * rescprojectile.projectile.quality.mod)
|
||||
damage mustEqual calcDam
|
||||
}
|
||||
|
||||
"charge (half)" in {
|
||||
val cprojectile = charge_projectile.quality(ProjectileQuality.Modified(0.5f))
|
||||
val rescprojectile = ResolvedProjectile(
|
||||
ProjectileResolution.Hit,
|
||||
cprojectile,
|
||||
SourceEntry(target),
|
||||
target.DamageModel,
|
||||
Vector3(15, 0, 0)
|
||||
)
|
||||
val damage = DamageModifiers.SpikerChargeDamage.Calculate(chargeBaseDamage, rescprojectile)
|
||||
val calcDam = minDamageBase + math.floor(chargeBaseDamage * rescprojectile.projectile.quality.mod)
|
||||
damage mustEqual calcDam
|
||||
}
|
||||
|
||||
"charge (full)" in {
|
||||
val cprojectile = charge_projectile.quality(ProjectileQuality.Modified(1))
|
||||
val rescprojectile = ResolvedProjectile(
|
||||
ProjectileResolution.Hit,
|
||||
cprojectile,
|
||||
SourceEntry(target),
|
||||
target.DamageModel,
|
||||
Vector3(15, 0, 0)
|
||||
)
|
||||
val damage = DamageModifiers.SpikerChargeDamage.Calculate(chargeBaseDamage, rescprojectile)
|
||||
val calcDam = minDamageBase + chargeBaseDamage
|
||||
damage mustEqual calcDam
|
||||
}
|
||||
|
||||
val flak_weapon = Tool(GlobalDefinitions.trhev_burster)
|
||||
val flak_projectile = Projectile(
|
||||
flak_weapon.Projectile,
|
||||
flak_weapon.Definition,
|
||||
flak_weapon.FireMode,
|
||||
player,
|
||||
Vector3(2, 2, 0),
|
||||
Vector3.Zero
|
||||
)
|
||||
|
||||
"flak hit (resolution is splash, no degrade)" in {
|
||||
val resfprojectile = ResolvedProjectile(
|
||||
ProjectileResolution.Splash,
|
||||
flak_projectile,
|
||||
SourceEntry(target),
|
||||
target.DamageModel,
|
||||
Vector3(10, 0, 0)
|
||||
)
|
||||
val damage = DamageModifiers.FlakHit.Calculate(100, resfprojectile)
|
||||
damage == 100 mustEqual true
|
||||
}
|
||||
|
||||
"flak hit (resolution is hit, no degrade)" in {
|
||||
val resfprojectile = ResolvedProjectile(
|
||||
ProjectileResolution.Hit,
|
||||
flak_projectile,
|
||||
SourceEntry(target),
|
||||
target.DamageModel,
|
||||
Vector3(10, 0, 0)
|
||||
)
|
||||
val damage = DamageModifiers.FlakHit.Calculate(100, resfprojectile)
|
||||
damage == 100 mustEqual true
|
||||
}
|
||||
|
||||
"flak burst (resolution is hit)" in {
|
||||
val resfprojectile = ResolvedProjectile(
|
||||
ProjectileResolution.Hit,
|
||||
flak_projectile,
|
||||
SourceEntry(target),
|
||||
target.DamageModel,
|
||||
Vector3(15, 0, 0)
|
||||
)
|
||||
val damage = DamageModifiers.FlakBurst.Calculate(100, resfprojectile)
|
||||
damage == 100 mustEqual true
|
||||
}
|
||||
|
||||
"flak burst (resolution is splash, no degrade)" in {
|
||||
val resfprojectile = ResolvedProjectile(
|
||||
ProjectileResolution.Splash,
|
||||
flak_projectile,
|
||||
SourceEntry(target),
|
||||
target.DamageModel,
|
||||
Vector3(10, 0, 0)
|
||||
)
|
||||
val damage = DamageModifiers.FlakBurst.Calculate(100, resfprojectile)
|
||||
damage == 100 mustEqual true
|
||||
}
|
||||
|
||||
"flak burst (resolution is splash, some degrade)" in {
|
||||
val resfprojectile = ResolvedProjectile(
|
||||
ProjectileResolution.Splash,
|
||||
flak_projectile,
|
||||
SourceEntry(target),
|
||||
target.DamageModel,
|
||||
Vector3(5, 0, 0)
|
||||
)
|
||||
val damage = DamageModifiers.FlakBurst.Calculate(100, resfprojectile)
|
||||
damage < 100 mustEqual true
|
||||
}
|
||||
|
||||
"extract a complete damage profile" in {
|
||||
val result1 = DamageModifiers.RadialDegrade.Calculate(
|
||||
AgainstVehicle(proj_prof) + AgainstVehicle(wep_prof),
|
||||
|
|
|
|||
Loading…
Reference in a new issue