added a LockerContainer global definition; adjusted how the lockers inhabit the fifthtSlot on players and how they are accessed; fixed converter tests to account for contents and added a quick content test; Live players will now register and unregister the contents of their fifthslot

This commit is contained in:
FateJH 2017-08-30 20:20:33 -04:00
parent 48e3f77d48
commit 85a6eb00fd
6 changed files with 79 additions and 25 deletions

View file

@ -2,7 +2,7 @@
package net.psforever.objects package net.psforever.objects
import net.psforever.objects.definition._ import net.psforever.objects.definition._
import net.psforever.objects.definition.converter.{CommandDetonaterConverter, REKConverter} import net.psforever.objects.definition.converter.{CommandDetonaterConverter, LockerContainerConverter, REKConverter}
import net.psforever.objects.equipment.CItem.DeployedItem import net.psforever.objects.equipment.CItem.DeployedItem
import net.psforever.objects.equipment._ import net.psforever.objects.equipment._
import net.psforever.objects.inventory.InventoryTile import net.psforever.objects.inventory.InventoryTile
@ -241,6 +241,13 @@ object GlobalDefinitions {
} }
} }
val
locker_container = new EquipmentDefinition(456) {
Name = "locker container"
Size = EquipmentSize.Inventory
Packet = new LockerContainerConverter()
}
val val
medkit = KitDefinition(Kits.medkit) medkit = KitDefinition(Kits.medkit)

View file

@ -7,17 +7,13 @@ import net.psforever.objects.equipment.{Equipment, EquipmentSize}
import net.psforever.objects.inventory.GridInventory import net.psforever.objects.inventory.GridInventory
class LockerContainer extends Equipment { class LockerContainer extends Equipment {
private val inventory = GridInventory() //? private val inventory = GridInventory(30, 20)
def Inventory : GridInventory = inventory def Inventory : GridInventory = inventory
def Fit(obj : Equipment) : Option[Int] = inventory.Fit(obj.Definition.Tile) def Fit(obj : Equipment) : Option[Int] = inventory.Fit(obj.Definition.Tile)
def Definition : EquipmentDefinition = new EquipmentDefinition(456) { def Definition : EquipmentDefinition = GlobalDefinitions.locker_container
Name = "locker container"
Size = EquipmentSize.Inventory
Packet = new LockerContainerConverter()
}
} }
object LockerContainer { object LockerContainer {

View file

@ -70,6 +70,7 @@ class Player(private val name : String,
var PlanetsideAttribute : Array[Long] = Array.ofDim(120) var PlanetsideAttribute : Array[Long] = Array.ofDim(120)
Player.SuitSetup(this, ExoSuit) Player.SuitSetup(this, ExoSuit)
fifthSlot.Equipment = new LockerContainer() //the fifth slot is the player's "locker"
def Name : String = name def Name : String = name
@ -158,7 +159,9 @@ class Player(private val name : String,
holsters(slot) holsters(slot)
} }
else if(slot == 5) { else if(slot == 5) {
fifthSlot new OffhandEquipmentSlot(EquipmentSize.Inventory) {
Equipment = fifthSlot.Equipment
}
} }
else if(slot == Player.FreeHandSlot) { else if(slot == Player.FreeHandSlot) {
freeHand freeHand

View file

@ -4,7 +4,6 @@ package net.psforever.objects.definition.converter
import net.psforever.objects.LockerContainer import net.psforever.objects.LockerContainer
import net.psforever.objects.equipment.Equipment import net.psforever.objects.equipment.Equipment
import net.psforever.objects.inventory.GridInventory import net.psforever.objects.inventory.GridInventory
import net.psforever.packet.game.PlanetSideGUID
import net.psforever.packet.game.objectcreate._ import net.psforever.packet.game.objectcreate._
import scala.util.{Success, Try} import scala.util.{Success, Try}
@ -16,7 +15,7 @@ class LockerContainerConverter extends ObjectCreateConverter[LockerContainer]()
override def DetailedConstructorData(obj : LockerContainer) : Try[DetailedLockerContainerData] = { override def DetailedConstructorData(obj : LockerContainer) : Try[DetailedLockerContainerData] = {
if(obj.Inventory.Size > 0) { if(obj.Inventory.Size > 0) {
Success(DetailedLockerContainerData(8, Some(InventoryData(MakeInventory(obj.Inventory))))) Success(DetailedLockerContainerData(8, Some(InventoryData(MakeDetailedInventory(obj.Inventory)))))
} }
else { else {
Success(DetailedLockerContainerData(8, None)) Success(DetailedLockerContainerData(8, None))
@ -32,9 +31,24 @@ class LockerContainerConverter extends ObjectCreateConverter[LockerContainer]()
private def MakeInventory(inv : GridInventory) : List[InternalSlot] = { private def MakeInventory(inv : GridInventory) : List[InternalSlot] = {
inv.Items inv.Items
.map({ .map({
case(guid, item) => case(_, item) =>
val equip : Equipment = item.obj val equip : Equipment = item.obj
InternalSlot(equip.Definition.ObjectId, PlanetSideGUID(guid), item.start, equip.Definition.Packet.ConstructorData(equip).get) InternalSlot(equip.Definition.ObjectId, equip.GUID, item.start, equip.Definition.Packet.ConstructorData(equip).get)
}).toList }).toList
} }
/**
* Transform a list of contained items into a list of contained `InternalSlot` objects.
* All objects will take the form of data as if found in an `0x18` packet.
* @param inv the inventory container
* @return a list of all items that were in the inventory in decoded packet form
*/
private def MakeDetailedInventory(inv : GridInventory) : List[InternalSlot] = {
inv.Items
.map({
case(_, item) =>
val equip : Equipment = item.obj
InternalSlot(equip.Definition.ObjectId, equip.GUID, item.start, equip.Definition.Packet.DetailedConstructorData(equip).get)
}).toList
}
} }

View file

@ -155,6 +155,7 @@ class ConverterTest extends Specification {
tool.AmmoSlots.head.Box = box1 tool.AmmoSlots.head.Box = box1
val obj = Player(PlanetSideGUID(93), "Chord", PlanetSideEmpire.TR, CharacterGender.Male, 0, 5) val obj = Player(PlanetSideGUID(93), "Chord", PlanetSideEmpire.TR, CharacterGender.Male, 0, 5)
obj.Slot(2).Equipment = tool obj.Slot(2).Equipment = tool
obj.Slot(5).Equipment.get.GUID = PlanetSideGUID(94)
obj.Inventory += 8 -> box2 obj.Inventory += 8 -> box2
obj.Definition.Packet.DetailedConstructorData(obj).isSuccess mustEqual true obj.Definition.Packet.DetailedConstructorData(obj).isSuccess mustEqual true
@ -163,11 +164,11 @@ class ConverterTest extends Specification {
} }
"LockerContainer" should { "LockerContainer" should {
"convert to packet" in { "convert to packet (empty)" in {
val obj = LockerContainer() val obj = LockerContainer()
obj.Definition.Packet.DetailedConstructorData(obj) match { obj.Definition.Packet.DetailedConstructorData(obj) match {
case Success(pkt) => case Success(pkt) =>
pkt mustEqual DetailedLockerContainerData(8) pkt mustEqual DetailedLockerContainerData(8, None)
case _ => case _ =>
ko ko
} }
@ -178,6 +179,27 @@ class ConverterTest extends Specification {
ko ko
} }
} }
"convert to packet (occupied)" in {
import GlobalDefinitions._
val obj = LockerContainer()
val rek = SimpleItem(remote_electronics_kit)
rek.GUID = PlanetSideGUID(1)
obj.Inventory += 0 -> rek
obj.Definition.Packet.DetailedConstructorData(obj) match {
case Success(pkt) =>
pkt mustEqual DetailedLockerContainerData(8, InternalSlot(remote_electronics_kit.ObjectId, PlanetSideGUID(1), 0, DetailedREKData(8)) :: Nil)
case _ =>
ko
}
obj.Definition.Packet.ConstructorData(obj) match {
case Success(pkt) =>
pkt mustEqual LockerContainerData(InventoryData(InternalSlot(remote_electronics_kit.ObjectId, PlanetSideGUID(1), 0, REKData(8,0)) :: Nil))
case _ =>
ko
}
}
} }
"Vehicle" should { "Vehicle" should {

View file

@ -564,7 +564,7 @@ class WorldSessionActor extends Actor with MDCContextAware {
forceblade1 = Tool(forceblade) forceblade1 = Tool(forceblade)
forceblade1.AmmoSlots.head.Box = melee_ammo_box forceblade1.AmmoSlots.head.Box = melee_ammo_box
val rek = SimpleItem(remote_electronics_kit) val rek = SimpleItem(remote_electronics_kit)
val lockerContainer = LockerContainer() val extra_rek = SimpleItem(remote_electronics_kit)
val val
player = Player("IlllIIIlllIlIllIlllIllI", PlanetSideEmpire.VS, CharacterGender.Female, 41, 1) player = Player("IlllIIIlllIlIllIlllIllI", PlanetSideEmpire.VS, CharacterGender.Female, 41, 1)
player.Position = Vector3(3674.8438f, 2726.789f, 91.15625f) player.Position = Vector3(3674.8438f, 2726.789f, 91.15625f)
@ -573,13 +573,13 @@ class WorldSessionActor extends Actor with MDCContextAware {
player.Slot(0).Equipment = beamer1 player.Slot(0).Equipment = beamer1
player.Slot(2).Equipment = suppressor1 player.Slot(2).Equipment = suppressor1
player.Slot(4).Equipment = forceblade1 player.Slot(4).Equipment = forceblade1
player.Slot(5).Equipment = lockerContainer
player.Slot(6).Equipment = bullet_9mm_box1 player.Slot(6).Equipment = bullet_9mm_box1
player.Slot(9).Equipment = bullet_9mm_box2 player.Slot(9).Equipment = bullet_9mm_box2
player.Slot(12).Equipment = bullet_9mm_box3 player.Slot(12).Equipment = bullet_9mm_box3
player.Slot(33).Equipment = bullet_9mm_AP_box player.Slot(33).Equipment = bullet_9mm_AP_box
player.Slot(36).Equipment = energy_cell_box1 player.Slot(36).Equipment = energy_cell_box1
player.Slot(39).Equipment = rek player.Slot(39).Equipment = rek
player.Slot(5).Equipment.get.asInstanceOf[LockerContainer].Inventory += 0 -> extra_rek
//for player2 //for player2
val energy_cell_box3 = AmmoBox(PlanetSideGUID(187), energy_cell) val energy_cell_box3 = AmmoBox(PlanetSideGUID(187), energy_cell)
@ -603,8 +603,6 @@ class WorldSessionActor extends Actor with MDCContextAware {
val val
rek2 = SimpleItem(PlanetSideGUID(188), remote_electronics_kit) rek2 = SimpleItem(PlanetSideGUID(188), remote_electronics_kit)
val val
lockerContainer2 = LockerContainer(PlanetSideGUID(182))
val
player2 = Player(PlanetSideGUID(275), "Doppelganger", PlanetSideEmpire.NC, CharacterGender.Female, 41, 1) player2 = Player(PlanetSideGUID(275), "Doppelganger", PlanetSideEmpire.NC, CharacterGender.Female, 41, 1)
player2.Position = Vector3(3680f, 2726.789f, 91.15625f) player2.Position = Vector3(3680f, 2726.789f, 91.15625f)
player2.Orientation = Vector3(0f, 0f, 0f) player2.Orientation = Vector3(0f, 0f, 0f)
@ -612,7 +610,7 @@ class WorldSessionActor extends Actor with MDCContextAware {
player2.Slot(0).Equipment = beamer2 player2.Slot(0).Equipment = beamer2
player2.Slot(2).Equipment = suppressor2 player2.Slot(2).Equipment = suppressor2
player2.Slot(4).Equipment = forceblade2 player2.Slot(4).Equipment = forceblade2
player2.Slot(5).Equipment = lockerContainer2 player2.Slot(5).Equipment.get.GUID = PlanetSideGUID(182)
player2.Slot(6).Equipment = bullet_9mm_box5 player2.Slot(6).Equipment = bullet_9mm_box5
player2.Slot(9).Equipment = bullet_9mm_box6 player2.Slot(9).Equipment = bullet_9mm_box6
player2.Slot(12).Equipment = bullet_9mm_box7 player2.Slot(12).Equipment = bullet_9mm_box7
@ -1271,8 +1269,8 @@ class WorldSessionActor extends Actor with MDCContextAware {
private def RegisterAvatar(tplayer : Player) : TaskResolver.GiveTask = { private def RegisterAvatar(tplayer : Player) : TaskResolver.GiveTask = {
val holsterTasks = recursiveHolsterTaskBuilding(tplayer.Holsters().iterator, RegisterEquipment) val holsterTasks = recursiveHolsterTaskBuilding(tplayer.Holsters().iterator, RegisterEquipment)
val fifthHolsterTask = tplayer.Slot(5).Equipment match { val fifthHolsterTask = tplayer.Slot(5).Equipment match {
case Some(item) => case Some(locker) =>
RegisterEquipment(item) :: Nil RegisterObjectTask(locker) :: locker.asInstanceOf[LockerContainer].Inventory.Items.map({ case((_ : Int, entry : InventoryItem)) => RegisterEquipment(entry.obj)}).toList
case None => case None =>
List.empty[TaskResolver.GiveTask]; List.empty[TaskResolver.GiveTask];
} }
@ -1399,8 +1397,8 @@ class WorldSessionActor extends Actor with MDCContextAware {
val holsterTasks = recursiveHolsterTaskBuilding(tplayer.Holsters().iterator, UnregisterEquipment) val holsterTasks = recursiveHolsterTaskBuilding(tplayer.Holsters().iterator, UnregisterEquipment)
val inventoryTasks = tplayer.Inventory.Items.map({ case((_ : Int, entry : InventoryItem)) => UnregisterEquipment(entry.obj)}) val inventoryTasks = tplayer.Inventory.Items.map({ case((_ : Int, entry : InventoryItem)) => UnregisterEquipment(entry.obj)})
val fifthHolsterTask = tplayer.Slot(5).Equipment match { val fifthHolsterTask = tplayer.Slot(5).Equipment match {
case Some(item) => case Some(locker) =>
UnregisterEquipment(item) :: Nil UnregisterObjectTask(locker) :: locker.asInstanceOf[LockerContainer].Inventory.Items.map({ case((_ : Int, entry : InventoryItem)) => UnregisterEquipment(entry.obj)}).toList
case None => case None =>
List.empty[TaskResolver.GiveTask]; List.empty[TaskResolver.GiveTask];
} }
@ -1422,7 +1420,14 @@ class WorldSessionActor extends Actor with MDCContextAware {
tplayer.Inventory.Items.foreach({ case((_, entry : InventoryItem)) => tplayer.Inventory.Items.foreach({ case((_, entry : InventoryItem)) =>
SetCharacterSelectScreenGUID_SelectEquipment(Some(entry.obj), gen) SetCharacterSelectScreenGUID_SelectEquipment(Some(entry.obj), gen)
}) })
tplayer.Slot(5).Equipment.get.GUID = PlanetSideGUID(gen.getAndIncrement) tplayer.Slot(5).Equipment match {
case Some(locker) =>
locker.GUID = PlanetSideGUID(gen.getAndIncrement)
locker.asInstanceOf[LockerContainer].Inventory.Items.foreach({ case((_, entry : InventoryItem)) =>
SetCharacterSelectScreenGUID_SelectEquipment(Some(entry.obj), gen)
})
case None => ;
}
tplayer.GUID = PlanetSideGUID(gen.getAndIncrement) tplayer.GUID = PlanetSideGUID(gen.getAndIncrement)
} }
@ -1457,7 +1462,14 @@ class WorldSessionActor extends Actor with MDCContextAware {
tplayer.Inventory.Items.foreach({ case((_, entry : InventoryItem)) => tplayer.Inventory.Items.foreach({ case((_, entry : InventoryItem)) =>
RemoveCharacterSelectScreenGUID_SelectEquipment(Some(entry.obj)) RemoveCharacterSelectScreenGUID_SelectEquipment(Some(entry.obj))
}) })
tplayer.Slot(5).Equipment.get.Invalidate() tplayer.Slot(5).Equipment match {
case Some(locker) =>
locker.Invalidate()
locker.asInstanceOf[LockerContainer].Inventory.Items.foreach({ case((_, entry : InventoryItem)) =>
RemoveCharacterSelectScreenGUID_SelectEquipment(Some(entry.obj))
})
case None => ;
}
tplayer.Invalidate() tplayer.Invalidate()
} }