mirror of
https://github.com/2revoemag/PSF-BotServer.git
synced 2026-03-04 04:30:21 +00:00
Removed duplicate code by moving the logic of Container around; removed duplicate code by producing a functional inventory search algorithm that handles both ammunition and weapon magazine options; corrected tests
This commit is contained in:
parent
ba49b5859e
commit
526ab7d5ec
8 changed files with 140 additions and 173 deletions
|
|
@ -3,10 +3,7 @@ package net.psforever.objects
|
|||
|
||||
import net.psforever.objects.definition.EquipmentDefinition
|
||||
import net.psforever.objects.equipment.Equipment
|
||||
import net.psforever.objects.inventory.{Container, GridInventory, InventoryItem}
|
||||
import net.psforever.packet.game.PlanetSideGUID
|
||||
|
||||
import scala.annotation.tailrec
|
||||
import net.psforever.objects.inventory.{Container, GridInventory}
|
||||
|
||||
/**
|
||||
* The companion of a `Locker` that is carried with a player
|
||||
|
|
@ -21,42 +18,8 @@ class LockerContainer extends Equipment with Container {
|
|||
|
||||
def VisibleSlots : Set[Int] = Set.empty[Int]
|
||||
|
||||
override def Slot(slot : Int) : EquipmentSlot = {
|
||||
if(inventory.Offset <= slot && slot <= inventory.LastIndex) {
|
||||
inventory.Slot(slot)
|
||||
}
|
||||
else {
|
||||
OffhandEquipmentSlot.BlockedSlot
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
def Fit(obj : Equipment) : Option[Int] = inventory.Fit(obj.Definition.Tile)
|
||||
|
||||
def Find(guid : PlanetSideGUID) : Option[Int] = {
|
||||
findInInventory(inventory.Items.values.iterator, guid) match {
|
||||
case Some(index) =>
|
||||
Some(index)
|
||||
case None =>
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
@tailrec private def findInInventory(iter : Iterator[InventoryItem], guid : PlanetSideGUID) : Option[Int] = {
|
||||
if(!iter.hasNext) {
|
||||
None
|
||||
}
|
||||
else {
|
||||
val item = iter.next
|
||||
if(item.obj.GUID == guid) {
|
||||
Some(item.start)
|
||||
}
|
||||
else {
|
||||
findInInventory(iter, guid)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def Definition : EquipmentDefinition = GlobalDefinitions.locker_container
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -192,11 +192,9 @@ class Player(private val core : Avatar) extends PlanetSideGameObject with Factio
|
|||
FreeHand.Equipment
|
||||
}
|
||||
|
||||
def Find(obj : Equipment) : Option[Int] = Find(obj.GUID)
|
||||
|
||||
def Find(guid : PlanetSideGUID) : Option[Int] = {
|
||||
override def Find(guid : PlanetSideGUID) : Option[Int] = {
|
||||
findInHolsters(holsters.iterator, guid)
|
||||
.orElse(findInInventory(inventory.Items.values.iterator, guid)) match {
|
||||
.orElse(inventory.Find(guid)) match {
|
||||
case Some(index) =>
|
||||
Some(index)
|
||||
case None =>
|
||||
|
|
@ -224,21 +222,6 @@ class Player(private val core : Avatar) extends PlanetSideGameObject with Factio
|
|||
}
|
||||
}
|
||||
|
||||
@tailrec private def findInInventory(iter : Iterator[InventoryItem], guid : PlanetSideGUID) : Option[Int] = {
|
||||
if(!iter.hasNext) {
|
||||
None
|
||||
}
|
||||
else {
|
||||
val item = iter.next
|
||||
if(item.obj.GUID == guid) {
|
||||
Some(item.start)
|
||||
}
|
||||
else {
|
||||
findInInventory(iter, guid)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override def Collisions(dest : Int, width : Int, height : Int) : Try[List[InventoryItem]] = {
|
||||
if(-1 < dest && dest < 5) {
|
||||
holsters(dest).Equipment match {
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ package net.psforever.objects
|
|||
|
||||
import net.psforever.objects.definition.VehicleDefinition
|
||||
import net.psforever.objects.equipment.{Equipment, EquipmentSize}
|
||||
import net.psforever.objects.inventory.{Container, GridInventory, InventoryItem, InventoryTile}
|
||||
import net.psforever.objects.inventory.{Container, GridInventory, InventoryTile}
|
||||
import net.psforever.objects.serverobject.mount.Mountable
|
||||
import net.psforever.objects.serverobject.PlanetSideServerObject
|
||||
import net.psforever.objects.serverobject.affinity.FactionAffinity
|
||||
|
|
@ -347,43 +347,8 @@ class Vehicle(private val vehicleDef : VehicleDefinition) extends PlanetSideServ
|
|||
|
||||
def Inventory : GridInventory = trunk
|
||||
|
||||
def Find(obj : Equipment) : Option[Int] = Find(obj.GUID)
|
||||
|
||||
def Find(guid : PlanetSideGUID) : Option[Int] = {
|
||||
findInInventory(Inventory.Items.values.iterator, guid) match {
|
||||
case Some(index) =>
|
||||
Some(index)
|
||||
case None =>
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
@tailrec private def findInInventory(iter : Iterator[InventoryItem], guid : PlanetSideGUID) : Option[Int] = {
|
||||
if(!iter.hasNext) {
|
||||
None
|
||||
}
|
||||
else {
|
||||
val item = iter.next
|
||||
if(item.obj.GUID == guid) {
|
||||
Some(item.start)
|
||||
}
|
||||
else {
|
||||
findInInventory(iter, guid)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def VisibleSlots : Set[Int] = weapons.keySet
|
||||
|
||||
override def Slot(slot : Int) : EquipmentSlot = {
|
||||
if(Inventory.Offset <= slot && slot <= Inventory.LastIndex) {
|
||||
Inventory.Slot(slot)
|
||||
}
|
||||
else {
|
||||
OffhandEquipmentSlot.BlockedSlot
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A reference to the `Vehicle` `Trunk` space.
|
||||
* @return this `Vehicle` `Trunk`
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
// Copyright (c) 2017 PSForever
|
||||
package net.psforever.objects.inventory
|
||||
|
||||
import net.psforever.objects.equipment.Equipment
|
||||
import net.psforever.objects.{EquipmentSlot, OffhandEquipmentSlot}
|
||||
import net.psforever.packet.game.PlanetSideGUID
|
||||
|
||||
|
|
@ -20,17 +21,26 @@ trait Container {
|
|||
* A(n imperfect) reference to a generalized pool of the contained objects.
|
||||
* Having access to all of the available positions is not required.
|
||||
* The entries in this reference should definitely include all unseen positions.
|
||||
* The `GridInventory` returned by this accessor is also an implementation of `Container`.
|
||||
* @see `VisibleSlots`
|
||||
*/
|
||||
def Inventory : GridInventory
|
||||
|
||||
/**
|
||||
* Given an object, attempt to locate its slot.
|
||||
* All positions, `VisibleSlot` and `Inventory`, and wherever else, should be searchable.
|
||||
* @param obj the `Equipment` object
|
||||
* @return the index of the `EquipmentSlot`, or `None`
|
||||
*/
|
||||
def Find(obj : Equipment) : Option[Int] = Find(obj.GUID)
|
||||
|
||||
/**
|
||||
* Given globally unique identifier, if the object using it is stowed, attempt to locate its slot.
|
||||
* All positions, `VisibleSlot` and `Inventory`, and wherever else, should be searchable.
|
||||
* @param guid the GUID of the `Equipment`
|
||||
* @return the index of the `EquipmentSlot`, or `None`
|
||||
*/
|
||||
def Find(guid : PlanetSideGUID) : Option[Int]
|
||||
def Find(guid : PlanetSideGUID) : Option[Int] = Inventory.Find(guid)
|
||||
|
||||
/**
|
||||
* A(n imperfect) reference to a generalized pool of the contained objects.<br>
|
||||
|
|
@ -53,7 +63,14 @@ trait Container {
|
|||
* @param slotNum an index
|
||||
* @return the searchable position identified by that index
|
||||
*/
|
||||
def Slot(slotNum : Int) : EquipmentSlot = OffhandEquipmentSlot.BlockedSlot
|
||||
def Slot(slotNum : Int) : EquipmentSlot = {
|
||||
if(Inventory.Offset <= slotNum && slotNum <= Inventory.LastIndex) {
|
||||
Inventory.Slot(slotNum)
|
||||
}
|
||||
else {
|
||||
OffhandEquipmentSlot.BlockedSlot
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a region of "searchable unit positions" considered as stowable,
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ import scala.util.{Failure, Success, Try}
|
|||
* The `Array` of spatial GUIDs is used for quick collision lookup.
|
||||
* Use of the `Array` only is hitherto referred as "using the inventory as a grid."
|
||||
*/
|
||||
class GridInventory {
|
||||
class GridInventory extends Container {
|
||||
private var width : Int = 1
|
||||
private var height : Int = 1
|
||||
private var offset : Int = 0 //the effective index of the first cell in the inventory where offset >= 0
|
||||
|
|
@ -83,12 +83,21 @@ class GridInventory {
|
|||
*/
|
||||
def LastIndex : Int = Offset + TotalCapacity - 1
|
||||
|
||||
override def Find(guid : PlanetSideGUID) : Option[Int] = {
|
||||
items.values.find({ case InventoryItem(obj, _) => obj.HasGUID && obj.GUID == guid}) match {
|
||||
case Some(InventoryItem(_, index)) =>
|
||||
Some(index)
|
||||
case None =>
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get whatever is stowed in the inventory at the given index.
|
||||
* @param slot the cell index
|
||||
* @return an `EquipmentSlot` that contains whatever `Equipment` was stored in `slot`
|
||||
*/
|
||||
def Slot(slot : Int) : EquipmentSlot = {
|
||||
override def Slot(slot : Int) : EquipmentSlot = {
|
||||
val actualSlot = slot - offset
|
||||
if(actualSlot < 0 || actualSlot > grid.length) {
|
||||
throw new IndexOutOfBoundsException(s"requested indices not in bounds of grid inventory - $actualSlot")
|
||||
|
|
@ -426,6 +435,10 @@ class GridInventory {
|
|||
height = h
|
||||
grid = Array.fill[Int](w * h)(-1)
|
||||
}
|
||||
|
||||
def VisibleSlots : Set[Int] = Set.empty[Int]
|
||||
|
||||
def Inventory = this
|
||||
}
|
||||
|
||||
object GridInventory {
|
||||
|
|
|
|||
|
|
@ -1,8 +1,9 @@
|
|||
// Copyright (c) 2017 PSForever
|
||||
package objects
|
||||
|
||||
import net.psforever.objects.inventory.{Container, GridInventory, InventoryItem}
|
||||
import net.psforever.objects.{GlobalDefinitions, OffhandEquipmentSlot, Tool}
|
||||
import net.psforever.objects.equipment.EquipmentSize
|
||||
import net.psforever.objects.inventory.{Container, GridInventory, InventoryEquipmentSlot}
|
||||
import net.psforever.objects.{EquipmentSlot, GlobalDefinitions, OffhandEquipmentSlot, Tool}
|
||||
import net.psforever.packet.game.PlanetSideGUID
|
||||
import org.specs2.mutable._
|
||||
|
||||
|
|
@ -16,7 +17,11 @@ class ContainerTest extends Specification {
|
|||
obj.Inventory.Size mustEqual 0
|
||||
obj.Inventory.Capacity mustEqual 9
|
||||
obj.Find(PlanetSideGUID(0)) mustEqual None
|
||||
obj.Slot(0) mustEqual OffhandEquipmentSlot.BlockedSlot
|
||||
obj.Slot(0).isInstanceOf[OffhandEquipmentSlot] mustEqual true
|
||||
obj.Slot(0).isInstanceOf[InventoryEquipmentSlot] mustEqual true
|
||||
obj.Slot(0).isInstanceOf[EquipmentSlot] mustEqual true
|
||||
obj.Slot(0).Size mustEqual EquipmentSize.Inventory
|
||||
obj.Slot(0).Equipment mustEqual None
|
||||
obj.Collisions(0, 2, 2) mustEqual Success(List())
|
||||
}
|
||||
|
||||
|
|
@ -49,23 +54,6 @@ object ContainerTest {
|
|||
|
||||
def Inventory : GridInventory = inv
|
||||
|
||||
def Find(guid : PlanetSideGUID) : Option[Int] = {
|
||||
Inventory.Items.find({
|
||||
case((_, item)) =>
|
||||
if(item.obj.HasGUID) {
|
||||
item.obj.GUID == guid
|
||||
}
|
||||
else {
|
||||
false
|
||||
}
|
||||
}) match {
|
||||
case Some((index, _)) =>
|
||||
Some(index)
|
||||
case None =>
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
def VisibleSlots :Set[Int] = Set[Int](0,1,2, 3,4,5, 6,7,8)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -303,7 +303,7 @@ class PlayerTest extends Specification {
|
|||
obj.Find(PlanetSideGUID(1)) mustEqual Some(0) //holsters
|
||||
obj.Find(PlanetSideGUID(2)) mustEqual Some(4) //holsters, melee
|
||||
obj.Find(PlanetSideGUID(3)) mustEqual Some(6) //inventory
|
||||
obj.Find(PlanetSideGUID(4)) mustEqual Some(Player.LockerSlot) //locker-space
|
||||
obj.Find(PlanetSideGUID(4)) mustEqual None //can not find in locker-space
|
||||
obj.Find(PlanetSideGUID(5)) mustEqual Some(Player.FreeHandSlot) //free hand
|
||||
obj.Find(PlanetSideGUID(6)) mustEqual None //not here
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue