From ba49b5859ece7bbb53e7085f9478cacec67b63de Mon Sep 17 00:00:00 2001 From: FateJH Date: Tue, 8 May 2018 23:55:01 -0400 Subject: [PATCH] replenishing supply of thrown grenades from player inventory; pulled in locker search for Player.Find to avoid wrongful indexing --- .../scala/net/psforever/objects/Player.scala | 5 +- .../src/main/scala/WorldSessionActor.scala | 55 ++++++++++++++++++- 2 files changed, 55 insertions(+), 5 deletions(-) diff --git a/common/src/main/scala/net/psforever/objects/Player.scala b/common/src/main/scala/net/psforever/objects/Player.scala index 1250051b..35e88540 100644 --- a/common/src/main/scala/net/psforever/objects/Player.scala +++ b/common/src/main/scala/net/psforever/objects/Player.scala @@ -200,10 +200,7 @@ class Player(private val core : Avatar) extends PlanetSideGameObject with Factio case Some(index) => Some(index) case None => - if(Locker.Find(guid).isDefined) { - Some(5) - } - else if(freeHand.Equipment.isDefined && freeHand.Equipment.get.GUID == guid) { + if(freeHand.Equipment.isDefined && freeHand.Equipment.get.GUID == guid) { Some(Player.FreeHandSlot) } else { diff --git a/pslogin/src/main/scala/WorldSessionActor.scala b/pslogin/src/main/scala/WorldSessionActor.scala index 72b3e1e3..d0735260 100644 --- a/pslogin/src/main/scala/WorldSessionActor.scala +++ b/pslogin/src/main/scala/WorldSessionActor.scala @@ -3263,6 +3263,29 @@ class WorldSessionActor extends Actor with MDCContextAware { previousAmount < desiredAmount }) } + def FindRestock(obj : Container, filterTest : (Equipment)=>Boolean, desiredAmount : Int) : List[InventoryItem] = { + var currentAmount : Int = 0 + obj.Inventory.Items + .map({ case ((_, item)) => item }) + .filter(obj => filterTest(obj.obj)) + .toList + .sortBy(_.start) + .takeWhile(entry => { + val previousAmount = currentAmount + currentAmount += (entry.obj match { + case obj : AmmoBox => + obj.Capacity + case obj : Tool => + if(GlobalDefinitions.isGrenade(obj.Definition)) { + obj.Magazine + } + else { + 1 + } + }) + previousAmount < desiredAmount + }) + } /** * Given an object that contains a box of amunition in its `Inventory` at a certain location, @@ -3404,13 +3427,43 @@ class WorldSessionActor extends Actor with MDCContextAware { //TODO this is temporary and will be replaced by more appropriate functionality in the future. val tdef = tool.Definition if(GlobalDefinitions.isGrenade(tdef)) { - taskResolver ! RemoveEquipmentFromSlot(player, tool, player.Find(tool).get) + val findGrenades : (Equipment)=>Boolean = FindGrenadesLike(tool.AmmoType) + FindRestock(player, findGrenades, 3) match { + case Nil => + taskResolver ! RemoveEquipmentFromSlot(player, tool, player.Find(tool).get) + + case x :: xs => //this is similar to ReloadMessage + val box = x.obj.asInstanceOf[Tool] + val tailReloadValue : Int = if(xs.isEmpty) { 0 } else { xs.map(_.obj.asInstanceOf[Tool].Magazine).reduce(_ + _) } + val sumReloadValue : Int = box.Magazine + tailReloadValue + val actualReloadValue = (if(sumReloadValue <= 3) { + taskResolver ! RemoveEquipmentFromSlot(player, x.obj, x.start) + sumReloadValue + } + else { + ModifyAmmunition(player)(box.AmmoSlot.Box, 3 - tailReloadValue) + 3 + }) + ModifyAmmunition(player)(tool.AmmoSlot.Box, -actualReloadValue) //grenades already in holster (negative because empty) + xs.foreach(item => { + taskResolver ! RemoveEquipmentFromSlot(player, item.obj, item.start) + }) + } } else if(tdef == GlobalDefinitions.phoenix) { taskResolver ! RemoveEquipmentFromSlot(player, tool, player.Find(tool).get) } } + def FindGrenadesLike(grenadeType : Ammo.Value)(e : Equipment) : Boolean = { + e match { + case t : Tool => + t.AmmoType == grenadeType + case _ => + false + } + } + /** * A predicate used to determine if an `InventoryItem` object contains `Equipment` that should be dropped. * Used to filter through lists of object data before it is placed into a player's inventory.