mirror of
https://github.com/2revoemag/PSF-BotServer.git
synced 2026-01-19 18:14:44 +00:00
Last Infantry Weapons (#987)
* preparations for deploying oicw little buddy projectiles * oicw little buddy projectiles spawn and animate properly, but damage dealing is inconclusive * radiator clouds cause damage to infantry health * oicw little buddy projectiles do damage upon detonation; different descent pattern; projectile types given own Enumeration * proximity terminals for vehicle actions no longer need to use the vehicle event system as a middleman for making changes * redid the workflow of the proximity terminal resolution so that it avoids SessionActor as much as is possible; this may be a mistake, but my future self will pay the price instead * changed the timing and the angles of the little buddy explosions; fixed proximity terminal tests
This commit is contained in:
parent
2b58d126b5
commit
0d8c717b73
|
|
@ -12,7 +12,7 @@ ignore:
|
||||||
- "src/main/scala/net/psforever/objects/ObjectType.scala"
|
- "src/main/scala/net/psforever/objects/ObjectType.scala"
|
||||||
- "src/main/scala/net/psforever/objects/avatar/Avatars.scala"
|
- "src/main/scala/net/psforever/objects/avatar/Avatars.scala"
|
||||||
- "src/main/scala/net/psforever/objects/ballistics/DamageResolution.scala"
|
- "src/main/scala/net/psforever/objects/ballistics/DamageResolution.scala"
|
||||||
- "src/main/scala/net/psforever/objects/ballistics/Projectiles.scala"
|
- "src/main/scala/net/psforever/objects/ballistics/Projectiles.Types.scala"
|
||||||
- "src/main/scala/net/psforever/objects/equipment/Ammo.scala"
|
- "src/main/scala/net/psforever/objects/equipment/Ammo.scala"
|
||||||
- "src/main/scala/net/psforever/objects/equipment/CItem.scala"
|
- "src/main/scala/net/psforever/objects/equipment/CItem.scala"
|
||||||
- "src/main/scala/net/psforever/objects/equipment/EquipmentSize.scala"
|
- "src/main/scala/net/psforever/objects/equipment/EquipmentSize.scala"
|
||||||
|
|
|
||||||
|
|
@ -659,8 +659,10 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con
|
||||||
case Terminal.TerminalMessage(tplayer, msg, order) =>
|
case Terminal.TerminalMessage(tplayer, msg, order) =>
|
||||||
HandleTerminalMessage(tplayer, msg, order)
|
HandleTerminalMessage(tplayer, msg, order)
|
||||||
|
|
||||||
case ProximityUnit.Action(term, target) =>
|
case ProximityUnit.Action(_, _) => ;
|
||||||
SelectProximityUnitBehavior(term, target)
|
|
||||||
|
case ProximityUnit.StopAction(term, target) =>
|
||||||
|
LocalStopUsingProximityUnit(term, target)
|
||||||
|
|
||||||
case VehicleServiceResponse(toChannel, guid, reply) =>
|
case VehicleServiceResponse(toChannel, guid, reply) =>
|
||||||
HandleVehicleServiceResponse(toChannel, guid, reply)
|
HandleVehicleServiceResponse(toChannel, guid, reply)
|
||||||
|
|
@ -5200,7 +5202,6 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con
|
||||||
}
|
}
|
||||||
|
|
||||||
case msg @ GenericObjectActionAtPositionMessage(object_guid, _, _) =>
|
case msg @ GenericObjectActionAtPositionMessage(object_guid, _, _) =>
|
||||||
//log.info(s"$msg")
|
|
||||||
ValidObject(object_guid, decorator = "GenericObjectActionAtPosition") match {
|
ValidObject(object_guid, decorator = "GenericObjectActionAtPosition") match {
|
||||||
case Some(tool: Tool) if GlobalDefinitions.isBattleFrameNTUSiphon(tool.Definition) =>
|
case Some(tool: Tool) if GlobalDefinitions.isBattleFrameNTUSiphon(tool.Definition) =>
|
||||||
FindContainedWeapon match {
|
FindContainedWeapon match {
|
||||||
|
|
@ -5208,7 +5209,8 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con
|
||||||
vehicle.Actor ! SpecialEmp.Burst()
|
vehicle.Actor ! SpecialEmp.Burst()
|
||||||
case _ => ;
|
case _ => ;
|
||||||
}
|
}
|
||||||
case _ => ;
|
case _ =>
|
||||||
|
log.info(s"$msg")
|
||||||
}
|
}
|
||||||
|
|
||||||
case msg @ GenericObjectStateMsg(object_guid, unk1) =>
|
case msg @ GenericObjectStateMsg(object_guid, unk1) =>
|
||||||
|
|
@ -5381,6 +5383,7 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con
|
||||||
_, //projectile_type,
|
_, //projectile_type,
|
||||||
thrown_projectile_vel
|
thrown_projectile_vel
|
||||||
) =>
|
) =>
|
||||||
|
log.info(s"$msg")
|
||||||
HandleWeaponFire(weapon_guid, projectile_guid, shot_origin, thrown_projectile_vel.flatten)
|
HandleWeaponFire(weapon_guid, projectile_guid, shot_origin, thrown_projectile_vel.flatten)
|
||||||
|
|
||||||
case WeaponLazeTargetPositionMessage(_, _, _) => ;
|
case WeaponLazeTargetPositionMessage(_, _, _) => ;
|
||||||
|
|
@ -7535,7 +7538,7 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Queue a proximity-base service.
|
* Queue a proximity-based service.
|
||||||
* @param terminal the proximity-based unit
|
* @param terminal the proximity-based unit
|
||||||
* @param target the entity that is being considered for terminal operation
|
* @param target the entity that is being considered for terminal operation
|
||||||
*/
|
*/
|
||||||
|
|
@ -7547,7 +7550,7 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con
|
||||||
case _: Player =>
|
case _: Player =>
|
||||||
terminal.Actor ! CommonMessages.Use(player, Some(target))
|
terminal.Actor ! CommonMessages.Use(player, Some(target))
|
||||||
case _: Vehicle =>
|
case _: Vehicle =>
|
||||||
terminal.Actor ! CommonMessages.Use(player, Some((target, continent.VehicleEvents)))
|
terminal.Actor ! CommonMessages.Use(player, Some(target))
|
||||||
case _ =>
|
case _ =>
|
||||||
log.error(
|
log.error(
|
||||||
s"StartUsingProximityUnit: ${player.Name}, this ${terminal.Definition.Name} can not deal with target $target"
|
s"StartUsingProximityUnit: ${player.Name}, this ${terminal.Definition.Name} can not deal with target $target"
|
||||||
|
|
@ -7562,38 +7565,30 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determine which functionality to pursue by a generic proximity-functional unit given the target for its activity.
|
* Stop using a proximity-base service.
|
||||||
* @see `VehicleService:receive, ProximityUnit.Action`
|
* If the suggested terminal detects our player or our player's vehicle as a valid target for its effect,
|
||||||
|
* inform it that we wish it stop affecting the discovered target(s).
|
||||||
* @param terminal the proximity-based unit
|
* @param terminal the proximity-based unit
|
||||||
* @param target the object being affected by the unit
|
|
||||||
*/
|
*/
|
||||||
def SelectProximityUnitBehavior(terminal: Terminal with ProximityUnit, target: PlanetSideGameObject): Unit = {
|
def StopUsingProximityUnit(terminal: Terminal with ProximityUnit): Unit = {
|
||||||
target match {
|
FindProximityUnitTargetsInScope(terminal).foreach { target =>
|
||||||
case o: Player =>
|
LocalStopUsingProximityUnit(terminal, target)
|
||||||
HealthAndArmorTerminal(terminal, o)
|
terminal.Actor ! CommonMessages.Unuse(player, Some(target))
|
||||||
case _ => ;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stop using a proximity-base service.
|
* Stop using a proximity-base service.
|
||||||
|
* Callback to handle flags specific to `SessionActor`.
|
||||||
* Special note is warranted when determining the identity of the proximity terminal.
|
* Special note is warranted when determining the identity of the proximity terminal.
|
||||||
* Medical terminals of both varieties can be cancelled by movement.
|
* Medical terminals of both varieties can be cancelled by movement.
|
||||||
* Other sorts of proximity-based units are put on a timer.
|
* Other sorts of proximity-based units are put on a timer.
|
||||||
* @param terminal the proximity-based unit
|
* @param terminal the proximity-based unit
|
||||||
*/
|
*/
|
||||||
def StopUsingProximityUnit(terminal: Terminal with ProximityUnit): Unit = {
|
def LocalStopUsingProximityUnit(terminal: Terminal with ProximityUnit, target: PlanetSideGameObject): Unit = {
|
||||||
val term_guid = terminal.GUID
|
val term_guid = terminal.GUID
|
||||||
val targets = FindProximityUnitTargetsInScope(terminal)
|
if (usingMedicalTerminal.contains(term_guid)) {
|
||||||
if (targets.nonEmpty) {
|
usingMedicalTerminal = None
|
||||||
if (usingMedicalTerminal.contains(term_guid)) {
|
|
||||||
usingMedicalTerminal = None
|
|
||||||
}
|
|
||||||
targets.foreach(target => terminal.Actor ! CommonMessages.Unuse(player, Some(target)))
|
|
||||||
} else {
|
|
||||||
log.warn(
|
|
||||||
s"StopUsingProximityUnit: ${player.Name} could not find valid targets for proximity unit ${terminal.Definition.Name}@${term_guid.guid}"
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -7623,72 +7618,6 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* When standing on the platform of a(n advanced) medical terminal,
|
|
||||||
* resotre the player's health and armor points (when they need their health and armor points restored).
|
|
||||||
* If the player is both fully healed and fully repaired, stop using the terminal.
|
|
||||||
* @param unit the medical terminal
|
|
||||||
* @param target the player being healed
|
|
||||||
*/
|
|
||||||
def HealthAndArmorTerminal(unit: Terminal with ProximityUnit, target: Player): Unit = {
|
|
||||||
val medDef = unit.Definition.asInstanceOf[MedicalTerminalDefinition]
|
|
||||||
val healAmount = medDef.HealAmount
|
|
||||||
val healthFull: Boolean = if (healAmount != 0 && target.Health < target.MaxHealth) {
|
|
||||||
target.History(HealFromTerm(PlayerSource(target), healAmount, 0, medDef))
|
|
||||||
HealAction(target, healAmount)
|
|
||||||
} else {
|
|
||||||
true
|
|
||||||
}
|
|
||||||
val repairAmount = medDef.ArmorAmount
|
|
||||||
val armorFull: Boolean = if (repairAmount != 0 && target.Armor < target.MaxArmor) {
|
|
||||||
target.History(HealFromTerm(PlayerSource(target), 0, repairAmount, medDef))
|
|
||||||
ArmorRepairAction(target, repairAmount)
|
|
||||||
} else {
|
|
||||||
true
|
|
||||||
}
|
|
||||||
if (healthFull && armorFull) {
|
|
||||||
StopUsingProximityUnit(unit)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Restore, at most, a specific amount of health points on a player.
|
|
||||||
* Send messages to connected client and to events system.
|
|
||||||
* @param tplayer the player
|
|
||||||
* @param healValue the amount to heal;
|
|
||||||
* 10 by default
|
|
||||||
* @return whether the player can be repaired for any more health points
|
|
||||||
*/
|
|
||||||
def HealAction(tplayer: Player, healValue: Int = 10): Boolean = {
|
|
||||||
val player_guid = tplayer.GUID
|
|
||||||
tplayer.Health = tplayer.Health + healValue
|
|
||||||
sendResponse(PlanetsideAttributeMessage(player_guid, 0, tplayer.Health))
|
|
||||||
continent.AvatarEvents ! AvatarServiceMessage(
|
|
||||||
continent.id,
|
|
||||||
AvatarAction.PlanetsideAttribute(player_guid, 0, tplayer.Health)
|
|
||||||
)
|
|
||||||
tplayer.Health == tplayer.MaxHealth
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Restore, at most, a specific amount of personal armor points on a player.
|
|
||||||
* Send messages to connected client and to events system.
|
|
||||||
* @param tplayer the player
|
|
||||||
* @param repairValue the amount to repair;
|
|
||||||
* 10 by default
|
|
||||||
* @return whether the player can be repaired for any more armor points
|
|
||||||
*/
|
|
||||||
def ArmorRepairAction(tplayer: Player, repairValue: Int = 10): Boolean = {
|
|
||||||
val player_guid = tplayer.GUID
|
|
||||||
tplayer.Armor = tplayer.Armor + repairValue
|
|
||||||
sendResponse(PlanetsideAttributeMessage(player_guid, 4, tplayer.Armor))
|
|
||||||
continent.AvatarEvents ! AvatarServiceMessage(
|
|
||||||
continent.id,
|
|
||||||
AvatarAction.PlanetsideAttribute(player_guid, 4, tplayer.Armor)
|
|
||||||
)
|
|
||||||
tplayer.Armor == tplayer.MaxArmor
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This function is applied to vehicles that are leaving a cargo vehicle's cargo hold to auto reverse them out
|
* This function is applied to vehicles that are leaving a cargo vehicle's cargo hold to auto reverse them out
|
||||||
* Lock all applicable controls of the current vehicle
|
* Lock all applicable controls of the current vehicle
|
||||||
|
|
@ -9353,40 +9282,110 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con
|
||||||
hitPos: Vector3
|
hitPos: Vector3
|
||||||
): List[(PlanetSideGameObject with FactionAffinity with Vitality, Projectile, Vector3, Vector3)] = {
|
): List[(PlanetSideGameObject with FactionAffinity with Vitality, Projectile, Vector3, Vector3)] = {
|
||||||
GlobalDefinitions.getDamageProxy(projectile, hitPos) match {
|
GlobalDefinitions.getDamageProxy(projectile, hitPos) match {
|
||||||
case Some(proxy) if proxy.profile.ExistsOnRemoteClients =>
|
case Nil =>
|
||||||
proxy.Position = hitPos
|
|
||||||
continent.Projectile ! ZoneProjectile.Add(player.GUID, proxy)
|
|
||||||
Nil
|
Nil
|
||||||
|
case list =>
|
||||||
case Some(proxy)
|
HandleDamageProxySetupLittleBuddy(list, hitPos)
|
||||||
if proxy.tool_def == GlobalDefinitions.maelstrom =>
|
list.flatMap { proxy =>
|
||||||
//server-side maelstrom grenade target selection
|
if (proxy.profile.ExistsOnRemoteClients) {
|
||||||
val radius = proxy.profile.LashRadius * proxy.profile.LashRadius
|
proxy.Position = hitPos
|
||||||
val targets = continent.blockMap
|
continent.Projectile ! ZoneProjectile.Add(player.GUID, proxy)
|
||||||
.sector(hitPos, proxy.profile.LashRadius)
|
Nil
|
||||||
.livePlayerList
|
} else if (proxy.tool_def == GlobalDefinitions.maelstrom) {
|
||||||
.filter { target =>
|
//server-side maelstrom grenade target selection
|
||||||
Vector3.DistanceSquared(target.Position, hitPos) <= radius
|
val radius = proxy.profile.LashRadius * proxy.profile.LashRadius
|
||||||
}
|
val targets = continent.blockMap
|
||||||
//chainlash is separated from the actual damage application for convenience
|
.sector(hitPos, proxy.profile.LashRadius)
|
||||||
continent.AvatarEvents ! AvatarServiceMessage(
|
.livePlayerList
|
||||||
continent.id,
|
.filter { target =>
|
||||||
AvatarAction.SendResponse(
|
Vector3.DistanceSquared(target.Position, hitPos) <= radius
|
||||||
PlanetSideGUID(0),
|
}
|
||||||
ChainLashMessage(
|
//chainlash is separated from the actual damage application for convenience
|
||||||
hitPos,
|
continent.AvatarEvents ! AvatarServiceMessage(
|
||||||
projectile.profile.ObjectId,
|
continent.id,
|
||||||
targets.map { _.GUID }
|
AvatarAction.SendResponse(
|
||||||
|
PlanetSideGUID(0),
|
||||||
|
ChainLashMessage(
|
||||||
|
hitPos,
|
||||||
|
projectile.profile.ObjectId,
|
||||||
|
targets.map { _.GUID }
|
||||||
|
)
|
||||||
|
)
|
||||||
)
|
)
|
||||||
)
|
targets.map { target =>
|
||||||
)
|
CheckForHitPositionDiscrepancy(pguid, hitPos, target)
|
||||||
targets.map { target =>
|
(target, proxy, hitPos, target.Position)
|
||||||
CheckForHitPositionDiscrepancy(pguid, hitPos, target)
|
}
|
||||||
(target, proxy, hitPos, target.Position)
|
} else {
|
||||||
|
Nil
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
case _ =>
|
def HandleDamageProxySetupLittleBuddy(listOfProjectiles: List[Projectile], detonationPosition: Vector3): Boolean = {
|
||||||
Nil
|
val listOfLittleBuddies: List[Projectile] = listOfProjectiles.filter { _.tool_def == GlobalDefinitions.oicw }
|
||||||
|
val size: Int = listOfLittleBuddies.size
|
||||||
|
if (size > 0) {
|
||||||
|
val desiredDownwardsProjectiles: Int = 2
|
||||||
|
val firstHalf: Int = math.min(size, desiredDownwardsProjectiles) //number that fly straight down
|
||||||
|
val secondHalf: Int = math.max(size - firstHalf, 0) //number that are flared out
|
||||||
|
val z: Float = player.Orientation.z //player's standing direction
|
||||||
|
val north: Vector3 = Vector3(0,1,0) //map North
|
||||||
|
val speed: Float = 144f //speed (packet discovered)
|
||||||
|
val dist: Float = 25 //distance (client defined)
|
||||||
|
val downwardsAngle: Float = -85f
|
||||||
|
val flaredAngle: Float = -70f
|
||||||
|
//angle of separation for downwards, degrees from vertical for flared out
|
||||||
|
val (smallStep, smallAngle): (Float, Float) = if (firstHalf > 1) {
|
||||||
|
(360f / firstHalf, downwardsAngle)
|
||||||
|
} else {
|
||||||
|
(0f, 0f)
|
||||||
|
}
|
||||||
|
val (largeStep, largeAngle): (Float, Float) = if (secondHalf > 1) {
|
||||||
|
(360f / secondHalf, flaredAngle)
|
||||||
|
} else {
|
||||||
|
(0f, 0f)
|
||||||
|
}
|
||||||
|
val smallRotOffset: Float = z + 90f
|
||||||
|
val largeRotOffset: Float = z + math.random().toFloat * 45f
|
||||||
|
val verticalCorrection = Vector3.z(dist - dist * math.sin(math.toRadians(90 - smallAngle + largeAngle)).toFloat)
|
||||||
|
//downwards projectiles
|
||||||
|
var i: Int = 0
|
||||||
|
listOfLittleBuddies.take(firstHalf).foreach { proxy =>
|
||||||
|
val facing = (smallRotOffset + smallStep * i.toFloat) % 360
|
||||||
|
val dir = north.Rx(smallAngle).Rz(facing)
|
||||||
|
proxy.Position = detonationPosition + dir.xy + verticalCorrection
|
||||||
|
proxy.Velocity = dir * speed
|
||||||
|
proxy.Orientation = Vector3(0, (360f + smallAngle) % 360, facing)
|
||||||
|
HandleDamageProxyLittleBuddyExplosion(proxy, dir, dist)
|
||||||
|
i += 1
|
||||||
|
}
|
||||||
|
//flared out projectiles
|
||||||
|
i = 0
|
||||||
|
listOfLittleBuddies.drop(firstHalf).foreach { proxy =>
|
||||||
|
val facing = (largeRotOffset + largeStep * i.toFloat) % 360
|
||||||
|
val dir = north.Rx(largeAngle).Rz(facing)
|
||||||
|
proxy.Position = detonationPosition + dir
|
||||||
|
proxy.Velocity = dir * speed
|
||||||
|
proxy.Orientation = Vector3(0, (360f + largeAngle) % 360, facing)
|
||||||
|
HandleDamageProxyLittleBuddyExplosion(proxy, dir, dist)
|
||||||
|
i += 1
|
||||||
|
}
|
||||||
|
true
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def HandleDamageProxyLittleBuddyExplosion(proxy: Projectile, orientation: Vector3, distance: Float): Unit = {
|
||||||
|
//explosion
|
||||||
|
val obj = DummyExplodingEntity(proxy)
|
||||||
|
obj.Position = obj.Position + orientation * distance
|
||||||
|
context.system.scheduler.scheduleOnce(500.milliseconds) {
|
||||||
|
val c = continent
|
||||||
|
val o = obj
|
||||||
|
Zone.serverSideDamage(c, o, Zone.explosionDamage(None, o.Position))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,64 @@
|
||||||
|
// Copyright (c) 2022 PSForever
|
||||||
|
package net.psforever.objects
|
||||||
|
|
||||||
|
import net.psforever.objects.definition.{ObjectDefinition, ProjectileDefinition}
|
||||||
|
import net.psforever.objects.serverobject.affinity.FactionAffinity
|
||||||
|
import net.psforever.objects.vital.resolution.{DamageAndResistance, DamageResistanceModel}
|
||||||
|
import net.psforever.objects.vital.{Vitality, VitalityDefinition}
|
||||||
|
import net.psforever.types.{PlanetSideEmpire, Vector3}
|
||||||
|
|
||||||
|
class DummyExplodingEntity(
|
||||||
|
private val obj: PlanetSideGameObject,
|
||||||
|
private val faction: PlanetSideEmpire.Value
|
||||||
|
)
|
||||||
|
extends PlanetSideGameObject
|
||||||
|
with FactionAffinity
|
||||||
|
with Vitality {
|
||||||
|
override def GUID = obj.GUID
|
||||||
|
|
||||||
|
override def Position: Vector3 = {
|
||||||
|
if (super.Position == Vector3.Zero) {
|
||||||
|
obj.Position
|
||||||
|
} else {
|
||||||
|
super.Position
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override def Orientation: Vector3 = {
|
||||||
|
if (super.Orientation == Vector3.Zero) {
|
||||||
|
obj.Orientation
|
||||||
|
} else {
|
||||||
|
super.Orientation
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override def Velocity : Option[Vector3] = {
|
||||||
|
super.Velocity.orElse(obj.Velocity)
|
||||||
|
}
|
||||||
|
|
||||||
|
def Faction: PlanetSideEmpire.Value = faction
|
||||||
|
|
||||||
|
def DamageModel: DamageAndResistance = DummyExplodingEntity.DefaultDamageResistanceModel
|
||||||
|
|
||||||
|
def Definition: ObjectDefinition with VitalityDefinition = {
|
||||||
|
new DefinitionWrappedInVitality(obj.Definition)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class DefinitionWrappedInVitality(definition: ObjectDefinition)
|
||||||
|
extends ObjectDefinition(definition.ObjectId)
|
||||||
|
with VitalityDefinition {
|
||||||
|
innateDamage = definition match {
|
||||||
|
case v: VitalityDefinition if v.innateDamage.nonEmpty => v.innateDamage.get
|
||||||
|
case p: ProjectileDefinition => p
|
||||||
|
case _ => GlobalDefinitions.no_projectile
|
||||||
|
}
|
||||||
|
|
||||||
|
DefaultHealth = 1 //just cuz
|
||||||
|
}
|
||||||
|
|
||||||
|
object DummyExplodingEntity {
|
||||||
|
final val DefaultDamageResistanceModel = new DamageResistanceModel { }
|
||||||
|
|
||||||
|
def apply(obj: PlanetSideGameObject): DummyExplodingEntity = new DummyExplodingEntity(obj, PlanetSideEmpire.NEUTRAL)
|
||||||
|
}
|
||||||
|
|
@ -28,7 +28,7 @@ import net.psforever.objects.serverobject.turret.{FacilityTurretDefinition, Turr
|
||||||
import net.psforever.objects.vehicles.{DestroyedVehicle, InternalTelepadDefinition, UtilityType, VehicleSubsystemEntry}
|
import net.psforever.objects.vehicles.{DestroyedVehicle, InternalTelepadDefinition, UtilityType, VehicleSubsystemEntry}
|
||||||
import net.psforever.objects.vital.base.DamageType
|
import net.psforever.objects.vital.base.DamageType
|
||||||
import net.psforever.objects.vital.damage._
|
import net.psforever.objects.vital.damage._
|
||||||
import net.psforever.objects.vital.etc.{ArmorSiphonMaxDistanceCutoff, ExplodingRadialDegrade, InfantryAggravatedRadiation, InfantryAggravatedRadiationBurn}
|
import net.psforever.objects.vital.etc.{ShieldAgainstRadiation => _, _}
|
||||||
import net.psforever.objects.vital.projectile._
|
import net.psforever.objects.vital.projectile._
|
||||||
import net.psforever.objects.vital.prop.DamageWithPosition
|
import net.psforever.objects.vital.prop.DamageWithPosition
|
||||||
import net.psforever.objects.vital._
|
import net.psforever.objects.vital._
|
||||||
|
|
@ -147,299 +147,299 @@ object GlobalDefinitions {
|
||||||
*/
|
*/
|
||||||
val no_projectile = new ProjectileDefinition(0) //also called none in ADB
|
val no_projectile = new ProjectileDefinition(0) //also called none in ADB
|
||||||
|
|
||||||
val bullet_105mm_projectile = ProjectileDefinition(Projectiles.bullet_105mm_projectile)
|
val bullet_105mm_projectile = ProjectileDefinition(Projectiles.Types.bullet_105mm_projectile)
|
||||||
|
|
||||||
val bullet_12mm_projectile = ProjectileDefinition(Projectiles.bullet_12mm_projectile)
|
val bullet_12mm_projectile = ProjectileDefinition(Projectiles.Types.bullet_12mm_projectile)
|
||||||
|
|
||||||
val bullet_12mm_projectileb = ProjectileDefinition(Projectiles.bullet_12mm_projectileb)
|
val bullet_12mm_projectileb = ProjectileDefinition(Projectiles.Types.bullet_12mm_projectileb)
|
||||||
|
|
||||||
val bullet_150mm_projectile = ProjectileDefinition(Projectiles.bullet_150mm_projectile)
|
val bullet_150mm_projectile = ProjectileDefinition(Projectiles.Types.bullet_150mm_projectile)
|
||||||
|
|
||||||
val bullet_15mm_apc_projectile = ProjectileDefinition(Projectiles.bullet_15mm_apc_projectile)
|
val bullet_15mm_apc_projectile = ProjectileDefinition(Projectiles.Types.bullet_15mm_apc_projectile)
|
||||||
|
|
||||||
val bullet_15mm_projectile = ProjectileDefinition(Projectiles.bullet_15mm_projectile)
|
val bullet_15mm_projectile = ProjectileDefinition(Projectiles.Types.bullet_15mm_projectile)
|
||||||
|
|
||||||
val bullet_20mm_apc_projectile = ProjectileDefinition(Projectiles.bullet_20mm_apc_projectile)
|
val bullet_20mm_apc_projectile = ProjectileDefinition(Projectiles.Types.bullet_20mm_apc_projectile)
|
||||||
|
|
||||||
val bullet_20mm_projectile = ProjectileDefinition(Projectiles.bullet_20mm_projectile)
|
val bullet_20mm_projectile = ProjectileDefinition(Projectiles.Types.bullet_20mm_projectile)
|
||||||
|
|
||||||
val bullet_25mm_projectile = ProjectileDefinition(Projectiles.bullet_25mm_projectile)
|
val bullet_25mm_projectile = ProjectileDefinition(Projectiles.Types.bullet_25mm_projectile)
|
||||||
|
|
||||||
val bullet_35mm_projectile = ProjectileDefinition(Projectiles.bullet_35mm_projectile)
|
val bullet_35mm_projectile = ProjectileDefinition(Projectiles.Types.bullet_35mm_projectile)
|
||||||
|
|
||||||
val bullet_75mm_apc_projectile = ProjectileDefinition(Projectiles.bullet_75mm_apc_projectile)
|
val bullet_75mm_apc_projectile = ProjectileDefinition(Projectiles.Types.bullet_75mm_apc_projectile)
|
||||||
|
|
||||||
val bullet_75mm_projectile = ProjectileDefinition(Projectiles.bullet_75mm_projectile)
|
val bullet_75mm_projectile = ProjectileDefinition(Projectiles.Types.bullet_75mm_projectile)
|
||||||
|
|
||||||
val bullet_9mm_AP_projectile = ProjectileDefinition(Projectiles.bullet_9mm_AP_projectile)
|
val bullet_9mm_AP_projectile = ProjectileDefinition(Projectiles.Types.bullet_9mm_AP_projectile)
|
||||||
|
|
||||||
val bullet_9mm_projectile = ProjectileDefinition(Projectiles.bullet_9mm_projectile)
|
val bullet_9mm_projectile = ProjectileDefinition(Projectiles.Types.bullet_9mm_projectile)
|
||||||
|
|
||||||
val anniversary_projectilea = ProjectileDefinition(Projectiles.anniversary_projectilea)
|
val anniversary_projectilea = ProjectileDefinition(Projectiles.Types.anniversary_projectilea)
|
||||||
|
|
||||||
val anniversary_projectileb = ProjectileDefinition(Projectiles.anniversary_projectileb)
|
val anniversary_projectileb = ProjectileDefinition(Projectiles.Types.anniversary_projectileb)
|
||||||
|
|
||||||
val aphelion_immolation_cannon_projectile = ProjectileDefinition(Projectiles.aphelion_immolation_cannon_projectile)
|
val aphelion_immolation_cannon_projectile = ProjectileDefinition(Projectiles.Types.aphelion_immolation_cannon_projectile)
|
||||||
|
|
||||||
val aphelion_laser_projectile = ProjectileDefinition(Projectiles.aphelion_laser_projectile)
|
val aphelion_laser_projectile = ProjectileDefinition(Projectiles.Types.aphelion_laser_projectile)
|
||||||
|
|
||||||
val aphelion_plasma_cloud = ProjectileDefinition(Projectiles.aphelion_plasma_cloud)
|
val aphelion_plasma_cloud = ProjectileDefinition(Projectiles.Types.aphelion_plasma_cloud)
|
||||||
|
|
||||||
val aphelion_plasma_rocket_projectile = ProjectileDefinition(Projectiles.aphelion_plasma_rocket_projectile)
|
val aphelion_plasma_rocket_projectile = ProjectileDefinition(Projectiles.Types.aphelion_plasma_rocket_projectile)
|
||||||
|
|
||||||
val aphelion_ppa_projectile = ProjectileDefinition(Projectiles.aphelion_ppa_projectile)
|
val aphelion_ppa_projectile = ProjectileDefinition(Projectiles.Types.aphelion_ppa_projectile)
|
||||||
|
|
||||||
val aphelion_starfire_projectile = ProjectileDefinition(Projectiles.aphelion_starfire_projectile)
|
val aphelion_starfire_projectile = ProjectileDefinition(Projectiles.Types.aphelion_starfire_projectile)
|
||||||
|
|
||||||
val bolt_projectile = ProjectileDefinition(Projectiles.bolt_projectile)
|
val bolt_projectile = ProjectileDefinition(Projectiles.Types.bolt_projectile)
|
||||||
|
|
||||||
val burster_projectile = ProjectileDefinition(Projectiles.burster_projectile)
|
val burster_projectile = ProjectileDefinition(Projectiles.Types.burster_projectile)
|
||||||
|
|
||||||
val chainblade_projectile = ProjectileDefinition(Projectiles.chainblade_projectile)
|
val chainblade_projectile = ProjectileDefinition(Projectiles.Types.chainblade_projectile)
|
||||||
|
|
||||||
val colossus_100mm_projectile = ProjectileDefinition(Projectiles.colossus_100mm_projectile)
|
val colossus_100mm_projectile = ProjectileDefinition(Projectiles.Types.colossus_100mm_projectile)
|
||||||
|
|
||||||
val colossus_burster_projectile = ProjectileDefinition(Projectiles.colossus_burster_projectile)
|
val colossus_burster_projectile = ProjectileDefinition(Projectiles.Types.colossus_burster_projectile)
|
||||||
|
|
||||||
val colossus_chaingun_projectile = ProjectileDefinition(Projectiles.colossus_chaingun_projectile)
|
val colossus_chaingun_projectile = ProjectileDefinition(Projectiles.Types.colossus_chaingun_projectile)
|
||||||
|
|
||||||
val colossus_cluster_bomb_projectile = ProjectileDefinition(Projectiles.colossus_cluster_bomb_projectile)
|
val colossus_cluster_bomb_projectile = ProjectileDefinition(Projectiles.Types.colossus_cluster_bomb_projectile)
|
||||||
|
|
||||||
val colossus_tank_cannon_projectile = ProjectileDefinition(Projectiles.colossus_tank_cannon_projectile)
|
val colossus_tank_cannon_projectile = ProjectileDefinition(Projectiles.Types.colossus_tank_cannon_projectile)
|
||||||
|
|
||||||
val comet_projectile = ProjectileDefinition(Projectiles.comet_projectile)
|
val comet_projectile = ProjectileDefinition(Projectiles.Types.comet_projectile)
|
||||||
|
|
||||||
val dualcycler_projectile = ProjectileDefinition(Projectiles.dualcycler_projectile)
|
val dualcycler_projectile = ProjectileDefinition(Projectiles.Types.dualcycler_projectile)
|
||||||
|
|
||||||
val dynomite_projectile = ProjectileDefinition(Projectiles.dynomite_projectile)
|
val dynomite_projectile = ProjectileDefinition(Projectiles.Types.dynomite_projectile)
|
||||||
|
|
||||||
val energy_cell_projectile = ProjectileDefinition(Projectiles.energy_cell_projectile)
|
val energy_cell_projectile = ProjectileDefinition(Projectiles.Types.energy_cell_projectile)
|
||||||
|
|
||||||
val energy_gun_nc_projectile = ProjectileDefinition(Projectiles.energy_gun_nc_projectile)
|
val energy_gun_nc_projectile = ProjectileDefinition(Projectiles.Types.energy_gun_nc_projectile)
|
||||||
|
|
||||||
val energy_gun_tr_projectile = ProjectileDefinition(Projectiles.energy_gun_tr_projectile)
|
val energy_gun_tr_projectile = ProjectileDefinition(Projectiles.Types.energy_gun_tr_projectile)
|
||||||
|
|
||||||
val energy_gun_vs_projectile = ProjectileDefinition(Projectiles.energy_gun_vs_projectile)
|
val energy_gun_vs_projectile = ProjectileDefinition(Projectiles.Types.energy_gun_vs_projectile)
|
||||||
|
|
||||||
val enhanced_energy_cell_projectile = ProjectileDefinition(Projectiles.enhanced_energy_cell_projectile)
|
val enhanced_energy_cell_projectile = ProjectileDefinition(Projectiles.Types.enhanced_energy_cell_projectile)
|
||||||
|
|
||||||
val enhanced_quasar_projectile = ProjectileDefinition(Projectiles.enhanced_quasar_projectile)
|
val enhanced_quasar_projectile = ProjectileDefinition(Projectiles.Types.enhanced_quasar_projectile)
|
||||||
|
|
||||||
val falcon_projectile = ProjectileDefinition(Projectiles.falcon_projectile)
|
val falcon_projectile = ProjectileDefinition(Projectiles.Types.falcon_projectile)
|
||||||
|
|
||||||
val firebird_missile_projectile = ProjectileDefinition(Projectiles.firebird_missile_projectile)
|
val firebird_missile_projectile = ProjectileDefinition(Projectiles.Types.firebird_missile_projectile)
|
||||||
|
|
||||||
val flail_projectile = ProjectileDefinition(Projectiles.flail_projectile)
|
val flail_projectile = ProjectileDefinition(Projectiles.Types.flail_projectile)
|
||||||
|
|
||||||
val flamethrower_fire_cloud = ProjectileDefinition(Projectiles.flamethrower_fire_cloud)
|
val flamethrower_fire_cloud = ProjectileDefinition(Projectiles.Types.flamethrower_fire_cloud)
|
||||||
|
|
||||||
val flamethrower_fireball = ProjectileDefinition(Projectiles.flamethrower_fireball)
|
val flamethrower_fireball = ProjectileDefinition(Projectiles.Types.flamethrower_fireball)
|
||||||
|
|
||||||
val flamethrower_projectile = ProjectileDefinition(Projectiles.flamethrower_projectile)
|
val flamethrower_projectile = ProjectileDefinition(Projectiles.Types.flamethrower_projectile)
|
||||||
|
|
||||||
val flux_cannon_apc_projectile = ProjectileDefinition(Projectiles.flux_cannon_apc_projectile)
|
val flux_cannon_apc_projectile = ProjectileDefinition(Projectiles.Types.flux_cannon_apc_projectile)
|
||||||
|
|
||||||
val flux_cannon_thresher_projectile = ProjectileDefinition(Projectiles.flux_cannon_thresher_projectile)
|
val flux_cannon_thresher_projectile = ProjectileDefinition(Projectiles.Types.flux_cannon_thresher_projectile)
|
||||||
|
|
||||||
val fluxpod_projectile = ProjectileDefinition(Projectiles.fluxpod_projectile)
|
val fluxpod_projectile = ProjectileDefinition(Projectiles.Types.fluxpod_projectile)
|
||||||
|
|
||||||
val forceblade_projectile = ProjectileDefinition(Projectiles.forceblade_projectile)
|
val forceblade_projectile = ProjectileDefinition(Projectiles.Types.forceblade_projectile)
|
||||||
|
|
||||||
val frag_cartridge_projectile = ProjectileDefinition(Projectiles.frag_cartridge_projectile)
|
val frag_cartridge_projectile = ProjectileDefinition(Projectiles.Types.frag_cartridge_projectile)
|
||||||
|
|
||||||
val frag_cartridge_projectile_b = ProjectileDefinition(Projectiles.frag_cartridge_projectile_b)
|
val frag_cartridge_projectile_b = ProjectileDefinition(Projectiles.Types.frag_cartridge_projectile_b)
|
||||||
|
|
||||||
val frag_grenade_projectile = ProjectileDefinition(Projectiles.frag_grenade_projectile)
|
val frag_grenade_projectile = ProjectileDefinition(Projectiles.Types.frag_grenade_projectile)
|
||||||
|
|
||||||
val frag_grenade_projectile_enh = ProjectileDefinition(Projectiles.frag_grenade_projectile_enh)
|
val frag_grenade_projectile_enh = ProjectileDefinition(Projectiles.Types.frag_grenade_projectile_enh)
|
||||||
|
|
||||||
val galaxy_gunship_gun_projectile = ProjectileDefinition(Projectiles.galaxy_gunship_gun_projectile)
|
val galaxy_gunship_gun_projectile = ProjectileDefinition(Projectiles.Types.galaxy_gunship_gun_projectile)
|
||||||
|
|
||||||
val gauss_cannon_projectile = ProjectileDefinition(Projectiles.gauss_cannon_projectile)
|
val gauss_cannon_projectile = ProjectileDefinition(Projectiles.Types.gauss_cannon_projectile)
|
||||||
|
|
||||||
val grenade_projectile = ProjectileDefinition(Projectiles.grenade_projectile)
|
val grenade_projectile = ProjectileDefinition(Projectiles.Types.grenade_projectile)
|
||||||
|
|
||||||
val heavy_grenade_projectile = ProjectileDefinition(Projectiles.heavy_grenade_projectile)
|
val heavy_grenade_projectile = ProjectileDefinition(Projectiles.Types.heavy_grenade_projectile)
|
||||||
|
|
||||||
val heavy_rail_beam_projectile = ProjectileDefinition(Projectiles.heavy_rail_beam_projectile)
|
val heavy_rail_beam_projectile = ProjectileDefinition(Projectiles.Types.heavy_rail_beam_projectile)
|
||||||
|
|
||||||
val heavy_sniper_projectile = ProjectileDefinition(Projectiles.heavy_sniper_projectile)
|
val heavy_sniper_projectile = ProjectileDefinition(Projectiles.Types.heavy_sniper_projectile)
|
||||||
|
|
||||||
val hellfire_projectile = ProjectileDefinition(Projectiles.hellfire_projectile)
|
val hellfire_projectile = ProjectileDefinition(Projectiles.Types.hellfire_projectile)
|
||||||
|
|
||||||
val hunter_seeker_missile_dumbfire = ProjectileDefinition(Projectiles.hunter_seeker_missile_dumbfire)
|
val hunter_seeker_missile_dumbfire = ProjectileDefinition(Projectiles.Types.hunter_seeker_missile_dumbfire)
|
||||||
|
|
||||||
val hunter_seeker_missile_projectile = ProjectileDefinition(Projectiles.hunter_seeker_missile_projectile)
|
val hunter_seeker_missile_projectile = ProjectileDefinition(Projectiles.Types.hunter_seeker_missile_projectile)
|
||||||
|
|
||||||
val jammer_cartridge_projectile = ProjectileDefinition(Projectiles.jammer_cartridge_projectile)
|
val jammer_cartridge_projectile = ProjectileDefinition(Projectiles.Types.jammer_cartridge_projectile)
|
||||||
|
|
||||||
val jammer_cartridge_projectile_b = ProjectileDefinition(Projectiles.jammer_cartridge_projectile_b)
|
val jammer_cartridge_projectile_b = ProjectileDefinition(Projectiles.Types.jammer_cartridge_projectile_b)
|
||||||
|
|
||||||
val jammer_grenade_projectile = ProjectileDefinition(Projectiles.jammer_grenade_projectile)
|
val jammer_grenade_projectile = ProjectileDefinition(Projectiles.Types.jammer_grenade_projectile)
|
||||||
|
|
||||||
val jammer_grenade_projectile_enh = ProjectileDefinition(Projectiles.jammer_grenade_projectile_enh)
|
val jammer_grenade_projectile_enh = ProjectileDefinition(Projectiles.Types.jammer_grenade_projectile_enh)
|
||||||
|
|
||||||
val katana_projectile = ProjectileDefinition(Projectiles.katana_projectile)
|
val katana_projectile = ProjectileDefinition(Projectiles.Types.katana_projectile)
|
||||||
|
|
||||||
val katana_projectileb = ProjectileDefinition(Projectiles.katana_projectileb)
|
val katana_projectileb = ProjectileDefinition(Projectiles.Types.katana_projectileb)
|
||||||
|
|
||||||
val lancer_projectile = ProjectileDefinition(Projectiles.lancer_projectile)
|
val lancer_projectile = ProjectileDefinition(Projectiles.Types.lancer_projectile)
|
||||||
|
|
||||||
val lasher_projectile = ProjectileDefinition(Projectiles.lasher_projectile)
|
val lasher_projectile = ProjectileDefinition(Projectiles.Types.lasher_projectile)
|
||||||
|
|
||||||
val lasher_projectile_ap = ProjectileDefinition(Projectiles.lasher_projectile_ap)
|
val lasher_projectile_ap = ProjectileDefinition(Projectiles.Types.lasher_projectile_ap)
|
||||||
|
|
||||||
val liberator_bomb_cluster_bomblet_projectile = ProjectileDefinition(
|
val liberator_bomb_cluster_bomblet_projectile = ProjectileDefinition(
|
||||||
Projectiles.liberator_bomb_cluster_bomblet_projectile
|
Projectiles.Types.liberator_bomb_cluster_bomblet_projectile
|
||||||
)
|
)
|
||||||
|
|
||||||
val liberator_bomb_cluster_projectile = ProjectileDefinition(Projectiles.liberator_bomb_cluster_projectile)
|
val liberator_bomb_cluster_projectile = ProjectileDefinition(Projectiles.Types.liberator_bomb_cluster_projectile)
|
||||||
|
|
||||||
val liberator_bomb_projectile = ProjectileDefinition(Projectiles.liberator_bomb_projectile)
|
val liberator_bomb_projectile = ProjectileDefinition(Projectiles.Types.liberator_bomb_projectile)
|
||||||
|
|
||||||
val maelstrom_grenade_damager = ProjectileDefinition(Projectiles.maelstrom_grenade_damager)
|
val maelstrom_grenade_damager = ProjectileDefinition(Projectiles.Types.maelstrom_grenade_damager)
|
||||||
|
|
||||||
val maelstrom_grenade_projectile = ProjectileDefinition(Projectiles.maelstrom_grenade_projectile)
|
val maelstrom_grenade_projectile = ProjectileDefinition(Projectiles.Types.maelstrom_grenade_projectile)
|
||||||
|
|
||||||
val maelstrom_grenade_projectile_contact = ProjectileDefinition(Projectiles.maelstrom_grenade_projectile_contact)
|
val maelstrom_grenade_projectile_contact = ProjectileDefinition(Projectiles.Types.maelstrom_grenade_projectile_contact)
|
||||||
|
|
||||||
val maelstrom_stream_projectile = ProjectileDefinition(Projectiles.maelstrom_stream_projectile)
|
val maelstrom_stream_projectile = ProjectileDefinition(Projectiles.Types.maelstrom_stream_projectile)
|
||||||
|
|
||||||
val magcutter_projectile = ProjectileDefinition(Projectiles.magcutter_projectile)
|
val magcutter_projectile = ProjectileDefinition(Projectiles.Types.magcutter_projectile)
|
||||||
|
|
||||||
val melee_ammo_projectile = ProjectileDefinition(Projectiles.melee_ammo_projectile)
|
val melee_ammo_projectile = ProjectileDefinition(Projectiles.Types.melee_ammo_projectile)
|
||||||
|
|
||||||
val meteor_common = ProjectileDefinition(Projectiles.meteor_common)
|
val meteor_common = ProjectileDefinition(Projectiles.Types.meteor_common)
|
||||||
|
|
||||||
val meteor_projectile_b_large = ProjectileDefinition(Projectiles.meteor_projectile_b_large)
|
val meteor_projectile_b_large = ProjectileDefinition(Projectiles.Types.meteor_projectile_b_large)
|
||||||
|
|
||||||
val meteor_projectile_b_medium = ProjectileDefinition(Projectiles.meteor_projectile_b_medium)
|
val meteor_projectile_b_medium = ProjectileDefinition(Projectiles.Types.meteor_projectile_b_medium)
|
||||||
|
|
||||||
val meteor_projectile_b_small = ProjectileDefinition(Projectiles.meteor_projectile_b_small)
|
val meteor_projectile_b_small = ProjectileDefinition(Projectiles.Types.meteor_projectile_b_small)
|
||||||
|
|
||||||
val meteor_projectile_large = ProjectileDefinition(Projectiles.meteor_projectile_large)
|
val meteor_projectile_large = ProjectileDefinition(Projectiles.Types.meteor_projectile_large)
|
||||||
|
|
||||||
val meteor_projectile_medium = ProjectileDefinition(Projectiles.meteor_projectile_medium)
|
val meteor_projectile_medium = ProjectileDefinition(Projectiles.Types.meteor_projectile_medium)
|
||||||
|
|
||||||
val meteor_projectile_small = ProjectileDefinition(Projectiles.meteor_projectile_small)
|
val meteor_projectile_small = ProjectileDefinition(Projectiles.Types.meteor_projectile_small)
|
||||||
|
|
||||||
val mine_projectile = ProjectileDefinition(Projectiles.mine_projectile)
|
val mine_projectile = ProjectileDefinition(Projectiles.Types.mine_projectile)
|
||||||
|
|
||||||
val mine_sweeper_projectile = ProjectileDefinition(Projectiles.mine_sweeper_projectile)
|
val mine_sweeper_projectile = ProjectileDefinition(Projectiles.Types.mine_sweeper_projectile)
|
||||||
|
|
||||||
val mine_sweeper_projectile_enh = ProjectileDefinition(Projectiles.mine_sweeper_projectile_enh)
|
val mine_sweeper_projectile_enh = ProjectileDefinition(Projectiles.Types.mine_sweeper_projectile_enh)
|
||||||
|
|
||||||
val oicw_projectile = ProjectileDefinition(Projectiles.oicw_projectile)
|
val oicw_projectile = ProjectileDefinition(Projectiles.Types.oicw_projectile)
|
||||||
|
|
||||||
val oicw_little_buddy = ProjectileDefinition(Projectiles.oicw_little_buddy)
|
val oicw_little_buddy = ProjectileDefinition(Projectiles.Types.oicw_little_buddy)
|
||||||
|
|
||||||
val pellet_gun_projectile = ProjectileDefinition(Projectiles.pellet_gun_projectile)
|
val pellet_gun_projectile = ProjectileDefinition(Projectiles.Types.pellet_gun_projectile)
|
||||||
|
|
||||||
val peregrine_dual_machine_gun_projectile = ProjectileDefinition(Projectiles.peregrine_dual_machine_gun_projectile)
|
val peregrine_dual_machine_gun_projectile = ProjectileDefinition(Projectiles.Types.peregrine_dual_machine_gun_projectile)
|
||||||
|
|
||||||
val peregrine_mechhammer_projectile = ProjectileDefinition(Projectiles.peregrine_mechhammer_projectile)
|
val peregrine_mechhammer_projectile = ProjectileDefinition(Projectiles.Types.peregrine_mechhammer_projectile)
|
||||||
|
|
||||||
val peregrine_particle_cannon_projectile = ProjectileDefinition(Projectiles.peregrine_particle_cannon_projectile)
|
val peregrine_particle_cannon_projectile = ProjectileDefinition(Projectiles.Types.peregrine_particle_cannon_projectile)
|
||||||
|
|
||||||
val peregrine_particle_cannon_radiation_cloud = ProjectileDefinition(Projectiles.peregrine_particle_cannon_radiation_cloud)
|
val peregrine_particle_cannon_radiation_cloud = ProjectileDefinition(Projectiles.Types.peregrine_particle_cannon_radiation_cloud)
|
||||||
|
|
||||||
val peregrine_rocket_pod_projectile = ProjectileDefinition(Projectiles.peregrine_rocket_pod_projectile)
|
val peregrine_rocket_pod_projectile = ProjectileDefinition(Projectiles.Types.peregrine_rocket_pod_projectile)
|
||||||
|
|
||||||
val peregrine_sparrow_projectile = ProjectileDefinition(Projectiles.peregrine_sparrow_projectile)
|
val peregrine_sparrow_projectile = ProjectileDefinition(Projectiles.Types.peregrine_sparrow_projectile)
|
||||||
|
|
||||||
val phalanx_av_projectile = ProjectileDefinition(Projectiles.phalanx_av_projectile)
|
val phalanx_av_projectile = ProjectileDefinition(Projectiles.Types.phalanx_av_projectile)
|
||||||
|
|
||||||
val phalanx_flak_projectile = ProjectileDefinition(Projectiles.phalanx_flak_projectile)
|
val phalanx_flak_projectile = ProjectileDefinition(Projectiles.Types.phalanx_flak_projectile)
|
||||||
|
|
||||||
val phalanx_projectile = ProjectileDefinition(Projectiles.phalanx_projectile)
|
val phalanx_projectile = ProjectileDefinition(Projectiles.Types.phalanx_projectile)
|
||||||
|
|
||||||
val phoenix_missile_guided_projectile = ProjectileDefinition(Projectiles.phoenix_missile_guided_projectile)
|
val phoenix_missile_guided_projectile = ProjectileDefinition(Projectiles.Types.phoenix_missile_guided_projectile)
|
||||||
|
|
||||||
val phoenix_missile_projectile = ProjectileDefinition(Projectiles.phoenix_missile_projectile)
|
val phoenix_missile_projectile = ProjectileDefinition(Projectiles.Types.phoenix_missile_projectile)
|
||||||
|
|
||||||
val plasma_cartridge_projectile = ProjectileDefinition(Projectiles.plasma_cartridge_projectile)
|
val plasma_cartridge_projectile = ProjectileDefinition(Projectiles.Types.plasma_cartridge_projectile)
|
||||||
|
|
||||||
val plasma_cartridge_projectile_b = ProjectileDefinition(Projectiles.plasma_cartridge_projectile_b)
|
val plasma_cartridge_projectile_b = ProjectileDefinition(Projectiles.Types.plasma_cartridge_projectile_b)
|
||||||
|
|
||||||
val plasma_grenade_projectile = ProjectileDefinition(Projectiles.plasma_grenade_projectile)
|
val plasma_grenade_projectile = ProjectileDefinition(Projectiles.Types.plasma_grenade_projectile)
|
||||||
|
|
||||||
val plasma_grenade_projectile_B = ProjectileDefinition(Projectiles.plasma_grenade_projectile_B)
|
val plasma_grenade_projectile_B = ProjectileDefinition(Projectiles.Types.plasma_grenade_projectile_B)
|
||||||
|
|
||||||
val pounder_projectile = ProjectileDefinition(Projectiles.pounder_projectile)
|
val pounder_projectile = ProjectileDefinition(Projectiles.Types.pounder_projectile)
|
||||||
|
|
||||||
val pounder_projectile_enh = ProjectileDefinition(Projectiles.pounder_projectile_enh)
|
val pounder_projectile_enh = ProjectileDefinition(Projectiles.Types.pounder_projectile_enh)
|
||||||
|
|
||||||
val ppa_projectile = ProjectileDefinition(Projectiles.ppa_projectile)
|
val ppa_projectile = ProjectileDefinition(Projectiles.Types.ppa_projectile)
|
||||||
|
|
||||||
val pulsar_ap_projectile = ProjectileDefinition(Projectiles.pulsar_ap_projectile)
|
val pulsar_ap_projectile = ProjectileDefinition(Projectiles.Types.pulsar_ap_projectile)
|
||||||
|
|
||||||
val pulsar_projectile = ProjectileDefinition(Projectiles.pulsar_projectile)
|
val pulsar_projectile = ProjectileDefinition(Projectiles.Types.pulsar_projectile)
|
||||||
|
|
||||||
val quasar_projectile = ProjectileDefinition(Projectiles.quasar_projectile)
|
val quasar_projectile = ProjectileDefinition(Projectiles.Types.quasar_projectile)
|
||||||
|
|
||||||
val radiator_cloud = ProjectileDefinition(Projectiles.radiator_cloud)
|
val radiator_cloud = ProjectileDefinition(Projectiles.Types.radiator_cloud)
|
||||||
|
|
||||||
val radiator_grenade_projectile = ProjectileDefinition(Projectiles.radiator_grenade_projectile)
|
val radiator_grenade_projectile = ProjectileDefinition(Projectiles.Types.radiator_grenade_projectile)
|
||||||
|
|
||||||
val radiator_sticky_projectile = ProjectileDefinition(Projectiles.radiator_sticky_projectile)
|
val radiator_sticky_projectile = ProjectileDefinition(Projectiles.Types.radiator_sticky_projectile)
|
||||||
|
|
||||||
val reaver_rocket_projectile = ProjectileDefinition(Projectiles.reaver_rocket_projectile)
|
val reaver_rocket_projectile = ProjectileDefinition(Projectiles.Types.reaver_rocket_projectile)
|
||||||
|
|
||||||
val rocket_projectile = ProjectileDefinition(Projectiles.rocket_projectile)
|
val rocket_projectile = ProjectileDefinition(Projectiles.Types.rocket_projectile)
|
||||||
|
|
||||||
val rocklet_flak_projectile = ProjectileDefinition(Projectiles.rocklet_flak_projectile)
|
val rocklet_flak_projectile = ProjectileDefinition(Projectiles.Types.rocklet_flak_projectile)
|
||||||
|
|
||||||
val rocklet_jammer_projectile = ProjectileDefinition(Projectiles.rocklet_jammer_projectile)
|
val rocklet_jammer_projectile = ProjectileDefinition(Projectiles.Types.rocklet_jammer_projectile)
|
||||||
|
|
||||||
val scattercannon_projectile = ProjectileDefinition(Projectiles.scattercannon_projectile)
|
val scattercannon_projectile = ProjectileDefinition(Projectiles.Types.scattercannon_projectile)
|
||||||
|
|
||||||
val scythe_projectile = ProjectileDefinition(Projectiles.scythe_projectile)
|
val scythe_projectile = ProjectileDefinition(Projectiles.Types.scythe_projectile)
|
||||||
|
|
||||||
val scythe_projectile_slave = ProjectileDefinition(Projectiles.scythe_projectile_slave)
|
val scythe_projectile_slave = ProjectileDefinition(Projectiles.Types.scythe_projectile_slave)
|
||||||
|
|
||||||
val shotgun_shell_AP_projectile = ProjectileDefinition(Projectiles.shotgun_shell_AP_projectile)
|
val shotgun_shell_AP_projectile = ProjectileDefinition(Projectiles.Types.shotgun_shell_AP_projectile)
|
||||||
|
|
||||||
val shotgun_shell_projectile = ProjectileDefinition(Projectiles.shotgun_shell_projectile)
|
val shotgun_shell_projectile = ProjectileDefinition(Projectiles.Types.shotgun_shell_projectile)
|
||||||
|
|
||||||
val six_shooter_projectile = ProjectileDefinition(Projectiles.six_shooter_projectile)
|
val six_shooter_projectile = ProjectileDefinition(Projectiles.Types.six_shooter_projectile)
|
||||||
|
|
||||||
val skyguard_flak_cannon_projectile = ProjectileDefinition(Projectiles.skyguard_flak_cannon_projectile)
|
val skyguard_flak_cannon_projectile = ProjectileDefinition(Projectiles.Types.skyguard_flak_cannon_projectile)
|
||||||
|
|
||||||
val sparrow_projectile = ProjectileDefinition(Projectiles.sparrow_projectile)
|
val sparrow_projectile = ProjectileDefinition(Projectiles.Types.sparrow_projectile)
|
||||||
|
|
||||||
val sparrow_secondary_projectile = ProjectileDefinition(Projectiles.sparrow_secondary_projectile)
|
val sparrow_secondary_projectile = ProjectileDefinition(Projectiles.Types.sparrow_secondary_projectile)
|
||||||
|
|
||||||
val spiker_projectile = ProjectileDefinition(Projectiles.spiker_projectile)
|
val spiker_projectile = ProjectileDefinition(Projectiles.Types.spiker_projectile)
|
||||||
|
|
||||||
val spitfire_aa_ammo_projectile = ProjectileDefinition(Projectiles.spitfire_aa_ammo_projectile)
|
val spitfire_aa_ammo_projectile = ProjectileDefinition(Projectiles.Types.spitfire_aa_ammo_projectile)
|
||||||
|
|
||||||
val spitfire_ammo_projectile = ProjectileDefinition(Projectiles.spitfire_ammo_projectile)
|
val spitfire_ammo_projectile = ProjectileDefinition(Projectiles.Types.spitfire_ammo_projectile)
|
||||||
|
|
||||||
val starfire_projectile = ProjectileDefinition(Projectiles.starfire_projectile)
|
val starfire_projectile = ProjectileDefinition(Projectiles.Types.starfire_projectile)
|
||||||
|
|
||||||
val striker_missile_projectile = ProjectileDefinition(Projectiles.striker_missile_projectile)
|
val striker_missile_projectile = ProjectileDefinition(Projectiles.Types.striker_missile_projectile)
|
||||||
|
|
||||||
val striker_missile_targeting_projectile = ProjectileDefinition(Projectiles.striker_missile_targeting_projectile)
|
val striker_missile_targeting_projectile = ProjectileDefinition(Projectiles.Types.striker_missile_targeting_projectile)
|
||||||
|
|
||||||
val trek_projectile = ProjectileDefinition(Projectiles.trek_projectile)
|
val trek_projectile = ProjectileDefinition(Projectiles.Types.trek_projectile)
|
||||||
|
|
||||||
val vanu_sentry_turret_projectile = ProjectileDefinition(Projectiles.vanu_sentry_turret_projectile)
|
val vanu_sentry_turret_projectile = ProjectileDefinition(Projectiles.Types.vanu_sentry_turret_projectile)
|
||||||
|
|
||||||
val vulture_bomb_projectile = ProjectileDefinition(Projectiles.vulture_bomb_projectile)
|
val vulture_bomb_projectile = ProjectileDefinition(Projectiles.Types.vulture_bomb_projectile)
|
||||||
|
|
||||||
val vulture_nose_bullet_projectile = ProjectileDefinition(Projectiles.vulture_nose_bullet_projectile)
|
val vulture_nose_bullet_projectile = ProjectileDefinition(Projectiles.Types.vulture_nose_bullet_projectile)
|
||||||
|
|
||||||
val vulture_tail_bullet_projectile = ProjectileDefinition(Projectiles.vulture_tail_bullet_projectile)
|
val vulture_tail_bullet_projectile = ProjectileDefinition(Projectiles.Types.vulture_tail_bullet_projectile)
|
||||||
|
|
||||||
val wasp_gun_projectile = ProjectileDefinition(Projectiles.wasp_gun_projectile)
|
val wasp_gun_projectile = ProjectileDefinition(Projectiles.Types.wasp_gun_projectile)
|
||||||
|
|
||||||
val wasp_rocket_projectile = ProjectileDefinition(Projectiles.wasp_rocket_projectile)
|
val wasp_rocket_projectile = ProjectileDefinition(Projectiles.Types.wasp_rocket_projectile)
|
||||||
|
|
||||||
val winchester_projectile = ProjectileDefinition(Projectiles.winchester_projectile)
|
val winchester_projectile = ProjectileDefinition(Projectiles.Types.winchester_projectile)
|
||||||
|
|
||||||
val armor_siphon_projectile = ProjectileDefinition(Projectiles.trek_projectile) //fake projectile for storing damage information
|
val armor_siphon_projectile = ProjectileDefinition(Projectiles.Types.trek_projectile) //fake projectile for storing damage information
|
||||||
|
|
||||||
val ntu_siphon_emp = ProjectileDefinition(Projectiles.ntu_siphon_emp)
|
val ntu_siphon_emp = ProjectileDefinition(Projectiles.Types.ntu_siphon_emp)
|
||||||
init_projectile()
|
init_projectile()
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -1180,7 +1180,9 @@ object GlobalDefinitions {
|
||||||
|
|
||||||
val repair_silo = new MedicalTerminalDefinition(729)
|
val repair_silo = new MedicalTerminalDefinition(729)
|
||||||
|
|
||||||
val recharge_terminal = new MedicalTerminalDefinition(724)
|
val recharge_terminal = new WeaponRechargeTerminalDefinition(724)
|
||||||
|
|
||||||
|
val recharge_terminal_weapon_module = new WeaponRechargeTerminalDefinition(725)
|
||||||
|
|
||||||
val mb_pad_creation = new VehicleSpawnPadDefinition(525)
|
val mb_pad_creation = new VehicleSpawnPadDefinition(525)
|
||||||
|
|
||||||
|
|
@ -1975,28 +1977,31 @@ object GlobalDefinitions {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return a projectile that is the damage proxy of another projectile,
|
* Return projectiles that are the damage proxies of another projectile,
|
||||||
* if such a damage proxy is defined in the appropriate field by its unique object identifier.
|
* if such a damage proxy is defined in the appropriate field by its unique object identifier.
|
||||||
* @see `ProjectileDefinition.DamageProxy`
|
* @see `ProjectileDefinition.DamageProxy`
|
||||||
* @param projectile the original projectile
|
* @param projectile the original projectile
|
||||||
* @return the damage proxy projectile definition, if that can be produced
|
* @return the damage proxy projectiles, if they can be produced
|
||||||
*/
|
*/
|
||||||
def getDamageProxy(projectile: Projectile, hitPosition: Vector3): Option[Projectile] = {
|
def getDamageProxy(projectile: Projectile, hitPosition: Vector3): List[Projectile] = {
|
||||||
projectile.Definition.DamageProxy match {
|
projectile
|
||||||
case Some(uoid) =>
|
.Definition
|
||||||
|
.DamageProxy
|
||||||
|
.flatMap { uoid =>
|
||||||
((uoid: @switch) match {
|
((uoid: @switch) match {
|
||||||
case 96 => Some(aphelion_plasma_cloud)
|
case 96 => Some(aphelion_plasma_cloud)
|
||||||
case 301 => Some(projectile.profile) //'flamethrower_fire_cloud' can not be made into a packet
|
case 301 => Some(projectile.profile) //'flamethrower_fire_cloud' can not be made into a packet
|
||||||
case 464 => Some(projectile.profile) //'maelstrom_grenade_damager' can not be made into a packet
|
case 464 => Some(projectile.profile) //'maelstrom_grenade_damager' can not be made into a packet
|
||||||
|
case 601 => Some(oicw_little_buddy)
|
||||||
case 655 => Some(peregrine_particle_cannon_radiation_cloud)
|
case 655 => Some(peregrine_particle_cannon_radiation_cloud)
|
||||||
case 717 => Some(radiator_cloud)
|
case 717 => Some(radiator_cloud)
|
||||||
case _ => None
|
case _ => None
|
||||||
}) match {
|
}) match {
|
||||||
case Some(proxy)
|
case Some(proxy)
|
||||||
if proxy eq projectile.profile =>
|
if proxy eq projectile.profile =>
|
||||||
Some(projectile)
|
List(projectile)
|
||||||
case Some(proxy) =>
|
case Some(proxy) =>
|
||||||
Some(Projectile(
|
List(Projectile(
|
||||||
proxy,
|
proxy,
|
||||||
projectile.tool_def,
|
projectile.tool_def,
|
||||||
projectile.fire_mode,
|
projectile.fire_mode,
|
||||||
|
|
@ -2006,11 +2011,9 @@ object GlobalDefinitions {
|
||||||
Vector3.Zero
|
Vector3.Zero
|
||||||
))
|
))
|
||||||
case None =>
|
case None =>
|
||||||
None
|
Nil
|
||||||
}
|
}
|
||||||
case None =>
|
}
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -3638,12 +3641,16 @@ object GlobalDefinitions {
|
||||||
oicw_projectile.ProjectileDamageType = DamageType.Splash
|
oicw_projectile.ProjectileDamageType = DamageType.Splash
|
||||||
oicw_projectile.InitialVelocity = 5
|
oicw_projectile.InitialVelocity = 5
|
||||||
oicw_projectile.Lifespan = 6.1f
|
oicw_projectile.Lifespan = 6.1f
|
||||||
|
oicw_projectile.DamageProxy = List(601, 601, 601, 601, 601) //5 x oicw_little_buddy
|
||||||
oicw_projectile.registerAs = "rc-projectiles"
|
oicw_projectile.registerAs = "rc-projectiles"
|
||||||
oicw_projectile.ExistsOnRemoteClients = true
|
oicw_projectile.ExistsOnRemoteClients = true
|
||||||
oicw_projectile.RemoteClientData = (13107, 195)
|
oicw_projectile.RemoteClientData = (13107, 195)
|
||||||
oicw_projectile.Packet = projectileConverter
|
oicw_projectile.Packet = projectileConverter
|
||||||
ProjectileDefinition.CalculateDerivedFields(oicw_projectile)
|
ProjectileDefinition.CalculateDerivedFields(oicw_projectile)
|
||||||
oicw_projectile.Modifiers = RadialDegrade
|
oicw_projectile.Modifiers = List(
|
||||||
|
//ExplodingRadialDegrade,
|
||||||
|
RadialDegrade
|
||||||
|
)
|
||||||
|
|
||||||
oicw_little_buddy.Name = "oicw_little_buddy"
|
oicw_little_buddy.Name = "oicw_little_buddy"
|
||||||
oicw_little_buddy.Damage0 = 75
|
oicw_little_buddy.Damage0 = 75
|
||||||
|
|
@ -3653,11 +3660,14 @@ object GlobalDefinitions {
|
||||||
oicw_little_buddy.ProjectileDamageType = DamageType.Splash
|
oicw_little_buddy.ProjectileDamageType = DamageType.Splash
|
||||||
oicw_little_buddy.InitialVelocity = 40
|
oicw_little_buddy.InitialVelocity = 40
|
||||||
oicw_little_buddy.Lifespan = 0.5f
|
oicw_little_buddy.Lifespan = 0.5f
|
||||||
oicw_little_buddy.ExistsOnRemoteClients = false //TODO true
|
oicw_little_buddy.registerAs = "rc-projectiles"
|
||||||
oicw_little_buddy.Packet = projectileConverter
|
oicw_little_buddy.ExistsOnRemoteClients = true //does not use RemoteClientData
|
||||||
|
oicw_little_buddy.Packet = new LittleBuddyProjectileConverter
|
||||||
//add_property oicw_little_buddy multi_stage_spawn_server_side true ...
|
//add_property oicw_little_buddy multi_stage_spawn_server_side true ...
|
||||||
ProjectileDefinition.CalculateDerivedFields(oicw_little_buddy)
|
ProjectileDefinition.CalculateDerivedFields(oicw_little_buddy)
|
||||||
oicw_little_buddy.Modifiers = RadialDegrade
|
oicw_little_buddy.Modifiers = List(
|
||||||
|
ExplosionDamagesOnlyAbove
|
||||||
|
)
|
||||||
|
|
||||||
pellet_gun_projectile.Name = "pellet_gun_projectile"
|
pellet_gun_projectile.Name = "pellet_gun_projectile"
|
||||||
// TODO for later, maybe : set_resource_parent pellet_gun_projectile game_objects shotgun_shell_projectile
|
// TODO for later, maybe : set_resource_parent pellet_gun_projectile game_objects shotgun_shell_projectile
|
||||||
|
|
@ -3943,16 +3953,29 @@ object GlobalDefinitions {
|
||||||
radiator_cloud.Damage0 = 2
|
radiator_cloud.Damage0 = 2
|
||||||
radiator_cloud.DamageAtEdge = 1.0f
|
radiator_cloud.DamageAtEdge = 1.0f
|
||||||
radiator_cloud.DamageRadius = 5f
|
radiator_cloud.DamageRadius = 5f
|
||||||
|
radiator_cloud.DamageToHealthOnly = true
|
||||||
radiator_cloud.radiation_cloud = true
|
radiator_cloud.radiation_cloud = true
|
||||||
radiator_cloud.ProjectileDamageType = DamageType.Radiation
|
radiator_cloud.ProjectileDamageType = DamageType.Radiation
|
||||||
|
//custom aggravated information
|
||||||
|
radiator_cloud.ProjectileDamageTypeSecondary = DamageType.Aggravated
|
||||||
|
radiator_cloud.Aggravated = AggravatedDamage(
|
||||||
|
AggravatedInfo(DamageType.Splash, 1f, 80),
|
||||||
|
Aura.None,
|
||||||
|
AggravatedTiming(250, 2),
|
||||||
|
0f,
|
||||||
|
false,
|
||||||
|
List(TargetValidation(EffectTarget.Category.Player, EffectTarget.Validation.Player))
|
||||||
|
)
|
||||||
radiator_cloud.Lifespan = 10.0f
|
radiator_cloud.Lifespan = 10.0f
|
||||||
ProjectileDefinition.CalculateDerivedFields(radiator_cloud)
|
ProjectileDefinition.CalculateDerivedFields(radiator_cloud)
|
||||||
radiator_cloud.registerAs = "rc-projectiles"
|
radiator_cloud.registerAs = "rc-projectiles"
|
||||||
radiator_cloud.ExistsOnRemoteClients = true
|
radiator_cloud.ExistsOnRemoteClients = true
|
||||||
radiator_cloud.Packet = radCloudConverter
|
radiator_cloud.Packet = radCloudConverter
|
||||||
radiator_cloud.Geometry = GeometryForm.representProjectileBySphere()
|
//radiator_cloud.Geometry = GeometryForm.representProjectileBySphere()
|
||||||
radiator_cloud.Modifiers = List(
|
radiator_cloud.Modifiers = List(
|
||||||
MaxDistanceCutoff,
|
MaxDistanceCutoff,
|
||||||
|
InfantryAggravatedRadiation,
|
||||||
|
InfantryAggravatedRadiationBurn,
|
||||||
ShieldAgainstRadiation
|
ShieldAgainstRadiation
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -3961,6 +3984,7 @@ object GlobalDefinitions {
|
||||||
radiator_grenade_projectile.ProjectileDamageType = DamageType.Direct
|
radiator_grenade_projectile.ProjectileDamageType = DamageType.Direct
|
||||||
radiator_grenade_projectile.InitialVelocity = 30
|
radiator_grenade_projectile.InitialVelocity = 30
|
||||||
radiator_grenade_projectile.Lifespan = 3f
|
radiator_grenade_projectile.Lifespan = 3f
|
||||||
|
radiator_grenade_projectile.DamageProxy = 717 //radiator_cloud
|
||||||
ProjectileDefinition.CalculateDerivedFields(radiator_grenade_projectile)
|
ProjectileDefinition.CalculateDerivedFields(radiator_grenade_projectile)
|
||||||
|
|
||||||
radiator_sticky_projectile.Name = "radiator_sticky_projectile"
|
radiator_sticky_projectile.Name = "radiator_sticky_projectile"
|
||||||
|
|
@ -3969,6 +3993,7 @@ object GlobalDefinitions {
|
||||||
radiator_sticky_projectile.ProjectileDamageType = DamageType.Direct
|
radiator_sticky_projectile.ProjectileDamageType = DamageType.Direct
|
||||||
radiator_sticky_projectile.InitialVelocity = 30
|
radiator_sticky_projectile.InitialVelocity = 30
|
||||||
radiator_sticky_projectile.Lifespan = 4f
|
radiator_sticky_projectile.Lifespan = 4f
|
||||||
|
radiator_sticky_projectile.DamageProxy = 717 //radiator_cloud
|
||||||
ProjectileDefinition.CalculateDerivedFields(radiator_sticky_projectile)
|
ProjectileDefinition.CalculateDerivedFields(radiator_sticky_projectile)
|
||||||
|
|
||||||
reaver_rocket_projectile.Name = "reaver_rocket_projectile"
|
reaver_rocket_projectile.Name = "reaver_rocket_projectile"
|
||||||
|
|
@ -4430,7 +4455,7 @@ object GlobalDefinitions {
|
||||||
aphelion_plasma_cloud.registerAs = "rc-projectiles"
|
aphelion_plasma_cloud.registerAs = "rc-projectiles"
|
||||||
aphelion_plasma_cloud.ExistsOnRemoteClients = true
|
aphelion_plasma_cloud.ExistsOnRemoteClients = true
|
||||||
aphelion_plasma_cloud.Packet = radCloudConverter
|
aphelion_plasma_cloud.Packet = radCloudConverter
|
||||||
aphelion_plasma_cloud.Geometry = GeometryForm.representProjectileBySphere()
|
//aphelion_plasma_cloud.Geometry = GeometryForm.representProjectileBySphere()
|
||||||
aphelion_plasma_cloud.Modifiers = List( //TODO placeholder values
|
aphelion_plasma_cloud.Modifiers = List( //TODO placeholder values
|
||||||
MaxDistanceCutoff,
|
MaxDistanceCutoff,
|
||||||
InfantryAggravatedRadiation,
|
InfantryAggravatedRadiation,
|
||||||
|
|
@ -4632,7 +4657,7 @@ object GlobalDefinitions {
|
||||||
peregrine_particle_cannon_radiation_cloud.registerAs = "rc-projectiles"
|
peregrine_particle_cannon_radiation_cloud.registerAs = "rc-projectiles"
|
||||||
peregrine_particle_cannon_radiation_cloud.ExistsOnRemoteClients = true
|
peregrine_particle_cannon_radiation_cloud.ExistsOnRemoteClients = true
|
||||||
peregrine_particle_cannon_radiation_cloud.Packet = radCloudConverter
|
peregrine_particle_cannon_radiation_cloud.Packet = radCloudConverter
|
||||||
peregrine_particle_cannon_radiation_cloud.Geometry = GeometryForm.representProjectileBySphere()
|
//peregrine_particle_cannon_radiation_cloud.Geometry = GeometryForm.representProjectileBySphere()
|
||||||
peregrine_particle_cannon_radiation_cloud.Modifiers = List(
|
peregrine_particle_cannon_radiation_cloud.Modifiers = List(
|
||||||
MaxDistanceCutoff,
|
MaxDistanceCutoff,
|
||||||
ShieldAgainstRadiation
|
ShieldAgainstRadiation
|
||||||
|
|
@ -9615,6 +9640,13 @@ object GlobalDefinitions {
|
||||||
recharge_terminal.Damageable = false
|
recharge_terminal.Damageable = false
|
||||||
recharge_terminal.Repairable = false
|
recharge_terminal.Repairable = false
|
||||||
|
|
||||||
|
recharge_terminal_weapon_module.Name = "recharge_terminal_weapon_module"
|
||||||
|
recharge_terminal_weapon_module.Interval = 1000
|
||||||
|
recharge_terminal_weapon_module.UseRadius = 300
|
||||||
|
recharge_terminal_weapon_module.TargetValidation += EffectTarget.Category.Player -> EffectTarget.Validation.AncientWeaponRecharge
|
||||||
|
recharge_terminal_weapon_module.Damageable = false
|
||||||
|
recharge_terminal_weapon_module.Repairable = false
|
||||||
|
|
||||||
mb_pad_creation.Name = "mb_pad_creation"
|
mb_pad_creation.Name = "mb_pad_creation"
|
||||||
mb_pad_creation.Damageable = false
|
mb_pad_creation.Damageable = false
|
||||||
mb_pad_creation.Repairable = false
|
mb_pad_creation.Repairable = false
|
||||||
|
|
|
||||||
|
|
@ -78,7 +78,7 @@ class Tool(private val toolDef: ToolDefinition)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
def ProjectileType: Projectiles.Value = Projectile.ProjectileType
|
def ProjectileType: Projectiles.Types.Value = Projectile.ProjectileType
|
||||||
|
|
||||||
def Magazine: Int = AmmoSlot.Magazine
|
def Magazine: Int = AmmoSlot.Magazine
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -62,7 +62,7 @@ class InteractWithRadiationClouds(
|
||||||
RadiationReason(
|
RadiationReason(
|
||||||
ProjectileQuality.modifiers(projectile, DamageResolution.Radiation, t, t.Position, user),
|
ProjectileQuality.modifiers(projectile, DamageResolution.Radiation, t, t.Position, user),
|
||||||
t.DamageModel,
|
t.DamageModel,
|
||||||
1f
|
0f
|
||||||
),
|
),
|
||||||
position
|
position
|
||||||
).calculate()
|
).calculate()
|
||||||
|
|
|
||||||
|
|
@ -5,151 +5,153 @@ package net.psforever.objects.ballistics
|
||||||
* An `Enumeration` of all the projectile types in the game, paired with their object id as the `Value`.
|
* An `Enumeration` of all the projectile types in the game, paired with their object id as the `Value`.
|
||||||
*/
|
*/
|
||||||
object Projectiles extends Enumeration {
|
object Projectiles extends Enumeration {
|
||||||
final val no_projectile = Value(0)
|
object Types extends Enumeration {
|
||||||
|
final val no_projectile = Value(0)
|
||||||
|
|
||||||
final val bullet_105mm_projectile = Value(1)
|
final val bullet_105mm_projectile = Value(1)
|
||||||
final val bullet_12mm_projectile = Value(4)
|
final val bullet_12mm_projectile = Value(4)
|
||||||
final val bullet_12mm_projectileb = Value(5)
|
final val bullet_12mm_projectileb = Value(5)
|
||||||
final val bullet_150mm_projectile = Value(7)
|
final val bullet_150mm_projectile = Value(7)
|
||||||
final val bullet_15mm_apc_projectile = Value(10)
|
final val bullet_15mm_apc_projectile = Value(10)
|
||||||
final val bullet_15mm_projectile = Value(11)
|
final val bullet_15mm_projectile = Value(11)
|
||||||
final val bullet_20mm_apc_projectile = Value(17)
|
final val bullet_20mm_apc_projectile = Value(17)
|
||||||
final val bullet_20mm_projectile = Value(18)
|
final val bullet_20mm_projectile = Value(18)
|
||||||
final val bullet_25mm_projectile = Value(20)
|
final val bullet_25mm_projectile = Value(20)
|
||||||
final val bullet_35mm_projectile = Value(22)
|
final val bullet_35mm_projectile = Value(22)
|
||||||
final val bullet_75mm_apc_projectile = Value(26)
|
final val bullet_75mm_apc_projectile = Value(26)
|
||||||
final val bullet_75mm_projectile = Value(27)
|
final val bullet_75mm_projectile = Value(27)
|
||||||
final val bullet_9mm_AP_projectile = Value(30)
|
final val bullet_9mm_AP_projectile = Value(30)
|
||||||
final val bullet_9mm_projectile = Value(31)
|
final val bullet_9mm_projectile = Value(31)
|
||||||
final val anniversary_projectilea = Value(58)
|
final val anniversary_projectilea = Value(58)
|
||||||
final val anniversary_projectileb = Value(59)
|
final val anniversary_projectileb = Value(59)
|
||||||
final val aphelion_immolation_cannon_projectile = Value(87)
|
final val aphelion_immolation_cannon_projectile = Value(87)
|
||||||
final val aphelion_laser_projectile = Value(91)
|
final val aphelion_laser_projectile = Value(91)
|
||||||
final val aphelion_plasma_cloud = Value(96) //radiation cloud
|
final val aphelion_plasma_cloud = Value(96) //radiation cloud
|
||||||
final val aphelion_plasma_rocket_projectile = Value(99)
|
final val aphelion_plasma_rocket_projectile = Value(99)
|
||||||
final val aphelion_ppa_projectile = Value(103)
|
final val aphelion_ppa_projectile = Value(103)
|
||||||
final val aphelion_starfire_projectile = Value(108)
|
final val aphelion_starfire_projectile = Value(108)
|
||||||
final val bolt_projectile = Value(147)
|
final val bolt_projectile = Value(147)
|
||||||
final val burster_projectile = Value(155)
|
final val burster_projectile = Value(155)
|
||||||
final val chainblade_projectile = Value(176)
|
final val chainblade_projectile = Value(176)
|
||||||
final val colossus_100mm_projectile = Value(181)
|
final val colossus_100mm_projectile = Value(181)
|
||||||
final val colossus_burster_projectile = Value(188)
|
final val colossus_burster_projectile = Value(188)
|
||||||
final val colossus_chaingun_projectile = Value(193)
|
final val colossus_chaingun_projectile = Value(193)
|
||||||
final val colossus_cluster_bomb_projectile = Value(197)
|
final val colossus_cluster_bomb_projectile = Value(197)
|
||||||
final val colossus_tank_cannon_projectile = Value(207)
|
final val colossus_tank_cannon_projectile = Value(207)
|
||||||
final val comet_projectile = Value(210)
|
final val comet_projectile = Value(210)
|
||||||
final val dualcycler_projectile = Value(266)
|
final val dualcycler_projectile = Value(266)
|
||||||
final val dynomite_projectile = Value(268)
|
final val dynomite_projectile = Value(268)
|
||||||
final val energy_cell_projectile = Value(273)
|
final val energy_cell_projectile = Value(273)
|
||||||
final val energy_gun_nc_projectile = Value(277)
|
final val energy_gun_nc_projectile = Value(277)
|
||||||
final val energy_gun_tr_projectile = Value(279)
|
final val energy_gun_tr_projectile = Value(279)
|
||||||
final val energy_gun_vs_projectile = Value(281)
|
final val energy_gun_vs_projectile = Value(281)
|
||||||
final val enhanced_energy_cell_projectile = Value(282)
|
final val enhanced_energy_cell_projectile = Value(282)
|
||||||
final val enhanced_quasar_projectile = Value(283)
|
final val enhanced_quasar_projectile = Value(283)
|
||||||
final val falcon_projectile = Value(286)
|
final val falcon_projectile = Value(286)
|
||||||
final val firebird_missile_projectile = Value(288)
|
final val firebird_missile_projectile = Value(288)
|
||||||
final val flail_projectile = Value(296)
|
final val flail_projectile = Value(296)
|
||||||
final val flamethrower_fire_cloud = Value(301)
|
final val flamethrower_fire_cloud = Value(301)
|
||||||
final val flamethrower_fireball = Value(302)
|
final val flamethrower_fireball = Value(302)
|
||||||
final val flamethrower_projectile = Value(303)
|
final val flamethrower_projectile = Value(303)
|
||||||
final val flux_cannon_apc_projectile = Value(305)
|
final val flux_cannon_apc_projectile = Value(305)
|
||||||
final val flux_cannon_thresher_projectile = Value(308)
|
final val flux_cannon_thresher_projectile = Value(308)
|
||||||
final val fluxpod_projectile = Value(311)
|
final val fluxpod_projectile = Value(311)
|
||||||
final val forceblade_projectile = Value(325)
|
final val forceblade_projectile = Value(325)
|
||||||
final val frag_cartridge_projectile = Value(328)
|
final val frag_cartridge_projectile = Value(328)
|
||||||
final val frag_cartridge_projectile_b = Value(329)
|
final val frag_cartridge_projectile_b = Value(329)
|
||||||
final val frag_grenade_projectile = Value(332)
|
final val frag_grenade_projectile = Value(332)
|
||||||
final val frag_grenade_projectile_enh = Value(333)
|
final val frag_grenade_projectile_enh = Value(333)
|
||||||
final val galaxy_gunship_gun_projectile = Value(341)
|
final val galaxy_gunship_gun_projectile = Value(341)
|
||||||
final val gauss_cannon_projectile = Value(348)
|
final val gauss_cannon_projectile = Value(348)
|
||||||
final val grenade_projectile = Value(372)
|
final val grenade_projectile = Value(372)
|
||||||
final val heavy_grenade_projectile = Value(392)
|
final val heavy_grenade_projectile = Value(392)
|
||||||
final val heavy_rail_beam_projectile = Value(395)
|
final val heavy_rail_beam_projectile = Value(395)
|
||||||
final val heavy_sniper_projectile = Value(397)
|
final val heavy_sniper_projectile = Value(397)
|
||||||
final val hellfire_projectile = Value(400)
|
final val hellfire_projectile = Value(400)
|
||||||
final val hunter_seeker_missile_dumbfire = Value(404)
|
final val hunter_seeker_missile_dumbfire = Value(404)
|
||||||
final val hunter_seeker_missile_projectile = Value(405)
|
final val hunter_seeker_missile_projectile = Value(405)
|
||||||
final val jammer_cartridge_projectile = Value(414)
|
final val jammer_cartridge_projectile = Value(414)
|
||||||
final val jammer_cartridge_projectile_b = Value(415)
|
final val jammer_cartridge_projectile_b = Value(415)
|
||||||
final val jammer_grenade_projectile = Value(418)
|
final val jammer_grenade_projectile = Value(418)
|
||||||
final val jammer_grenade_projectile_enh = Value(419)
|
final val jammer_grenade_projectile_enh = Value(419)
|
||||||
final val katana_projectile = Value(422)
|
final val katana_projectile = Value(422)
|
||||||
final val katana_projectileb = Value(423)
|
final val katana_projectileb = Value(423)
|
||||||
final val lancer_projectile = Value(427)
|
final val lancer_projectile = Value(427)
|
||||||
final val lasher_projectile = Value(430)
|
final val lasher_projectile = Value(430)
|
||||||
final val lasher_projectile_ap = Value(431)
|
final val lasher_projectile_ap = Value(431)
|
||||||
final val liberator_bomb_cluster_bomblet_projectile = Value(436)
|
final val liberator_bomb_cluster_bomblet_projectile = Value(436)
|
||||||
final val liberator_bomb_cluster_projectile = Value(437)
|
final val liberator_bomb_cluster_projectile = Value(437)
|
||||||
final val liberator_bomb_projectile = Value(438)
|
final val liberator_bomb_projectile = Value(438)
|
||||||
final val maelstrom_grenade_damager = Value(464)
|
final val maelstrom_grenade_damager = Value(464)
|
||||||
final val maelstrom_grenade_projectile = Value(465)
|
final val maelstrom_grenade_projectile = Value(465)
|
||||||
final val maelstrom_grenade_projectile_contact = Value(466)
|
final val maelstrom_grenade_projectile_contact = Value(466)
|
||||||
final val maelstrom_stream_projectile = Value(467)
|
final val maelstrom_stream_projectile = Value(467)
|
||||||
final val magcutter_projectile = Value(469)
|
final val magcutter_projectile = Value(469)
|
||||||
final val melee_ammo_projectile = Value(541)
|
final val melee_ammo_projectile = Value(541)
|
||||||
final val meteor_common = Value(543)
|
final val meteor_common = Value(543)
|
||||||
final val meteor_projectile_b_large = Value(544)
|
final val meteor_projectile_b_large = Value(544)
|
||||||
final val meteor_projectile_b_medium = Value(545)
|
final val meteor_projectile_b_medium = Value(545)
|
||||||
final val meteor_projectile_b_small = Value(546)
|
final val meteor_projectile_b_small = Value(546)
|
||||||
final val meteor_projectile_large = Value(547)
|
final val meteor_projectile_large = Value(547)
|
||||||
final val meteor_projectile_medium = Value(548)
|
final val meteor_projectile_medium = Value(548)
|
||||||
final val meteor_projectile_small = Value(549)
|
final val meteor_projectile_small = Value(549)
|
||||||
final val mine_projectile = Value(551)
|
final val mine_projectile = Value(551)
|
||||||
final val mine_sweeper_projectile = Value(554)
|
final val mine_sweeper_projectile = Value(554)
|
||||||
final val mine_sweeper_projectile_enh = Value(555)
|
final val mine_sweeper_projectile_enh = Value(555)
|
||||||
final val ntu_siphon_emp = Value(596)
|
final val ntu_siphon_emp = Value(596)
|
||||||
final val oicw_little_buddy = Value(601)
|
final val oicw_little_buddy = Value(601)
|
||||||
final val oicw_projectile = Value(602)
|
final val oicw_projectile = Value(602)
|
||||||
final val pellet_gun_projectile = Value(631)
|
final val pellet_gun_projectile = Value(631)
|
||||||
final val peregrine_dual_machine_gun_projectile = Value(639)
|
final val peregrine_dual_machine_gun_projectile = Value(639)
|
||||||
final val peregrine_mechhammer_projectile = Value(647)
|
final val peregrine_mechhammer_projectile = Value(647)
|
||||||
final val peregrine_particle_cannon_projectile = Value(654)
|
final val peregrine_particle_cannon_projectile = Value(654)
|
||||||
final val peregrine_particle_cannon_radiation_cloud = Value(655) //radiation cloud
|
final val peregrine_particle_cannon_radiation_cloud = Value(655) //radiation cloud
|
||||||
final val peregrine_rocket_pod_projectile = Value(657)
|
final val peregrine_rocket_pod_projectile = Value(657)
|
||||||
final val peregrine_sparrow_projectile = Value(661)
|
final val peregrine_sparrow_projectile = Value(661)
|
||||||
final val phalanx_av_projectile = Value(665)
|
final val phalanx_av_projectile = Value(665)
|
||||||
final val phalanx_flak_projectile = Value(667)
|
final val phalanx_flak_projectile = Value(667)
|
||||||
final val phalanx_projectile = Value(669)
|
final val phalanx_projectile = Value(669)
|
||||||
final val phoenix_missile_guided_projectile = Value(675)
|
final val phoenix_missile_guided_projectile = Value(675)
|
||||||
final val phoenix_missile_projectile = Value(676)
|
final val phoenix_missile_projectile = Value(676)
|
||||||
final val plasma_cartridge_projectile = Value(678)
|
final val plasma_cartridge_projectile = Value(678)
|
||||||
final val plasma_cartridge_projectile_b = Value(679)
|
final val plasma_cartridge_projectile_b = Value(679)
|
||||||
final val plasma_grenade_projectile = Value(682)
|
final val plasma_grenade_projectile = Value(682)
|
||||||
final val plasma_grenade_projectile_B = Value(683)
|
final val plasma_grenade_projectile_B = Value(683)
|
||||||
final val pounder_projectile = Value(694)
|
final val pounder_projectile = Value(694)
|
||||||
final val pounder_projectile_enh = Value(695)
|
final val pounder_projectile_enh = Value(695)
|
||||||
final val ppa_projectile = Value(696)
|
final val ppa_projectile = Value(696)
|
||||||
final val pulsar_ap_projectile = Value(702)
|
final val pulsar_ap_projectile = Value(702)
|
||||||
final val pulsar_projectile = Value(703)
|
final val pulsar_projectile = Value(703)
|
||||||
final val quasar_projectile = Value(713)
|
final val quasar_projectile = Value(713)
|
||||||
final val radiator_cloud = Value(717) //radiation cloud
|
final val radiator_cloud = Value(717) //radiation cloud
|
||||||
final val radiator_grenade_projectile = Value(718)
|
final val radiator_grenade_projectile = Value(718)
|
||||||
final val radiator_sticky_projectile = Value(719)
|
final val radiator_sticky_projectile = Value(719)
|
||||||
final val reaver_rocket_projectile = Value(723)
|
final val reaver_rocket_projectile = Value(723)
|
||||||
final val rocket_projectile = Value(735)
|
final val rocket_projectile = Value(735)
|
||||||
final val rocklet_flak_projectile = Value(738)
|
final val rocklet_flak_projectile = Value(738)
|
||||||
final val rocklet_jammer_projectile = Value(739)
|
final val rocklet_jammer_projectile = Value(739)
|
||||||
final val scattercannon_projectile = Value(746)
|
final val scattercannon_projectile = Value(746)
|
||||||
final val scythe_projectile = Value(748)
|
final val scythe_projectile = Value(748)
|
||||||
final val scythe_projectile_slave = Value(749)
|
final val scythe_projectile_slave = Value(749)
|
||||||
final val shotgun_shell_AP_projectile = Value(757)
|
final val shotgun_shell_AP_projectile = Value(757)
|
||||||
final val shotgun_shell_projectile = Value(758)
|
final val shotgun_shell_projectile = Value(758)
|
||||||
final val six_shooter_projectile = Value(763)
|
final val six_shooter_projectile = Value(763)
|
||||||
final val skyguard_flak_cannon_projectile = Value(787)
|
final val skyguard_flak_cannon_projectile = Value(787)
|
||||||
final val sparrow_projectile = Value(792)
|
final val sparrow_projectile = Value(792)
|
||||||
final val sparrow_secondary_projectile = Value(793)
|
final val sparrow_secondary_projectile = Value(793)
|
||||||
final val spiker_projectile = Value(818)
|
final val spiker_projectile = Value(818)
|
||||||
final val spitfire_aa_ammo_projectile = Value(821)
|
final val spitfire_aa_ammo_projectile = Value(821)
|
||||||
final val spitfire_ammo_projectile = Value(824)
|
final val spitfire_ammo_projectile = Value(824)
|
||||||
final val starfire_projectile = Value(831)
|
final val starfire_projectile = Value(831)
|
||||||
final val striker_missile_projectile = Value(840)
|
final val striker_missile_projectile = Value(840)
|
||||||
final val striker_missile_targeting_projectile = Value(841)
|
final val striker_missile_targeting_projectile = Value(841)
|
||||||
final val trek_projectile = Value(878)
|
final val trek_projectile = Value(878)
|
||||||
final val vanu_sentry_turret_projectile = Value(944)
|
final val vanu_sentry_turret_projectile = Value(944)
|
||||||
final val vulture_bomb_projectile = Value(988)
|
final val vulture_bomb_projectile = Value(988)
|
||||||
final val vulture_nose_bullet_projectile = Value(989)
|
final val vulture_nose_bullet_projectile = Value(989)
|
||||||
final val vulture_tail_bullet_projectile = Value(991)
|
final val vulture_tail_bullet_projectile = Value(991)
|
||||||
final val wasp_gun_projectile = Value(999)
|
final val wasp_gun_projectile = Value(999)
|
||||||
final val wasp_rocket_projectile = Value(1001)
|
final val wasp_rocket_projectile = Value(1001)
|
||||||
final val winchester_projectile = Value(1005)
|
final val winchester_projectile = Value(1005)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ class ProjectileDefinition(objectId: Int)
|
||||||
extends ObjectDefinition(objectId)
|
extends ObjectDefinition(objectId)
|
||||||
with DamageWithPosition {
|
with DamageWithPosition {
|
||||||
/** ascertain that this object is a valid projectile type */
|
/** ascertain that this object is a valid projectile type */
|
||||||
private val projectileType: Projectiles.Value = Projectiles(objectId) //let throw NoSuchElementException
|
private val projectileType: Projectiles.Types.Value = Projectiles.Types(objectId) //let throw NoSuchElementException
|
||||||
/** how much faster (or slower) the projectile moves (m/s^2^) */
|
/** how much faster (or slower) the projectile moves (m/s^2^) */
|
||||||
private var acceleration: Int = 0
|
private var acceleration: Int = 0
|
||||||
/** when the acceleration stops being applied (s) */
|
/** when the acceleration stops being applied (s) */
|
||||||
|
|
@ -64,7 +64,7 @@ class ProjectileDefinition(objectId: Int)
|
||||||
Modifiers = DistanceDegrade
|
Modifiers = DistanceDegrade
|
||||||
registerAs = "projectiles"
|
registerAs = "projectiles"
|
||||||
|
|
||||||
def ProjectileType: Projectiles.Value = projectileType
|
def ProjectileType: Projectiles.Types.Value = projectileType
|
||||||
|
|
||||||
def Acceleration: Int = acceleration
|
def Acceleration: Int = acceleration
|
||||||
|
|
||||||
|
|
@ -176,7 +176,7 @@ class ProjectileDefinition(objectId: Int)
|
||||||
}
|
}
|
||||||
|
|
||||||
object ProjectileDefinition {
|
object ProjectileDefinition {
|
||||||
def apply(projectileType: Projectiles.Value): ProjectileDefinition = {
|
def apply(projectileType: Projectiles.Types.Value): ProjectileDefinition = {
|
||||||
new ProjectileDefinition(projectileType.id)
|
new ProjectileDefinition(projectileType.id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,41 @@
|
||||||
|
// Copyright (c) 2022 PSForever
|
||||||
|
package net.psforever.objects.definition.converter
|
||||||
|
|
||||||
|
import net.psforever.objects.ballistics.Projectile
|
||||||
|
import net.psforever.packet.game.objectcreate._
|
||||||
|
import net.psforever.types.PlanetSideGUID
|
||||||
|
|
||||||
|
import scala.util.{Success, Try}
|
||||||
|
|
||||||
|
class LittleBuddyProjectileConverter extends ObjectCreateConverter[Projectile]() {
|
||||||
|
override def ConstructorData(obj: Projectile): Try[LittleBuddyProjectileData] = lilBudData(obj)
|
||||||
|
|
||||||
|
override def DetailedConstructorData(obj: Projectile): Try[LittleBuddyProjectileData] = lilBudData(obj)
|
||||||
|
|
||||||
|
private def lilBudData(obj: Projectile): Try[LittleBuddyProjectileData] = {
|
||||||
|
Success(
|
||||||
|
LittleBuddyProjectileData(
|
||||||
|
CommonFieldDataWithPlacement(
|
||||||
|
PlacementData(
|
||||||
|
obj.Position,
|
||||||
|
obj.Orientation,
|
||||||
|
obj.Velocity
|
||||||
|
),
|
||||||
|
CommonFieldData(
|
||||||
|
obj.owner.Faction,
|
||||||
|
bops = false,
|
||||||
|
alternate = false,
|
||||||
|
v1 = true,
|
||||||
|
v2 = None,
|
||||||
|
jammered = false,
|
||||||
|
v4 = None,
|
||||||
|
v5 = None,
|
||||||
|
guid = PlanetSideGUID(0)
|
||||||
|
)
|
||||||
|
),
|
||||||
|
u2 = 0,
|
||||||
|
u4 = true
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -42,7 +42,7 @@ object EffectTarget {
|
||||||
def RepairSilo(target: PlanetSideGameObject): Boolean =
|
def RepairSilo(target: PlanetSideGameObject): Boolean =
|
||||||
target match {
|
target match {
|
||||||
case v: Vehicle =>
|
case v: Vehicle =>
|
||||||
!GlobalDefinitions.isFlightVehicle(v.Definition) && v.Health > 0 && v.Health < v.MaxHealth && v.History.exists(x => x.isInstanceOf[DamagingActivity] && x.time >= (System.currentTimeMillis() - 5000L))
|
!GlobalDefinitions.isFlightVehicle(v.Definition) && v.Health > 0 && v.Health < v.MaxHealth && !v.History.takeWhile(System.currentTimeMillis() - _.time <= 5000L).exists(_.isInstanceOf[DamagingActivity])
|
||||||
case _ =>
|
case _ =>
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
@ -50,22 +50,7 @@ object EffectTarget {
|
||||||
def PadLanding(target: PlanetSideGameObject): Boolean =
|
def PadLanding(target: PlanetSideGameObject): Boolean =
|
||||||
target match {
|
target match {
|
||||||
case v: Vehicle =>
|
case v: Vehicle =>
|
||||||
GlobalDefinitions.isFlightVehicle(v.Definition) && v.Health > 0 && v.Health < v.MaxHealth && v.History.exists(x => x.isInstanceOf[DamagingActivity] && x.time >= (System.currentTimeMillis() - 5000000000L))
|
GlobalDefinitions.isFlightVehicle(v.Definition) && v.Health > 0 && v.Health < v.MaxHealth && !v.History.takeWhile(System.currentTimeMillis() - _.time <= 5000L).exists(_.isInstanceOf[DamagingActivity])
|
||||||
case _ =>
|
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|
||||||
def AncientVehicleWeaponRecharge(target: PlanetSideGameObject): Boolean =
|
|
||||||
target match {
|
|
||||||
case v: Vehicle =>
|
|
||||||
GlobalDefinitions.isCavernVehicle(v.Definition) && v.Health > 0 &&
|
|
||||||
v.Weapons.values
|
|
||||||
.map { _.Equipment }
|
|
||||||
.flatMap {
|
|
||||||
case Some(weapon: Tool) => weapon.AmmoSlots
|
|
||||||
case _ => Nil
|
|
||||||
}
|
|
||||||
.exists { slot => slot.Box.Capacity < slot.Definition.Magazine }
|
|
||||||
case _ =>
|
case _ =>
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
@ -135,5 +120,34 @@ object EffectTarget {
|
||||||
case _ =>
|
case _ =>
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def AncientWeaponRecharge(target: PlanetSideGameObject): Boolean = {
|
||||||
|
target match {
|
||||||
|
case p: Player =>
|
||||||
|
(p.Holsters().map { _.Equipment }.flatten.toIterable ++ p.Inventory.Items.map { _.obj })
|
||||||
|
.flatMap {
|
||||||
|
case weapon: Tool => weapon.AmmoSlots
|
||||||
|
case _ => Nil
|
||||||
|
}
|
||||||
|
.exists { slot => slot.Box.Capacity < slot.Definition.Magazine }
|
||||||
|
case _ =>
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def AncientVehicleWeaponRecharge(target: PlanetSideGameObject): Boolean =
|
||||||
|
target match {
|
||||||
|
case v: Vehicle =>
|
||||||
|
GlobalDefinitions.isCavernVehicle(v.Definition) && v.Health > 0 &&
|
||||||
|
v.Weapons.values
|
||||||
|
.map { _.Equipment }
|
||||||
|
.flatMap {
|
||||||
|
case Some(weapon: Tool) => weapon.AmmoSlots
|
||||||
|
case _ => Nil
|
||||||
|
}
|
||||||
|
.exists { slot => slot.Box.Capacity < slot.Definition.Magazine }
|
||||||
|
case _ =>
|
||||||
|
false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,28 +3,15 @@ package net.psforever.objects.serverobject.terminals
|
||||||
|
|
||||||
import net.psforever.objects.Player
|
import net.psforever.objects.Player
|
||||||
|
|
||||||
import scala.concurrent.duration.{Duration, FiniteDuration}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The definition for any `Terminal` that is of a type "medical_terminal".
|
* The definition for any `Terminal` that is of a type "medical_terminal".
|
||||||
* This includes the functionality of the formal medical terminals and some of the cavern crystals.
|
* This includes the functionality of the formal medical terminals and some of the cavern crystals.
|
||||||
* Do not confuse the game's internal "medical_terminal" object category and the actual `medical_terminal` object (529).
|
* Do not confuse the game's internal "medical_terminal" object category and the actual `medical_terminal` object (529).
|
||||||
*/
|
*/
|
||||||
class MedicalTerminalDefinition(objectId: Int) extends ProximityTerminalDefinition(objectId) {
|
class MedicalTerminalDefinition(objectId: Int)
|
||||||
private var interval: FiniteDuration = Duration(0, "seconds")
|
extends ProximityTerminalDefinition(objectId) {
|
||||||
private var healAmount: Int = 0
|
private var healAmount: Int = 0
|
||||||
private var armorAmount: Int = 0
|
private var armorAmount: Int = 0
|
||||||
|
|
||||||
def Interval: FiniteDuration = interval
|
|
||||||
|
|
||||||
def Interval_=(amount: Int): FiniteDuration = {
|
|
||||||
Interval_=(Duration(amount, "milliseconds"))
|
|
||||||
}
|
|
||||||
|
|
||||||
def Interval_=(amount: FiniteDuration): FiniteDuration = {
|
|
||||||
interval = amount
|
|
||||||
Interval
|
|
||||||
}
|
|
||||||
|
|
||||||
def HealAmount: Int = healAmount
|
def HealAmount: Int = healAmount
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ import net.psforever.objects.definition.ObjectDefinition
|
||||||
import net.psforever.objects.equipment.EffectTarget
|
import net.psforever.objects.equipment.EffectTarget
|
||||||
|
|
||||||
import scala.collection.mutable
|
import scala.collection.mutable
|
||||||
|
import scala.concurrent.duration.{Duration, FiniteDuration}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The definition mix-in for any game object that possesses a proximity-based effect.
|
* The definition mix-in for any game object that possesses a proximity-based effect.
|
||||||
|
|
@ -17,10 +18,22 @@ import scala.collection.mutable
|
||||||
trait ProximityDefinition {
|
trait ProximityDefinition {
|
||||||
this: ObjectDefinition =>
|
this: ObjectDefinition =>
|
||||||
|
|
||||||
|
private var interval: FiniteDuration = Duration(0, "seconds")
|
||||||
private var useRadius: Float = 0f //TODO belongs on a wider range of object definitions
|
private var useRadius: Float = 0f //TODO belongs on a wider range of object definitions
|
||||||
private val targetValidation: mutable.HashMap[EffectTarget.Category.Value, PlanetSideGameObject => Boolean] =
|
private val targetValidation: mutable.HashMap[EffectTarget.Category.Value, PlanetSideGameObject => Boolean] =
|
||||||
new mutable.HashMap[EffectTarget.Category.Value, PlanetSideGameObject => Boolean]()
|
new mutable.HashMap[EffectTarget.Category.Value, PlanetSideGameObject => Boolean]()
|
||||||
|
|
||||||
|
def Interval: FiniteDuration = interval
|
||||||
|
|
||||||
|
def Interval_=(amount: Int): FiniteDuration = {
|
||||||
|
Interval_=(Duration(amount, "milliseconds"))
|
||||||
|
}
|
||||||
|
|
||||||
|
def Interval_=(amount: FiniteDuration): FiniteDuration = {
|
||||||
|
interval = amount
|
||||||
|
Interval
|
||||||
|
}
|
||||||
|
|
||||||
def UseRadius: Float = useRadius
|
def UseRadius: Float = useRadius
|
||||||
|
|
||||||
def UseRadius_=(radius: Float): Float = {
|
def UseRadius_=(radius: Float): Float = {
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,8 @@ package net.psforever.objects.serverobject.terminals
|
||||||
|
|
||||||
import akka.actor.{ActorRef, Cancellable}
|
import akka.actor.{ActorRef, Cancellable}
|
||||||
import net.psforever.objects._
|
import net.psforever.objects._
|
||||||
|
import net.psforever.objects.ballistics.{PlayerSource, VehicleSource}
|
||||||
|
import net.psforever.objects.equipment.Equipment
|
||||||
import net.psforever.objects.serverobject.CommonMessages
|
import net.psforever.objects.serverobject.CommonMessages
|
||||||
import net.psforever.objects.serverobject.affinity.FactionAffinityBehavior
|
import net.psforever.objects.serverobject.affinity.FactionAffinityBehavior
|
||||||
import net.psforever.objects.serverobject.damage.Damageable.Target
|
import net.psforever.objects.serverobject.damage.Damageable.Target
|
||||||
|
|
@ -10,8 +12,12 @@ import net.psforever.objects.serverobject.damage.DamageableAmenity
|
||||||
import net.psforever.objects.serverobject.hackable.{GenericHackables, HackableBehavior}
|
import net.psforever.objects.serverobject.hackable.{GenericHackables, HackableBehavior}
|
||||||
import net.psforever.objects.serverobject.repair.{AmenityAutoRepair, RepairableAmenity}
|
import net.psforever.objects.serverobject.repair.{AmenityAutoRepair, RepairableAmenity}
|
||||||
import net.psforever.objects.serverobject.structures.{Building, PoweredAmenityControl}
|
import net.psforever.objects.serverobject.structures.{Building, PoweredAmenityControl}
|
||||||
|
import net.psforever.objects.vital.{HealFromTerm, RepairFromTerm}
|
||||||
|
import net.psforever.packet.game.InventoryStateMessage
|
||||||
import net.psforever.services.Service
|
import net.psforever.services.Service
|
||||||
|
import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage}
|
||||||
import net.psforever.services.local.{LocalAction, LocalServiceMessage}
|
import net.psforever.services.local.{LocalAction, LocalServiceMessage}
|
||||||
|
import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage}
|
||||||
|
|
||||||
import scala.collection.mutable
|
import scala.collection.mutable
|
||||||
import scala.concurrent.duration._
|
import scala.concurrent.duration._
|
||||||
|
|
@ -92,6 +98,9 @@ class ProximityTerminalControl(term: Terminal with ProximityUnit)
|
||||||
callbackList.lift(index) match {
|
callbackList.lift(index) match {
|
||||||
case Some(cback) =>
|
case Some(cback) =>
|
||||||
cback ! ProximityUnit.Action(term, target)
|
cback ! ProximityUnit.Action(term, target)
|
||||||
|
if (ProximityTerminalControl.selectAndTryProximityUnitBehavior(cback, term, target)) {
|
||||||
|
Unuse(target, term.Zone.id)
|
||||||
|
}
|
||||||
case None =>
|
case None =>
|
||||||
log.error(
|
log.error(
|
||||||
s"improper callback registered for $target on $term in zone ${term.Owner.Continent}; this may be recoverable"
|
s"improper callback registered for $target on $term in zone ${term.Owner.Continent}; this may be recoverable"
|
||||||
|
|
@ -141,12 +150,12 @@ class ProximityTerminalControl(term: Terminal with ProximityUnit)
|
||||||
callbacks += callback
|
callbacks += callback
|
||||||
//activation
|
//activation
|
||||||
if (term.NumberUsers == 1 && hadNoUsers) {
|
if (term.NumberUsers == 1 && hadNoUsers) {
|
||||||
val medDef = term.Definition.asInstanceOf[MedicalTerminalDefinition]
|
val tdef = term.Definition.asInstanceOf[ProximityDefinition]
|
||||||
import scala.concurrent.ExecutionContext.Implicits.global
|
import scala.concurrent.ExecutionContext.Implicits.global
|
||||||
terminalAction.cancel()
|
terminalAction.cancel()
|
||||||
terminalAction = context.system.scheduler.scheduleWithFixedDelay(
|
terminalAction = context.system.scheduler.scheduleWithFixedDelay(
|
||||||
500 milliseconds,
|
500 milliseconds,
|
||||||
medDef.Interval,
|
tdef.Interval,
|
||||||
self,
|
self,
|
||||||
ProximityTerminalControl.TerminalAction()
|
ProximityTerminalControl.TerminalAction()
|
||||||
)
|
)
|
||||||
|
|
@ -166,7 +175,7 @@ class ProximityTerminalControl(term: Terminal with ProximityUnit)
|
||||||
s"ProximityTerminal.Unuse: unit ${term.Definition.Name}@${term.GUID.guid} will cease operation on $target"
|
s"ProximityTerminal.Unuse: unit ${term.Definition.Name}@${term.GUID.guid} will cease operation on $target"
|
||||||
)
|
)
|
||||||
//remove callback
|
//remove callback
|
||||||
callbacks.remove(whereTarget)
|
callbacks.remove(whereTarget) ! ProximityUnit.StopAction(term, target)
|
||||||
//de-activation (global / local)
|
//de-activation (global / local)
|
||||||
if (term.NumberUsers == 0 && hadUsers) {
|
if (term.NumberUsers == 0 && hadUsers) {
|
||||||
terminalAction.cancel()
|
terminalAction.cancel()
|
||||||
|
|
@ -203,4 +212,209 @@ class ProximityTerminalControl(term: Terminal with ProximityUnit)
|
||||||
|
|
||||||
object ProximityTerminalControl {
|
object ProximityTerminalControl {
|
||||||
private case class TerminalAction()
|
private case class TerminalAction()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine which functionality to pursue by a generic proximity-functional unit given the target for its activity.
|
||||||
|
* @see `VehicleService:receive, ProximityUnit.Action`
|
||||||
|
* @param terminal the proximity-based unit
|
||||||
|
* @param target the object being affected by the unit
|
||||||
|
*/
|
||||||
|
def selectAndTryProximityUnitBehavior(
|
||||||
|
callback: ActorRef,
|
||||||
|
terminal: Terminal with ProximityUnit,
|
||||||
|
target: PlanetSideGameObject
|
||||||
|
): Boolean = {
|
||||||
|
(terminal.Definition, target) match {
|
||||||
|
case (_: MedicalTerminalDefinition, p: Player) => HealthAndArmorTerminal(terminal, p)
|
||||||
|
case (_: WeaponRechargeTerminalDefinition, p: Player) => WeaponRechargeTerminal(terminal, p)
|
||||||
|
case (_: MedicalTerminalDefinition, v: Vehicle) => VehicleRepairTerminal(terminal, v)
|
||||||
|
case (_: WeaponRechargeTerminalDefinition, v: Vehicle) => WeaponRechargeTerminal(terminal, v)
|
||||||
|
case _ => false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When standing on the platform of a(n advanced) medical terminal,
|
||||||
|
* restore the player's health and armor points (when they need their health and armor points restored).
|
||||||
|
* If the player is both fully healed and fully repaired, stop using the terminal.
|
||||||
|
* @param unit the medical terminal
|
||||||
|
* @param target the player being healed
|
||||||
|
*/
|
||||||
|
def HealthAndArmorTerminal(unit: Terminal with ProximityUnit, target: Player): Boolean = {
|
||||||
|
val medDef = unit.Definition.asInstanceOf[MedicalTerminalDefinition]
|
||||||
|
val healAmount = medDef.HealAmount
|
||||||
|
val healthFull: Boolean = if (healAmount != 0 && target.Health < target.MaxHealth) {
|
||||||
|
target.History(HealFromTerm(PlayerSource(target), healAmount, 0, medDef))
|
||||||
|
HealAction(target, healAmount)
|
||||||
|
} else {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
val repairAmount = medDef.ArmorAmount
|
||||||
|
val armorFull: Boolean = if (repairAmount != 0 && target.Armor < target.MaxArmor) {
|
||||||
|
target.History(HealFromTerm(PlayerSource(target), 0, repairAmount, medDef))
|
||||||
|
ArmorRepairAction(target, repairAmount)
|
||||||
|
} else {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
healthFull && armorFull
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Restore, at most, a specific amount of health points on a player.
|
||||||
|
* Send messages to connected client and to events system.
|
||||||
|
* @param tplayer the player
|
||||||
|
* @param healValue the amount to heal;
|
||||||
|
* 10 by default
|
||||||
|
* @return whether the player can be repaired for any more health points
|
||||||
|
*/
|
||||||
|
def HealAction(tplayer: Player, healValue: Int = 10): Boolean = {
|
||||||
|
tplayer.Health = tplayer.Health + healValue
|
||||||
|
val zone = tplayer.Zone
|
||||||
|
zone.AvatarEvents ! AvatarServiceMessage(
|
||||||
|
zone.id,
|
||||||
|
AvatarAction.PlanetsideAttributeToAll(tplayer.GUID, 0, tplayer.Health)
|
||||||
|
)
|
||||||
|
tplayer.Health == tplayer.MaxHealth
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Restore, at most, a specific amount of personal armor points on a player.
|
||||||
|
* Send messages to connected client and to events system.
|
||||||
|
* @param tplayer the player
|
||||||
|
* @param repairValue the amount to repair;
|
||||||
|
* 10 by default
|
||||||
|
* @return whether the player can be repaired for any more armor points
|
||||||
|
*/
|
||||||
|
def ArmorRepairAction(tplayer: Player, repairValue: Int = 10): Boolean = {
|
||||||
|
tplayer.Armor = tplayer.Armor + repairValue
|
||||||
|
val zone = tplayer.Zone
|
||||||
|
zone.AvatarEvents ! AvatarServiceMessage(
|
||||||
|
zone.id,
|
||||||
|
AvatarAction.PlanetsideAttributeToAll(tplayer.GUID, 4, tplayer.Armor)
|
||||||
|
)
|
||||||
|
tplayer.Armor == tplayer.MaxArmor
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When driving a vehicle close to a rearm/repair silo,
|
||||||
|
* restore the vehicle's health points.
|
||||||
|
* If the vehicle is fully repaired, stop using the terminal.
|
||||||
|
* @param unit the terminal
|
||||||
|
* @param target the vehicle being repaired
|
||||||
|
*/
|
||||||
|
def VehicleRepairTerminal(unit: Terminal with ProximityUnit, target: Vehicle): Boolean = {
|
||||||
|
val medDef = unit.Definition.asInstanceOf[MedicalTerminalDefinition]
|
||||||
|
val healAmount = medDef.HealAmount
|
||||||
|
val maxHealth = target.MaxHealth
|
||||||
|
val noMoreHeal = if (!target.Destroyed && unit.Validate(target)) {
|
||||||
|
//repair vehicle
|
||||||
|
if (healAmount > 0 && target.Health < maxHealth) {
|
||||||
|
target.Health = target.Health + healAmount
|
||||||
|
target.History(RepairFromTerm(VehicleSource(target), healAmount, medDef))
|
||||||
|
val zone = target.Zone
|
||||||
|
zone.VehicleEvents ! VehicleServiceMessage(
|
||||||
|
zone.id,
|
||||||
|
VehicleAction.PlanetsideAttribute(Service.defaultPlayerGUID, target.GUID, 0, target.Health)
|
||||||
|
)
|
||||||
|
target.Health == maxHealth
|
||||||
|
} else {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
noMoreHeal
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When standing in a friendly SOI whose facility is under the influence of an Ancient Weapon Module benefit,
|
||||||
|
* and the player is in possession of Ancient weaponnry whose magazine is not full,
|
||||||
|
* restore some ammunition to its magazine.
|
||||||
|
* If no valid weapons are discovered or the discovered valid weapons have full magazines, stop using the terminal.
|
||||||
|
* @param unit the terminal
|
||||||
|
* @param target the player with weapons being recharged
|
||||||
|
*/
|
||||||
|
def WeaponRechargeTerminal(unit: Terminal with ProximityUnit, target: Player): Boolean = {
|
||||||
|
val result = WeaponsBeingRechargedWithSomeAmmunition(
|
||||||
|
unit.Definition.asInstanceOf[WeaponRechargeTerminalDefinition].AmmoAmount,
|
||||||
|
target.Holsters().map { _.Equipment }.flatten.toIterable ++ target.Inventory.Items.map { _.obj }
|
||||||
|
)
|
||||||
|
val events = unit.Zone.AvatarEvents
|
||||||
|
val channel = target.Name
|
||||||
|
result.foreach { case (weapon, slots) =>
|
||||||
|
slots.foreach { slot =>
|
||||||
|
events ! AvatarServiceMessage(
|
||||||
|
channel,
|
||||||
|
AvatarAction.SendResponse(Service.defaultPlayerGUID, InventoryStateMessage(slot.Box.GUID, weapon.GUID, slot.Box.Capacity))
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
!result.unzip._2.flatten.exists { slot => slot.Magazine < slot.MaxMagazine() }
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When driving close to a rearm/repair silo whose facility is under the influence of an Ancient Weapon Module benefit,
|
||||||
|
* and the vehicle is an Ancient vehicle with mounted weaponry whose magazine(s) is not full,
|
||||||
|
* restore some ammunition to the magazine(s).
|
||||||
|
* If no valid weapons are discovered or the discovered valid weapons have full magazines, stop using the terminal.
|
||||||
|
* @param unit the terminal
|
||||||
|
* @param target the vehicle with weapons being recharged
|
||||||
|
*/
|
||||||
|
def WeaponRechargeTerminal(unit: Terminal with ProximityUnit, target: Vehicle): Boolean = {
|
||||||
|
val result = WeaponsBeingRechargedWithSomeAmmunition(
|
||||||
|
unit.Definition.asInstanceOf[WeaponRechargeTerminalDefinition].AmmoAmount,
|
||||||
|
target.Weapons.values.collect { case e if e.Equipment.nonEmpty => e.Equipment.get }
|
||||||
|
)
|
||||||
|
val events = unit.Zone.VehicleEvents
|
||||||
|
val channel = target.Actor.toString
|
||||||
|
result.foreach { case (weapon, slots) =>
|
||||||
|
slots.foreach { slot =>
|
||||||
|
events ! VehicleServiceMessage(
|
||||||
|
channel,
|
||||||
|
VehicleAction.SendResponse(Service.defaultPlayerGUID, InventoryStateMessage(slot.Box.GUID, weapon.GUID, slot.Box.Capacity))
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
!result.unzip._2.flatten.exists { slot => slot.Magazine < slot.MaxMagazine() }
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Collect all weapons with magazines that need to have ammunition reloaded,
|
||||||
|
* and reload some ammunition into them.
|
||||||
|
* @param ammoAdded the amount of ammo to be added to a weapon
|
||||||
|
* @param equipment the equipment being considered;
|
||||||
|
* weapons whose ammo will be increased will be isolated
|
||||||
|
* @return na
|
||||||
|
*/
|
||||||
|
def WeaponsBeingRechargedWithSomeAmmunition(
|
||||||
|
ammoAdded: Int,
|
||||||
|
equipment: Iterable[Equipment]
|
||||||
|
): Iterable[(Tool, Iterable[Tool.FireModeSlot])] = {
|
||||||
|
equipment
|
||||||
|
.collect {
|
||||||
|
case weapon: Tool
|
||||||
|
if weapon.AmmoSlots.exists(slot => slot.Box.Capacity < slot.Definition.Magazine) =>
|
||||||
|
(weapon, WeaponAmmoRecharge(ammoAdded, weapon.AmmoSlots))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Collect all magazines from this weapon that need to have ammunition reloaded,
|
||||||
|
* and reload some ammunition into them.
|
||||||
|
* @param ammoAdded the amount of ammo to be added to a weapon
|
||||||
|
* @param slots the vehicle with weapons being recharged
|
||||||
|
* @return ammunition slots that were affected
|
||||||
|
*/
|
||||||
|
def WeaponAmmoRecharge(
|
||||||
|
ammoAdded: Int,
|
||||||
|
slots: List[Tool.FireModeSlot]
|
||||||
|
): List[Tool.FireModeSlot] = {
|
||||||
|
val unfilledSlots = slots.filter { slot => slot.Magazine < slot.MaxMagazine() }
|
||||||
|
if (unfilledSlots.nonEmpty) {
|
||||||
|
unfilledSlots.foreach { slot => slot.Box.Capacity = slot.Box.Capacity + ammoAdded }
|
||||||
|
unfilledSlots
|
||||||
|
} else {
|
||||||
|
Nil
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,8 @@ import net.psforever.objects.Player
|
||||||
*
|
*
|
||||||
* @param objectId the object's identifier number
|
* @param objectId the object's identifier number
|
||||||
*/
|
*/
|
||||||
class ProximityTerminalDefinition(objectId: Int) extends TerminalDefinition(objectId) with ProximityDefinition {
|
class ProximityTerminalDefinition(objectId: Int)
|
||||||
|
extends TerminalDefinition(objectId)
|
||||||
|
with ProximityDefinition {
|
||||||
def Request(player: Player, msg: Any): Terminal.Exchange = Terminal.NoDeal()
|
def Request(player: Player, msg: Any): Terminal.Exchange = Terminal.NoDeal()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -81,7 +81,7 @@ trait ProximityUnit {
|
||||||
* @return `true`, if the entity passes the validation tests;
|
* @return `true`, if the entity passes the validation tests;
|
||||||
* `false`, otherwise
|
* `false`, otherwise
|
||||||
*/
|
*/
|
||||||
def Validate(radius: Float, validations: Seq[(PlanetSideGameObject) => Boolean])(
|
def Validate(radius: Float, validations: Seq[PlanetSideGameObject => Boolean])(
|
||||||
target: PlanetSideGameObject
|
target: PlanetSideGameObject
|
||||||
): Boolean = {
|
): Boolean = {
|
||||||
//org.log4s.getLogger("ProximityUnit").info(s"vehicle: ${Owner.Position}, terminal: $Position, target: ${target.Position}, toOwner: ${Vector3.Distance(Position, Owner.Position)}, toTarget: ${Vector3.Distance(Position, target.Position)}")
|
//org.log4s.getLogger("ProximityUnit").info(s"vehicle: ${Owner.Position}, terminal: $Position, target: ${target.Position}, toOwner: ${Vector3.Distance(Position, Owner.Position)}, toTarget: ${Vector3.Distance(Position, target.Position)}")
|
||||||
|
|
@ -93,4 +93,6 @@ trait ProximityUnit {
|
||||||
|
|
||||||
object ProximityUnit {
|
object ProximityUnit {
|
||||||
final case class Action(terminal: Terminal with ProximityUnit, target: PlanetSideGameObject)
|
final case class Action(terminal: Terminal with ProximityUnit, target: PlanetSideGameObject)
|
||||||
|
|
||||||
|
final case class StopAction(terminal: Terminal with ProximityUnit, target: PlanetSideGameObject)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
// Copyright (c) 2022 PSForever
|
||||||
|
package net.psforever.objects.serverobject.terminals
|
||||||
|
|
||||||
|
import net.psforever.objects.Player
|
||||||
|
|
||||||
|
/**
|
||||||
|
* na
|
||||||
|
*/
|
||||||
|
class WeaponRechargeTerminalDefinition(objectId: Int)
|
||||||
|
extends ProximityTerminalDefinition(objectId) {
|
||||||
|
private var ammoAmount: Int = 1
|
||||||
|
|
||||||
|
def AmmoAmount: Int = ammoAmount
|
||||||
|
|
||||||
|
def AmmoAmount_=(amount: Int): Int = {
|
||||||
|
ammoAmount = amount
|
||||||
|
AmmoAmount
|
||||||
|
}
|
||||||
|
|
||||||
|
override def Request(player: Player, msg: Any): Terminal.Exchange = Terminal.NoDeal()
|
||||||
|
}
|
||||||
|
|
@ -162,11 +162,13 @@ trait VitalityDefinition extends DamageModifiers {
|
||||||
/**
|
/**
|
||||||
* damage that is inherent to the object, used for explosions, mainly
|
* damage that is inherent to the object, used for explosions, mainly
|
||||||
*/
|
*/
|
||||||
var innateDamage: Option[DamageWithPosition] = None
|
private var _innateDamage: Option[DamageWithPosition] = None
|
||||||
|
|
||||||
|
def innateDamage: Option[DamageWithPosition] = _innateDamage
|
||||||
|
|
||||||
def innateDamage_=(combustion: DamageWithPosition): Option[DamageWithPosition] = {
|
def innateDamage_=(combustion: DamageWithPosition): Option[DamageWithPosition] = {
|
||||||
innateDamage = Some(combustion)
|
_innateDamage = Some(combustion)
|
||||||
innateDamage
|
_innateDamage
|
||||||
}
|
}
|
||||||
|
|
||||||
val collision: CollisionData = new CollisionData()
|
val collision: CollisionData = new CollisionData()
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,6 @@ package net.psforever.objects.vital.base
|
||||||
object DamageType extends Enumeration(1) {
|
object DamageType extends Enumeration(1) {
|
||||||
type Type = Value
|
type Type = Value
|
||||||
|
|
||||||
//"one" (numerical 1 in the ADB) corresponds to objects that explode
|
//"one" (numerical 1 in the ADB) corresponds to objects that explode and kill fields
|
||||||
final val Direct, Splash, Lash, Radiation, Aggravated, One, Siphon, None = Value
|
final val Direct, Splash, Lash, Radiation, Aggravated, One, Siphon, None = Value
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -109,3 +109,13 @@ case object ExplodingRadialDegrade extends ExplodingDamageModifiers.Mod {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case object ExplosionDamagesOnlyAbove extends ExplodingDamageModifiers.Mod {
|
||||||
|
def calculate(damage: Int, data: DamageInteraction, cause: ExplodingEntityReason): Int = {
|
||||||
|
if (data.target.Position.z <= data.hitPos.z) {
|
||||||
|
damage
|
||||||
|
} else {
|
||||||
|
0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ import net.psforever.objects.vital.resolution.{DamageAndResistance, DamageResist
|
||||||
|
|
||||||
final case class PainboxReason(entity: Painbox) extends DamageReason {
|
final case class PainboxReason(entity: Painbox) extends DamageReason {
|
||||||
private val definition = entity.Definition
|
private val definition = entity.Definition
|
||||||
assert(definition.innateDamage.nonEmpty, "causal entity does not emit pain field")
|
assert(definition.innateDamage.nonEmpty, s"causal entity '${definition.Name}' does not emit pain field")
|
||||||
|
|
||||||
def source: DamageWithPosition = definition.innateDamage.get
|
def source: DamageWithPosition = definition.innateDamage.get
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,6 @@ import net.psforever.objects.vital.resolution.DamageAndResistance
|
||||||
/**
|
/**
|
||||||
* A wrapper for a "damage source" in damage calculations
|
* A wrapper for a "damage source" in damage calculations
|
||||||
* that parameterizes information necessary to explain a radiation cloud.
|
* that parameterizes information necessary to explain a radiation cloud.
|
||||||
* @param resolution how the damage is processed
|
|
||||||
* @param projectile the projectile that caused the damage
|
* @param projectile the projectile that caused the damage
|
||||||
* @param damageModel the model to be utilized in these calculations;
|
* @param damageModel the model to be utilized in these calculations;
|
||||||
* typically, but not always, defined by the target
|
* typically, but not always, defined by the target
|
||||||
|
|
@ -55,9 +54,8 @@ object RadiationDamageModifiers {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If the damge is caused by a projectile that emits a field that permeates vehicle armor,
|
* If the damage is caused by a projectile that emits a field that permeates vehicle armor,
|
||||||
* determine by how much the traversed armor's shielding reduces the damage.
|
* determine by how much the traversed armor's shielding reduces the damage.
|
||||||
* Infantry take damage, reduced only if one is equipped with a mechanized assault exo-suit.
|
|
||||||
*/
|
*/
|
||||||
case object ShieldAgainstRadiation extends RadiationDamageModifiers.Mod {
|
case object ShieldAgainstRadiation extends RadiationDamageModifiers.Mod {
|
||||||
def calculate(damage: Int, data: DamageInteraction, cause: RadiationReason): Int = {
|
def calculate(damage: Int, data: DamageInteraction, cause: RadiationReason): Int = {
|
||||||
|
|
|
||||||
|
|
@ -330,7 +330,7 @@ case object FlailDistanceDamageBoost extends ProjectileDamageModifiers.Mod {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If the damge is caused by a projectile that emits a field that permeates vehicle armor,
|
* If the damge is caused by a projectile that emits a field that permeates armor,
|
||||||
* determine by how much the traversed armor's shielding reduces the damage.
|
* determine by how much the traversed armor's shielding reduces the damage.
|
||||||
* Infantry take damage, reduced only if one is equipped with a mechanized assault exo-suit.
|
* Infantry take damage, reduced only if one is equipped with a mechanized assault exo-suit.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -30,8 +30,9 @@ trait DamageProperties
|
||||||
private var useDamage1Subtract: Boolean = false
|
private var useDamage1Subtract: Boolean = false
|
||||||
/** some other entity confers damage;
|
/** some other entity confers damage;
|
||||||
* a set value should be the damager's object uid
|
* a set value should be the damager's object uid
|
||||||
* usually corresponding to a projectile */
|
* usually corresponding to a projectile;
|
||||||
private var damageProxy: Option[Int] = None
|
* also used to produce staged projectiles */
|
||||||
|
private var damageProxy: List[Int] = Nil
|
||||||
/** na;
|
/** na;
|
||||||
* currently used with jammer properties only */
|
* currently used with jammer properties only */
|
||||||
private var additionalEffect: Boolean = false
|
private var additionalEffect: Boolean = false
|
||||||
|
|
@ -88,11 +89,14 @@ trait DamageProperties
|
||||||
DamageToBattleframeOnly
|
DamageToBattleframeOnly
|
||||||
}
|
}
|
||||||
|
|
||||||
def DamageProxy : Option[Int] = damageProxy
|
def DamageProxy : List[Int] = damageProxy
|
||||||
|
|
||||||
def DamageProxy_=(proxyObjectId : Int) : Option[Int] = DamageProxy_=(Some(proxyObjectId))
|
def DamageProxy_=(proxyObjectId: Int): List[Int] = {
|
||||||
|
damageProxy = damageProxy :+ proxyObjectId
|
||||||
|
DamageProxy
|
||||||
|
}
|
||||||
|
|
||||||
def DamageProxy_=(proxyObjectId : Option[Int]) : Option[Int] = {
|
def DamageProxy_=(proxyObjectId: List[Int]): List[Int] = {
|
||||||
damageProxy = proxyObjectId
|
damageProxy = proxyObjectId
|
||||||
DamageProxy
|
DamageProxy
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1257,10 +1257,27 @@ object Zone {
|
||||||
source: PlanetSideGameObject with FactionAffinity with Vitality,
|
source: PlanetSideGameObject with FactionAffinity with Vitality,
|
||||||
target: PlanetSideGameObject with FactionAffinity with Vitality
|
target: PlanetSideGameObject with FactionAffinity with Vitality
|
||||||
): DamageInteraction = {
|
): DamageInteraction = {
|
||||||
|
explosionDamage(instigation, target.Position)(source, target)
|
||||||
|
}/**
|
||||||
|
* na
|
||||||
|
* @param instigation what previous event happened, if any, that caused this explosion
|
||||||
|
* @param explosionPosition the coordinates of the detected explosion
|
||||||
|
* @param source a game object that represents the source of the explosion
|
||||||
|
* @param target a game object that is affected by the explosion
|
||||||
|
* @return a `DamageInteraction` object
|
||||||
|
*/
|
||||||
|
def explosionDamage(
|
||||||
|
instigation: Option[DamageResult],
|
||||||
|
explosionPosition: Vector3
|
||||||
|
)
|
||||||
|
(
|
||||||
|
source: PlanetSideGameObject with FactionAffinity with Vitality,
|
||||||
|
target: PlanetSideGameObject with FactionAffinity with Vitality
|
||||||
|
): DamageInteraction = {
|
||||||
DamageInteraction(
|
DamageInteraction(
|
||||||
SourceEntry(target),
|
SourceEntry(target),
|
||||||
ExplodingEntityReason(source, target.DamageModel, instigation),
|
ExplodingEntityReason(source, target.DamageModel, instigation),
|
||||||
target.Position
|
explosionPosition
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -143,6 +143,10 @@ class ZoneProjectileActor(
|
||||||
val (clarifiedFilterGuid, duration) = if (definition.radiation_cloud) {
|
val (clarifiedFilterGuid, duration) = if (definition.radiation_cloud) {
|
||||||
zone.blockMap.addTo(projectile)
|
zone.blockMap.addTo(projectile)
|
||||||
(Service.defaultPlayerGUID, projectile.profile.Lifespan seconds)
|
(Service.defaultPlayerGUID, projectile.profile.Lifespan seconds)
|
||||||
|
} else if (definition.RemoteClientData == (0,0)) {
|
||||||
|
//remote projectiles that are not radiation clouds have lifespans controlled by the controller (user)
|
||||||
|
//this projectile has defaulted remote client data
|
||||||
|
(Service.defaultPlayerGUID, projectile.profile.Lifespan * 1.5f seconds)
|
||||||
} else {
|
} else {
|
||||||
//remote projectiles that are not radiation clouds have lifespans controlled by the controller (user)
|
//remote projectiles that are not radiation clouds have lifespans controlled by the controller (user)
|
||||||
//if the controller fails, the projectile has a bit more than its normal lifespan before automatic clean up
|
//if the controller fails, the projectile has a bit more than its normal lifespan before automatic clean up
|
||||||
|
|
@ -188,6 +192,11 @@ class ZoneProjectileActor(
|
||||||
zone.id,
|
zone.id,
|
||||||
AvatarAction.ObjectDelete(PlanetSideGUID(0), projectile_guid, 2)
|
AvatarAction.ObjectDelete(PlanetSideGUID(0), projectile_guid, 2)
|
||||||
)
|
)
|
||||||
|
} else if (projectile.Definition.RemoteClientData == (0,0)) {
|
||||||
|
zone.AvatarEvents ! AvatarServiceMessage(
|
||||||
|
zone.id,
|
||||||
|
AvatarAction.ObjectDelete(PlanetSideGUID(0), projectile_guid, 2)
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
zone.AvatarEvents ! AvatarServiceMessage(
|
zone.AvatarEvents ! AvatarServiceMessage(
|
||||||
zone.id,
|
zone.id,
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,40 @@
|
||||||
|
// Copyright (c) 2022 PSForever
|
||||||
|
package net.psforever.packet.game.objectcreate
|
||||||
|
|
||||||
|
import net.psforever.packet.Marshallable
|
||||||
|
import scodec.{Attempt, Codec}
|
||||||
|
import scodec.codecs._
|
||||||
|
import shapeless.{::, HNil}
|
||||||
|
|
||||||
|
final case class LittleBuddyProjectileData(
|
||||||
|
data: CommonFieldDataWithPlacement,
|
||||||
|
u2: Int,
|
||||||
|
u4: Boolean
|
||||||
|
) extends ConstructorData {
|
||||||
|
assert(data.pos.vel.nonEmpty, "oicw little buddy object always requires velocity to be defined")
|
||||||
|
/**
|
||||||
|
* The length of the little buddy data is functionally `32u`
|
||||||
|
* after all other fields are accounted for
|
||||||
|
* but the packet decode demands an additional bit be accounted for.
|
||||||
|
* @return the number of bits necessary to measure an object of this class
|
||||||
|
*/
|
||||||
|
override def bitsize: Long = 33L + data.bitsize
|
||||||
|
}
|
||||||
|
|
||||||
|
object LittleBuddyProjectileData extends Marshallable[LittleBuddyProjectileData] {
|
||||||
|
implicit val codec: Codec[LittleBuddyProjectileData] = (
|
||||||
|
("data" | CommonFieldDataWithPlacement.codec) ::
|
||||||
|
("unk2" | uint24L) ::
|
||||||
|
uint(bits = 7) ::
|
||||||
|
("unk4" | bool)
|
||||||
|
).exmap[LittleBuddyProjectileData](
|
||||||
|
{
|
||||||
|
case data :: u2 :: 31 :: u4 :: HNil =>
|
||||||
|
Attempt.successful(LittleBuddyProjectileData(data, u2, u4))
|
||||||
|
},
|
||||||
|
{
|
||||||
|
case LittleBuddyProjectileData(data, u2, u4) =>
|
||||||
|
Attempt.successful(data :: u2 :: 31 :: u4 :: HNil)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
@ -669,7 +669,8 @@ object ObjectClass {
|
||||||
def selectDataDroppedDetailedCodec(objClass: Int): Codec[ConstructorData] =
|
def selectDataDroppedDetailedCodec(objClass: Int): Codec[ConstructorData] =
|
||||||
(objClass: @switch) match {
|
(objClass: @switch) match {
|
||||||
//special cases
|
//special cases
|
||||||
case ObjectClass.avatar => ConstructorData(DetailedPlayerData.codec(true), "avatar")
|
case ObjectClass.avatar => ConstructorData(DetailedPlayerData.codec(position_defined = true), "avatar")
|
||||||
|
case ObjectClass.oicw_little_buddy => ConstructorData(LittleBuddyProjectileData.codec, "projectile")
|
||||||
//defer to other codec selection
|
//defer to other codec selection
|
||||||
case _ => selectDataDetailedCodec(objClass)
|
case _ => selectDataDetailedCodec(objClass)
|
||||||
}
|
}
|
||||||
|
|
@ -1240,7 +1241,7 @@ object ObjectClass {
|
||||||
case ObjectClass.meteor_projectile_small => ConstructorData(RemoteProjectileData.codec, "meteor")
|
case ObjectClass.meteor_projectile_small => ConstructorData(RemoteProjectileData.codec, "meteor")
|
||||||
case ObjectClass.peregrine_particle_cannon_radiation_cloud => ConstructorData(RadiationCloudData.codec, "radiation cloud")
|
case ObjectClass.peregrine_particle_cannon_radiation_cloud => ConstructorData(RadiationCloudData.codec, "radiation cloud")
|
||||||
case ObjectClass.phoenix_missile_guided_projectile => ConstructorData(RemoteProjectileData.codec, "projectile")
|
case ObjectClass.phoenix_missile_guided_projectile => ConstructorData(RemoteProjectileData.codec, "projectile")
|
||||||
case ObjectClass.oicw_little_buddy => ConstructorData(RemoteProjectileData.codec, "projectile")
|
case ObjectClass.oicw_little_buddy => ConstructorData(LittleBuddyProjectileData.codec, "projectile")
|
||||||
case ObjectClass.oicw_projectile => ConstructorData(RemoteProjectileData.codec, "projectile")
|
case ObjectClass.oicw_projectile => ConstructorData(RemoteProjectileData.codec, "projectile")
|
||||||
case ObjectClass.radiator_cloud => ConstructorData(RadiationCloudData.codec, "radiation cloud")
|
case ObjectClass.radiator_cloud => ConstructorData(RadiationCloudData.codec, "radiation cloud")
|
||||||
case ObjectClass.sparrow_projectile => ConstructorData(RemoteProjectileData.codec, "projectile")
|
case ObjectClass.sparrow_projectile => ConstructorData(RemoteProjectileData.codec, "projectile")
|
||||||
|
|
|
||||||
|
|
@ -9,14 +9,15 @@ import shapeless.{::, HNil}
|
||||||
object RemoteProjectiles {
|
object RemoteProjectiles {
|
||||||
abstract class Data(val a: Int, val b: Int)
|
abstract class Data(val a: Int, val b: Int)
|
||||||
|
|
||||||
final case object Meteor extends Data(0, 32)
|
final case object Meteor extends Data(0, 32)
|
||||||
final case object Wasp extends Data(0, 208)
|
final case object Wasp extends Data(0, 208)
|
||||||
final case object Sparrow extends Data(13107, 187)
|
final case object Sparrow extends Data(13107, 187)
|
||||||
final case object OICW extends Data(13107, 195)
|
final case object OICW extends Data(13107, 195)
|
||||||
final case object Striker extends Data(26214, 134)
|
final case object Striker extends Data(26214, 134)
|
||||||
final case object HunterSeeker extends Data(39577, 201)
|
final case object HunterSeeker extends Data(39577, 201)
|
||||||
final case object Starfire extends Data(39577, 249)
|
final case object Starfire extends Data(39577, 249)
|
||||||
class OICWLittleBuddy(x: Int, y: Int) extends Data(x, y)
|
|
||||||
|
//the oicw_little_buddy is handled by its own transcoder
|
||||||
}
|
}
|
||||||
|
|
||||||
object FlightPhysics extends Enumeration {
|
object FlightPhysics extends Enumeration {
|
||||||
|
|
@ -67,7 +68,7 @@ object RemoteProjectileData extends Marshallable[RemoteProjectileData] {
|
||||||
("u1" | uint16) ::
|
("u1" | uint16) ::
|
||||||
("u2" | uint8) ::
|
("u2" | uint8) ::
|
||||||
("unk3" | FlightPhysics.codec) ::
|
("unk3" | FlightPhysics.codec) ::
|
||||||
("unk4" | uint(3)) ::
|
("unk4" | uint(bits = 3)) ::
|
||||||
("unk5" | uint2)
|
("unk5" | uint2)
|
||||||
).exmap[RemoteProjectileData](
|
).exmap[RemoteProjectileData](
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -2,16 +2,12 @@
|
||||||
package net.psforever.services.vehicle
|
package net.psforever.services.vehicle
|
||||||
|
|
||||||
import akka.actor.{Actor, ActorRef, Props}
|
import akka.actor.{Actor, ActorRef, Props}
|
||||||
import net.psforever.objects.{GlobalDefinitions, Tool, Vehicle}
|
|
||||||
import net.psforever.objects.ballistics.VehicleSource
|
|
||||||
import net.psforever.objects.serverobject.pad.VehicleSpawnPad
|
import net.psforever.objects.serverobject.pad.VehicleSpawnPad
|
||||||
import net.psforever.objects.serverobject.terminals.{MedicalTerminalDefinition, ProximityUnit}
|
|
||||||
import net.psforever.objects.vital.RepairFromTerm
|
|
||||||
import net.psforever.objects.zones.Zone
|
import net.psforever.objects.zones.Zone
|
||||||
import net.psforever.packet.game.ObjectCreateMessage
|
import net.psforever.packet.game.ObjectCreateMessage
|
||||||
import net.psforever.packet.game.objectcreate.ObjectCreateMessageParent
|
import net.psforever.packet.game.objectcreate.ObjectCreateMessageParent
|
||||||
import net.psforever.services.vehicle.support.TurretUpgrader
|
import net.psforever.services.vehicle.support.TurretUpgrader
|
||||||
import net.psforever.types.{DriveState, PlanetSideGUID}
|
import net.psforever.types.DriveState
|
||||||
import net.psforever.services.{GenericEventBus, Service}
|
import net.psforever.services.{GenericEventBus, Service}
|
||||||
|
|
||||||
class VehicleService(zone: Zone) extends Actor {
|
class VehicleService(zone: Zone) extends Actor {
|
||||||
|
|
@ -395,51 +391,6 @@ class VehicleService(zone: Zone) extends Actor {
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
//from ProximityTerminalControl (?)
|
|
||||||
case ProximityUnit.Action(term, target: Vehicle) =>
|
|
||||||
val medDef = term.Definition.asInstanceOf[MedicalTerminalDefinition]
|
|
||||||
val healAmount = medDef.HealAmount
|
|
||||||
if (!target.Destroyed && term.Validate(target)) {
|
|
||||||
//repair vehicle
|
|
||||||
if (healAmount > 0 && target.Health < target.MaxHealth) {
|
|
||||||
val healAmount = medDef.HealAmount
|
|
||||||
target.Health = target.Health + healAmount
|
|
||||||
target.History(RepairFromTerm(VehicleSource(target), healAmount, medDef))
|
|
||||||
VehicleEvents.publish(
|
|
||||||
VehicleServiceResponse(
|
|
||||||
s"/${term.Continent}/Vehicle",
|
|
||||||
PlanetSideGUID(0),
|
|
||||||
VehicleResponse.PlanetsideAttribute(target.GUID, 0, target.Health)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
//recharge ammunition of cavern vehicles
|
|
||||||
if (GlobalDefinitions.isCavernVehicle(target.Definition) && term.Definition == GlobalDefinitions.recharge_terminal) {
|
|
||||||
//TODO check cavern module benefits on facility; unlike facility benefits, it's faked for now
|
|
||||||
val channel = s"/${target.Actor.toString}/Vehicle"
|
|
||||||
val parent = target.GUID
|
|
||||||
val excludeNone = Service.defaultPlayerGUID
|
|
||||||
target.Weapons.values
|
|
||||||
.map { _.Equipment }
|
|
||||||
.collect { case Some(weapon: Tool) =>
|
|
||||||
weapon.AmmoSlots
|
|
||||||
.foreach { slot =>
|
|
||||||
val box = slot.Box
|
|
||||||
if (box.Capacity < slot.Definition.Magazine) {
|
|
||||||
val capacity = box.Capacity += 1
|
|
||||||
VehicleEvents.publish(
|
|
||||||
VehicleServiceResponse(
|
|
||||||
channel,
|
|
||||||
excludeNone,
|
|
||||||
VehicleResponse.InventoryState2(box.GUID, parent, capacity)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
case msg =>
|
case msg =>
|
||||||
log.warn(s"Unhandled message $msg from ${sender()}")
|
log.warn(s"Unhandled message $msg from ${sender()}")
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -295,6 +295,19 @@ object Zones {
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
if (facilityTypes.contains(structure.objectType)) {
|
||||||
|
//major overworld facilities have an intrinsic terminal that occasionally recharges ancient weapons
|
||||||
|
val buildingGuid = structure.guid
|
||||||
|
val terminalGuid = buildingGuid + 1
|
||||||
|
zoneMap.addLocalObject(
|
||||||
|
buildingGuid + 1,
|
||||||
|
ProximityTerminal.Constructor(
|
||||||
|
structure.position,
|
||||||
|
GlobalDefinitions.recharge_terminal_weapon_module
|
||||||
|
),
|
||||||
|
owningBuildingGuid = buildingGuid
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
val filteredZoneEntities =
|
val filteredZoneEntities =
|
||||||
data.filter { _.owner.contains(structure.id) } ++
|
data.filter { _.owner.contains(structure.id) } ++
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
package game.objectcreate
|
package game.objectcreate
|
||||||
|
|
||||||
import net.psforever.packet.PacketCoding
|
import net.psforever.packet.PacketCoding
|
||||||
import net.psforever.packet.game.ObjectCreateMessage
|
import net.psforever.packet.game.{ObjectCreateDetailedMessage, ObjectCreateMessage}
|
||||||
import net.psforever.packet.game.objectcreate._
|
import net.psforever.packet.game.objectcreate._
|
||||||
import net.psforever.types.{PlanetSideEmpire, PlanetSideGUID, Vector3}
|
import net.psforever.types.{PlanetSideEmpire, PlanetSideGUID, Vector3}
|
||||||
import org.specs2.mutable._
|
import org.specs2.mutable._
|
||||||
|
|
@ -11,6 +11,7 @@ import scodec.bits._
|
||||||
class RemoteProjectileDataTest extends Specification {
|
class RemoteProjectileDataTest extends Specification {
|
||||||
val string_striker_projectile = hex"17 C5000000 A4B 009D 4C129 0CB0A 9814 00 F5 E3 040000666686400"
|
val string_striker_projectile = hex"17 C5000000 A4B 009D 4C129 0CB0A 9814 00 F5 E3 040000666686400"
|
||||||
val string_hunter_seeker_missile_projectile = hex"17 c5000000 ca9 ab9e af127 ec465 3723 00 15 c4 2400009a99c9400"
|
val string_hunter_seeker_missile_projectile = hex"17 c5000000 ca9 ab9e af127 ec465 3723 00 15 c4 2400009a99c9400"
|
||||||
|
val string_oicw_little_buddy = hex"18 ef000000 aca 3d0e 1ef35 d9417 2511 00 0f 21 d3bf0d1bc38900000000000fc"
|
||||||
|
|
||||||
"RemoteProjectileData" should {
|
"RemoteProjectileData" should {
|
||||||
"decode (striker_missile_targeting_projectile)" in {
|
"decode (striker_missile_targeting_projectile)" in {
|
||||||
|
|
@ -33,7 +34,6 @@ class RemoteProjectileDataTest extends Specification {
|
||||||
deploy.v4.isEmpty mustEqual true
|
deploy.v4.isEmpty mustEqual true
|
||||||
deploy.v5.isEmpty mustEqual true
|
deploy.v5.isEmpty mustEqual true
|
||||||
deploy.guid mustEqual PlanetSideGUID(0)
|
deploy.guid mustEqual PlanetSideGUID(0)
|
||||||
|
|
||||||
unk2 mustEqual 26214
|
unk2 mustEqual 26214
|
||||||
lim mustEqual 134
|
lim mustEqual 134
|
||||||
unk3 mustEqual FlightPhysics.State4
|
unk3 mustEqual FlightPhysics.State4
|
||||||
|
|
@ -67,7 +67,6 @@ class RemoteProjectileDataTest extends Specification {
|
||||||
deploy.v4.isEmpty mustEqual true
|
deploy.v4.isEmpty mustEqual true
|
||||||
deploy.v5.isEmpty mustEqual true
|
deploy.v5.isEmpty mustEqual true
|
||||||
deploy.guid mustEqual PlanetSideGUID(0)
|
deploy.guid mustEqual PlanetSideGUID(0)
|
||||||
|
|
||||||
unk2 mustEqual 39577
|
unk2 mustEqual 39577
|
||||||
lim mustEqual 201
|
lim mustEqual 201
|
||||||
unk3 mustEqual FlightPhysics.State4
|
unk3 mustEqual FlightPhysics.State4
|
||||||
|
|
@ -81,6 +80,37 @@ class RemoteProjectileDataTest extends Specification {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
"decode (oicw_little_buddy)" in {
|
||||||
|
PacketCoding.decodePacket(string_oicw_little_buddy).require match {
|
||||||
|
case ObjectCreateDetailedMessage(len, cls, guid, parent, data) =>
|
||||||
|
len mustEqual 239
|
||||||
|
cls mustEqual ObjectClass.oicw_little_buddy
|
||||||
|
guid mustEqual PlanetSideGUID(3645)
|
||||||
|
parent.isDefined mustEqual false
|
||||||
|
data match {
|
||||||
|
case LittleBuddyProjectileData(dat, u2, u4) =>
|
||||||
|
dat.pos.coord mustEqual Vector3(3046.2344f, 3715.6953f, 68.578125f)
|
||||||
|
dat.pos.orient mustEqual Vector3(0, 317.8125f, 357.1875f)
|
||||||
|
dat.pos.vel.contains(Vector3(-10.0125f, 101.475f, -101.7f)) mustEqual true
|
||||||
|
dat.data.faction mustEqual PlanetSideEmpire.NC
|
||||||
|
dat.data.bops mustEqual false
|
||||||
|
dat.data.alternate mustEqual false
|
||||||
|
dat.data.v1 mustEqual true
|
||||||
|
dat.data.v2.isEmpty mustEqual true
|
||||||
|
dat.data.jammered mustEqual false
|
||||||
|
dat.data.v4.isEmpty mustEqual true
|
||||||
|
dat.data.v5.isEmpty mustEqual true
|
||||||
|
dat.data.guid mustEqual PlanetSideGUID(0)
|
||||||
|
u2 mustEqual 0
|
||||||
|
u4 mustEqual true
|
||||||
|
case _ =>
|
||||||
|
ko
|
||||||
|
}
|
||||||
|
case _ =>
|
||||||
|
ko
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
"encode (striker_missile_targeting_projectile)" in {
|
"encode (striker_missile_targeting_projectile)" in {
|
||||||
val obj = RemoteProjectileData(
|
val obj = RemoteProjectileData(
|
||||||
CommonFieldDataWithPlacement(
|
CommonFieldDataWithPlacement(
|
||||||
|
|
@ -101,26 +131,53 @@ class RemoteProjectileDataTest extends Specification {
|
||||||
pkt.toBitVector.drop(133).take(7) mustEqual string_striker_projectile.toBitVector.drop(133).take(7)
|
pkt.toBitVector.drop(133).take(7) mustEqual string_striker_projectile.toBitVector.drop(133).take(7)
|
||||||
pkt.toBitVector.drop(141) mustEqual string_striker_projectile.toBitVector.drop(141)
|
pkt.toBitVector.drop(141) mustEqual string_striker_projectile.toBitVector.drop(141)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
"encode (hunter_seeker_missile_projectile)" in {
|
"encode (hunter_seeker_missile_projectile)" in {
|
||||||
val obj = RemoteProjectileData(
|
val obj = RemoteProjectileData(
|
||||||
CommonFieldDataWithPlacement(
|
CommonFieldDataWithPlacement(
|
||||||
PlacementData(3621.3672f, 2701.8438f, 140.85938f, 0, 300.9375f, 258.75f),
|
PlacementData(3621.3672f, 2701.8438f, 140.85938f, 0, 300.9375f, 258.75f),
|
||||||
CommonFieldData(PlanetSideEmpire.NC, false, false, true, None, false, None, None, PlanetSideGUID(0))
|
CommonFieldData(PlanetSideEmpire.NC, false, false, true, None, false, None, None, PlanetSideGUID(0))
|
||||||
),
|
),
|
||||||
39577,
|
39577,
|
||||||
201,
|
201,
|
||||||
FlightPhysics.State4,
|
FlightPhysics.State4,
|
||||||
0,
|
0,
|
||||||
0
|
0
|
||||||
)
|
)
|
||||||
val msg = ObjectCreateMessage(ObjectClass.hunter_seeker_missile_projectile, PlanetSideGUID(40619), obj)
|
val msg = ObjectCreateMessage(ObjectClass.hunter_seeker_missile_projectile, PlanetSideGUID(40619), obj)
|
||||||
val pkt = PacketCoding.encodePacket(msg).require.toByteVector
|
val pkt = PacketCoding.encodePacket(msg).require.toByteVector
|
||||||
//pkt mustEqual string_hunter_seeker_missile_projectile
|
//pkt mustEqual string_hunter_seeker_missile_projectile
|
||||||
|
|
||||||
pkt.toBitVector.take(132) mustEqual string_hunter_seeker_missile_projectile.toBitVector.take(132)
|
pkt.toBitVector.take(132) mustEqual string_hunter_seeker_missile_projectile.toBitVector.take(132)
|
||||||
pkt.toBitVector.drop(133).take(7) mustEqual string_hunter_seeker_missile_projectile.toBitVector.drop(133).take(7)
|
pkt.toBitVector.drop(133).take(7) mustEqual string_hunter_seeker_missile_projectile.toBitVector.drop(133).take(7)
|
||||||
pkt.toBitVector.drop(141) mustEqual string_hunter_seeker_missile_projectile.toBitVector.drop(141)
|
pkt.toBitVector.drop(141) mustEqual string_hunter_seeker_missile_projectile.toBitVector.drop(141)
|
||||||
|
}
|
||||||
|
|
||||||
|
"encode (oicw_little_buddy)" in {
|
||||||
|
val obj = LittleBuddyProjectileData(
|
||||||
|
CommonFieldDataWithPlacement(
|
||||||
|
PlacementData(Vector3(3046.2344f, 3715.6953f, 68.578125f),
|
||||||
|
Vector3(0, 317.8125f, 357.1875f),
|
||||||
|
Some(Vector3(-10.0125f, 101.475f, -101.7f))
|
||||||
|
),
|
||||||
|
CommonFieldData(
|
||||||
|
PlanetSideEmpire.NC,
|
||||||
|
bops = false,
|
||||||
|
alternate = false,
|
||||||
|
v1 = true,
|
||||||
|
v2 = None,
|
||||||
|
jammered = false,
|
||||||
|
v4 = None,
|
||||||
|
v5 = None,
|
||||||
|
guid = PlanetSideGUID(0)
|
||||||
|
)
|
||||||
|
),
|
||||||
|
u2 = 0,
|
||||||
|
u4 = true
|
||||||
|
)
|
||||||
|
val msg = ObjectCreateDetailedMessage(ObjectClass.oicw_little_buddy, PlanetSideGUID(3645), obj)
|
||||||
|
val pkt = PacketCoding.encodePacket(msg).require.toByteVector
|
||||||
|
pkt mustEqual string_oicw_little_buddy
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -921,7 +921,7 @@ class DamageModelTests extends Specification {
|
||||||
}
|
}
|
||||||
|
|
||||||
object DamageModelTests {
|
object DamageModelTests {
|
||||||
final val projectile = new ProjectileDefinition(Projectiles.heavy_grenade_projectile.id) {
|
final val projectile = new ProjectileDefinition(Projectiles.Types.heavy_grenade_projectile.id) {
|
||||||
Damage0 = 50
|
Damage0 = 50
|
||||||
Damage1 = 82
|
Damage1 = 82
|
||||||
Damage2 = 82
|
Damage2 = 82
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@ class ProjectileTest extends Specification {
|
||||||
"define (default)" in {
|
"define (default)" in {
|
||||||
val obj = new ProjectileDefinition(31) //9mmbullet_projectile
|
val obj = new ProjectileDefinition(31) //9mmbullet_projectile
|
||||||
|
|
||||||
obj.ProjectileType mustEqual Projectiles.bullet_9mm_projectile
|
obj.ProjectileType mustEqual Projectiles.Types.bullet_9mm_projectile
|
||||||
obj.ObjectId mustEqual 31
|
obj.ObjectId mustEqual 31
|
||||||
obj.Damage0 mustEqual 0
|
obj.Damage0 mustEqual 0
|
||||||
obj.Damage1 mustEqual 0
|
obj.Damage1 mustEqual 0
|
||||||
|
|
@ -84,9 +84,9 @@ class ProjectileTest extends Specification {
|
||||||
}
|
}
|
||||||
|
|
||||||
"define (failure)" in {
|
"define (failure)" in {
|
||||||
Projectiles(31) mustEqual Projectiles.bullet_9mm_projectile
|
Projectiles.Types(31) mustEqual Projectiles.Types.bullet_9mm_projectile
|
||||||
try {
|
try {
|
||||||
ProjectileDefinition(Projectiles.bullet_9mm_projectile) //passes
|
ProjectileDefinition(Projectiles.Types.bullet_9mm_projectile) //passes
|
||||||
} catch {
|
} catch {
|
||||||
case _: NoSuchElementException =>
|
case _: NoSuchElementException =>
|
||||||
ko
|
ko
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ import net.psforever.objects.guid.source.MaxNumberSource
|
||||||
import net.psforever.objects.serverobject.environment._
|
import net.psforever.objects.serverobject.environment._
|
||||||
import net.psforever.objects.serverobject.mount.Mountable
|
import net.psforever.objects.serverobject.mount.Mountable
|
||||||
import net.psforever.objects.vehicles.VehicleLockState
|
import net.psforever.objects.vehicles.VehicleLockState
|
||||||
import net.psforever.objects.vehicles.control.{CargoCarrierControl, VehicleControl}
|
import net.psforever.objects.vehicles.control.{/*CargoCarrierControl, */VehicleControl}
|
||||||
import net.psforever.objects.vital.{VehicleShieldCharge, Vitality}
|
import net.psforever.objects.vital.{VehicleShieldCharge, Vitality}
|
||||||
import net.psforever.objects.zones.{Zone, ZoneMap}
|
import net.psforever.objects.zones.{Zone, ZoneMap}
|
||||||
import net.psforever.packet.game._
|
import net.psforever.packet.game._
|
||||||
|
|
|
||||||
|
|
@ -241,6 +241,7 @@ class ProximityTerminalControlTwoUsersTest extends ActorTest {
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
avatar.Continent = "test"
|
avatar.Continent = "test"
|
||||||
|
avatar.Zone = zone
|
||||||
avatar.Spawn()
|
avatar.Spawn()
|
||||||
avatar.Health = 50
|
avatar.Health = 50
|
||||||
val avatar2 =
|
val avatar2 =
|
||||||
|
|
@ -249,12 +250,13 @@ class ProximityTerminalControlTwoUsersTest extends ActorTest {
|
||||||
ProximityTest.avatarId.getAndIncrement(),
|
ProximityTest.avatarId.getAndIncrement(),
|
||||||
"TestCharacter2",
|
"TestCharacter2",
|
||||||
PlanetSideEmpire.VS,
|
PlanetSideEmpire.VS,
|
||||||
CharacterSex.Female,
|
CharacterSex.Male,
|
||||||
1,
|
1,
|
||||||
CharacterVoice.Voice1
|
CharacterVoice.Voice1
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
avatar2.Continent = "test"
|
avatar2.Continent = "test"
|
||||||
|
avatar2.Zone = zone
|
||||||
avatar2.Spawn()
|
avatar2.Spawn()
|
||||||
avatar2.Health = 50
|
avatar2.Health = 50
|
||||||
|
|
||||||
|
|
@ -266,6 +268,7 @@ class ProximityTerminalControlTwoUsersTest extends ActorTest {
|
||||||
val probe1 = new TestProbe(system, "local-events")
|
val probe1 = new TestProbe(system, "local-events")
|
||||||
val probe2 = new TestProbe(system, "target-callback-1")
|
val probe2 = new TestProbe(system, "target-callback-1")
|
||||||
val probe3 = new TestProbe(system, "target-callback-2")
|
val probe3 = new TestProbe(system, "target-callback-2")
|
||||||
|
zone.AvatarEvents = new TestProbe(system, "avatar-events-throwaway").ref
|
||||||
zone.LocalEvents = probe1.ref
|
zone.LocalEvents = probe1.ref
|
||||||
|
|
||||||
"not send out a start message if not the first user" in {
|
"not send out a start message if not the first user" in {
|
||||||
|
|
@ -274,7 +277,7 @@ class ProximityTerminalControlTwoUsersTest extends ActorTest {
|
||||||
|
|
||||||
terminal.Actor.tell(CommonMessages.Use(avatar, Some(avatar)), probe2.ref)
|
terminal.Actor.tell(CommonMessages.Use(avatar, Some(avatar)), probe2.ref)
|
||||||
probe1.expectMsgClass(1 second, classOf[Terminal.StartProximityEffect])
|
probe1.expectMsgClass(1 second, classOf[Terminal.StartProximityEffect])
|
||||||
probe2.expectMsgClass(1 second, classOf[ProximityUnit.Action])
|
probe2.expectMsgClass(5 second, classOf[ProximityUnit.Action])
|
||||||
|
|
||||||
terminal.Actor.tell(CommonMessages.Use(avatar2, Some(avatar2)), probe3.ref)
|
terminal.Actor.tell(CommonMessages.Use(avatar2, Some(avatar2)), probe3.ref)
|
||||||
probe1.expectNoMessage(1 second)
|
probe1.expectNoMessage(1 second)
|
||||||
|
|
@ -313,15 +316,17 @@ class ProximityTerminalControlStopTest extends ActorTest {
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
avatar.Continent = "test"
|
avatar.Continent = "test"
|
||||||
|
avatar.Zone = zone
|
||||||
avatar.Spawn()
|
avatar.Spawn()
|
||||||
avatar.Health = 50
|
avatar.Health = 1
|
||||||
|
|
||||||
avatar.GUID = PlanetSideGUID(1)
|
avatar.GUID = PlanetSideGUID(1)
|
||||||
terminal.GUID = PlanetSideGUID(2)
|
terminal.GUID = PlanetSideGUID(2)
|
||||||
terminal.Actor ! Service.Startup()
|
terminal.Actor ! Service.Startup()
|
||||||
expectNoMessage(500 milliseconds) //spacer
|
expectNoMessage(500 milliseconds) //spacer
|
||||||
val probe1 = new TestProbe(system, "local-events")
|
val probe1 = new TestProbe(system, "local-events")
|
||||||
val probe2 = new TestProbe(system, "target-callback-1")
|
val probe2 = new TestProbe(system, "target-callback")
|
||||||
|
zone.AvatarEvents = new TestProbe(system, "avatar-events-throwaway").ref
|
||||||
zone.LocalEvents = probe1.ref
|
zone.LocalEvents = probe1.ref
|
||||||
|
|
||||||
"send out a stop message" in {
|
"send out a stop message" in {
|
||||||
|
|
@ -333,6 +338,14 @@ class ProximityTerminalControlStopTest extends ActorTest {
|
||||||
probe2.expectMsgClass(1 second, classOf[ProximityUnit.Action])
|
probe2.expectMsgClass(1 second, classOf[ProximityUnit.Action])
|
||||||
|
|
||||||
terminal.Actor ! CommonMessages.Unuse(avatar, Some(avatar))
|
terminal.Actor ! CommonMessages.Unuse(avatar, Some(avatar))
|
||||||
|
probe2.fishForMessage(2.seconds, hint = "could not find StopAction") {
|
||||||
|
case _ : ProximityUnit.Action => false
|
||||||
|
case _ => true
|
||||||
|
} match {
|
||||||
|
case _ : ProximityUnit.StopAction => ;
|
||||||
|
case out => assert(false, s"last message $out is not StopAction")
|
||||||
|
}
|
||||||
|
//probe2.expectMsgClass(1 second, classOf[ProximityUnit.StopAction])
|
||||||
probe1.expectMsgClass(1 second, classOf[Terminal.StopProximityEffect])
|
probe1.expectMsgClass(1 second, classOf[Terminal.StopProximityEffect])
|
||||||
assert(terminal.NumberUsers == 0)
|
assert(terminal.NumberUsers == 0)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue