diff --git a/common/src/main/scala/net/psforever/objects/inventory/InventoryItem.scala b/common/src/main/scala/net/psforever/objects/inventory/InventoryItem.scala
index 09000022..82c43bcc 100644
--- a/common/src/main/scala/net/psforever/objects/inventory/InventoryItem.scala
+++ b/common/src/main/scala/net/psforever/objects/inventory/InventoryItem.scala
@@ -20,4 +20,8 @@ object InventoryItem {
def apply(obj : Equipment, start : Int) : InventoryItem = {
new InventoryItem(obj, start)
}
+
+ def unapply(entry : InventoryItem) : Option[(Equipment, Int)] = {
+ Some((entry.obj, entry.start))
+ }
}
diff --git a/pslogin/src/main/scala/WorldSessionActor.scala b/pslogin/src/main/scala/WorldSessionActor.scala
index e5a212b9..72b3e1e3 100644
--- a/pslogin/src/main/scala/WorldSessionActor.scala
+++ b/pslogin/src/main/scala/WorldSessionActor.scala
@@ -273,14 +273,14 @@ class WorldSessionActor extends Actor with MDCContextAware {
sendResponse(GenericObjectActionMessage(guid, 36))
}
- case AvatarResponse.EquipmentInHand(slot, item) =>
+ case AvatarResponse.EquipmentInHand(target, slot, item) =>
if(tplayer_guid != guid) {
val definition = item.Definition
sendResponse(
ObjectCreateMessage(
definition.ObjectId,
item.GUID,
- ObjectCreateMessageParent(guid, slot),
+ ObjectCreateMessageParent(target, slot),
definition.Packet.ConstructorData(item).get
)
)
@@ -369,6 +369,19 @@ class WorldSessionActor extends Actor with MDCContextAware {
sendResponse(ReloadMessage(item_guid, 1, 0))
}
+ case AvatarResponse.StowEquipment(target, slot, item) =>
+ if(tplayer_guid != guid) {
+ val definition = item.Definition
+ sendResponse(
+ ObjectCreateDetailedMessage(
+ definition.ObjectId,
+ item.GUID,
+ ObjectCreateMessageParent(target, slot),
+ definition.Packet.DetailedConstructorData(item).get
+ )
+ )
+ }
+
case AvatarResponse.WeaponDryFire(weapon_guid) =>
if(tplayer_guid != guid) {
sendResponse(WeaponDryFireMessage(weapon_guid))
@@ -589,7 +602,7 @@ class WorldSessionActor extends Actor with MDCContextAware {
val player_guid : PlanetSideGUID = tplayer.GUID
val obj_guid : PlanetSideGUID = obj.GUID
log.info(s"MountVehicleMsg: $player_guid mounts $obj @ $seat_num")
- //tplayer.VehicleSeated = Some(obj_guid)
+ PlayerActionsToCancel()
sendResponse(PlanetsideAttributeMessage(obj_guid, 0, 1000L)) //health of mech
sendResponse(ObjectAttachMessage(obj_guid, player_guid, seat_num))
vehicleService ! VehicleServiceMessage(continent.Id, VehicleAction.MountVehicle(player_guid, obj_guid, seat_num))
@@ -599,7 +612,7 @@ class WorldSessionActor extends Actor with MDCContextAware {
val player_guid : PlanetSideGUID = tplayer.GUID
log.info(s"MountVehicleMsg: $player_guid mounts $obj_guid @ $seat_num")
vehicleService ! VehicleServiceMessage.UnscheduleDeconstruction(obj_guid) //clear all deconstruction timers
- //tplayer.VehicleSeated = Some(obj_guid)
+ PlayerActionsToCancel()
if(seat_num == 0) { //simplistic vehicle ownership management
obj.Owner match {
case Some(owner_guid) =>
@@ -739,7 +752,7 @@ class WorldSessionActor extends Actor with MDCContextAware {
definition.Packet.DetailedConstructorData(obj).get
)
)
- avatarService ! AvatarServiceMessage(player.Continent, AvatarAction.EquipmentInHand(player.GUID, index, obj))
+ avatarService ! AvatarServiceMessage(player.Continent, AvatarAction.EquipmentInHand(player.GUID, player.GUID, index, obj))
case None => ;
}
})
@@ -1296,7 +1309,7 @@ class WorldSessionActor extends Actor with MDCContextAware {
)
)
if(tplayer.VisibleSlots.contains(slot)) {
- avatarService ! AvatarServiceMessage(tplayer.Continent, AvatarAction.EquipmentInHand(player_guid, slot, item))
+ avatarService ! AvatarServiceMessage(tplayer.Continent, AvatarAction.EquipmentInHand(player_guid, player_guid, slot, item))
}
case None =>
continent.Ground ! Zone.DropItemOnGround(item, item.Position, item.Orientation) //restore
@@ -2027,8 +2040,8 @@ class WorldSessionActor extends Actor with MDCContextAware {
case Some(obj : Equipment) =>
val findFunc : PlanetSideGameObject with Container => Option[(PlanetSideGameObject with Container, Option[Int])] = FindInLocalContainer(object_guid)
- findFunc(player)
- .orElse(findFunc(player.Locker))
+ findFunc(player.Locker)
+ .orElse(findFunc(player))
.orElse(accessedContainer match {
case Some(parent) =>
findFunc(parent)
@@ -2056,100 +2069,159 @@ class WorldSessionActor extends Actor with MDCContextAware {
sendResponse(ObjectDeleteMessage(object_guid, 0))
log.info("ObjectDelete: " + msg)
- case msg @ MoveItemMessage(item_guid, source_guid, destination_guid, dest, unk1) =>
+ case msg @ MoveItemMessage(item_guid, source_guid, destination_guid, dest, _) =>
log.info(s"MoveItem: $msg")
(continent.GUID(source_guid), continent.GUID(destination_guid), continent.GUID(item_guid)) match {
case (Some(source : Container), Some(destination : Container), Some(item : Equipment)) =>
source.Find(item_guid) match {
case Some(index) =>
val indexSlot = source.Slot(index)
- val destSlot = destination.Slot(dest)
- val destItem = destSlot.Equipment
+ val tile = item.Definition.Tile
+ val destinationCollisionTest = destination.Collisions(dest, tile.Width, tile.Height)
+ val destItemEntry = destinationCollisionTest match {
+ case Success(entry :: Nil) =>
+ Some(entry)
+ case _ =>
+ None
+ }
if( {
- val tile = item.Definition.Tile
- destination.Collisions(dest, tile.Width, tile.Height) match {
- case Success(Nil) =>
- destItem.isEmpty //no item swap; abort if encountering an unexpected item
- case Success(entry :: Nil) =>
- destItem.contains(entry.obj) //one item to swap; abort if destination item is missing or is wrong
- case Success(_) | scala.util.Failure(_) =>
+ destinationCollisionTest match {
+ case Success(Nil) | Success(_ :: Nil) =>
+ true //no item or one item to swap
+ case _ =>
false //abort when too many items at destination or other failure case
}
} && indexSlot.Equipment.contains(item)) {
log.info(s"MoveItem: $item_guid moved from $source_guid @ $index to $destination_guid @ $dest")
+ val player_guid = player.GUID
+ val sourceIsNotDestination : Boolean = source != destination //if source is destination, OCDM style is not required
+ //remove item from source
indexSlot.Equipment = None
- destItem match { //do we have a swap item?
- case Some(item2) => //yes, swap
- destSlot.Equipment = None //remove item2 to make room for item
- destSlot.Equipment = item
+ source match {
+ case obj : Vehicle =>
+ vehicleService ! VehicleServiceMessage(s"${obj.Actor}", VehicleAction.UnstowEquipment(player_guid, item_guid))
+ case obj : Player =>
+ if(obj.isBackpack || source.VisibleSlots.contains(index)) { //corpse being looted, or item was in hands
+ avatarService ! AvatarServiceMessage(continent.Id, AvatarAction.ObjectDelete(player_guid, item_guid))
+ }
+ case _ => ;
+ }
+
+ destItemEntry match { //do we have a swap item in the destination slot?
+ case Some(InventoryItem(item2, destIndex)) => //yes, swap
+ //cleanly shuffle items around to avoid losing icons
+ //the next ObjectDetachMessage is necessary to avoid icons being lost, but only as part of this swap
+ sendResponse(ObjectDetachMessage(source_guid, item_guid, Vector3.Zero, 0f, 0f, 0f))
+ val item2_guid = item2.GUID
+ destination.Slot(destIndex).Equipment = None //remove the swap item from destination
(indexSlot.Equipment = item2) match {
case Some(_) => //item and item2 swapped places successfully
- log.info(s"MoveItem: ${item2.GUID} swapped to $source_guid @ $index")
- //cleanly shuffle items around to avoid losing icons
- sendResponse(ObjectDetachMessage(source_guid, item_guid, Vector3(0f, 0f, 0f), 0f, 0f, 0f)) //ground; A -> C
- sendResponse(ObjectAttachMessage(source_guid, item2.GUID, index)) //B -> A
- source match {
- case (obj : Vehicle) =>
- val player_guid = player.GUID
- vehicleService ! VehicleServiceMessage(s"${obj.Actor}", VehicleAction.UnstowEquipment(player_guid, item_guid))
- vehicleService ! VehicleServiceMessage(s"${obj.Actor}", VehicleAction.StowEquipment(player_guid, source_guid, index, item2))
- //TODO visible slot verification, in the case of BFR arms
- case (obj : Player) =>
- if(source.VisibleSlots.contains(index)) {
- avatarService ! AvatarServiceMessage(player.Continent, AvatarAction.EquipmentInHand(source_guid, index, item2))
+ log.info(s"MoveItem: $item2_guid swapped to $source_guid @ $index")
+ //remove item2 from destination
+ sendResponse(ObjectDetachMessage(destination_guid, item2_guid, Vector3.Zero, 0f, 0f, 0f))
+ destination match {
+ case obj : Vehicle =>
+ vehicleService ! VehicleServiceMessage(s"${obj.Actor}", VehicleAction.UnstowEquipment(player_guid, item2_guid))
+ case obj : Player =>
+ if(obj.isBackpack || destination.VisibleSlots.contains(dest)) { //corpse being looted, or item was in hands
+ avatarService ! AvatarServiceMessage(continent.Id, AvatarAction.ObjectDelete(player_guid, item2_guid))
+ }
+ case _ => ;
+ }
+ //display item2 in source
+ if(sourceIsNotDestination && player == source) {
+ val objDef = item2.Definition
+ sendResponse(
+ ObjectCreateDetailedMessage(
+ objDef.ObjectId,
+ item2_guid,
+ ObjectCreateMessageParent(source_guid, index),
+ objDef.Packet.DetailedConstructorData(item2).get
+ )
+ )
+ }
+ else {
+ sendResponse(ObjectAttachMessage(source_guid, item2_guid, index))
+ }
+ source match {
+ case obj : Vehicle =>
+ vehicleService ! VehicleServiceMessage(s"${obj.Actor}", VehicleAction.StowEquipment(player_guid, source_guid, index, item2))
+ case obj : Player =>
+ if(source.VisibleSlots.contains(index)) { //item is put in hands
+ avatarService ! AvatarServiceMessage(continent.Id, AvatarAction.EquipmentInHand(player_guid, source_guid, index, item2))
+ }
+ else if(obj.isBackpack) { //corpse being given item
+ avatarService ! AvatarServiceMessage(continent.Id, AvatarAction.StowEquipment(player_guid, source_guid, index, item2))
}
case _ => ;
- //TODO something?
}
case None => //item2 does not fit; drop on ground
+ log.info(s"MoveItem: $item2_guid can not fit in swap location; dropping on ground @ ${source.Position}")
val pos = source.Position
val sourceOrientZ = source.Orientation.z
val orient : Vector3 = Vector3(0f, 0f, sourceOrientZ)
continent.Actor ! Zone.DropItemOnGround(item2, pos, orient)
- sendResponse(ObjectDetachMessage(source_guid, item2.GUID, pos, 0f, 0f, sourceOrientZ)) //ground
+ sendResponse(ObjectDetachMessage(destination_guid, item2_guid, pos, 0f, 0f, sourceOrientZ)) //ground
val objDef = item2.Definition
- avatarService ! AvatarServiceMessage(player.Continent, AvatarAction.EquipmentOnGround(player.GUID, pos, orient, objDef.ObjectId, item2.GUID, objDef.Packet.ConstructorData(item2).get))
- }
-
- case None => //just move item over
- destSlot.Equipment = item
- source match {
- case (obj : Vehicle) =>
- vehicleService ! VehicleServiceMessage(s"${obj.Actor}", VehicleAction.UnstowEquipment(player.GUID, item_guid))
- //TODO visible slot verification, in the case of BFR arms
- case _ => ;
- //TODO something?
+ destination match {
+ case obj : Vehicle =>
+ vehicleService ! VehicleServiceMessage(s"${obj.Actor}", VehicleAction.UnstowEquipment(player_guid, item2_guid))
+ case _ => ;
+ //Player does not require special case; the act of dropping forces the item and icon to change
+ }
+ avatarService ! AvatarServiceMessage(continent.Id, AvatarAction.EquipmentOnGround(player_guid, pos, orient, objDef.ObjectId, item2_guid, objDef.Packet.ConstructorData(item2).get))
}
+ case None => ;
+ }
+ //move item into destination slot
+ destination.Slot(dest).Equipment = item
+ if(sourceIsNotDestination && player == destination) {
+ val objDef = item.Definition
+ sendResponse(
+ ObjectCreateDetailedMessage(
+ objDef.ObjectId,
+ item_guid,
+ ObjectCreateMessageParent(destination_guid, dest),
+ objDef.Packet.DetailedConstructorData(item).get
+ )
+ )
+ }
+ else {
+ sendResponse(ObjectAttachMessage(destination_guid, item_guid, dest))
}
- sendResponse(ObjectAttachMessage(destination_guid, item_guid, dest))
destination match {
- case (obj : Vehicle) =>
- vehicleService ! VehicleServiceMessage(s"${obj.Actor}", VehicleAction.StowEquipment(player.GUID, destination_guid, dest, item))
- //TODO visible slot verification, in the case of BFR arms
- case (_ : Player) =>
- if(destination.VisibleSlots.contains(dest)) {
- avatarService ! AvatarServiceMessage(player.Continent, AvatarAction.EquipmentInHand(destination_guid, dest, item))
+ case obj : Vehicle =>
+ vehicleService ! VehicleServiceMessage(s"${obj.Actor}", VehicleAction.StowEquipment(player_guid, destination_guid, dest, item))
+ case obj : Player =>
+ if(destination.VisibleSlots.contains(dest)) { //item is put in hands
+ avatarService ! AvatarServiceMessage(continent.Id, AvatarAction.EquipmentInHand(player_guid, destination_guid, dest, item))
+ }
+ else if(obj.isBackpack) { //corpse being given item
+ avatarService ! AvatarServiceMessage(continent.Id, AvatarAction.StowEquipment(player_guid, destination_guid, dest, item))
}
case _ => ;
- //TODO something?
}
}
- else if(indexSlot.Equipment.nonEmpty) {
- log.error(s"MoveItem: wanted to move $item_guid, but unexpected item ${indexSlot.Equipment.get} at origin")
+ else if(!indexSlot.Equipment.contains(item)) {
+ log.error(s"MoveItem: wanted to move $item_guid, but found unexpected ${indexSlot.Equipment.get} at source location")
}
else {
- log.error(s"MoveItem: wanted to move $item_guid, but unexpected item(s) at destination")
+ destinationCollisionTest match {
+ case Success(_) =>
+ log.error(s"MoveItem: wanted to move $item_guid, but multiple unexpected items at destination blocked progress")
+ case scala.util.Failure(err) =>
+ log.error(s"MoveItem: wanted to move $item_guid, but $err")
+ }
}
case _ =>
log.error(s"MoveItem: wanted to move $item_guid, but could not find it")
}
-
case (None, _, _) =>
- log.error(s"MoveItem: wanted to move $item_guid from $source_guid, but could not find source")
+ log.error(s"MoveItem: wanted to move $item_guid from $source_guid, but could not find source object")
case (_, None, _) =>
- log.error(s"MoveItem: wanted to move $item_guid from $source_guid to $destination_guid, but could not find destination")
+ log.error(s"MoveItem: wanted to move $item_guid to $destination_guid, but could not find destination object")
case (_, _, None) =>
log.error(s"MoveItem: wanted to move $item_guid, but could not find it")
case _ =>
@@ -2680,7 +2752,7 @@ class WorldSessionActor extends Actor with MDCContextAware {
)
)
if(localTarget.VisibleSlots.contains(localIndex)) {
- localService ! AvatarServiceMessage(continent.Id, AvatarAction.EquipmentInHand(localTarget.GUID, localIndex, localObject))
+ localService ! AvatarServiceMessage(continent.Id, AvatarAction.EquipmentInHand(localTarget.GUID, localTarget.GUID, localIndex, localObject))
}
}
})
@@ -3554,7 +3626,7 @@ class WorldSessionActor extends Actor with MDCContextAware {
/**
* An event has occurred that would cause the player character to stop certain stateful activities.
- * These activities include shooting, hacking, accessing (a container), flying, and running.
+ * These activities include shooting, weapon drawing, hacking, accessing (a container), flying, and running.
* Other players in the same zone must be made aware that the player has stopped as well.
*
* Things whose configuration should not be changed:
@@ -3583,6 +3655,11 @@ class WorldSessionActor extends Actor with MDCContextAware {
shooting = None
case None => ;
}
+ if(player != null && player.isAlive && player.VisibleSlots.contains(player.DrawnSlot)) {
+ player.DrawnSlot = Player.HandsDownSlot
+ sendResponse(ObjectHeldMessage(player.GUID, Player.HandsDownSlot, true))
+ avatarService ! AvatarServiceMessage(continent.Id, AvatarAction.ObjectHeld(player.GUID, player.LastDrawnSlot))
+ }
if(flying) {
sendResponse(ChatMsg(ChatMessageType.CMT_FLY, false, "", "off", None))
flying = false
diff --git a/pslogin/src/main/scala/services/avatar/AvatarAction.scala b/pslogin/src/main/scala/services/avatar/AvatarAction.scala
index 80d49828..d0701767 100644
--- a/pslogin/src/main/scala/services/avatar/AvatarAction.scala
+++ b/pslogin/src/main/scala/services/avatar/AvatarAction.scala
@@ -17,7 +17,7 @@ object AvatarAction {
final case class ChangeFireState_Start(player_guid : PlanetSideGUID, weapon_guid : PlanetSideGUID) extends Action
final case class ChangeFireState_Stop(player_guid : PlanetSideGUID, weapon_guid : PlanetSideGUID) extends Action
final case class ConcealPlayer(player_guid : PlanetSideGUID) extends Action
- final case class EquipmentInHand(player_guid : PlanetSideGUID, slot : Int, item : Equipment) extends Action
+ final case class EquipmentInHand(player_guid : PlanetSideGUID, target_guid : PlanetSideGUID, slot : Int, item : Equipment) extends Action
final case class EquipmentOnGround(player_guid : PlanetSideGUID, pos : Vector3, orient : Vector3, item_id : Int, item_guid : PlanetSideGUID, item_data : ConstructorData) extends Action
final case class LoadPlayer(player_guid : PlanetSideGUID, pdata : ConstructorData) extends Action
// final case class LoadMap(msg : PlanetSideGUID) extends Action
@@ -28,6 +28,7 @@ object AvatarAction {
final case class PlayerState(player_guid : PlanetSideGUID, msg : PlayerStateMessageUpstream, spectator : Boolean, weaponInHand : Boolean) extends Action
final case class Release(player : Player, zone : Zone, time : Option[Long] = None) extends Action
final case class Reload(player_guid : PlanetSideGUID, weapon_guid : PlanetSideGUID) extends Action
+ final case class StowEquipment(player_guid : PlanetSideGUID, target_guid : PlanetSideGUID, slot : Int, item : Equipment) extends Action
final case class WeaponDryFire(player_guid : PlanetSideGUID, weapon_guid : PlanetSideGUID) extends Action
// final case class PlayerStateShift(killer : PlanetSideGUID, victim : PlanetSideGUID) extends Action
// final case class DestroyDisplay(killer : PlanetSideGUID, victim : PlanetSideGUID) extends Action
diff --git a/pslogin/src/main/scala/services/avatar/AvatarResponse.scala b/pslogin/src/main/scala/services/avatar/AvatarResponse.scala
index f3c605ed..5932bace 100644
--- a/pslogin/src/main/scala/services/avatar/AvatarResponse.scala
+++ b/pslogin/src/main/scala/services/avatar/AvatarResponse.scala
@@ -16,7 +16,7 @@ object AvatarResponse {
final case class ChangeFireState_Start(weapon_guid : PlanetSideGUID) extends Response
final case class ChangeFireState_Stop(weapon_guid : PlanetSideGUID) extends Response
final case class ConcealPlayer() extends Response
- final case class EquipmentInHand(slot : Int, item : Equipment) extends Response
+ final case class EquipmentInHand(target_guid : PlanetSideGUID, slot : Int, item : Equipment) extends Response
final case class EquipmentOnGround(pos : Vector3, orient : Vector3, item_id : Int, item_guid : PlanetSideGUID, item_data : ConstructorData) extends Response
final case class LoadPlayer(pdata : ConstructorData) extends Response
// final case class unLoadMap() extends Response
@@ -27,6 +27,7 @@ object AvatarResponse {
final case class PlayerState(msg : PlayerStateMessageUpstream, spectator : Boolean, weaponInHand : Boolean) extends Response
final case class Release(player : Player) extends Response
final case class Reload(weapon_guid : PlanetSideGUID) extends Response
+ final case class StowEquipment(target_guid : PlanetSideGUID, slot : Int, item : Equipment) extends Response
final case class WeaponDryFire(weapon_guid : PlanetSideGUID) extends Response
// final case class PlayerStateShift(itemID : PlanetSideGUID) extends Response
// final case class DestroyDisplay(itemID : PlanetSideGUID) extends Response
diff --git a/pslogin/src/main/scala/services/avatar/AvatarService.scala b/pslogin/src/main/scala/services/avatar/AvatarService.scala
index 2978f1a1..17cec7ae 100644
--- a/pslogin/src/main/scala/services/avatar/AvatarService.scala
+++ b/pslogin/src/main/scala/services/avatar/AvatarService.scala
@@ -62,9 +62,9 @@ class AvatarService extends Actor {
AvatarEvents.publish(
AvatarServiceResponse(s"/$forChannel/Avatar", player_guid, AvatarResponse.ConcealPlayer())
)
- case AvatarAction.EquipmentInHand(player_guid, slot, obj) =>
+ case AvatarAction.EquipmentInHand(player_guid, target_guid, slot, obj) =>
AvatarEvents.publish(
- AvatarServiceResponse(s"/$forChannel/Avatar", player_guid, AvatarResponse.EquipmentInHand(slot, obj))
+ AvatarServiceResponse(s"/$forChannel/Avatar", player_guid, AvatarResponse.EquipmentInHand(target_guid, slot, obj))
)
case AvatarAction.EquipmentOnGround(player_guid, pos, orient, item_id, item_guid, item_data) =>
AvatarEvents.publish(
@@ -102,6 +102,10 @@ class AvatarService extends Actor {
AvatarEvents.publish(
AvatarServiceResponse(s"/$forChannel/Avatar", player_guid, AvatarResponse.Reload(weapon_guid))
)
+ case AvatarAction.StowEquipment(player_guid, target_guid, slot, obj) =>
+ AvatarEvents.publish(
+ AvatarServiceResponse(s"/$forChannel/Avatar", player_guid, AvatarResponse.StowEquipment(target_guid, slot, obj))
+ )
case AvatarAction.WeaponDryFire(player_guid, weapon_guid) =>
AvatarEvents.publish(
AvatarServiceResponse(s"/$forChannel/Avatar", player_guid, AvatarResponse.WeaponDryFire(weapon_guid))
diff --git a/pslogin/src/test/scala/AvatarServiceTest.scala b/pslogin/src/test/scala/AvatarServiceTest.scala
index ea86a6d7..c122dcdf 100644
--- a/pslogin/src/test/scala/AvatarServiceTest.scala
+++ b/pslogin/src/test/scala/AvatarServiceTest.scala
@@ -100,8 +100,8 @@ class EquipmentInHandTest extends ActorTest {
ServiceManager.boot(system)
val service = system.actorOf(Props[AvatarService], AvatarServiceTest.TestName)
service ! Service.Join("test")
- service ! AvatarServiceMessage("test", AvatarAction.EquipmentInHand(PlanetSideGUID(10), 2, tool))
- expectMsg(AvatarServiceResponse("/test/Avatar", PlanetSideGUID(10), AvatarResponse.EquipmentInHand(2, tool)))
+ service ! AvatarServiceMessage("test", AvatarAction.EquipmentInHand(PlanetSideGUID(10), PlanetSideGUID(11), 2, tool))
+ expectMsg(AvatarServiceResponse("/test/Avatar", PlanetSideGUID(10), AvatarResponse.EquipmentInHand(PlanetSideGUID(11), 2, tool)))
}
}
}
@@ -271,6 +271,20 @@ class WeaponDryFireTest extends ActorTest {
}
}
+class AvatarStowEquipmentTest extends ActorTest {
+ val tool = Tool(GlobalDefinitions.beamer)
+
+ "AvatarService" should {
+ "pass StowEquipment" in {
+ ServiceManager.boot(system)
+ val service = system.actorOf(Props[AvatarService], AvatarServiceTest.TestName)
+ service ! Service.Join("test")
+ service ! AvatarServiceMessage("test", AvatarAction.StowEquipment(PlanetSideGUID(10), PlanetSideGUID(11), 2, tool))
+ expectMsg(AvatarServiceResponse("/test/Avatar", PlanetSideGUID(10), AvatarResponse.StowEquipment(PlanetSideGUID(11), 2, tool)))
+ }
+ }
+}
+
/*
Preparation for these three Release tests is involved.
The ServiceManager must not only be set up correctly, but must be given a TaskResolver.