mirror of
https://github.com/2revoemag/PSF-BotServer.git
synced 2026-03-04 04:30:21 +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.
|
||||
* @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.
|
||||
* @param zone the `Zone` object
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ class ZonePopulationActor(zone : Zone, playerMap : TrieMap[Avatar, Option[Player
|
|||
PopulationSpawn(avatar, player, playerMap) match {
|
||||
case Some(tplayer) =>
|
||||
if(tplayer ne player) {
|
||||
sender ! Zone.Population.PlayerAlreadySpawned(player)
|
||||
sender ! Zone.Population.PlayerAlreadySpawned(zone, player)
|
||||
}
|
||||
case None =>
|
||||
sender ! Zone.Population.PlayerCanNotSpawn(zone, player)
|
||||
|
|
|
|||
|
|
@ -2,15 +2,19 @@
|
|||
package net.psforever.packet.game
|
||||
|
||||
import net.psforever.packet.{GamePacketOpcode, Marshallable, PacketHelpers, PlanetSideGamePacket}
|
||||
import net.psforever.types.Vector3
|
||||
import scodec.Codec
|
||||
import net.psforever.types.{PlanetSideEmpire, Vector3}
|
||||
import scodec.Attempt.{Failure, Successful}
|
||||
import scodec.{Codec, Err}
|
||||
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 {
|
||||
type Type = Value
|
||||
|
||||
val
|
||||
Nothing,
|
||||
Alive,
|
||||
Dead,
|
||||
Release,
|
||||
RespawnTime
|
||||
|
|
@ -20,19 +24,41 @@ object DeadState extends Enumeration {
|
|||
}
|
||||
|
||||
/**
|
||||
* na
|
||||
* @param state avatar's relationship with the world
|
||||
* Dispatched by the server to manipulate the client's management of the `Player` object owned by the user as his "avatar."<br>
|
||||
* <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 initial length of the respawn timer, in milliseconds
|
||||
* @param pos last position
|
||||
* @param unk4 na
|
||||
* @param pos player's last position
|
||||
* @param faction spawn points available for this faction on redeployment map
|
||||
* @param unk5 na
|
||||
*/
|
||||
final case class AvatarDeadStateMessage(state : DeadState.Value,
|
||||
timer_max : Long,
|
||||
timer : Long,
|
||||
pos : Vector3,
|
||||
unk4 : Long,
|
||||
faction : PlanetSideEmpire.Value,
|
||||
unk5 : Boolean)
|
||||
extends PlanetSideGamePacket {
|
||||
type Packet = AvatarDeadStateMessage
|
||||
|
|
@ -41,12 +67,32 @@ final case class AvatarDeadStateMessage(state : DeadState.Value,
|
|||
}
|
||||
|
||||
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] = (
|
||||
("state" | DeadState.codec) ::
|
||||
("timer_max" | uint32L) ::
|
||||
("timer" | uint32L) ::
|
||||
("pos" | Vector3.codec_pos) ::
|
||||
("unk4" | uint32L) ::
|
||||
("unk4" | factionLongCodec) ::
|
||||
("unk5" | bool)
|
||||
).as[AvatarDeadStateMessage]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,11 +4,12 @@ package game
|
|||
import org.specs2.mutable._
|
||||
import net.psforever.packet._
|
||||
import net.psforever.packet.game._
|
||||
import net.psforever.types.Vector3
|
||||
import net.psforever.types.{PlanetSideEmpire, Vector3}
|
||||
import scodec.bits._
|
||||
|
||||
class AvatarDeadStateMessageTest extends Specification {
|
||||
val string = hex"ad3c1260801c12608009f99861fb0741e040000010"
|
||||
val string_invalid = hex"ad3c1260801c12608009f99861fb0741e0400000F0"
|
||||
|
||||
"decode" in {
|
||||
PacketCoding.DecodePacket(string).require match {
|
||||
|
|
@ -17,15 +18,19 @@ class AvatarDeadStateMessageTest extends Specification {
|
|||
unk2 mustEqual 300000
|
||||
unk3 mustEqual 300000
|
||||
pos mustEqual Vector3(6552.617f,4602.375f,60.90625f)
|
||||
unk4 mustEqual 2
|
||||
unk4 mustEqual PlanetSideEmpire.VS
|
||||
unk5 mustEqual true
|
||||
case _ =>
|
||||
ko
|
||||
}
|
||||
}
|
||||
|
||||
"decode (failure)" in {
|
||||
PacketCoding.DecodePacket(string_invalid).isFailure mustEqual true
|
||||
}
|
||||
|
||||
"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
|
||||
|
||||
pkt mustEqual string
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue