mirror of
https://github.com/2revoemag/PSF-BotServer.git
synced 2026-04-23 12:55:20 +00:00
timing and damage tuning around: standard, reinforced, max; plasma grenades, dragon
This commit is contained in:
parent
d149e07e89
commit
97e64d5edc
16 changed files with 500 additions and 136 deletions
|
|
@ -1,13 +1,26 @@
|
|||
package net.psforever.actors.session
|
||||
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
import akka.actor.MDCContextAware.Implicits._
|
||||
import akka.actor.typed
|
||||
import akka.actor.typed.receptionist.Receptionist
|
||||
import akka.actor.{Actor, ActorRef, Cancellable, MDCContextAware}
|
||||
import java.util.concurrent.atomic.AtomicInteger
|
||||
import org.log4s.MDC
|
||||
import scala.collection.mutable.LongMap
|
||||
import scala.concurrent.{Await, Future}
|
||||
import scala.concurrent.duration._
|
||||
import scala.concurrent.ExecutionContext.Implicits.global
|
||||
import scala.util.{Failure, Success}
|
||||
import scodec.bits.ByteVector
|
||||
import services.properties.PropertyOverrideManager
|
||||
import org.joda.time.{LocalDateTime, Period}
|
||||
import csr.{CSRWarp, CSRZone, Traveler}
|
||||
import MDCContextAware.Implicits._
|
||||
import net.psforever.objects.{GlobalDefinitions, _}
|
||||
import net.psforever.objects.avatar.{Avatar, Certification, DeployableToolbox}
|
||||
import net.psforever.objects._
|
||||
import net.psforever.objects.avatar.{Certification, DeployableToolbox, FirstTimeEvents}
|
||||
import net.psforever.objects.ballistics._
|
||||
import net.psforever.objects.ce._
|
||||
import net.psforever.objects.definition._
|
||||
|
|
@ -37,15 +50,7 @@ import net.psforever.objects.serverobject.turret.{FacilityTurret, WeaponTurret}
|
|||
import net.psforever.objects.serverobject.zipline.ZipLinePath
|
||||
import net.psforever.objects.serverobject.{CommonMessages, PlanetSideServerObject}
|
||||
import net.psforever.objects.teamwork.Squad
|
||||
import net.psforever.objects.vehicles.{
|
||||
AccessPermissionGroup,
|
||||
CargoBehavior,
|
||||
MountedWeapons,
|
||||
Utility,
|
||||
UtilityType,
|
||||
VehicleControl,
|
||||
VehicleLockState
|
||||
}
|
||||
import net.psforever.objects.vehicles._
|
||||
import net.psforever.objects.vehicles.Utility.InternalTelepad
|
||||
import net.psforever.objects.vital._
|
||||
import net.psforever.objects.zones.{Zone, ZoneHotSpotProjector, Zoning}
|
||||
|
|
@ -53,6 +58,13 @@ import net.psforever.packet._
|
|||
import net.psforever.packet.control._
|
||||
import net.psforever.packet.game.objectcreate._
|
||||
import net.psforever.packet.game.{HotSpotInfo => PacketHotSpotInfo, _}
|
||||
import net.psforever.objects.zones.{InterstellarCluster, Zone, ZoneHotSpotProjector, Zoning}
|
||||
import net.psforever.packet._
|
||||
import net.psforever.packet.control._
|
||||
import net.psforever.packet.game._
|
||||
import net.psforever.packet.game.objectcreate._
|
||||
import net.psforever.packet.game.{HotSpotInfo => PacketHotSpotInfo}
|
||||
import net.psforever.persistence
|
||||
import net.psforever.types._
|
||||
import org.log4s.MDC
|
||||
import scodec.bits.ByteVector
|
||||
|
|
@ -78,7 +90,6 @@ import net.psforever.login.WorldSession._
|
|||
import net.psforever.zones.Zones
|
||||
import net.psforever.services.chat.ChatService
|
||||
import net.psforever.objects.avatar.Cosmetic
|
||||
|
||||
import scala.concurrent.ExecutionContext.Implicits.global
|
||||
import scala.concurrent.duration._
|
||||
import scala.concurrent.{Await, Future}
|
||||
|
|
@ -86,7 +97,6 @@ import scala.util.Success
|
|||
import akka.actor.typed.scaladsl.adapter._
|
||||
import akka.pattern.ask
|
||||
import akka.util.Timeout
|
||||
|
||||
import scala.collection.mutable
|
||||
|
||||
object SessionActor {
|
||||
|
|
@ -5328,7 +5338,15 @@ class SessionActor extends Actor with MDCContextAware {
|
|||
case _ => ;
|
||||
}
|
||||
|
||||
case msg @ HitMessage(seq_time, projectile_guid, unk1, hit_info, unk2, unk3, unk4) =>
|
||||
case msg @ HitMessage(
|
||||
seq_time,
|
||||
projectile_guid,
|
||||
unk1,
|
||||
hit_info,
|
||||
unk2,
|
||||
unk3,
|
||||
unk4
|
||||
) =>
|
||||
log.info(s"Hit: $msg")
|
||||
//find defined projectile
|
||||
FindProjectileEntry(projectile_guid) match {
|
||||
|
|
@ -5395,31 +5413,33 @@ class SessionActor extends Actor with MDCContextAware {
|
|||
}
|
||||
|
||||
case msg @ SplashHitMessage(
|
||||
seq_time,
|
||||
projectile_guid,
|
||||
explosion_pos,
|
||||
direct_victim_uid,
|
||||
unk3,
|
||||
projectile_vel,
|
||||
unk4,
|
||||
targets
|
||||
seq_time,
|
||||
projectile_guid,
|
||||
explosion_pos,
|
||||
direct_victim_uid,
|
||||
unk3,
|
||||
projectile_vel,
|
||||
unk4,
|
||||
targets
|
||||
) =>
|
||||
log.info(s"Splash: $msg")
|
||||
FindProjectileEntry(projectile_guid) match {
|
||||
case Some(projectile) =>
|
||||
val profile = projectile.profile
|
||||
projectile.Position = explosion_pos
|
||||
projectile.Velocity = projectile_vel
|
||||
val (resolution1, resolution2) = profile.Aggravated match {
|
||||
case Some(_)
|
||||
if profile.ProjectileDamageTypes.contains(DamageType.Aggravated) =>
|
||||
(ProjectileResolution.AggravatedDirect, ProjectileResolution.AggravatedSplash)
|
||||
case _ =>
|
||||
(ProjectileResolution.Splash, ProjectileResolution.Splash)
|
||||
}
|
||||
//direct_victim_uid
|
||||
ValidObject(direct_victim_uid) match {
|
||||
case Some(
|
||||
target: PlanetSideGameObject with FactionAffinity with Vitality
|
||||
) =>
|
||||
CheckForHitPositionDiscrepancy(
|
||||
projectile_guid,
|
||||
explosion_pos,
|
||||
target
|
||||
)
|
||||
ResolveProjectileEntry(projectile, ProjectileResolution.Splash, target, explosion_pos) match {
|
||||
case Some(target: PlanetSideGameObject with FactionAffinity with Vitality) =>
|
||||
CheckForHitPositionDiscrepancy(projectile_guid, target.Position, target)
|
||||
ResolveProjectileEntry(projectile, resolution1, target, target.Position) match {
|
||||
case Some(projectile) =>
|
||||
HandleDealingDamage(target, projectile)
|
||||
case None => ;
|
||||
|
|
@ -5431,7 +5451,7 @@ class SessionActor extends Actor with MDCContextAware {
|
|||
ValidObject(elem.uid) match {
|
||||
case Some(target: PlanetSideGameObject with FactionAffinity with Vitality) =>
|
||||
CheckForHitPositionDiscrepancy(projectile_guid, explosion_pos, target)
|
||||
ResolveProjectileEntry(projectile, ProjectileResolution.Splash, target, explosion_pos) match {
|
||||
ResolveProjectileEntry(projectile, resolution2, target, explosion_pos) match {
|
||||
case Some(projectile) =>
|
||||
HandleDealingDamage(target, projectile)
|
||||
case None => ;
|
||||
|
|
@ -5439,7 +5459,7 @@ class SessionActor extends Actor with MDCContextAware {
|
|||
case _ => ;
|
||||
}
|
||||
})
|
||||
if (projectile.profile.ExistsOnRemoteClients && projectile.HasGUID) {
|
||||
if (profile.ExistsOnRemoteClients && projectile.HasGUID) {
|
||||
//cleanup
|
||||
val localIndex = projectile_guid.guid - Projectile.baseUID
|
||||
if (projectile.HasGUID) {
|
||||
|
|
@ -5642,16 +5662,16 @@ class SessionActor extends Actor with MDCContextAware {
|
|||
log.debug("Ouch! " + msg)
|
||||
|
||||
case msg @ BugReportMessage(
|
||||
version_major,
|
||||
version_minor,
|
||||
version_date,
|
||||
bug_type,
|
||||
repeatable,
|
||||
location,
|
||||
zone,
|
||||
pos,
|
||||
summary,
|
||||
desc
|
||||
version_major,
|
||||
version_minor,
|
||||
version_date,
|
||||
bug_type,
|
||||
repeatable,
|
||||
location,
|
||||
zone,
|
||||
pos,
|
||||
summary,
|
||||
desc
|
||||
) =>
|
||||
log.info("BugReportMessage: " + msg)
|
||||
|
||||
|
|
|
|||
|
|
@ -2040,6 +2040,7 @@ object GlobalDefinitions {
|
|||
|
||||
no_projectile.Name = "none"
|
||||
ProjectileDefinition.CalculateDerivedFields(no_projectile)
|
||||
no_projectile.Modifiers = Nil
|
||||
|
||||
bullet_105mm_projectile.Name = "105mmbullet_projectile"
|
||||
bullet_105mm_projectile.Damage0 = 150
|
||||
|
|
@ -2363,6 +2364,7 @@ object GlobalDefinitions {
|
|||
chainblade_projectile.InitialVelocity = 100
|
||||
chainblade_projectile.Lifespan = .02f
|
||||
ProjectileDefinition.CalculateDerivedFields(chainblade_projectile)
|
||||
chainblade_projectile.Modifiers = DamageModifiers.MaxDistanceCutoff
|
||||
|
||||
colossus_100mm_projectile.Name = "colossus_100mm_projectile"
|
||||
colossus_100mm_projectile.Damage0 = 58
|
||||
|
|
@ -2597,6 +2599,7 @@ object GlobalDefinitions {
|
|||
flamethrower_fireball.Damage2 = 0
|
||||
flamethrower_fireball.Damage3 = 20
|
||||
flamethrower_fireball.Damage4 = 0
|
||||
flamethrower_fireball.DamageToHealthOnly = true
|
||||
flamethrower_fireball.DamageAtEdge = 0.15f
|
||||
flamethrower_fireball.DamageRadius = 5f
|
||||
flamethrower_fireball.ProjectileDamageType = DamageType.Aggravated
|
||||
|
|
@ -2611,6 +2614,13 @@ object GlobalDefinitions {
|
|||
flamethrower_fireball.InitialVelocity = 15
|
||||
flamethrower_fireball.Lifespan = 1.2f
|
||||
ProjectileDefinition.CalculateDerivedFields(flamethrower_fireball)
|
||||
flamethrower_fireball.Modifiers = List(
|
||||
DamageModifiers.AggravatedDirect,
|
||||
DamageModifiers.AggravatedDirectBurn,
|
||||
DamageModifiers.AggravatedSplash,
|
||||
DamageModifiers.AggravatedSplashBurn,
|
||||
DamageModifiers.RadialDegrade
|
||||
)
|
||||
|
||||
flamethrower_projectile.Name = "flamethrower_projectile"
|
||||
flamethrower_projectile.Damage0 = 10
|
||||
|
|
@ -2618,6 +2628,7 @@ object GlobalDefinitions {
|
|||
flamethrower_projectile.Damage2 = 0
|
||||
flamethrower_projectile.Damage3 = 4
|
||||
flamethrower_projectile.Damage4 = 0
|
||||
flamethrower_projectile.DamageToHealthOnly = true
|
||||
flamethrower_projectile.Acceleration = -5
|
||||
flamethrower_projectile.AccelerationUntil = 2f
|
||||
flamethrower_projectile.ProjectileDamageType = DamageType.Aggravated
|
||||
|
|
@ -2634,6 +2645,11 @@ object GlobalDefinitions {
|
|||
flamethrower_projectile.InitialVelocity = 10
|
||||
flamethrower_projectile.Lifespan = 2.0f
|
||||
ProjectileDefinition.CalculateDerivedFields(flamethrower_projectile)
|
||||
flamethrower_projectile.Modifiers = List(
|
||||
DamageModifiers.AggravatedDirect,
|
||||
DamageModifiers.AggravatedDirectBurn,
|
||||
DamageModifiers.MaxDistanceCutoff
|
||||
)
|
||||
|
||||
flux_cannon_apc_projectile.Name = "flux_cannon_apc_projectile"
|
||||
// TODO for later, maybe : set_resource_parent flux_cannon_apc_projectile game_objects flux_cannon_thresher_projectile
|
||||
|
|
@ -2685,6 +2701,7 @@ object GlobalDefinitions {
|
|||
forceblade_projectile.InitialVelocity = 100
|
||||
forceblade_projectile.Lifespan = .02f
|
||||
ProjectileDefinition.CalculateDerivedFields(forceblade_projectile)
|
||||
forceblade_projectile.Modifiers = DamageModifiers.MaxDistanceCutoff
|
||||
|
||||
frag_cartridge_projectile.Name = "frag_cartridge_projectile"
|
||||
// TODO for later, maybe : set_resource_parent frag_cartridge_projectile game_objects frag_grenade_projectile
|
||||
|
|
@ -2898,7 +2915,7 @@ object GlobalDefinitions {
|
|||
EffectTarget.Validation.VehicleNotAMS
|
||||
) -> 10000
|
||||
ProjectileDefinition.CalculateDerivedFields(jammer_cartridge_projectile)
|
||||
jammer_cartridge_projectile.Modifiers = Nil
|
||||
jammer_cartridge_projectile.Modifiers = DamageModifiers.MaxDistanceCutoff
|
||||
|
||||
jammer_cartridge_projectile_b.Name = "jammer_cartridge_projectile_b"
|
||||
// TODO for later, maybe : set_resource_parent jammer_cartridge_projectile_b game_objects jammer_grenade_projectile_enh
|
||||
|
|
@ -2937,7 +2954,7 @@ object GlobalDefinitions {
|
|||
EffectTarget.Validation.VehicleNotAMS
|
||||
) -> 10000
|
||||
ProjectileDefinition.CalculateDerivedFields(jammer_cartridge_projectile_b)
|
||||
jammer_cartridge_projectile_b.Modifiers = Nil
|
||||
jammer_cartridge_projectile_b.Modifiers = DamageModifiers.MaxDistanceCutoff
|
||||
|
||||
jammer_grenade_projectile.Name = "jammer_grenade_projectile"
|
||||
jammer_grenade_projectile.Damage0 = 0
|
||||
|
|
@ -2975,7 +2992,7 @@ object GlobalDefinitions {
|
|||
EffectTarget.Validation.VehicleNotAMS
|
||||
) -> 10000
|
||||
ProjectileDefinition.CalculateDerivedFields(jammer_grenade_projectile)
|
||||
jammer_grenade_projectile.Modifiers = Nil
|
||||
jammer_grenade_projectile.Modifiers = DamageModifiers.MaxDistanceCutoff
|
||||
|
||||
jammer_grenade_projectile_enh.Name = "jammer_grenade_projectile_enh"
|
||||
// TODO for later, maybe : set_resource_parent jammer_grenade_projectile_enh game_objects jammer_grenade_projectile
|
||||
|
|
@ -3014,7 +3031,7 @@ object GlobalDefinitions {
|
|||
EffectTarget.Validation.VehicleNotAMS
|
||||
) -> 10000
|
||||
ProjectileDefinition.CalculateDerivedFields(jammer_grenade_projectile_enh)
|
||||
jammer_grenade_projectile_enh.Modifiers = Nil
|
||||
jammer_grenade_projectile_enh.Modifiers = DamageModifiers.MaxDistanceCutoff
|
||||
|
||||
katana_projectile.Name = "katana_projectile"
|
||||
katana_projectile.Damage0 = 25
|
||||
|
|
@ -3057,7 +3074,10 @@ object GlobalDefinitions {
|
|||
lasher_projectile.LashRadius = 2.5f
|
||||
lasher_projectile.Lifespan = 0.75f
|
||||
ProjectileDefinition.CalculateDerivedFields(lasher_projectile)
|
||||
lasher_projectile.Modifiers = List(DamageModifiers.DistanceDegrade, DamageModifiers.Lash)
|
||||
lasher_projectile.Modifiers = List(
|
||||
DamageModifiers.DistanceDegrade,
|
||||
DamageModifiers.Lash
|
||||
)
|
||||
|
||||
lasher_projectile_ap.Name = "lasher_projectile_ap"
|
||||
lasher_projectile_ap.Damage0 = 12
|
||||
|
|
@ -3072,7 +3092,10 @@ object GlobalDefinitions {
|
|||
lasher_projectile_ap.LashRadius = 2.5f
|
||||
lasher_projectile_ap.Lifespan = 0.75f
|
||||
ProjectileDefinition.CalculateDerivedFields(lasher_projectile_ap)
|
||||
lasher_projectile_ap.Modifiers = List(DamageModifiers.DistanceDegrade, DamageModifiers.Lash)
|
||||
lasher_projectile_ap.Modifiers = List(
|
||||
DamageModifiers.DistanceDegrade,
|
||||
DamageModifiers.Lash
|
||||
)
|
||||
|
||||
liberator_bomb_cluster_bomblet_projectile.Name = "liberator_bomb_cluster_bomblet_projectile"
|
||||
liberator_bomb_cluster_bomblet_projectile.Damage0 = 75
|
||||
|
|
@ -3145,6 +3168,7 @@ object GlobalDefinitions {
|
|||
maelstrom_stream_projectile.InitialVelocity = 200
|
||||
maelstrom_stream_projectile.Lifespan = 0.2f
|
||||
ProjectileDefinition.CalculateDerivedFields(maelstrom_stream_projectile)
|
||||
maelstrom_stream_projectile.Modifiers = DamageModifiers.MaxDistanceCutoff
|
||||
|
||||
magcutter_projectile.Name = "magcutter_projectile"
|
||||
// TODO for later, maybe : set_resource_parent magcutter_projectile game_objects melee_ammo_projectile
|
||||
|
|
@ -3154,6 +3178,7 @@ object GlobalDefinitions {
|
|||
magcutter_projectile.InitialVelocity = 100
|
||||
magcutter_projectile.Lifespan = .02f
|
||||
ProjectileDefinition.CalculateDerivedFields(magcutter_projectile)
|
||||
magcutter_projectile.Modifiers = DamageModifiers.MaxDistanceCutoff
|
||||
|
||||
melee_ammo_projectile.Name = "melee_ammo_projectile"
|
||||
melee_ammo_projectile.Damage0 = 25
|
||||
|
|
@ -3162,6 +3187,7 @@ object GlobalDefinitions {
|
|||
melee_ammo_projectile.InitialVelocity = 100
|
||||
melee_ammo_projectile.Lifespan = .02f
|
||||
ProjectileDefinition.CalculateDerivedFields(melee_ammo_projectile)
|
||||
melee_ammo_projectile.Modifiers = DamageModifiers.MaxDistanceCutoff
|
||||
|
||||
meteor_common.Name = "meteor_common"
|
||||
meteor_common.DamageAtEdge = .1f
|
||||
|
|
@ -3482,6 +3508,13 @@ object GlobalDefinitions {
|
|||
plasma_cartridge_projectile.InitialVelocity = 30
|
||||
plasma_cartridge_projectile.Lifespan = 15f
|
||||
ProjectileDefinition.CalculateDerivedFields(plasma_cartridge_projectile)
|
||||
plasma_cartridge_projectile.Modifiers = List(
|
||||
DamageModifiers.AggravatedDirect,
|
||||
DamageModifiers.AggravatedDirectBurn,
|
||||
DamageModifiers.AggravatedSplash,
|
||||
DamageModifiers.AggravatedSplashBurn,
|
||||
DamageModifiers.RadialDegrade
|
||||
)
|
||||
|
||||
plasma_cartridge_projectile_b.Name = "plasma_cartridge_projectile_b"
|
||||
// TODO for later, maybe : set_resource_parent plasma_cartridge_projectile_b game_objects plasma_grenade_projectile_B
|
||||
|
|
@ -3502,6 +3535,13 @@ object GlobalDefinitions {
|
|||
plasma_cartridge_projectile_b.InitialVelocity = 30
|
||||
plasma_cartridge_projectile_b.Lifespan = 2f
|
||||
ProjectileDefinition.CalculateDerivedFields(plasma_cartridge_projectile_b)
|
||||
plasma_cartridge_projectile_b.Modifiers = List(
|
||||
DamageModifiers.AggravatedDirect,
|
||||
DamageModifiers.AggravatedDirectBurn,
|
||||
DamageModifiers.AggravatedSplash,
|
||||
DamageModifiers.AggravatedSplashBurn,
|
||||
DamageModifiers.RadialDegrade
|
||||
)
|
||||
|
||||
plasma_grenade_projectile.Name = "plasma_grenade_projectile"
|
||||
plasma_grenade_projectile.Damage0 = 40
|
||||
|
|
@ -3521,6 +3561,13 @@ object GlobalDefinitions {
|
|||
plasma_grenade_projectile.InitialVelocity = 30
|
||||
plasma_grenade_projectile.Lifespan = 15f
|
||||
ProjectileDefinition.CalculateDerivedFields(plasma_grenade_projectile)
|
||||
plasma_grenade_projectile.Modifiers = List(
|
||||
DamageModifiers.AggravatedDirect,
|
||||
DamageModifiers.AggravatedDirectBurn,
|
||||
DamageModifiers.AggravatedSplash,
|
||||
DamageModifiers.AggravatedSplashBurn,
|
||||
DamageModifiers.RadialDegrade
|
||||
)
|
||||
|
||||
plasma_grenade_projectile_B.Name = "plasma_grenade_projectile_B"
|
||||
// TODO for later, maybe : set_resource_parent plasma_grenade_projectile_B game_objects plasma_grenade_projectile
|
||||
|
|
@ -3541,6 +3588,13 @@ object GlobalDefinitions {
|
|||
plasma_grenade_projectile_B.InitialVelocity = 30
|
||||
plasma_grenade_projectile_B.Lifespan = 3f
|
||||
ProjectileDefinition.CalculateDerivedFields(plasma_grenade_projectile_B)
|
||||
plasma_grenade_projectile_B.Modifiers = List(
|
||||
DamageModifiers.AggravatedDirect,
|
||||
DamageModifiers.AggravatedDirectBurn,
|
||||
DamageModifiers.AggravatedSplash,
|
||||
DamageModifiers.AggravatedSplashBurn,
|
||||
DamageModifiers.RadialDegrade
|
||||
)
|
||||
|
||||
pounder_projectile.Name = "pounder_projectile"
|
||||
pounder_projectile.Damage0 = 31
|
||||
|
|
@ -3689,7 +3743,7 @@ object GlobalDefinitions {
|
|||
rocklet_jammer_projectile.InitialVelocity = 50
|
||||
rocklet_jammer_projectile.Lifespan = 8f
|
||||
ProjectileDefinition.CalculateDerivedFields(rocklet_jammer_projectile)
|
||||
rocklet_jammer_projectile.Modifiers = Nil
|
||||
//TODO rocklet_jammer_projectile.Modifiers = DamageModifiers.RadialDegrade?
|
||||
|
||||
scattercannon_projectile.Name = "scattercannon_projectile"
|
||||
scattercannon_projectile.Damage0 = 11
|
||||
|
|
@ -3809,7 +3863,6 @@ object GlobalDefinitions {
|
|||
spiker_projectile.InitialVelocity = 40
|
||||
spiker_projectile.Lifespan = 5f
|
||||
ProjectileDefinition.CalculateDerivedFields(spiker_projectile)
|
||||
spiker_projectile.Modifiers = DamageModifiers.RadialDegrade
|
||||
|
||||
spitfire_aa_ammo_projectile.Name = "spitfire_aa_ammo_projectile"
|
||||
spitfire_aa_ammo_projectile.Damage0 = 5
|
||||
|
|
@ -3907,6 +3960,7 @@ object GlobalDefinitions {
|
|||
trek_projectile.InitialVelocity = 40
|
||||
trek_projectile.Lifespan = 7f
|
||||
ProjectileDefinition.CalculateDerivedFields(trek_projectile)
|
||||
trek_projectile.Modifiers = DamageModifiers.MaxDistanceCutoff
|
||||
|
||||
vanu_sentry_turret_projectile.Name = "vanu_sentry_turret_projectile"
|
||||
vanu_sentry_turret_projectile.Damage0 = 25
|
||||
|
|
@ -4585,7 +4639,7 @@ object GlobalDefinitions {
|
|||
flamethrower.FireModes(1).AmmoSlotIndex = 0
|
||||
flamethrower.FireModes(1).Magazine = 100
|
||||
flamethrower.FireModes(1).RoundsPerShot = 50
|
||||
flamethrower.Tile = InventoryTile.Tile63
|
||||
flamethrower.Tile = InventoryTile.Tile93
|
||||
|
||||
winchester.Name = "winchester"
|
||||
winchester.Size = EquipmentSize.Rifle
|
||||
|
|
|
|||
|
|
@ -359,7 +359,9 @@ class Player(var avatar: Avatar)
|
|||
def Aura : Set[AuraEffect.Value] = aura
|
||||
|
||||
def AddEffectToAura(effect : AuraEffect.Value) : Set[AuraEffect.Value] = {
|
||||
aura = aura + effect
|
||||
if(effect != AuraEffect.None) {
|
||||
aura = aura + effect
|
||||
}
|
||||
Aura
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,16 +2,32 @@
|
|||
package net.psforever.objects.ballistics
|
||||
|
||||
/**
|
||||
* An `Enumeration` of outcomes regarding what actually happened to the projectile.
|
||||
* An `Enumeration` of outcomes regarding what actually happened to the projectile,
|
||||
* complementing normal damage type distinction in directing damage calculations.<br>
|
||||
* <br>
|
||||
* Although the latter states reflect what sort of damage the projectile might perform - `Hit`, `Splash`, etc. -
|
||||
* the state is more a communication about how that damage is interpreted by the server.
|
||||
* For example, some projectiles:
|
||||
* perform `Direct` damage, are reported by `HitMessage` packets, and resolve as `Hit`;
|
||||
* or, perform `Direct` damage, are reported by `LashDamage` packets, and resolve as `Lash`.
|
||||
* Furthermore, some projectiles:
|
||||
* perform `Splash` damage, are reported by `SplashHitMessage` packets, and resolve as `Splash`;
|
||||
* or, perform `Aggravated` damage, are reported by `SplashHitMessage` packets
|
||||
* and resolve either as `AggravatedDirect` or as `AggravatedSplash`.
|
||||
*/
|
||||
object ProjectileResolution extends Enumeration {
|
||||
type Type = Value
|
||||
|
||||
val Unresolved, //original basic non-resolution
|
||||
MissedShot, //projectile did not encounter any collision object and was despawned
|
||||
Resolved, //a general "projectile encountered something" status with a more specific resolution
|
||||
Hit, //direct hit, one target
|
||||
Splash, //area of effect damage, potentially multiple targets
|
||||
Lash //lashing damage, potentially multiple targets
|
||||
val
|
||||
Unresolved, //original basic non-resolution
|
||||
MissedShot, //projectile did not encounter any collision object and was despawned
|
||||
Resolved, //a general "projectile encountered something" status with a more specific resolution
|
||||
Hit, //direct hit, one target
|
||||
Splash, //area of effect damage, potentially multiple targets
|
||||
Lash, //lashing damage, potentially multiple targets
|
||||
AggravatedDirect, //direct hit aggravated damage
|
||||
AggravatedDirectBurn, //continuous direct hit aggravated damage
|
||||
AggravatedSplash, //splashed aggravated damage
|
||||
AggravatedSplashBurn //continuous splashed aggravated damage
|
||||
= Value
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ class ProjectileDefinition(objectId: Int)
|
|||
private var accelerationUntil: Float = 0f
|
||||
private var damageType: DamageType.Value = DamageType.None
|
||||
private var damageTypeSecondary: DamageType.Value = DamageType.None
|
||||
private var damageToHealthOnly: Boolean = false
|
||||
private var degradeDelay: Float = 1f
|
||||
private var degradeMultiplier: Float = 1f
|
||||
private var initialVelocity: Int = 1
|
||||
|
|
@ -83,6 +84,17 @@ class ProjectileDefinition(objectId: Int)
|
|||
ProjectileDamageTypeSecondary
|
||||
}
|
||||
|
||||
def ProjectileDamageTypes : Set[DamageType.Value] = {
|
||||
Set(damageType, damageTypeSecondary).filterNot(_ == DamageType.None)
|
||||
}
|
||||
|
||||
def DamageToHealthOnly : Boolean = damageToHealthOnly
|
||||
|
||||
def DamageToHealthOnly_=(healthOnly: Boolean) : Boolean = {
|
||||
damageToHealthOnly = healthOnly
|
||||
DamageToHealthOnly
|
||||
}
|
||||
|
||||
def DegradeDelay: Float = degradeDelay
|
||||
|
||||
def DegradeDelay_=(degradeDelay: Float): Float = {
|
||||
|
|
|
|||
|
|
@ -11,13 +11,13 @@ object NoResolutions
|
|||
|
||||
object InfantryResolutions
|
||||
extends DamageResistCalculations(
|
||||
ResolutionCalculations.InfantryDamageAfterResist,
|
||||
ResolutionCalculations.InfantryDamage,
|
||||
ResolutionCalculations.InfantryApplication
|
||||
)
|
||||
|
||||
object MaxResolutions
|
||||
extends DamageResistCalculations(
|
||||
ResolutionCalculations.MaxDamageAfterResist,
|
||||
ResolutionCalculations.MaxDamage,
|
||||
ResolutionCalculations.InfantryApplication
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,9 @@
|
|||
// Copyright (c) 2020 PSForever
|
||||
package net.psforever.objects.vital.damage
|
||||
|
||||
import net.psforever.objects.ballistics.{ProjectileResolution, ResolvedProjectile}
|
||||
import net.psforever.types.Vector3
|
||||
import net.psforever.objects.ballistics.{PlayerSource, ProjectileResolution, ResolvedProjectile}
|
||||
import net.psforever.objects.vital.DamageType
|
||||
import net.psforever.types.{ExoSuitType, Vector3}
|
||||
|
||||
/**
|
||||
* Adjustments performed on the subsequent manipulations of the "base damage" value of an attack vector
|
||||
|
|
@ -45,6 +46,21 @@ object DamageModifiers {
|
|||
private def function(damage: Int, data: ResolvedProjectile): Int = damage
|
||||
}
|
||||
|
||||
case object MaxDistanceCutoff 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) {
|
||||
damage
|
||||
} else {
|
||||
0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The input value degrades (lessens)
|
||||
* the further the distance between the point of origin (`shot_origin`)
|
||||
|
|
@ -117,4 +133,91 @@ object DamageModifiers {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
case object AggravatedDirect extends Mod {
|
||||
def Calculate: DamageModifiers.Format =
|
||||
BaseAggravatedFormula(ProjectileResolution.AggravatedDirect, DamageType.Direct)
|
||||
}
|
||||
|
||||
case object AggravatedSplash extends Mod {
|
||||
def Calculate: DamageModifiers.Format =
|
||||
BaseAggravatedFormula(ProjectileResolution.AggravatedSplash, DamageType.Splash)
|
||||
}
|
||||
|
||||
case object AggravatedDirectBurn extends Mod {
|
||||
def Calculate: DamageModifiers.Format =
|
||||
BaseAggravatedBurnFormula(ProjectileResolution.AggravatedDirectBurn, DamageType.Direct)
|
||||
}
|
||||
|
||||
case object AggravatedSplashBurn extends Mod {
|
||||
def Calculate: DamageModifiers.Format =
|
||||
BaseAggravatedBurnFormula(ProjectileResolution.AggravatedSplashBurn, DamageType.Splash)
|
||||
}
|
||||
|
||||
private def BaseAggravatedFormula(
|
||||
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) if p.ExoSuit == ExoSuitType.MAX =>
|
||||
val aggravatedDirectDamage = (aggravation.info.find(_.damage_type == damageType) match {
|
||||
case Some(infos) =>
|
||||
damage * infos.degradation_percentage
|
||||
case _ =>
|
||||
damage toFloat
|
||||
}) * aggravation.max_factor
|
||||
damage + aggravatedDirectDamage toInt
|
||||
case _ =>
|
||||
damage
|
||||
}
|
||||
} else {
|
||||
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)
|
||||
if (damage > resist) {
|
||||
((damage - resist) * degradation).toInt + resist
|
||||
} else {
|
||||
val degradedDamage = damage * degradation
|
||||
if (degradedDamage > resist) {
|
||||
degradedDamage toInt
|
||||
}
|
||||
else {
|
||||
damage
|
||||
}
|
||||
}
|
||||
}
|
||||
case _ =>
|
||||
damage
|
||||
}
|
||||
} else {
|
||||
damage
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,15 +38,31 @@ object ResolutionCalculations {
|
|||
|
||||
def NoDamage(data: ResolvedProjectile)(a: Int, b: Int): Int = 0
|
||||
|
||||
def InfantryDamageAfterResist(data: ResolvedProjectile): (Int, Int) => (Int, Int) = {
|
||||
def InfantryDamage(data: ResolvedProjectile): (Int, Int) => (Int, Int) = {
|
||||
data.target match {
|
||||
case target: PlayerSource =>
|
||||
InfantryDamageAfterResist(target.health, target.armor)
|
||||
if(data.projectile.profile.DamageToHealthOnly) {
|
||||
DamageToHealthOnly(target.health)
|
||||
} else {
|
||||
InfantryDamageAfterResist(target.health, target.armor)
|
||||
}
|
||||
case _ =>
|
||||
InfantryDamageAfterResist(0, 0)
|
||||
}
|
||||
}
|
||||
|
||||
def DamageToHealthOnly(currentHP: Int)(damages: Int, resistance: Int): (Int, Int) = {
|
||||
if (damages > 0 && currentHP > 0) {
|
||||
if(damages > resistance) {
|
||||
(damages - resistance, 0)
|
||||
} else {
|
||||
(damages, 0)
|
||||
}
|
||||
} else {
|
||||
(0, 0)
|
||||
}
|
||||
}
|
||||
|
||||
def InfantryDamageAfterResist(currentHP: Int, currentArmor: Int)(damages: Int, resistance: Int): (Int, Int) = {
|
||||
if (damages > 0 && currentHP > 0) {
|
||||
if (currentArmor <= 0) {
|
||||
|
|
@ -67,10 +83,14 @@ object ResolutionCalculations {
|
|||
}
|
||||
}
|
||||
|
||||
def MaxDamageAfterResist(data: ResolvedProjectile): (Int, Int) => (Int, Int) = {
|
||||
def MaxDamage(data: ResolvedProjectile): (Int, Int) => (Int, Int) = {
|
||||
data.target match {
|
||||
case target: PlayerSource =>
|
||||
MaxDamageAfterResist(target.health, target.armor)
|
||||
if(data.projectile.profile.DamageToHealthOnly) {
|
||||
DamageToHealthOnly(target.health)
|
||||
} else {
|
||||
MaxDamageAfterResist(target.health, target.armor)
|
||||
}
|
||||
case _ =>
|
||||
MaxDamageAfterResist(0, 0)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue