mirror of
https://github.com/2revoemag/PSF-BotServer.git
synced 2026-02-28 02:33:37 +00:00
Player Control (#329)
* basic non-mounted avatar damage and death on the control actor * deferred passenger death to hand off control from mountable control to player control; removed event-focused messaging path from vehicle control to avatar-appropraiet WSA * extending manipulation of jammering secondary effects, such as stamina and implants
This commit is contained in:
parent
d0bd823e9e
commit
eebd5174a0
10 changed files with 281 additions and 256 deletions
|
|
@ -67,6 +67,7 @@ class Player(private val core : Avatar) extends PlanetSideServerObject
|
|||
var lastShotSeq_time : Int = -1
|
||||
/** From PlanetsideAttributeMessage */
|
||||
var PlanetsideAttribute : Array[Long] = Array.ofDim(120)
|
||||
var skipStaminaRegenForTurns : Int = 0
|
||||
|
||||
Player.SuitSetup(this, exosuit)
|
||||
|
||||
|
|
@ -639,6 +640,8 @@ object Player {
|
|||
final val FreeHandSlot : Int = 250
|
||||
final val HandsDownSlot : Int = 255
|
||||
|
||||
final case class Die()
|
||||
|
||||
def apply(core : Avatar) : Player = {
|
||||
new Player(core)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -162,9 +162,8 @@ object TurretControl {
|
|||
seat.isOccupied && seat.Occupant.get.isAlive
|
||||
}).foreach(seat => {
|
||||
val tplayer = seat.Occupant.get
|
||||
val tplayerGUID = tplayer.GUID
|
||||
zone.AvatarEvents ! AvatarServiceMessage(tplayer.Name, AvatarAction.KilledWhileInVehicle(tplayerGUID))
|
||||
zone.AvatarEvents ! AvatarServiceMessage(continentId, AvatarAction.ObjectDelete(tplayerGUID, tplayerGUID)) //dead player still sees self
|
||||
tplayer.History(lastShot)
|
||||
tplayer.Actor ! Player.Die()
|
||||
})
|
||||
//vehicle wreckage has no weapons
|
||||
target.Weapons.values
|
||||
|
|
|
|||
|
|
@ -1,15 +1,234 @@
|
|||
// Copyright (c) 2019 PSForever
|
||||
// Copyright (c) 2020 PSForever
|
||||
package net.psforever.objects.avatar
|
||||
|
||||
import akka.actor.Actor
|
||||
import net.psforever.objects.Player
|
||||
import net.psforever.objects.ballistics.{PlayerSource, ResolvedProjectile, SourceEntry}
|
||||
import net.psforever.objects.equipment.{JammableBehavior, JammableUnit}
|
||||
import net.psforever.objects.vital.{PlayerSuicide, Vitality}
|
||||
import net.psforever.objects.zones.Zone
|
||||
import net.psforever.packet.game._
|
||||
import net.psforever.types.{ExoSuitType, PlanetSideGUID}
|
||||
import services.Service
|
||||
import services.avatar.{AvatarAction, AvatarServiceMessage}
|
||||
|
||||
import scala.concurrent.duration._
|
||||
|
||||
/**
|
||||
* na;
|
||||
* stub for future development
|
||||
*/
|
||||
class PlayerControl(player : Player) extends Actor {
|
||||
def receive : Receive = {
|
||||
class PlayerControl(player : Player) extends Actor
|
||||
with JammableBehavior {
|
||||
def JammableObject = player
|
||||
|
||||
def receive : Receive = jammableBehavior.orElse {
|
||||
case Player.Die() =>
|
||||
PlayerControl.HandleDestructionAwareness(player, player.GUID, None)
|
||||
|
||||
case Vitality.Damage(resolution_function) =>
|
||||
if(player.isAlive) {
|
||||
val originalHealth = player.Health
|
||||
val originalArmor = player.Armor
|
||||
val originalCapacitor = player.Capacitor.toInt
|
||||
val cause = resolution_function(player)
|
||||
val health = player.Health
|
||||
val armor = player.Armor
|
||||
val capacitor = player.Capacitor.toInt
|
||||
val damageToHealth = originalHealth - health
|
||||
val damageToArmor = originalArmor - armor
|
||||
val damageToCapacitor = originalCapacitor - capacitor
|
||||
PlayerControl.HandleDamageResolution(player, cause, damageToHealth, damageToArmor, damageToCapacitor)
|
||||
if(damageToHealth != 0 || damageToArmor != 0 || damageToCapacitor != 0) {
|
||||
org.log4s.getLogger("DamageResolution")
|
||||
.info(s"${player.Name}-infantry: BEFORE=$originalHealth/$originalArmor/$originalCapacitor, AFTER=$health/$armor/$capacitor, CHANGE=$damageToHealth/$damageToArmor/$damageToCapacitor")
|
||||
}
|
||||
}
|
||||
case _ => ;
|
||||
}
|
||||
|
||||
/**
|
||||
* Start the jammered buzzing.
|
||||
* Although, as a rule, the jammering sound effect should last as long as the jammering status,
|
||||
* Infantry seem to hear the sound for a bit longer than the effect.
|
||||
* @see `JammableBehavior.StartJammeredSound`
|
||||
* @param target an object that can be affected by the jammered status
|
||||
* @param dur the duration of the timer, in milliseconds;
|
||||
* by default, 30000
|
||||
*/
|
||||
override def StartJammeredSound(target : Any, dur : Int) : Unit = target match {
|
||||
case obj : Player if !jammedSound =>
|
||||
obj.Zone.AvatarEvents ! AvatarServiceMessage(obj.Zone.Id, AvatarAction.PlanetsideAttributeToAll(obj.GUID, 27, 1))
|
||||
super.StartJammeredSound(obj, 3000)
|
||||
case _ => ;
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform a variety of tasks to indicate being jammered.
|
||||
* Deactivate implants (should also uninitialize them),
|
||||
* delay stamina regeneration for a certain number of turns,
|
||||
* and set the jammered status on specific holstered equipment.
|
||||
* @see `JammableBehavior.StartJammeredStatus`
|
||||
* @param target an object that can be affected by the jammered status
|
||||
* @param dur the duration of the timer, in milliseconds
|
||||
*/
|
||||
override def StartJammeredStatus(target : Any, dur : Int) : Unit = target match {
|
||||
case obj : Player =>
|
||||
//TODO these features
|
||||
obj.Zone.AvatarEvents ! AvatarServiceMessage(obj.Zone.Id, AvatarAction.DeactivateImplantSlot(obj.GUID, 1))
|
||||
obj.Zone.AvatarEvents ! AvatarServiceMessage(obj.Zone.Id, AvatarAction.DeactivateImplantSlot(obj.GUID, 2))
|
||||
obj.skipStaminaRegenForTurns = math.max(obj.skipStaminaRegenForTurns, 10)
|
||||
super.StartJammeredStatus(target, dur)
|
||||
case _ => ;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop the jammered buzzing.
|
||||
* @see `JammableBehavior.CancelJammeredSound`
|
||||
* @param target an object that can be affected by the jammered status
|
||||
*/
|
||||
override def CancelJammeredSound(target : Any) : Unit = target match {
|
||||
case obj : Player if jammedSound =>
|
||||
obj.Zone.AvatarEvents ! AvatarServiceMessage(obj.Zone.Id, AvatarAction.PlanetsideAttributeToAll(obj.GUID, 27, 0))
|
||||
super.CancelJammeredSound(obj)
|
||||
case _ => ;
|
||||
}
|
||||
}
|
||||
|
||||
object PlayerControl {
|
||||
/**
|
||||
* na
|
||||
* @param target na
|
||||
*/
|
||||
def HandleDamageResolution(target : Player, cause : ResolvedProjectile, damageToHealth : Int, damageToArmor : Int, damageToCapacitor : Int) : Unit = {
|
||||
val targetGUID = target.GUID
|
||||
val playerGUID = target.Zone.LivePlayers.find { p => cause.projectile.owner.Name.equals(p.Name) } match {
|
||||
case Some(player) => player.GUID
|
||||
case _ => PlanetSideGUID(0)
|
||||
}
|
||||
if(target.Health > 0) {
|
||||
//activity on map
|
||||
if(damageToHealth + damageToArmor > 0) {
|
||||
target.Zone.Activity ! Zone.HotSpot.Activity(cause.target, cause.projectile.owner, cause.hit_pos)
|
||||
//alert damage source
|
||||
HandleDamageAwareness(target, playerGUID, cause)
|
||||
}
|
||||
if(cause.projectile.profile.JammerProjectile) {
|
||||
target.Actor ! JammableUnit.Jammered(cause)
|
||||
}
|
||||
}
|
||||
else {
|
||||
HandleDestructionAwareness(target, playerGUID, Some(cause))
|
||||
}
|
||||
if(damageToHealth > 0) {
|
||||
target.Zone.AvatarEvents ! AvatarServiceMessage(target.Zone.Id, AvatarAction.PlanetsideAttributeToAll(targetGUID, 0, target.Health))
|
||||
}
|
||||
if(damageToArmor > 0) {
|
||||
target.Zone.AvatarEvents ! AvatarServiceMessage(target.Zone.Id, AvatarAction.PlanetsideAttributeToAll(targetGUID, 4, target.Armor))
|
||||
}
|
||||
if(damageToCapacitor > 0) {
|
||||
target.Zone.AvatarEvents ! AvatarServiceMessage(target.Name, AvatarAction.PlanetsideAttributeSelf(targetGUID, 7, target.Capacitor.toLong))
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* na
|
||||
* @param target na
|
||||
* @param attribution na
|
||||
* @param lastShot na
|
||||
*/
|
||||
def HandleDamageAwareness(target : Player, attribution : PlanetSideGUID, lastShot : ResolvedProjectile) : Unit = {
|
||||
val owner = lastShot.projectile.owner
|
||||
owner match {
|
||||
case pSource : PlayerSource =>
|
||||
target.Zone.LivePlayers.find(_.Name == pSource.Name) match {
|
||||
case Some(tplayer) =>
|
||||
target.Zone.AvatarEvents ! AvatarServiceMessage(
|
||||
target.Name,
|
||||
AvatarAction.HitHint(tplayer.GUID, target.GUID)
|
||||
)
|
||||
case None => ;
|
||||
}
|
||||
case vSource : SourceEntry =>
|
||||
target.Zone.AvatarEvents ! AvatarServiceMessage(
|
||||
target.Name,
|
||||
AvatarAction.SendResponse(Service.defaultPlayerGUID, DamageWithPositionMessage(10, vSource.Position))
|
||||
)
|
||||
case _ => ;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The player has lost all his vitality and must be killed.<br>
|
||||
* <br>
|
||||
* Shift directly into a state of being dead on the client by setting health to zero points,
|
||||
* whereupon the player will perform a dramatic death animation.
|
||||
* Stamina is also set to zero points.
|
||||
* If the player was in a vehicle at the time of demise, special conditions apply and
|
||||
* the model must be manipulated so it behaves correctly.
|
||||
* Do not move or completely destroy the `Player` object as its coordinates of death will be important.<br>
|
||||
* <br>
|
||||
* A maximum revive waiting timer is started.
|
||||
* When this timer reaches zero, the avatar will attempt to spawn back on its faction-specific sanctuary continent.
|
||||
* @param target na
|
||||
* @param attribution na
|
||||
* @param lastShot na
|
||||
*/
|
||||
def HandleDestructionAwareness(target : Player, attribution : PlanetSideGUID, lastShot : Option[ResolvedProjectile]) : Unit = {
|
||||
val player_guid = target.GUID
|
||||
val pos = target.Position
|
||||
val respawnTimer = 300000 //milliseconds
|
||||
val zone = target.Zone
|
||||
val events = zone.AvatarEvents
|
||||
val nameChannel = target.Name
|
||||
val zoneChannel = zone.Id
|
||||
target.Die
|
||||
target.Actor ! JammableUnit.ClearJammeredSound()
|
||||
target.Actor ! JammableUnit.ClearJammeredStatus()
|
||||
events ! AvatarServiceMessage(nameChannel, AvatarAction.Killed(player_guid)) //align client interface fields with state
|
||||
if(target.VehicleSeated.nonEmpty) {
|
||||
//make player invisible (if not, the cadaver sticks out the side in a seated position)
|
||||
events ! AvatarServiceMessage(nameChannel, AvatarAction.PlanetsideAttributeToAll(player_guid, 29, 1))
|
||||
//only the dead player should "see" their own body, so that the death camera has something to focus on
|
||||
events ! AvatarServiceMessage(zoneChannel, AvatarAction.ObjectDelete(player_guid, player_guid))
|
||||
}
|
||||
events ! AvatarServiceMessage(zoneChannel, AvatarAction.PlanetsideAttributeToAll(player_guid, 0, 0)) //health
|
||||
events ! AvatarServiceMessage(nameChannel, AvatarAction.PlanetsideAttributeToAll(player_guid, 2, 0)) //stamina
|
||||
events ! AvatarServiceMessage(zoneChannel, AvatarAction.PlanetsideAttributeToAll(player_guid, 4, target.Armor)) //armor
|
||||
if(target.ExoSuit == ExoSuitType.MAX) {
|
||||
events ! AvatarServiceMessage(nameChannel, AvatarAction.PlanetsideAttributeToAll(player_guid, 7, 0)) // capacitor
|
||||
}
|
||||
events ! AvatarServiceMessage(
|
||||
nameChannel,
|
||||
AvatarAction.SendResponse(Service.defaultPlayerGUID, DestroyMessage(player_guid, player_guid, Service.defaultPlayerGUID, pos)) //how many players get this message?
|
||||
)
|
||||
events ! AvatarServiceMessage(
|
||||
nameChannel,
|
||||
AvatarAction.SendResponse(Service.defaultPlayerGUID, AvatarDeadStateMessage(DeadState.Dead, respawnTimer, respawnTimer, pos, target.Faction, true))
|
||||
)
|
||||
//TODO other methods of death?
|
||||
val pentry = PlayerSource(target)
|
||||
(target.History.find({p => p.isInstanceOf[PlayerSuicide]}) match {
|
||||
case Some(PlayerSuicide(_)) =>
|
||||
None
|
||||
case _ =>
|
||||
lastShot.orElse { target.LastShot } match {
|
||||
case out @ Some(shot) =>
|
||||
if(System.nanoTime - shot.hit_time < (10 seconds).toNanos) {
|
||||
out
|
||||
}
|
||||
else {
|
||||
None //suicide
|
||||
}
|
||||
case None =>
|
||||
None //suicide
|
||||
}
|
||||
}) match {
|
||||
case Some(shot) =>
|
||||
zone.Activity ! Zone.HotSpot.Activity(pentry, shot.projectile.owner, shot.hit_pos)
|
||||
events ! AvatarServiceMessage(zoneChannel, AvatarAction.DestroyDisplay(shot.projectile.owner, pentry, shot.projectile.attribute_to))
|
||||
case None =>
|
||||
events ! AvatarServiceMessage(zoneChannel, AvatarAction.DestroyDisplay(pentry, pentry, 0))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -148,7 +148,7 @@ trait JammableBehavior {
|
|||
jammedSound = true
|
||||
import scala.concurrent.ExecutionContext.Implicits.global
|
||||
jammeredSoundTimer.cancel
|
||||
jammeredSoundTimer = context.system.scheduler.scheduleOnce(dur seconds, self, JammableUnit.ClearJammeredSound())
|
||||
jammeredSoundTimer = context.system.scheduler.scheduleOnce(dur milliseconds, self, JammableUnit.ClearJammeredSound())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
package net.psforever.objects.serverobject.turret
|
||||
|
||||
import akka.actor.Actor
|
||||
import net.psforever.objects.Player
|
||||
import net.psforever.objects.ballistics.ResolvedProjectile
|
||||
import net.psforever.objects.equipment.{JammableMountedWeapons, JammableUnit}
|
||||
import net.psforever.objects.serverobject.mount.{Mountable, MountableBehavior}
|
||||
|
|
@ -130,9 +131,8 @@ object FacilityTurretControl {
|
|||
seat.isOccupied && seat.Occupant.get.isAlive
|
||||
}).foreach(seat => {
|
||||
val tplayer = seat.Occupant.get
|
||||
val tplayerGUID = tplayer.GUID
|
||||
zone.AvatarEvents ! AvatarServiceMessage(tplayer.Name, AvatarAction.KilledWhileInVehicle(tplayerGUID))
|
||||
zone.AvatarEvents ! AvatarServiceMessage(zoneId, AvatarAction.ObjectDelete(tplayerGUID, tplayerGUID)) //dead player still sees self
|
||||
tplayer.History(lastShot)
|
||||
tplayer.Actor ! Player.Die()
|
||||
})
|
||||
//turret wreckage has no weapons
|
||||
// target.Weapons.values
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
package net.psforever.objects.vehicles
|
||||
|
||||
import akka.actor.{Actor, ActorRef}
|
||||
import net.psforever.objects.{GlobalDefinitions, Vehicle}
|
||||
import net.psforever.objects.{GlobalDefinitions, Player, Vehicle}
|
||||
import net.psforever.objects.ballistics.{ResolvedProjectile, VehicleSource}
|
||||
import net.psforever.objects.equipment.{JammableMountedWeapons, JammableUnit}
|
||||
import net.psforever.objects.serverobject.mount.{Mountable, MountableBehavior}
|
||||
|
|
@ -226,9 +226,8 @@ object VehicleControl {
|
|||
seat.isOccupied && seat.Occupant.get.isAlive
|
||||
}).foreach(seat => {
|
||||
val tplayer = seat.Occupant.get
|
||||
val tplayerGUID = tplayer.GUID
|
||||
zone.AvatarEvents ! AvatarServiceMessage(tplayer.Name, AvatarAction.KilledWhileInVehicle(tplayerGUID))
|
||||
zone.AvatarEvents ! AvatarServiceMessage(continentId, AvatarAction.ObjectDelete(tplayerGUID, tplayerGUID)) //dead player still sees self
|
||||
tplayer.History(lastShot)
|
||||
tplayer.Actor ! Player.Die()
|
||||
})
|
||||
//vehicle wreckage has no weapons
|
||||
target.Weapons.values
|
||||
|
|
|
|||
|
|
@ -70,10 +70,10 @@ class AvatarService(zone : Zone) extends Actor {
|
|||
AvatarEvents.publish(
|
||||
AvatarServiceResponse(s"/$forChannel/Avatar", player_guid, AvatarResponse.EnvironmentalDamage(player_guid, source_guid, amount))
|
||||
)
|
||||
case AvatarAction.Damage(player_guid, target, resolution_function) =>
|
||||
case AvatarAction.DeactivateImplantSlot(player_guid, slot) =>
|
||||
AvatarEvents.publish(
|
||||
AvatarServiceResponse(s"/$forChannel/Avatar", player_guid, AvatarResponse.DamageResolution(target, resolution_function))
|
||||
)
|
||||
AvatarServiceResponse(s"/$forChannel/Avatar", player_guid, AvatarResponse.DeactivateImplantSlot(slot))
|
||||
)
|
||||
case AvatarAction.DeployItem(player_guid, item) =>
|
||||
val definition = item.Definition
|
||||
val objectData = definition.Packet.ConstructorData(item).get
|
||||
|
|
@ -119,9 +119,9 @@ class AvatarService(zone : Zone) extends Actor {
|
|||
AvatarEvents.publish(
|
||||
AvatarServiceResponse(s"/$forChannel/Avatar", player_guid, AvatarResponse.HitHint(source_guid))
|
||||
)
|
||||
case AvatarAction.KilledWhileInVehicle(player_guid) =>
|
||||
case AvatarAction.Killed(player_guid) =>
|
||||
AvatarEvents.publish(
|
||||
AvatarServiceResponse(s"/$forChannel/Avatar", player_guid, AvatarResponse.KilledWhileInVehicle())
|
||||
AvatarServiceResponse(s"/$forChannel/Avatar", player_guid, AvatarResponse.Killed())
|
||||
)
|
||||
case AvatarAction.LoadPlayer(player_guid, object_id, target_guid, cdata, pdata) =>
|
||||
val pkt = pdata match {
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@ import net.psforever.objects.ballistics.{Projectile, SourceEntry}
|
|||
import net.psforever.objects.ce.Deployable
|
||||
import net.psforever.objects.equipment.Equipment
|
||||
import net.psforever.objects.inventory.Container
|
||||
import net.psforever.objects.vital.resolution.ResolutionCalculations
|
||||
import net.psforever.objects.zones.Zone
|
||||
import net.psforever.packet.PlanetSideGamePacket
|
||||
import net.psforever.packet.game.objectcreate.{ConstructorData, ObjectCreateMessageParent}
|
||||
|
|
@ -31,15 +30,15 @@ object AvatarAction {
|
|||
final case class ChangeFireState_Stop(player_guid : PlanetSideGUID, weapon_guid : PlanetSideGUID) extends Action
|
||||
final case class ConcealPlayer(player_guid : PlanetSideGUID) extends Action
|
||||
final case class EnvironmentalDamage(player_guid : PlanetSideGUID, source_guid : PlanetSideGUID, amount: Int) extends Action
|
||||
final case class Damage(player_guid : PlanetSideGUID, target : Player, resolution_function : ResolutionCalculations.Output) extends Action
|
||||
final case class DeployItem(player_guid : PlanetSideGUID, item : PlanetSideGameObject with Deployable) extends Action
|
||||
final case class DeactivateImplantSlot(player_guid : PlanetSideGUID, slot : Int) extends Action
|
||||
final case class Destroy(victim : PlanetSideGUID, killer : PlanetSideGUID, weapon : PlanetSideGUID, pos : Vector3) extends Action
|
||||
final case class DestroyDisplay(killer : SourceEntry, victim : SourceEntry, method : Int, unk : Int = 121) extends Action
|
||||
final case class DropItem(player_guid : PlanetSideGUID, item : Equipment, zone : Zone) extends Action
|
||||
final case class EquipmentInHand(player_guid : PlanetSideGUID, target_guid : PlanetSideGUID, slot : Int, item : Equipment) extends Action
|
||||
final case class GenericObjectAction(player_guid : PlanetSideGUID, object_guid : PlanetSideGUID, action_code : Int) extends Action
|
||||
final case class HitHint(source_guid : PlanetSideGUID, player_guid : PlanetSideGUID) extends Action
|
||||
final case class KilledWhileInVehicle(player_guid : PlanetSideGUID) extends Action
|
||||
final case class Killed(player_guid : PlanetSideGUID) extends Action
|
||||
final case class LoadPlayer(player_guid : PlanetSideGUID, object_id : Int, target_guid : PlanetSideGUID, cdata : ConstructorData, pdata : Option[ObjectCreateMessageParent]) extends Action
|
||||
final case class LoadProjectile(player_guid : PlanetSideGUID, object_id : Int, projectile_guid : PlanetSideGUID, cdata : ConstructorData) extends Action
|
||||
final case class ObjectDelete(player_guid : PlanetSideGUID, item_guid : PlanetSideGUID, unk : Int = 0) extends Action
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ package services.avatar
|
|||
import net.psforever.objects.Player
|
||||
import net.psforever.objects.ballistics.{Projectile, SourceEntry}
|
||||
import net.psforever.objects.equipment.Equipment
|
||||
import net.psforever.objects.vital.resolution.ResolutionCalculations
|
||||
import net.psforever.packet.PlanetSideGamePacket
|
||||
import net.psforever.packet.game.objectcreate.ConstructorData
|
||||
import net.psforever.packet.game.ObjectCreateMessage
|
||||
|
|
@ -26,14 +25,14 @@ object AvatarResponse {
|
|||
final case class ChangeFireState_Stop(weapon_guid : PlanetSideGUID) extends Response
|
||||
final case class ConcealPlayer() extends Response
|
||||
final case class EnvironmentalDamage(target : PlanetSideGUID, source_guid : PlanetSideGUID, amount : Int) extends Response
|
||||
final case class DamageResolution(target : Player, resolution_function : ResolutionCalculations.Output) extends Response
|
||||
final case class DeactivateImplantSlot(slot : Int) extends Response
|
||||
final case class Destroy(victim : PlanetSideGUID, killer : PlanetSideGUID, weapon : PlanetSideGUID, pos : Vector3) extends Response
|
||||
final case class DestroyDisplay(killer : SourceEntry, victim : SourceEntry, method : Int, unk : Int) extends Response
|
||||
final case class DropItem(pkt : ObjectCreateMessage) extends Response
|
||||
final case class EquipmentInHand(pkt : ObjectCreateMessage) extends Response
|
||||
final case class GenericObjectAction(object_guid : PlanetSideGUID, action_code : Int) extends Response
|
||||
final case class HitHint(source_guid : PlanetSideGUID) extends Response
|
||||
final case class KilledWhileInVehicle() extends Response
|
||||
final case class Killed() extends Response
|
||||
final case class LoadPlayer(pkt : ObjectCreateMessage) extends Response
|
||||
final case class LoadProjectile(pkt : ObjectCreateMessage) extends Response
|
||||
final case class ObjectDelete(item_guid : PlanetSideGUID, unk : Int) extends Response
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue