mirror of
https://github.com/2revoemag/PSF-BotServer.git
synced 2026-07-15 00:14:40 +00:00
commit
41a381a212
3 changed files with 165 additions and 1 deletions
|
|
@ -461,7 +461,7 @@ object GamePacketOpcode extends Enumeration {
|
||||||
case 0x76 => game.DeployableObjectsInfoMessage.decode
|
case 0x76 => game.DeployableObjectsInfoMessage.decode
|
||||||
case 0x77 => noDecoder(SquadState)
|
case 0x77 => noDecoder(SquadState)
|
||||||
// 0x78
|
// 0x78
|
||||||
case 0x78 => noDecoder(OxygenStateMessage)
|
case 0x78 => game.OxygenStateMessage.decode
|
||||||
case 0x79 => noDecoder(TradeMessage)
|
case 0x79 => noDecoder(TradeMessage)
|
||||||
case 0x7a => noDecoder(UnknownMessage122)
|
case 0x7a => noDecoder(UnknownMessage122)
|
||||||
case 0x7b => noDecoder(DamageFeedbackMessage)
|
case 0x7b => noDecoder(DamageFeedbackMessage)
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,111 @@
|
||||||
|
// Copyright (c) 2017 PSForever
|
||||||
|
package net.psforever.packet.game
|
||||||
|
|
||||||
|
import net.psforever.newcodecs.newcodecs
|
||||||
|
import net.psforever.packet.{GamePacketOpcode, Marshallable, PlanetSideGamePacket}
|
||||||
|
import scodec.{Attempt, Codec}
|
||||||
|
import scodec.codecs._
|
||||||
|
import shapeless.{::, HNil}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Alert the condition of a vehicle the player is using when going too far underwater.
|
||||||
|
* The player must be mounted in/on this vehicle at start time for this countdown to display.
|
||||||
|
* @param vehicle_guid the player's mounted vehicle
|
||||||
|
* @param progress the remaining countdown;
|
||||||
|
* for vehicle waterlog condition, the progress per second rate is very high
|
||||||
|
* @param active show a new countdown if `true` (resets any active countdown);
|
||||||
|
* clear any active countdowns if `false`;
|
||||||
|
* defaults to `true`
|
||||||
|
*/
|
||||||
|
final case class WaterloggedVehicleState(vehicle_guid : PlanetSideGUID,
|
||||||
|
progress : Float,
|
||||||
|
active : Boolean = true)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dispatched by the server to cause the player to slowly drown.
|
||||||
|
* If the player is mounted in a vehicle at the time, alert the player that the vehicle may be disabled.<br>
|
||||||
|
* <br>
|
||||||
|
* When a player walks too far underwater, a borderless red progress bar with a countdown from 100 (98) is displayed across the screen.
|
||||||
|
* The countdown proceeds to zero at a fixed rate and is timed with the depleting progress bar.
|
||||||
|
* When it reaches zero, the player will be killed.
|
||||||
|
* If the player is in a vehicle after a certain depth, a blue bar and countdown pair will superimpose the red indicators.
|
||||||
|
* It depletes much more rapidly than the red indicators.
|
||||||
|
* When it reaches zero, the vehicle will become disabled.
|
||||||
|
* All players in the vehicle's seats will be kicked and they will not be allowed back in.<br>
|
||||||
|
* <br>
|
||||||
|
* Normally, the countdowns should be set to begin at 100 (100.0).
|
||||||
|
* This is the earliest the drowning GUI will appear for either blue or red indicators.
|
||||||
|
* Passing greater intervals - up to 204.8 - will start the countdown silently but the GUI will be hidden until 100.0.
|
||||||
|
* (The progress indicators will actually appear to start counting from 98.)
|
||||||
|
* Managing the secondary vehicle countdown independent of the primary player countdown requires updating with the correct levels.
|
||||||
|
* The countdown can be cancelled by instructing it to be `active = false`.<br>
|
||||||
|
* <br>
|
||||||
|
* Except for updating the indicators, all other functionality of "drowning" is automated by the server.
|
||||||
|
* @param player_guid the player
|
||||||
|
* @param progress the remaining countdown;
|
||||||
|
* for character oxygen, the progress per second rate is about 1
|
||||||
|
* @param active show a new countdown if `true` (resets any active countdown);
|
||||||
|
* clear any active countdowns if `false`
|
||||||
|
* @param vehicle_state optional state of the vehicle the player is driving
|
||||||
|
*/
|
||||||
|
final case class OxygenStateMessage(player_guid : PlanetSideGUID,
|
||||||
|
progress : Float,
|
||||||
|
active : Boolean,
|
||||||
|
vehicle_state : Option[WaterloggedVehicleState] = None)
|
||||||
|
extends PlanetSideGamePacket {
|
||||||
|
type Packet = OxygenStateMessage
|
||||||
|
def opcode = GamePacketOpcode.OxygenStateMessage
|
||||||
|
def encode = OxygenStateMessage.encode(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
object OxygenStateMessage extends Marshallable[OxygenStateMessage] {
|
||||||
|
/**
|
||||||
|
* Overloaded constructor that removes the optional state of the `WaterloggedVehicleState` parameter.
|
||||||
|
* @param player_guid the player
|
||||||
|
* @param progress the remaining countdown
|
||||||
|
* @param active show or clear the countdown
|
||||||
|
* @param vehicle_state state of the vehicle the player is driving
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
def apply(player_guid : PlanetSideGUID, progress : Float, active : Boolean, vehicle_state : WaterloggedVehicleState) : OxygenStateMessage =
|
||||||
|
OxygenStateMessage(player_guid, progress, active, Some(vehicle_state))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A simple pattern that expands the datatypes of the packet's basic `Codec`.
|
||||||
|
*/
|
||||||
|
private type basePattern = PlanetSideGUID :: Float :: Boolean :: HNil
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A `Codec` for the repeated processing of three values.
|
||||||
|
* This `Codec` is the basis for the packet's data.
|
||||||
|
*/
|
||||||
|
private val base_codec : Codec[basePattern] =
|
||||||
|
PlanetSideGUID.codec ::
|
||||||
|
newcodecs.q_float(0.0f, 204.8f, 11) :: //hackish: 2^11 == 2047, so it should be 204.7; but, 204.8 allows decode == encode
|
||||||
|
bool
|
||||||
|
|
||||||
|
implicit val codec : Codec[OxygenStateMessage] = (
|
||||||
|
base_codec.exmap[basePattern] (
|
||||||
|
{
|
||||||
|
case guid :: time :: active :: HNil =>
|
||||||
|
Attempt.successful(guid :: time :: active :: HNil)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
case guid :: time :: active :: HNil =>
|
||||||
|
Attempt.successful(guid :: time :: active :: HNil)
|
||||||
|
}
|
||||||
|
) :+
|
||||||
|
optional(bool,
|
||||||
|
"vehicle_state" | base_codec.exmap[WaterloggedVehicleState] (
|
||||||
|
{
|
||||||
|
case guid :: time :: active :: HNil =>
|
||||||
|
Attempt.successful(WaterloggedVehicleState(guid, time, active))
|
||||||
|
},
|
||||||
|
{
|
||||||
|
case WaterloggedVehicleState(guid, time, active) =>
|
||||||
|
Attempt.successful(guid :: time :: active :: HNil)
|
||||||
|
}
|
||||||
|
).as[WaterloggedVehicleState]
|
||||||
|
)
|
||||||
|
).as[OxygenStateMessage]
|
||||||
|
}
|
||||||
53
common/src/test/scala/game/OxygenStateMessageTest.scala
Normal file
53
common/src/test/scala/game/OxygenStateMessageTest.scala
Normal file
|
|
@ -0,0 +1,53 @@
|
||||||
|
// Copyright (c) 2017 PSForever
|
||||||
|
package game
|
||||||
|
|
||||||
|
import org.specs2.mutable._
|
||||||
|
import net.psforever.packet._
|
||||||
|
import net.psforever.packet.game._
|
||||||
|
import scodec.bits._
|
||||||
|
|
||||||
|
class OxygenStateMessageTest extends Specification {
|
||||||
|
val string_self = hex"78 4b00f430"
|
||||||
|
val string_vehicle = hex"78 4b00f4385037a180"
|
||||||
|
|
||||||
|
"decode (self)" in {
|
||||||
|
PacketCoding.DecodePacket(string_self).require match {
|
||||||
|
case OxygenStateMessage(guid, progress, active, veh_state) =>
|
||||||
|
guid mustEqual PlanetSideGUID(75)
|
||||||
|
progress mustEqual 50.0
|
||||||
|
active mustEqual true
|
||||||
|
veh_state.isDefined mustEqual false
|
||||||
|
case _ =>
|
||||||
|
ko
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
"decode (vehicle)" in {
|
||||||
|
PacketCoding.DecodePacket(string_vehicle).require match {
|
||||||
|
case OxygenStateMessage(guid, progress, active, veh_state) =>
|
||||||
|
guid mustEqual PlanetSideGUID(75)
|
||||||
|
progress mustEqual 50.0f
|
||||||
|
active mustEqual true
|
||||||
|
veh_state.isDefined mustEqual true
|
||||||
|
veh_state.get.vehicle_guid mustEqual PlanetSideGUID(1546)
|
||||||
|
veh_state.get.progress mustEqual 50.0f
|
||||||
|
veh_state.get.active mustEqual true
|
||||||
|
case _ =>
|
||||||
|
ko
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
"encode (self)" in {
|
||||||
|
val msg = OxygenStateMessage(PlanetSideGUID(75), 50.0f, true)
|
||||||
|
val pkt = PacketCoding.EncodePacket(msg).require.toByteVector
|
||||||
|
|
||||||
|
pkt mustEqual string_self
|
||||||
|
}
|
||||||
|
|
||||||
|
"encode (vehicle)" in {
|
||||||
|
val msg = OxygenStateMessage(PlanetSideGUID(75), 50.0f, true, WaterloggedVehicleState(PlanetSideGUID(1546), 50.0f, true))
|
||||||
|
val pkt = PacketCoding.EncodePacket(msg).require.toByteVector
|
||||||
|
|
||||||
|
pkt mustEqual string_vehicle
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue