mirror of
https://github.com/2revoemag/PSF-BotServer.git
synced 2026-07-14 07:55:07 +00:00
Modifying AvatarDeadStateMessage to manipulate visible respawn points on deployment mpa; improving postStop conditions on WSA to consider player in different situations; added basic Zone.Population.(message) case statements
This commit is contained in:
parent
f444a35785
commit
82c68ebedb
5 changed files with 136 additions and 32 deletions
|
|
@ -359,7 +359,7 @@ object Zone {
|
||||||
* Message that acts in reply to `Spawn(avatar, player)`, but the avatar already has a player.
|
* Message that acts in reply to `Spawn(avatar, player)`, but the avatar already has a player.
|
||||||
* @param player the `Player` object
|
* @param player the `Player` object
|
||||||
*/
|
*/
|
||||||
final case class PlayerAlreadySpawned(player : Player)
|
final case class PlayerAlreadySpawned(zone : Zone, player : Player)
|
||||||
/**
|
/**
|
||||||
* Message that acts in reply to `Spawn(avatar, player)`, but the avatar did not initially `Join` this zone.
|
* Message that acts in reply to `Spawn(avatar, player)`, but the avatar did not initially `Join` this zone.
|
||||||
* @param zone the `Zone` object
|
* @param zone the `Zone` object
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,7 @@ class ZonePopulationActor(zone : Zone, playerMap : TrieMap[Avatar, Option[Player
|
||||||
PopulationSpawn(avatar, player, playerMap) match {
|
PopulationSpawn(avatar, player, playerMap) match {
|
||||||
case Some(tplayer) =>
|
case Some(tplayer) =>
|
||||||
if(tplayer ne player) {
|
if(tplayer ne player) {
|
||||||
sender ! Zone.Population.PlayerAlreadySpawned(player)
|
sender ! Zone.Population.PlayerAlreadySpawned(zone, player)
|
||||||
}
|
}
|
||||||
case None =>
|
case None =>
|
||||||
sender ! Zone.Population.PlayerCanNotSpawn(zone, player)
|
sender ! Zone.Population.PlayerCanNotSpawn(zone, player)
|
||||||
|
|
|
||||||
|
|
@ -2,15 +2,19 @@
|
||||||
package net.psforever.packet.game
|
package net.psforever.packet.game
|
||||||
|
|
||||||
import net.psforever.packet.{GamePacketOpcode, Marshallable, PacketHelpers, PlanetSideGamePacket}
|
import net.psforever.packet.{GamePacketOpcode, Marshallable, PacketHelpers, PlanetSideGamePacket}
|
||||||
import net.psforever.types.Vector3
|
import net.psforever.types.{PlanetSideEmpire, Vector3}
|
||||||
import scodec.Codec
|
import scodec.Attempt.{Failure, Successful}
|
||||||
|
import scodec.{Codec, Err}
|
||||||
import scodec.codecs._
|
import scodec.codecs._
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An `Enumeration` of the various states a `Player` may possess in the cycle of nanite life and death.
|
||||||
|
*/
|
||||||
object DeadState extends Enumeration {
|
object DeadState extends Enumeration {
|
||||||
type Type = Value
|
type Type = Value
|
||||||
|
|
||||||
val
|
val
|
||||||
Nothing,
|
Alive,
|
||||||
Dead,
|
Dead,
|
||||||
Release,
|
Release,
|
||||||
RespawnTime
|
RespawnTime
|
||||||
|
|
@ -20,19 +24,41 @@ object DeadState extends Enumeration {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* na
|
* Dispatched by the server to manipulate the client's management of the `Player` object owned by the user as his "avatar."<br>
|
||||||
* @param state avatar's relationship with the world
|
* <br>
|
||||||
|
* The cycle of a player is generally `Alive` to `Dead` and `Dead` to `Release` and `Release` to `RespawnTimer` to `Alive`.
|
||||||
|
* When deconstructing oneself, the user makes a jump between `Alive` and `Release`;
|
||||||
|
* and, he may make a further jump from `Release` to `Alive` depending on spawning choices.
|
||||||
|
* Being `Alive` is the most common state.
|
||||||
|
* (Despite what anyone says.)
|
||||||
|
* Being `Dead` is just a technical requirement to initialize the revive timer.
|
||||||
|
* The player should be sufficiently "dead" by having his health points decreased to zero.
|
||||||
|
* If the timer is reduced to zero, the player is sent back to their faction-appropriate sanctuary continent.<br>
|
||||||
|
* <br>
|
||||||
|
* `Release` causes a "dead" player to have its character model converted into a backpack or a form of pastry.
|
||||||
|
* This cancels the revival timer - the player may no longer be revived - and brings the user to the deployment map.
|
||||||
|
* From the deployment map, the user may select a place where they may respawn a new character.
|
||||||
|
* The options available form this spawn are not only related to the faction affinity of the bases compared to the user's player(s)
|
||||||
|
* but also to the field `faction` as is provided in the packet.
|
||||||
|
* If the player is converted to a state of `Release` while being alive, the deployment map is still displayed.
|
||||||
|
* Their character model is not replaced by a backpack or pastry.<br>
|
||||||
|
* <br>
|
||||||
|
* `RespawnTimer` is like `Dead` as it is just a formal distinction to cause the client to display a timer.
|
||||||
|
* The state indicates that the player is being resurrected at a previously-selected location in the state `Alive`.
|
||||||
|
* @param state avatar's mortal relationship with the world;
|
||||||
|
* the following timers are applicable during `Death` and `RespawnTimer`;
|
||||||
|
* `faction` is applicable mainly during `Release`
|
||||||
* @param timer_max total length of respawn countdown, in milliseconds
|
* @param timer_max total length of respawn countdown, in milliseconds
|
||||||
* @param timer initial length of the respawn timer, in milliseconds
|
* @param timer initial length of the respawn timer, in milliseconds
|
||||||
* @param pos last position
|
* @param pos player's last position
|
||||||
* @param unk4 na
|
* @param faction spawn points available for this faction on redeployment map
|
||||||
* @param unk5 na
|
* @param unk5 na
|
||||||
*/
|
*/
|
||||||
final case class AvatarDeadStateMessage(state : DeadState.Value,
|
final case class AvatarDeadStateMessage(state : DeadState.Value,
|
||||||
timer_max : Long,
|
timer_max : Long,
|
||||||
timer : Long,
|
timer : Long,
|
||||||
pos : Vector3,
|
pos : Vector3,
|
||||||
unk4 : Long,
|
faction : PlanetSideEmpire.Value,
|
||||||
unk5 : Boolean)
|
unk5 : Boolean)
|
||||||
extends PlanetSideGamePacket {
|
extends PlanetSideGamePacket {
|
||||||
type Packet = AvatarDeadStateMessage
|
type Packet = AvatarDeadStateMessage
|
||||||
|
|
@ -41,12 +67,32 @@ final case class AvatarDeadStateMessage(state : DeadState.Value,
|
||||||
}
|
}
|
||||||
|
|
||||||
object AvatarDeadStateMessage extends Marshallable[AvatarDeadStateMessage] {
|
object AvatarDeadStateMessage extends Marshallable[AvatarDeadStateMessage] {
|
||||||
|
/**
|
||||||
|
* allocate all values from the `PlanetSideEmpire` `Enumeration`
|
||||||
|
*/
|
||||||
|
private val factionLongValues = PlanetSideEmpire.values map { _.id.toLong }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* `Codec` for converting between the limited `PlanetSideEmpire` `Enumeration` and a `Long` value.
|
||||||
|
*/
|
||||||
|
private val factionLongCodec = uint32L.exmap[PlanetSideEmpire.Value] (
|
||||||
|
fv =>
|
||||||
|
if(factionLongValues.contains(fv)) {
|
||||||
|
Successful(PlanetSideEmpire(fv.toInt))
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Failure(Err(s"$fv is not mapped to a PlanetSideEmpire value"))
|
||||||
|
},
|
||||||
|
f =>
|
||||||
|
Successful(f.id.toLong)
|
||||||
|
)
|
||||||
|
|
||||||
implicit val codec : Codec[AvatarDeadStateMessage] = (
|
implicit val codec : Codec[AvatarDeadStateMessage] = (
|
||||||
("state" | DeadState.codec) ::
|
("state" | DeadState.codec) ::
|
||||||
("timer_max" | uint32L) ::
|
("timer_max" | uint32L) ::
|
||||||
("timer" | uint32L) ::
|
("timer" | uint32L) ::
|
||||||
("pos" | Vector3.codec_pos) ::
|
("pos" | Vector3.codec_pos) ::
|
||||||
("unk4" | uint32L) ::
|
("unk4" | factionLongCodec) ::
|
||||||
("unk5" | bool)
|
("unk5" | bool)
|
||||||
).as[AvatarDeadStateMessage]
|
).as[AvatarDeadStateMessage]
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,11 +4,12 @@ package game
|
||||||
import org.specs2.mutable._
|
import org.specs2.mutable._
|
||||||
import net.psforever.packet._
|
import net.psforever.packet._
|
||||||
import net.psforever.packet.game._
|
import net.psforever.packet.game._
|
||||||
import net.psforever.types.Vector3
|
import net.psforever.types.{PlanetSideEmpire, Vector3}
|
||||||
import scodec.bits._
|
import scodec.bits._
|
||||||
|
|
||||||
class AvatarDeadStateMessageTest extends Specification {
|
class AvatarDeadStateMessageTest extends Specification {
|
||||||
val string = hex"ad3c1260801c12608009f99861fb0741e040000010"
|
val string = hex"ad3c1260801c12608009f99861fb0741e040000010"
|
||||||
|
val string_invalid = hex"ad3c1260801c12608009f99861fb0741e0400000F0"
|
||||||
|
|
||||||
"decode" in {
|
"decode" in {
|
||||||
PacketCoding.DecodePacket(string).require match {
|
PacketCoding.DecodePacket(string).require match {
|
||||||
|
|
@ -17,15 +18,19 @@ class AvatarDeadStateMessageTest extends Specification {
|
||||||
unk2 mustEqual 300000
|
unk2 mustEqual 300000
|
||||||
unk3 mustEqual 300000
|
unk3 mustEqual 300000
|
||||||
pos mustEqual Vector3(6552.617f,4602.375f,60.90625f)
|
pos mustEqual Vector3(6552.617f,4602.375f,60.90625f)
|
||||||
unk4 mustEqual 2
|
unk4 mustEqual PlanetSideEmpire.VS
|
||||||
unk5 mustEqual true
|
unk5 mustEqual true
|
||||||
case _ =>
|
case _ =>
|
||||||
ko
|
ko
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
"decode (failure)" in {
|
||||||
|
PacketCoding.DecodePacket(string_invalid).isFailure mustEqual true
|
||||||
|
}
|
||||||
|
|
||||||
"encode" in {
|
"encode" in {
|
||||||
val msg = AvatarDeadStateMessage(DeadState.Dead, 300000, 300000, Vector3(6552.617f,4602.375f,60.90625f), 2, true)
|
val msg = AvatarDeadStateMessage(DeadState.Dead, 300000, 300000, Vector3(6552.617f,4602.375f,60.90625f), PlanetSideEmpire.VS, true)
|
||||||
val pkt = PacketCoding.EncodePacket(msg).require.toByteVector
|
val pkt = PacketCoding.EncodePacket(msg).require.toByteVector
|
||||||
|
|
||||||
pkt mustEqual string
|
pkt mustEqual string
|
||||||
|
|
|
||||||
|
|
@ -56,7 +56,7 @@ class WorldSessionActor extends Actor with MDCContextAware {
|
||||||
var vehicleService : ActorRef = ActorRef.noSender
|
var vehicleService : ActorRef = ActorRef.noSender
|
||||||
var taskResolver : ActorRef = Actor.noSender
|
var taskResolver : ActorRef = Actor.noSender
|
||||||
var galaxy : ActorRef = Actor.noSender
|
var galaxy : ActorRef = Actor.noSender
|
||||||
var continent : Zone = null
|
var continent : Zone = Zone.Nowhere
|
||||||
var player : Player = null
|
var player : Player = null
|
||||||
var avatar : Avatar = null
|
var avatar : Avatar = null
|
||||||
var progressBarValue : Option[Float] = None
|
var progressBarValue : Option[Float] = None
|
||||||
|
|
@ -74,7 +74,7 @@ class WorldSessionActor extends Actor with MDCContextAware {
|
||||||
override def postStop() = {
|
override def postStop() = {
|
||||||
clientKeepAlive.cancel
|
clientKeepAlive.cancel
|
||||||
reviveTimer.cancel
|
reviveTimer.cancel
|
||||||
PlayerActionsToCancel() //progressBarUpdate.cancel
|
PlayerActionsToCancel()
|
||||||
localService ! Service.Leave()
|
localService ! Service.Leave()
|
||||||
vehicleService ! Service.Leave()
|
vehicleService ! Service.Leave()
|
||||||
avatarService ! Service.Leave()
|
avatarService ! Service.Leave()
|
||||||
|
|
@ -82,12 +82,49 @@ class WorldSessionActor extends Actor with MDCContextAware {
|
||||||
LivePlayerList.Remove(sessionId)
|
LivePlayerList.Remove(sessionId)
|
||||||
if(player != null && player.HasGUID) {
|
if(player != null && player.HasGUID) {
|
||||||
val player_guid = player.GUID
|
val player_guid = player.GUID
|
||||||
player.VehicleSeated match {
|
if(player.isAlive) {
|
||||||
case Some(vehicle_guid) =>
|
//actually being alive or manually deconstructing
|
||||||
//TODO do this at some other time
|
player.VehicleSeated match {
|
||||||
vehicleService ! VehicleServiceMessage(continent.Id, VehicleAction.KickPassenger(player_guid, 0, true, vehicle_guid))
|
case Some(vehicle_guid) =>
|
||||||
case None => ;
|
DismountVehicleOnLogOut(vehicle_guid, player_guid)
|
||||||
|
case None => ;
|
||||||
|
}
|
||||||
|
|
||||||
|
continent.Population ! Zone.Population.Release(avatar)
|
||||||
|
player.Position = Vector3.Zero //save character before doing this
|
||||||
|
avatarService ! AvatarServiceMessage(player.Continent, AvatarAction.ObjectDelete(player_guid, player_guid))
|
||||||
|
taskResolver ! GUIDTask.UnregisterAvatar(player)(continent.GUID)
|
||||||
|
//TODO normally, the actual player avatar persists a minute or so after the user disconnects
|
||||||
}
|
}
|
||||||
|
else if(continent.LivePlayers.contains(player) && !continent.Corpses.contains(player)) {
|
||||||
|
//player disconnected while waiting for a revive
|
||||||
|
//similar to handling ReleaseAvatarRequestMessage
|
||||||
|
player.Release
|
||||||
|
continent.Population ! Zone.Population.Release(avatar)
|
||||||
|
player.VehicleSeated match {
|
||||||
|
case None =>
|
||||||
|
continent.Population ! Zone.Corpse.Add(player)
|
||||||
|
FriskCorpse(player) //TODO eliminate dead letters
|
||||||
|
if(!WellLootedCorpse(player)) {
|
||||||
|
avatarService ! AvatarServiceMessage(continent.Id, AvatarAction.Release(player, continent))
|
||||||
|
taskResolver ! GUIDTask.UnregisterLocker(player.Locker)(continent.GUID) //rest of player will be cleaned up with corpses
|
||||||
|
}
|
||||||
|
else { //no items in inventory; leave no corpse
|
||||||
|
val player_guid = player.GUID
|
||||||
|
player.Position = Vector3.Zero //save character before doing this
|
||||||
|
avatarService ! AvatarServiceMessage(continent.Id, AvatarAction.ObjectDelete(player_guid, player_guid, 0))
|
||||||
|
taskResolver ! GUIDTask.UnregisterAvatar(player)(continent.GUID)
|
||||||
|
}
|
||||||
|
|
||||||
|
case Some(vehicle_guid) =>
|
||||||
|
val player_guid = player.GUID
|
||||||
|
player.Position = Vector3.Zero //save character before doing this
|
||||||
|
avatarService ! AvatarServiceMessage(continent.Id, AvatarAction.ObjectDelete(player_guid, player_guid, 0))
|
||||||
|
taskResolver ! GUIDTask.UnregisterAvatar(player)(continent.GUID)
|
||||||
|
DismountVehicleOnLogOut(vehicle_guid, player_guid)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
player.VehicleOwned match {
|
player.VehicleOwned match {
|
||||||
case Some(vehicle_guid) =>
|
case Some(vehicle_guid) =>
|
||||||
continent.GUID(vehicle_guid) match {
|
continent.GUID(vehicle_guid) match {
|
||||||
|
|
@ -100,15 +137,25 @@ class WorldSessionActor extends Actor with MDCContextAware {
|
||||||
}
|
}
|
||||||
case None => ;
|
case None => ;
|
||||||
}
|
}
|
||||||
continent.Population ! Zone.Population.Release(avatar)
|
|
||||||
continent.Population ! Zone.Population.Leave(avatar)
|
continent.Population ! Zone.Population.Leave(avatar)
|
||||||
player.Position = Vector3.Zero //save character before doing this
|
|
||||||
avatarService ! AvatarServiceMessage(player.Continent, AvatarAction.ObjectDelete(player_guid, player_guid))
|
|
||||||
taskResolver ! GUIDTask.UnregisterAvatar(player)(continent.GUID)
|
|
||||||
//TODO normally, the actual player avatar persists a minute or so after the user disconnects
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Vehicle cleanup that is specific to log out behavior.
|
||||||
|
* @param vehicle_guid the vehicle being occupied
|
||||||
|
* @param player_guid the player
|
||||||
|
*/
|
||||||
|
def DismountVehicleOnLogOut(vehicle_guid : PlanetSideGUID, player_guid : PlanetSideGUID) : Unit = {
|
||||||
|
val vehicle = continent.GUID(vehicle_guid).get.asInstanceOf[Vehicle]
|
||||||
|
vehicle.Seat(vehicle.PassengerInSeat(player).get).get.Occupant = None
|
||||||
|
if(vehicle.Seats.values.count(_.isOccupied) == 0) {
|
||||||
|
vehicleService ! VehicleServiceMessage.DelayedVehicleDeconstruction(vehicle, continent, 600L) //start vehicle decay (10m)
|
||||||
|
}
|
||||||
|
vehicleService ! Service.Leave(Some(s"${vehicle.Actor}"))
|
||||||
|
vehicleService ! VehicleServiceMessage(continent.Id, VehicleAction.KickPassenger(player_guid, 0, true, vehicle_guid))
|
||||||
|
}
|
||||||
|
|
||||||
def receive = Initializing
|
def receive = Initializing
|
||||||
|
|
||||||
def Initializing : Receive = {
|
def Initializing : Receive = {
|
||||||
|
|
@ -554,7 +601,7 @@ class WorldSessionActor extends Actor with MDCContextAware {
|
||||||
else {
|
else {
|
||||||
vehicleService ! VehicleServiceMessage(continent.Id, VehicleAction.KickPassenger(player_guid, seat_num, true, obj.GUID))
|
vehicleService ! VehicleServiceMessage(continent.Id, VehicleAction.KickPassenger(player_guid, seat_num, true, obj.GUID))
|
||||||
}
|
}
|
||||||
if(obj.Seats.values.count(seat => seat.isOccupied) == 0) {
|
if(obj.Seats.values.count(_.isOccupied) == 0) {
|
||||||
vehicleService ! VehicleServiceMessage.DelayedVehicleDeconstruction(obj, continent, 600L) //start vehicle decay (10m)
|
vehicleService ! VehicleServiceMessage.DelayedVehicleDeconstruction(obj, continent, 600L) //start vehicle decay (10m)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1008,6 +1055,12 @@ class WorldSessionActor extends Actor with MDCContextAware {
|
||||||
log.info(s"$tplayer has left zone ${zone.Id}")
|
log.info(s"$tplayer has left zone ${zone.Id}")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case Zone.Population.PlayerCanNotSpawn(zone, tplayer) =>
|
||||||
|
log.warn(s"$tplayer can not spawn in zone ${zone.Id}; why?")
|
||||||
|
|
||||||
|
case Zone.Population.PlayerAlreadySpawned(zone, tplayer) =>
|
||||||
|
log.warn(s"$tplayer is already spawned on zone ${zone.Id}; a clerical error?")
|
||||||
|
|
||||||
case Zone.Lattice.SpawnPoint(zone_id, building, spawn_tube) =>
|
case Zone.Lattice.SpawnPoint(zone_id, building, spawn_tube) =>
|
||||||
log.info(s"Zone.Lattice.SpawnPoint: spawn point on $zone_id in ${building.Id} @ ${spawn_tube.GUID.guid} selected")
|
log.info(s"Zone.Lattice.SpawnPoint: spawn point on $zone_id in ${building.Id} @ ${spawn_tube.GUID.guid} selected")
|
||||||
reviveTimer.cancel
|
reviveTimer.cancel
|
||||||
|
|
@ -1015,7 +1068,7 @@ class WorldSessionActor extends Actor with MDCContextAware {
|
||||||
val backpack = player.isBackpack
|
val backpack = player.isBackpack
|
||||||
val respawnTime : Long = if(sameZone) { 10 } else { 0 } //s
|
val respawnTime : Long = if(sameZone) { 10 } else { 0 } //s
|
||||||
val respawnTimeMillis = respawnTime * 1000 //ms
|
val respawnTimeMillis = respawnTime * 1000 //ms
|
||||||
sendResponse(AvatarDeadStateMessage(DeadState.RespawnTime, respawnTimeMillis, respawnTimeMillis, Vector3.Zero, 2, true))
|
sendResponse(AvatarDeadStateMessage(DeadState.RespawnTime, respawnTimeMillis, respawnTimeMillis, Vector3.Zero, player.Faction, true))
|
||||||
val tplayer = if(backpack) {
|
val tplayer = if(backpack) {
|
||||||
RespawnClone(player) //new player
|
RespawnClone(player) //new player
|
||||||
}
|
}
|
||||||
|
|
@ -1122,7 +1175,7 @@ class WorldSessionActor extends Actor with MDCContextAware {
|
||||||
sendResponse(ChangeShortcutBankMessage(guid, 0))
|
sendResponse(ChangeShortcutBankMessage(guid, 0))
|
||||||
//FavoritesMessage
|
//FavoritesMessage
|
||||||
sendResponse(SetChatFilterMessage(ChatChannel.Local, false, ChatChannel.values.toList)) //TODO will not always be "on" like this
|
sendResponse(SetChatFilterMessage(ChatChannel.Local, false, ChatChannel.values.toList)) //TODO will not always be "on" like this
|
||||||
sendResponse(AvatarDeadStateMessage(DeadState.Nothing, 0,0, tplayer.Position, 0, true))
|
sendResponse(AvatarDeadStateMessage(DeadState.Alive, 0,0, tplayer.Position, player.Faction, true))
|
||||||
sendResponse(PlanetsideAttributeMessage(guid, 53, 1))
|
sendResponse(PlanetsideAttributeMessage(guid, 53, 1))
|
||||||
sendResponse(AvatarSearchCriteriaMessage(guid, List(0,0,0,0,0,0)))
|
sendResponse(AvatarSearchCriteriaMessage(guid, List(0,0,0,0,0,0)))
|
||||||
(1 to 73).foreach(i => {
|
(1 to 73).foreach(i => {
|
||||||
|
|
@ -1500,7 +1553,7 @@ class WorldSessionActor extends Actor with MDCContextAware {
|
||||||
log.info(s"ReleaseAvatarRequest: ${player.GUID} on ${continent.Id} has released")
|
log.info(s"ReleaseAvatarRequest: ${player.GUID} on ${continent.Id} has released")
|
||||||
reviveTimer.cancel
|
reviveTimer.cancel
|
||||||
player.Release
|
player.Release
|
||||||
sendResponse(AvatarDeadStateMessage(DeadState.Release, 0, 0, player.Position, 2, true))
|
sendResponse(AvatarDeadStateMessage(DeadState.Release, 0, 0, player.Position, player.Faction, true))
|
||||||
continent.Population ! Zone.Population.Release(avatar)
|
continent.Population ! Zone.Population.Release(avatar)
|
||||||
player.VehicleSeated match {
|
player.VehicleSeated match {
|
||||||
case None =>
|
case None =>
|
||||||
|
|
@ -2153,7 +2206,7 @@ class WorldSessionActor extends Actor with MDCContextAware {
|
||||||
//deconstruction
|
//deconstruction
|
||||||
PlayerActionsToCancel()
|
PlayerActionsToCancel()
|
||||||
player.Release
|
player.Release
|
||||||
sendResponse(AvatarDeadStateMessage(DeadState.Release, 0, 0, player.Position, 2, true))
|
sendResponse(AvatarDeadStateMessage(DeadState.Release, 0, 0, player.Position, player.Faction, true))
|
||||||
continent.Population ! Zone.Population.Release(avatar)
|
continent.Population ! Zone.Population.Release(avatar)
|
||||||
|
|
||||||
case Some(obj : PlanetSideGameObject) =>
|
case Some(obj : PlanetSideGameObject) =>
|
||||||
|
|
@ -3418,7 +3471,7 @@ class WorldSessionActor extends Actor with MDCContextAware {
|
||||||
sendResponse(PlanetsideAttributeMessage(player_guid, 2, 0))
|
sendResponse(PlanetsideAttributeMessage(player_guid, 2, 0))
|
||||||
avatarService ! AvatarServiceMessage(continent.Id, AvatarAction.PlanetsideAttribute(player_guid, 0, 0))
|
avatarService ! AvatarServiceMessage(continent.Id, AvatarAction.PlanetsideAttribute(player_guid, 0, 0))
|
||||||
sendResponse(DestroyMessage(player_guid, player_guid, PlanetSideGUID(0), pos)) //how many players get this message?
|
sendResponse(DestroyMessage(player_guid, player_guid, PlanetSideGUID(0), pos)) //how many players get this message?
|
||||||
sendResponse(AvatarDeadStateMessage(DeadState.Dead, respawnTimer, respawnTimer, pos, 2, true))
|
sendResponse(AvatarDeadStateMessage(DeadState.Dead, respawnTimer, respawnTimer, pos, player.Faction, true))
|
||||||
if(tplayer.VehicleSeated.nonEmpty) {
|
if(tplayer.VehicleSeated.nonEmpty) {
|
||||||
//make player invisible (if not, the cadaver sticks out the side in a seated position)
|
//make player invisible (if not, the cadaver sticks out the side in a seated position)
|
||||||
sendResponse(PlanetsideAttributeMessage(player_guid, 29, 1))
|
sendResponse(PlanetsideAttributeMessage(player_guid, 29, 1))
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue