unified code paths for dropping an item, and reinforced code path for picking an item back up; LocalService will handle some of the work now; ActionResultMessage embraces its simplistic nature (we don't have enough error messages)

This commit is contained in:
FateJH 2018-05-22 19:13:59 -04:00
parent fdf05337fd
commit f6f7ad5617
12 changed files with 192 additions and 126 deletions

View file

@ -386,27 +386,15 @@ object Zone {
final case class NoValidSpawnPoint(zone_number : Int, spawn_group : Option[Int])
}
/**
* Message to relinguish an item and place in on the ground.
* @param item the piece of `Equipment`
* @param pos where it is dropped
* @param orient in which direction it is facing when dropped
*/
final case class DropItemOnGround(item : Equipment, pos : Vector3, orient : Vector3)
object Ground {
final case class DropItem(item : Equipment, pos : Vector3, orient : Vector3)
final case class ItemOnGround(item : Equipment, pos : Vector3, orient : Vector3)
final case class CanNotDropItem(item : Equipment)
/**
* Message to attempt to acquire an item from the ground (before somoene else?).
* @param player who wants the piece of `Equipment`
* @param item_guid the unique identifier of the piece of `Equipment`
*/
final case class GetItemOnGround(player : Player, item_guid : PlanetSideGUID)
/**
* Message to give an item from the ground to a specific user.
* @param player who wants the piece of `Equipment`
* @param item the piece of `Equipment`
*/
final case class ItemFromGround(player : Player, item : Equipment)
final case class PickupItem(item_guid : PlanetSideGUID)
final case class ItemInHand(item : Equipment)
final case class CanNotPickupItem(item_guid : PlanetSideGUID)
}
object Vehicle {
final case class Spawn(vehicle : Vehicle)

View file

@ -50,10 +50,10 @@ class ZoneActor(zone : Zone) extends Actor {
zone.Population forward msg
//frwd to Ground Actor
case msg @ Zone.DropItemOnGround =>
case msg @ Zone.Ground.DropItem =>
zone.Ground forward msg
case msg @ Zone.GetItemOnGround =>
case msg @ Zone.Ground.PickupItem =>
zone.Ground forward msg
//frwd to Vehicle Actor

View file

@ -16,18 +16,22 @@ class ZoneGroundActor(equipmentOnGround : ListBuffer[Equipment]) extends Actor {
//private[this] val log = org.log4s.getLogger
def receive : Receive = {
case Zone.DropItemOnGround(item, pos, orient) =>
item.Position = pos
item.Orientation = orient
equipmentOnGround += item
case Zone.GetItemOnGround(player, item_guid) =>
FindItemOnGround(item_guid) match {
case Some(item) =>
sender ! Zone.ItemFromGround(player, item)
case Zone.Ground.DropItem(item, pos, orient) =>
sender ! (FindItemOnGround(item.GUID) match {
case None =>
org.log4s.getLogger.warn(s"item on ground $item_guid was requested by $player for pickup but was not found")
}
equipmentOnGround += item
Zone.Ground.ItemOnGround(item, pos, orient)
case Some(_) =>
Zone.Ground.CanNotDropItem(item)
})
case Zone.Ground.PickupItem(item_guid) =>
sender ! (FindItemOnGround(item_guid) match {
case Some(item) =>
Zone.Ground.ItemInHand(item)
case None =>
Zone.Ground.CanNotPickupItem(item_guid)
})
case _ => ;
}

View file

@ -19,13 +19,18 @@ final case class ActionResultMessage(successful : Boolean,
}
object ActionResultMessage extends Marshallable[ActionResultMessage] {
def apply() : ActionResultMessage = {
ActionResultMessage(true, None)
}
/**
* A message where the result is always a pass.
* @return an `ActionResultMessage` object
*/
def Pass : ActionResultMessage = ActionResultMessage(true, None)
def apply(error : Long) : ActionResultMessage = {
ActionResultMessage(false, Some(error))
}
/**
* A message where the result is always a failure.
* @param error the error code
* @return an `ActionResultMessage` object
*/
def Fail(error : Long) : ActionResultMessage = ActionResultMessage(false, Some(error))
implicit val codec : Codec[ActionResultMessage] = (
("successful" | bool) >>:~ { res =>

View file

@ -40,6 +40,14 @@ final case class ObjectDetachMessage(parent_guid : PlanetSideGUID,
}
object ObjectDetachMessage extends Marshallable[ObjectDetachMessage] {
def apply(parent_guid : PlanetSideGUID, child_guid : PlanetSideGUID, pos : Vector3, orient : Vector3) : ObjectDetachMessage = {
ObjectDetachMessage(parent_guid, child_guid, pos, orient.x, orient.y, orient.z)
}
def apply(parent_guid : PlanetSideGUID, child_guid : PlanetSideGUID, pos : Vector3, orient_z : Float) : ObjectDetachMessage = {
ObjectDetachMessage(parent_guid, child_guid, pos, 0, 0, orient_z)
}
implicit val codec : Codec[ObjectDetachMessage] = (
("parent_guid" | PlanetSideGUID.codec) ::
("child_guid" | PlanetSideGUID.codec) ::

View file

@ -38,7 +38,7 @@ class ActionResultMessageTest extends Specification {
}
"encode (pass, minimal)" in {
val msg = ActionResultMessage()
val msg = ActionResultMessage.Pass
val pkt = PacketCoding.EncodePacket(msg).require.toByteVector
pkt mustEqual string_pass
@ -52,7 +52,7 @@ class ActionResultMessageTest extends Specification {
}
"encode (fail, minimal)" in {
val msg = ActionResultMessage(1)
val msg = ActionResultMessage.Fail(1)
val pkt = PacketCoding.EncodePacket(msg).require.toByteVector
pkt mustEqual string_fail

View file

@ -26,10 +26,24 @@ class ObjectDetachMessageTest extends Specification {
}
}
"encode" in {
"encode (1)" in {
val msg = ObjectDetachMessage(PlanetSideGUID(2916), PlanetSideGUID(2502), Vector3(3567.1406f, 2988.0078f, 71.84375f), 0f, 0f, 270f)
val pkt = PacketCoding.EncodePacket(msg).require.toByteVector
pkt mustEqual string
}
"encode (2)" in {
val msg = ObjectDetachMessage(PlanetSideGUID(2916), PlanetSideGUID(2502), Vector3(3567.1406f, 2988.0078f, 71.84375f), Vector3(0f, 0f, 270f))
val pkt = PacketCoding.EncodePacket(msg).require.toByteVector
pkt mustEqual string
}
"encode (3)" in {
val msg = ObjectDetachMessage(PlanetSideGUID(2916), PlanetSideGUID(2502), Vector3(3567.1406f, 2988.0078f, 71.84375f), 270f)
val pkt = PacketCoding.EncodePacket(msg).require.toByteVector
pkt mustEqual string
}
}

View file

@ -477,7 +477,7 @@ class ZoneGroundTest extends ActorTest {
assert(zone.EquipmentOnGround.isEmpty)
assert(item.Position == Vector3.Zero)
assert(item.Orientation == Vector3.Zero)
zone.Ground ! Zone.DropItemOnGround(item, Vector3(1.1f, 2.2f, 3.3f), Vector3(4.4f, 5.5f, 6.6f))
zone.Ground ! Zone.Ground.DropItem(item, Vector3(1.1f, 2.2f, 3.3f), Vector3(4.4f, 5.5f, 6.6f))
expectNoMsg(Duration.create(100, "ms"))
assert(zone.EquipmentOnGround == List(item))
@ -490,17 +490,16 @@ class ZoneGroundTest extends ActorTest {
val player = Player(Avatar("Chord", PlanetSideEmpire.TR, CharacterGender.Male, 0, 5))
system.actorOf(Props(classOf[ZoneTest.ZoneInitActor], zone), "get-item-test-good") ! "!"
receiveOne(Duration.create(200, "ms")) //consume
zone.Ground ! Zone.DropItemOnGround(item, Vector3.Zero, Vector3.Zero)
zone.Ground ! Zone.Ground.DropItem(item, Vector3.Zero, Vector3.Zero)
expectNoMsg(Duration.create(100, "ms"))
assert(zone.EquipmentOnGround == List(item))
zone.Ground ! Zone.GetItemOnGround(player, PlanetSideGUID(10))
zone.Ground ! Zone.Ground.PickupItem(PlanetSideGUID(10))
val reply = receiveOne(Duration.create(100, "ms"))
assert(zone.EquipmentOnGround.isEmpty)
assert(reply.isInstanceOf[Zone.ItemFromGround])
assert(reply.asInstanceOf[Zone.ItemFromGround].player == player)
assert(reply.asInstanceOf[Zone.ItemFromGround].item == item)
assert(reply.isInstanceOf[Zone.Ground.ItemInHand])
assert(reply.asInstanceOf[Zone.Ground.ItemInHand].item == item)
}
"get item from ground (failure)" in {
@ -508,11 +507,11 @@ class ZoneGroundTest extends ActorTest {
val player = Player(Avatar("Chord", PlanetSideEmpire.TR, CharacterGender.Male, 0, 5))
system.actorOf(Props(classOf[ZoneTest.ZoneInitActor], zone), "get-item-test-fail") ! "!"
receiveOne(Duration.create(200, "ms")) //consume
zone.Ground ! Zone.DropItemOnGround(item, Vector3.Zero, Vector3.Zero)
zone.Ground ! Zone.Ground.DropItem(item, Vector3.Zero, Vector3.Zero)
expectNoMsg(Duration.create(100, "ms"))
assert(zone.EquipmentOnGround == List(item))
zone.Ground ! Zone.GetItemOnGround(player, PlanetSideGUID(11)) //wrong guid
zone.Ground ! Zone.Ground.PickupItem(PlanetSideGUID(11)) //wrong guid
expectNoMsg(Duration.create(500, "ms"))
}
}