diff --git a/common/src/main/scala/net/psforever/objects/definition/converter/AvatarConverter.scala b/common/src/main/scala/net/psforever/objects/definition/converter/AvatarConverter.scala index 40726412c..c1193cc8a 100644 --- a/common/src/main/scala/net/psforever/objects/definition/converter/AvatarConverter.scala +++ b/common/src/main/scala/net/psforever/objects/definition/converter/AvatarConverter.scala @@ -249,11 +249,10 @@ object AvatarConverter { */ private def MakeInventory(obj : Player) : List[InternalSlot] = { obj.Inventory.Items - .map({ - case(_, item) => + .map(item => { val equip : Equipment = item.obj InternalSlot(equip.Definition.ObjectId, equip.GUID, item.start, equip.Definition.Packet.DetailedConstructorData(equip).get) - }).toList + }) } /** diff --git a/common/src/main/scala/net/psforever/objects/definition/converter/CorpseConverter.scala b/common/src/main/scala/net/psforever/objects/definition/converter/CorpseConverter.scala index 7dd030a50..762b48da4 100644 --- a/common/src/main/scala/net/psforever/objects/definition/converter/CorpseConverter.scala +++ b/common/src/main/scala/net/psforever/objects/definition/converter/CorpseConverter.scala @@ -73,11 +73,10 @@ class CorpseConverter extends AvatarConverter { */ private def MakeInventory(obj : Player) : List[InternalSlot] = { obj.Inventory.Items - .map({ - case(_, item) => + .map(item => { val equip : Equipment = item.obj BuildEquipment(item.start, equip) - }).toList + }) } /** diff --git a/common/src/main/scala/net/psforever/objects/definition/converter/LockerContainerConverter.scala b/common/src/main/scala/net/psforever/objects/definition/converter/LockerContainerConverter.scala index bd3213136..124a4c971 100644 --- a/common/src/main/scala/net/psforever/objects/definition/converter/LockerContainerConverter.scala +++ b/common/src/main/scala/net/psforever/objects/definition/converter/LockerContainerConverter.scala @@ -30,11 +30,10 @@ class LockerContainerConverter extends ObjectCreateConverter[LockerContainer]() */ private def MakeInventory(inv : GridInventory) : List[InternalSlot] = { inv.Items - .map({ - case(_, item) => + .map(item => { val equip : Equipment = item.obj InternalSlot(equip.Definition.ObjectId, equip.GUID, item.start, equip.Definition.Packet.ConstructorData(equip).get) - }).toList + }) } /** @@ -45,10 +44,9 @@ class LockerContainerConverter extends ObjectCreateConverter[LockerContainer]() */ private def MakeDetailedInventory(inv : GridInventory) : List[InternalSlot] = { inv.Items - .map({ - case(_, item) => + .map(item => { val equip : Equipment = item.obj InternalSlot(equip.Definition.ObjectId, equip.GUID, item.start, equip.Definition.Packet.DetailedConstructorData(equip).get) - }).toList + }) } } diff --git a/common/src/main/scala/net/psforever/objects/guid/GUIDTask.scala b/common/src/main/scala/net/psforever/objects/guid/GUIDTask.scala index 2ea7fb4a5..af5c2db43 100644 --- a/common/src/main/scala/net/psforever/objects/guid/GUIDTask.scala +++ b/common/src/main/scala/net/psforever/objects/guid/GUIDTask.scala @@ -100,7 +100,7 @@ object GUIDTask { * @return a list of `TaskResolver.GiveTask` messages */ def RegisterInventory(container : Container)(implicit guid : ActorRef) : List[TaskResolver.GiveTask] = { - container.Inventory.Items.values.map(entry => { RegisterEquipment(entry.obj)}).toList + container.Inventory.Items.map(entry => { RegisterEquipment(entry.obj)}) } /** @@ -257,7 +257,7 @@ object GUIDTask { * @return a list of `TaskResolver.GiveTask` messages */ def UnregisterInventory(container : Container)(implicit guid : ActorRef) : List[TaskResolver.GiveTask] = { - container.Inventory.Items.values.map(entry => { UnregisterEquipment(entry.obj)}).toList + container.Inventory.Items.map(entry => { UnregisterEquipment(entry.obj)}) } /** diff --git a/common/src/main/scala/net/psforever/objects/inventory/GridInventory.scala b/common/src/main/scala/net/psforever/objects/inventory/GridInventory.scala index c05c04607..72967165a 100644 --- a/common/src/main/scala/net/psforever/objects/inventory/GridInventory.scala +++ b/common/src/main/scala/net/psforever/objects/inventory/GridInventory.scala @@ -8,7 +8,6 @@ import net.psforever.objects.EquipmentSlot import net.psforever.packet.game.PlanetSideGUID import scala.annotation.tailrec -import scala.collection.immutable.Map import scala.collection.mutable import scala.util.{Failure, Success, Try} @@ -38,7 +37,7 @@ class GridInventory extends Container { private val entryIndex : AtomicInteger = new AtomicInteger(0) private var grid : Array[Int] = Array.fill[Int](1)(-1) - def Items : Map[Int, InventoryItem] = items.toMap[Int, InventoryItem] + def Items : List[InventoryItem] = items.values.toList def Width : Int = width @@ -331,26 +330,23 @@ class GridInventory extends Container { def Insertion_CheckCollisions(start : Int, obj : Equipment, key : Int) : Boolean = { CheckCollisions(start, obj) match { case Success(Nil) => - val card = InventoryItem(obj, start) - items += key -> card - val tile = obj.Tile - SetCells(start, tile.Width, tile.Height, key) - true + InsertQuickly(start, obj, key) case _ => false } } - def +=(kv : (Int, Equipment)) : Boolean = Insert(kv._1, kv._2) + def InsertQuickly(start : Int, obj : Equipment) : Boolean = InsertQuickly(start, obj, entryIndex.getAndIncrement()) -// def InsertQuickly(start : Int, obj : Equipment) : Boolean = { -// val guid : Int = obj.GUID.guid -// val card = InventoryItemData(obj, start) -// items += guid -> card -// val tile = obj.Tile -// SetCellsOffset(start, tile.width, tile.height, guid) -// true -// } + private def InsertQuickly(start : Int, obj : Equipment, key : Int) : Boolean = { + val card = InventoryItem(obj, start) + items += key -> card + val tile = obj.Tile + SetCells(start, tile.Width, tile.Height, key) + true + } + + def +=(kv : (Int, Equipment)) : Boolean = Insert(kv._1, kv._2) def Remove(index : Int) : Boolean = { val key = grid(index - Offset) diff --git a/common/src/main/scala/net/psforever/objects/inventory/InventoryEquipmentSlot.scala b/common/src/main/scala/net/psforever/objects/inventory/InventoryEquipmentSlot.scala index 575a43a10..f387eb73e 100644 --- a/common/src/main/scala/net/psforever/objects/inventory/InventoryEquipmentSlot.scala +++ b/common/src/main/scala/net/psforever/objects/inventory/InventoryEquipmentSlot.scala @@ -34,7 +34,7 @@ class InventoryEquipmentSlot(private val slot : Int, private val inv : GridInven case Some(equip) => val tile = equip.Definition.Tile inv.CheckCollisionsVar(slot, tile.Width, tile.Height) match { - case Success(Nil) => inv += slot -> equip + case Success(Nil) => inv.InsertQuickly(slot, equip) case _ => ; } diff --git a/common/src/main/scala/net/psforever/objects/inventory/InventoryTile.scala b/common/src/main/scala/net/psforever/objects/inventory/InventoryTile.scala index ea0b58c3e..a1468cd5c 100644 --- a/common/src/main/scala/net/psforever/objects/inventory/InventoryTile.scala +++ b/common/src/main/scala/net/psforever/objects/inventory/InventoryTile.scala @@ -26,14 +26,14 @@ object InventoryTile { final val Tile33 = InventoryTile(3,3) //ammo box, pistols, ace final val Tile44 = InventoryTile(4,4) //large ammo box final val Tile55 = InventoryTile(5,5) //bfr ammo box - final val Tile66 = InventoryTile(6,6) //standard assault inventory + final val Tile66 = InventoryTile(6,6) //infiltration suit inventory final val Tile63 = InventoryTile(6,3) //rifles final val Tile93 = InventoryTile(9,3) //long-body weapons - final val Tile96 = InventoryTile(9,6) //standard exo-suit - final val Tile99 = InventoryTile(9,9) //agile exo-suit + final val Tile96 = InventoryTile(9,6) //standard exo-suit inventory + final val Tile99 = InventoryTile(9,9) //agile exo-suit inventory final val Tile1107 = InventoryTile(11, 7) //uncommon small trunk capacity - phantasm final val Tile1111 = InventoryTile(11,11) //common small trunk capacity - final val Tile1209 = InventoryTile(12, 9) //reinforced exo-suit + final val Tile1209 = InventoryTile(12, 9) //reinforced exo-suit inventory final val Tile1511 = InventoryTile(15,11) //common medium trunk capacity final val Tile1515 = InventoryTile(15,15) //common large trunk capacity final val Tile1611 = InventoryTile(16,11) //uncommon medium trunk capacity - vulture diff --git a/common/src/main/scala/net/psforever/objects/loadouts/Loadout.scala b/common/src/main/scala/net/psforever/objects/loadouts/Loadout.scala index 5ff4f92de..82cab3d47 100644 --- a/common/src/main/scala/net/psforever/objects/loadouts/Loadout.scala +++ b/common/src/main/scala/net/psforever/objects/loadouts/Loadout.scala @@ -39,7 +39,7 @@ object Loadout { InfantryLoadout( label, packageSimplifications(player.Holsters()), - packageSimplifications(player.Inventory.Items.values.toList), + packageSimplifications(player.Inventory.Items), player.ExoSuit, DetermineSubtype(player) ) @@ -55,7 +55,7 @@ object Loadout { VehicleLoadout( label, packageSimplifications(vehicle.Weapons.map({ case ((index, weapon)) => InventoryItem(weapon.Equipment.get, index) }).toList), - packageSimplifications(vehicle.Trunk.Items.values.toList), + packageSimplifications(vehicle.Trunk.Items), vehicle.Definition ) } diff --git a/common/src/test/scala/objects/InventoryTest.scala b/common/src/test/scala/objects/InventoryTest.scala index fb6410b75..9236ff246 100644 --- a/common/src/test/scala/objects/InventoryTest.scala +++ b/common/src/test/scala/objects/InventoryTest.scala @@ -349,5 +349,42 @@ class InventoryTest extends Specification { out(1).Definition.Tile mustEqual InventoryTile.Tile22 //did not fit ok } + + "insert items quickly (risk overwriting entries)" in { + val obj : GridInventory = GridInventory(6, 6) + (obj += 0 -> bullet9mmBox1) mustEqual true + val collision1 = obj.CheckCollisions(0,1,1) + obj.CheckCollisions(1,1,1) mustEqual collision1 + obj.CheckCollisions(2,1,1) mustEqual collision1 + obj.CheckCollisions(6,1,1) mustEqual collision1 + obj.CheckCollisions(7,1,1) mustEqual collision1 + obj.CheckCollisions(8,1,1) mustEqual collision1 + obj.CheckCollisions(12,1,1) mustEqual collision1 + obj.CheckCollisions(13,1,1) mustEqual collision1 + obj.CheckCollisions(14,1,1) mustEqual collision1 + + (obj += 7 -> bullet9mmBox2) mustEqual false //can not insert overlapping object + obj.CheckCollisions(0,1,1) mustEqual collision1 + obj.CheckCollisions(1,1,1) mustEqual collision1 + obj.CheckCollisions(2,1,1) mustEqual collision1 + obj.CheckCollisions(6,1,1) mustEqual collision1 + obj.CheckCollisions(7,1,1) mustEqual collision1 + obj.CheckCollisions(8,1,1) mustEqual collision1 + obj.CheckCollisions(12,1,1) mustEqual collision1 + obj.CheckCollisions(13,1,1) mustEqual collision1 + obj.CheckCollisions(14,1,1) mustEqual collision1 + + obj.InsertQuickly(7, bullet9mmBox2) mustEqual true //overwrite + val collision2 = obj.CheckCollisions(7,1,1) + obj.CheckCollisions(0,1,1) mustEqual collision1 + obj.CheckCollisions(1,1,1) mustEqual collision1 + obj.CheckCollisions(2,1,1) mustEqual collision1 + obj.CheckCollisions(6,1,1) mustEqual collision1 + obj.CheckCollisions(7,1,1) mustEqual collision2 + obj.CheckCollisions(8,1,1) mustEqual collision2 + obj.CheckCollisions(12,1,1) mustEqual collision1 + obj.CheckCollisions(13,1,1) mustEqual collision2 + obj.CheckCollisions(14,1,1) mustEqual collision2 + } } } diff --git a/pslogin/src/main/scala/WorldSessionActor.scala b/pslogin/src/main/scala/WorldSessionActor.scala index cb72d4573..6b2bbad3c 100644 --- a/pslogin/src/main/scala/WorldSessionActor.scala +++ b/pslogin/src/main/scala/WorldSessionActor.scala @@ -2032,7 +2032,6 @@ class WorldSessionActor extends Actor with MDCContextAware { //divide capacity across other existing and not full boxes of that ammo type var capacity = previousBox.Capacity val iter = obj.Inventory.Items - .map({case(_, entry) => entry }) .filter(entry => { entry.obj match { case (item : AmmoBox) => @@ -3542,18 +3541,17 @@ class WorldSessionActor extends Actor with MDCContextAware { def AccessContents(vehicle : Vehicle) : Unit = { vehicleService ! Service.Join(s"${vehicle.Actor}") val parent_guid = vehicle.GUID - vehicle.Trunk.Items.foreach({ - case ((_, entry)) => - val obj = entry.obj - val objDef = obj.Definition - sendResponse( - ObjectCreateDetailedMessage( - objDef.ObjectId, - obj.GUID, - ObjectCreateMessageParent(parent_guid, entry.start), - objDef.Packet.DetailedConstructorData(obj).get - ) + vehicle.Trunk.Items.foreach(entry => { + val obj = entry.obj + val objDef = obj.Definition + sendResponse( + ObjectCreateDetailedMessage( + objDef.ObjectId, + obj.GUID, + ObjectCreateMessageParent(parent_guid, entry.start), + objDef.Packet.DetailedConstructorData(obj).get ) + ) }) } @@ -3565,8 +3563,7 @@ class WorldSessionActor extends Actor with MDCContextAware { */ def UnAccessContents(vehicle : Vehicle) : Unit = { vehicleService ! Service.Leave(Some(s"${vehicle.Actor}")) - vehicle.Trunk.Items.foreach({ - case ((_, entry)) => + vehicle.Trunk.Items.foreach(entry =>{ sendResponse(ObjectDeleteMessage(entry.obj.GUID, 0)) }) } @@ -3655,7 +3652,6 @@ class WorldSessionActor extends Actor with MDCContextAware { counting : (Equipment)=>Int = DefaultCount) : List[InventoryItem] = { var currentAmount : Int = 0 obj.Inventory.Items - .map({ case ((_, item)) => item }) .filter(item => filterTest(item.obj)) .toList .sortBy(_.start)