mirror of
https://github.com/2revoemag/PSF-BotServer.git
synced 2026-01-20 02:24:45 +00:00
timing and damage tuning around: standard, reinforced, max; plasma grenades, dragon
This commit is contained in:
parent
d149e07e89
commit
97e64d5edc
|
|
@ -3,19 +3,24 @@ package net.psforever.objects.avatar
|
|||
|
||||
import akka.actor.{Actor, Cancellable}
|
||||
import net.psforever.objects.Player
|
||||
import net.psforever.objects.ballistics.{AggravatedDamage, AggravatedInfo, ResolvedProjectile}
|
||||
import net.psforever.objects.vital.DamageType
|
||||
import net.psforever.objects.ballistics._
|
||||
import net.psforever.objects.serverobject.damage.Damageable
|
||||
import net.psforever.objects.vital.{DamageType, Vitality}
|
||||
import net.psforever.types.Vector3
|
||||
|
||||
import scala.collection.mutable
|
||||
import scala.concurrent.duration._
|
||||
import scala.concurrent.ExecutionContext.Implicits.global
|
||||
|
||||
trait AuraEffectBehavior {
|
||||
_ : Actor =>
|
||||
private var activeEffectIndex : Long = 0
|
||||
private var effectsToIds : mutable.HashMap[Aura.Value, List[Long]] = mutable.HashMap.empty[Aura.Value, List[Long]]
|
||||
private var idsToTimers : mutable.LongMap[Cancellable] = mutable.LongMap.empty[Cancellable]
|
||||
private var idsToEntries : mutable.LongMap[AuraEffectBehavior.Entry] = mutable.LongMap.empty[AuraEffectBehavior.Entry]
|
||||
_ : Actor with Damageable =>
|
||||
private var activeEffectIndex: Long = 0
|
||||
private val effectToEntryId: mutable.HashMap[Aura.Value, List[Long]] =
|
||||
mutable.HashMap.empty[Aura.Value, List[Long]]
|
||||
private val entryIdToTimer: mutable.LongMap[Cancellable] =
|
||||
mutable.LongMap.empty[Cancellable]
|
||||
private val entryIdToEntry: mutable.LongMap[AuraEffectBehavior.Entry] =
|
||||
mutable.LongMap.empty[AuraEffectBehavior.Entry]
|
||||
|
||||
def AuraTargetObject : Player
|
||||
|
||||
|
|
@ -25,114 +30,181 @@ trait AuraEffectBehavior {
|
|||
PerformCleanupEffect(id)
|
||||
|
||||
case AuraEffectBehavior.Aggravate(id, 0, leftoverTime) =>
|
||||
PerformAggravationAndRetimeEvent(id, iteration = 0, Some(leftoverTime), leftoverTime = 0)
|
||||
RemoveEffectEntry(id)
|
||||
RetimeEvent(id, iteration = 0, Some(leftoverTime), leftoverTime = 0)
|
||||
|
||||
case AuraEffectBehavior.Aggravate(id, iteration, leftover) => ;
|
||||
PerformAggravationAndRetimeEvent(id, iteration - 1, None, leftover)
|
||||
RetimeEventAndPerformAggravation(id, iteration - 1, None, leftover)
|
||||
}
|
||||
|
||||
def PerformAggravationAndRetimeEvent(id : Long, iteration : Int, time : Option[Long], leftoverTime : Long) : Unit = {
|
||||
private def RetimeEvent(
|
||||
id: Long,
|
||||
iteration: Int,
|
||||
time: Option[Long],
|
||||
leftoverTime: Long
|
||||
): Option[AuraEffectBehavior.Entry] = {
|
||||
CancelEffectTimer(id)
|
||||
idsToEntries.get(id) match {
|
||||
case Some(entry) =>
|
||||
//TODO stuff ...
|
||||
idsToTimers += id -> context.system.scheduler.scheduleOnce(
|
||||
time.getOrElse(entry.effect.infliction_rate) milliseconds,
|
||||
entryIdToEntry.get(id) match {
|
||||
case Some(oldEntry) =>
|
||||
val target = SourceEntry(AuraTargetObject)
|
||||
val entry = PairIdWithAggravationEntry(
|
||||
id,
|
||||
oldEntry.effect,
|
||||
oldEntry.retime,
|
||||
oldEntry.data,
|
||||
target,
|
||||
target.Position - oldEntry.data.target.Position
|
||||
)
|
||||
entryIdToTimer += id -> context.system.scheduler.scheduleOnce(
|
||||
time.getOrElse(entry.retime) milliseconds,
|
||||
self,
|
||||
AuraEffectBehavior.Aggravate(id, iteration, leftoverTime)
|
||||
)
|
||||
Some(entry)
|
||||
case _ =>
|
||||
PerformCleanupEffect(id)
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
def CancelEffectTimer(id : Long) : Unit = {
|
||||
idsToTimers.remove(id) match {
|
||||
private def RetimeEventAndPerformAggravation(id: Long, iteration: Int, time: Option[Long], leftoverTime: Long) : Unit = {
|
||||
RetimeEvent(id, iteration, time, leftoverTime) match {
|
||||
case Some(entry) =>
|
||||
PerformAggravation(entry)
|
||||
case _ => ;
|
||||
}
|
||||
}
|
||||
|
||||
def CancelEffectTimer(id: Long) : Unit = {
|
||||
entryIdToTimer.remove(id) match {
|
||||
case Some(timer) => timer.cancel
|
||||
case _ => ;
|
||||
}
|
||||
}
|
||||
|
||||
def PerformCleanupEffect(id : Long) : Unit = {
|
||||
def PerformCleanupEffect(id: Long) : Unit = {
|
||||
CleanupEffect(id) match {
|
||||
case Aura.None => ;
|
||||
case _ => UpdateAggravatedEffect(AuraTargetObject)
|
||||
}
|
||||
}
|
||||
|
||||
def TryAggravationEffect(data : ResolvedProjectile) : Unit = {
|
||||
def TryAggravationEffect(data: ResolvedProjectile) : Unit = {
|
||||
data.projectile.profile.Aggravated match {
|
||||
case Some(damage)
|
||||
if data.projectile.profile.ProjectileDamageType == DamageType.Aggravated && damage.effect_type != Aura.None =>
|
||||
if data.projectile.profile.ProjectileDamageTypes.contains(DamageType.Aggravated) &&
|
||||
damage.effect_type != Aura.None =>
|
||||
TryAggravationEffect(damage, data)
|
||||
case _ => ;
|
||||
}
|
||||
}
|
||||
|
||||
private def TryAggravationEffect(aggravation : AggravatedDamage, data : ResolvedProjectile) : Unit = {
|
||||
private def TryAggravationEffect(aggravation: AggravatedDamage, data: ResolvedProjectile) : Unit = {
|
||||
val effect = aggravation.effect_type
|
||||
val obj = AuraTargetObject
|
||||
if(obj.Aura.contains(effect)) { //TODO cumulative?
|
||||
SetupAggravationEntry(aggravation)
|
||||
}
|
||||
else if(obj.Aura.diff(obj.AddEffectToAura(effect)).contains(effect)) {
|
||||
SetupAggravationEntry(aggravation)
|
||||
UpdateAggravatedEffect(obj)
|
||||
}
|
||||
}
|
||||
|
||||
private def SetupAggravationEntry(aggravation : AggravatedDamage) : Unit = {
|
||||
val effect = aggravation.effect_type
|
||||
aggravation.info.foreach { infos =>
|
||||
//get unused id
|
||||
val id = activeEffectIndex
|
||||
activeEffectIndex += 1
|
||||
//pair aura effect with id
|
||||
effectsToIds.get(effect) match {
|
||||
case None | Some(Nil) => effectsToIds += effect -> List(id)
|
||||
case Some(list) => effectsToIds -> (list :+ id)
|
||||
if(CheckForUniqueUnqueuedProjectile(data.projectile)) {
|
||||
val auraEffects = obj.Aura
|
||||
if(auraEffects.contains(effect) && aggravation.cumulative_damage_degrade) { //TODO cumulative?
|
||||
SetupAggravationEntry(aggravation, data)
|
||||
}
|
||||
else if(obj.AddEffectToAura(effect).diff(auraEffects).contains(effect)) {
|
||||
SetupAggravationEntry(aggravation, data)
|
||||
UpdateAggravatedEffect(obj)
|
||||
}
|
||||
//pair id with entry
|
||||
idsToEntries += id -> AuraEffectBehavior.Entry(id, infos, aggravation, 0)
|
||||
//pair id with timer
|
||||
val iterations = (aggravation.duration / infos.infliction_rate).toInt
|
||||
val leftoverTime = aggravation.duration % infos.infliction_rate
|
||||
idsToTimers += id -> context.system.scheduler.scheduleOnce(infos.infliction_rate milliseconds, self, AuraEffectBehavior.Aggravate(id, iterations, leftoverTime))
|
||||
}
|
||||
}
|
||||
|
||||
def CleanupEffect(id : Long) : Aura.Value = {
|
||||
private def CheckForUniqueUnqueuedProjectile(projectile : Projectile) : Boolean = {
|
||||
!entryIdToEntry.values.exists { entry => entry.data.projectile eq projectile }
|
||||
}
|
||||
|
||||
private def SetupAggravationEntry(aggravation: AggravatedDamage, data: ResolvedProjectile) : Unit = {
|
||||
val effect = aggravation.effect_type
|
||||
aggravation.info.find(_.damage_type == AuraEffectBehavior.basicDamageType(data.resolution)) match {
|
||||
case Some(info) =>
|
||||
//get unused id
|
||||
val id = activeEffectIndex
|
||||
activeEffectIndex += 1
|
||||
//pair aura effect with id
|
||||
effectToEntryId.get(effect) match {
|
||||
case None | Some(Nil) => effectToEntryId += effect -> List(id)
|
||||
case Some(list) => effectToEntryId -> (list :+ id)
|
||||
}
|
||||
//pair id with timer
|
||||
val inflictionRate = info.infliction_rate
|
||||
val iterations = (aggravation.duration / inflictionRate).toInt
|
||||
val leftoverTime = aggravation.duration % inflictionRate
|
||||
entryIdToTimer += id -> context.system.scheduler.scheduleOnce(inflictionRate milliseconds, self, AuraEffectBehavior.Aggravate(id, iterations, leftoverTime))
|
||||
//pair id with entry
|
||||
PairIdWithAggravationEntry(id, effect, inflictionRate, data, data.target, Vector3.Zero)
|
||||
case _ => ;
|
||||
}
|
||||
}
|
||||
|
||||
private def PairIdWithAggravationEntry(
|
||||
id: Long,
|
||||
effect: Aura.Value,
|
||||
retime:Long,
|
||||
data: ResolvedProjectile,
|
||||
target: SourceEntry,
|
||||
offset: Vector3
|
||||
): AuraEffectBehavior.Entry = {
|
||||
val aggravatedDamageInfo = ResolvedProjectile(
|
||||
AuraEffectBehavior.burning(data.resolution),
|
||||
data.projectile,
|
||||
target,
|
||||
data.damage_model,
|
||||
data.hit_pos + offset
|
||||
)
|
||||
val entry = AuraEffectBehavior.Entry(id, effect, retime, aggravatedDamageInfo)
|
||||
entryIdToEntry += id -> entry
|
||||
entry
|
||||
}
|
||||
|
||||
def RemoveEffectEntry(id: Long) : Aura.Value = {
|
||||
entryIdToEntry.remove(id) match {
|
||||
case Some(entry) =>
|
||||
entry.data.projectile.profile.Aggravated.get.effect_type
|
||||
case None =>
|
||||
effectToEntryId.find { case (_, values) => values.contains(id) } match {
|
||||
case Some((effect, _)) => effect
|
||||
case _ => Aura.None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def CleanupEffect(id: Long) : Aura.Value = {
|
||||
//remove and cancel timer
|
||||
idsToTimers.remove(id) match {
|
||||
entryIdToTimer.remove(id) match {
|
||||
case Some(timer) => timer.cancel
|
||||
case _ => ;
|
||||
}
|
||||
//remove entry and cache effect
|
||||
val out = idsToEntries.remove(id) match {
|
||||
case Some(entry) => entry.aggravation.effect_type
|
||||
case _ => Aura.None
|
||||
}
|
||||
val out = RemoveEffectEntry(id)
|
||||
//remove id and, if now unsupported, effect
|
||||
(effectsToIds.get(out) match {
|
||||
(effectToEntryId.get(out) match {
|
||||
case Some(list) => (out, list.filterNot(_ == id))
|
||||
case _ => (Aura.None, Nil)
|
||||
}) match {
|
||||
case (Aura.None, _) =>
|
||||
Aura.None
|
||||
case (effect, Nil) =>
|
||||
effectsToIds.remove(effect)
|
||||
AuraTargetObject.RemoveEffectFromAura(effect)
|
||||
effectToEntryId.remove(effect)
|
||||
effect
|
||||
case (effect, list) =>
|
||||
effectsToIds += effect -> list
|
||||
effectToEntryId += effect -> list
|
||||
Aura.None
|
||||
}
|
||||
}
|
||||
|
||||
def EndAllEffects() : Unit = {
|
||||
idsToEntries.clear
|
||||
idsToTimers.values.foreach { _.cancel }
|
||||
idsToTimers.clear
|
||||
effectsToIds.clear
|
||||
entryIdToEntry.clear
|
||||
entryIdToTimer.values.foreach { _.cancel }
|
||||
entryIdToTimer.clear
|
||||
effectToEntryId.clear
|
||||
val obj = AuraTargetObject
|
||||
obj.Aura.foreach { obj.RemoveEffectFromAura }
|
||||
}
|
||||
|
||||
def EndAllEffectsAndUpdate() : Unit = {
|
||||
|
|
@ -140,16 +212,39 @@ trait AuraEffectBehavior {
|
|||
UpdateAggravatedEffect(AuraTargetObject)
|
||||
}
|
||||
|
||||
def UpdateAggravatedEffect(target : Player) : Unit = {
|
||||
def UpdateAggravatedEffect(target: Player) : Unit = {
|
||||
import services.avatar.{AvatarAction, AvatarServiceMessage}
|
||||
val zone = target.Zone
|
||||
val value = target.Aura.foldLeft(0)(_ + _.id)
|
||||
zone.AvatarEvents ! AvatarServiceMessage(zone.Id, AvatarAction.PlanetsideAttributeToAll(target.GUID, 54, value))
|
||||
}
|
||||
|
||||
private def PerformAggravation(entry: AuraEffectBehavior.Entry) : Unit = {
|
||||
TakesDamage.apply(Vitality.Damage(entry.data.damage_model.Calculate(entry.data)))
|
||||
}
|
||||
}
|
||||
|
||||
object AuraEffectBehavior {
|
||||
private case class Entry(id : Long, effect : AggravatedInfo, aggravation : AggravatedDamage, damage : Any)
|
||||
private case class Entry(id: Long, effect: Aura.Value, retime: Long, data: ResolvedProjectile)
|
||||
|
||||
private case class Aggravate(id : Long, iterations : Int, leftover : Long)
|
||||
private case class Aggravate(id: Long, iterations: Int, leftover: Long)
|
||||
|
||||
private def burning(resolution: ProjectileResolution.Value): ProjectileResolution.Value = {
|
||||
resolution match {
|
||||
case ProjectileResolution.AggravatedDirect => ProjectileResolution.AggravatedDirectBurn
|
||||
case ProjectileResolution.AggravatedSplash => ProjectileResolution.AggravatedSplashBurn
|
||||
case _ => resolution
|
||||
}
|
||||
}
|
||||
|
||||
private def basicDamageType(resolution: ProjectileResolution.Value): DamageType.Value = {
|
||||
resolution match {
|
||||
case ProjectileResolution.AggravatedDirect | ProjectileResolution.AggravatedDirectBurn =>
|
||||
DamageType.Direct
|
||||
case ProjectileResolution.AggravatedSplash | ProjectileResolution.AggravatedSplashBurn =>
|
||||
DamageType.Splash
|
||||
case _ =>
|
||||
DamageType.None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -302,7 +302,7 @@ class ResolutionCalculationsTests extends Specification {
|
|||
target1.DamageModel,
|
||||
Vector3.Zero
|
||||
)
|
||||
InfantryDamageAfterResist(resprojectile1)(50, 10) mustEqual (0, 0)
|
||||
InfantryDamage(resprojectile1)(50, 10) mustEqual (0, 0)
|
||||
|
||||
val target2 = player
|
||||
val resprojectile2 = ResolvedProjectile(
|
||||
|
|
@ -312,7 +312,7 @@ class ResolutionCalculationsTests extends Specification {
|
|||
target2.DamageModel,
|
||||
Vector3.Zero
|
||||
)
|
||||
InfantryDamageAfterResist(resprojectile2)(50, 10) mustEqual (40, 10)
|
||||
InfantryDamage(resprojectile2)(50, 10) mustEqual (40, 10)
|
||||
}
|
||||
|
||||
"calculate health and armor damage for infantry target" in {
|
||||
|
|
@ -346,7 +346,7 @@ class ResolutionCalculationsTests extends Specification {
|
|||
target1.DamageModel,
|
||||
Vector3.Zero
|
||||
)
|
||||
MaxDamageAfterResist(resprojectile1)(50, 10) mustEqual (0, 0)
|
||||
MaxDamage(resprojectile1)(50, 10) mustEqual (0, 0)
|
||||
|
||||
val target2 = player2
|
||||
val resprojectile2 = ResolvedProjectile(
|
||||
|
|
@ -356,7 +356,7 @@ class ResolutionCalculationsTests extends Specification {
|
|||
target2.DamageModel,
|
||||
Vector3.Zero
|
||||
)
|
||||
MaxDamageAfterResist(resprojectile2)(50, 10) mustEqual (0, 40)
|
||||
MaxDamage(resprojectile2)(50, 10) mustEqual (0, 40)
|
||||
}
|
||||
|
||||
"calculate health and armor damage for max target" in {
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@ class DamageableTest extends Specification {
|
|||
"permit damage" in {
|
||||
val target = new SensorDeployable(GlobalDefinitions.motionalarmsensor)
|
||||
val resolved = ResolvedProjectile(
|
||||
ProjectileResolution.Hit,
|
||||
Projectile(projectileA, weaponA.Definition, weaponA.FireMode, pSource, 0, Vector3.Zero, Vector3.Zero),
|
||||
SourceEntry(target),
|
||||
target.DamageModel,
|
||||
|
|
@ -52,6 +53,7 @@ class DamageableTest extends Specification {
|
|||
"ignore attempts at non-zero damage" in {
|
||||
val target = new SensorDeployable(GlobalDefinitions.motionalarmsensor)
|
||||
val resolved = ResolvedProjectile(
|
||||
ProjectileResolution.Hit,
|
||||
Projectile(
|
||||
projectileA,
|
||||
weaponA.Definition,
|
||||
|
|
@ -76,6 +78,7 @@ class DamageableTest extends Specification {
|
|||
Faction = player1.Faction
|
||||
}
|
||||
val resolved = ResolvedProjectile(
|
||||
ProjectileResolution.Hit,
|
||||
Projectile(projectileA, weaponA.Definition, weaponA.FireMode, pSource, 0, Vector3.Zero, Vector3.Zero),
|
||||
SourceEntry(target),
|
||||
target.DamageModel,
|
||||
|
|
@ -98,6 +101,7 @@ class DamageableTest extends Specification {
|
|||
Faction = PlanetSideEmpire.NC
|
||||
}
|
||||
val resolved = ResolvedProjectile(
|
||||
ProjectileResolution.Hit,
|
||||
Projectile(projectileA, weaponA.Definition, weaponA.FireMode, pSource, 0, Vector3.Zero, Vector3.Zero),
|
||||
SourceEntry(target),
|
||||
target.DamageModel,
|
||||
|
|
@ -124,6 +128,7 @@ class DamageableTest extends Specification {
|
|||
Faction = player1.Faction
|
||||
}
|
||||
val resolved = ResolvedProjectile(
|
||||
ProjectileResolution.Hit,
|
||||
Projectile(projectileA, weaponA.Definition, weaponA.FireMode, pSource, 0, Vector3.Zero, Vector3.Zero),
|
||||
SourceEntry(target),
|
||||
target.DamageModel,
|
||||
|
|
@ -147,6 +152,7 @@ class DamageableTest extends Specification {
|
|||
"permit jamming" in {
|
||||
val target = new SensorDeployable(GlobalDefinitions.motionalarmsensor)
|
||||
val resolved = ResolvedProjectile(
|
||||
ProjectileResolution.Hit,
|
||||
Projectile(projectileB, weaponB.Definition, weaponB.FireMode, pSource, 0, Vector3.Zero, Vector3.Zero),
|
||||
SourceEntry(target),
|
||||
target.DamageModel,
|
||||
|
|
@ -160,6 +166,7 @@ class DamageableTest extends Specification {
|
|||
"ignore attempts at jamming if the projectile is does not cause the effect" in {
|
||||
val target = new SensorDeployable(GlobalDefinitions.motionalarmsensor)
|
||||
val resolved = ResolvedProjectile(
|
||||
ProjectileResolution.Hit,
|
||||
Projectile(projectileA, weaponA.Definition, weaponA.FireMode, pSource, 0, Vector3.Zero, Vector3.Zero),
|
||||
SourceEntry(target),
|
||||
target.DamageModel,
|
||||
|
|
@ -174,6 +181,7 @@ class DamageableTest extends Specification {
|
|||
val target = new SensorDeployable(GlobalDefinitions.motionalarmsensor)
|
||||
target.Faction = player1.Faction
|
||||
val resolved = ResolvedProjectile(
|
||||
ProjectileResolution.Hit,
|
||||
Projectile(projectileB, weaponB.Definition, weaponB.FireMode, pSource, 0, Vector3.Zero, Vector3.Zero),
|
||||
SourceEntry(target),
|
||||
target.DamageModel,
|
||||
|
|
@ -188,6 +196,7 @@ class DamageableTest extends Specification {
|
|||
"ignore attempts at jamming targets that are not jammable" in {
|
||||
val target = new TrapDeployable(GlobalDefinitions.tank_traps)
|
||||
val resolved = ResolvedProjectile(
|
||||
ProjectileResolution.Hit,
|
||||
Projectile(projectileB, weaponB.Definition, weaponB.FireMode, pSource, 0, Vector3.Zero, Vector3.Zero),
|
||||
SourceEntry(target),
|
||||
target.DamageModel,
|
||||
|
|
@ -207,6 +216,7 @@ class DamageableTest extends Specification {
|
|||
val target = new SensorDeployable(GlobalDefinitions.motionalarmsensor)
|
||||
target.Faction = player1.Faction
|
||||
val resolved = ResolvedProjectile(
|
||||
ProjectileResolution.Hit,
|
||||
Projectile(projectileB, weaponB.Definition, weaponB.FireMode, pSource, 0, Vector3.Zero, Vector3.Zero),
|
||||
SourceEntry(target),
|
||||
target.DamageModel,
|
||||
|
|
@ -261,6 +271,7 @@ class DamageableEntityDamageTest extends ActorTest {
|
|||
val weapon = Tool(GlobalDefinitions.phoenix) //decimator
|
||||
val projectile = weapon.Projectile
|
||||
val resolved = ResolvedProjectile(
|
||||
ProjectileResolution.Hit,
|
||||
Projectile(
|
||||
projectile,
|
||||
weapon.Definition,
|
||||
|
|
@ -331,6 +342,7 @@ class DamageableEntityDestroyedTest extends ActorTest {
|
|||
val weapon = Tool(GlobalDefinitions.phoenix) //decimator
|
||||
val projectile = weapon.Projectile
|
||||
val resolved = ResolvedProjectile(
|
||||
ProjectileResolution.Hit,
|
||||
Projectile(
|
||||
projectile,
|
||||
weapon.Definition,
|
||||
|
|
@ -404,6 +416,7 @@ class DamageableEntityNotDestroyTwice extends ActorTest {
|
|||
val weapon = Tool(GlobalDefinitions.phoenix) //decimator
|
||||
val projectile = weapon.Projectile
|
||||
val resolved = ResolvedProjectile(
|
||||
ProjectileResolution.Hit,
|
||||
Projectile(
|
||||
projectile,
|
||||
weapon.Definition,
|
||||
|
|
@ -474,6 +487,7 @@ class DamageableAmenityTest extends ActorTest {
|
|||
val weapon = Tool(GlobalDefinitions.phoenix) //decimator
|
||||
val projectile = weapon.Projectile
|
||||
val resolved = ResolvedProjectile(
|
||||
ProjectileResolution.Hit,
|
||||
Projectile(
|
||||
projectile,
|
||||
weapon.Definition,
|
||||
|
|
@ -566,6 +580,7 @@ class DamageableMountableDamageTest extends ActorTest {
|
|||
val weapon = Tool(GlobalDefinitions.phoenix) //decimator
|
||||
val projectile = weapon.Projectile
|
||||
val resolved = ResolvedProjectile(
|
||||
ProjectileResolution.Hit,
|
||||
Projectile(
|
||||
projectile,
|
||||
weapon.Definition,
|
||||
|
|
@ -660,6 +675,7 @@ class DamageableMountableDestroyTest extends ActorTest {
|
|||
val weapon = Tool(GlobalDefinitions.phoenix) //decimator
|
||||
val projectile = weapon.Projectile
|
||||
val resolved = ResolvedProjectile(
|
||||
ProjectileResolution.Hit,
|
||||
Projectile(
|
||||
projectile,
|
||||
weapon.Definition,
|
||||
|
|
@ -748,6 +764,7 @@ class DamageableWeaponTurretDamageTest extends ActorTest {
|
|||
val projectile = weapon.Projectile
|
||||
val turretSource = SourceEntry(turret)
|
||||
val resolved = ResolvedProjectile(
|
||||
ProjectileResolution.Hit,
|
||||
Projectile(
|
||||
projectile,
|
||||
weapon.Definition,
|
||||
|
|
@ -845,6 +862,7 @@ class DamageableWeaponTurretJammerTest extends ActorTest {
|
|||
val projectile = weapon.Projectile
|
||||
val turretSource = SourceEntry(turret)
|
||||
val resolved = ResolvedProjectile(
|
||||
ProjectileResolution.Hit,
|
||||
Projectile(
|
||||
projectile,
|
||||
weapon.Definition,
|
||||
|
|
@ -946,6 +964,7 @@ class DamageableWeaponTurretDestructionTest extends ActorTest {
|
|||
val weaponA = Tool(GlobalDefinitions.jammer_grenade)
|
||||
val projectileA = weaponA.Projectile
|
||||
val resolvedA = ResolvedProjectile(
|
||||
ProjectileResolution.Hit,
|
||||
Projectile(
|
||||
projectileA,
|
||||
weaponA.Definition,
|
||||
|
|
@ -964,6 +983,7 @@ class DamageableWeaponTurretDestructionTest extends ActorTest {
|
|||
val weaponB = Tool(GlobalDefinitions.phoenix) //decimator
|
||||
val projectileB = weaponB.Projectile
|
||||
val resolvedB = ResolvedProjectile(
|
||||
ProjectileResolution.Hit,
|
||||
Projectile(
|
||||
projectileB,
|
||||
weaponB.Definition,
|
||||
|
|
@ -1085,6 +1105,7 @@ class DamageableVehicleDamageTest extends ActorTest {
|
|||
val projectile = weapon.Projectile
|
||||
val vehicleSource = SourceEntry(atv)
|
||||
val resolved = ResolvedProjectile(
|
||||
ProjectileResolution.Hit,
|
||||
Projectile(
|
||||
projectile,
|
||||
weapon.Definition,
|
||||
|
|
@ -1216,6 +1237,7 @@ class DamageableVehicleDamageMountedTest extends ActorTest {
|
|||
val projectile = weapon.Projectile
|
||||
val vehicleSource = SourceEntry(lodestar)
|
||||
val resolved = ResolvedProjectile(
|
||||
ProjectileResolution.Hit,
|
||||
Projectile(
|
||||
projectile,
|
||||
weapon.Definition,
|
||||
|
|
@ -1363,6 +1385,7 @@ class DamageableVehicleJammeringMountedTest extends ActorTest {
|
|||
val weapon = Tool(GlobalDefinitions.jammer_grenade)
|
||||
val projectile = weapon.Projectile
|
||||
val resolved = ResolvedProjectile(
|
||||
ProjectileResolution.Hit,
|
||||
Projectile(
|
||||
projectile,
|
||||
weapon.Definition,
|
||||
|
|
@ -1452,6 +1475,7 @@ class DamageableVehicleDestroyTest extends ActorTest {
|
|||
val projectile = weapon.Projectile
|
||||
val vehicleSource = SourceEntry(atv)
|
||||
val resolved = ResolvedProjectile(
|
||||
ProjectileResolution.Hit,
|
||||
Projectile(
|
||||
projectile,
|
||||
weapon.Definition,
|
||||
|
|
@ -1577,6 +1601,7 @@ class DamageableVehicleDestroyMountedTest extends ActorTest {
|
|||
val weaponA = Tool(GlobalDefinitions.jammer_grenade)
|
||||
val projectileA = weaponA.Projectile
|
||||
val resolvedA = ResolvedProjectile(
|
||||
ProjectileResolution.Hit,
|
||||
Projectile(
|
||||
projectileA,
|
||||
weaponA.Definition,
|
||||
|
|
@ -1595,6 +1620,7 @@ class DamageableVehicleDestroyMountedTest extends ActorTest {
|
|||
val weaponB = Tool(GlobalDefinitions.phoenix) //decimator
|
||||
val projectileB = weaponB.Projectile
|
||||
val resolvedB = ResolvedProjectile(
|
||||
ProjectileResolution.Hit,
|
||||
Projectile(
|
||||
projectileB,
|
||||
weaponB.Definition,
|
||||
|
|
|
|||
|
|
@ -334,6 +334,7 @@ class ExplosiveDeployableJammerTest extends ActorTest {
|
|||
val pSource = PlayerSource(player1)
|
||||
val projectile = weapon.Projectile
|
||||
val resolved = ResolvedProjectile(
|
||||
ProjectileResolution.Hit,
|
||||
Projectile(projectile, weapon.Definition, weapon.FireMode, pSource, 0, Vector3.Zero, Vector3.Zero),
|
||||
jMineSource,
|
||||
j_mine.DamageModel,
|
||||
|
|
@ -373,7 +374,7 @@ class ExplosiveDeployableJammerTest extends ActorTest {
|
|||
assert(
|
||||
msg_local(2) match {
|
||||
case LocalServiceMessage.Deployables(SupportActor.ClearSpecific(List(target), _zone)) =>
|
||||
(target eq j_mine) && (_zone eq zone)
|
||||
(j_mine eq target) && (_zone eq zone)
|
||||
case _ => false
|
||||
}
|
||||
)
|
||||
|
|
@ -431,6 +432,7 @@ class ExplosiveDeployableJammerExplodeTest extends ActorTest {
|
|||
val pSource = PlayerSource(player1)
|
||||
val projectile = weapon.Projectile
|
||||
val resolved = ResolvedProjectile(
|
||||
ProjectileResolution.Hit,
|
||||
Projectile(projectile, weapon.Definition, weapon.FireMode, pSource, 0, Vector3.Zero, Vector3.Zero),
|
||||
hMineSource,
|
||||
h_mine.DamageModel,
|
||||
|
|
@ -476,7 +478,7 @@ class ExplosiveDeployableJammerExplodeTest extends ActorTest {
|
|||
assert(
|
||||
msg_local(3) match {
|
||||
case LocalServiceMessage.Deployables(SupportActor.ClearSpecific(List(target), _zone)) =>
|
||||
(target eq h_mine) && (_zone eq zone)
|
||||
(h_mine eq target) && (_zone eq zone)
|
||||
case _ => false
|
||||
}
|
||||
)
|
||||
|
|
@ -540,6 +542,7 @@ class ExplosiveDeployableDestructionTest extends ActorTest {
|
|||
val pSource = PlayerSource(player1)
|
||||
val projectile = weapon.Projectile
|
||||
val resolved = ResolvedProjectile(
|
||||
ProjectileResolution.Hit,
|
||||
Projectile(projectile, weapon.Definition, weapon.FireMode, pSource, 0, Vector3.Zero, Vector3.Zero),
|
||||
hMineSource,
|
||||
h_mine.DamageModel,
|
||||
|
|
@ -581,7 +584,7 @@ class ExplosiveDeployableDestructionTest extends ActorTest {
|
|||
assert(
|
||||
msg_local(2) match {
|
||||
case LocalServiceMessage.Deployables(SupportActor.ClearSpecific(List(target), _zone)) =>
|
||||
(target eq h_mine) && (_zone eq zone)
|
||||
(h_mine eq target) && (_zone eq zone)
|
||||
case _ => false
|
||||
}
|
||||
)
|
||||
|
|
|
|||
|
|
@ -80,6 +80,7 @@ class GeneratorControlDamageTest extends ActorTest {
|
|||
val weapon = Tool(GlobalDefinitions.phoenix) //decimator
|
||||
val projectile = weapon.Projectile
|
||||
val resolved = ResolvedProjectile(
|
||||
ProjectileResolution.Hit,
|
||||
Projectile(
|
||||
projectile,
|
||||
weapon.Definition,
|
||||
|
|
@ -161,6 +162,7 @@ class GeneratorControlCriticalTest extends ActorTest {
|
|||
val weapon = Tool(GlobalDefinitions.phoenix) //decimator
|
||||
val projectile = weapon.Projectile
|
||||
val resolved = ResolvedProjectile(
|
||||
ProjectileResolution.Hit,
|
||||
Projectile(
|
||||
projectile,
|
||||
weapon.Definition,
|
||||
|
|
@ -251,6 +253,7 @@ class GeneratorControlDestroyedTest extends ActorTest {
|
|||
val weapon = Tool(GlobalDefinitions.phoenix) //decimator
|
||||
val projectile = weapon.Projectile
|
||||
val resolved = ResolvedProjectile(
|
||||
ProjectileResolution.Hit,
|
||||
Projectile(
|
||||
projectile,
|
||||
weapon.Definition,
|
||||
|
|
@ -381,6 +384,7 @@ class GeneratorControlKillsTest extends ActorTest {
|
|||
val weapon = Tool(GlobalDefinitions.phoenix) //decimator
|
||||
val projectile = weapon.Projectile
|
||||
val resolved = ResolvedProjectile(
|
||||
ProjectileResolution.Hit,
|
||||
Projectile(
|
||||
projectile,
|
||||
weapon.Definition,
|
||||
|
|
@ -503,6 +507,7 @@ class GeneratorControlNotDestroyTwice extends ActorTest {
|
|||
val weapon = Tool(GlobalDefinitions.phoenix) //decimator
|
||||
val projectile = weapon.Projectile
|
||||
val resolved = ResolvedProjectile(
|
||||
ProjectileResolution.Hit,
|
||||
Projectile(
|
||||
projectile,
|
||||
weapon.Definition,
|
||||
|
|
@ -592,6 +597,7 @@ class GeneratorControlNotDamageIfExplodingTest extends ActorTest {
|
|||
val weapon = Tool(GlobalDefinitions.phoenix) //decimator
|
||||
val projectile = weapon.Projectile
|
||||
val resolved = ResolvedProjectile(
|
||||
ProjectileResolution.Hit,
|
||||
Projectile(
|
||||
projectile,
|
||||
weapon.Definition,
|
||||
|
|
@ -685,6 +691,7 @@ class GeneratorControlNotRepairIfExplodingTest extends ActorTest {
|
|||
val weapon = Tool(GlobalDefinitions.phoenix) //decimator
|
||||
val projectile = weapon.Projectile
|
||||
val resolved = ResolvedProjectile(
|
||||
ProjectileResolution.Hit,
|
||||
Projectile(
|
||||
projectile,
|
||||
weapon.Definition,
|
||||
|
|
|
|||
|
|
@ -378,6 +378,7 @@ class PlayerControlDamageTest extends ActorTest {
|
|||
val projectile = tool.Projectile
|
||||
val playerSource = SourceEntry(player2)
|
||||
val resolved = ResolvedProjectile(
|
||||
ProjectileResolution.Hit,
|
||||
Projectile(
|
||||
projectile,
|
||||
tool.Definition,
|
||||
|
|
@ -477,6 +478,7 @@ class PlayerControlDeathStandingTest extends ActorTest {
|
|||
val projectile = tool.Projectile
|
||||
val player1Source = SourceEntry(player1)
|
||||
val resolved = ResolvedProjectile(
|
||||
ProjectileResolution.Hit,
|
||||
Projectile(projectile, tool.Definition, tool.FireMode, player1Source, 0, Vector3(2, 0, 0), Vector3(-1, 0, 0)),
|
||||
SourceEntry(player2),
|
||||
player2.DamageModel,
|
||||
|
|
@ -605,6 +607,7 @@ class PlayerControlDeathSeatedTest extends ActorTest {
|
|||
val projectile = tool.Projectile
|
||||
val player1Source = SourceEntry(player1)
|
||||
val resolved = ResolvedProjectile(
|
||||
ProjectileResolution.Hit,
|
||||
Projectile(projectile, tool.Definition, tool.FireMode, player1Source, 0, Vector3(2, 0, 0), Vector3(-1, 0, 0)),
|
||||
SourceEntry(player2),
|
||||
player2.DamageModel,
|
||||
|
|
|
|||
|
|
@ -352,6 +352,7 @@ class ProjectileTest extends Specification {
|
|||
|
||||
"construct" in {
|
||||
val obj = ResolvedProjectile(
|
||||
ProjectileResolution.Hit,
|
||||
projectile,
|
||||
PlayerSource(player2),
|
||||
fury_dm,
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ class VitalityTest extends Specification {
|
|||
val pSource = PlayerSource(player)
|
||||
val projectile = Projectile(proj, wep, wep_fmode, player, Vector3(2, 2, 0), Vector3.Zero)
|
||||
val resprojectile = ResolvedProjectile(
|
||||
ProjectileResolution.Hit,
|
||||
projectile,
|
||||
SourceEntry(player),
|
||||
player.DamageModel,
|
||||
|
|
@ -68,6 +69,7 @@ class VitalityTest extends Specification {
|
|||
val pSource = PlayerSource(player)
|
||||
val projectile = Projectile(proj, wep, wep_fmode, player, Vector3(2, 2, 0), Vector3.Zero)
|
||||
val resprojectile = ResolvedProjectile(
|
||||
ProjectileResolution.Hit,
|
||||
projectile,
|
||||
SourceEntry(player),
|
||||
player.DamageModel,
|
||||
|
|
|
|||
Loading…
Reference in a new issue