mirror of
https://github.com/2revoemag/PSF-BotServer.git
synced 2026-07-13 15:34:42 +00:00
added initial AvatarStatisticsMessage packet and tests; gave an Enumeration type to AvtarImplant action field
This commit is contained in:
parent
2475b468b8
commit
d965b5b3c8
8 changed files with 254 additions and 44 deletions
|
|
@ -16,7 +16,7 @@ import net.psforever.packet.game.objectcreate.ObjectClass
|
||||||
*/
|
*/
|
||||||
class ImplantTerminalInterfaceDefinition extends TerminalDefinition(ObjectClass.implant_terminal_interface) {
|
class ImplantTerminalInterfaceDefinition extends TerminalDefinition(ObjectClass.implant_terminal_interface) {
|
||||||
Packet = new ImplantTerminalInterfaceConverter
|
Packet = new ImplantTerminalInterfaceConverter
|
||||||
Name = "implante_terminal_interface"
|
Name = "implant_terminal_interface"
|
||||||
|
|
||||||
private val implants : Map[String, ImplantDefinition] = Map (
|
private val implants : Map[String, ImplantDefinition] = Map (
|
||||||
"advanced_regen" -> GlobalDefinitions.advanced_regen,
|
"advanced_regen" -> GlobalDefinitions.advanced_regen,
|
||||||
|
|
|
||||||
|
|
@ -468,7 +468,7 @@ object GamePacketOpcode extends Enumeration {
|
||||||
case 0x7c => game.DismountBuildingMsg.decode
|
case 0x7c => game.DismountBuildingMsg.decode
|
||||||
case 0x7d => noDecoder(UnknownMessage125)
|
case 0x7d => noDecoder(UnknownMessage125)
|
||||||
case 0x7e => noDecoder(UnknownMessage126)
|
case 0x7e => noDecoder(UnknownMessage126)
|
||||||
case 0x7f => noDecoder(AvatarStatisticsMessage)
|
case 0x7f => game.AvatarStatisticsMessage.decode
|
||||||
|
|
||||||
// OPCODES 0x80-8f
|
// OPCODES 0x80-8f
|
||||||
case 0x80 => noDecoder(GenericObjectAction2Message)
|
case 0x80 => noDecoder(GenericObjectAction2Message)
|
||||||
|
|
|
||||||
|
|
@ -1,40 +1,48 @@
|
||||||
// Copyright (c) 2017 PSForever
|
// Copyright (c) 2017 PSForever
|
||||||
package net.psforever.packet.game
|
package net.psforever.packet.game
|
||||||
|
|
||||||
import net.psforever.packet.{GamePacketOpcode, Marshallable, PlanetSideGamePacket}
|
import net.psforever.packet.{GamePacketOpcode, Marshallable, PacketHelpers, PlanetSideGamePacket}
|
||||||
import net.psforever.types.ImplantType
|
|
||||||
import scodec.Codec
|
import scodec.Codec
|
||||||
import scodec.codecs._
|
import scodec.codecs._
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Change the state of the implant.<br>
|
* An `Enumeration` for all the actions that can be applied to implants and implant slots.
|
||||||
|
*/
|
||||||
|
object ImplantAction extends Enumeration {
|
||||||
|
type Type = Value
|
||||||
|
|
||||||
|
val
|
||||||
|
Add,
|
||||||
|
Remove,
|
||||||
|
Initialization,
|
||||||
|
Activation,
|
||||||
|
UnlockMessage,
|
||||||
|
OutOfStamina
|
||||||
|
= Value
|
||||||
|
|
||||||
|
implicit val codec = PacketHelpers.createEnumerationCodec(this, uintL(3))
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Change the state of the implant.
|
||||||
|
* Spawn messages for certain implant-related events.<br>
|
||||||
* <br>
|
* <br>
|
||||||
* The implant Second Wind is technically an invalid `ImplantType` for this packet.
|
* The implant Second Wind is technically an invalid `ImplantType` for this packet.
|
||||||
* This owes to the unique activation trigger for that implant - a near-death experience of ~0HP.
|
* This owes to the unique activation trigger for that implant - a near-death experience of ~0HP.
|
||||||
|
* @see `ImplantType`
|
||||||
* @param player_guid the player
|
* @param player_guid the player
|
||||||
* @param action
|
* @param action how to affect the implant or the slot
|
||||||
* 0 : add implant
|
|
||||||
* with status = 0 to 9 (from ImplantType)
|
|
||||||
* 1 : remove implant
|
|
||||||
* seems work with any value in status
|
|
||||||
* 2 : init implant
|
|
||||||
* status : 0 to "uninit"
|
|
||||||
* status : 1 to init
|
|
||||||
* 3 : activate implant
|
|
||||||
* status : 0 to desactivate
|
|
||||||
* status : 1 to activate
|
|
||||||
* 4 : number of implant slots unlocked
|
|
||||||
* status : 0 = no implant slot
|
|
||||||
* status : 1 = first implant slot + "implant message"
|
|
||||||
* status : 2 or 3 = unlock second & third slots
|
|
||||||
* 5 : out of stamina message
|
|
||||||
* status : 0 to stop the lock
|
|
||||||
* status : 1 to active the lock
|
|
||||||
* @param implantSlot : from 0 to 2
|
* @param implantSlot : from 0 to 2
|
||||||
* @param status : see action
|
* @param status : a value that depends on context from `ImplantAction`:<br>
|
||||||
|
* `Add` - 0-9 depending on the `ImplantType`<br>
|
||||||
|
* `Remove` - any valid value; field is not significant to this action<br>
|
||||||
|
* `Initialization` - 0 to revoke slot; 1 to allocate implant slot<br>
|
||||||
|
* `Activation` - 0 to deactivate implant; 1 to activate implant<br>
|
||||||
|
* `UnlockMessage` - 0-3 as an unlocked implant slot; display a message<br>
|
||||||
|
* `OutOfStamina` - lock implant; 0 to lock; 1 to unlock; display a message
|
||||||
*/
|
*/
|
||||||
final case class AvatarImplantMessage(player_guid : PlanetSideGUID,
|
final case class AvatarImplantMessage(player_guid : PlanetSideGUID,
|
||||||
action : Int,
|
action : ImplantAction.Value,
|
||||||
implantSlot : Int,
|
implantSlot : Int,
|
||||||
status : Int)
|
status : Int)
|
||||||
extends PlanetSideGamePacket {
|
extends PlanetSideGamePacket {
|
||||||
|
|
@ -46,7 +54,7 @@ final case class AvatarImplantMessage(player_guid : PlanetSideGUID,
|
||||||
object AvatarImplantMessage extends Marshallable[AvatarImplantMessage] {
|
object AvatarImplantMessage extends Marshallable[AvatarImplantMessage] {
|
||||||
implicit val codec : Codec[AvatarImplantMessage] = (
|
implicit val codec : Codec[AvatarImplantMessage] = (
|
||||||
("player_guid" | PlanetSideGUID.codec) ::
|
("player_guid" | PlanetSideGUID.codec) ::
|
||||||
("action" | uintL(3)) ::
|
("action" | ImplantAction.codec) ::
|
||||||
("implantSlot" | uint2L) ::
|
("implantSlot" | uint2L) ::
|
||||||
("status" | uint4L)
|
("status" | uint4L)
|
||||||
).as[AvatarImplantMessage]
|
).as[AvatarImplantMessage]
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,105 @@
|
||||||
|
// Copyright (c) 2017 PSForever
|
||||||
|
package net.psforever.packet.game
|
||||||
|
|
||||||
|
import net.psforever.packet.{GamePacketOpcode, Marshallable, PacketHelpers, PlanetSideGamePacket}
|
||||||
|
import scodec.{Attempt, Codec, Err}
|
||||||
|
import scodec.codecs._
|
||||||
|
import shapeless.{::, HNil}
|
||||||
|
|
||||||
|
import scala.annotation.switch
|
||||||
|
|
||||||
|
/**
|
||||||
|
* na
|
||||||
|
* @param unk1 na
|
||||||
|
* @param unk2 na
|
||||||
|
* @param unk3 na
|
||||||
|
*/
|
||||||
|
final case class Statistics(unk1 : Option[Int],
|
||||||
|
unk2 : Option[Int],
|
||||||
|
unk3 : List[Long])
|
||||||
|
|
||||||
|
/**
|
||||||
|
* na
|
||||||
|
* @param unk na
|
||||||
|
* @param stats na
|
||||||
|
*/
|
||||||
|
final case class AvatarStatisticsMessage(unk : Int,
|
||||||
|
stats : Statistics)
|
||||||
|
extends PlanetSideGamePacket {
|
||||||
|
type Packet = AvatarStatisticsMessage
|
||||||
|
def opcode = GamePacketOpcode.AvatarStatisticsMessage
|
||||||
|
def encode = AvatarStatisticsMessage.encode(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
object AvatarStatisticsMessage extends Marshallable[AvatarStatisticsMessage] {
|
||||||
|
/**
|
||||||
|
* na
|
||||||
|
*/
|
||||||
|
private val longCodec : Codec[Statistics] = ulong(32).hlist.exmap (
|
||||||
|
{
|
||||||
|
case n :: HNil =>
|
||||||
|
Attempt.Successful(Statistics(None,None, List(n)))
|
||||||
|
},
|
||||||
|
{
|
||||||
|
case Statistics(_, _, Nil) =>
|
||||||
|
Attempt.Failure(Err("missing value (32-bit)"))
|
||||||
|
|
||||||
|
case Statistics(_, _, n) =>
|
||||||
|
Attempt.Successful(n.head :: HNil)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* na
|
||||||
|
*/
|
||||||
|
private val complexCodec : Codec[Statistics] = (
|
||||||
|
uint(5) ::
|
||||||
|
uintL(11) ::
|
||||||
|
PacketHelpers.listOfNSized(8, uint32L)
|
||||||
|
).exmap[Statistics] (
|
||||||
|
{
|
||||||
|
case a :: b :: c :: HNil =>
|
||||||
|
Attempt.Successful(Statistics(Some(a), Some(b), c))
|
||||||
|
},
|
||||||
|
{
|
||||||
|
case Statistics(None, _, _) =>
|
||||||
|
Attempt.Failure(Err("missing value (5-bit)"))
|
||||||
|
|
||||||
|
case Statistics(_, None, _) =>
|
||||||
|
Attempt.Failure(Err("missing value (11-bit)"))
|
||||||
|
|
||||||
|
case Statistics(a, b, c) =>
|
||||||
|
if(c.length != 8) {
|
||||||
|
Attempt.Failure(Err("list must have 8 entries"))
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Attempt.Successful(a.get :: b.get :: c :: HNil)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* na
|
||||||
|
* @param n na
|
||||||
|
* @return na
|
||||||
|
*/
|
||||||
|
private def selectCodec(n : Int) : Codec[Statistics] = (n : @switch) match {
|
||||||
|
case 2 | 3 =>
|
||||||
|
longCodec
|
||||||
|
case _ =>
|
||||||
|
complexCodec
|
||||||
|
}
|
||||||
|
|
||||||
|
implicit val codec : Codec[AvatarStatisticsMessage] = (
|
||||||
|
("unk" | uint(3)) >>:~ { unk =>
|
||||||
|
("stats" | selectCodec(unk)).hlist
|
||||||
|
}).as[AvatarStatisticsMessage]
|
||||||
|
}
|
||||||
|
|
||||||
|
object Statistics {
|
||||||
|
def apply(unk : Long) : Statistics =
|
||||||
|
Statistics(None, None, List(unk))
|
||||||
|
|
||||||
|
def apply(unk1 : Int, unk2 : Int, unk3 : List[Long]) : Statistics =
|
||||||
|
Statistics(Some(unk1), Some(unk2), unk3)
|
||||||
|
}
|
||||||
|
|
@ -4,7 +4,6 @@ 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.ImplantType
|
|
||||||
import scodec.bits._
|
import scodec.bits._
|
||||||
|
|
||||||
class AvatarImplantMessageTest extends Specification {
|
class AvatarImplantMessageTest extends Specification {
|
||||||
|
|
@ -14,7 +13,7 @@ class AvatarImplantMessageTest extends Specification {
|
||||||
PacketCoding.DecodePacket(string).require match {
|
PacketCoding.DecodePacket(string).require match {
|
||||||
case AvatarImplantMessage(player_guid, unk1, unk2, implant) =>
|
case AvatarImplantMessage(player_guid, unk1, unk2, implant) =>
|
||||||
player_guid mustEqual PlanetSideGUID(3171)
|
player_guid mustEqual PlanetSideGUID(3171)
|
||||||
unk1 mustEqual 3
|
unk1 mustEqual ImplantAction.Activation
|
||||||
unk2 mustEqual 1
|
unk2 mustEqual 1
|
||||||
implant mustEqual 1
|
implant mustEqual 1
|
||||||
case _ =>
|
case _ =>
|
||||||
|
|
@ -23,7 +22,7 @@ class AvatarImplantMessageTest extends Specification {
|
||||||
}
|
}
|
||||||
|
|
||||||
"encode" in {
|
"encode" in {
|
||||||
val msg = AvatarImplantMessage(PlanetSideGUID(3171), 3, 1, 1)
|
val msg = AvatarImplantMessage(PlanetSideGUID(3171), ImplantAction.Activation, 1, 1)
|
||||||
val pkt = PacketCoding.EncodePacket(msg).require.toByteVector
|
val pkt = PacketCoding.EncodePacket(msg).require.toByteVector
|
||||||
|
|
||||||
pkt mustEqual string
|
pkt mustEqual string
|
||||||
|
|
|
||||||
79
common/src/test/scala/game/AvatarStatisticsMessageTest.scala
Normal file
79
common/src/test/scala/game/AvatarStatisticsMessageTest.scala
Normal file
|
|
@ -0,0 +1,79 @@
|
||||||
|
// Copyright (c) 2017 PSForever
|
||||||
|
package game
|
||||||
|
|
||||||
|
import org.specs2.mutable._
|
||||||
|
import net.psforever.packet._
|
||||||
|
import net.psforever.packet.game._
|
||||||
|
import scodec.bits._
|
||||||
|
|
||||||
|
class AvatarStatisticsMessageTest extends Specification {
|
||||||
|
val string_long = hex"7F 4 00000000 0"
|
||||||
|
val string_complex = hex"7F 01 3C 40 20 00 00 00 C0 00 00 00 00 00 00 00 20 00 00 00 20 00 00 00 40 00 00 00 00 00 00 00 00 00 00 00"
|
||||||
|
|
||||||
|
"decode (long)" in {
|
||||||
|
PacketCoding.DecodePacket(string_long).require match {
|
||||||
|
case AvatarStatisticsMessage(unk, stats) =>
|
||||||
|
unk mustEqual 2
|
||||||
|
stats.unk1 mustEqual None
|
||||||
|
stats.unk2 mustEqual None
|
||||||
|
stats.unk3.length mustEqual 1
|
||||||
|
stats.unk3.head mustEqual 0
|
||||||
|
case _ =>
|
||||||
|
ko
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
"decode (complex)" in {
|
||||||
|
PacketCoding.DecodePacket(string_complex).require match {
|
||||||
|
case AvatarStatisticsMessage(unk, stats) =>
|
||||||
|
unk mustEqual 0
|
||||||
|
stats.unk1 mustEqual Some(1)
|
||||||
|
stats.unk2 mustEqual Some(572)
|
||||||
|
stats.unk3.length mustEqual 8
|
||||||
|
stats.unk3.head mustEqual 1
|
||||||
|
stats.unk3(1) mustEqual 6
|
||||||
|
stats.unk3(2) mustEqual 0
|
||||||
|
stats.unk3(3) mustEqual 1
|
||||||
|
stats.unk3(4) mustEqual 1
|
||||||
|
stats.unk3(5) mustEqual 2
|
||||||
|
stats.unk3(6) mustEqual 0
|
||||||
|
stats.unk3(7) mustEqual 0
|
||||||
|
case _ =>
|
||||||
|
ko
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
"encode (long)" in {
|
||||||
|
val msg = AvatarStatisticsMessage(2, Statistics(0L))
|
||||||
|
val pkt = PacketCoding.EncodePacket(msg).require.toByteVector
|
||||||
|
|
||||||
|
pkt mustEqual string_long
|
||||||
|
}
|
||||||
|
|
||||||
|
"encode (complex)" in {
|
||||||
|
val msg = AvatarStatisticsMessage(0, Statistics(1, 572, List[Long](1,6,0,1,1,2,0,0)))
|
||||||
|
val pkt = PacketCoding.EncodePacket(msg).require.toByteVector
|
||||||
|
|
||||||
|
pkt mustEqual string_complex
|
||||||
|
}
|
||||||
|
|
||||||
|
"encode (failure; long; missing value)" in {
|
||||||
|
val msg = AvatarStatisticsMessage(0, Statistics(None, None,List(0L)))
|
||||||
|
PacketCoding.EncodePacket(msg).isFailure mustEqual true
|
||||||
|
}
|
||||||
|
|
||||||
|
"encode (failure; complex; missing value (5-bit))" in {
|
||||||
|
val msg = AvatarStatisticsMessage(0, Statistics(None, Some(572), List[Long](1,6,0,1,1,2,0,0)))
|
||||||
|
PacketCoding.EncodePacket(msg).isFailure mustEqual true
|
||||||
|
}
|
||||||
|
|
||||||
|
"encode (failure; complex; missing value (11-bit))" in {
|
||||||
|
val msg = AvatarStatisticsMessage(0, Statistics(Some(1), None, List[Long](1,6,0,1,1,2,0,0)))
|
||||||
|
PacketCoding.EncodePacket(msg).isFailure mustEqual true
|
||||||
|
}
|
||||||
|
|
||||||
|
"encode (failure; complex; wrong number of list entries)" in {
|
||||||
|
val msg = AvatarStatisticsMessage(0, Statistics(Some(1), None, List[Long](1,6,0,1)))
|
||||||
|
PacketCoding.EncodePacket(msg).isFailure mustEqual true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -56,10 +56,11 @@ object Maps {
|
||||||
LocalObject(ServerObjectBuilder(373, Door.Constructor))
|
LocalObject(ServerObjectBuilder(373, Door.Constructor))
|
||||||
|
|
||||||
LocalObject(ServerObjectBuilder(520, ImplantTerminalMech.Constructor)) //Hart B
|
LocalObject(ServerObjectBuilder(520, ImplantTerminalMech.Constructor)) //Hart B
|
||||||
LocalObject(ServerObjectBuilder(1081, Terminal.Constructor(implant_terminal_interface))) //tube 520
|
|
||||||
LocalObject(ServerObjectBuilder(853, Terminal.Constructor(order_terminal)))
|
LocalObject(ServerObjectBuilder(853, Terminal.Constructor(order_terminal)))
|
||||||
LocalObject(ServerObjectBuilder(855, Terminal.Constructor(order_terminal)))
|
LocalObject(ServerObjectBuilder(855, Terminal.Constructor(order_terminal)))
|
||||||
LocalObject(ServerObjectBuilder(860, Terminal.Constructor(order_terminal)))
|
LocalObject(ServerObjectBuilder(860, Terminal.Constructor(order_terminal)))
|
||||||
|
LocalObject(ServerObjectBuilder(1081, Terminal.Constructor(implant_terminal_interface))) //tube 520
|
||||||
|
TerminalToInterface(520, 1081)
|
||||||
|
|
||||||
LocalBuilding(2, FoundationBuilder(Building.Structure)) //HART building C
|
LocalBuilding(2, FoundationBuilder(Building.Structure)) //HART building C
|
||||||
LocalObject(ServerObjectBuilder(186, Terminal.Constructor(cert_terminal)))
|
LocalObject(ServerObjectBuilder(186, Terminal.Constructor(cert_terminal)))
|
||||||
|
|
@ -128,7 +129,14 @@ object Maps {
|
||||||
ObjectToBuilding(843, 2)
|
ObjectToBuilding(843, 2)
|
||||||
ObjectToBuilding(844, 2)
|
ObjectToBuilding(844, 2)
|
||||||
ObjectToBuilding(845, 2)
|
ObjectToBuilding(845, 2)
|
||||||
TerminalToInterface(520, 1081)
|
ObjectToBuilding(1082, 2)
|
||||||
|
ObjectToBuilding(1083, 2)
|
||||||
|
ObjectToBuilding(1084, 2)
|
||||||
|
ObjectToBuilding(1085, 2)
|
||||||
|
ObjectToBuilding(1086, 2)
|
||||||
|
ObjectToBuilding(1087, 2)
|
||||||
|
ObjectToBuilding(1088, 2)
|
||||||
|
ObjectToBuilding(1089, 2)
|
||||||
TerminalToInterface(522, 1082)
|
TerminalToInterface(522, 1082)
|
||||||
TerminalToInterface(523, 1083)
|
TerminalToInterface(523, 1083)
|
||||||
TerminalToInterface(524, 1084)
|
TerminalToInterface(524, 1084)
|
||||||
|
|
@ -178,8 +186,6 @@ object Maps {
|
||||||
ObjectToBuilding(706, 77)
|
ObjectToBuilding(706, 77)
|
||||||
TerminalToSpawnPad(1063, 706)
|
TerminalToSpawnPad(1063, 706)
|
||||||
|
|
||||||
//ObjectToBuilding(1081, ?)
|
|
||||||
//ObjectToBuilding(520, ?)
|
|
||||||
ObjectToBuilding(853, 2) //TODO check building_id
|
ObjectToBuilding(853, 2) //TODO check building_id
|
||||||
ObjectToBuilding(855, 2) //TODO check building_id
|
ObjectToBuilding(855, 2) //TODO check building_id
|
||||||
ObjectToBuilding(860, 2) //TODO check building_id
|
ObjectToBuilding(860, 2) //TODO check building_id
|
||||||
|
|
|
||||||
|
|
@ -801,7 +801,7 @@ class WorldSessionActor extends Actor with MDCContextAware {
|
||||||
if(interface.contains(terminal_guid.guid) && slotNumber.isDefined) {
|
if(interface.contains(terminal_guid.guid) && slotNumber.isDefined) {
|
||||||
val slot = slotNumber.get
|
val slot = slotNumber.get
|
||||||
log.info(s"$message - put in slot $slot")
|
log.info(s"$message - put in slot $slot")
|
||||||
sendResponse(AvatarImplantMessage(tplayer.GUID, 0, slot, implant_type.id))
|
sendResponse(AvatarImplantMessage(tplayer.GUID, ImplantAction.Add, slot, implant_type.id))
|
||||||
sendResponse(ItemTransactionResultMessage(terminal_guid, TransactionType.Learn, true))
|
sendResponse(ItemTransactionResultMessage(terminal_guid, TransactionType.Learn, true))
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
@ -836,7 +836,7 @@ class WorldSessionActor extends Actor with MDCContextAware {
|
||||||
if(interface.contains(terminal_guid.guid) && slotNumber.isDefined) {
|
if(interface.contains(terminal_guid.guid) && slotNumber.isDefined) {
|
||||||
val slot = slotNumber.get
|
val slot = slotNumber.get
|
||||||
log.info(s"$tplayer is selling $implant_type - take from slot $slot")
|
log.info(s"$tplayer is selling $implant_type - take from slot $slot")
|
||||||
sendResponse(AvatarImplantMessage(tplayer.GUID, 1, slot, 0))
|
sendResponse(AvatarImplantMessage(tplayer.GUID, ImplantAction.Remove, slot, 0))
|
||||||
sendResponse(ItemTransactionResultMessage(terminal_guid, TransactionType.Sell, true))
|
sendResponse(ItemTransactionResultMessage(terminal_guid, TransactionType.Sell, true))
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
@ -982,10 +982,10 @@ class WorldSessionActor extends Actor with MDCContextAware {
|
||||||
case Zone.ClientInitialization(zone) =>
|
case Zone.ClientInitialization(zone) =>
|
||||||
val continentNumber = zone.Number
|
val continentNumber = zone.Number
|
||||||
val poplist = LivePlayerList.ZonePopulation(continentNumber, _ => true)
|
val poplist = LivePlayerList.ZonePopulation(continentNumber, _ => true)
|
||||||
|
val popBO = 0 //TODO black ops test (partition)
|
||||||
val popTR = poplist.count(_.Faction == PlanetSideEmpire.TR)
|
val popTR = poplist.count(_.Faction == PlanetSideEmpire.TR)
|
||||||
val popNC = poplist.count(_.Faction == PlanetSideEmpire.NC)
|
val popNC = poplist.count(_.Faction == PlanetSideEmpire.NC)
|
||||||
val popVS = poplist.count(_.Faction == PlanetSideEmpire.VS)
|
val popVS = poplist.count(_.Faction == PlanetSideEmpire.VS)
|
||||||
val popBO = poplist.size - popTR - popNC - popVS
|
|
||||||
|
|
||||||
zone.Buildings.foreach({ case(id, building) => initBuilding(continentNumber, id, building) })
|
zone.Buildings.foreach({ case(id, building) => initBuilding(continentNumber, id, building) })
|
||||||
sendResponse(ZonePopulationUpdateMessage(continentNumber, 414, 138, popTR, 138, popNC, 138, popVS, 138, popBO))
|
sendResponse(ZonePopulationUpdateMessage(continentNumber, 414, 138, popTR, 138, popNC, 138, popVS, 138, popBO))
|
||||||
|
|
@ -1020,18 +1020,30 @@ class WorldSessionActor extends Actor with MDCContextAware {
|
||||||
val guid = tplayer.GUID
|
val guid = tplayer.GUID
|
||||||
LivePlayerList.Assign(continent.Number, sessionId, guid)
|
LivePlayerList.Assign(continent.Number, sessionId, guid)
|
||||||
sendResponse(SetCurrentAvatarMessage(guid,0,0))
|
sendResponse(SetCurrentAvatarMessage(guid,0,0))
|
||||||
|
|
||||||
|
(0 until DetailedCharacterData.numberOfImplantSlots(tplayer.BEP)).foreach(slot => {
|
||||||
|
sendResponse(AvatarImplantMessage(guid, ImplantAction.Initialization, slot, 1)) //init implant slot
|
||||||
|
sendResponse(AvatarImplantMessage(guid, ImplantAction.Activation, slot, 0)) //deactivate implant
|
||||||
|
//TODO: if this implant is Installed but does not have shortcut, add to a free slot or write over slot 61/62/63
|
||||||
|
})
|
||||||
|
|
||||||
sendResponse(PlanetsideAttributeMessage(PlanetSideGUID(0), 82, 0))
|
sendResponse(PlanetsideAttributeMessage(PlanetSideGUID(0), 82, 0))
|
||||||
|
//TODO: if Medkit does not have shortcut, add to a free slot or write over slot 64
|
||||||
sendResponse(CreateShortcutMessage(guid, 1, 0, true, Shortcut.MEDKIT))
|
sendResponse(CreateShortcutMessage(guid, 1, 0, true, Shortcut.MEDKIT))
|
||||||
sendResponse(ChangeShortcutBankMessage(guid, 0))
|
sendResponse(ChangeShortcutBankMessage(guid, 0))
|
||||||
//FavoritesMessage
|
//FavoritesMessage
|
||||||
sendResponse(SetChatFilterMessage(ChatChannel.Local, false, ChatChannel.values.toList)) //TODO will not always be "on"
|
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.Nothing, 0,0, tplayer.Position, 0, 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 => {
|
||||||
sendResponse(PlanetsideAttributeMessage(PlanetSideGUID(i), 67, 0))
|
sendResponse(PlanetsideAttributeMessage(PlanetSideGUID(i), 67, 0))
|
||||||
})
|
})
|
||||||
//AvatarStatisticsMessage
|
(0 to 30).foreach(i => { //TODO 30 for a new character only?
|
||||||
|
sendResponse(AvatarStatisticsMessage(2, Statistics(0L)))
|
||||||
|
})
|
||||||
|
//AvatarAwardMessage
|
||||||
|
//DisplayAwardMessage
|
||||||
//SquadDefinitionActionMessage and SquadDetailDefinitionUpdateMessage
|
//SquadDefinitionActionMessage and SquadDetailDefinitionUpdateMessage
|
||||||
//MapObjectStateBlockMessage and ObjectCreateMessage
|
//MapObjectStateBlockMessage and ObjectCreateMessage
|
||||||
//TacticsMessage
|
//TacticsMessage
|
||||||
|
|
@ -2023,11 +2035,12 @@ class WorldSessionActor extends Actor with MDCContextAware {
|
||||||
log.info("ItemTransaction: " + msg)
|
log.info("ItemTransaction: " + msg)
|
||||||
continent.GUID(terminal_guid) match {
|
continent.GUID(terminal_guid) match {
|
||||||
case Some(term : Terminal) =>
|
case Some(term : Terminal) =>
|
||||||
if(player.Faction == term.Faction) {
|
log.info(s"ItemTransaction: ${term.Definition.Name} found")
|
||||||
term.Actor ! Terminal.Request(player, msg)
|
term.Actor ! Terminal.Request(player, msg)
|
||||||
}
|
case Some(obj : PlanetSideGameObject) =>
|
||||||
case Some(obj : PlanetSideGameObject) => ;
|
log.error(s"ItemTransaction: $obj is not a terminal")
|
||||||
case None => ;
|
case _ =>
|
||||||
|
log.error(s"ItemTransaction: $terminal_guid does not exist")
|
||||||
}
|
}
|
||||||
|
|
||||||
case msg @ FavoritesRequest(player_guid, unk, action, line, label) =>
|
case msg @ FavoritesRequest(player_guid, unk, action, line, label) =>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue