mirror of
https://github.com/2revoemag/PSF-BotServer.git
synced 2026-01-19 18:14:44 +00:00
Lightweight Locker (#578)
* object registration adjustments for players and avatars and lockers (especially lockers) * refactored locker container * modifications to fields and method names for guid-related files; SpecificNumberSource created * locker item display; proper item insertion into locker-space and searchability of that locker-space * proper item removal from locker-space, including swap-items on other insertion tasks * comments and tests; adjusted avatar/player registrations; allowed for restriction in the SpecificNumberSource; renamed CataloguedInventory to LocallyRegisteredInventory, and made internal object registration work * accommodations for RequestDestroy, to allow the locker's Clear button to work; modification of expectation for resolving projectiles through ValidObject
This commit is contained in:
parent
8245d3ff1e
commit
7626c8e6c9
|
|
@ -213,7 +213,7 @@ object VehicleSpawnPadControlTest {
|
|||
faction: PlanetSideEmpire.Value
|
||||
)(implicit system: ActorSystem): (Vehicle, Player, VehicleSpawnPad, Zone) = {
|
||||
import net.psforever.objects.guid.NumberPoolHub
|
||||
import net.psforever.objects.guid.source.LimitedNumberSource
|
||||
import net.psforever.objects.guid.source.MaxNumberSource
|
||||
import net.psforever.objects.serverobject.structures.Building
|
||||
import net.psforever.objects.vehicles.VehicleControl
|
||||
import net.psforever.objects.Tool
|
||||
|
|
@ -221,7 +221,7 @@ object VehicleSpawnPadControlTest {
|
|||
|
||||
val vehicle = Vehicle(GlobalDefinitions.two_man_assault_buggy)
|
||||
val weapon = vehicle.WeaponControlledFromSeat(1).get.asInstanceOf[Tool]
|
||||
val guid: NumberPoolHub = new NumberPoolHub(LimitedNumberSource(5))
|
||||
val guid: NumberPoolHub = new NumberPoolHub(MaxNumberSource(5))
|
||||
guid.AddPool("test-pool", (0 to 5).toList)
|
||||
guid.register(vehicle, "test-pool")
|
||||
guid.register(weapon, "test-pool")
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ import scala.concurrent.duration._
|
|||
import akka.actor.typed.scaladsl.adapter._
|
||||
import net.psforever.actors.zone.ZoneActor
|
||||
import net.psforever.objects.avatar.Avatar
|
||||
import net.psforever.objects.guid.source.LimitedNumberSource
|
||||
import net.psforever.objects.guid.source.MaxNumberSource
|
||||
|
||||
class AvatarService1Test extends ActorTest {
|
||||
"AvatarService" should {
|
||||
|
|
@ -512,7 +512,7 @@ class AvatarReleaseTest extends ActorTest {
|
|||
val zone = new Zone("test", new ZoneMap("test-map"), 0) {
|
||||
override def SetupNumberPools() = { AddPool("dynamic", 1 to 10) }
|
||||
}
|
||||
val guid1: NumberPoolHub = new NumberPoolHub(new LimitedNumberSource(100))
|
||||
val guid1: NumberPoolHub = new NumberPoolHub(new MaxNumberSource(100))
|
||||
zone.GUID(guid1)
|
||||
val service = system.actorOf(Props(classOf[AvatarService], zone), "release-test-service")
|
||||
zone.actor = system.spawn(ZoneActor(zone), "release-test-zone")
|
||||
|
|
@ -564,7 +564,7 @@ class AvatarReleaseEarly1Test extends ActorTest {
|
|||
val zone = new Zone("test", new ZoneMap("test-map"), 0) {
|
||||
override def SetupNumberPools() = { AddPool("dynamic", 1 to 10) }
|
||||
}
|
||||
val guid1: NumberPoolHub = new NumberPoolHub(new LimitedNumberSource(100))
|
||||
val guid1: NumberPoolHub = new NumberPoolHub(new MaxNumberSource(100))
|
||||
zone.GUID(guid1)
|
||||
val service = system.actorOf(Props(classOf[AvatarService], zone), "release-test-service")
|
||||
zone.actor = system.spawn(ZoneActor(zone), "release-test-zone")
|
||||
|
|
@ -617,7 +617,7 @@ class AvatarReleaseEarly2Test extends ActorTest {
|
|||
val zone = new Zone("test", new ZoneMap("test-map"), 0) {
|
||||
override def SetupNumberPools() = { AddPool("dynamic", 1 to 10) }
|
||||
}
|
||||
val guid1: NumberPoolHub = new NumberPoolHub(new LimitedNumberSource(100))
|
||||
val guid1: NumberPoolHub = new NumberPoolHub(new MaxNumberSource(100))
|
||||
zone.GUID(guid1)
|
||||
val service = system.actorOf(Props(classOf[AvatarService], zone), "release-test-service")
|
||||
zone.actor = system.spawn(ZoneActor(zone), "release-test-zone")
|
||||
|
|
|
|||
|
|
@ -8,8 +8,11 @@ import akka.actor.{Actor, ActorRef, Cancellable, MDCContextAware}
|
|||
import akka.pattern.ask
|
||||
import akka.util.Timeout
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
import MDCContextAware.Implicits._
|
||||
import net.psforever.objects.locker.LockerContainer
|
||||
import org.log4s.MDC
|
||||
|
||||
import scala.collection.mutable
|
||||
import scala.concurrent.{Await, Future}
|
||||
import scala.concurrent.duration._
|
||||
|
|
@ -359,13 +362,29 @@ class SessionActor extends Actor with MDCContextAware {
|
|||
|
||||
def ValidObject(id: Option[PlanetSideGUID]): Option[PlanetSideGameObject] =
|
||||
continent.GUID(id) match {
|
||||
case Some(obj: LocalProjectile) =>
|
||||
FindProjectileEntry(id.get)
|
||||
|
||||
case Some(_: LocalLockerItem) =>
|
||||
player.avatar.locker.Inventory.hasItem(id.get) match {
|
||||
case out @ Some(_) =>
|
||||
out
|
||||
case None =>
|
||||
//delete stale entity reference from client
|
||||
log.warn(s"${player.Name} has an invalid reference to GUID ${id.get} in zone ${continent.id}")
|
||||
sendResponse(ObjectDeleteMessage(id.get, 0))
|
||||
None
|
||||
}
|
||||
|
||||
case out @ Some(obj) if obj.HasGUID =>
|
||||
out
|
||||
|
||||
case None if id.nonEmpty && id.get != PlanetSideGUID(0) =>
|
||||
//delete stale entity reference from client
|
||||
log.warn(s"Player ${player.Name} has an invalid reference to GUID ${id.get} in zone ${continent.id}.")
|
||||
log.warn(s"${player.Name} has an invalid reference to GUID ${id.get} in zone ${continent.id}")
|
||||
sendResponse(ObjectDeleteMessage(id.get, 0))
|
||||
None
|
||||
|
||||
case _ =>
|
||||
None
|
||||
}
|
||||
|
|
@ -1893,7 +1912,7 @@ class SessionActor extends Actor with MDCContextAware {
|
|||
continent.GUID(mount) match {
|
||||
case Some(obj: Vehicle) =>
|
||||
TotalDriverVehicleControl(obj)
|
||||
UnAccessContents(obj)
|
||||
UnaccessContainer(obj)
|
||||
case _ => ;
|
||||
}
|
||||
PlayerActionsToCancel()
|
||||
|
|
@ -2480,7 +2499,7 @@ class SessionActor extends Actor with MDCContextAware {
|
|||
// the player will receive no messages consistently except the KeepAliveMessage echo
|
||||
keepAliveFunc = KeepAlivePersistence
|
||||
}
|
||||
AccessContents(obj)
|
||||
AccessContainer(obj)
|
||||
UpdateWeaponAtSeatPosition(obj, seat_num)
|
||||
MountingAction(tplayer, obj, seat_num)
|
||||
|
||||
|
|
@ -2516,7 +2535,7 @@ class SessionActor extends Actor with MDCContextAware {
|
|||
DismountAction(tplayer, obj, seat_num)
|
||||
|
||||
case Mountable.CanDismount(obj: Vehicle, seat_num) if obj.Definition == GlobalDefinitions.droppod =>
|
||||
UnAccessContents(obj)
|
||||
UnaccessContainer(obj)
|
||||
DismountAction(tplayer, obj, seat_num)
|
||||
|
||||
case Mountable.CanDismount(obj: Vehicle, seat_num) =>
|
||||
|
|
@ -2524,7 +2543,7 @@ class SessionActor extends Actor with MDCContextAware {
|
|||
if (player_guid == player.GUID) {
|
||||
//disembarking self
|
||||
TotalDriverVehicleControl(obj)
|
||||
UnAccessContents(obj)
|
||||
UnaccessContainer(obj)
|
||||
DismountAction(tplayer, obj, seat_num)
|
||||
} else {
|
||||
continent.VehicleEvents ! VehicleServiceMessage(
|
||||
|
|
@ -2735,7 +2754,7 @@ class SessionActor extends Actor with MDCContextAware {
|
|||
if (tplayer_guid == guid) {
|
||||
continent.GUID(vehicle_guid) match {
|
||||
case Some(obj: Vehicle) =>
|
||||
UnAccessContents(obj)
|
||||
UnaccessContainer(obj)
|
||||
case _ => ;
|
||||
}
|
||||
}
|
||||
|
|
@ -3779,9 +3798,7 @@ class SessionActor extends Actor with MDCContextAware {
|
|||
val guid = player.GUID
|
||||
sendResponse(UnuseItemMessage(guid, veh.GUID))
|
||||
sendResponse(UnuseItemMessage(guid, guid))
|
||||
veh.AccessingTrunk = None
|
||||
UnAccessContents(veh)
|
||||
accessedContainer = None
|
||||
UnaccessContainer(veh)
|
||||
}
|
||||
case Some(container) => //just in case
|
||||
if (isMovingPlus) {
|
||||
|
|
@ -3791,7 +3808,7 @@ class SessionActor extends Actor with MDCContextAware {
|
|||
sendResponse(UnuseItemMessage(guid, container.GUID))
|
||||
}
|
||||
sendResponse(UnuseItemMessage(guid, guid))
|
||||
accessedContainer = None
|
||||
UnaccessContainer(container)
|
||||
}
|
||||
case None => ;
|
||||
}
|
||||
|
|
@ -4384,25 +4401,20 @@ class SessionActor extends Actor with MDCContextAware {
|
|||
case Some(obj: Equipment) =>
|
||||
FindEquipmentToDelete(object_guid, obj)
|
||||
|
||||
case Some(_: LocalProjectile) =>
|
||||
FindProjectileEntry(object_guid) match {
|
||||
case Some(projectile) =>
|
||||
if (projectile.isResolved) {
|
||||
log.warn(
|
||||
s"RequestDestroy: tried to clean up projectile ${object_guid.guid} but it was already resolved"
|
||||
)
|
||||
} else {
|
||||
projectile.Miss()
|
||||
if (projectile.profile.ExistsOnRemoteClients && projectile.HasGUID) {
|
||||
continent.AvatarEvents ! AvatarServiceMessage(
|
||||
continent.id,
|
||||
AvatarAction.ProjectileExplodes(player.GUID, projectile.GUID, projectile)
|
||||
)
|
||||
taskResolver ! UnregisterProjectile(projectile)
|
||||
}
|
||||
}
|
||||
case None =>
|
||||
log.warn(s"RequestDestroy: projectile ${object_guid.guid} has never been fired")
|
||||
case Some(obj: Projectile) =>
|
||||
if (obj.isResolved) {
|
||||
log.warn(
|
||||
s"RequestDestroy: tried to clean up projectile ${object_guid.guid} but it was already resolved"
|
||||
)
|
||||
} else {
|
||||
obj.Miss()
|
||||
if (obj.profile.ExistsOnRemoteClients && obj.HasGUID) {
|
||||
continent.AvatarEvents ! AvatarServiceMessage(
|
||||
continent.id,
|
||||
AvatarAction.ProjectileExplodes(player.GUID, obj.GUID, obj)
|
||||
)
|
||||
taskResolver ! UnregisterProjectile(obj)
|
||||
}
|
||||
}
|
||||
|
||||
case Some(obj: BoomerDeployable) =>
|
||||
|
|
@ -4463,7 +4475,7 @@ class SessionActor extends Actor with MDCContextAware {
|
|||
Some(destination: PlanetSideServerObject with Container),
|
||||
Some(item: Equipment)
|
||||
) =>
|
||||
source.Actor ! Containable.MoveItem(destination, item, dest)
|
||||
ContainableMoveItem(taskResolver, player.Name, source, destination, item, dest)
|
||||
case (None, _, _) =>
|
||||
log.error(s"MoveItem: wanted to move $item_guid from $source_guid, but could not find source object")
|
||||
case (_, None, _) =>
|
||||
|
|
@ -4500,7 +4512,7 @@ class SessionActor extends Actor with MDCContextAware {
|
|||
destination.Fit(item)
|
||||
) match {
|
||||
case (Some((source, Some(_))), Some(dest)) =>
|
||||
source.Actor ! Containable.MoveItem(destination, item, dest)
|
||||
ContainableMoveItem(taskResolver, player.Name, source, destination, item, dest)
|
||||
case (None, _) =>
|
||||
log.error(s"LootItem: can not find where $item is put currently")
|
||||
case (_, None) =>
|
||||
|
|
@ -4610,7 +4622,7 @@ class SessionActor extends Actor with MDCContextAware {
|
|||
itemType
|
||||
)
|
||||
)
|
||||
accessedContainer = Some(obj)
|
||||
AccessContainer(obj)
|
||||
}
|
||||
} else if (!unk3 && player.isAlive) { //potential kit use
|
||||
ValidObject(item_used_guid) match {
|
||||
|
|
@ -4759,13 +4771,12 @@ class SessionActor extends Actor with MDCContextAware {
|
|||
case None if locker.Faction == player.Faction || !locker.HackedBy.isEmpty =>
|
||||
log.trace(s"UseItem: ${player.Name} accessing a locker")
|
||||
CancelZoningProcessWithDescriptiveReason("cancel_use")
|
||||
val container = player.avatar.locker
|
||||
accessedContainer = Some(container)
|
||||
val playerLocker = player.avatar.locker
|
||||
sendResponse(
|
||||
UseItemMessage(
|
||||
avatar_guid,
|
||||
item_used_guid,
|
||||
container.GUID,
|
||||
playerLocker.GUID,
|
||||
unk2,
|
||||
unk3,
|
||||
unk4,
|
||||
|
|
@ -4776,6 +4787,7 @@ class SessionActor extends Actor with MDCContextAware {
|
|||
456
|
||||
)
|
||||
)
|
||||
AccessContainer(playerLocker)
|
||||
case _ => ;
|
||||
}
|
||||
|
||||
|
|
@ -4827,8 +4839,7 @@ class SessionActor extends Actor with MDCContextAware {
|
|||
) {
|
||||
CancelZoningProcessWithDescriptiveReason("cancel_use")
|
||||
obj.AccessingTrunk = player.GUID
|
||||
accessedContainer = Some(obj)
|
||||
AccessContents(obj)
|
||||
AccessContainer(obj)
|
||||
sendResponse(
|
||||
UseItemMessage(
|
||||
avatar_guid,
|
||||
|
|
@ -5044,19 +5055,16 @@ class SessionActor extends Actor with MDCContextAware {
|
|||
|
||||
case msg @ UnuseItemMessage(player_guid, object_guid) =>
|
||||
log.info(s"UnuseItem: $msg")
|
||||
//TODO check for existing accessedContainer value?
|
||||
ValidObject(object_guid) match {
|
||||
case Some(obj: Vehicle) =>
|
||||
if (obj.AccessingTrunk.contains(player.GUID)) {
|
||||
obj.AccessingTrunk = None
|
||||
UnAccessContents(obj)
|
||||
}
|
||||
case Some(obj: Player) =>
|
||||
UnaccessContainer(obj)
|
||||
TryDisposeOfLootedCorpse(obj)
|
||||
|
||||
case Some(obj: Container) =>
|
||||
UnaccessContainer(obj)
|
||||
|
||||
case _ => ;
|
||||
}
|
||||
accessedContainer = None
|
||||
|
||||
case msg @ DeployObjectMessage(guid, unk1, pos, orient, unk2) =>
|
||||
log.info(s"DeployObject: $msg")
|
||||
|
|
@ -5757,7 +5765,8 @@ class SessionActor extends Actor with MDCContextAware {
|
|||
}
|
||||
|
||||
/**
|
||||
* Construct tasking that registers all aspects of a `Player` avatar.
|
||||
* Construct tasking that registers all aspects of a `Player` avatar
|
||||
* as if that player is only just being introduced.
|
||||
* `Players` are complex objects that contain a variety of other register-able objects and each of these objects much be handled.
|
||||
* @param tplayer the avatar `Player`
|
||||
* @return a `TaskResolver.GiveTask` message
|
||||
|
|
@ -5785,7 +5794,7 @@ class SessionActor extends Actor with MDCContextAware {
|
|||
}
|
||||
|
||||
override def onFailure(ex: Throwable): Unit = {
|
||||
localAnnounce ! PlayerFailedToLoad(localPlayer) //alerts WorldSessionActor
|
||||
localAnnounce ! PlayerFailedToLoad(localPlayer) //alerts SessionActor
|
||||
}
|
||||
},
|
||||
List(GUIDTask.RegisterAvatar(tplayer)(continent.GUID))
|
||||
|
|
@ -5793,7 +5802,8 @@ class SessionActor extends Actor with MDCContextAware {
|
|||
}
|
||||
|
||||
/**
|
||||
* Construct tasking that registers all aspects of a `Player` avatar.
|
||||
* Construct tasking that registers all aspects of a `Player` avatar
|
||||
* as if that player was already introduced and is just being renewed.
|
||||
* `Players` are complex objects that contain a variety of other register-able objects and each of these objects much be handled.
|
||||
* @param tplayer the avatar `Player`
|
||||
* @return a `TaskResolver.GiveTask` message
|
||||
|
|
@ -5872,7 +5882,7 @@ class SessionActor extends Actor with MDCContextAware {
|
|||
* Additionally, the driver is only partially associated with the vehicle at this time.
|
||||
* `interstellarFerry` is properly keeping track of the vehicle during the transition
|
||||
* and the user who is the driver (second param) is properly seated
|
||||
* but the said driver does not know about the vehicle through his usual convention - VehicleSeated` - yet.
|
||||
* but the said driver does not know about the vehicle through his usual convention - `VehicleSeated` - yet.
|
||||
* @see `GlobalDefinitions.droppod`
|
||||
* @see `GUIDTask.RegisterObjectTask`
|
||||
* @see `interstellarFerry`
|
||||
|
|
@ -5975,10 +5985,10 @@ class SessionActor extends Actor with MDCContextAware {
|
|||
}
|
||||
|
||||
override def onFailure(ex: Throwable): Unit = {
|
||||
localAnnounce ! PlayerFailedToLoad(localDriver) //alerts WorldSessionActor
|
||||
localAnnounce ! PlayerFailedToLoad(localDriver) //alerts SessionActor
|
||||
}
|
||||
},
|
||||
List(GUIDTask.RegisterAvatar(driver)(continent.GUID), GUIDTask.RegisterVehicle(obj)(continent.GUID))
|
||||
List(RegisterNewAvatar(driver), GUIDTask.RegisterVehicle(obj)(continent.GUID))
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -6115,50 +6125,106 @@ class SessionActor extends Actor with MDCContextAware {
|
|||
)
|
||||
}
|
||||
|
||||
def AccessContainer(container: Container): Unit = {
|
||||
container match {
|
||||
case v: Vehicle =>
|
||||
AccessVehicleContents(v)
|
||||
case o: LockerContainer =>
|
||||
AccessGenericContainer(o)
|
||||
case p: PlanetSideServerObject with Container =>
|
||||
accessedContainer = Some(p)
|
||||
case _ => ;
|
||||
}
|
||||
}
|
||||
|
||||
def AccessGenericContainer(container: PlanetSideServerObject with Container): Unit = {
|
||||
accessedContainer = Some(container)
|
||||
DisplayContainerContents(container.GUID, container)
|
||||
}
|
||||
|
||||
/**
|
||||
* Common preparation for interfacing with a vehicle.
|
||||
* Join a vehicle-specific group for shared updates.
|
||||
* Construct every object in the vehicle's inventory for shared manipulation updates.
|
||||
* @param vehicle the vehicle
|
||||
*/
|
||||
def AccessContents(vehicle: Vehicle): Unit = {
|
||||
AccessContentsChannel(vehicle)
|
||||
val parent_guid = vehicle.GUID
|
||||
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
|
||||
)
|
||||
)
|
||||
})
|
||||
def AccessVehicleContents(vehicle: Vehicle): Unit = {
|
||||
accessedContainer = Some(vehicle)
|
||||
if(vehicle.AccessingTrunk.isEmpty) {
|
||||
vehicle.AccessingTrunk = Some(player.GUID)
|
||||
}
|
||||
AccessVehicleContainerChannel(vehicle)
|
||||
DisplayContainerContents(vehicle.GUID, vehicle)
|
||||
}
|
||||
|
||||
def AccessContentsChannel(container: PlanetSideServerObject): Unit = {
|
||||
def AccessVehicleContainerChannel(container: PlanetSideServerObject): Unit = {
|
||||
continent.VehicleEvents ! Service.Join(s"${container.Actor}")
|
||||
}
|
||||
|
||||
def DisplayContainerContents(containerId: PlanetSideGUID, container: Container): Unit = {
|
||||
container.Inventory.Items.foreach(entry => {
|
||||
val obj = entry.obj
|
||||
val objDef = obj.Definition
|
||||
sendResponse(
|
||||
ObjectCreateDetailedMessage(
|
||||
objDef.ObjectId,
|
||||
obj.GUID,
|
||||
ObjectCreateMessageParent(containerId, entry.start),
|
||||
objDef.Packet.DetailedConstructorData(obj).get
|
||||
)
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
def UnaccessContainer(): Unit = {
|
||||
accessedContainer match {
|
||||
case Some(container) => UnaccessContainer(container)
|
||||
case _ => ;
|
||||
}
|
||||
}
|
||||
|
||||
def UnaccessContainer(container: Container): Unit = {
|
||||
container match {
|
||||
case v: Vehicle =>
|
||||
UnaccessVehicleContainer(v)
|
||||
case o: LockerContainer =>
|
||||
UnaccessGenericContainer(o)
|
||||
case _: PlanetSideServerObject with Container =>
|
||||
accessedContainer = None
|
||||
case _ => ;
|
||||
}
|
||||
}
|
||||
|
||||
def UnaccessGenericContainer(container: Container): Unit = {
|
||||
accessedContainer = None
|
||||
HideContainerContents(container)
|
||||
}
|
||||
|
||||
/**
|
||||
* Common preparation for disengaging from a vehicle.
|
||||
* Leave the vehicle-specific group that was used for shared updates.
|
||||
* Deconstruct every object in the vehicle's inventory.
|
||||
* @param vehicle the vehicle
|
||||
*/
|
||||
def UnAccessContents(vehicle: Vehicle): Unit = {
|
||||
continent.VehicleEvents ! Service.Leave(Some(s"${vehicle.Actor}"))
|
||||
vehicle.Trunk.Items.foreach(entry => {
|
||||
sendResponse(ObjectDeleteMessage(entry.obj.GUID, 0))
|
||||
})
|
||||
def UnaccessVehicleContainer(vehicle: Vehicle): Unit = {
|
||||
accessedContainer = None
|
||||
if(vehicle.AccessingTrunk.contains(player.GUID)) {
|
||||
vehicle.AccessingTrunk = None
|
||||
}
|
||||
UnaccessVehicleContainerChannel(vehicle)
|
||||
HideContainerContents(vehicle)
|
||||
}
|
||||
|
||||
def UnAccessContentsChannel(container: PlanetSideServerObject): Unit = {
|
||||
def UnaccessVehicleContainerChannel(container: PlanetSideServerObject): Unit = {
|
||||
continent.VehicleEvents ! Service.Leave(Some(s"${container.Actor}"))
|
||||
}
|
||||
|
||||
def HideContainerContents(container: Container): Unit = {
|
||||
container.Inventory.Items.foreach(entry => {
|
||||
sendResponse(ObjectDeleteMessage(entry.obj.GUID, 0))
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Check two locations for a controlled piece of equipment that is associated with the `player`.<br>
|
||||
* <br>
|
||||
|
|
@ -6813,19 +6879,7 @@ class SessionActor extends Actor with MDCContextAware {
|
|||
progressBarUpdate.cancel()
|
||||
progressBarValue = None
|
||||
lastTerminalOrderFulfillment = true
|
||||
accessedContainer match {
|
||||
case Some(obj: Vehicle) =>
|
||||
if (obj.AccessingTrunk.contains(player.GUID)) {
|
||||
obj.AccessingTrunk = None
|
||||
UnAccessContents(obj)
|
||||
}
|
||||
accessedContainer = None
|
||||
|
||||
case Some(_) =>
|
||||
accessedContainer = None
|
||||
|
||||
case None => ;
|
||||
}
|
||||
UnaccessContainer()
|
||||
prefire.orElse(shooting) match {
|
||||
case Some(guid) =>
|
||||
sendResponse(ChangeFireStateMessage_Stop(guid))
|
||||
|
|
@ -7030,7 +7084,7 @@ class SessionActor extends Actor with MDCContextAware {
|
|||
* and is permitted to introduce the avatar to the vehicle's internal settings in a similar way.
|
||||
* Neither the player avatar nor the vehicle should be reconstructed before the next zone load operation
|
||||
* to avoid damaging the critical setup of this function.
|
||||
* @see `AccessContents`
|
||||
* @see `AccessContainer`
|
||||
* @see `UpdateWeaponAtSeatPosition`
|
||||
* @param tplayer the player avatar seated in the vehicle's seat
|
||||
* @param vehicle the vehicle the player is riding
|
||||
|
|
@ -7046,7 +7100,7 @@ class SessionActor extends Actor with MDCContextAware {
|
|||
sendResponse(ObjectCreateDetailedMessage(pdef.ObjectId, pguid, pdata))
|
||||
if (seat == 0 || vehicle.Seats(seat).ControlledWeapon.nonEmpty) {
|
||||
sendResponse(ObjectAttachMessage(vguid, pguid, seat))
|
||||
AccessContents(vehicle)
|
||||
AccessContainer(vehicle)
|
||||
UpdateWeaponAtSeatPosition(vehicle, seat)
|
||||
} else {
|
||||
interimUngunnedVehicle = Some(vguid)
|
||||
|
|
@ -7120,7 +7174,7 @@ class SessionActor extends Actor with MDCContextAware {
|
|||
//log.info(s"AvatarRejoin: $vguid -> $vdata")
|
||||
if (seat == 0 || vehicle.Seats(seat).ControlledWeapon.nonEmpty) {
|
||||
sendResponse(ObjectAttachMessage(vguid, pguid, seat))
|
||||
AccessContents(vehicle)
|
||||
AccessContainer(vehicle)
|
||||
UpdateWeaponAtSeatPosition(vehicle, seat)
|
||||
} else {
|
||||
interimUngunnedVehicle = Some(vguid)
|
||||
|
|
@ -8203,6 +8257,7 @@ class SessionActor extends Actor with MDCContextAware {
|
|||
/**
|
||||
* A simple object searching algorithm that is limited to containers currently known and accessible by the player.
|
||||
* If all relatively local containers are checked and the object is not found,
|
||||
* the player's locker inventory will be checked, and then
|
||||
* the game environment (items on the ground) will be checked too.
|
||||
* If the target object is discovered, it is removed from its current location and is completely destroyed.
|
||||
* @see `RequestDestroyMessage`<br>
|
||||
|
|
@ -8218,8 +8273,7 @@ class SessionActor extends Actor with MDCContextAware {
|
|||
: PlanetSideServerObject with Container => Option[(PlanetSideServerObject with Container, Option[Int])] =
|
||||
FindInLocalContainer(object_guid)
|
||||
|
||||
findFunc(player.avatar.locker)
|
||||
.orElse(findFunc(player))
|
||||
findFunc(player)
|
||||
.orElse(accessedContainer match {
|
||||
case Some(parent: PlanetSideServerObject) =>
|
||||
findFunc(parent)
|
||||
|
|
@ -8239,7 +8293,11 @@ class SessionActor extends Actor with MDCContextAware {
|
|||
true
|
||||
|
||||
case _ =>
|
||||
if (continent.EquipmentOnGround.contains(obj)) {
|
||||
if (player.avatar.locker.Inventory.Remove(object_guid)) {
|
||||
sendResponse(ObjectDeleteMessage(object_guid, 0))
|
||||
log.info(s"RequestDestroy: equipment $obj")
|
||||
true
|
||||
} else if (continent.EquipmentOnGround.contains(obj)) {
|
||||
obj.Position = Vector3.Zero
|
||||
continent.Ground ! Zone.Ground.RemoveItem(object_guid)
|
||||
continent.AvatarEvents ! AvatarServiceMessage.Ground(RemoverActor.ClearSpecific(List(obj), continent))
|
||||
|
|
@ -8440,7 +8498,7 @@ class SessionActor extends Actor with MDCContextAware {
|
|||
if (player.isBackpack) {
|
||||
session = session.copy(player = targetPlayer)
|
||||
taskThenZoneChange(
|
||||
GUIDTask.UnregisterLocker(original.avatar.locker)(continent.GUID),
|
||||
GUIDTask.UnregisterObjectTask(original.avatar.locker)(continent.GUID),
|
||||
InterstellarClusterService.FindZone(_.id == zoneId, context.self)
|
||||
)
|
||||
} else if (player.HasGUID) {
|
||||
|
|
@ -8545,12 +8603,12 @@ class SessionActor extends Actor with MDCContextAware {
|
|||
InterstellarClusterService.FindZone(_.id == zoneId, context.self)
|
||||
)
|
||||
} else {
|
||||
UnAccessContents(vehicle)
|
||||
UnaccessContainer(vehicle)
|
||||
LoadZoneCommonTransferActivity()
|
||||
player.VehicleSeated = vehicle.GUID
|
||||
player.Continent = zoneId //forward-set the continent id to perform a test
|
||||
interstellarFerryTopLevelGUID =
|
||||
(if (
|
||||
if (
|
||||
manifest.passengers.isEmpty && manifest.cargo.count { case (name, _) => !name.equals("MISSING_DRIVER") } == 0
|
||||
) {
|
||||
//do not delete if vehicle has passengers or cargo
|
||||
|
|
@ -8561,7 +8619,7 @@ class SessionActor extends Actor with MDCContextAware {
|
|||
None
|
||||
} else {
|
||||
Some(topLevel)
|
||||
})
|
||||
}
|
||||
//unregister vehicle and driver whole + GiveWorld
|
||||
continent.Transport ! Zone.Vehicle.Despawn(vehicle)
|
||||
taskThenZoneChange(
|
||||
|
|
@ -8586,12 +8644,12 @@ class SessionActor extends Actor with MDCContextAware {
|
|||
* A reference to the top-level ferrying vehicle's former globally unique identifier has been retained for this purpose.
|
||||
* This vehicle can be deleted for everyone if no more work can be detected.
|
||||
*
|
||||
* @see `GUIDTask.UnregisterAvatar`
|
||||
* @see `GUIDTask.UnregisterPlayer`
|
||||
* @see `LoadZoneCommonTransferActivity`
|
||||
* @see `Vehicles.AllGatedOccupantsInSameZone`
|
||||
* @see `PlayerLoaded`
|
||||
* @see `TaskBeforeZoneChange`
|
||||
* @see `UnAccessContents`
|
||||
* @see `UnaccessContainer`
|
||||
* @param vehicle the target vehicle being moved around
|
||||
* @param zoneId the zone in which the vehicle and driver will be placed
|
||||
* @return a tuple composed of an `ActorRef` destination and a message to send to that destination
|
||||
|
|
@ -9209,7 +9267,7 @@ class SessionActor extends Actor with MDCContextAware {
|
|||
}
|
||||
|
||||
/**
|
||||
* The upstream counter accumulates when the server receives sp[ecific messages from the client.
|
||||
* The upstream counter accumulates when the server receives specific messages from the client.
|
||||
* It counts upwards until it reach maximum value, and then starts over.
|
||||
* When it starts over, which should take an exceptionally long time to achieve,
|
||||
* it starts counting at one rather than zero.
|
||||
|
|
@ -9265,7 +9323,7 @@ class SessionActor extends Actor with MDCContextAware {
|
|||
case (Some(vehicle: Vehicle), Some(vguid), Some(seat)) =>
|
||||
//sit down
|
||||
sendResponse(ObjectAttachMessage(vguid, pguid, seat))
|
||||
AccessContents(vehicle)
|
||||
AccessContainer(vehicle)
|
||||
keepAliveFunc = KeepAlivePersistence
|
||||
case _ => ;
|
||||
//we can't find a vehicle? and we're still here? that's bad
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import akka.util.Timeout
|
|||
import net.psforever.objects.equipment.{Ammo, Equipment}
|
||||
import net.psforever.objects.guid.{GUIDTask, Task, TaskResolver}
|
||||
import net.psforever.objects.inventory.{Container, InventoryItem}
|
||||
import net.psforever.objects.locker.LockerContainer
|
||||
import net.psforever.objects.serverobject.PlanetSideServerObject
|
||||
import net.psforever.objects.serverobject.containable.Containable
|
||||
import net.psforever.objects.zones.Zone
|
||||
|
|
@ -504,6 +505,215 @@ object WorldSession {
|
|||
result
|
||||
}
|
||||
|
||||
/**
|
||||
* Move an item from one container to another.
|
||||
* If the source or if the destination is a kind of container called a `LockerContainer`,
|
||||
* then a special procedure for the movement of the item must be respected.
|
||||
* If the source and the destination are both `LockerContainer` objects, however,
|
||||
* the normal operations for moving an item may be executed.
|
||||
* @see `ActorRef`
|
||||
* @see `Containable.MoveItem`
|
||||
* @see `Container`
|
||||
* @see `Equipment`
|
||||
* @see `LockerContainer`
|
||||
* @see `RemoveEquipmentFromLockerContainer`
|
||||
* @see `StowEquipmentInLockerContainer`
|
||||
* @see `TaskResolver`
|
||||
* @param taskResolver na
|
||||
* @param toChannel broadcast channel name for a manual packet callback
|
||||
* @param source the container in which the item is to be removed
|
||||
* @param destination the container into which the item is to be placed
|
||||
* @param item the item
|
||||
* @param dest where in the destination container the item is being placed
|
||||
*/
|
||||
def ContainableMoveItem(
|
||||
taskResolver: ActorRef,
|
||||
toChannel: String,
|
||||
source: PlanetSideServerObject with Container,
|
||||
destination: PlanetSideServerObject with Container,
|
||||
item: Equipment,
|
||||
dest: Int
|
||||
) : Unit = {
|
||||
(source, destination) match {
|
||||
case (locker: LockerContainer, _) if !destination.isInstanceOf[LockerContainer] =>
|
||||
RemoveEquipmentFromLockerContainer(taskResolver, toChannel, locker, destination, item, dest)
|
||||
case (_, locker: LockerContainer) =>
|
||||
StowEquipmentInLockerContainer(taskResolver, toChannel, source, locker, item, dest)
|
||||
case _ =>
|
||||
source.Actor ! Containable.MoveItem(destination, item, dest)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Move an item into a player's locker inventory.
|
||||
* Handle any swap item that might become involved in the transfer.
|
||||
* Failure of this process is not supported and may lead to irregular behavior.
|
||||
* @see `ActorRef`
|
||||
* @see `AvatarAction.ObjectDelete`
|
||||
* @see `AvatarServiceMessage`
|
||||
* @see `Containable.MoveItem`
|
||||
* @see `Container`
|
||||
* @see `Equipment`
|
||||
* @see `GridInventory.CheckCollisionsVar`
|
||||
* @see `GUIDTask.RegisterEquipment`
|
||||
* @see `GUIDTask.UnregisterEquipment`
|
||||
* @see `IdentifiableEntity.Invalidate`
|
||||
* @see `LockerContainer`
|
||||
* @see `Service`
|
||||
* @see `Task`
|
||||
* @see `TaskResolver`
|
||||
* @see `TaskResolver.GiveTask`
|
||||
* @see `Zone.AvatarEvents`
|
||||
* @param taskResolver na
|
||||
* @param toChannel broadcast channel name for a manual packet callback
|
||||
* @param source the container in which the item is to be removed
|
||||
* @param destination the container into which the item is to be placed
|
||||
* @param item the item
|
||||
* @param dest where in the destination container the item is being placed
|
||||
*/
|
||||
def StowEquipmentInLockerContainer(
|
||||
taskResolver: ActorRef,
|
||||
toChannel: String,
|
||||
source: PlanetSideServerObject with Container,
|
||||
destination: PlanetSideServerObject with Container,
|
||||
item: Equipment,
|
||||
dest: Int
|
||||
): Unit = {
|
||||
val registrationTask = GUIDTask.UnregisterEquipment(item)(source.Zone.GUID)
|
||||
//check for the existence of a swap item - account for that in advance
|
||||
val (subtasks, swapItemGUID): (List[TaskResolver.GiveTask], Option[PlanetSideGUID]) = {
|
||||
val tile = item.Definition.Tile
|
||||
destination.Inventory.CheckCollisionsVar(dest, tile.Width, tile.Height)
|
||||
} match {
|
||||
case Success(Nil) =>
|
||||
//no swap item
|
||||
(List(registrationTask), None)
|
||||
case Success(List(swapEntry: InventoryItem)) =>
|
||||
//the swap item is to be registered to the source's zone
|
||||
/*
|
||||
destination is a locker container that has its own internal unique number system
|
||||
the swap item is currently registered to this system
|
||||
the swap item will be moved into the system in which the source operates
|
||||
to facilitate the transfer, the item needs to be partially unregistered from the destination's system
|
||||
to facilitate the transfer, the item needs to be preemptively registered to the source's system
|
||||
invalidating the current unique number is sufficient for both of these steps
|
||||
*/
|
||||
val swapItem = swapEntry.obj
|
||||
swapItem.Invalidate()
|
||||
(List(GUIDTask.RegisterEquipment(swapItem)(source.Zone.GUID), registrationTask), Some(swapItem.GUID))
|
||||
case _ =>
|
||||
//too many swap items or other error; this attempt will probably fail
|
||||
(Nil, None)
|
||||
}
|
||||
taskResolver ! TaskResolver.GiveTask(
|
||||
new Task() {
|
||||
val localGUID = swapItemGUID //the swap item's original GUID, if any swap item
|
||||
val localChannel = toChannel
|
||||
val localSource = source
|
||||
val localDestination = destination
|
||||
val localItem = item
|
||||
val localSlot = dest
|
||||
|
||||
override def Description: String = s"unregistering $localItem before stowing in $localDestination"
|
||||
|
||||
override def isComplete: Task.Resolution.Value = {
|
||||
if (localItem.HasGUID && localDestination.Find(localItem).contains(localSlot)) {
|
||||
Task.Resolution.Success
|
||||
} else {
|
||||
Task.Resolution.Incomplete
|
||||
}
|
||||
}
|
||||
|
||||
def Execute(resolver: ActorRef): Unit = {
|
||||
localGUID match {
|
||||
case Some(guid) =>
|
||||
//see LockerContainerControl.RemoveItemFromSlotCallback
|
||||
val zone = localSource.Zone
|
||||
zone.AvatarEvents ! AvatarServiceMessage(localChannel, AvatarAction.ObjectDelete(Service.defaultPlayerGUID, guid))
|
||||
case None => ;
|
||||
}
|
||||
localSource.Actor ! Containable.MoveItem(localDestination, localItem, localSlot)
|
||||
resolver ! Success(this)
|
||||
}
|
||||
},
|
||||
subtasks
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove an item from a player's locker inventory.
|
||||
* Failure of this process is not supported and may lead to irregular behavior.
|
||||
* @see `ActorRef`
|
||||
* @see `AvatarAction.ObjectDelete`
|
||||
* @see `AvatarServiceMessage`
|
||||
* @see `Containable.MoveItem`
|
||||
* @see `Container`
|
||||
* @see `Equipment`
|
||||
* @see `GridInventory.CheckCollisionsVar`
|
||||
* @see `GUIDTask.RegisterEquipment`
|
||||
* @see `GUIDTask.UnregisterEquipment`
|
||||
* @see `IdentifiableEntity.Invalidate`
|
||||
* @see `LockerContainer`
|
||||
* @see `Service`
|
||||
* @see `Task`
|
||||
* @see `TaskResolver`
|
||||
* @see `TaskResolver.GiveTask`
|
||||
* @see `Zone.AvatarEvents`
|
||||
* @param taskResolver na
|
||||
* @param toChannel broadcast channel name for a manual packet callback
|
||||
* @param source the container in which the item is to be removed
|
||||
* @param destination the container into which the item is to be placed
|
||||
* @param item the item
|
||||
* @param dest where in the destination container the item is being placed
|
||||
*/
|
||||
def RemoveEquipmentFromLockerContainer(
|
||||
taskResolver: ActorRef,
|
||||
toChannel: String,
|
||||
source: PlanetSideServerObject with Container,
|
||||
destination: PlanetSideServerObject with Container,
|
||||
item: Equipment,
|
||||
dest: Int
|
||||
): Unit = {
|
||||
taskResolver ! TaskResolver.GiveTask(
|
||||
new Task() {
|
||||
val localGUID = item.GUID //original GUID
|
||||
val localChannel = toChannel
|
||||
val localSource = source
|
||||
val localDestination = destination
|
||||
val localItem = item
|
||||
val localSlot = dest
|
||||
/*
|
||||
source is a locker container that has its own internal unique number system
|
||||
the item is currently registered to this system
|
||||
the item will be moved into the system in which the destination operates
|
||||
to facilitate the transfer, the item needs to be partially unregistered from the source's system
|
||||
to facilitate the transfer, the item needs to be preemptively registered to the destination's system
|
||||
invalidating the current unique number is sufficient for both of these steps
|
||||
*/
|
||||
localItem.Invalidate()
|
||||
|
||||
override def Description: String = s"registering $localItem in ${localDestination.Zone.id} before removing from $localSource"
|
||||
|
||||
override def isComplete: Task.Resolution.Value = {
|
||||
if (localItem.HasGUID && localDestination.Find(localItem).isEmpty) {
|
||||
Task.Resolution.Success
|
||||
} else {
|
||||
Task.Resolution.Incomplete
|
||||
}
|
||||
}
|
||||
|
||||
def Execute(resolver: ActorRef): Unit = {
|
||||
val zone = localSource.Zone
|
||||
//see LockerContainerControl.RemoveItemFromSlotCallback
|
||||
zone.AvatarEvents ! AvatarServiceMessage(localChannel, AvatarAction.ObjectDelete(Service.defaultPlayerGUID, localGUID))
|
||||
localSource.Actor ! Containable.MoveItem(localDestination, localItem, localSlot)
|
||||
resolver ! Success(this)
|
||||
}
|
||||
},
|
||||
List(GUIDTask.RegisterEquipment(item)(destination.Zone.GUID))
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* If a timeout occurs on the manipulation, declare a terminal transaction failure.
|
||||
* @see `AskTimeoutException`
|
||||
|
|
|
|||
37
src/main/scala/net/psforever/objects/LocalLockerItem.scala
Normal file
37
src/main/scala/net/psforever/objects/LocalLockerItem.scala
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
// Copyright (c) 2020 PSForever
|
||||
package net.psforever.objects
|
||||
|
||||
import akka.actor.ActorContext
|
||||
import net.psforever.objects.serverobject.PlanetSideServerObject
|
||||
import net.psforever.types.PlanetSideEmpire
|
||||
|
||||
/**
|
||||
* A `LocalLockerItem` is a server-side object designed to populate a fake unshared space within a shared space.
|
||||
* It is a placeholder intended to block out the existence of locker objects that may or may not exist.
|
||||
* All clients reserve the same internal range of user-generated GUID's from 40150 to 40449, inclusive.
|
||||
* All clients recognize this same range independent of each other as "equipment in their own locker."
|
||||
* The GUID's in this locker-space can be reflected onto the zone GUID.
|
||||
* The item of that GUID may exist to the client.
|
||||
* The item of that GUID does not formally exist to the server, but it can be searched.
|
||||
* @see `Zone.MakeReservedObjects`
|
||||
*/
|
||||
class LocalLockerItem extends PlanetSideServerObject {
|
||||
def Faction = PlanetSideEmpire.NEUTRAL
|
||||
|
||||
def Definition = LocalLockerItem.local
|
||||
}
|
||||
|
||||
object LocalLockerItem {
|
||||
import net.psforever.objects.definition.ObjectDefinition
|
||||
def local = new ObjectDefinition(0) { Name = "locker-equipment" }
|
||||
|
||||
/**
|
||||
* Instantiate and configure a `LocalProjectile` object.
|
||||
* @param id the unique id that will be assigned to this entity
|
||||
* @param context a context to allow the object to properly set up `ActorSystem` functionality
|
||||
* @return the `LocalProjectile` object
|
||||
*/
|
||||
def Constructor(id: Int, context: ActorContext): LocalLockerItem = {
|
||||
new LocalLockerItem()
|
||||
}
|
||||
}
|
||||
|
|
@ -2,8 +2,10 @@ package net.psforever.objects.avatar
|
|||
|
||||
import net.psforever.objects.definition.{AvatarDefinition, BasicDefinition}
|
||||
import net.psforever.objects.equipment.{EquipmentSize, EquipmentSlot}
|
||||
import net.psforever.objects.inventory.LocallyRegisteredInventory
|
||||
import net.psforever.objects.loadouts.{Loadout, SquadLoadout}
|
||||
import net.psforever.objects.{GlobalDefinitions, LockerContainer, LockerEquipment, OffhandEquipmentSlot}
|
||||
import net.psforever.objects.locker.{LockerContainer, LockerEquipment}
|
||||
import net.psforever.objects.{GlobalDefinitions, OffhandEquipmentSlot}
|
||||
import net.psforever.types._
|
||||
import org.joda.time.{Duration, LocalDateTime, Seconds}
|
||||
|
||||
|
|
@ -82,7 +84,11 @@ case class Avatar(
|
|||
loadouts: Seq[Option[Loadout]] = Seq.fill(15)(None),
|
||||
squadLoadouts: Seq[Option[SquadLoadout]] = Seq.fill(10)(None),
|
||||
implants: Seq[Option[Implant]] = Seq(None, None, None),
|
||||
locker: LockerContainer = new LockerContainer(), // TODO var bad
|
||||
locker: LockerContainer = new LockerContainer({
|
||||
val inv = new LocallyRegisteredInventory(numbers = 40150 until 40450) // TODO var bad
|
||||
inv.Resize(30,20)
|
||||
inv
|
||||
}),
|
||||
deployables: DeployableToolbox = new DeployableToolbox(), // TODO var bad
|
||||
lookingForSquad: Boolean = false,
|
||||
var vehicle: Option[PlanetSideGUID] = None, // TODO var bad
|
||||
|
|
|
|||
|
|
@ -27,6 +27,8 @@ import net.psforever.services.{RemoverActor, Service}
|
|||
import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage}
|
||||
import net.psforever.services.local.{LocalAction, LocalServiceMessage}
|
||||
import akka.actor.typed
|
||||
import net.psforever.objects.locker.LockerContainerControl
|
||||
|
||||
import scala.concurrent.duration._
|
||||
|
||||
class PlayerControl(player: Player, avatarActor: typed.ActorRef[AvatarActor.Command])
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ package net.psforever.objects.definition.converter
|
|||
import net.psforever.objects.Player
|
||||
import net.psforever.objects.equipment.{Equipment, EquipmentSlot}
|
||||
import net.psforever.packet.game.objectcreate._
|
||||
import net.psforever.types.{ExoSuitType, GrenadeState, PlanetSideGUID}
|
||||
import net.psforever.types.{ExoSuitType, GrenadeState, PlanetSideEmpire, PlanetSideGUID}
|
||||
|
||||
import scala.annotation.tailrec
|
||||
import scala.util.{Success, Try}
|
||||
|
|
@ -175,7 +175,9 @@ object AvatarConverter {
|
|||
|
||||
def MakeDetailedInventoryData(obj: Player): InventoryData = {
|
||||
InventoryData(
|
||||
(MakeHolsters(obj, BuildDetailedEquipment) ++ MakeFifthSlot(obj) ++ MakeInventory(obj)).sortBy(_.parentSlot)
|
||||
(MakeHolsters(obj, BuildDetailedEquipment) ++
|
||||
MakeFifthSlot(obj) ++
|
||||
MakeInventory(obj)).sortBy(_.parentSlot)
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -222,7 +224,16 @@ object AvatarConverter {
|
|||
private def MakeFifthSlot(obj: Player): List[InternalSlot] = {
|
||||
obj.Slot(5).Equipment match {
|
||||
case Some(equip) =>
|
||||
BuildDetailedEquipment(5, equip) :: Nil
|
||||
//List(BuildDetailedEquipment(5, equip))
|
||||
List(InternalSlot(
|
||||
equip.Definition.ObjectId,
|
||||
equip.GUID,
|
||||
5,
|
||||
DetailedLockerContainerData(
|
||||
CommonFieldData(PlanetSideEmpire.NEUTRAL, false, false, true, None, false, None, None, PlanetSideGUID(0)),
|
||||
None
|
||||
)
|
||||
))
|
||||
case _ =>
|
||||
Nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
// Copyright (c) 2017 PSForever
|
||||
package net.psforever.objects.definition.converter
|
||||
|
||||
import net.psforever.objects.LockerEquipment
|
||||
import net.psforever.objects.equipment.Equipment
|
||||
import net.psforever.objects.inventory.GridInventory
|
||||
import net.psforever.objects.locker.LockerEquipment
|
||||
import net.psforever.packet.game.objectcreate._
|
||||
import net.psforever.types.{PlanetSideEmpire, PlanetSideGUID}
|
||||
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import net.psforever.objects.entity.IdentifiableEntity
|
|||
import net.psforever.objects.equipment.{Equipment, EquipmentSlot}
|
||||
import net.psforever.objects._
|
||||
import net.psforever.objects.inventory.Container
|
||||
import net.psforever.objects.locker.{LockerContainer, LockerEquipment}
|
||||
import net.psforever.objects.serverobject.turret.WeaponTurret
|
||||
|
||||
import scala.annotation.tailrec
|
||||
|
|
@ -153,7 +154,7 @@ object GUIDTask {
|
|||
*/
|
||||
def RegisterAvatar(tplayer: Player)(implicit guid: ActorRef): TaskResolver.GiveTask = {
|
||||
val holsterTasks = VisibleSlotTaskBuilding(tplayer.Holsters(), RegisterEquipment)
|
||||
val lockerTask = List(RegisterLocker(tplayer.avatar.locker))
|
||||
val lockerTask = List(RegisterObjectTask(tplayer.avatar.locker))
|
||||
val inventoryTasks = RegisterInventory(tplayer)
|
||||
TaskResolver.GiveTask(RegisterObjectTask(tplayer).task, holsterTasks ++ lockerTask ++ inventoryTasks)
|
||||
}
|
||||
|
|
@ -311,7 +312,7 @@ object GUIDTask {
|
|||
*/
|
||||
def UnregisterAvatar(tplayer: Player)(implicit guid: ActorRef): TaskResolver.GiveTask = {
|
||||
val holsterTasks = VisibleSlotTaskBuilding(tplayer.Holsters(), UnregisterEquipment)
|
||||
val lockerTask = List(UnregisterLocker(tplayer.avatar.locker))
|
||||
val lockerTask = List(UnregisterObjectTask(tplayer.avatar.locker))
|
||||
val inventoryTasks = UnregisterInventory(tplayer)
|
||||
TaskResolver.GiveTask(UnregisterObjectTask(tplayer).task, holsterTasks ++ lockerTask ++ inventoryTasks)
|
||||
}
|
||||
|
|
@ -368,7 +369,7 @@ object GUIDTask {
|
|||
* @param guid implicit reference to a unique number system
|
||||
* @return a list of `TaskResolver.GiveTask` messages
|
||||
*/
|
||||
def VisibleSlotTaskBuilding(list: Iterable[EquipmentSlot], func: ((Equipment) => TaskResolver.GiveTask))(implicit
|
||||
def VisibleSlotTaskBuilding(list: Iterable[EquipmentSlot], func: Equipment => TaskResolver.GiveTask)(implicit
|
||||
guid: ActorRef
|
||||
): List[TaskResolver.GiveTask] = {
|
||||
recursiveVisibleSlotTaskBuilding(list.iterator, func)
|
||||
|
|
@ -386,7 +387,7 @@ object GUIDTask {
|
|||
*/
|
||||
@tailrec private def recursiveVisibleSlotTaskBuilding(
|
||||
iter: Iterator[EquipmentSlot],
|
||||
func: ((Equipment) => TaskResolver.GiveTask),
|
||||
func: Equipment => TaskResolver.GiveTask,
|
||||
list: List[TaskResolver.GiveTask] = Nil
|
||||
)(implicit guid: ActorRef): List[TaskResolver.GiveTask] = {
|
||||
if (!iter.hasNext) {
|
||||
|
|
|
|||
|
|
@ -24,8 +24,8 @@ class NumberPoolHub(private val source: NumberSource) {
|
|||
import scala.collection.mutable
|
||||
private val hash: mutable.HashMap[String, NumberPool] = mutable.HashMap[String, NumberPool]()
|
||||
private val bigpool: mutable.LongMap[String] = mutable.LongMap[String]()
|
||||
hash += "generic" -> new GenericPool(bigpool, source.Size)
|
||||
source.FinalizeRestrictions.foreach(i =>
|
||||
hash += "generic" -> new GenericPool(bigpool, source.size)
|
||||
source.finalizeRestrictions.foreach(i =>
|
||||
bigpool += i.toLong -> ""
|
||||
) //these numbers can never be pooled; the source can no longer restrict numbers
|
||||
|
||||
|
|
@ -47,7 +47,7 @@ class NumberPoolHub(private val source: NumberSource) {
|
|||
* @param number the unique number to attempt to retrieve from the `source`
|
||||
* @return the object that is assigned to the number
|
||||
*/
|
||||
def apply(number: Int): Option[IdentifiableEntity] = source.Get(number).orElse(return None).get.Object
|
||||
def apply(number: Int): Option[IdentifiableEntity] = source.get(number).orElse(return None).get.Object
|
||||
|
||||
def Numbers: List[Int] = bigpool.keys.map(key => key.toInt).toList
|
||||
|
||||
|
|
@ -74,14 +74,15 @@ class NumberPoolHub(private val source: NumberSource) {
|
|||
if (pool.isEmpty) {
|
||||
throw new IllegalArgumentException(s"can not add empty pool $name")
|
||||
}
|
||||
if (source.Size <= pool.max) {
|
||||
throw new IllegalArgumentException(s"can not add pool $name - max(pool) is greater than source.size")
|
||||
if (source.max < pool.max) {
|
||||
throw new IllegalArgumentException(s"can not add pool $name - pool.max is greater than source.max")
|
||||
}
|
||||
val collision = bigpool.keys.map(n => n.toInt).toSet.intersect(pool.toSet)
|
||||
if (collision.nonEmpty) {
|
||||
throw new IllegalArgumentException(
|
||||
s"can not add pool $name - it contains the following redundant numbers: ${collision.toString}"
|
||||
)
|
||||
bigpool.keys.map(n => n.toInt).toSet.intersect(pool.toSet).toSeq match {
|
||||
case Nil => ;
|
||||
case collisions =>
|
||||
throw new IllegalArgumentException(
|
||||
s"can not add pool $name - it contains the following redundant numbers: ${collisions.mkString(",")}"
|
||||
)
|
||||
}
|
||||
pool.foreach(i => bigpool += i.toLong -> name)
|
||||
hash += name -> new ExclusivePool(pool)
|
||||
|
|
@ -162,7 +163,7 @@ class NumberPoolHub(private val source: NumberSource) {
|
|||
def WhichPool(obj: IdentifiableEntity): Option[String] = {
|
||||
try {
|
||||
val number: Int = obj.GUID.guid
|
||||
val entry = source.Get(number)
|
||||
val entry = source.get(number)
|
||||
if (entry.isDefined && entry.get.Object.contains(obj)) { WhichPool(number) }
|
||||
else { None }
|
||||
} catch {
|
||||
|
|
@ -228,7 +229,7 @@ class NumberPoolHub(private val source: NumberSource) {
|
|||
}
|
||||
|
||||
private def register_GetAvailableNumberFromSource(number: Int): Try[LoanedKey] = {
|
||||
source.Available(number) match {
|
||||
source.getAvailable(number) match {
|
||||
case Some(key) =>
|
||||
Success(key)
|
||||
case None =>
|
||||
|
|
@ -243,22 +244,21 @@ class NumberPoolHub(private val source: NumberSource) {
|
|||
* @return the number the was given to the object
|
||||
*/
|
||||
def register(obj: IdentifiableEntity, name: String): Try[Int] = {
|
||||
try {
|
||||
if (obj.HasGUID) {
|
||||
register_CheckNumberAgainstDesiredPool(obj, name, obj.GUID.guid)
|
||||
} catch {
|
||||
case _: Exception =>
|
||||
register_GetPool(name) match {
|
||||
case Success(key) =>
|
||||
key.Object = obj
|
||||
Success(obj.GUID.guid)
|
||||
case Failure(ex) =>
|
||||
Failure(new Exception(s"trying to register an object but, ${ex.getMessage}"))
|
||||
}
|
||||
} else {
|
||||
register_GetPool(name) match {
|
||||
case Success(key) =>
|
||||
key.Object = obj
|
||||
Success(obj.GUID.guid)
|
||||
case Failure(ex) =>
|
||||
Failure(new Exception(s"trying to register an object but, ${ex.getMessage}"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private def register_CheckNumberAgainstDesiredPool(obj: IdentifiableEntity, name: String, number: Int): Try[Int] = {
|
||||
val directKey = source.Get(number)
|
||||
val directKey = source.get(number)
|
||||
if (directKey.isEmpty || !directKey.get.Object.contains(obj)) {
|
||||
Failure(new Exception("object already registered, but not to this source"))
|
||||
} else if (!WhichPool(number).contains(name)) {
|
||||
|
|
@ -347,11 +347,34 @@ class NumberPoolHub(private val source: NumberSource) {
|
|||
case Success(pool) =>
|
||||
val number = obj.GUID.guid
|
||||
pool.Return(number)
|
||||
source.Return(number)
|
||||
source.returnNumber(number)
|
||||
obj.Invalidate()
|
||||
Success(number)
|
||||
case Failure(ex) =>
|
||||
Failure(new Exception(s"can not unregister this object: ${ex.getMessage}"))
|
||||
unregister_GetMonitorFromObject(obj, ex.getMessage)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregister a specific object
|
||||
* by actually finding the object itself, if it exists.
|
||||
* @param obj an object being unregistered
|
||||
* @param msg custom error message;
|
||||
* has a vague default
|
||||
* @return the number associated with this object
|
||||
*/
|
||||
def unregister_GetMonitorFromObject(
|
||||
obj: IdentifiableEntity,
|
||||
msg: String = "can not find this object"
|
||||
): Try[Int] = {
|
||||
source.get(obj) match {
|
||||
case Some(key) =>
|
||||
val number = key.GUID
|
||||
GetPool(WhichPool(number).get).get.Return(number)
|
||||
source.returnNumber(number)
|
||||
Success(number)
|
||||
case _ =>
|
||||
Failure(new Exception(s"can not unregister this $obj - $msg"))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -360,7 +383,7 @@ class NumberPoolHub(private val source: NumberSource) {
|
|||
case Some(name) =>
|
||||
unregister_GetPool(name)
|
||||
case None =>
|
||||
Failure(throw new Exception("can not find a pool for this object"))
|
||||
Failure(new Exception(s"can not find a pool for this $obj"))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -379,7 +402,7 @@ class NumberPoolHub(private val source: NumberSource) {
|
|||
* @return the object, if any, previous associated with the number
|
||||
*/
|
||||
def unregister(number: Int): Try[Option[IdentifiableEntity]] = {
|
||||
if (source.Test(number)) {
|
||||
if (source.test(number)) {
|
||||
unregister_GetObjectFromSource(number)
|
||||
} else {
|
||||
Failure(new Exception(s"can not unregister a number $number that this source does not own"))
|
||||
|
|
@ -387,7 +410,7 @@ class NumberPoolHub(private val source: NumberSource) {
|
|||
}
|
||||
|
||||
private def unregister_GetObjectFromSource(number: Int): Try[Option[IdentifiableEntity]] = {
|
||||
source.Return(number) match {
|
||||
source.returnNumber(number) match {
|
||||
case Some(obj) =>
|
||||
unregister_ReturnObjectToPool(obj)
|
||||
case None =>
|
||||
|
|
@ -403,7 +426,7 @@ class NumberPoolHub(private val source: NumberSource) {
|
|||
obj.Invalidate()
|
||||
Success(Some(obj))
|
||||
case Failure(ex) =>
|
||||
source.Available(number) //undo
|
||||
source.getAvailable(number) //undo
|
||||
Failure(new Exception(s"started unregistering, but ${ex.getMessage}"))
|
||||
}
|
||||
}
|
||||
|
|
@ -432,11 +455,11 @@ class NumberPoolHub(private val source: NumberSource) {
|
|||
}
|
||||
|
||||
/**
|
||||
* For accessing the `Return` function of the contained `NumberSource` directly.
|
||||
* For accessing the `returnNumber` function of the contained `NumberSource` directly.
|
||||
* @param number the number to return.
|
||||
* @return any object previously using this number
|
||||
*/
|
||||
def latterPartUnregister(number: Int): Option[IdentifiableEntity] = source.Return(number)
|
||||
def latterPartUnregister(number: Int): Option[IdentifiableEntity] = source.returnNumber(number)
|
||||
|
||||
/**
|
||||
* Determines if the object is registered.<br>
|
||||
|
|
@ -451,7 +474,7 @@ class NumberPoolHub(private val source: NumberSource) {
|
|||
*/
|
||||
def isRegistered(obj: IdentifiableEntity): Boolean = {
|
||||
try {
|
||||
source.Get(obj.GUID.guid) match {
|
||||
source.get(obj.GUID.guid) match {
|
||||
case Some(monitor) =>
|
||||
monitor.Object.contains(obj)
|
||||
case None =>
|
||||
|
|
@ -474,7 +497,7 @@ class NumberPoolHub(private val source: NumberSource) {
|
|||
* @see `isRegistered(IdentifiableEntity)`
|
||||
*/
|
||||
def isRegistered(number: Int): Boolean = {
|
||||
source.Get(number) match {
|
||||
source.get(number) match {
|
||||
case Some(monitor) =>
|
||||
monitor.Policy == AvailabilityPolicy.Leased
|
||||
case None =>
|
||||
|
|
|
|||
|
|
@ -73,7 +73,7 @@ object NumberPoolActor {
|
|||
final case class NoNumber(ex: Throwable, id: Option[Any] = None)
|
||||
|
||||
/**
|
||||
* A message to invoke the `Return` functionality of the current `NumberSelector`.
|
||||
* A message to invoke the `returnNumber` functionality of the current `NumberSelector`.
|
||||
* @param number the number
|
||||
*/
|
||||
final case class ReturnNumber(number: Int, id: Option[Any] = None)
|
||||
|
|
|
|||
|
|
@ -12,9 +12,9 @@ import net.psforever.objects.guid.AvailabilityPolicy
|
|||
class LoanedKey(private val guid: Int, private val key: Monitor) {
|
||||
def GUID: Int = guid
|
||||
|
||||
def Policy: AvailabilityPolicy.Value = key.Policy
|
||||
def Policy: AvailabilityPolicy.Value = key.policy
|
||||
|
||||
def Object: Option[IdentifiableEntity] = key.Object
|
||||
def Object: Option[IdentifiableEntity] = key.obj
|
||||
|
||||
/**
|
||||
* na
|
||||
|
|
@ -30,18 +30,18 @@ class LoanedKey(private val guid: Int, private val key: Monitor) {
|
|||
*/
|
||||
def Object_=(obj: Option[IdentifiableEntity]): Option[IdentifiableEntity] = {
|
||||
if (
|
||||
key.Policy == AvailabilityPolicy.Leased || (key.Policy == AvailabilityPolicy.Restricted && key.Object.isEmpty)
|
||||
key.policy == AvailabilityPolicy.Leased || (key.policy == AvailabilityPolicy.Restricted && key.obj.isEmpty)
|
||||
) {
|
||||
if (key.Object.isDefined) {
|
||||
key.Object.get.Invalidate()
|
||||
key.Object = None
|
||||
if (key.obj.isDefined) {
|
||||
key.obj.get.Invalidate()
|
||||
key.obj = None
|
||||
}
|
||||
key.Object = obj
|
||||
key.obj = obj
|
||||
if (obj.isDefined) {
|
||||
import net.psforever.types.PlanetSideGUID
|
||||
obj.get.GUID = PlanetSideGUID(guid)
|
||||
}
|
||||
}
|
||||
key.Object
|
||||
key.obj
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,9 +5,7 @@ import net.psforever.objects.entity.IdentifiableEntity
|
|||
import net.psforever.objects.guid.AvailabilityPolicy
|
||||
|
||||
trait Monitor {
|
||||
def Policy: AvailabilityPolicy.Value
|
||||
var policy: AvailabilityPolicy.Value
|
||||
|
||||
def Object: Option[IdentifiableEntity]
|
||||
|
||||
def Object_=(objct: Option[IdentifiableEntity]): Option[IdentifiableEntity]
|
||||
var obj: Option[IdentifiableEntity]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,8 +11,8 @@ import net.psforever.objects.guid.AvailabilityPolicy
|
|||
final class SecureKey(private val guid: Int, private val key: Monitor) {
|
||||
def GUID: Int = guid
|
||||
|
||||
def Policy: AvailabilityPolicy.Value = key.Policy
|
||||
def Policy: AvailabilityPolicy.Value = key.policy
|
||||
|
||||
import net.psforever.objects.entity.IdentifiableEntity
|
||||
def Object: Option[IdentifiableEntity] = key.Object
|
||||
def Object: Option[IdentifiableEntity] = key.obj
|
||||
}
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ abstract class NumberSelector {
|
|||
* By default, a simple policy for returning numbers has been provided.
|
||||
* This will not be sufficient for all selection actions that can be implemented so `override` where necessary.
|
||||
* <br>
|
||||
* `Return` is under no obligation to leave its parameter `Array` unmodified.
|
||||
* `returnNumber` is under no obligation to leave its parameter `Array` unmodified.
|
||||
* In fact, it should modify it by default to provide additional feedback of its process.
|
||||
* Pass a copy if data mutation is a concern.
|
||||
* @param number the number to be returned
|
||||
|
|
|
|||
|
|
@ -6,20 +6,7 @@ import net.psforever.objects.guid.AvailabilityPolicy
|
|||
import net.psforever.objects.guid.key.Monitor
|
||||
|
||||
private class Key extends Monitor {
|
||||
private var policy: AvailabilityPolicy.Value = AvailabilityPolicy.Available
|
||||
private var obj: Option[IdentifiableEntity] = None
|
||||
var policy: AvailabilityPolicy.Value = AvailabilityPolicy.Available
|
||||
|
||||
def Policy: AvailabilityPolicy.Value = policy
|
||||
|
||||
def Policy_=(pol: AvailabilityPolicy.Value): AvailabilityPolicy.Value = {
|
||||
policy = pol
|
||||
Policy
|
||||
}
|
||||
|
||||
def Object: Option[IdentifiableEntity] = obj
|
||||
|
||||
def Object_=(objct: Option[IdentifiableEntity]): Option[IdentifiableEntity] = {
|
||||
obj = objct
|
||||
Object
|
||||
}
|
||||
var obj: Option[IdentifiableEntity] = None
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,111 +0,0 @@
|
|||
// Copyright (c) 2017 PSForever
|
||||
package net.psforever.objects.guid.source
|
||||
|
||||
import net.psforever.objects.entity.IdentifiableEntity
|
||||
import net.psforever.objects.guid.key.{LoanedKey, SecureKey}
|
||||
import net.psforever.objects.guid.AvailabilityPolicy
|
||||
|
||||
import scala.collection.mutable
|
||||
|
||||
/**
|
||||
* A `NumberSource` is considered a master "pool" of numbers from which all numbers are available to be drawn.
|
||||
* The numbers are considered to be exclusive.<br>
|
||||
* <br>
|
||||
* Produce a series of numbers from 0 to a maximum number (inclusive) to be used as globally unique identifiers (GUIDs).
|
||||
* @param max the highest number to be generated by this source;
|
||||
* must be a positive integer or zero
|
||||
* @throws IllegalArgumentException if `max` is less than zero (therefore the count of generated numbers is at most zero)
|
||||
* @throws java.lang.NegativeArraySizeException if the count of numbers generated due to max is negative
|
||||
*/
|
||||
class LimitedNumberSource(max: Int) extends NumberSource {
|
||||
if (max < 0) {
|
||||
throw new IllegalArgumentException(s"non-negative integers only, not $max")
|
||||
}
|
||||
private val ary: Array[Key] = Array.ofDim[Key](max + 1)
|
||||
(0 to max).foreach(x => { ary(x) = new Key })
|
||||
private var allowRestrictions: Boolean = true
|
||||
|
||||
def Size: Int = ary.length
|
||||
|
||||
def CountAvailable: Int = ary.count(key => key.Policy == AvailabilityPolicy.Available)
|
||||
|
||||
def CountUsed: Int = ary.count(key => key.Policy != AvailabilityPolicy.Available)
|
||||
|
||||
def Get(number: Int): Option[SecureKey] = {
|
||||
if (Test(number)) {
|
||||
Some(new SecureKey(number, ary(number)))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
def Available(number: Int): Option[LoanedKey] = {
|
||||
var out: Option[LoanedKey] = None
|
||||
if (Test(number)) {
|
||||
val key: Key = ary(number)
|
||||
if (key.Policy == AvailabilityPolicy.Available) {
|
||||
key.Policy = AvailabilityPolicy.Leased
|
||||
out = Some(new LoanedKey(number, key))
|
||||
}
|
||||
}
|
||||
out
|
||||
}
|
||||
|
||||
/**
|
||||
* Consume the number of a `Monitor` and release that number from its previous assignment/use.
|
||||
* @param number the number
|
||||
* @return any object previously using this number
|
||||
*/
|
||||
def Return(number: Int): Option[IdentifiableEntity] = {
|
||||
var out: Option[IdentifiableEntity] = None
|
||||
if (Test(number)) {
|
||||
val existing: Key = ary(number)
|
||||
if (existing.Policy == AvailabilityPolicy.Leased) {
|
||||
out = existing.Object
|
||||
existing.Policy = AvailabilityPolicy.Available
|
||||
existing.Object = None
|
||||
}
|
||||
}
|
||||
out
|
||||
}
|
||||
|
||||
/**
|
||||
* Produce a modifiable wrapper for the `Monitor` for this number, only if the number has not been used.
|
||||
* This wrapped `Monitor` can only be assigned once and the number may not be `Return`ed to this source.
|
||||
* @param number the number
|
||||
* @return the wrapped `Monitor`
|
||||
* @throws ArrayIndexOutOfBoundsException if the requested number is above or below the range
|
||||
*/
|
||||
def Restrict(number: Int): Option[LoanedKey] = {
|
||||
if (allowRestrictions && Test(number)) {
|
||||
val key: Key = ary(number)
|
||||
key.Policy = AvailabilityPolicy.Restricted
|
||||
Some(new LoanedKey(number, key))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
def FinalizeRestrictions: List[Int] = {
|
||||
allowRestrictions = false
|
||||
ary.zipWithIndex.filter(entry => entry._1.Policy == AvailabilityPolicy.Restricted).map(entry => entry._2).toList
|
||||
}
|
||||
|
||||
def Clear(): List[IdentifiableEntity] = {
|
||||
val outList: mutable.ListBuffer[IdentifiableEntity] = mutable.ListBuffer[IdentifiableEntity]()
|
||||
for (x <- ary.indices) {
|
||||
ary(x).Policy = AvailabilityPolicy.Available
|
||||
if (ary(x).Object.isDefined) {
|
||||
outList += ary(x).Object.get
|
||||
ary(x).Object = None
|
||||
}
|
||||
}
|
||||
outList.toList
|
||||
}
|
||||
}
|
||||
|
||||
object LimitedNumberSource {
|
||||
def apply(max: Int): LimitedNumberSource = {
|
||||
new LimitedNumberSource(max)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,121 @@
|
|||
// Copyright (c) 2017 PSForever
|
||||
package net.psforever.objects.guid.source
|
||||
|
||||
import net.psforever.objects.entity.IdentifiableEntity
|
||||
import net.psforever.objects.guid.key.{LoanedKey, SecureKey}
|
||||
import net.psforever.objects.guid.AvailabilityPolicy
|
||||
|
||||
/**
|
||||
* A `NumberSource` is considered a master "pool" of numbers from which all numbers are available to be drawn.
|
||||
* Produce a series of numbers from 0 to a maximum number (inclusive) to be used as globally unique identifiers (GUID's).
|
||||
* @param max the highest number to be generated by this source;
|
||||
* must be a positive integer or zero
|
||||
* @throws IllegalArgumentException if `max` is less than zero (therefore the count of generated numbers is at most zero)
|
||||
*/
|
||||
class MaxNumberSource(val max: Int) extends NumberSource {
|
||||
if (max < 0) {
|
||||
throw new IllegalArgumentException(s"non-negative integers only, not $max")
|
||||
}
|
||||
private val ary: Array[Key] = Array.ofDim[Key](max + 1)
|
||||
(0 to max).foreach(x => { ary(x) = new Key })
|
||||
private var allowRestrictions: Boolean = true
|
||||
|
||||
def size: Int = ary.length
|
||||
|
||||
def countAvailable: Int = ary.count(key => key.policy == AvailabilityPolicy.Available)
|
||||
|
||||
def countUsed: Int = ary.count(_.policy != AvailabilityPolicy.Available)
|
||||
|
||||
def test(number: Int): Boolean = -1 < number && number < size
|
||||
|
||||
def get(number: Int): Option[SecureKey] = {
|
||||
if (test(number)) {
|
||||
Some(new SecureKey(number, ary(number)))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
def get(obj: IdentifiableEntity) : Option[SecureKey] = {
|
||||
ary.zipWithIndex.find { case (key, _) =>
|
||||
key.obj match {
|
||||
case Some(o) => o eq obj
|
||||
case _ => false
|
||||
}
|
||||
} match {
|
||||
case Some((key, number)) => Some(new SecureKey(number, key))
|
||||
case _=> None
|
||||
}
|
||||
}
|
||||
|
||||
def getAvailable(number: Int): Option[LoanedKey] = {
|
||||
var out: Option[LoanedKey] = None
|
||||
if (test(number)) {
|
||||
val key: Key = ary(number)
|
||||
if (key.policy == AvailabilityPolicy.Available) {
|
||||
key.policy = AvailabilityPolicy.Leased
|
||||
out = Some(new LoanedKey(number, key))
|
||||
}
|
||||
}
|
||||
out
|
||||
}
|
||||
|
||||
/**
|
||||
* Consume the number of a `Monitor` and release that number from its previous assignment/use.
|
||||
* @param number the number
|
||||
* @return any object previously using this number
|
||||
*/
|
||||
def returnNumber(number: Int): Option[IdentifiableEntity] = {
|
||||
var out: Option[IdentifiableEntity] = None
|
||||
if (test(number)) {
|
||||
val existing: Key = ary(number)
|
||||
if (existing.policy == AvailabilityPolicy.Leased) {
|
||||
out = existing.obj
|
||||
existing.policy = AvailabilityPolicy.Available
|
||||
existing.obj = None
|
||||
}
|
||||
}
|
||||
out
|
||||
}
|
||||
|
||||
/**
|
||||
* Produce a modifiable wrapper for the `Monitor` for this number, only if the number has not been used.
|
||||
* This wrapped `Monitor` can only be assigned once and the number may not be `returnNumber`ed to this source.
|
||||
* @param number the number
|
||||
* @return the wrapped `Monitor`
|
||||
* @throws ArrayIndexOutOfBoundsException if the requested number is above or below the range
|
||||
*/
|
||||
def restrictNumber(number: Int): Option[LoanedKey] = {
|
||||
ary.lift(number) match {
|
||||
case Some(key: Key) if allowRestrictions && key.policy != AvailabilityPolicy.Restricted =>
|
||||
key.policy = AvailabilityPolicy.Restricted
|
||||
Some(new LoanedKey(number, key))
|
||||
case None =>
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
def finalizeRestrictions: List[Int] = {
|
||||
allowRestrictions = false
|
||||
ary.zipWithIndex.filter(entry => entry._1.policy == AvailabilityPolicy.Restricted).map(entry => entry._2).toList
|
||||
}
|
||||
|
||||
def clear(): List[IdentifiableEntity] = {
|
||||
val leased = ary.filter(_.policy != AvailabilityPolicy.Available)
|
||||
leased collect { case key if key.obj.isEmpty =>
|
||||
key.policy = AvailabilityPolicy.Available
|
||||
}
|
||||
leased.toList collect { case key if key.obj.nonEmpty =>
|
||||
key.policy = AvailabilityPolicy.Available
|
||||
val out = key.obj.get
|
||||
key.obj = None
|
||||
out
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
object MaxNumberSource {
|
||||
def apply(max: Int): MaxNumberSource = {
|
||||
new MaxNumberSource(max)
|
||||
}
|
||||
}
|
||||
|
|
@ -18,42 +18,51 @@ import net.psforever.objects.guid.key.{LoanedKey, SecureKey}
|
|||
* The purpose of a `NumberSource` is to help facilitate globally unique identifiers (GUID, pl. GUIDs).
|
||||
*/
|
||||
trait NumberSource {
|
||||
/**
|
||||
* The maximum number that can be produced by this source.
|
||||
* @return the max
|
||||
*/
|
||||
def max: Int
|
||||
|
||||
/**
|
||||
* The count of numbers allocated to this source.
|
||||
* @return the count
|
||||
*/
|
||||
def Size: Int
|
||||
def size: Int
|
||||
|
||||
/**
|
||||
* The count of numbers that can still be drawn.
|
||||
* @return the count
|
||||
*/
|
||||
def CountAvailable: Int
|
||||
def countAvailable: Int
|
||||
|
||||
/**
|
||||
* The count of numbers that can not be drawn.
|
||||
* @return the count
|
||||
*/
|
||||
def CountUsed: Int
|
||||
def countUsed: Int
|
||||
|
||||
/**
|
||||
* Is this number a member of this number source?
|
||||
* @param number the number
|
||||
* @return `true`, if it is a member; `false`, otherwise
|
||||
*/
|
||||
def Test(number: Int): Boolean = -1 < number && number < Size
|
||||
def test(number: Int): Boolean
|
||||
|
||||
/**
|
||||
* Produce an un-modifiable wrapper for the `Monitor` for this number.
|
||||
* @param number the number
|
||||
* @return the wrapped `Monitor`
|
||||
*/
|
||||
def Get(number: Int): Option[SecureKey]
|
||||
def get(number: Int): Option[SecureKey]
|
||||
|
||||
//def GetAll(list : List[Int]) : List[SecureKey]
|
||||
|
||||
//def GetAll(p : Key => Boolean) : List[SecureKey]
|
||||
/**
|
||||
* Produce an un-modifiable wrapper for the `Monitor` for this entity,
|
||||
* if the entity is discovered being represented in this source.
|
||||
* @param obj the entity
|
||||
* @return the wrapped `Monitor`
|
||||
*/
|
||||
def get(obj: IdentifiableEntity) : Option[SecureKey]
|
||||
|
||||
/**
|
||||
* Produce a modifiable wrapper for the `Monitor` for this number, only if the number has not been used.
|
||||
|
|
@ -61,15 +70,15 @@ trait NumberSource {
|
|||
* @param number the number
|
||||
* @return the wrapped `Monitor`, or `None`
|
||||
*/
|
||||
def Available(number: Int): Option[LoanedKey]
|
||||
def getAvailable(number: Int): Option[LoanedKey]
|
||||
|
||||
/**
|
||||
* Consume a wrapped `Monitor` and release its number from its previous assignment/use.
|
||||
* @param monitor the `Monitor`
|
||||
* @return any object previously using this `Monitor`
|
||||
*/
|
||||
def Return(monitor: SecureKey): Option[IdentifiableEntity] = {
|
||||
Return(monitor.GUID)
|
||||
def returnNumber(monitor: SecureKey): Option[IdentifiableEntity] = {
|
||||
returnNumber(monitor.GUID)
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -77,8 +86,8 @@ trait NumberSource {
|
|||
* @param monitor the `Monitor`
|
||||
* @return any object previously using this `Monitor`
|
||||
*/
|
||||
def Return(monitor: LoanedKey): Option[IdentifiableEntity] = {
|
||||
Return(monitor.GUID)
|
||||
def returnNumber(monitor: LoanedKey): Option[IdentifiableEntity] = {
|
||||
returnNumber(monitor.GUID)
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -86,21 +95,21 @@ trait NumberSource {
|
|||
* @param number the number
|
||||
* @return any object previously using this number
|
||||
*/
|
||||
def Return(number: Int): Option[IdentifiableEntity]
|
||||
def returnNumber(number: Int): Option[IdentifiableEntity]
|
||||
|
||||
/**
|
||||
* Produce a modifiable wrapper for the `Monitor` for this number, only if the number has not been used.
|
||||
* This wrapped `Monitor` can only be assigned once and the number may not be `Return`ed to this source.
|
||||
* This wrapped `Monitor` can only be assigned once and the number may not be `returnNumber`ed to this source.
|
||||
* @param number the number
|
||||
* @return the wrapped `Monitor`
|
||||
*/
|
||||
def Restrict(number: Int): Option[LoanedKey]
|
||||
def restrictNumber(number: Int): Option[LoanedKey]
|
||||
|
||||
/**
|
||||
* Numbers from this source may not longer be marked as `Restricted`.
|
||||
* @return the `List` of all numbers that have been restricted
|
||||
*/
|
||||
def FinalizeRestrictions: List[Int]
|
||||
def finalizeRestrictions: List[Int]
|
||||
|
||||
import net.psforever.objects.entity.IdentifiableEntity
|
||||
|
||||
|
|
@ -110,5 +119,5 @@ trait NumberSource {
|
|||
* This is the only way to free `Monitors` that are marked as `Restricted`.
|
||||
* @return a `List` of assignments maintained by all the currently-used number `Monitors`
|
||||
*/
|
||||
def Clear(): List[IdentifiableEntity]
|
||||
def clear(): List[IdentifiableEntity]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,112 @@
|
|||
// Copyright (c) 2020 PSForever
|
||||
package net.psforever.objects.guid.source
|
||||
|
||||
import net.psforever.objects.entity.IdentifiableEntity
|
||||
import net.psforever.objects.guid.AvailabilityPolicy
|
||||
import net.psforever.objects.guid.key.{LoanedKey, SecureKey}
|
||||
|
||||
/**
|
||||
* A `NumberSource` is considered a master "pool" of numbers from which all numbers are available to be drawn.
|
||||
* Produce a series of numbers from 0 to a maximum number (inclusive) to be used as globally unique identifiers (GUID's).
|
||||
* @param values the domain of numbers to be used by this source;
|
||||
* must only be positive integers or zero
|
||||
* @throws IllegalArgumentException if no numbers are provided
|
||||
* @throws IllegalArgumentException if any of the numbers provided are negative
|
||||
*/
|
||||
class SpecificNumberSource(values: Iterable[Int]) extends NumberSource {
|
||||
if (values.isEmpty) {
|
||||
throw new IllegalArgumentException(s"must provide one or more positive integers (or zero)")
|
||||
}
|
||||
values.filter(_ < 0) match {
|
||||
case Nil => ;
|
||||
case list => throw new IllegalArgumentException(s"non-negative integers only, not ${list.mkString(" ")}")
|
||||
}
|
||||
private val ary : Map[Int, Key] = values.map(index => (index, new Key)).toMap
|
||||
|
||||
def max : Int = ary.keys.max
|
||||
|
||||
def size : Int = ary.size
|
||||
|
||||
def countAvailable : Int = ary.values.count(key => key.policy == AvailabilityPolicy.Available)
|
||||
|
||||
def countUsed : Int = ary.values.count(_.policy != AvailabilityPolicy.Available)
|
||||
|
||||
def test(number : Int) : Boolean = ary.get(number).nonEmpty
|
||||
|
||||
def get(number : Int) : Option[SecureKey] = {
|
||||
ary.get(number) match {
|
||||
case Some(key) => Some(new SecureKey(number, key))
|
||||
case _ => None
|
||||
}
|
||||
}
|
||||
|
||||
def get(obj : IdentifiableEntity) : Option[SecureKey] = {
|
||||
ary.find { case (_, key) =>
|
||||
key.obj match {
|
||||
case Some(o) => o eq obj
|
||||
case _ => false
|
||||
}
|
||||
} match {
|
||||
case Some((number, key)) => Some(new SecureKey(number, key))
|
||||
case _ => None
|
||||
}
|
||||
}
|
||||
|
||||
def getAvailable(number : Int) : Option[LoanedKey] = {
|
||||
ary.get(number) match {
|
||||
case Some(key) if key.policy == AvailabilityPolicy.Available =>
|
||||
key.policy = AvailabilityPolicy.Leased
|
||||
Some(new LoanedKey(number, key))
|
||||
case _ =>
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
def returnNumber(number : Int) : Option[IdentifiableEntity] = {
|
||||
ary.get(number) match {
|
||||
case Some(key) if key.policy == AvailabilityPolicy.Leased =>
|
||||
val out = key.obj
|
||||
key.policy = AvailabilityPolicy.Available
|
||||
key.obj = None
|
||||
out
|
||||
case _ =>
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
def restrictNumber(number : Int) : Option[LoanedKey] = {
|
||||
ary.get(number) match {
|
||||
case Some(key) if key.policy != AvailabilityPolicy.Restricted =>
|
||||
key.policy = AvailabilityPolicy.Restricted
|
||||
Some(new LoanedKey(number, key))
|
||||
case _ =>
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
def finalizeRestrictions : List[Int] = {
|
||||
ary
|
||||
.filter { case (_, key : Key) => key.policy == AvailabilityPolicy.Restricted }
|
||||
.keys
|
||||
.toList
|
||||
}
|
||||
|
||||
def clear(): List[IdentifiableEntity] = {
|
||||
val leased = ary.values.filter(_.policy != AvailabilityPolicy.Available)
|
||||
leased collect { case key if key.obj.isEmpty =>
|
||||
key.policy = AvailabilityPolicy.Available
|
||||
}
|
||||
leased.toList collect { case key if key.obj.nonEmpty =>
|
||||
key.policy = AvailabilityPolicy.Available
|
||||
val out = key.obj.get
|
||||
key.obj = None
|
||||
out
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
object SpecificNumberSource {
|
||||
def apply(values: Iterable[Int]): SpecificNumberSource = {
|
||||
new SpecificNumberSource(values)
|
||||
}
|
||||
}
|
||||
|
|
@ -98,94 +98,3 @@ trait Container {
|
|||
def Collisions(index: Int, width: Int, height: Int): Try[List[InventoryItem]] =
|
||||
Inventory.CheckCollisionsVar(index, width, height)
|
||||
}
|
||||
|
||||
//object Container {
|
||||
// type ValidContainer = PlanetSideServerObject with Container
|
||||
//
|
||||
// final case class GetMoveItem(where_src : Int, other : ValidContainer, where_other : Int, other_item : Option[Equipment])
|
||||
//
|
||||
// final case class GiveMoveItem(cont1 : ValidContainer, where_cont1 : Int, item : Option[Equipment], cont2 : ValidContainer, where_cont2 : Int, other_item : Option[Equipment])
|
||||
//
|
||||
//
|
||||
// final case class TakeMoveItem(source_index : Int, destination : ValidContainer, destination_index : Int)
|
||||
//
|
||||
// final case class TakeMoveItem2(item_guid : PlanetSideGUID, destination : ValidContainer, destination_index : Int)
|
||||
//
|
||||
// final case class GivingMoveItem(item : Equipment, source : ValidContainer, source_index : Int, destination : ValidContainer, destination_index : Int)
|
||||
//
|
||||
// final case class PutMoveItem(item : Equipment, target_index : Int, source : ValidContainer, source_index : Int)
|
||||
//
|
||||
// final case class DropMoveItem(item : Equipment, source : ValidContainer, source_index : Int)
|
||||
//
|
||||
// final case class ItemMoved(item : Equipment, location : ValidContainer, location_index : Int)
|
||||
//
|
||||
// final case class NoMoveItem(source : ValidContainer, source_index : Int)
|
||||
//}
|
||||
//
|
||||
//trait ContainerBehavior {
|
||||
// this : Actor =>
|
||||
//
|
||||
// def ContainableObject : Container.ValidContainer
|
||||
//
|
||||
// val containerBehavior : Receive = {
|
||||
// case Container.GetMoveItem(where_src, destination, where_dest, other_item) =>
|
||||
// val slot : EquipmentSlot = ContainableObject.Slot(where_src)
|
||||
// val equipment = slot.Equipment
|
||||
// slot.Equipment = None
|
||||
// sender ! Container.GiveMoveItem(ContainableObject, where_src, equipment, destination, where_dest, other_item)
|
||||
//
|
||||
// case Container.TakeMoveItem(source_index, destination, destination_index) =>
|
||||
// val slot : EquipmentSlot = ContainableObject.Slot(source_index)
|
||||
// val equipment : Option[Equipment] = slot.Equipment
|
||||
// slot.Equipment = None
|
||||
// sender ! (equipment match {
|
||||
// case Some(item) =>
|
||||
// Container.GivingMoveItem(item, ContainableObject, source_index, destination, destination_index)
|
||||
// case None =>
|
||||
// Container.NoMoveItem(ContainableObject, source_index)
|
||||
// })
|
||||
//
|
||||
// case Container.TakeMoveItem2(item_guid, destination, destination_index) =>
|
||||
// ContainableObject.Find(item_guid) match {
|
||||
// case Some(source_index) =>
|
||||
// val slot : EquipmentSlot = ContainableObject.Slot(source_index)
|
||||
// val equipment : Option[Equipment] = slot.Equipment
|
||||
// slot.Equipment = None
|
||||
// sender ! (equipment match {
|
||||
// case Some(item) =>
|
||||
// Container.GivingMoveItem(item, ContainableObject, source_index, destination, destination_index)
|
||||
// case None => ;
|
||||
// })
|
||||
//
|
||||
// case None =>
|
||||
// sender ! Container.NoMoveItem(ContainableObject, 65535)
|
||||
// }
|
||||
//
|
||||
// case Container.PutMoveItem(item, target_index, source, source_index) =>
|
||||
// val slot : EquipmentSlot = ContainableObject.Slot(target_index)
|
||||
// val equipment : Option[Equipment] = slot.Equipment
|
||||
// if( {
|
||||
// val tile = item.Definition.Tile
|
||||
// ContainableObject.Collisions(target_index, tile.Width, tile.Height) match {
|
||||
// case Success(Nil) => //no item swap
|
||||
// true
|
||||
// case Success(_ :: Nil) => //one item to swap
|
||||
// true
|
||||
// case Success(_) | Failure(_) =>
|
||||
// false //abort when too many items at destination or other failure case
|
||||
// }
|
||||
// }) {
|
||||
// slot.Equipment = None
|
||||
// slot.Equipment = item
|
||||
// equipment match {
|
||||
// case Some(swapItem) =>
|
||||
// sender ! Container.GivingMoveItem(swapItem, ContainableObject, target_index, source, source_index)
|
||||
// case None => ;
|
||||
// }
|
||||
// sender ! Container.ItemMoved(item, ContainableObject, target_index)
|
||||
// }
|
||||
// else {
|
||||
// sender ! Container.DropMoveItem(item, source, source_index)
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
|
|
|
|||
|
|
@ -191,8 +191,7 @@ class GridInventory extends Container {
|
|||
} else {
|
||||
val collisions: mutable.Set[InventoryItem] = mutable.Set[InventoryItem]()
|
||||
items
|
||||
.map { case (_, item: InventoryItem) => item }
|
||||
.foreach { item: InventoryItem =>
|
||||
.foreach { case (_, item: InventoryItem) =>
|
||||
val actualItemStart: Int = item.start - offset
|
||||
val itemx: Int = actualItemStart % width
|
||||
val itemy: Int = actualItemStart / width
|
||||
|
|
@ -542,8 +541,8 @@ class GridInventory extends Container {
|
|||
//lists with multiple entries represent a group of items that collide
|
||||
//perform a specific distinct on the list of lists of numeric id overlaps
|
||||
//THEN map each list of list's item id to an item
|
||||
val out = testGrid.collect {
|
||||
case (_, list) if list.size > 1 => list.sortWith(_ < _)
|
||||
val out = testGrid.values.collect {
|
||||
case list if list.size > 1 => list.sortWith(_ < _)
|
||||
}
|
||||
recursiveRelatedListCollisions(out.iterator, out.toList).map { list => list.map { items } }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,132 @@
|
|||
// Copyright (c) 2020 PSForever
|
||||
package net.psforever.objects.inventory
|
||||
|
||||
import net.psforever.objects.Tool
|
||||
import net.psforever.objects.equipment.Equipment
|
||||
import net.psforever.objects.guid.NumberPoolHub
|
||||
import net.psforever.objects.guid.selector.RandomSelector
|
||||
import net.psforever.objects.guid.source.SpecificNumberSource
|
||||
import net.psforever.types.PlanetSideGUID
|
||||
|
||||
import scala.util.{Failure, Success}
|
||||
|
||||
/**
|
||||
* An inventory that contains its own internal unique number system bound by a domain of numbers.
|
||||
* When equipment is inserted into this inventory,
|
||||
* the equipment is registered to it, assigned one of its internal unique numbers.
|
||||
* The equipment must not already be registered to another unique number system for that reason.
|
||||
* Upon being removed, the removed equipment is unregistered.
|
||||
* The registration system adds another unspoken layer to `Capacity`
|
||||
* as it imposes a total object count to the inventory.
|
||||
* @see `NumberSourceHub`
|
||||
* @see `RandomSelector`
|
||||
* @see `SpecificNumberSource`
|
||||
* @param numbers the numbers used as unique identifiers
|
||||
*/
|
||||
class LocallyRegisteredInventory(numbers: Iterable[Int])
|
||||
extends GridInventory {
|
||||
private val hub: NumberPoolHub = {
|
||||
val numHub = new NumberPoolHub(SpecificNumberSource(numbers))
|
||||
//only one pool composed of all of the numbers; randomized selection
|
||||
numHub.AddPool("internal", numbers.toList).Selector = new RandomSelector
|
||||
numHub
|
||||
}
|
||||
|
||||
override def Insert(start : Int, obj : Equipment) : Boolean = {
|
||||
if(!obj.HasGUID) {
|
||||
registerEquipment(obj) match {
|
||||
case true if super.Insert(start, obj) =>
|
||||
true
|
||||
case true =>
|
||||
unregisterEquipment(obj) //the item failed to be inserted; undo the previous registration
|
||||
false
|
||||
case _ =>
|
||||
false
|
||||
}
|
||||
}
|
||||
else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
override def InsertQuickly(start : Int, obj : Equipment) : Boolean = {
|
||||
if(!obj.HasGUID) {
|
||||
registerEquipment(obj) match {
|
||||
case true if super.InsertQuickly(start, obj) =>
|
||||
true
|
||||
case true =>
|
||||
unregisterEquipment(obj) //the item failed to be inserted; undo the previous registration
|
||||
false
|
||||
case _ =>
|
||||
false
|
||||
}
|
||||
}
|
||||
else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
override def Remove(guid : PlanetSideGUID) : Boolean = {
|
||||
hub(guid) match {
|
||||
case Some(obj: Equipment) if super.Remove(guid) =>
|
||||
unregisterEquipment(obj)
|
||||
case _ =>
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
override def Remove(index : Int) : Boolean = {
|
||||
Slot(index).Equipment match {
|
||||
case Some(obj: Equipment) if super.Remove(obj.GUID) =>
|
||||
unregisterEquipment(obj)
|
||||
case _ =>
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
override def Clear() : List[InventoryItem] = {
|
||||
val items = super.Clear()
|
||||
items.foreach { item => unregisterEquipment(item.obj) }
|
||||
items
|
||||
}
|
||||
|
||||
private def registerEquipment(obj: Equipment): Boolean = {
|
||||
obj match {
|
||||
case tool: Tool => registerTool(tool)
|
||||
case _ => registerObject(obj)
|
||||
}
|
||||
}
|
||||
|
||||
private def registerTool(obj: Tool): Boolean = {
|
||||
val parts = obj +: obj.AmmoSlots.map { _.Box }
|
||||
val tasks = parts.map { part => hub.register(part, "internal") }
|
||||
if(tasks.exists(o => o.isInstanceOf[Failure[Int]])) {
|
||||
tasks.zipWithIndex.collect { case (Success(_), index) =>
|
||||
unregisterEquipment(parts(index))
|
||||
}
|
||||
false
|
||||
} else {
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
private def registerObject(obj: Equipment): Boolean = {
|
||||
hub.register(obj, "internal").isSuccess
|
||||
}
|
||||
|
||||
private def unregisterEquipment(obj: Equipment): Boolean = {
|
||||
obj match {
|
||||
case tool: Tool => unregisterTool(tool)
|
||||
case _ => unregisterObject(obj)
|
||||
}
|
||||
}
|
||||
|
||||
private def unregisterTool(obj: Tool): Boolean = {
|
||||
val parts = obj +: obj.AmmoSlots.map { _.Box }
|
||||
parts.map { part => hub.unregister(part) }.forall(o => o.isInstanceOf[Success[Int]])
|
||||
}
|
||||
|
||||
private def unregisterObject(obj: Equipment): Boolean = {
|
||||
hub.unregister(obj).isSuccess
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
// Copyright (c) 2017 PSForever
|
||||
package net.psforever.objects.locker
|
||||
|
||||
import net.psforever.objects.GlobalDefinitions
|
||||
import net.psforever.objects.definition.EquipmentDefinition
|
||||
import net.psforever.objects.inventory.{Container, GridInventory}
|
||||
import net.psforever.objects.serverobject.PlanetSideServerObject
|
||||
import net.psforever.types.PlanetSideEmpire
|
||||
|
||||
/**
|
||||
* The companion of a `Locker` that is carried with a player
|
||||
* masquerading as their sixth `EquipmentSlot` object and a sub-inventory item.
|
||||
* The inventory of this object is accessed indirectly using a game world `Locker` object (`mb_locker`) as a proxy.
|
||||
* The `Player` class refers to it as the "fifth slot".
|
||||
*/
|
||||
class LockerContainer(inventory: GridInventory)
|
||||
extends PlanetSideServerObject
|
||||
with Container {
|
||||
private var faction: PlanetSideEmpire.Value = PlanetSideEmpire.NEUTRAL
|
||||
private val inv: GridInventory = inventory
|
||||
|
||||
def Faction: PlanetSideEmpire.Value = faction
|
||||
|
||||
override def Faction_=(fact: PlanetSideEmpire.Value): PlanetSideEmpire.Value = {
|
||||
faction = fact
|
||||
Faction
|
||||
}
|
||||
|
||||
def Inventory: GridInventory = inv
|
||||
|
||||
def VisibleSlots: Set[Int] = Set.empty[Int]
|
||||
|
||||
def Definition: EquipmentDefinition = GlobalDefinitions.locker_container
|
||||
}
|
||||
|
||||
object LockerContainer {
|
||||
/**
|
||||
* Overloaded constructor for the standard Infantry locker container of size 30x20.
|
||||
* @return a `LockerContainer` object
|
||||
*/
|
||||
def apply(): LockerContainer = {
|
||||
new LockerContainer(GridInventory(30, 20))
|
||||
}
|
||||
}
|
||||
|
|
@ -1,69 +1,24 @@
|
|||
// Copyright (c) 2017 PSForever
|
||||
package net.psforever.objects
|
||||
// Copyright (c) 2020 PSForever
|
||||
package net.psforever.objects.locker
|
||||
|
||||
import akka.actor.Actor
|
||||
import net.psforever.objects.definition.EquipmentDefinition
|
||||
import net.psforever.objects.equipment.Equipment
|
||||
import net.psforever.objects.inventory.{Container, GridInventory}
|
||||
import net.psforever.objects.serverobject.PlanetSideServerObject
|
||||
import net.psforever.objects.serverobject.containable.{Containable, ContainableBehavior}
|
||||
import net.psforever.packet.game.{ObjectAttachMessage, ObjectCreateDetailedMessage, ObjectDetachMessage}
|
||||
import net.psforever.packet.game.objectcreate.ObjectCreateMessageParent
|
||||
import net.psforever.types.{PlanetSideEmpire, PlanetSideGUID, Vector3}
|
||||
import net.psforever.packet.game.{ObjectAttachMessage, ObjectCreateDetailedMessage, ObjectDetachMessage}
|
||||
import net.psforever.services.Service
|
||||
import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage}
|
||||
import net.psforever.types.{PlanetSideEmpire, Vector3}
|
||||
|
||||
/**
|
||||
* The companion of a `Locker` that is carried with a player
|
||||
* masquerading as their sixth `EquipmentSlot` object and a sub-inventory item.
|
||||
* The `Player` class refers to it as the "fifth slot" as its permanent slot number is encoded as `0x85`.
|
||||
* The inventory of this object is accessed using a game world `Locker` object (`mb_locker`).
|
||||
* A control agency mainly for manipulating the equipment stowed by a player in a `LockerContainer`
|
||||
* and reporting back to a specific xchannel in the event system about these changes.
|
||||
* @param locker the governed player-facing locker component
|
||||
* @param toChannel the channel to which to publish events, typically the owning player's name
|
||||
*/
|
||||
class LockerContainer extends PlanetSideServerObject with Container {
|
||||
private var faction: PlanetSideEmpire.Value = PlanetSideEmpire.NEUTRAL
|
||||
private val inventory = GridInventory(30, 20)
|
||||
|
||||
def Faction: PlanetSideEmpire.Value = faction
|
||||
|
||||
override def Faction_=(fact: PlanetSideEmpire.Value): PlanetSideEmpire.Value = {
|
||||
faction = fact
|
||||
Faction
|
||||
}
|
||||
|
||||
def Inventory: GridInventory = inventory
|
||||
|
||||
def VisibleSlots: Set[Int] = Set.empty[Int]
|
||||
|
||||
def Definition: EquipmentDefinition = GlobalDefinitions.locker_container
|
||||
}
|
||||
|
||||
object LockerContainer {
|
||||
def apply(): LockerContainer = {
|
||||
new LockerContainer()
|
||||
}
|
||||
}
|
||||
|
||||
class LockerEquipment(locker: LockerContainer) extends Equipment with Container {
|
||||
private val obj = locker
|
||||
|
||||
override def GUID: PlanetSideGUID = obj.GUID
|
||||
|
||||
override def GUID_=(guid: PlanetSideGUID): PlanetSideGUID = obj.GUID_=(guid)
|
||||
|
||||
override def HasGUID: Boolean = obj.HasGUID
|
||||
|
||||
override def Invalidate(): Unit = obj.Invalidate()
|
||||
|
||||
override def Faction: PlanetSideEmpire.Value = obj.Faction
|
||||
|
||||
def Inventory: GridInventory = obj.Inventory
|
||||
|
||||
def VisibleSlots: Set[Int] = Set.empty[Int]
|
||||
|
||||
def Definition: EquipmentDefinition = obj.Definition
|
||||
}
|
||||
|
||||
class LockerContainerControl(locker: LockerContainer, toChannel: String) extends Actor with ContainableBehavior {
|
||||
class LockerContainerControl(locker: LockerContainer, toChannel: String)
|
||||
extends Actor
|
||||
with ContainableBehavior {
|
||||
def ContainerObject = locker
|
||||
|
||||
def receive: Receive =
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
// Copyright (c) 2020 PSForever
|
||||
package net.psforever.objects.locker
|
||||
|
||||
import net.psforever.objects.definition.EquipmentDefinition
|
||||
import net.psforever.objects.equipment.Equipment
|
||||
import net.psforever.objects.inventory.{Container, GridInventory}
|
||||
import net.psforever.types.{PlanetSideEmpire, PlanetSideGUID}
|
||||
|
||||
/**
|
||||
* A wrapper class that allows a player-facing locker component
|
||||
* to be treated standard `Equipment` object in the player's fifth (sixth) slot.
|
||||
* (The opposite is not true - the equipment does not get treated as a locker component.)
|
||||
* During packet conversion and registration and general access in terms of holsters or "equipment slots",
|
||||
* the component may be be treated the same as other existing objects at the same level.
|
||||
* The entity's ability to be utilized like an inventory-stowable entity is not compromised.
|
||||
* @see `EquipmentSlot`
|
||||
* @see `IdentifiableEntity`
|
||||
* @see `LockerContainer`
|
||||
* @param locker the player-facing locker
|
||||
*/
|
||||
class LockerEquipment(locker: LockerContainer)
|
||||
extends Equipment
|
||||
with Container {
|
||||
private val obj = locker
|
||||
|
||||
override def GUID: PlanetSideGUID = obj.GUID
|
||||
|
||||
override def GUID_=(guid: PlanetSideGUID): PlanetSideGUID = obj.GUID_=(guid)
|
||||
|
||||
override def HasGUID: Boolean = obj.HasGUID
|
||||
|
||||
override def Invalidate(): Unit = obj.Invalidate()
|
||||
|
||||
override def Faction: PlanetSideEmpire.Value = obj.Faction
|
||||
|
||||
def Inventory: GridInventory = obj.Inventory
|
||||
|
||||
def VisibleSlots: Set[Int] = Set.empty[Int]
|
||||
|
||||
def Definition: EquipmentDefinition = obj.Definition
|
||||
}
|
||||
|
|
@ -12,7 +12,7 @@ import net.psforever.objects.guid.NumberPoolHub
|
|||
import net.psforever.objects.guid.actor.UniqueNumberSystem
|
||||
import net.psforever.objects.guid.key.LoanedKey
|
||||
import net.psforever.objects.guid.selector.RandomSelector
|
||||
import net.psforever.objects.guid.source.LimitedNumberSource
|
||||
import net.psforever.objects.guid.source.MaxNumberSource
|
||||
import net.psforever.objects.inventory.Container
|
||||
import net.psforever.objects.serverobject.painbox.{Painbox, PainboxDefinition}
|
||||
import net.psforever.objects.serverobject.resourcesilo.ResourceSilo
|
||||
|
|
@ -73,7 +73,7 @@ class Zone(val id: String, val map: ZoneMap, zoneNumber: Int) {
|
|||
private var accessor: ActorRef = ActorRef.noSender
|
||||
|
||||
/** The basic support structure for the globally unique number system used by this `Zone`. */
|
||||
private var guid: NumberPoolHub = new NumberPoolHub(new LimitedNumberSource(65536))
|
||||
private var guid: NumberPoolHub = new NumberPoolHub(new MaxNumberSource(65536))
|
||||
|
||||
/** A synchronized `List` of items (`Equipment`) dropped by players on the ground and can be collected again. */
|
||||
private val equipmentOnGround: ListBuffer[Equipment] = ListBuffer[Equipment]()
|
||||
|
|
@ -322,6 +322,7 @@ class Zone(val id: String, val map: ZoneMap, zoneNumber: Int) {
|
|||
guid.AddPool("f", (30001 to 35000).toList).Selector = new RandomSelector
|
||||
guid.AddPool("g", (35001 until 40100).toList).Selector = new RandomSelector
|
||||
guid.AddPool("projectiles", (Projectile.baseUID until Projectile.rangeUID).toList)
|
||||
guid.AddPool("locker-contents", (40150 until 40450).toList).Selector = new RandomSelector
|
||||
//TODO disabled temporarily to lighten load times
|
||||
//guid.AddPool("h", (40150 to 45000).toList).Selector = new RandomSelector
|
||||
//guid.AddPool("i", (45001 to 50000).toList).Selector = new RandomSelector
|
||||
|
|
@ -358,12 +359,12 @@ class Zone(val id: String, val map: ZoneMap, zoneNumber: Int) {
|
|||
building match {
|
||||
case warpGate: WarpGate =>
|
||||
warpGate.Faction == faction || warpGate.Faction == PlanetSideEmpire.NEUTRAL || warpGate.Broadcast
|
||||
case building =>
|
||||
case _ =>
|
||||
building.Faction == faction
|
||||
}
|
||||
}
|
||||
.map {
|
||||
case (building, spawns) =>
|
||||
case (building, spawns: List[SpawnPoint]) =>
|
||||
(building, spawns.filter(!_.Offline))
|
||||
}
|
||||
.concat(
|
||||
|
|
|
|||
|
|
@ -364,13 +364,12 @@ class PersistenceMonitor(name: String, squadService: ActorRef, taskResolver: Act
|
|||
//player has released
|
||||
//our last body was turned into a corpse; just the avatar remains
|
||||
//TODO perform any last minute saving now ...
|
||||
AvatarLogout(avatar)
|
||||
inZone.GUID(avatar.vehicle) match {
|
||||
case Some(obj: Vehicle) if obj.OwnerName.contains(avatar.name) =>
|
||||
obj.Actor ! Vehicle.Ownership(None)
|
||||
case _ => ;
|
||||
}
|
||||
taskResolver.tell(GUIDTask.UnregisterLocker(avatar.locker)(inZone.GUID), context.parent)
|
||||
AvatarLogout(avatar)
|
||||
|
||||
case _ =>
|
||||
//user stalled during initial session, or was caught in between zone transfer
|
||||
|
|
@ -386,7 +385,7 @@ class PersistenceMonitor(name: String, squadService: ActorRef, taskResolver: Act
|
|||
* @see `Avatar`
|
||||
* @see `AvatarAction.ObjectDelete`
|
||||
* @see `AvatarServiceMessage`
|
||||
* @see `GUIDTask.UnregisterAvatar`
|
||||
* @see `GUIDTask.UnregisterPlayer`
|
||||
* @see `Player`
|
||||
* @see `Zone.AvatarEvents`
|
||||
* @see `Zone.Population.Release`
|
||||
|
|
@ -405,8 +404,8 @@ class PersistenceMonitor(name: String, squadService: ActorRef, taskResolver: Act
|
|||
}
|
||||
inZone.Population.tell(Zone.Population.Release(avatar), parent)
|
||||
inZone.AvatarEvents.tell(AvatarServiceMessage(inZone.id, AvatarAction.ObjectDelete(pguid, pguid)), parent)
|
||||
taskResolver.tell(GUIDTask.UnregisterPlayer(player)(inZone.GUID), parent)
|
||||
AvatarLogout(avatar)
|
||||
taskResolver.tell(GUIDTask.UnregisterAvatar(player)(inZone.GUID), parent)
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -424,6 +423,7 @@ class PersistenceMonitor(name: String, squadService: ActorRef, taskResolver: Act
|
|||
squadService.tell(Service.Leave(Some(avatar.id.toString)), context.parent)
|
||||
Deployables.Disown(inZone, avatar, context.parent)
|
||||
inZone.Population.tell(Zone.Population.Leave(avatar), context.parent)
|
||||
taskResolver.tell(GUIDTask.UnregisterObjectTask(avatar.locker)(inZone.GUID), context.parent)
|
||||
log.info(s"logout of ${avatar.name}")
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,21 +2,14 @@ package net.psforever.zones
|
|||
|
||||
import java.io.FileNotFoundException
|
||||
|
||||
import net.psforever.objects.serverobject.terminals.{
|
||||
CaptureTerminal,
|
||||
CaptureTerminalDefinition,
|
||||
ProximityTerminal,
|
||||
ProximityTerminalDefinition,
|
||||
Terminal,
|
||||
TerminalDefinition
|
||||
}
|
||||
import net.psforever.objects.serverobject.terminals.{CaptureTerminal, CaptureTerminalDefinition, ProximityTerminal, ProximityTerminalDefinition, Terminal, TerminalDefinition}
|
||||
import net.psforever.objects.serverobject.mblocker.Locker
|
||||
import java.util.concurrent.atomic.AtomicInteger
|
||||
|
||||
import akka.actor.ActorContext
|
||||
import io.circe._
|
||||
import io.circe.parser._
|
||||
import net.psforever.objects.{GlobalDefinitions, LocalProjectile}
|
||||
import net.psforever.objects.{GlobalDefinitions, LocalLockerItem, LocalProjectile}
|
||||
import net.psforever.objects.ballistics.Projectile
|
||||
import net.psforever.objects.definition.BasicDefinition
|
||||
import net.psforever.objects.serverobject.doors.Door
|
||||
|
|
@ -25,18 +18,13 @@ import net.psforever.objects.serverobject.locks.IFFLock
|
|||
import net.psforever.objects.serverobject.pad.{VehicleSpawnPad, VehicleSpawnPadDefinition}
|
||||
import net.psforever.objects.serverobject.painbox.{Painbox, PainboxDefinition}
|
||||
import net.psforever.objects.serverobject.resourcesilo.ResourceSilo
|
||||
import net.psforever.objects.serverobject.structures.{
|
||||
Building,
|
||||
BuildingDefinition,
|
||||
FoundationBuilder,
|
||||
StructureType,
|
||||
WarpGate
|
||||
}
|
||||
import net.psforever.objects.serverobject.structures.{Building, BuildingDefinition, FoundationBuilder, StructureType, WarpGate}
|
||||
import net.psforever.objects.serverobject.tube.SpawnTube
|
||||
import net.psforever.objects.serverobject.turret.{FacilityTurret, FacilityTurretDefinition}
|
||||
import net.psforever.objects.zones.{MapInfo, Zone, ZoneInfo, ZoneMap}
|
||||
import net.psforever.types.{PlanetSideEmpire, Vector3}
|
||||
import net.psforever.util.DefinitionUtil
|
||||
|
||||
import scala.io.Source
|
||||
import scala.collection.parallel.CollectionConverters._
|
||||
|
||||
|
|
@ -281,6 +269,9 @@ object Zones {
|
|||
(Projectile.baseUID until Projectile.rangeUID) foreach {
|
||||
zoneMap.addLocalObject(_, LocalProjectile.Constructor)
|
||||
}
|
||||
40150 until 40450 foreach {
|
||||
zoneMap.addLocalObject(_, LocalLockerItem.Constructor)
|
||||
}
|
||||
|
||||
lattice.asObject.get(info.value).foreach { obj =>
|
||||
obj.asArray.get.foreach { entry =>
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import net.psforever.objects.GlobalDefinitions._
|
|||
import net.psforever.objects._
|
||||
import net.psforever.objects.avatar.{Avatar, BattleRank, Implant}
|
||||
import net.psforever.objects.definition.ImplantDefinition
|
||||
import net.psforever.objects.locker.LockerEquipment
|
||||
import net.psforever.types.{CharacterGender, CharacterVoice, ImplantType, PlanetSideEmpire}
|
||||
import org.specs2.mutable._
|
||||
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import net.psforever.objects.avatar.Avatar
|
|||
import net.psforever.objects.definition._
|
||||
import net.psforever.objects.equipment._
|
||||
import net.psforever.objects.inventory.InventoryTile
|
||||
import net.psforever.objects.locker.{LockerContainer, LockerEquipment}
|
||||
import net.psforever.objects.serverobject.terminals.Terminal
|
||||
import net.psforever.objects.serverobject.tube.SpawnTube
|
||||
import net.psforever.objects.vehicles.UtilityType
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import net.psforever.objects._
|
|||
import net.psforever.objects.ballistics._
|
||||
import net.psforever.objects.equipment.JammableUnit
|
||||
import net.psforever.objects.guid.NumberPoolHub
|
||||
import net.psforever.objects.guid.source.LimitedNumberSource
|
||||
import net.psforever.objects.guid.source.MaxNumberSource
|
||||
import net.psforever.objects.serverobject.damage.Damageable
|
||||
import net.psforever.objects.serverobject.generator.{Generator, GeneratorControl}
|
||||
import net.psforever.objects.serverobject.implantmech.{ImplantTerminalMech, ImplantTerminalMechControl}
|
||||
|
|
@ -242,7 +242,7 @@ essentially, treat them more as generic entities whose object types are damageab
|
|||
see specific object type tests in relation to what those object types does above and beyond that during damage
|
||||
*/
|
||||
class DamageableEntityDamageTest extends ActorTest {
|
||||
val guid = new NumberPoolHub(new LimitedNumberSource(5))
|
||||
val guid = new NumberPoolHub(new MaxNumberSource(5))
|
||||
val zone = new Zone("test", new ZoneMap("test"), 0) {
|
||||
override def SetupNumberPools() = {}
|
||||
|
||||
|
|
@ -313,7 +313,7 @@ class DamageableEntityDamageTest extends ActorTest {
|
|||
}
|
||||
|
||||
class DamageableEntityDestroyedTest extends ActorTest {
|
||||
val guid = new NumberPoolHub(new LimitedNumberSource(5))
|
||||
val guid = new NumberPoolHub(new MaxNumberSource(5))
|
||||
val zone = new Zone("test", new ZoneMap("test"), 0) {
|
||||
override def SetupNumberPools() = {}
|
||||
|
||||
|
|
@ -387,7 +387,7 @@ class DamageableEntityDestroyedTest extends ActorTest {
|
|||
}
|
||||
|
||||
class DamageableEntityNotDestroyTwice extends ActorTest {
|
||||
val guid = new NumberPoolHub(new LimitedNumberSource(10))
|
||||
val guid = new NumberPoolHub(new MaxNumberSource(10))
|
||||
val zone = new Zone("test", new ZoneMap("test"), 0) {
|
||||
override def SetupNumberPools() = {}
|
||||
|
||||
|
|
@ -458,7 +458,7 @@ class DamageableEntityNotDestroyTwice extends ActorTest {
|
|||
}
|
||||
|
||||
class DamageableAmenityTest extends ActorTest {
|
||||
val guid = new NumberPoolHub(new LimitedNumberSource(10))
|
||||
val guid = new NumberPoolHub(new MaxNumberSource(10))
|
||||
val zone = new Zone("test", new ZoneMap("test"), 0) {
|
||||
override def SetupNumberPools() = {}
|
||||
|
||||
|
|
@ -546,7 +546,7 @@ class DamageableAmenityTest extends ActorTest {
|
|||
|
||||
class DamageableMountableDamageTest extends ActorTest {
|
||||
//TODO this test with not send HitHint packets because LivePlayers is not being allocated for the players in the zone
|
||||
val guid = new NumberPoolHub(new LimitedNumberSource(10))
|
||||
val guid = new NumberPoolHub(new MaxNumberSource(10))
|
||||
val zone = new Zone("test", new ZoneMap("test"), 0) {
|
||||
override def SetupNumberPools() = {}
|
||||
|
||||
|
|
@ -638,7 +638,7 @@ class DamageableMountableDamageTest extends ActorTest {
|
|||
|
||||
class DamageableMountableDestroyTest extends ActorTest {
|
||||
//TODO this test with not send HitHint packets because LivePlayers is not being allocated for the players in the zone
|
||||
val guid = new NumberPoolHub(new LimitedNumberSource(10))
|
||||
val guid = new NumberPoolHub(new MaxNumberSource(10))
|
||||
val zone = new Zone("test", new ZoneMap("test"), 0) {
|
||||
override def SetupNumberPools() = {}
|
||||
|
||||
|
|
@ -730,7 +730,7 @@ class DamageableMountableDestroyTest extends ActorTest {
|
|||
}
|
||||
|
||||
class DamageableWeaponTurretDamageTest extends ActorTest {
|
||||
val guid = new NumberPoolHub(new LimitedNumberSource(10))
|
||||
val guid = new NumberPoolHub(new MaxNumberSource(10))
|
||||
val zone = new Zone("test", new ZoneMap("test"), 0) {
|
||||
override def SetupNumberPools() = {}
|
||||
GUID(guid)
|
||||
|
|
@ -823,7 +823,7 @@ class DamageableWeaponTurretDamageTest extends ActorTest {
|
|||
}
|
||||
|
||||
class DamageableWeaponTurretJammerTest extends ActorTest {
|
||||
val guid = new NumberPoolHub(new LimitedNumberSource(10))
|
||||
val guid = new NumberPoolHub(new MaxNumberSource(10))
|
||||
val zone = new Zone("test", new ZoneMap("test"), 0) {
|
||||
override def SetupNumberPools() = {}
|
||||
GUID(guid)
|
||||
|
|
@ -918,7 +918,7 @@ class DamageableWeaponTurretJammerTest extends ActorTest {
|
|||
}
|
||||
|
||||
class DamageableWeaponTurretDestructionTest extends ActorTest {
|
||||
val guid = new NumberPoolHub(new LimitedNumberSource(10))
|
||||
val guid = new NumberPoolHub(new MaxNumberSource(10))
|
||||
val zone = new Zone("test", new ZoneMap("test"), 0) {
|
||||
override def SetupNumberPools() = {}
|
||||
GUID(guid)
|
||||
|
|
@ -1069,7 +1069,7 @@ class DamageableWeaponTurretDestructionTest extends ActorTest {
|
|||
}
|
||||
|
||||
class DamageableVehicleDamageTest extends ActorTest {
|
||||
val guid = new NumberPoolHub(new LimitedNumberSource(10))
|
||||
val guid = new NumberPoolHub(new MaxNumberSource(10))
|
||||
val zone = new Zone("test", new ZoneMap("test"), 0) {
|
||||
override def SetupNumberPools() = {}
|
||||
GUID(guid)
|
||||
|
|
@ -1174,7 +1174,7 @@ class DamageableVehicleDamageTest extends ActorTest {
|
|||
}
|
||||
|
||||
class DamageableVehicleDamageMountedTest extends ActorTest {
|
||||
val guid = new NumberPoolHub(new LimitedNumberSource(15))
|
||||
val guid = new NumberPoolHub(new MaxNumberSource(15))
|
||||
val zone = new Zone("test", new ZoneMap("test"), 0) {
|
||||
override def SetupNumberPools() = {}
|
||||
GUID(guid)
|
||||
|
|
@ -1315,7 +1315,7 @@ class DamageableVehicleDamageMountedTest extends ActorTest {
|
|||
}
|
||||
|
||||
class DamageableVehicleJammeringMountedTest extends ActorTest {
|
||||
val guid = new NumberPoolHub(new LimitedNumberSource(15))
|
||||
val guid = new NumberPoolHub(new MaxNumberSource(15))
|
||||
val zone = new Zone("test", new ZoneMap("test"), 0) {
|
||||
override def SetupNumberPools() = {}
|
||||
GUID(guid)
|
||||
|
|
@ -1428,7 +1428,7 @@ class DamageableVehicleJammeringMountedTest extends ActorTest {
|
|||
}
|
||||
|
||||
class DamageableVehicleDestroyTest extends ActorTest {
|
||||
val guid = new NumberPoolHub(new LimitedNumberSource(10))
|
||||
val guid = new NumberPoolHub(new MaxNumberSource(10))
|
||||
val zone = new Zone("test", new ZoneMap("test"), 0) {
|
||||
override def SetupNumberPools() = {}
|
||||
GUID(guid)
|
||||
|
|
@ -1531,7 +1531,7 @@ class DamageableVehicleDestroyTest extends ActorTest {
|
|||
}
|
||||
|
||||
class DamageableVehicleDestroyMountedTest extends ActorTest {
|
||||
val guid = new NumberPoolHub(new LimitedNumberSource(15))
|
||||
val guid = new NumberPoolHub(new MaxNumberSource(15))
|
||||
val zone = new Zone("test", new ZoneMap("test"), 0) {
|
||||
override def SetupNumberPools() = {}
|
||||
GUID(guid)
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import base.ActorTest
|
|||
import net.psforever.objects.ballistics._
|
||||
import net.psforever.objects.ce.DeployedItem
|
||||
import net.psforever.objects.guid.NumberPoolHub
|
||||
import net.psforever.objects.guid.source.LimitedNumberSource
|
||||
import net.psforever.objects.guid.source.MaxNumberSource
|
||||
import net.psforever.objects.serverobject.mount.Mountable
|
||||
import net.psforever.objects.vital.Vitality
|
||||
import net.psforever.objects.zones.{Zone, ZoneMap}
|
||||
|
|
@ -300,7 +300,7 @@ class ShieldGeneratorDeployableTest extends Specification {
|
|||
}
|
||||
|
||||
class ExplosiveDeployableJammerTest extends ActorTest {
|
||||
val guid = new NumberPoolHub(new LimitedNumberSource(10))
|
||||
val guid = new NumberPoolHub(new MaxNumberSource(10))
|
||||
val zone = new Zone("test", new ZoneMap("test"), 0) {
|
||||
override def SetupNumberPools() = {}
|
||||
GUID(guid)
|
||||
|
|
@ -398,7 +398,7 @@ class ExplosiveDeployableJammerTest extends ActorTest {
|
|||
}
|
||||
|
||||
class ExplosiveDeployableJammerExplodeTest extends ActorTest {
|
||||
val guid = new NumberPoolHub(new LimitedNumberSource(10))
|
||||
val guid = new NumberPoolHub(new MaxNumberSource(10))
|
||||
val zone = new Zone("test", new ZoneMap("test"), 0) {
|
||||
override def SetupNumberPools() = {}
|
||||
GUID(guid)
|
||||
|
|
@ -508,7 +508,7 @@ class ExplosiveDeployableJammerExplodeTest extends ActorTest {
|
|||
}
|
||||
|
||||
class ExplosiveDeployableDestructionTest extends ActorTest {
|
||||
val guid = new NumberPoolHub(new LimitedNumberSource(10))
|
||||
val guid = new NumberPoolHub(new MaxNumberSource(10))
|
||||
val zone = new Zone("test", new ZoneMap("test"), 0) {
|
||||
override def SetupNumberPools() = {}
|
||||
GUID(guid)
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import net.psforever.objects.avatar.Avatar
|
|||
import net.psforever.objects.{Default, GlobalDefinitions, Player, Tool}
|
||||
import net.psforever.objects.definition.ToolDefinition
|
||||
import net.psforever.objects.guid.NumberPoolHub
|
||||
import net.psforever.objects.guid.source.LimitedNumberSource
|
||||
import net.psforever.objects.guid.source.MaxNumberSource
|
||||
import net.psforever.objects.serverobject.CommonMessages
|
||||
import net.psforever.objects.serverobject.mount.Mountable
|
||||
import net.psforever.objects.serverobject.structures.{Building, StructureType}
|
||||
|
|
@ -182,7 +182,7 @@ class FacilityTurretControl4Test extends ActorTest {
|
|||
}
|
||||
|
||||
class FacilityTurretControlRestorationTest extends ActorTest {
|
||||
val guid = new NumberPoolHub(new LimitedNumberSource(10))
|
||||
val guid = new NumberPoolHub(new MaxNumberSource(10))
|
||||
val zone = new Zone("test", new ZoneMap("test"), 0) {
|
||||
override def SetupNumberPools() = {}
|
||||
GUID(guid)
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import net.psforever.objects.avatar.Avatar
|
|||
import net.psforever.objects.ballistics._
|
||||
import net.psforever.objects.{GlobalDefinitions, Player, Tool}
|
||||
import net.psforever.objects.guid.NumberPoolHub
|
||||
import net.psforever.objects.guid.source.LimitedNumberSource
|
||||
import net.psforever.objects.guid.source.MaxNumberSource
|
||||
import net.psforever.objects.serverobject.CommonMessages
|
||||
import net.psforever.objects.serverobject.generator.{Generator, GeneratorControl}
|
||||
import net.psforever.objects.serverobject.structures.{Building, StructureType}
|
||||
|
|
@ -46,7 +46,7 @@ class GeneratorControlConstructTest extends ActorTest {
|
|||
}
|
||||
|
||||
class GeneratorControlDamageTest extends ActorTest {
|
||||
val guid = new NumberPoolHub(new LimitedNumberSource(5))
|
||||
val guid = new NumberPoolHub(new MaxNumberSource(5))
|
||||
val zone = new Zone("test", new ZoneMap("test"), 0) {
|
||||
override def SetupNumberPools() = {}
|
||||
GUID(guid)
|
||||
|
|
@ -128,7 +128,7 @@ class GeneratorControlDamageTest extends ActorTest {
|
|||
}
|
||||
|
||||
class GeneratorControlCriticalTest extends ActorTest {
|
||||
val guid = new NumberPoolHub(new LimitedNumberSource(5))
|
||||
val guid = new NumberPoolHub(new MaxNumberSource(5))
|
||||
val zone = new Zone("test", new ZoneMap("test"), 0) {
|
||||
override def SetupNumberPools() = {}
|
||||
GUID(guid)
|
||||
|
|
@ -218,7 +218,7 @@ class GeneratorControlCriticalTest extends ActorTest {
|
|||
}
|
||||
|
||||
class GeneratorControlDestroyedTest extends ActorTest {
|
||||
val guid = new NumberPoolHub(new LimitedNumberSource(5))
|
||||
val guid = new NumberPoolHub(new MaxNumberSource(5))
|
||||
val zone = new Zone("test", new ZoneMap("test"), 0) {
|
||||
override def SetupNumberPools() = {}
|
||||
GUID(guid)
|
||||
|
|
@ -341,7 +341,7 @@ class GeneratorControlKillsTest extends ActorTest {
|
|||
but its SOI information can be loaded with the players manually
|
||||
the players need something to catch the die message
|
||||
*/
|
||||
val guid = new NumberPoolHub(new LimitedNumberSource(5))
|
||||
val guid = new NumberPoolHub(new MaxNumberSource(5))
|
||||
val zone = new Zone("test", new ZoneMap("test"), 0) {
|
||||
override def SetupNumberPools() = {}
|
||||
GUID(guid)
|
||||
|
|
@ -478,7 +478,7 @@ class GeneratorControlKillsTest extends ActorTest {
|
|||
}
|
||||
|
||||
class GeneratorControlNotDestroyTwice extends ActorTest {
|
||||
val guid = new NumberPoolHub(new LimitedNumberSource(10))
|
||||
val guid = new NumberPoolHub(new MaxNumberSource(10))
|
||||
val zone = new Zone("test", new ZoneMap("test"), 0) {
|
||||
override def SetupNumberPools() = {}
|
||||
|
||||
|
|
@ -561,7 +561,7 @@ class GeneratorControlNotDestroyTwice extends ActorTest {
|
|||
}
|
||||
|
||||
class GeneratorControlNotDamageIfExplodingTest extends ActorTest {
|
||||
val guid = new NumberPoolHub(new LimitedNumberSource(5))
|
||||
val guid = new NumberPoolHub(new MaxNumberSource(5))
|
||||
val zone = new Zone("test", new ZoneMap("test"), 0) {
|
||||
override def SetupNumberPools() = {}
|
||||
GUID(guid)
|
||||
|
|
@ -655,7 +655,7 @@ class GeneratorControlNotDamageIfExplodingTest extends ActorTest {
|
|||
}
|
||||
|
||||
class GeneratorControlNotRepairIfExplodingTest extends ActorTest {
|
||||
val guid = new NumberPoolHub(new LimitedNumberSource(5))
|
||||
val guid = new NumberPoolHub(new MaxNumberSource(5))
|
||||
val zone = new Zone("test", new ZoneMap("test"), 0) {
|
||||
override def SetupNumberPools() = {}
|
||||
GUID(guid)
|
||||
|
|
@ -753,7 +753,7 @@ class GeneratorControlNotRepairIfExplodingTest extends ActorTest {
|
|||
}
|
||||
|
||||
class GeneratorControlRepairPastRestorePoint extends ActorTest {
|
||||
val guid = new NumberPoolHub(new LimitedNumberSource(5))
|
||||
val guid = new NumberPoolHub(new MaxNumberSource(5))
|
||||
val zone = new Zone("test", new ZoneMap("test"), 0) {
|
||||
override def SetupNumberPools() = {}
|
||||
GUID(guid)
|
||||
|
|
|
|||
|
|
@ -3,13 +3,13 @@ package objects
|
|||
|
||||
import net.psforever.objects.{AmmoBox, SimpleItem, Tool}
|
||||
import net.psforever.objects.definition.SimpleItemDefinition
|
||||
import net.psforever.objects.inventory.{GridInventory, InventoryDisarrayException, InventoryItem, InventoryTile}
|
||||
import net.psforever.objects.inventory._
|
||||
import net.psforever.objects.GlobalDefinitions.{bullet_9mm, suppressor}
|
||||
import net.psforever.types.PlanetSideGUID
|
||||
import org.specs2.mutable._
|
||||
|
||||
import scala.collection.mutable.ListBuffer
|
||||
import scala.util.{Success, Failure}
|
||||
import scala.util.{Failure, Success}
|
||||
|
||||
class InventoryTest extends Specification {
|
||||
val bullet9mmBox1 = AmmoBox(bullet_9mm)
|
||||
|
|
@ -522,6 +522,168 @@ class InventoryTest extends Specification {
|
|||
}
|
||||
}
|
||||
|
||||
"LocallyRegisteredInventory" should {
|
||||
"construct" in {
|
||||
val obj: LocallyRegisteredInventory = new LocallyRegisteredInventory(List(15))
|
||||
obj.TotalCapacity mustEqual 1
|
||||
obj.Capacity mustEqual 1
|
||||
}
|
||||
|
||||
"insert (and register) item" in {
|
||||
val obj: LocallyRegisteredInventory = new LocallyRegisteredInventory(List(15))
|
||||
obj.Resize(9, 6)
|
||||
obj.Size mustEqual 0
|
||||
val item = AmmoBox(bullet_9mm)
|
||||
item.HasGUID mustEqual false
|
||||
obj.CheckCollisions(2, item) mustEqual Success(Nil)
|
||||
obj += 2 -> item
|
||||
obj.Size mustEqual 1
|
||||
obj.hasItem(PlanetSideGUID(15)).contains(item) mustEqual true
|
||||
item.HasGUID mustEqual true
|
||||
item.GUID mustEqual PlanetSideGUID(15)
|
||||
}
|
||||
|
||||
"insert (and register) complex item" in {
|
||||
val obj: LocallyRegisteredInventory = new LocallyRegisteredInventory(List(15, 16))
|
||||
obj.Resize(9, 6)
|
||||
obj.Size mustEqual 0
|
||||
val item = Tool(suppressor)
|
||||
item.HasGUID mustEqual false
|
||||
item.AmmoSlot.Box.HasGUID mustEqual false
|
||||
obj.CheckCollisions(2, item) mustEqual Success(Nil)
|
||||
obj += 2 -> item
|
||||
obj.Size mustEqual 1
|
||||
item.HasGUID mustEqual true
|
||||
item.AmmoSlot.Box.HasGUID mustEqual true
|
||||
}
|
||||
|
||||
"not insert item if already registered" in {
|
||||
val obj: LocallyRegisteredInventory = new LocallyRegisteredInventory(List(15))
|
||||
obj.Resize(9, 6)
|
||||
obj.Size mustEqual 0
|
||||
val item = AmmoBox(bullet_9mm)
|
||||
item.GUID = PlanetSideGUID(10) //artificially register
|
||||
item.HasGUID mustEqual true
|
||||
|
||||
obj.CheckCollisions(2, item) mustEqual Success(Nil) //insert should be possible
|
||||
obj += 2 -> item
|
||||
obj.Size mustEqual 0
|
||||
obj.hasItem(PlanetSideGUID(15)).isEmpty mustEqual true
|
||||
}
|
||||
|
||||
"not insert (or register) item if no (more) GUID's are available" in {
|
||||
val obj: LocallyRegisteredInventory = new LocallyRegisteredInventory(List(15))
|
||||
obj.Resize(9, 6)
|
||||
val item1 = AmmoBox(bullet_9mm)
|
||||
val item2 = AmmoBox(bullet_9mm)
|
||||
item1.HasGUID mustEqual false
|
||||
item2.HasGUID mustEqual false
|
||||
|
||||
obj.CheckCollisions(2, item1) mustEqual Success(Nil) //insert should be possible
|
||||
obj += 2 -> item1
|
||||
obj.Size mustEqual 1
|
||||
obj.hasItem(PlanetSideGUID(15)).contains(item1) mustEqual true
|
||||
item1.HasGUID mustEqual true
|
||||
item1.GUID mustEqual PlanetSideGUID(15)
|
||||
|
||||
obj.CheckCollisions(5, item2) mustEqual Success(Nil) //insert should be possible
|
||||
obj += 5 -> item2
|
||||
obj.Size mustEqual 1
|
||||
item2.HasGUID mustEqual false
|
||||
}
|
||||
|
||||
"not insert (or register) complex item if no (more) GUID's are available" in {
|
||||
val item = Tool(suppressor)
|
||||
val obj: LocallyRegisteredInventory = new LocallyRegisteredInventory(List(15))
|
||||
obj.Resize(9, 6)
|
||||
obj.Size mustEqual 0
|
||||
item.HasGUID mustEqual false
|
||||
item.AmmoSlot.Box.HasGUID mustEqual false
|
||||
|
||||
obj.CheckCollisions(2, item) mustEqual Success(Nil) //insert should be possible
|
||||
obj += 2 -> item
|
||||
obj.Size mustEqual 0
|
||||
item.HasGUID mustEqual false
|
||||
item.AmmoSlot.Box.HasGUID mustEqual false
|
||||
}
|
||||
|
||||
"insert (and register) multiple items" in {
|
||||
val obj: LocallyRegisteredInventory = new LocallyRegisteredInventory(List(15, 17))
|
||||
obj.Resize(9, 6)
|
||||
val item1 = AmmoBox(bullet_9mm)
|
||||
val item2 = AmmoBox(bullet_9mm)
|
||||
item1.HasGUID mustEqual false
|
||||
item2.HasGUID mustEqual false
|
||||
|
||||
obj.CheckCollisions(2, item1) mustEqual Success(Nil) //insert should be possible
|
||||
obj += 2 -> item1
|
||||
obj.Size mustEqual 1
|
||||
item1.HasGUID mustEqual true
|
||||
|
||||
obj.CheckCollisions(5, item2) mustEqual Success(Nil) //insert should be possible
|
||||
obj += 5 -> item2
|
||||
obj.Size mustEqual 2
|
||||
item2.HasGUID mustEqual true
|
||||
}
|
||||
|
||||
"clear (and unregister) all items" in {
|
||||
val obj: LocallyRegisteredInventory = new LocallyRegisteredInventory(List(15, 17))
|
||||
obj.Resize(9, 6)
|
||||
val item1 = AmmoBox(bullet_9mm)
|
||||
val item2 = AmmoBox(bullet_9mm)
|
||||
obj += 2 -> item1
|
||||
obj += 5 -> item2
|
||||
obj.Size mustEqual 2
|
||||
item1.HasGUID mustEqual true
|
||||
item2.HasGUID mustEqual true
|
||||
|
||||
obj.Clear()
|
||||
obj.Size mustEqual 0
|
||||
item1.HasGUID mustEqual false
|
||||
item2.HasGUID mustEqual false
|
||||
}
|
||||
|
||||
"remove (and unregister) item" in {
|
||||
val obj: LocallyRegisteredInventory = new LocallyRegisteredInventory(List(15, 17))
|
||||
obj.Resize(9, 6)
|
||||
val item1 = AmmoBox(bullet_9mm)
|
||||
val item2 = AmmoBox(bullet_9mm)
|
||||
obj += 2 -> item1
|
||||
obj += 5 -> item2
|
||||
obj.Size mustEqual 2
|
||||
item1.HasGUID mustEqual true
|
||||
item2.HasGUID mustEqual true
|
||||
|
||||
obj -= 2
|
||||
obj.Size mustEqual 1
|
||||
item1.HasGUID mustEqual false
|
||||
item2.HasGUID mustEqual true
|
||||
|
||||
obj -= 5
|
||||
obj.Size mustEqual 0
|
||||
item1.HasGUID mustEqual false
|
||||
item2.HasGUID mustEqual false
|
||||
}
|
||||
}
|
||||
|
||||
"remove (and unregister) complex item" in {
|
||||
val obj: LocallyRegisteredInventory = new LocallyRegisteredInventory(List(15, 17))
|
||||
obj.Resize(9, 6)
|
||||
val item = Tool(suppressor)
|
||||
item.HasGUID mustEqual false
|
||||
item.AmmoSlot.Box.HasGUID mustEqual false
|
||||
obj.CheckCollisions(2, item) mustEqual Success(Nil)
|
||||
obj += 2 -> item
|
||||
obj.Size mustEqual 1
|
||||
item.HasGUID mustEqual true
|
||||
item.AmmoSlot.Box.HasGUID mustEqual true
|
||||
|
||||
obj -= 2
|
||||
obj.Size mustEqual 0
|
||||
item.HasGUID mustEqual false
|
||||
item.AmmoSlot.Box.HasGUID mustEqual false
|
||||
}
|
||||
|
||||
"InventoryEquiupmentSlot" should {
|
||||
"insert, collide, insert" in {
|
||||
val obj: GridInventory = GridInventory(7, 7)
|
||||
|
|
|
|||
24
src/test/scala/objects/LocalTest.scala
Normal file
24
src/test/scala/objects/LocalTest.scala
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
package objects
|
||||
|
||||
import net.psforever.objects.{LocalLockerItem, LocalProjectile}
|
||||
import net.psforever.types.PlanetSideEmpire
|
||||
import org.specs2.mutable.Specification
|
||||
|
||||
class LocalTest extends Specification {
|
||||
"LocalProjectile" should {
|
||||
"construct" in {
|
||||
val obj = new LocalProjectile() //since they're just placeholders, they only need to construct
|
||||
obj.Definition.ObjectId mustEqual 0
|
||||
obj.Definition.Name mustEqual "projectile"
|
||||
}
|
||||
}
|
||||
|
||||
"LocalLockerItem" should {
|
||||
"construct" in {
|
||||
val obj = new LocalLockerItem() //since they're just placeholders, they only need to construct
|
||||
obj.Faction mustEqual PlanetSideEmpire.NEUTRAL
|
||||
obj.Definition.ObjectId mustEqual 0
|
||||
obj.Definition.Name mustEqual "locker-equipment"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -7,7 +7,7 @@ import base.ActorTest
|
|||
import net.psforever.objects.avatar.{Avatar, PlayerControl}
|
||||
import net.psforever.objects.ballistics._
|
||||
import net.psforever.objects.guid.NumberPoolHub
|
||||
import net.psforever.objects.guid.source.LimitedNumberSource
|
||||
import net.psforever.objects.guid.source.MaxNumberSource
|
||||
import net.psforever.objects.vital.Vitality
|
||||
import net.psforever.objects.zones.{Zone, ZoneMap}
|
||||
import net.psforever.objects._
|
||||
|
|
@ -20,7 +20,7 @@ import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage}
|
|||
import scala.concurrent.duration._
|
||||
|
||||
class PlayerControlHealTest extends ActorTest {
|
||||
val guid = new NumberPoolHub(new LimitedNumberSource(15))
|
||||
val guid = new NumberPoolHub(new MaxNumberSource(15))
|
||||
val zone = new Zone("test", new ZoneMap("test"), 0) {
|
||||
override def SetupNumberPools() = {}
|
||||
GUID(guid)
|
||||
|
|
@ -106,7 +106,7 @@ class PlayerControlHealTest extends ActorTest {
|
|||
}
|
||||
|
||||
class PlayerControlHealSelfTest extends ActorTest {
|
||||
val guid = new NumberPoolHub(new LimitedNumberSource(15))
|
||||
val guid = new NumberPoolHub(new MaxNumberSource(15))
|
||||
val zone = new Zone("test", new ZoneMap("test"), 0) {
|
||||
override def SetupNumberPools() = {}
|
||||
GUID(guid)
|
||||
|
|
@ -181,7 +181,7 @@ class PlayerControlHealSelfTest extends ActorTest {
|
|||
}
|
||||
|
||||
class PlayerControlRepairTest extends ActorTest {
|
||||
val guid = new NumberPoolHub(new LimitedNumberSource(15))
|
||||
val guid = new NumberPoolHub(new MaxNumberSource(15))
|
||||
val zone = new Zone("test", new ZoneMap("test"), 0) {
|
||||
override def SetupNumberPools() = {}
|
||||
GUID(guid)
|
||||
|
|
@ -277,7 +277,7 @@ class PlayerControlRepairTest extends ActorTest {
|
|||
}
|
||||
|
||||
class PlayerControlRepairSelfTest extends ActorTest {
|
||||
val guid = new NumberPoolHub(new LimitedNumberSource(15))
|
||||
val guid = new NumberPoolHub(new MaxNumberSource(15))
|
||||
val zone = new Zone("test", new ZoneMap("test"), 0) {
|
||||
override def SetupNumberPools() = {}
|
||||
GUID(guid)
|
||||
|
|
@ -352,7 +352,7 @@ class PlayerControlRepairSelfTest extends ActorTest {
|
|||
}
|
||||
|
||||
class PlayerControlDamageTest extends ActorTest {
|
||||
val guid = new NumberPoolHub(new LimitedNumberSource(15))
|
||||
val guid = new NumberPoolHub(new MaxNumberSource(15))
|
||||
val zone = new Zone("test", new ZoneMap("test"), 0) {
|
||||
override def SetupNumberPools() = {}
|
||||
GUID(guid)
|
||||
|
|
@ -449,7 +449,7 @@ class PlayerControlDamageTest extends ActorTest {
|
|||
}
|
||||
|
||||
class PlayerControlDeathStandingTest extends ActorTest {
|
||||
val guid = new NumberPoolHub(new LimitedNumberSource(15))
|
||||
val guid = new NumberPoolHub(new MaxNumberSource(15))
|
||||
val zone = new Zone("test", new ZoneMap("test"), 0) {
|
||||
override def SetupNumberPools() = {}
|
||||
GUID(guid)
|
||||
|
|
@ -575,7 +575,7 @@ class PlayerControlDeathStandingTest extends ActorTest {
|
|||
}
|
||||
|
||||
class PlayerControlDeathSeatedTest extends ActorTest {
|
||||
val guid = new NumberPoolHub(new LimitedNumberSource(15))
|
||||
val guid = new NumberPoolHub(new MaxNumberSource(15))
|
||||
val zone = new Zone("test", new ZoneMap("test"), 0) {
|
||||
override def SetupNumberPools() = {}
|
||||
GUID(guid)
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import net.psforever.objects._
|
|||
import net.psforever.objects.avatar.Avatar
|
||||
import net.psforever.objects.definition.{SimpleItemDefinition, SpecialExoSuitDefinition}
|
||||
import net.psforever.objects.equipment.EquipmentSize
|
||||
import net.psforever.objects.locker.LockerEquipment
|
||||
import net.psforever.types.{PlanetSideGUID, _}
|
||||
import org.specs2.mutable._
|
||||
|
||||
|
|
|
|||
|
|
@ -14,13 +14,7 @@ class ProjectileTest extends Specification {
|
|||
val player = Player(Avatar(0, "TestCharacter", PlanetSideEmpire.TR, CharacterGender.Male, 0, CharacterVoice.Mute))
|
||||
val fury = Vehicle(GlobalDefinitions.fury)
|
||||
|
||||
"LocalProjectile" should {
|
||||
"construct" in {
|
||||
val obj = new LocalProjectile() //since they're just placeholders, they only need to construct
|
||||
obj.Definition.ObjectId mustEqual 0
|
||||
obj.Definition.Name mustEqual "projectile"
|
||||
}
|
||||
|
||||
"Range" should {
|
||||
"local projectile range" in {
|
||||
Projectile.baseUID < Projectile.rangeUID mustEqual true
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import base.ActorTest
|
|||
import net.psforever.objects._
|
||||
import net.psforever.objects.avatar.Avatar
|
||||
import net.psforever.objects.guid.NumberPoolHub
|
||||
import net.psforever.objects.guid.source.LimitedNumberSource
|
||||
import net.psforever.objects.guid.source.MaxNumberSource
|
||||
import net.psforever.objects.serverobject.CommonMessages
|
||||
import net.psforever.objects.serverobject.generator.{Generator, GeneratorControl}
|
||||
import net.psforever.objects.serverobject.structures.{Building, StructureType}
|
||||
|
|
@ -28,7 +28,7 @@ essentially, treat it more as a generic entity whose object type is repairable
|
|||
see GeneratorTest in relation to what the generator does above and beyond that during repair
|
||||
*/
|
||||
class RepairableEntityRepairTest extends ActorTest {
|
||||
val guid = new NumberPoolHub(new LimitedNumberSource(10))
|
||||
val guid = new NumberPoolHub(new MaxNumberSource(10))
|
||||
val zone = new Zone("test", new ZoneMap("test"), 0) {
|
||||
override def SetupNumberPools() = {}
|
||||
|
||||
|
|
@ -100,7 +100,7 @@ class RepairableEntityRepairTest extends ActorTest {
|
|||
}
|
||||
|
||||
class RepairableEntityNotRepairTest extends ActorTest {
|
||||
val guid = new NumberPoolHub(new LimitedNumberSource(10))
|
||||
val guid = new NumberPoolHub(new MaxNumberSource(10))
|
||||
val zone = new Zone("test", new ZoneMap("test"), 0) {
|
||||
override def SetupNumberPools() = {}
|
||||
|
||||
|
|
@ -141,7 +141,7 @@ class RepairableEntityNotRepairTest extends ActorTest {
|
|||
}
|
||||
|
||||
class RepairableAmenityTest extends ActorTest {
|
||||
val guid = new NumberPoolHub(new LimitedNumberSource(10))
|
||||
val guid = new NumberPoolHub(new MaxNumberSource(10))
|
||||
val zone = new Zone("test", new ZoneMap("test"), 0) {
|
||||
override def SetupNumberPools() = {}
|
||||
|
||||
|
|
@ -229,7 +229,7 @@ class RepairableAmenityTest extends ActorTest {
|
|||
}
|
||||
|
||||
class RepairableTurretWeapon extends ActorTest {
|
||||
val guid = new NumberPoolHub(new LimitedNumberSource(10))
|
||||
val guid = new NumberPoolHub(new MaxNumberSource(10))
|
||||
val zone = new Zone("test", new ZoneMap("test"), 0) {
|
||||
override def SetupNumberPools() = {}
|
||||
GUID(guid)
|
||||
|
|
@ -323,7 +323,7 @@ class RepairableTurretWeapon extends ActorTest {
|
|||
}
|
||||
|
||||
class RepairableVehicleRepair extends ActorTest {
|
||||
val guid = new NumberPoolHub(new LimitedNumberSource(10))
|
||||
val guid = new NumberPoolHub(new MaxNumberSource(10))
|
||||
val zone = new Zone("test", new ZoneMap("test"), 0) {
|
||||
override def SetupNumberPools() = {}
|
||||
GUID(guid)
|
||||
|
|
@ -396,7 +396,7 @@ class RepairableVehicleRestoration extends ActorTest {
|
|||
/*
|
||||
no messages are dispatched, in this case, because most vehicles are flagged to not be repairable if destroyed
|
||||
*/
|
||||
val guid = new NumberPoolHub(new LimitedNumberSource(10))
|
||||
val guid = new NumberPoolHub(new MaxNumberSource(10))
|
||||
val zone = new Zone("test", new ZoneMap("test"), 0) {
|
||||
override def SetupNumberPools() = {}
|
||||
GUID(guid)
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import akka.testkit.TestProbe
|
|||
import base.ActorTest
|
||||
import net.psforever.actors.zone.{BuildingActor, ZoneActor}
|
||||
import net.psforever.objects.guid.{NumberPoolHub, TaskResolver}
|
||||
import net.psforever.objects.guid.source.LimitedNumberSource
|
||||
import net.psforever.objects.guid.source.MaxNumberSource
|
||||
import net.psforever.objects.serverobject.CommonMessages
|
||||
import net.psforever.objects.{GlobalDefinitions, Ntu, Player, Vehicle}
|
||||
import net.psforever.objects.serverobject.resourcesilo.{ResourceSilo, ResourceSiloControl, ResourceSiloDefinition}
|
||||
|
|
@ -94,7 +94,7 @@ class ResourceSiloControlStartupTest extends ActorTest {
|
|||
}
|
||||
|
||||
class ResourceSiloControlUseTest extends ActorTest {
|
||||
val guid = new NumberPoolHub(new LimitedNumberSource(10))
|
||||
val guid = new NumberPoolHub(new MaxNumberSource(10))
|
||||
val map = new ZoneMap("test")
|
||||
val zone = new Zone("test", map, 0) {
|
||||
override def SetupNumberPools() = {}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
// Copyright (c) 2017 PSForever
|
||||
package objects
|
||||
|
||||
import akka.actor.{Actor, ActorContext, Props}
|
||||
import base.ActorTest
|
||||
import akka.actor.ActorContext
|
||||
import base.FreedContextActorTest
|
||||
import net.psforever.objects.GlobalDefinitions
|
||||
import net.psforever.objects.guid.NumberPoolHub
|
||||
import net.psforever.objects.serverobject.ServerObjectBuilder
|
||||
|
|
@ -11,361 +11,223 @@ import net.psforever.objects.serverobject.terminals.ProximityTerminal
|
|||
import net.psforever.objects.zones.Zone
|
||||
import net.psforever.types.{PlanetSideGUID, Vector3}
|
||||
|
||||
import scala.concurrent.duration.Duration
|
||||
|
||||
class BuildingBuilderTest extends ActorTest {
|
||||
class BuildingBuilderTest extends FreedContextActorTest {
|
||||
"Building object" should {
|
||||
"build" in {
|
||||
val structure: (String, Int, Int, Zone, ActorContext) => Building = Building.Structure(StructureType.Building)
|
||||
val actor = system.actorOf(
|
||||
Props(classOf[ServerObjectBuilderTest.BuildingTestActor], structure, "Building", 10, 10, Zone.Nowhere),
|
||||
"building"
|
||||
)
|
||||
actor ! "!"
|
||||
|
||||
val reply = receiveOne(Duration.create(1000, "ms"))
|
||||
assert(reply.isInstanceOf[Building])
|
||||
assert(reply.asInstanceOf[Building].MapId == 10)
|
||||
assert(reply.asInstanceOf[Building].Zone == Zone.Nowhere)
|
||||
val building = FoundationBuilder(structure).Build("building", 10, 10, Zone.Nowhere)(context)
|
||||
assert(building ne null)
|
||||
assert(building.isInstanceOf[Building])
|
||||
assert(building.MapId == 10)
|
||||
assert(building.Zone == Zone.Nowhere)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class WarpGateBuilderTest extends ActorTest {
|
||||
class WarpGateBuilderTest extends FreedContextActorTest {
|
||||
"WarpGate object" should {
|
||||
"build" in {
|
||||
val structure: (String, Int, Int, Zone, ActorContext) => Building = WarpGate.Structure
|
||||
val actor = system.actorOf(
|
||||
Props(classOf[ServerObjectBuilderTest.BuildingTestActor], structure, "wgate", 10, 10, Zone.Nowhere),
|
||||
"wgate"
|
||||
)
|
||||
actor ! "!"
|
||||
|
||||
val reply = receiveOne(Duration.create(1000, "ms"))
|
||||
assert(reply.isInstanceOf[Building])
|
||||
assert(reply.asInstanceOf[Building].MapId == 10)
|
||||
assert(reply.asInstanceOf[Building].Zone == Zone.Nowhere)
|
||||
val building = FoundationBuilder(structure).Build("wgate", 10, 10, Zone.Nowhere)(context)
|
||||
assert(building ne null)
|
||||
assert(building.isInstanceOf[WarpGate])
|
||||
assert(building.MapId == 10)
|
||||
assert(building.Zone == Zone.Nowhere)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class DoorObjectBuilderTest1 extends ActorTest {
|
||||
class DoorObjectBuilderTest1 extends FreedContextActorTest {
|
||||
import net.psforever.objects.serverobject.doors.Door
|
||||
"Door object" should {
|
||||
"build" in {
|
||||
val hub = ServerObjectBuilderTest.NumberPoolHub
|
||||
val actor = system.actorOf(
|
||||
Props(classOf[ServerObjectBuilderTest.BuilderTestActor], ServerObjectBuilder(1, Door.Constructor), hub),
|
||||
"door"
|
||||
)
|
||||
actor ! "!"
|
||||
|
||||
val reply = receiveOne(Duration.create(1000, "ms"))
|
||||
assert(reply.isInstanceOf[Door])
|
||||
assert(reply.asInstanceOf[Door].HasGUID)
|
||||
assert(reply.asInstanceOf[Door].GUID == PlanetSideGUID(1))
|
||||
assert(reply == hub(1).get)
|
||||
val obj = ServerObjectBuilder(1, Door.Constructor).Build(context, hub)
|
||||
assert(obj.isInstanceOf[Door])
|
||||
assert(obj.HasGUID)
|
||||
assert(obj.GUID == PlanetSideGUID(1))
|
||||
assert(obj == hub(1).get)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class DoorObjectBuilderTest2 extends ActorTest {
|
||||
class DoorObjectBuilderTest2 extends FreedContextActorTest {
|
||||
import net.psforever.objects.serverobject.doors.Door
|
||||
"Door object" should {
|
||||
"build" in {
|
||||
val hub = ServerObjectBuilderTest.NumberPoolHub
|
||||
val actor = system.actorOf(
|
||||
Props(
|
||||
classOf[ServerObjectBuilderTest.BuilderTestActor],
|
||||
ServerObjectBuilder(1, Door.Constructor(Vector3(1, 2, 3))),
|
||||
hub
|
||||
),
|
||||
"door"
|
||||
)
|
||||
actor ! "!"
|
||||
|
||||
val reply = receiveOne(Duration.create(1000, "ms"))
|
||||
assert(reply.isInstanceOf[Door])
|
||||
assert(reply.asInstanceOf[Door].Position == Vector3(1, 2, 3))
|
||||
assert(reply.asInstanceOf[Door].HasGUID)
|
||||
assert(reply.asInstanceOf[Door].GUID == PlanetSideGUID(1))
|
||||
assert(reply == hub(1).get)
|
||||
val obj = ServerObjectBuilder(1, Door.Constructor(Vector3(1, 2, 3))).Build(context, hub)
|
||||
assert(obj.isInstanceOf[Door])
|
||||
assert(obj.HasGUID)
|
||||
assert(obj.GUID == PlanetSideGUID(1))
|
||||
assert(obj == hub(1).get)
|
||||
assert(obj.Position == Vector3(1, 2, 3))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class IFFLockObjectBuilderTest extends ActorTest {
|
||||
class IFFLockObjectBuilderTest extends FreedContextActorTest {
|
||||
import net.psforever.objects.serverobject.locks.IFFLock
|
||||
"IFFLock object" should {
|
||||
"build" in {
|
||||
val hub = ServerObjectBuilderTest.NumberPoolHub
|
||||
val actor = system.actorOf(
|
||||
Props(
|
||||
classOf[ServerObjectBuilderTest.BuilderTestActor],
|
||||
ServerObjectBuilder(1, IFFLock.Constructor(Vector3(0f, 0f, 0f), Vector3(0f, 0f, 0f))),
|
||||
hub
|
||||
),
|
||||
"lock"
|
||||
)
|
||||
actor ! "!"
|
||||
|
||||
val reply = receiveOne(Duration.create(1000, "ms"))
|
||||
assert(reply.isInstanceOf[IFFLock])
|
||||
assert(reply.asInstanceOf[IFFLock].HasGUID)
|
||||
assert(reply.asInstanceOf[IFFLock].GUID == PlanetSideGUID(1))
|
||||
assert(reply == hub(1).get)
|
||||
val obj = ServerObjectBuilder(1, IFFLock.Constructor(Vector3(1f, 1f, 1f), Vector3(2f, 2f, 2f))).Build(context, hub)
|
||||
assert(obj.isInstanceOf[IFFLock])
|
||||
assert(obj.HasGUID)
|
||||
assert(obj.GUID == PlanetSideGUID(1))
|
||||
assert(obj.Position == Vector3(1,1,1))
|
||||
assert(obj.Outwards == Vector3(0.034899496f, 0.99939084f, 0.0f))
|
||||
assert(obj == hub(1).get)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class ImplantTerminalMechObjectBuilderTest extends ActorTest {
|
||||
class ImplantTerminalMechObjectBuilderTest extends FreedContextActorTest {
|
||||
import net.psforever.objects.serverobject.implantmech.ImplantTerminalMech
|
||||
"Implant terminal mech object" should {
|
||||
"build" in {
|
||||
val hub = ServerObjectBuilderTest.NumberPoolHub
|
||||
val actor = system.actorOf(
|
||||
Props(
|
||||
classOf[ServerObjectBuilderTest.BuilderTestActor],
|
||||
ServerObjectBuilder(1, ImplantTerminalMech.Constructor(Vector3.Zero)),
|
||||
hub
|
||||
),
|
||||
"mech"
|
||||
)
|
||||
actor ! "!"
|
||||
|
||||
val reply = receiveOne(Duration.create(1000, "ms"))
|
||||
assert(reply.isInstanceOf[ImplantTerminalMech])
|
||||
assert(reply.asInstanceOf[ImplantTerminalMech].HasGUID)
|
||||
assert(reply.asInstanceOf[ImplantTerminalMech].GUID == PlanetSideGUID(1))
|
||||
assert(reply == hub(1).get)
|
||||
val obj = ServerObjectBuilder(1, ImplantTerminalMech.Constructor(Vector3.Zero)).Build(context, hub)
|
||||
assert(obj.isInstanceOf[ImplantTerminalMech])
|
||||
assert(obj.HasGUID)
|
||||
assert(obj.GUID == PlanetSideGUID(1))
|
||||
assert(obj == hub(1).get)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class TerminalObjectBuilderTest extends ActorTest {
|
||||
class TerminalObjectBuilderTest extends FreedContextActorTest {
|
||||
import net.psforever.objects.GlobalDefinitions.order_terminal
|
||||
import net.psforever.objects.serverobject.terminals.Terminal
|
||||
"Terminal object" should {
|
||||
"build" in {
|
||||
val hub = ServerObjectBuilderTest.NumberPoolHub
|
||||
val actor = system.actorOf(
|
||||
Props(
|
||||
classOf[ServerObjectBuilderTest.BuilderTestActor],
|
||||
ServerObjectBuilder(1, Terminal.Constructor(Vector3(1.1f, 2.2f, 3.3f), order_terminal)),
|
||||
hub
|
||||
),
|
||||
"term"
|
||||
)
|
||||
actor ! "!"
|
||||
|
||||
val reply = receiveOne(Duration.create(1000, "ms"))
|
||||
assert(reply.isInstanceOf[Terminal])
|
||||
assert(reply.asInstanceOf[Terminal].HasGUID)
|
||||
assert(reply.asInstanceOf[Terminal].GUID == PlanetSideGUID(1))
|
||||
assert(reply.asInstanceOf[Terminal].Position == Vector3(1.1f, 2.2f, 3.3f))
|
||||
assert(reply == hub(1).get)
|
||||
val obj = ServerObjectBuilder(1, Terminal.Constructor(Vector3(1.1f, 2.2f, 3.3f), order_terminal)).Build(context, hub)
|
||||
assert(obj.isInstanceOf[Terminal])
|
||||
assert(obj.HasGUID)
|
||||
assert(obj.GUID == PlanetSideGUID(1))
|
||||
assert(obj.Position == Vector3(1.1f, 2.2f, 3.3f))
|
||||
assert(obj == hub(1).get)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class ProximityTerminalObjectBuilderTest extends ActorTest {
|
||||
class ProximityTerminalObjectBuilderTest extends FreedContextActorTest {
|
||||
import net.psforever.objects.GlobalDefinitions.medical_terminal
|
||||
import net.psforever.objects.serverobject.terminals.Terminal
|
||||
"Terminal object" should {
|
||||
"build" in {
|
||||
val hub = ServerObjectBuilderTest.NumberPoolHub
|
||||
val actor = system.actorOf(
|
||||
Props(
|
||||
classOf[ServerObjectBuilderTest.BuilderTestActor],
|
||||
ServerObjectBuilder(1, ProximityTerminal.Constructor(medical_terminal)),
|
||||
hub
|
||||
),
|
||||
"term"
|
||||
)
|
||||
actor ! "!"
|
||||
|
||||
val reply = receiveOne(Duration.create(1000, "ms"))
|
||||
assert(reply.isInstanceOf[Terminal])
|
||||
assert(reply.asInstanceOf[Terminal].HasGUID)
|
||||
assert(reply.asInstanceOf[Terminal].GUID == PlanetSideGUID(1))
|
||||
assert(reply == hub(1).get)
|
||||
val obj = ServerObjectBuilder(1, ProximityTerminal.Constructor(medical_terminal)).Build(context, hub)
|
||||
assert(obj.isInstanceOf[Terminal])
|
||||
assert(obj.HasGUID)
|
||||
assert(obj.GUID == PlanetSideGUID(1))
|
||||
assert(obj == hub(1).get)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class VehicleSpawnPadObjectBuilderTest extends ActorTest {
|
||||
class VehicleSpawnPadObjectBuilderTest extends FreedContextActorTest {
|
||||
import net.psforever.objects.serverobject.pad.VehicleSpawnPad
|
||||
"Vehicle spawn pad object" should {
|
||||
"build" in {
|
||||
val hub = ServerObjectBuilderTest.NumberPoolHub
|
||||
val actor = system.actorOf(
|
||||
Props(
|
||||
classOf[ServerObjectBuilderTest.BuilderTestActor],
|
||||
ServerObjectBuilder(
|
||||
1,
|
||||
VehicleSpawnPad
|
||||
.Constructor(Vector3(1.1f, 2.2f, 3.3f), GlobalDefinitions.mb_pad_creation, Vector3(4.4f, 5.5f, 6.6f))
|
||||
),
|
||||
hub
|
||||
),
|
||||
"pad"
|
||||
)
|
||||
actor ! "!"
|
||||
|
||||
val reply = receiveOne(Duration.create(1000, "ms"))
|
||||
assert(reply.isInstanceOf[VehicleSpawnPad])
|
||||
assert(reply.asInstanceOf[VehicleSpawnPad].HasGUID)
|
||||
assert(reply.asInstanceOf[VehicleSpawnPad].GUID == PlanetSideGUID(1))
|
||||
assert(reply.asInstanceOf[VehicleSpawnPad].Position == Vector3(1.1f, 2.2f, 3.3f))
|
||||
assert(reply.asInstanceOf[VehicleSpawnPad].Orientation == Vector3(4.4f, 5.5f, 6.6f))
|
||||
assert(reply == hub(1).get)
|
||||
val obj = ServerObjectBuilder(1,
|
||||
VehicleSpawnPad.Constructor(
|
||||
Vector3(1.1f, 2.2f, 3.3f), GlobalDefinitions.mb_pad_creation, Vector3(4.4f, 5.5f, 6.6f)
|
||||
)
|
||||
).Build(context, hub)
|
||||
assert(obj.isInstanceOf[VehicleSpawnPad])
|
||||
assert(obj.HasGUID)
|
||||
assert(obj.GUID == PlanetSideGUID(1))
|
||||
assert(obj.Position == Vector3(1.1f, 2.2f, 3.3f))
|
||||
assert(obj.Orientation == Vector3(4.4f, 5.5f, 6.6f))
|
||||
assert(obj == hub(1).get)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class LocalProjectileBuilderTest extends ActorTest {
|
||||
class LocalProjectileBuilderTest extends FreedContextActorTest {
|
||||
import net.psforever.objects.LocalProjectile
|
||||
"Local projectile object" should {
|
||||
"build" in {
|
||||
val hub = ServerObjectBuilderTest.NumberPoolHub
|
||||
val actor = system.actorOf(
|
||||
Props(
|
||||
classOf[ServerObjectBuilderTest.BuilderTestActor],
|
||||
ServerObjectBuilder(1, LocalProjectile.Constructor),
|
||||
hub
|
||||
),
|
||||
"locker"
|
||||
)
|
||||
actor ! "!"
|
||||
|
||||
val reply = receiveOne(Duration.create(1000, "ms"))
|
||||
assert(reply.isInstanceOf[LocalProjectile])
|
||||
assert(reply.asInstanceOf[LocalProjectile].HasGUID)
|
||||
assert(reply.asInstanceOf[LocalProjectile].GUID == PlanetSideGUID(1))
|
||||
assert(reply == hub(1).get)
|
||||
val obj = ServerObjectBuilder(1, LocalProjectile.Constructor).Build(context, hub)
|
||||
assert(obj.isInstanceOf[LocalProjectile])
|
||||
assert(obj.HasGUID)
|
||||
assert(obj.GUID == PlanetSideGUID(1))
|
||||
assert(obj == hub(1).get)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class LockerObjectBuilderTest extends ActorTest {
|
||||
class LockerObjectBuilderTest extends FreedContextActorTest {
|
||||
import net.psforever.objects.serverobject.mblocker.Locker
|
||||
"Locker object" should {
|
||||
"build" in {
|
||||
val hub = ServerObjectBuilderTest.NumberPoolHub
|
||||
val actor = system.actorOf(
|
||||
Props(classOf[ServerObjectBuilderTest.BuilderTestActor], ServerObjectBuilder(1, Locker.Constructor), hub),
|
||||
"locker"
|
||||
)
|
||||
actor ! "!"
|
||||
|
||||
val reply = receiveOne(Duration.create(1000, "ms"))
|
||||
assert(reply.isInstanceOf[Locker])
|
||||
assert(reply.asInstanceOf[Locker].HasGUID)
|
||||
assert(reply.asInstanceOf[Locker].GUID == PlanetSideGUID(1))
|
||||
assert(reply == hub(1).get)
|
||||
val obj = ServerObjectBuilder(1, Locker.Constructor).Build(context, hub)
|
||||
assert(obj.isInstanceOf[Locker])
|
||||
assert(obj.HasGUID)
|
||||
assert(obj.GUID == PlanetSideGUID(1))
|
||||
assert(obj == hub(1).get)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class ResourceSiloObjectBuilderTest extends ActorTest {
|
||||
class ResourceSiloObjectBuilderTest extends FreedContextActorTest {
|
||||
import net.psforever.objects.serverobject.resourcesilo.ResourceSilo
|
||||
"Resource silo object" should {
|
||||
"build" in {
|
||||
val hub = ServerObjectBuilderTest.NumberPoolHub
|
||||
val actor = system.actorOf(
|
||||
Props(
|
||||
classOf[ServerObjectBuilderTest.BuilderTestActor],
|
||||
ServerObjectBuilder(1, ResourceSilo.Constructor(Vector3(0f, 0f, 0f))),
|
||||
hub
|
||||
),
|
||||
"resource-silo"
|
||||
)
|
||||
actor ! "startup"
|
||||
|
||||
val reply = receiveOne(Duration.create(1000, "ms"))
|
||||
assert(reply.isInstanceOf[ResourceSilo])
|
||||
assert(reply.asInstanceOf[ResourceSilo].HasGUID)
|
||||
assert(reply.asInstanceOf[ResourceSilo].GUID == PlanetSideGUID(1))
|
||||
assert(reply == hub(1).get)
|
||||
val obj = ServerObjectBuilder(1, ResourceSilo.Constructor(Vector3(1f, 1f, 1f))).Build(context, hub)
|
||||
assert(obj.isInstanceOf[ResourceSilo])
|
||||
assert(obj.HasGUID)
|
||||
assert(obj.GUID == PlanetSideGUID(1))
|
||||
assert(obj.Position == Vector3(1,1,1))
|
||||
assert(obj == hub(1).get)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class SpawnTubeObjectBuilderTest extends ActorTest {
|
||||
class SpawnTubeObjectBuilderTest extends FreedContextActorTest {
|
||||
import net.psforever.objects.serverobject.tube.SpawnTube
|
||||
"Spawn tube object" should {
|
||||
"build" in {
|
||||
val hub = ServerObjectBuilderTest.NumberPoolHub
|
||||
val actor = system.actorOf(
|
||||
Props(
|
||||
classOf[ServerObjectBuilderTest.BuilderTestActor],
|
||||
ServerObjectBuilder(1, SpawnTube.Constructor(Vector3(3980.4062f, 4267.3047f, 257.5625f), Vector3(0, 0, 90))),
|
||||
hub
|
||||
),
|
||||
"spawn-tube"
|
||||
)
|
||||
actor ! "!"
|
||||
|
||||
val reply = receiveOne(Duration.create(1000, "ms"))
|
||||
assert(reply.isInstanceOf[SpawnTube])
|
||||
assert(reply.asInstanceOf[SpawnTube].HasGUID)
|
||||
assert(reply.asInstanceOf[SpawnTube].GUID == PlanetSideGUID(1))
|
||||
assert(reply.asInstanceOf[SpawnTube].Position == Vector3(3980.4062f, 4267.3047f, 257.5625f))
|
||||
assert(reply.asInstanceOf[SpawnTube].Orientation == Vector3(0, 0, 90))
|
||||
assert(reply == hub(1).get)
|
||||
val obj = ServerObjectBuilder(
|
||||
1,
|
||||
SpawnTube.Constructor(Vector3(3980.4062f, 4267.3047f, 257.5625f), Vector3(0, 0, 90))
|
||||
).Build(context, hub)
|
||||
assert(obj.isInstanceOf[SpawnTube])
|
||||
assert(obj.HasGUID)
|
||||
assert(obj.GUID == PlanetSideGUID(1))
|
||||
assert(obj.Position == Vector3(3980.4062f, 4267.3047f, 257.5625f))
|
||||
assert(obj.Orientation == Vector3(0, 0, 90))
|
||||
assert(obj == hub(1).get)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class FacilityTurretObjectBuilderTest extends ActorTest {
|
||||
class FacilityTurretObjectBuilderTest extends FreedContextActorTest {
|
||||
import net.psforever.objects.GlobalDefinitions.manned_turret
|
||||
import net.psforever.objects.serverobject.turret.FacilityTurret
|
||||
"FacilityTurretObjectBuilder" should {
|
||||
"build" in {
|
||||
val hub = ServerObjectBuilderTest.NumberPoolHub
|
||||
val actor = system.actorOf(
|
||||
Props(
|
||||
classOf[ServerObjectBuilderTest.BuilderTestActor],
|
||||
ServerObjectBuilder(1, FacilityTurret.Constructor(manned_turret)),
|
||||
hub
|
||||
),
|
||||
"manned-turret"
|
||||
)
|
||||
actor ! "!"
|
||||
|
||||
val reply = receiveOne(Duration.create(1000, "ms"))
|
||||
assert(reply.isInstanceOf[FacilityTurret])
|
||||
assert(reply.asInstanceOf[FacilityTurret].HasGUID)
|
||||
assert(reply.asInstanceOf[FacilityTurret].GUID == PlanetSideGUID(1))
|
||||
assert(reply == hub(1).get)
|
||||
val obj = ServerObjectBuilder(1, FacilityTurret.Constructor(manned_turret)).Build(context, hub)
|
||||
assert(obj.isInstanceOf[FacilityTurret])
|
||||
assert(obj.HasGUID)
|
||||
assert(obj.GUID == PlanetSideGUID(1))
|
||||
assert(obj == hub(1).get)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
object ServerObjectBuilderTest {
|
||||
import net.psforever.objects.guid.source.LimitedNumberSource
|
||||
import net.psforever.objects.guid.source.MaxNumberSource
|
||||
def NumberPoolHub: NumberPoolHub = {
|
||||
val obj = new NumberPoolHub(new LimitedNumberSource(2))
|
||||
val obj = new NumberPoolHub(new MaxNumberSource(2))
|
||||
obj
|
||||
}
|
||||
|
||||
class BuilderTestActor(builder: ServerObjectBuilder[_], hub: NumberPoolHub) extends Actor {
|
||||
def receive: Receive = {
|
||||
case _ =>
|
||||
sender() ! builder.Build(context, hub)
|
||||
}
|
||||
}
|
||||
|
||||
class BuildingTestActor(
|
||||
structure_con: (String, Int, Int, Zone, ActorContext) => Building,
|
||||
name: String,
|
||||
building_guid: Int,
|
||||
map_id: Int,
|
||||
zone: Zone
|
||||
) extends Actor {
|
||||
def receive: Receive = {
|
||||
case _ =>
|
||||
sender() ! FoundationBuilder(structure_con).Build(name, building_guid, map_id, zone)(context)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import base.{ActorTest, FreedContextActorTest}
|
|||
import net.psforever.objects._
|
||||
import net.psforever.objects.definition.{SeatDefinition, VehicleDefinition}
|
||||
import net.psforever.objects.guid.NumberPoolHub
|
||||
import net.psforever.objects.guid.source.LimitedNumberSource
|
||||
import net.psforever.objects.guid.source.MaxNumberSource
|
||||
import net.psforever.objects.serverobject.mount.Mountable
|
||||
import net.psforever.objects.vehicles._
|
||||
import net.psforever.objects.vital.VehicleShieldCharge
|
||||
|
|
@ -408,7 +408,7 @@ class VehicleControlPrepareForDeletionPassengerTest extends ActorTest {
|
|||
|
||||
class VehicleControlPrepareForDeletionMountedInTest extends FreedContextActorTest {
|
||||
ServiceManager.boot
|
||||
val guid = new NumberPoolHub(new LimitedNumberSource(10))
|
||||
val guid = new NumberPoolHub(new MaxNumberSource(10))
|
||||
val zone = new Zone("test", new ZoneMap("test"), 0) {
|
||||
GUID(guid)
|
||||
|
||||
|
|
@ -534,7 +534,7 @@ class VehicleControlPrepareForDeletionMountedInTest extends FreedContextActorTes
|
|||
}
|
||||
|
||||
class VehicleControlPrepareForDeletionMountedCargoTest extends FreedContextActorTest {
|
||||
val guid = new NumberPoolHub(new LimitedNumberSource(10))
|
||||
val guid = new NumberPoolHub(new MaxNumberSource(10))
|
||||
ServiceManager.boot
|
||||
val zone = new Zone("test", new ZoneMap("test"), 0) {
|
||||
GUID(guid)
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import base.ActorTest
|
|||
import net.psforever.objects.entity.IdentifiableEntity
|
||||
import net.psforever.objects.equipment.Equipment
|
||||
import net.psforever.objects.guid.NumberPoolHub
|
||||
import net.psforever.objects.guid.source.LimitedNumberSource
|
||||
import net.psforever.objects.guid.source.MaxNumberSource
|
||||
import net.psforever.objects.serverobject.terminals.Terminal
|
||||
import net.psforever.objects.serverobject.tube.SpawnTube
|
||||
import net.psforever.objects._
|
||||
|
|
@ -104,7 +104,7 @@ class ZoneTest extends Specification {
|
|||
|
||||
"can have its unique identifier system changed if no objects were added to it" in {
|
||||
val zone = new Zone("home3", map13, 13)
|
||||
val guid1: NumberPoolHub = new NumberPoolHub(new LimitedNumberSource(100))
|
||||
val guid1: NumberPoolHub = new NumberPoolHub(new MaxNumberSource(100))
|
||||
zone.GUID(guid1) mustEqual true
|
||||
zone.AddPool("pool1", (0 to 50).toList)
|
||||
zone.AddPool("pool2", (51 to 75).toList)
|
||||
|
|
@ -114,7 +114,7 @@ class ZoneTest extends Specification {
|
|||
registration.isSuccess mustEqual true
|
||||
guid1.WhichPool(obj).contains("pool2") mustEqual true
|
||||
|
||||
zone.GUID(new NumberPoolHub(new LimitedNumberSource(150))) mustEqual false
|
||||
zone.GUID(new NumberPoolHub(new MaxNumberSource(150))) mustEqual false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -123,7 +123,7 @@ class ZoneActorTest extends ActorTest {
|
|||
"Zone" should {
|
||||
"refuse new number pools after the Actor is started" in {
|
||||
val zone = new Zone("test", new ZoneMap("map6"), 1) { override def SetupNumberPools() = {} }
|
||||
zone.GUID(new NumberPoolHub(new LimitedNumberSource(40150)))
|
||||
zone.GUID(new NumberPoolHub(new MaxNumberSource(40150)))
|
||||
zone.actor = system.spawn(ZoneActor(zone), "test-add-pool-actor-init")
|
||||
expectNoMessage(Duration.create(500, "ms"))
|
||||
|
||||
|
|
@ -133,7 +133,7 @@ class ZoneActorTest extends ActorTest {
|
|||
"refuse to remove number pools after the Actor is started" in {
|
||||
val zone = new Zone("test", new ZoneMap("map6"), 1) { override def SetupNumberPools() = {} }
|
||||
|
||||
zone.GUID(new NumberPoolHub(new LimitedNumberSource(10)))
|
||||
zone.GUID(new NumberPoolHub(new MaxNumberSource(10)))
|
||||
zone.AddPool("test", 1 to 2)
|
||||
zone.actor = system.spawn(ZoneActor(zone), "test-remove-pool-actor-init")
|
||||
expectNoMessage(Duration.create(300, "ms"))
|
||||
|
|
@ -482,7 +482,7 @@ class ZonePopulationTest extends ActorTest {
|
|||
|
||||
class ZoneGroundDropItemTest extends ActorTest {
|
||||
val item = AmmoBox(GlobalDefinitions.bullet_9mm)
|
||||
val hub = new NumberPoolHub(new LimitedNumberSource(20))
|
||||
val hub = new NumberPoolHub(new MaxNumberSource(20))
|
||||
hub.register(item, 10)
|
||||
val zone = new Zone("test", new ZoneMap("test-map"), 0) { override def SetupNumberPools() = {} }
|
||||
zone.GUID(hub)
|
||||
|
|
@ -507,7 +507,7 @@ class ZoneGroundDropItemTest extends ActorTest {
|
|||
|
||||
class ZoneGroundCanNotDropItem1Test extends ActorTest {
|
||||
val item = AmmoBox(GlobalDefinitions.bullet_9mm)
|
||||
val hub = new NumberPoolHub(new LimitedNumberSource(20))
|
||||
val hub = new NumberPoolHub(new MaxNumberSource(20))
|
||||
//hub.register(item, 10) //!important
|
||||
val zone = new Zone("test", new ZoneMap("test-map"), 0) { override def SetupNumberPools() = {} }
|
||||
zone.GUID(hub)
|
||||
|
|
@ -532,7 +532,7 @@ class ZoneGroundCanNotDropItem1Test extends ActorTest {
|
|||
|
||||
class ZoneGroundCanNotDropItem2Test extends ActorTest {
|
||||
val item = AmmoBox(GlobalDefinitions.bullet_9mm)
|
||||
val hub = new NumberPoolHub(new LimitedNumberSource(20))
|
||||
val hub = new NumberPoolHub(new MaxNumberSource(20))
|
||||
hub.register(item, 10) //!important
|
||||
val zone = new Zone("test", new ZoneMap("test-map"), 0) { override def SetupNumberPools() = {} }
|
||||
//zone.GUID(hub) //!important
|
||||
|
|
@ -557,7 +557,7 @@ class ZoneGroundCanNotDropItem2Test extends ActorTest {
|
|||
|
||||
class ZoneGroundCanNotDropItem3Test extends ActorTest {
|
||||
val item = AmmoBox(GlobalDefinitions.bullet_9mm)
|
||||
val hub = new NumberPoolHub(new LimitedNumberSource(20))
|
||||
val hub = new NumberPoolHub(new MaxNumberSource(20))
|
||||
hub.register(item, 10) //!important
|
||||
val zone = new Zone("test", new ZoneMap("test-map"), 0) { override def SetupNumberPools() = {} }
|
||||
zone.GUID(hub) //!important
|
||||
|
|
@ -590,7 +590,7 @@ class ZoneGroundCanNotDropItem3Test extends ActorTest {
|
|||
|
||||
class ZoneGroundPickupItemTest extends ActorTest {
|
||||
val item = AmmoBox(GlobalDefinitions.bullet_9mm)
|
||||
val hub = new NumberPoolHub(new LimitedNumberSource(20))
|
||||
val hub = new NumberPoolHub(new MaxNumberSource(20))
|
||||
hub.register(item, 10)
|
||||
val zone = new Zone("test", new ZoneMap("test-map"), 0) { override def SetupNumberPools() = {} }
|
||||
zone.GUID(hub)
|
||||
|
|
@ -618,7 +618,7 @@ class ZoneGroundPickupItemTest extends ActorTest {
|
|||
|
||||
class ZoneGroundCanNotPickupItemTest extends ActorTest {
|
||||
val item = AmmoBox(GlobalDefinitions.bullet_9mm)
|
||||
val hub = new NumberPoolHub(new LimitedNumberSource(20))
|
||||
val hub = new NumberPoolHub(new MaxNumberSource(20))
|
||||
hub.register(item, 10)
|
||||
val zone = new Zone("test", new ZoneMap("test-map"), 0) { override def SetupNumberPools() = {} }
|
||||
zone.GUID(hub) //still registered to this zone
|
||||
|
|
@ -642,7 +642,7 @@ class ZoneGroundCanNotPickupItemTest extends ActorTest {
|
|||
|
||||
class ZoneGroundRemoveItemTest extends ActorTest {
|
||||
val item = AmmoBox(GlobalDefinitions.bullet_9mm)
|
||||
val hub = new NumberPoolHub(new LimitedNumberSource(20))
|
||||
val hub = new NumberPoolHub(new MaxNumberSource(20))
|
||||
hub.register(item, 10)
|
||||
val zone = new Zone("test", new ZoneMap("test-map"), 0) { override def SetupNumberPools() = {} }
|
||||
zone.GUID(hub) //still registered to this zone
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import base.ActorTest
|
|||
import net.psforever.objects._
|
||||
import net.psforever.objects.avatar.Avatar
|
||||
import net.psforever.objects.guid.{GUIDTask, TaskResolver}
|
||||
import net.psforever.objects.locker.LockerEquipment
|
||||
import net.psforever.types.{CharacterGender, CharacterVoice, PlanetSideEmpire}
|
||||
|
||||
class GUIDTaskRegisterAvatarTest extends ActorTest {
|
||||
|
|
@ -26,7 +27,7 @@ class GUIDTaskRegisterAvatarTest extends ActorTest {
|
|||
assert(!obj_wep_ammo.HasGUID)
|
||||
assert(!obj_inv_ammo.HasGUID)
|
||||
assert(!obj_locker.HasGUID)
|
||||
assert(!obj_locker_ammo.HasGUID)
|
||||
assert(obj_locker_ammo.HasGUID)
|
||||
taskResolver ! TaskResolver.GiveTask(
|
||||
new GUIDTaskTest.RegisterTestTask(probe.ref),
|
||||
List(GUIDTask.RegisterAvatar(obj)(uns))
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import base.ActorTest
|
|||
import net.psforever.objects._
|
||||
import net.psforever.objects.avatar.Avatar
|
||||
import net.psforever.objects.guid.{GUIDTask, TaskResolver}
|
||||
import net.psforever.objects.locker.LockerEquipment
|
||||
import net.psforever.types.{CharacterGender, CharacterVoice, PlanetSideEmpire}
|
||||
|
||||
class GUIDTaskRegisterPlayerTest extends ActorTest {
|
||||
|
|
@ -26,7 +27,7 @@ class GUIDTaskRegisterPlayerTest extends ActorTest {
|
|||
assert(!obj_wep_ammo.HasGUID)
|
||||
assert(!obj_inv_ammo.HasGUID)
|
||||
assert(!obj_locker.HasGUID)
|
||||
assert(!obj_locker_ammo.HasGUID)
|
||||
assert(obj_locker_ammo.HasGUID)
|
||||
taskResolver ! TaskResolver.GiveTask(
|
||||
new GUIDTaskTest.RegisterTestTask(probe.ref),
|
||||
List(GUIDTask.RegisterPlayer(obj)(uns))
|
||||
|
|
@ -37,6 +38,6 @@ class GUIDTaskRegisterPlayerTest extends ActorTest {
|
|||
assert(obj_wep_ammo.HasGUID)
|
||||
assert(obj_inv_ammo.HasGUID)
|
||||
assert(!obj_locker.HasGUID)
|
||||
assert(!obj_locker_ammo.HasGUID)
|
||||
assert(obj_locker_ammo.HasGUID)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import akka.testkit.TestProbe
|
|||
import net.psforever.objects.entity.IdentifiableEntity
|
||||
import net.psforever.objects.guid.actor.{NumberPoolActor, UniqueNumberSystem}
|
||||
import net.psforever.objects.guid.selector.RandomSelector
|
||||
import net.psforever.objects.guid.source.LimitedNumberSource
|
||||
import net.psforever.objects.guid.source.MaxNumberSource
|
||||
import net.psforever.objects.guid.{NumberPoolHub, Task, TaskResolver}
|
||||
|
||||
object GUIDTaskTest {
|
||||
|
|
@ -26,7 +26,7 @@ object GUIDTaskTest {
|
|||
import akka.routing.RandomPool
|
||||
import akka.testkit.TestProbe
|
||||
|
||||
val guid: NumberPoolHub = new NumberPoolHub(new LimitedNumberSource(110))
|
||||
val guid: NumberPoolHub = new NumberPoolHub(new MaxNumberSource(110))
|
||||
guid.AddPool("dynamic", (1 to 100).toList).Selector = new RandomSelector //TODO name is hardcoded for now
|
||||
val uns = system.actorOf(
|
||||
RandomPool(25).props(Props(classOf[UniqueNumberSystem], guid, GUIDTaskTest.AllocateNumberPoolActors(guid))),
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import base.ActorTest
|
|||
import net.psforever.objects._
|
||||
import net.psforever.objects.avatar.Avatar
|
||||
import net.psforever.objects.guid.{GUIDTask, TaskResolver}
|
||||
import net.psforever.objects.locker.LockerEquipment
|
||||
import net.psforever.types.{CharacterGender, CharacterVoice, PlanetSideEmpire}
|
||||
|
||||
class GUIDTaskUnregisterAvatarTest extends ActorTest {
|
||||
|
|
@ -43,6 +44,6 @@ class GUIDTaskUnregisterAvatarTest extends ActorTest {
|
|||
assert(!obj_wep_ammo.HasGUID)
|
||||
assert(!obj_inv_ammo.HasGUID)
|
||||
assert(!obj_locker.HasGUID)
|
||||
assert(!obj_locker_ammo.HasGUID)
|
||||
assert(obj_locker_ammo.HasGUID)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import base.ActorTest
|
|||
import net.psforever.objects._
|
||||
import net.psforever.objects.avatar.Avatar
|
||||
import net.psforever.objects.guid.{GUIDTask, TaskResolver}
|
||||
import net.psforever.objects.locker.LockerEquipment
|
||||
import net.psforever.types.{CharacterGender, CharacterVoice, PlanetSideEmpire}
|
||||
|
||||
class GUIDTaskUnregisterPlayerTest extends ActorTest {
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ package objects.number
|
|||
import net.psforever.objects.entity.IdentifiableEntity
|
||||
import net.psforever.objects.guid.NumberPoolHub
|
||||
import net.psforever.objects.guid.selector.RandomSelector
|
||||
import net.psforever.objects.guid.source.LimitedNumberSource
|
||||
import net.psforever.objects.guid.source.MaxNumberSource
|
||||
import net.psforever.types.PlanetSideGUID
|
||||
import org.specs2.mutable.Specification
|
||||
|
||||
|
|
@ -20,17 +20,17 @@ class NumberPoolHubTest extends Specification {
|
|||
|
||||
"NumberPoolHub" should {
|
||||
"construct" in {
|
||||
new NumberPoolHub(new LimitedNumberSource(51))
|
||||
new NumberPoolHub(new MaxNumberSource(51))
|
||||
ok
|
||||
}
|
||||
|
||||
"get a pool" in {
|
||||
val obj = new NumberPoolHub(new LimitedNumberSource(51))
|
||||
val obj = new NumberPoolHub(new MaxNumberSource(51))
|
||||
obj.GetPool("generic").isDefined mustEqual true //default pool
|
||||
}
|
||||
|
||||
"add a pool" in {
|
||||
val obj = new NumberPoolHub(new LimitedNumberSource(51))
|
||||
val obj = new NumberPoolHub(new MaxNumberSource(51))
|
||||
obj.Numbers.isEmpty mustEqual true
|
||||
obj.AddPool("fibonacci", numberList)
|
||||
obj.Numbers.toSet.equals(numberList.toSet) mustEqual true
|
||||
|
|
@ -40,7 +40,7 @@ class NumberPoolHubTest extends Specification {
|
|||
}
|
||||
|
||||
"enumerate the content of all pools" in {
|
||||
val obj = new NumberPoolHub(new LimitedNumberSource(51))
|
||||
val obj = new NumberPoolHub(new MaxNumberSource(51))
|
||||
obj.AddPool("fibonacci1", numberList1)
|
||||
obj.AddPool("fibonacci2", numberList2)
|
||||
numberSet1.intersect(obj.Numbers.toSet) mustEqual numberSet1
|
||||
|
|
@ -49,7 +49,7 @@ class NumberPoolHubTest extends Specification {
|
|||
}
|
||||
|
||||
"remove a pool" in {
|
||||
val obj = new NumberPoolHub(new LimitedNumberSource(51))
|
||||
val obj = new NumberPoolHub(new MaxNumberSource(51))
|
||||
obj.Numbers.isEmpty mustEqual true
|
||||
obj.AddPool("fibonacci", numberList)
|
||||
obj.Numbers.toSet.equals(numberList.toSet) mustEqual true
|
||||
|
|
@ -59,19 +59,19 @@ class NumberPoolHubTest extends Specification {
|
|||
}
|
||||
|
||||
"block removing the default 'generic' pool" in {
|
||||
val obj = new NumberPoolHub(new LimitedNumberSource(51))
|
||||
val obj = new NumberPoolHub(new MaxNumberSource(51))
|
||||
obj.RemovePool("generic") must throwA[IllegalArgumentException]
|
||||
}
|
||||
|
||||
"block adding pools that use already-included numbers" in {
|
||||
val obj = new NumberPoolHub(new LimitedNumberSource(51))
|
||||
val obj = new NumberPoolHub(new MaxNumberSource(51))
|
||||
obj.AddPool("fibonacci1", numberList)
|
||||
val numberList4 = 3 :: 7 :: 21 :: 34 :: 45 :: Nil
|
||||
obj.AddPool("fibonacci2", numberList4) must throwA[IllegalArgumentException]
|
||||
}
|
||||
|
||||
"enumerate only the content of all current pools" in {
|
||||
val obj = new NumberPoolHub(new LimitedNumberSource(51))
|
||||
val obj = new NumberPoolHub(new MaxNumberSource(51))
|
||||
obj.AddPool("fibonacci1", numberList1)
|
||||
obj.AddPool("fibonacci2", numberList2)
|
||||
numberSet1.intersect(obj.Numbers.toSet) mustEqual numberSet1
|
||||
|
|
@ -82,7 +82,7 @@ class NumberPoolHubTest extends Specification {
|
|||
}
|
||||
|
||||
"register an object to a pool" in {
|
||||
val hub = new NumberPoolHub(new LimitedNumberSource(51))
|
||||
val hub = new NumberPoolHub(new MaxNumberSource(51))
|
||||
hub.AddPool("fibonacci", numberList)
|
||||
val obj = new EntityTestClass()
|
||||
obj.GUID must throwA[Exception]
|
||||
|
|
@ -95,7 +95,7 @@ class NumberPoolHubTest extends Specification {
|
|||
}
|
||||
|
||||
"lookup a registered object" in {
|
||||
val hub = new NumberPoolHub(new LimitedNumberSource(51))
|
||||
val hub = new NumberPoolHub(new MaxNumberSource(51))
|
||||
hub.AddPool("fibonacci", numberList)
|
||||
val obj = new EntityTestClass()
|
||||
hub.register(obj, "fibonacci") match {
|
||||
|
|
@ -108,14 +108,14 @@ class NumberPoolHubTest extends Specification {
|
|||
}
|
||||
|
||||
"lookup the pool of a(n unassigned) number" in {
|
||||
val hub = new NumberPoolHub(new LimitedNumberSource(51))
|
||||
val hub = new NumberPoolHub(new MaxNumberSource(51))
|
||||
hub.AddPool("fibonacci1", numberList1)
|
||||
hub.AddPool("fibonacci2", numberList2)
|
||||
hub.WhichPool(13).contains("fibonacci2") mustEqual true
|
||||
}
|
||||
|
||||
"lookup the pool of a registered object" in {
|
||||
val hub = new NumberPoolHub(new LimitedNumberSource(51))
|
||||
val hub = new NumberPoolHub(new MaxNumberSource(51))
|
||||
hub.AddPool("fibonacci", numberList1)
|
||||
val obj = new EntityTestClass()
|
||||
hub.register(obj, "fibonacci")
|
||||
|
|
@ -123,7 +123,7 @@ class NumberPoolHubTest extends Specification {
|
|||
}
|
||||
|
||||
"register an object to a specific, unused number; it is assigned to pool 'generic'" in {
|
||||
val hub = new NumberPoolHub(new LimitedNumberSource(51))
|
||||
val hub = new NumberPoolHub(new MaxNumberSource(51))
|
||||
hub.AddPool("fibonacci", numberList1)
|
||||
val obj = new EntityTestClass()
|
||||
obj.GUID must throwA[Exception]
|
||||
|
|
@ -137,7 +137,7 @@ class NumberPoolHubTest extends Specification {
|
|||
}
|
||||
|
||||
"register an object to a specific, pooled number (list 1)" in {
|
||||
val src = new LimitedNumberSource(51)
|
||||
val src = new MaxNumberSource(51)
|
||||
val hub = new NumberPoolHub(src)
|
||||
hub.AddPool("fibonacci", numberList)
|
||||
val obj = new EntityTestClass()
|
||||
|
|
@ -146,14 +146,14 @@ class NumberPoolHubTest extends Specification {
|
|||
case Success(number) =>
|
||||
obj.GUID mustEqual PlanetSideGUID(number)
|
||||
hub.WhichPool(obj).contains("fibonacci") mustEqual true
|
||||
src.Available(5).isEmpty mustEqual true
|
||||
src.getAvailable(5).isEmpty mustEqual true
|
||||
case _ =>
|
||||
ko
|
||||
}
|
||||
}
|
||||
|
||||
"register an object to a specific, pooled number (list 2)" in {
|
||||
val src = new LimitedNumberSource(51)
|
||||
val src = new MaxNumberSource(51)
|
||||
val hub = new NumberPoolHub(src)
|
||||
hub.AddPool("fibonacci", numberList2)
|
||||
val obj = new EntityTestClass()
|
||||
|
|
@ -162,21 +162,21 @@ class NumberPoolHubTest extends Specification {
|
|||
case Success(number) =>
|
||||
obj.GUID mustEqual PlanetSideGUID(number)
|
||||
hub.WhichPool(obj).contains("fibonacci") mustEqual true
|
||||
src.Available(13).isEmpty mustEqual true
|
||||
src.getAvailable(13).isEmpty mustEqual true
|
||||
case _ =>
|
||||
ko
|
||||
}
|
||||
}
|
||||
|
||||
"register an object without extra specifications; it is assigned to pool 'generic'" in {
|
||||
val hub = new NumberPoolHub(new LimitedNumberSource(51))
|
||||
val hub = new NumberPoolHub(new MaxNumberSource(51))
|
||||
val obj = new EntityTestClass()
|
||||
hub.register(obj)
|
||||
hub.WhichPool(obj).contains("generic") mustEqual true
|
||||
}
|
||||
|
||||
"unregister an object" in {
|
||||
val hub = new NumberPoolHub(new LimitedNumberSource(51))
|
||||
val hub = new NumberPoolHub(new MaxNumberSource(51))
|
||||
hub.AddPool("fibonacci", numberList)
|
||||
val obj = new EntityTestClass()
|
||||
obj.HasGUID mustEqual false
|
||||
|
|
@ -190,7 +190,7 @@ class NumberPoolHubTest extends Specification {
|
|||
}
|
||||
|
||||
"not register an object to a different pool" in {
|
||||
val hub = new NumberPoolHub(new LimitedNumberSource(51))
|
||||
val hub = new NumberPoolHub(new MaxNumberSource(51))
|
||||
hub.AddPool("fibonacci1", numberList1)
|
||||
hub.AddPool("fibonacci2", numberList2)
|
||||
val obj = new EntityTestClass()
|
||||
|
|
@ -200,17 +200,17 @@ class NumberPoolHubTest extends Specification {
|
|||
}
|
||||
|
||||
"fail to unregister an object that is not registered to this hub" in {
|
||||
val hub1 = new NumberPoolHub(new LimitedNumberSource(51))
|
||||
val hub2 = new NumberPoolHub(new LimitedNumberSource(51))
|
||||
val hub1 = new NumberPoolHub(new MaxNumberSource(51))
|
||||
val hub2 = new NumberPoolHub(new MaxNumberSource(51))
|
||||
hub1.AddPool("fibonacci", numberList)
|
||||
hub2.AddPool("fibonacci", numberList)
|
||||
val obj = new EntityTestClass()
|
||||
hub1.register(obj, "fibonacci")
|
||||
hub2.unregister(obj) must throwA[Exception]
|
||||
hub2.unregister(obj).isFailure mustEqual true
|
||||
}
|
||||
|
||||
"pre-register a specific, unused number" in {
|
||||
val hub = new NumberPoolHub(new LimitedNumberSource(51))
|
||||
val hub = new NumberPoolHub(new MaxNumberSource(51))
|
||||
hub.register(13) match {
|
||||
case Success(_) =>
|
||||
ok
|
||||
|
|
@ -220,7 +220,7 @@ class NumberPoolHubTest extends Specification {
|
|||
}
|
||||
|
||||
"pre-register a specific, pooled number" in {
|
||||
val hub = new NumberPoolHub(new LimitedNumberSource(51))
|
||||
val hub = new NumberPoolHub(new MaxNumberSource(51))
|
||||
hub.AddPool("fibonacci", numberList)
|
||||
hub.register(13) match {
|
||||
case Success(key) =>
|
||||
|
|
@ -231,7 +231,7 @@ class NumberPoolHubTest extends Specification {
|
|||
}
|
||||
|
||||
"pre-register a number from a known pool" in {
|
||||
val hub = new NumberPoolHub(new LimitedNumberSource(51))
|
||||
val hub = new NumberPoolHub(new MaxNumberSource(51))
|
||||
hub.AddPool("fibonacci", numberList).Selector = new RandomSelector
|
||||
hub.register("fibonacci") match {
|
||||
case Success(key) =>
|
||||
|
|
@ -242,7 +242,7 @@ class NumberPoolHubTest extends Specification {
|
|||
}
|
||||
|
||||
"unregister a number" in {
|
||||
val hub = new NumberPoolHub(new LimitedNumberSource(51))
|
||||
val hub = new NumberPoolHub(new MaxNumberSource(51))
|
||||
hub.AddPool("fibonacci", numberList).Selector = new RandomSelector //leave this tagged on
|
||||
val obj = new EntityTestClass()
|
||||
hub.register(13) match {
|
||||
|
|
@ -263,48 +263,48 @@ class NumberPoolHubTest extends Specification {
|
|||
}
|
||||
|
||||
"not affect the hidden restricted pool by adding a new pool" in {
|
||||
val src = new LimitedNumberSource(51)
|
||||
src.Restrict(4)
|
||||
src.Restrict(8) //in fibonacci
|
||||
src.Restrict(10)
|
||||
src.Restrict(12)
|
||||
val src = new MaxNumberSource(51)
|
||||
src.restrictNumber(4)
|
||||
src.restrictNumber(8) //in fibonacci
|
||||
src.restrictNumber(10)
|
||||
src.restrictNumber(12)
|
||||
val hub = new NumberPoolHub(src)
|
||||
hub.AddPool("fibonacci", numberList) must throwA[IllegalArgumentException]
|
||||
}
|
||||
|
||||
"not register an object to a number belonging to the restricted pool" in {
|
||||
val src = new LimitedNumberSource(51)
|
||||
src.Restrict(4)
|
||||
val src = new MaxNumberSource(51)
|
||||
src.restrictNumber(4)
|
||||
val hub = new NumberPoolHub(src)
|
||||
val obj = new EntityTestClass()
|
||||
hub.register(obj, 4).isFailure mustEqual true
|
||||
}
|
||||
|
||||
"not register an object to the restricted pool directly" in {
|
||||
val src = new LimitedNumberSource(51)
|
||||
// src.Restrict(4)
|
||||
val src = new MaxNumberSource(51)
|
||||
// src.restrictNumber(4)
|
||||
val hub = new NumberPoolHub(src)
|
||||
val obj = new EntityTestClass()
|
||||
hub.register(obj, "").isFailure mustEqual true //the empty string represents the restricted pool
|
||||
}
|
||||
|
||||
"not register a number belonging to the restricted pool" in {
|
||||
val src = new LimitedNumberSource(51)
|
||||
src.Restrict(4)
|
||||
val src = new MaxNumberSource(51)
|
||||
src.restrictNumber(4)
|
||||
val hub = new NumberPoolHub(src)
|
||||
hub.register(4).isFailure mustEqual true
|
||||
}
|
||||
|
||||
"not unregister a number belonging to the restricted pool" in {
|
||||
val src = new LimitedNumberSource(51)
|
||||
src.Restrict(4)
|
||||
val src = new MaxNumberSource(51)
|
||||
src.restrictNumber(4)
|
||||
val hub = new NumberPoolHub(src)
|
||||
hub.unregister(4).isFailure mustEqual true
|
||||
}
|
||||
|
||||
"identity an object that is registered to it" in {
|
||||
val hub1 = new NumberPoolHub(new LimitedNumberSource(10))
|
||||
val hub2 = new NumberPoolHub(new LimitedNumberSource(10))
|
||||
val hub1 = new NumberPoolHub(new MaxNumberSource(10))
|
||||
val hub2 = new NumberPoolHub(new MaxNumberSource(10))
|
||||
val obj1 = new EntityTestClass()
|
||||
val obj2 = new EntityTestClass()
|
||||
hub1.register(obj1)
|
||||
|
|
@ -317,15 +317,15 @@ class NumberPoolHubTest extends Specification {
|
|||
}
|
||||
|
||||
"identity a number that is registered to it" in {
|
||||
val src1 = new LimitedNumberSource(5)
|
||||
val src1 = new MaxNumberSource(5)
|
||||
val hub1 = new NumberPoolHub(src1)
|
||||
val src2 = new LimitedNumberSource(10)
|
||||
src2.Restrict(0)
|
||||
src2.Restrict(1)
|
||||
src2.Restrict(2)
|
||||
src2.Restrict(3)
|
||||
src2.Restrict(4)
|
||||
src2.Restrict(5)
|
||||
val src2 = new MaxNumberSource(10)
|
||||
src2.restrictNumber(0)
|
||||
src2.restrictNumber(1)
|
||||
src2.restrictNumber(2)
|
||||
src2.restrictNumber(3)
|
||||
src2.restrictNumber(4)
|
||||
src2.restrictNumber(5)
|
||||
val hub2 = new NumberPoolHub(src2)
|
||||
val obj1 = new EntityTestClass()
|
||||
val obj2 = new EntityTestClass()
|
||||
|
|
|
|||
|
|
@ -10,62 +10,71 @@ class NumberSourceTest extends Specification {
|
|||
import net.psforever.objects.entity.IdentifiableEntity
|
||||
private class TestClass extends IdentifiableEntity
|
||||
|
||||
"LimitedNumberSource" should {
|
||||
import net.psforever.objects.guid.source.LimitedNumberSource
|
||||
"MaxNumberSource" should {
|
||||
import net.psforever.objects.guid.source.MaxNumberSource
|
||||
"construct" in {
|
||||
val obj = LimitedNumberSource(25)
|
||||
obj.Size mustEqual 26
|
||||
obj.CountAvailable mustEqual 26
|
||||
obj.CountUsed mustEqual 0
|
||||
val obj = MaxNumberSource(25)
|
||||
obj.size mustEqual 26
|
||||
obj.countAvailable mustEqual 26
|
||||
obj.countUsed mustEqual 0
|
||||
}
|
||||
|
||||
"get a number" in {
|
||||
val obj = LimitedNumberSource(25)
|
||||
val result: Option[LoanedKey] = obj.Available(5)
|
||||
"construct failure (negative max value)" in {
|
||||
MaxNumberSource(-1) must throwA[IllegalArgumentException]
|
||||
}
|
||||
|
||||
"get any number (failure)" in {
|
||||
val obj = MaxNumberSource(25)
|
||||
obj.getAvailable(number = 50).isDefined mustEqual false
|
||||
}
|
||||
|
||||
"get a valid number" in {
|
||||
val obj = MaxNumberSource(25)
|
||||
val result: Option[LoanedKey] = obj.getAvailable(5)
|
||||
result.isDefined mustEqual true
|
||||
result.get.GUID mustEqual 5
|
||||
result.get.Policy mustEqual AvailabilityPolicy.Leased
|
||||
result.get.Object.isEmpty mustEqual true
|
||||
obj.Size mustEqual 26
|
||||
obj.CountAvailable mustEqual 25
|
||||
obj.CountUsed mustEqual 1
|
||||
obj.size mustEqual 26
|
||||
obj.countAvailable mustEqual 25
|
||||
obj.countUsed mustEqual 1
|
||||
}
|
||||
|
||||
"assign the number" in {
|
||||
val obj = LimitedNumberSource(25)
|
||||
val result: Option[LoanedKey] = obj.Available(5)
|
||||
val obj = MaxNumberSource(25)
|
||||
val result: Option[LoanedKey] = obj.getAvailable(5)
|
||||
result.isDefined mustEqual true
|
||||
result.get.Object = new TestClass()
|
||||
ok
|
||||
}
|
||||
|
||||
"return a number (unused)" in {
|
||||
val obj = LimitedNumberSource(25)
|
||||
val result: Option[LoanedKey] = obj.Available(5)
|
||||
val obj = MaxNumberSource(25)
|
||||
val result: Option[LoanedKey] = obj.getAvailable(5)
|
||||
result.isDefined mustEqual true
|
||||
result.get.GUID mustEqual 5
|
||||
obj.CountUsed mustEqual 1
|
||||
val ret = obj.Return(result.get)
|
||||
obj.countUsed mustEqual 1
|
||||
val ret = obj.returnNumber(result.get)
|
||||
ret.isEmpty mustEqual true
|
||||
obj.CountUsed mustEqual 0
|
||||
obj.countUsed mustEqual 0
|
||||
}
|
||||
|
||||
"return a number (assigned)" in {
|
||||
val obj = LimitedNumberSource(25)
|
||||
val obj = MaxNumberSource(25)
|
||||
val test = new TestClass()
|
||||
val result: Option[LoanedKey] = obj.Available(5)
|
||||
val result: Option[LoanedKey] = obj.getAvailable(5)
|
||||
result.isDefined mustEqual true
|
||||
result.get.GUID mustEqual 5
|
||||
result.get.Object = test
|
||||
obj.CountUsed mustEqual 1
|
||||
val ret = obj.Return(result.get)
|
||||
obj.countUsed mustEqual 1
|
||||
val ret = obj.returnNumber(result.get)
|
||||
ret.contains(test) mustEqual true
|
||||
obj.CountUsed mustEqual 0
|
||||
obj.countUsed mustEqual 0
|
||||
}
|
||||
|
||||
"restrict a number (unassigned)" in {
|
||||
val obj = LimitedNumberSource(25)
|
||||
val result: Option[LoanedKey] = obj.Restrict(5)
|
||||
val obj = MaxNumberSource(25)
|
||||
val result: Option[LoanedKey] = obj.restrictNumber(5)
|
||||
result.isDefined mustEqual true
|
||||
result.get.GUID mustEqual 5
|
||||
result.get.Policy mustEqual AvailabilityPolicy.Restricted
|
||||
|
|
@ -73,10 +82,10 @@ class NumberSourceTest extends Specification {
|
|||
}
|
||||
|
||||
"restrict a number (assigned + multiple assignments)" in {
|
||||
val obj = LimitedNumberSource(25)
|
||||
val obj = MaxNumberSource(25)
|
||||
val test1 = new TestClass()
|
||||
val test2 = new TestClass()
|
||||
val result: Option[LoanedKey] = obj.Restrict(5)
|
||||
val result: Option[LoanedKey] = obj.restrictNumber(5)
|
||||
result.get.GUID mustEqual 5
|
||||
result.get.Policy mustEqual AvailabilityPolicy.Restricted
|
||||
result.get.Object.isEmpty mustEqual true
|
||||
|
|
@ -89,108 +98,309 @@ class NumberSourceTest extends Specification {
|
|||
}
|
||||
|
||||
"return a restricted number (correctly fail)" in {
|
||||
val obj = LimitedNumberSource(25)
|
||||
val obj = MaxNumberSource(25)
|
||||
val test = new TestClass()
|
||||
val result: Option[LoanedKey] = obj.Restrict(5)
|
||||
val result: Option[LoanedKey] = obj.restrictNumber(5)
|
||||
result.get.GUID mustEqual 5
|
||||
result.get.Policy mustEqual AvailabilityPolicy.Restricted
|
||||
result.get.Object = test
|
||||
|
||||
obj.Return(5)
|
||||
val result2: Option[SecureKey] = obj.Get(5)
|
||||
obj.returnNumber(5)
|
||||
val result2: Option[SecureKey] = obj.get(5)
|
||||
result2.get.GUID mustEqual 5
|
||||
result2.get.Policy mustEqual AvailabilityPolicy.Restricted
|
||||
result2.get.Object.contains(test) mustEqual true
|
||||
}
|
||||
|
||||
"return a secure key" in {
|
||||
val obj = LimitedNumberSource(25)
|
||||
val obj = MaxNumberSource(25)
|
||||
val test = new TestClass()
|
||||
|
||||
val result1: Option[LoanedKey] = obj.Available(5)
|
||||
val result1: Option[LoanedKey] = obj.getAvailable(5)
|
||||
result1.get.Object = test
|
||||
test.GUID mustEqual PlanetSideGUID(5)
|
||||
|
||||
val result2: Option[SecureKey] = obj.Get(5)
|
||||
obj.Return(result2.get).contains(test) mustEqual true
|
||||
val result2: Option[SecureKey] = obj.get(5)
|
||||
obj.returnNumber(result2.get).contains(test) mustEqual true
|
||||
}
|
||||
|
||||
"restrict a previously-assigned number" in {
|
||||
val obj = LimitedNumberSource(25)
|
||||
val obj = MaxNumberSource(25)
|
||||
val test = new TestClass()
|
||||
val result1: Option[LoanedKey] = obj.Available(5)
|
||||
val result1: Option[LoanedKey] = obj.getAvailable(5)
|
||||
result1.isDefined mustEqual true
|
||||
result1.get.Policy mustEqual AvailabilityPolicy.Leased
|
||||
result1.get.Object = test
|
||||
val result2: Option[LoanedKey] = obj.Restrict(5)
|
||||
val result2: Option[LoanedKey] = obj.restrictNumber(5)
|
||||
result2.isDefined mustEqual true
|
||||
result2.get.Policy mustEqual AvailabilityPolicy.Restricted
|
||||
result2.get.Object.contains(test) mustEqual true
|
||||
}
|
||||
|
||||
"check a number (not previously gotten)" in {
|
||||
val obj = LimitedNumberSource(25)
|
||||
val result2: Option[SecureKey] = obj.Get(5)
|
||||
val obj = MaxNumberSource(25)
|
||||
val result2: Option[SecureKey] = obj.get(5)
|
||||
result2.get.GUID mustEqual 5
|
||||
result2.get.Policy mustEqual AvailabilityPolicy.Available
|
||||
result2.get.Object.isEmpty mustEqual true
|
||||
}
|
||||
|
||||
"check a number (previously gotten)" in {
|
||||
val obj = LimitedNumberSource(25)
|
||||
val result: Option[LoanedKey] = obj.Available(5)
|
||||
val obj = MaxNumberSource(25)
|
||||
val result: Option[LoanedKey] = obj.getAvailable(5)
|
||||
result.isDefined mustEqual true
|
||||
result.get.GUID mustEqual 5
|
||||
result.get.Policy mustEqual AvailabilityPolicy.Leased
|
||||
result.get.Object.isEmpty mustEqual true
|
||||
val result2: Option[SecureKey] = obj.Get(5)
|
||||
val result2: Option[SecureKey] = obj.get(5)
|
||||
result2.get.GUID mustEqual 5
|
||||
result2.get.Policy mustEqual AvailabilityPolicy.Leased
|
||||
result2.get.Object.isEmpty mustEqual true
|
||||
}
|
||||
|
||||
"check a number (assigned)" in {
|
||||
val obj = LimitedNumberSource(25)
|
||||
val result: Option[LoanedKey] = obj.Available(5)
|
||||
val obj = MaxNumberSource(25)
|
||||
val result: Option[LoanedKey] = obj.getAvailable(5)
|
||||
result.isDefined mustEqual true
|
||||
result.get.GUID mustEqual 5
|
||||
result.get.Policy mustEqual AvailabilityPolicy.Leased
|
||||
result.get.Object = new TestClass()
|
||||
val result2: Option[SecureKey] = obj.Get(5)
|
||||
val result2: Option[SecureKey] = obj.get(5)
|
||||
result2.get.GUID mustEqual 5
|
||||
result2.get.Policy mustEqual AvailabilityPolicy.Leased
|
||||
result2.get.Object mustEqual result.get.Object
|
||||
}
|
||||
|
||||
"check a number (assigned and returned)" in {
|
||||
val obj = LimitedNumberSource(25)
|
||||
val obj = MaxNumberSource(25)
|
||||
val test = new TestClass()
|
||||
val result: Option[LoanedKey] = obj.Available(5)
|
||||
val result: Option[LoanedKey] = obj.getAvailable(5)
|
||||
result.get.Policy mustEqual AvailabilityPolicy.Leased
|
||||
result.get.Object = test
|
||||
val result2: Option[SecureKey] = obj.Get(5)
|
||||
val result2: Option[SecureKey] = obj.get(5)
|
||||
result2.get.Policy mustEqual AvailabilityPolicy.Leased
|
||||
result2.get.Object.get mustEqual test
|
||||
obj.Return(5).contains(test) mustEqual true
|
||||
val result3: Option[SecureKey] = obj.Get(5)
|
||||
obj.returnNumber(5).contains(test) mustEqual true
|
||||
val result3: Option[SecureKey] = obj.get(5)
|
||||
result3.get.Policy mustEqual AvailabilityPolicy.Available
|
||||
result3.get.Object.isEmpty mustEqual true
|
||||
}
|
||||
|
||||
"clear" in {
|
||||
val obj = LimitedNumberSource(25)
|
||||
val obj = MaxNumberSource(25)
|
||||
val test1 = new TestClass()
|
||||
val test2 = new TestClass()
|
||||
val test3 = new TestClass()
|
||||
obj.Available(5) //no assignment
|
||||
obj.Available(10).get.Object = test1
|
||||
obj.Available(15).get.Object = test2
|
||||
obj.Restrict(15)
|
||||
obj.Restrict(20).get.Object = test3
|
||||
obj.CountUsed mustEqual 4
|
||||
obj.getAvailable(5) //no assignment
|
||||
obj.getAvailable(10).get.Object = test1
|
||||
obj.getAvailable(15).get.Object = test2
|
||||
obj.restrictNumber(15)
|
||||
obj.restrictNumber(20).get.Object = test3
|
||||
obj.countUsed mustEqual 4
|
||||
|
||||
val list: List[IdentifiableEntity] = obj.Clear()
|
||||
obj.CountUsed mustEqual 0
|
||||
val list: List[IdentifiableEntity] = obj.clear()
|
||||
obj.countUsed mustEqual 0
|
||||
list.size mustEqual 3
|
||||
list.count(obj => obj == test1) mustEqual 1
|
||||
list.count(obj => obj == test2) mustEqual 1
|
||||
list.count(obj => obj == test3) mustEqual 1
|
||||
}
|
||||
}
|
||||
|
||||
"SpecificNumberSource" should {
|
||||
import net.psforever.objects.guid.source.SpecificNumberSource
|
||||
"construct" in {
|
||||
val obj = SpecificNumberSource(List(25))
|
||||
obj.size mustEqual 1
|
||||
obj.countAvailable mustEqual 1
|
||||
obj.countUsed mustEqual 0
|
||||
}
|
||||
|
||||
"construct failure (no values)" in {
|
||||
SpecificNumberSource(List()) must throwA[IllegalArgumentException]
|
||||
}
|
||||
|
||||
"construct failure (at least one value is negative)" in {
|
||||
SpecificNumberSource(List(0, 1, -1, 2, 3)) must throwA[IllegalArgumentException]
|
||||
}
|
||||
|
||||
"get any number (failure)" in {
|
||||
val obj = SpecificNumberSource(List(25))
|
||||
obj.getAvailable(number = 5).isDefined mustEqual false
|
||||
}
|
||||
|
||||
"get specific number (success)" in {
|
||||
val obj = SpecificNumberSource(List(25))
|
||||
val result: Option[LoanedKey] = obj.getAvailable(25)
|
||||
result.isDefined mustEqual true
|
||||
result.get.GUID mustEqual 25
|
||||
result.get.Policy mustEqual AvailabilityPolicy.Leased
|
||||
result.get.Object.isEmpty mustEqual true
|
||||
obj.size mustEqual 1
|
||||
obj.countAvailable mustEqual 0
|
||||
obj.countUsed mustEqual 1
|
||||
}
|
||||
|
||||
"assign the number" in {
|
||||
val obj = SpecificNumberSource(List(25))
|
||||
val result: Option[LoanedKey] = obj.getAvailable(number = 25)
|
||||
result.isDefined mustEqual true
|
||||
result.get.Object = new TestClass()
|
||||
ok
|
||||
}
|
||||
|
||||
"return a number (unused)" in {
|
||||
val obj = SpecificNumberSource(List(25))
|
||||
val result: Option[LoanedKey] = obj.getAvailable(number = 25)
|
||||
result.isDefined mustEqual true
|
||||
result.get.GUID mustEqual 25
|
||||
obj.countUsed mustEqual 1
|
||||
val ret = obj.returnNumber(result.get)
|
||||
ret.isEmpty mustEqual true
|
||||
obj.countUsed mustEqual 0
|
||||
}
|
||||
|
||||
"return a number (assigned)" in {
|
||||
val obj = SpecificNumberSource(List(25))
|
||||
val test = new TestClass()
|
||||
val result: Option[LoanedKey] = obj.getAvailable(number = 25)
|
||||
result.isDefined mustEqual true
|
||||
result.get.GUID mustEqual 25
|
||||
result.get.Object = test
|
||||
obj.countUsed mustEqual 1
|
||||
val ret = obj.returnNumber(result.get)
|
||||
ret.contains(test) mustEqual true
|
||||
obj.countUsed mustEqual 0
|
||||
}
|
||||
|
||||
"restrict a number (unassigned)" in {
|
||||
val obj = SpecificNumberSource(List(25))
|
||||
val result: Option[LoanedKey] = obj.restrictNumber(number = 25)
|
||||
result.isDefined mustEqual true
|
||||
result.get.GUID mustEqual 25
|
||||
result.get.Policy mustEqual AvailabilityPolicy.Restricted
|
||||
result.get.Object.isEmpty mustEqual true
|
||||
}
|
||||
|
||||
"restrict a number (assigned + multiple assignments)" in {
|
||||
val obj = SpecificNumberSource(List(25, 26))
|
||||
val test1 = new TestClass()
|
||||
val test2 = new TestClass()
|
||||
val result: Option[LoanedKey] = obj.restrictNumber(number = 25)
|
||||
result.get.GUID mustEqual 25
|
||||
result.get.Policy mustEqual AvailabilityPolicy.Restricted
|
||||
result.get.Object.isEmpty mustEqual true
|
||||
result.get.Object = None //assignment 1
|
||||
result.get.Object.isEmpty mustEqual true //still unassigned
|
||||
result.get.Object = test1 //assignment 2
|
||||
result.get.Object.contains(test1) mustEqual true
|
||||
result.get.Object = test2 //assignment 3
|
||||
result.get.Object.contains(test1) mustEqual true //same as above
|
||||
}
|
||||
|
||||
"return a restricted number (correctly fail)" in {
|
||||
val obj = SpecificNumberSource(List(25))
|
||||
val test = new TestClass()
|
||||
val result: Option[LoanedKey] = obj.restrictNumber(number = 25)
|
||||
result.get.GUID mustEqual 25
|
||||
result.get.Policy mustEqual AvailabilityPolicy.Restricted
|
||||
result.get.Object = test
|
||||
|
||||
obj.returnNumber(number = 25)
|
||||
val result2: Option[SecureKey] = obj.get(25)
|
||||
result2.get.GUID mustEqual 25
|
||||
result2.get.Policy mustEqual AvailabilityPolicy.Restricted
|
||||
result2.get.Object.contains(test) mustEqual true
|
||||
}
|
||||
|
||||
"return a secure key" in {
|
||||
val obj = SpecificNumberSource(List(25))
|
||||
val test = new TestClass()
|
||||
|
||||
val result1: Option[LoanedKey] = obj.getAvailable(number = 25)
|
||||
result1.get.Object = test
|
||||
test.GUID mustEqual PlanetSideGUID(25)
|
||||
|
||||
val result2: Option[SecureKey] = obj.get(25)
|
||||
obj.returnNumber(result2.get).contains(test) mustEqual true
|
||||
}
|
||||
|
||||
"restrict a previously-assigned number" in {
|
||||
val obj = SpecificNumberSource(List(25))
|
||||
val test = new TestClass()
|
||||
val result1: Option[LoanedKey] = obj.getAvailable(number = 25)
|
||||
result1.isDefined mustEqual true
|
||||
result1.get.Policy mustEqual AvailabilityPolicy.Leased
|
||||
result1.get.Object = test
|
||||
val result2: Option[LoanedKey] = obj.restrictNumber(number = 25)
|
||||
result2.isDefined mustEqual true
|
||||
result2.get.Policy mustEqual AvailabilityPolicy.Restricted
|
||||
result2.get.Object.contains(test) mustEqual true
|
||||
}
|
||||
|
||||
"check a number (not previously gotten)" in {
|
||||
val obj = SpecificNumberSource(List(25))
|
||||
val result2: Option[SecureKey] = obj.get(25)
|
||||
result2.get.GUID mustEqual 25
|
||||
result2.get.Policy mustEqual AvailabilityPolicy.Available
|
||||
result2.get.Object.isEmpty mustEqual true
|
||||
}
|
||||
|
||||
"check a number (previously gotten)" in {
|
||||
val obj = SpecificNumberSource(List(25))
|
||||
val result: Option[LoanedKey] = obj.getAvailable(number = 25)
|
||||
result.isDefined mustEqual true
|
||||
result.get.GUID mustEqual 25
|
||||
result.get.Policy mustEqual AvailabilityPolicy.Leased
|
||||
result.get.Object.isEmpty mustEqual true
|
||||
val result2: Option[SecureKey] = obj.get(25)
|
||||
result2.get.GUID mustEqual 25
|
||||
result2.get.Policy mustEqual AvailabilityPolicy.Leased
|
||||
result2.get.Object.isEmpty mustEqual true
|
||||
}
|
||||
|
||||
"check a number (assigned)" in {
|
||||
val obj = SpecificNumberSource(List(25))
|
||||
val result: Option[LoanedKey] = obj.getAvailable(number = 25)
|
||||
result.isDefined mustEqual true
|
||||
result.get.GUID mustEqual 25
|
||||
result.get.Policy mustEqual AvailabilityPolicy.Leased
|
||||
result.get.Object = new TestClass()
|
||||
val result2: Option[SecureKey] = obj.get(25)
|
||||
result2.get.GUID mustEqual 25
|
||||
result2.get.Policy mustEqual AvailabilityPolicy.Leased
|
||||
result2.get.Object mustEqual result.get.Object
|
||||
}
|
||||
|
||||
"check a number (assigned and returned)" in {
|
||||
val obj = SpecificNumberSource(List(25))
|
||||
val test = new TestClass()
|
||||
val result: Option[LoanedKey] = obj.getAvailable(number = 25)
|
||||
result.get.Policy mustEqual AvailabilityPolicy.Leased
|
||||
result.get.Object = test
|
||||
val result2: Option[SecureKey] = obj.get(25)
|
||||
result2.get.Policy mustEqual AvailabilityPolicy.Leased
|
||||
result2.get.Object.get mustEqual test
|
||||
obj.returnNumber(number = 25).contains(test) mustEqual true
|
||||
val result3: Option[SecureKey] = obj.get(25)
|
||||
result3.get.Policy mustEqual AvailabilityPolicy.Available
|
||||
result3.get.Object.isEmpty mustEqual true
|
||||
}
|
||||
|
||||
"clear" in {
|
||||
val obj = SpecificNumberSource(List(25, 26, 27, 28, 29, 30))
|
||||
val test1 = new TestClass()
|
||||
val test2 = new TestClass()
|
||||
val test3 = new TestClass()
|
||||
obj.getAvailable(25) //no assignment
|
||||
obj.getAvailable(26).get.Object = test1
|
||||
obj.getAvailable(28).get.Object = test2
|
||||
obj.restrictNumber(28)
|
||||
obj.restrictNumber(30).get.Object = test3
|
||||
obj.countUsed mustEqual 4
|
||||
|
||||
val list: List[IdentifiableEntity] = obj.clear()
|
||||
obj.countUsed mustEqual 0
|
||||
list.size mustEqual 3
|
||||
list.count(obj => obj == test1) mustEqual 1
|
||||
list.count(obj => obj == test2) mustEqual 1
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import net.psforever.objects.entity.IdentifiableEntity
|
|||
import net.psforever.objects.guid.NumberPoolHub
|
||||
import net.psforever.objects.guid.actor.{NumberPoolActor, Register, UniqueNumberSystem, Unregister}
|
||||
import net.psforever.objects.guid.selector.RandomSelector
|
||||
import net.psforever.objects.guid.source.LimitedNumberSource
|
||||
import net.psforever.objects.guid.source.MaxNumberSource
|
||||
import net.psforever.types.PlanetSideGUID
|
||||
|
||||
import scala.concurrent.duration._
|
||||
|
|
@ -15,7 +15,7 @@ import scala.util.{Failure, Success}
|
|||
|
||||
class AllocateNumberPoolActors extends ActorTest {
|
||||
"AllocateNumberPoolActors" in {
|
||||
val src: LimitedNumberSource = LimitedNumberSource(6000)
|
||||
val src: MaxNumberSource = MaxNumberSource(6000)
|
||||
val guid: NumberPoolHub = new NumberPoolHub(src)
|
||||
guid.AddPool("pool1", (1001 to 2000).toList)
|
||||
guid.AddPool("pool2", (3001 to 4000).toList)
|
||||
|
|
@ -32,7 +32,7 @@ class AllocateNumberPoolActors extends ActorTest {
|
|||
class UniqueNumberSystemTest extends ActorTest() {
|
||||
"UniqueNumberSystem" should {
|
||||
"constructor" in {
|
||||
val src: LimitedNumberSource = LimitedNumberSource(6000)
|
||||
val src: MaxNumberSource = MaxNumberSource(6000)
|
||||
val guid: NumberPoolHub = new NumberPoolHub(src)
|
||||
guid.AddPool("pool1", (1001 to 2000).toList)
|
||||
guid.AddPool("pool2", (3001 to 4000).toList)
|
||||
|
|
@ -51,7 +51,7 @@ class UniqueNumberSystemTest1 extends ActorTest() {
|
|||
|
||||
"UniqueNumberSystem" should {
|
||||
"Register (success)" in {
|
||||
val src: LimitedNumberSource = LimitedNumberSource(6000)
|
||||
val src: MaxNumberSource = MaxNumberSource(6000)
|
||||
val guid: NumberPoolHub = new NumberPoolHub(src)
|
||||
val pool1 = (1001 to 2000).toList
|
||||
val pool2 = (3001 to 4000).toList
|
||||
|
|
@ -63,7 +63,7 @@ class UniqueNumberSystemTest1 extends ActorTest() {
|
|||
Props(classOf[UniqueNumberSystem], guid, UniqueNumberSystemTest.AllocateNumberPoolActors(guid)),
|
||||
"uns"
|
||||
)
|
||||
assert(src.CountUsed == 0)
|
||||
assert(src.countUsed == 0)
|
||||
//pool1
|
||||
for (_ <- 1 to 100) {
|
||||
val testObj = new EntityTestClass()
|
||||
|
|
@ -88,7 +88,7 @@ class UniqueNumberSystemTest1 extends ActorTest() {
|
|||
assert(msg.isInstanceOf[Success[_]])
|
||||
assert(pool3.contains(testObj.GUID.guid))
|
||||
}
|
||||
assert(src.CountUsed == 300)
|
||||
assert(src.countUsed == 300)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -98,7 +98,7 @@ class UniqueNumberSystemTest2 extends ActorTest() {
|
|||
|
||||
"UniqueNumberSystem" should {
|
||||
"Register (success; already registered)" in {
|
||||
val src: LimitedNumberSource = LimitedNumberSource(6000)
|
||||
val src: MaxNumberSource = MaxNumberSource(6000)
|
||||
val guid: NumberPoolHub = new NumberPoolHub(src)
|
||||
guid.AddPool("pool1", (1001 to 2000).toList).Selector = new RandomSelector
|
||||
guid.AddPool("pool2", (3001 to 4000).toList).Selector = new RandomSelector
|
||||
|
|
@ -109,20 +109,20 @@ class UniqueNumberSystemTest2 extends ActorTest() {
|
|||
)
|
||||
val testObj = new EntityTestClass()
|
||||
assert(!testObj.HasGUID)
|
||||
assert(src.CountUsed == 0)
|
||||
assert(src.countUsed == 0)
|
||||
|
||||
uns ! Register(testObj, "pool1")
|
||||
val msg1 = receiveOne(Duration.create(500, "ms"))
|
||||
assert(msg1.isInstanceOf[Success[_]])
|
||||
assert(testObj.HasGUID)
|
||||
assert(src.CountUsed == 1)
|
||||
assert(src.countUsed == 1)
|
||||
|
||||
val id = testObj.GUID.guid
|
||||
uns ! Register(testObj, "pool2") //different pool; makes no difference
|
||||
val msg2 = receiveOne(Duration.create(500, "ms"))
|
||||
assert(msg2.isInstanceOf[Success[_]])
|
||||
assert(testObj.HasGUID)
|
||||
assert(src.CountUsed == 1)
|
||||
assert(src.countUsed == 1)
|
||||
assert(testObj.GUID.guid == id) //unchanged
|
||||
}
|
||||
}
|
||||
|
|
@ -134,7 +134,7 @@ class UniqueNumberSystemTest3 extends ActorTest() {
|
|||
|
||||
"UniqueNumberSystem" should {
|
||||
"Register (failure; no pool)" in {
|
||||
val src: LimitedNumberSource = LimitedNumberSource(6000)
|
||||
val src: MaxNumberSource = MaxNumberSource(6000)
|
||||
val guid: NumberPoolHub = new NumberPoolHub(src)
|
||||
guid.AddPool("pool1", (1001 to 2000).toList).Selector = new RandomSelector
|
||||
guid.AddPool("pool2", (3001 to 4000).toList).Selector = new RandomSelector
|
||||
|
|
@ -145,13 +145,13 @@ class UniqueNumberSystemTest3 extends ActorTest() {
|
|||
)
|
||||
val testObj = new EntityTestClass()
|
||||
assert(!testObj.HasGUID)
|
||||
assert(src.CountUsed == 0)
|
||||
assert(src.countUsed == 0)
|
||||
|
||||
uns ! Register(testObj, "pool4")
|
||||
val msg1 = receiveOne(Duration.create(500, "ms"))
|
||||
assert(msg1.isInstanceOf[Failure[_]])
|
||||
assert(!testObj.HasGUID)
|
||||
assert(src.CountUsed == 0)
|
||||
assert(src.countUsed == 0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -161,7 +161,7 @@ class UniqueNumberSystemTest4 extends ActorTest() {
|
|||
|
||||
"UniqueNumberSystem" should {
|
||||
"Register (failure; empty pool)" in {
|
||||
val src: LimitedNumberSource = LimitedNumberSource(6000)
|
||||
val src: MaxNumberSource = MaxNumberSource(6000)
|
||||
val guid: NumberPoolHub = new NumberPoolHub(src)
|
||||
guid.AddPool("pool1", (1001 to 2000).toList).Selector = new RandomSelector
|
||||
guid.AddPool("pool2", (3001 to 4000).toList).Selector = new RandomSelector
|
||||
|
|
@ -190,7 +190,7 @@ class UniqueNumberSystemTest5 extends ActorTest() {
|
|||
|
||||
"UniqueNumberSystem" should {
|
||||
"Unregister (success)" in {
|
||||
val src: LimitedNumberSource = LimitedNumberSource(6000)
|
||||
val src: MaxNumberSource = MaxNumberSource(6000)
|
||||
val guid: NumberPoolHub = new NumberPoolHub(src)
|
||||
val pool2 = (3001 to 4000).toList
|
||||
guid.AddPool("pool1", (1001 to 2000).toList).Selector = new RandomSelector
|
||||
|
|
@ -202,20 +202,20 @@ class UniqueNumberSystemTest5 extends ActorTest() {
|
|||
)
|
||||
val testObj = new EntityTestClass()
|
||||
assert(!testObj.HasGUID)
|
||||
assert(src.CountUsed == 0)
|
||||
assert(src.countUsed == 0)
|
||||
|
||||
uns ! Register(testObj, "pool2")
|
||||
val msg1 = receiveOne(Duration.create(2000, "ms"))
|
||||
assert(msg1.isInstanceOf[Success[_]])
|
||||
assert(testObj.HasGUID)
|
||||
assert(pool2.contains(testObj.GUID.guid))
|
||||
assert(src.CountUsed == 1)
|
||||
assert(src.countUsed == 1)
|
||||
|
||||
uns ! Unregister(testObj)
|
||||
val msg2 = receiveOne(Duration.create(2000, "ms"))
|
||||
assert(msg2.isInstanceOf[Success[_]])
|
||||
assert(!testObj.HasGUID)
|
||||
assert(src.CountUsed == 0)
|
||||
assert(src.countUsed == 0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -225,7 +225,7 @@ class UniqueNumberSystemTest6 extends ActorTest() {
|
|||
|
||||
"UniqueNumberSystem" should {
|
||||
"Unregister (success; object not registered at all)" in {
|
||||
val src: LimitedNumberSource = LimitedNumberSource(6000)
|
||||
val src: MaxNumberSource = MaxNumberSource(6000)
|
||||
val guid: NumberPoolHub = new NumberPoolHub(src)
|
||||
guid.AddPool("pool1", (1001 to 2000).toList).Selector = new RandomSelector
|
||||
guid.AddPool("pool2", (3001 to 4000).toList).Selector = new RandomSelector
|
||||
|
|
@ -236,13 +236,13 @@ class UniqueNumberSystemTest6 extends ActorTest() {
|
|||
)
|
||||
val testObj = new EntityTestClass()
|
||||
assert(!testObj.HasGUID)
|
||||
assert(src.CountUsed == 0)
|
||||
assert(src.countUsed == 0)
|
||||
|
||||
uns ! Unregister(testObj)
|
||||
val msg1 = receiveOne(Duration.create(500, "ms"))
|
||||
assert(msg1.isInstanceOf[Success[_]])
|
||||
assert(!testObj.HasGUID)
|
||||
assert(src.CountUsed == 0)
|
||||
assert(src.countUsed == 0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -252,7 +252,7 @@ class UniqueNumberSystemTest7 extends ActorTest() {
|
|||
|
||||
"UniqueNumberSystem" should {
|
||||
"Unregister (failure; number not in system)" in {
|
||||
val src: LimitedNumberSource = LimitedNumberSource(6000)
|
||||
val src: MaxNumberSource = MaxNumberSource(6000)
|
||||
val guid: NumberPoolHub = new NumberPoolHub(src)
|
||||
guid.AddPool("pool1", (1001 to 2000).toList).Selector = new RandomSelector
|
||||
guid.AddPool("pool2", (3001 to 4000).toList).Selector = new RandomSelector
|
||||
|
|
@ -264,13 +264,13 @@ class UniqueNumberSystemTest7 extends ActorTest() {
|
|||
val testObj = new EntityTestClass()
|
||||
testObj.GUID = PlanetSideGUID(6001) //fake registering; number too high
|
||||
assert(testObj.HasGUID)
|
||||
assert(src.CountUsed == 0)
|
||||
assert(src.countUsed == 0)
|
||||
|
||||
uns ! Unregister(testObj)
|
||||
val msg1 = receiveOne(Duration.create(500, "ms"))
|
||||
assert(msg1.isInstanceOf[Failure[_]])
|
||||
assert(testObj.HasGUID)
|
||||
assert(src.CountUsed == 0)
|
||||
assert(src.countUsed == 0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -280,7 +280,7 @@ class UniqueNumberSystemTest8 extends ActorTest() {
|
|||
|
||||
"UniqueNumberSystem" should {
|
||||
"Unregister (failure; object is not registered to that number)" in {
|
||||
val src: LimitedNumberSource = LimitedNumberSource(6000)
|
||||
val src: MaxNumberSource = MaxNumberSource(6000)
|
||||
val guid: NumberPoolHub = new NumberPoolHub(src)
|
||||
guid.AddPool("pool1", (1001 to 2000).toList).Selector = new RandomSelector
|
||||
guid.AddPool("pool2", (3001 to 4000).toList).Selector = new RandomSelector
|
||||
|
|
@ -292,13 +292,13 @@ class UniqueNumberSystemTest8 extends ActorTest() {
|
|||
val testObj = new EntityTestClass()
|
||||
testObj.GUID = PlanetSideGUID(3500) //fake registering
|
||||
assert(testObj.HasGUID)
|
||||
assert(src.CountUsed == 0)
|
||||
assert(src.countUsed == 0)
|
||||
|
||||
uns ! Unregister(testObj)
|
||||
val msg1 = receiveOne(Duration.create(500, "ms"))
|
||||
assert(msg1.isInstanceOf[Failure[_]])
|
||||
assert(testObj.HasGUID)
|
||||
assert(src.CountUsed == 0)
|
||||
assert(src.countUsed == 0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -308,7 +308,7 @@ class UniqueNumberSystemTest9 extends ActorTest() {
|
|||
|
||||
"UniqueNumberSystem" should {
|
||||
"Failures (manually walking the failure cases)" in {
|
||||
val src: LimitedNumberSource = LimitedNumberSource(6000)
|
||||
val src: MaxNumberSource = MaxNumberSource(6000)
|
||||
val guid: NumberPoolHub = new NumberPoolHub(src)
|
||||
guid.AddPool("pool1", (1001 to 2000).toList).Selector = new RandomSelector
|
||||
guid.AddPool("pool2", (3001 to 4000).toList).Selector = new RandomSelector
|
||||
|
|
@ -345,7 +345,7 @@ class UniqueNumberSystemTestA extends ActorTest {
|
|||
|
||||
"UniqueNumberSystem" should {
|
||||
"remain consistent between registrations" in {
|
||||
val src: LimitedNumberSource = LimitedNumberSource(10)
|
||||
val src: MaxNumberSource = MaxNumberSource(10)
|
||||
val guid: NumberPoolHub = new NumberPoolHub(src)
|
||||
guid.AddPool("pool1", (0 until 10).toList).Selector = new RandomSelector
|
||||
val uns = system.actorOf(
|
||||
|
|
@ -354,9 +354,9 @@ class UniqueNumberSystemTestA extends ActorTest {
|
|||
)
|
||||
expectNoMessage(Duration.create(200, "ms"))
|
||||
|
||||
assert(src.CountUsed == 0)
|
||||
assert(src.countUsed == 0)
|
||||
(0 to 4).foreach(i => { assert(guid.register(new EntityTestClass(), i).isSuccess) })
|
||||
assert(src.CountUsed == 5)
|
||||
assert(src.countUsed == 5)
|
||||
|
||||
(0 to 5).foreach(_ => { uns ! Register(new EntityTestClass(), "pool1") })
|
||||
assert(receiveOne(200 milliseconds).isInstanceOf[Success[_]]) //6th
|
||||
|
|
@ -365,7 +365,7 @@ class UniqueNumberSystemTestA extends ActorTest {
|
|||
assert(receiveOne(200 milliseconds).isInstanceOf[Success[_]]) //9th
|
||||
assert(receiveOne(200 milliseconds).isInstanceOf[Success[_]]) //10th
|
||||
assert(receiveOne(200 milliseconds).isInstanceOf[Failure[_]]) //no more
|
||||
assert(src.CountUsed == 10)
|
||||
assert(src.countUsed == 10)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import net.psforever.objects.avatar.Avatar
|
|||
import net.psforever.objects.{Default, GlobalDefinitions, Player}
|
||||
import net.psforever.objects.definition.SeatDefinition
|
||||
import net.psforever.objects.guid.NumberPoolHub
|
||||
import net.psforever.objects.guid.source.LimitedNumberSource
|
||||
import net.psforever.objects.guid.source.MaxNumberSource
|
||||
import net.psforever.objects.serverobject.mount.Mountable
|
||||
import net.psforever.objects.serverobject.implantmech.{ImplantTerminalMech, ImplantTerminalMechControl}
|
||||
import net.psforever.objects.serverobject.structures.{Building, StructureType}
|
||||
|
|
@ -162,7 +162,7 @@ class ImplantTerminalMechControl5Test extends ActorTest {
|
|||
|
||||
object ImplantTerminalMechTest {
|
||||
def SetUpAgents(faction: PlanetSideEmpire.Value)(implicit system: ActorSystem): (Player, ImplantTerminalMech) = {
|
||||
val guid = new NumberPoolHub(new LimitedNumberSource(10))
|
||||
val guid = new NumberPoolHub(new MaxNumberSource(10))
|
||||
val map = new ZoneMap("test")
|
||||
val zone = new Zone("test", map, 0) {
|
||||
override def SetupNumberPools() = {}
|
||||
|
|
|
|||
Loading…
Reference in a new issue