mirror of
https://github.com/2revoemag/PSF-BotServer.git
synced 2026-07-13 23:44:40 +00:00
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:
parent
fdf05337fd
commit
f6f7ad5617
12 changed files with 192 additions and 126 deletions
|
|
@ -386,27 +386,15 @@ object Zone {
|
||||||
final case class NoValidSpawnPoint(zone_number : Int, spawn_group : Option[Int])
|
final case class NoValidSpawnPoint(zone_number : Int, spawn_group : Option[Int])
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
object Ground {
|
||||||
* Message to relinguish an item and place in on the ground.
|
final case class DropItem(item : Equipment, pos : Vector3, orient : Vector3)
|
||||||
* @param item the piece of `Equipment`
|
final case class ItemOnGround(item : Equipment, pos : Vector3, orient : Vector3)
|
||||||
* @param pos where it is dropped
|
final case class CanNotDropItem(item : Equipment)
|
||||||
* @param orient in which direction it is facing when dropped
|
|
||||||
*/
|
|
||||||
final case class DropItemOnGround(item : Equipment, pos : Vector3, orient : Vector3)
|
|
||||||
|
|
||||||
/**
|
final case class PickupItem(item_guid : PlanetSideGUID)
|
||||||
* Message to attempt to acquire an item from the ground (before somoene else?).
|
final case class ItemInHand(item : Equipment)
|
||||||
* @param player who wants the piece of `Equipment`
|
final case class CanNotPickupItem(item_guid : PlanetSideGUID)
|
||||||
* @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)
|
|
||||||
|
|
||||||
object Vehicle {
|
object Vehicle {
|
||||||
final case class Spawn(vehicle : Vehicle)
|
final case class Spawn(vehicle : Vehicle)
|
||||||
|
|
|
||||||
|
|
@ -50,10 +50,10 @@ class ZoneActor(zone : Zone) extends Actor {
|
||||||
zone.Population forward msg
|
zone.Population forward msg
|
||||||
|
|
||||||
//frwd to Ground Actor
|
//frwd to Ground Actor
|
||||||
case msg @ Zone.DropItemOnGround =>
|
case msg @ Zone.Ground.DropItem =>
|
||||||
zone.Ground forward msg
|
zone.Ground forward msg
|
||||||
|
|
||||||
case msg @ Zone.GetItemOnGround =>
|
case msg @ Zone.Ground.PickupItem =>
|
||||||
zone.Ground forward msg
|
zone.Ground forward msg
|
||||||
|
|
||||||
//frwd to Vehicle Actor
|
//frwd to Vehicle Actor
|
||||||
|
|
|
||||||
|
|
@ -16,18 +16,22 @@ class ZoneGroundActor(equipmentOnGround : ListBuffer[Equipment]) extends Actor {
|
||||||
//private[this] val log = org.log4s.getLogger
|
//private[this] val log = org.log4s.getLogger
|
||||||
|
|
||||||
def receive : Receive = {
|
def receive : Receive = {
|
||||||
case Zone.DropItemOnGround(item, pos, orient) =>
|
case Zone.Ground.DropItem(item, pos, orient) =>
|
||||||
item.Position = pos
|
sender ! (FindItemOnGround(item.GUID) match {
|
||||||
item.Orientation = orient
|
|
||||||
equipmentOnGround += item
|
|
||||||
|
|
||||||
case Zone.GetItemOnGround(player, item_guid) =>
|
|
||||||
FindItemOnGround(item_guid) match {
|
|
||||||
case Some(item) =>
|
|
||||||
sender ! Zone.ItemFromGround(player, item)
|
|
||||||
case None =>
|
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 _ => ;
|
case _ => ;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -19,13 +19,18 @@ final case class ActionResultMessage(successful : Boolean,
|
||||||
}
|
}
|
||||||
|
|
||||||
object ActionResultMessage extends Marshallable[ActionResultMessage] {
|
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] = (
|
implicit val codec : Codec[ActionResultMessage] = (
|
||||||
("successful" | bool) >>:~ { res =>
|
("successful" | bool) >>:~ { res =>
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,14 @@ final case class ObjectDetachMessage(parent_guid : PlanetSideGUID,
|
||||||
}
|
}
|
||||||
|
|
||||||
object ObjectDetachMessage extends Marshallable[ObjectDetachMessage] {
|
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] = (
|
implicit val codec : Codec[ObjectDetachMessage] = (
|
||||||
("parent_guid" | PlanetSideGUID.codec) ::
|
("parent_guid" | PlanetSideGUID.codec) ::
|
||||||
("child_guid" | PlanetSideGUID.codec) ::
|
("child_guid" | PlanetSideGUID.codec) ::
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,7 @@ class ActionResultMessageTest extends Specification {
|
||||||
}
|
}
|
||||||
|
|
||||||
"encode (pass, minimal)" in {
|
"encode (pass, minimal)" in {
|
||||||
val msg = ActionResultMessage()
|
val msg = ActionResultMessage.Pass
|
||||||
val pkt = PacketCoding.EncodePacket(msg).require.toByteVector
|
val pkt = PacketCoding.EncodePacket(msg).require.toByteVector
|
||||||
|
|
||||||
pkt mustEqual string_pass
|
pkt mustEqual string_pass
|
||||||
|
|
@ -52,7 +52,7 @@ class ActionResultMessageTest extends Specification {
|
||||||
}
|
}
|
||||||
|
|
||||||
"encode (fail, minimal)" in {
|
"encode (fail, minimal)" in {
|
||||||
val msg = ActionResultMessage(1)
|
val msg = ActionResultMessage.Fail(1)
|
||||||
val pkt = PacketCoding.EncodePacket(msg).require.toByteVector
|
val pkt = PacketCoding.EncodePacket(msg).require.toByteVector
|
||||||
|
|
||||||
pkt mustEqual string_fail
|
pkt mustEqual string_fail
|
||||||
|
|
|
||||||
|
|
@ -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 msg = ObjectDetachMessage(PlanetSideGUID(2916), PlanetSideGUID(2502), Vector3(3567.1406f, 2988.0078f, 71.84375f), 0f, 0f, 270f)
|
||||||
val pkt = PacketCoding.EncodePacket(msg).require.toByteVector
|
val pkt = PacketCoding.EncodePacket(msg).require.toByteVector
|
||||||
|
|
||||||
pkt mustEqual string
|
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
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -477,7 +477,7 @@ class ZoneGroundTest extends ActorTest {
|
||||||
assert(zone.EquipmentOnGround.isEmpty)
|
assert(zone.EquipmentOnGround.isEmpty)
|
||||||
assert(item.Position == Vector3.Zero)
|
assert(item.Position == Vector3.Zero)
|
||||||
assert(item.Orientation == 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"))
|
expectNoMsg(Duration.create(100, "ms"))
|
||||||
|
|
||||||
assert(zone.EquipmentOnGround == List(item))
|
assert(zone.EquipmentOnGround == List(item))
|
||||||
|
|
@ -490,17 +490,16 @@ class ZoneGroundTest extends ActorTest {
|
||||||
val player = Player(Avatar("Chord", PlanetSideEmpire.TR, CharacterGender.Male, 0, 5))
|
val player = Player(Avatar("Chord", PlanetSideEmpire.TR, CharacterGender.Male, 0, 5))
|
||||||
system.actorOf(Props(classOf[ZoneTest.ZoneInitActor], zone), "get-item-test-good") ! "!"
|
system.actorOf(Props(classOf[ZoneTest.ZoneInitActor], zone), "get-item-test-good") ! "!"
|
||||||
receiveOne(Duration.create(200, "ms")) //consume
|
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"))
|
expectNoMsg(Duration.create(100, "ms"))
|
||||||
|
|
||||||
assert(zone.EquipmentOnGround == List(item))
|
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"))
|
val reply = receiveOne(Duration.create(100, "ms"))
|
||||||
|
|
||||||
assert(zone.EquipmentOnGround.isEmpty)
|
assert(zone.EquipmentOnGround.isEmpty)
|
||||||
assert(reply.isInstanceOf[Zone.ItemFromGround])
|
assert(reply.isInstanceOf[Zone.Ground.ItemInHand])
|
||||||
assert(reply.asInstanceOf[Zone.ItemFromGround].player == player)
|
assert(reply.asInstanceOf[Zone.Ground.ItemInHand].item == item)
|
||||||
assert(reply.asInstanceOf[Zone.ItemFromGround].item == item)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
"get item from ground (failure)" in {
|
"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))
|
val player = Player(Avatar("Chord", PlanetSideEmpire.TR, CharacterGender.Male, 0, 5))
|
||||||
system.actorOf(Props(classOf[ZoneTest.ZoneInitActor], zone), "get-item-test-fail") ! "!"
|
system.actorOf(Props(classOf[ZoneTest.ZoneInitActor], zone), "get-item-test-fail") ! "!"
|
||||||
receiveOne(Duration.create(200, "ms")) //consume
|
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"))
|
expectNoMsg(Duration.create(100, "ms"))
|
||||||
|
|
||||||
assert(zone.EquipmentOnGround == List(item))
|
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"))
|
expectNoMsg(Duration.create(500, "ms"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -255,7 +255,7 @@ class WorldSessionActor extends Actor with MDCContextAware {
|
||||||
|
|
||||||
case AvatarResponse.ChangeAmmo(weapon_guid, weapon_slot, previous_guid, ammo_id, ammo_guid, ammo_data) =>
|
case AvatarResponse.ChangeAmmo(weapon_guid, weapon_slot, previous_guid, ammo_id, ammo_guid, ammo_data) =>
|
||||||
if(tplayer_guid != guid) {
|
if(tplayer_guid != guid) {
|
||||||
sendResponse(ObjectDetachMessage(weapon_guid, previous_guid, Vector3(0,0,0), 0f, 0f, 0f))
|
sendResponse(ObjectDetachMessage(weapon_guid, previous_guid, Vector3.Zero, 0))
|
||||||
sendResponse(
|
sendResponse(
|
||||||
ObjectCreateMessage(
|
ObjectCreateMessage(
|
||||||
ammo_id,
|
ammo_id,
|
||||||
|
|
@ -405,7 +405,7 @@ class WorldSessionActor extends Actor with MDCContextAware {
|
||||||
}
|
}
|
||||||
|
|
||||||
case LocalServiceResponse(_, guid, reply) =>
|
case LocalServiceResponse(_, guid, reply) =>
|
||||||
val tplayer_guid = if(player.HasGUID) { player.GUID} else { PlanetSideGUID(0) }
|
val tplayer_guid = if(player.HasGUID) { player.GUID} else { PlanetSideGUID(-1) }
|
||||||
reply match {
|
reply match {
|
||||||
case LocalResponse.DoorOpens(door_guid) =>
|
case LocalResponse.DoorOpens(door_guid) =>
|
||||||
if(tplayer_guid != guid) {
|
if(tplayer_guid != guid) {
|
||||||
|
|
@ -415,16 +415,21 @@ class WorldSessionActor extends Actor with MDCContextAware {
|
||||||
case LocalResponse.DoorCloses(door_guid) => //door closes for everyone
|
case LocalResponse.DoorCloses(door_guid) => //door closes for everyone
|
||||||
sendResponse(GenericObjectStateMsg(door_guid, 17))
|
sendResponse(GenericObjectStateMsg(door_guid, 17))
|
||||||
|
|
||||||
|
case LocalResponse.DropItem(id, item_guid, data) =>
|
||||||
|
if(tplayer_guid != guid) {
|
||||||
|
sendResponse(ObjectCreateMessage(id, item_guid, data))
|
||||||
|
}
|
||||||
|
|
||||||
case LocalResponse.HackClear(target_guid, unk1, unk2) =>
|
case LocalResponse.HackClear(target_guid, unk1, unk2) =>
|
||||||
sendResponse(HackMessage(0, target_guid, guid, 0, unk1, HackState.HackCleared, unk2))
|
sendResponse(HackMessage(0, target_guid, guid, 0, unk1, HackState.HackCleared, unk2))
|
||||||
|
|
||||||
case LocalResponse.HackObject(target_guid, unk1, unk2) =>
|
case LocalResponse.HackObject(target_guid, unk1, unk2) =>
|
||||||
if(player.GUID != guid) {
|
if(tplayer_guid != guid) {
|
||||||
sendResponse(HackMessage(0, target_guid, guid, 100, unk1, HackState.Hacked, unk2))
|
sendResponse(HackMessage(0, target_guid, guid, 100, unk1, HackState.Hacked, unk2))
|
||||||
}
|
}
|
||||||
|
|
||||||
case LocalResponse.ProximityTerminalEffect(object_guid, effectState) =>
|
case LocalResponse.ProximityTerminalEffect(object_guid, effectState) =>
|
||||||
if(player.GUID != guid) {
|
if(tplayer_guid != guid) {
|
||||||
sendResponse(ProximityTerminalUseMessage(PlanetSideGUID(0), object_guid, effectState))
|
sendResponse(ProximityTerminalUseMessage(PlanetSideGUID(0), object_guid, effectState))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -465,7 +470,7 @@ class WorldSessionActor extends Actor with MDCContextAware {
|
||||||
}
|
}
|
||||||
|
|
||||||
case VehicleResponse.DetachFromRails(vehicle_guid, pad_guid, pad_position, pad_orientation_z) =>
|
case VehicleResponse.DetachFromRails(vehicle_guid, pad_guid, pad_position, pad_orientation_z) =>
|
||||||
sendResponse(ObjectDetachMessage(pad_guid, vehicle_guid, pad_position + Vector3(0,0,0.5f), 0, 0, pad_orientation_z))
|
sendResponse(ObjectDetachMessage(pad_guid, vehicle_guid, pad_position + Vector3(0,0,0.5f), pad_orientation_z))
|
||||||
|
|
||||||
case VehicleResponse.InventoryState(obj, parent_guid, start, con_data) =>
|
case VehicleResponse.InventoryState(obj, parent_guid, start, con_data) =>
|
||||||
if(tplayer_guid != guid) {
|
if(tplayer_guid != guid) {
|
||||||
|
|
@ -844,12 +849,10 @@ class WorldSessionActor extends Actor with MDCContextAware {
|
||||||
})
|
})
|
||||||
//drop items on ground
|
//drop items on ground
|
||||||
val pos = tplayer.Position
|
val pos = tplayer.Position
|
||||||
val orient = tplayer.Orientation
|
val orient = Vector3(0,0, tplayer.Orientation.z)
|
||||||
((dropHolsters ++ dropInventory).map(_.obj) ++ drop).foreach(obj => {
|
((dropHolsters ++ dropInventory).map(_.obj) ++ drop).foreach(obj => {
|
||||||
continent.Ground ! Zone.DropItemOnGround(obj, pos, Vector3(0f, 0f, orient.z))
|
//TODO make a sound when dropping stuff
|
||||||
sendResponse(ObjectDetachMessage(tplayer.GUID, obj.GUID, pos, 0f, 0f, orient.z))
|
continent.Ground ! Zone.Ground.DropItem(obj, pos, orient)
|
||||||
val objDef = obj.Definition
|
|
||||||
avatarService ! AvatarServiceMessage(tplayer.Continent, AvatarAction.EquipmentOnGround(tplayer.GUID, pos, orient, objDef.ObjectId, obj.GUID, objDef.Packet.ConstructorData(obj).get))
|
|
||||||
})
|
})
|
||||||
sendResponse(ItemTransactionResultMessage (msg.terminal_guid, TransactionType.Buy, true))
|
sendResponse(ItemTransactionResultMessage (msg.terminal_guid, TransactionType.Buy, true))
|
||||||
}
|
}
|
||||||
|
|
@ -938,12 +941,9 @@ class WorldSessionActor extends Actor with MDCContextAware {
|
||||||
})
|
})
|
||||||
//drop stuff on ground
|
//drop stuff on ground
|
||||||
val pos = tplayer.Position
|
val pos = tplayer.Position
|
||||||
val orient = tplayer.Orientation
|
val orient = Vector3(0,0, tplayer.Orientation.z)
|
||||||
((dropHolsters ++ dropInventory).map(_.obj)).foreach(obj => {
|
((dropHolsters ++ dropInventory).map(_.obj)).foreach(obj => {
|
||||||
continent.Ground ! Zone.DropItemOnGround(obj, pos, Vector3(0f, 0f, orient.z))
|
continent.Ground ! Zone.Ground.DropItem(obj, pos, orient)
|
||||||
sendResponse(ObjectDetachMessage(tplayer.GUID, obj.GUID, pos, 0f, 0f, orient.z))
|
|
||||||
val objDef = obj.Definition
|
|
||||||
avatarService ! AvatarServiceMessage(tplayer.Continent, AvatarAction.EquipmentOnGround(tplayer.GUID, pos, orient, objDef.ObjectId, obj.GUID, objDef.Packet.ConstructorData(obj).get))
|
|
||||||
})
|
})
|
||||||
|
|
||||||
case Terminal.VehicleLoadout(definition, weapons, inventory) =>
|
case Terminal.VehicleLoadout(definition, weapons, inventory) =>
|
||||||
|
|
@ -1177,7 +1177,7 @@ class WorldSessionActor extends Actor with MDCContextAware {
|
||||||
case VehicleSpawnPad.ServerVehicleOverrideStart(vehicle, pad) =>
|
case VehicleSpawnPad.ServerVehicleOverrideStart(vehicle, pad) =>
|
||||||
val vdef = vehicle.Definition
|
val vdef = vehicle.Definition
|
||||||
if(vehicle.Seats(0).isOccupied) {
|
if(vehicle.Seats(0).isOccupied) {
|
||||||
sendResponse(ObjectDetachMessage(pad.GUID, vehicle.GUID, pad.Position + Vector3(0, 0, 0.5f), 0, 0, pad.Orientation.z))
|
sendResponse(ObjectDetachMessage(pad.GUID, vehicle.GUID, pad.Position + Vector3(0, 0, 0.5f), pad.Orientation.z))
|
||||||
}
|
}
|
||||||
ServerVehicleOverride(vehicle, vdef.AutoPilotSpeed1, GlobalDefinitions.isFlightVehicle(vdef):Int)
|
ServerVehicleOverride(vehicle, vdef.AutoPilotSpeed1, GlobalDefinitions.isFlightVehicle(vdef):Int)
|
||||||
|
|
||||||
|
|
@ -1375,6 +1375,62 @@ class WorldSessionActor extends Actor with MDCContextAware {
|
||||||
RequestSanctuaryZoneSpawn(player, zone_number)
|
RequestSanctuaryZoneSpawn(player, zone_number)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case Zone.Ground.ItemOnGround(item, pos, orient) =>
|
||||||
|
item.Position = pos
|
||||||
|
item.Orientation = Vector3(0,0, orient.z) //only one kind of rotation is important
|
||||||
|
val exclusionId = player.Find(item) match {
|
||||||
|
case Some(slotNum) =>
|
||||||
|
player.Slot(slotNum).Equipment = None
|
||||||
|
sendResponse(ObjectDetachMessage(player.GUID, item.GUID, pos, orient.z))
|
||||||
|
sendResponse(ActionResultMessage.Pass)
|
||||||
|
player.GUID //we're dropping it; don't need to see it dropped again
|
||||||
|
case None =>
|
||||||
|
PlanetSideGUID(0) //object is being introduced into the world upon drop
|
||||||
|
}
|
||||||
|
localService ! LocalServiceMessage(continent.Id, LocalAction.DropItem(exclusionId, item))
|
||||||
|
|
||||||
|
case Zone.Ground.CanNotDropItem(item) =>
|
||||||
|
log.warn(s"DropItem: $player tried to drop a $item on the ground, but he missed")
|
||||||
|
player.Find(item) match {
|
||||||
|
case None => //item in limbo
|
||||||
|
taskResolver ! GUIDTask.UnregisterEquipment(item)(continent.GUID)
|
||||||
|
case Some(_) => ;
|
||||||
|
}
|
||||||
|
|
||||||
|
case Zone.Ground.ItemInHand(item) =>
|
||||||
|
player.Fit(item) match {
|
||||||
|
case Some(slotNum) =>
|
||||||
|
val item_guid = item.GUID
|
||||||
|
val player_guid = player.GUID
|
||||||
|
player.Slot(slotNum).Equipment = item
|
||||||
|
val definition = item.Definition
|
||||||
|
sendResponse(
|
||||||
|
ObjectCreateDetailedMessage(
|
||||||
|
definition.ObjectId,
|
||||||
|
item_guid,
|
||||||
|
ObjectCreateMessageParent(player_guid, slotNum),
|
||||||
|
definition.Packet.DetailedConstructorData(item).get
|
||||||
|
)
|
||||||
|
)
|
||||||
|
avatarService ! AvatarServiceMessage(continent.Id, if(player.VisibleSlots.contains(slotNum)) {
|
||||||
|
AvatarAction.EquipmentInHand(player_guid, player_guid, slotNum, item)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
AvatarAction.ObjectDelete(player_guid, item_guid)
|
||||||
|
})
|
||||||
|
sendResponse(ActionResultMessage.Pass)
|
||||||
|
case None =>
|
||||||
|
continent.Ground ! Zone.Ground.DropItem(item, item.Position, item.Orientation) //restore previous state
|
||||||
|
}
|
||||||
|
|
||||||
|
case Zone.Ground.CanNotPickupItem(item_guid) =>
|
||||||
|
continent.GUID(item_guid) match {
|
||||||
|
case Some(item) =>
|
||||||
|
log.warn(s"DropItem: finding a $item on the ground was suggested, but $player can not reach it")
|
||||||
|
case None =>
|
||||||
|
log.warn(s"DropItem: finding an item ($item_guid) on the ground was suggested, but $player can not see it")
|
||||||
|
}
|
||||||
|
|
||||||
case InterstellarCluster.ClientInitializationComplete() =>
|
case InterstellarCluster.ClientInitializationComplete() =>
|
||||||
StopBundlingPackets()
|
StopBundlingPackets()
|
||||||
LivePlayerList.Add(sessionId, avatar)
|
LivePlayerList.Add(sessionId, avatar)
|
||||||
|
|
@ -1467,31 +1523,6 @@ class WorldSessionActor extends Actor with MDCContextAware {
|
||||||
//TacticsMessage
|
//TacticsMessage
|
||||||
StopBundlingPackets()
|
StopBundlingPackets()
|
||||||
|
|
||||||
|
|
||||||
case Zone.ItemFromGround(tplayer, item) =>
|
|
||||||
val obj_guid = item.GUID
|
|
||||||
val player_guid = tplayer.GUID
|
|
||||||
tplayer.Fit(item) match {
|
|
||||||
case Some(slot) =>
|
|
||||||
tplayer.Slot(slot).Equipment = item
|
|
||||||
avatarService ! AvatarServiceMessage(tplayer.Continent, AvatarAction.ObjectDelete(player_guid, obj_guid))
|
|
||||||
val definition = item.Definition
|
|
||||||
sendResponse(
|
|
||||||
ObjectCreateDetailedMessage(
|
|
||||||
definition.ObjectId,
|
|
||||||
obj_guid,
|
|
||||||
ObjectCreateMessageParent(player_guid, slot),
|
|
||||||
definition.Packet.DetailedConstructorData(item).get
|
|
||||||
)
|
|
||||||
)
|
|
||||||
sendResponse(ActionResultMessage())
|
|
||||||
if(tplayer.VisibleSlots.contains(slot)) {
|
|
||||||
avatarService ! AvatarServiceMessage(tplayer.Continent, AvatarAction.EquipmentInHand(player_guid, player_guid, slot, item))
|
|
||||||
}
|
|
||||||
case None =>
|
|
||||||
continent.Ground ! Zone.DropItemOnGround(item, item.Position, item.Orientation) //restore
|
|
||||||
}
|
|
||||||
|
|
||||||
case ItemHacking(tplayer, target, tool_guid, delta, completeAction, tickAction) =>
|
case ItemHacking(tplayer, target, tool_guid, delta, completeAction, tickAction) =>
|
||||||
progressBarUpdate.cancel
|
progressBarUpdate.cancel
|
||||||
if(progressBarValue.isDefined) {
|
if(progressBarValue.isDefined) {
|
||||||
|
|
@ -1607,18 +1638,17 @@ class WorldSessionActor extends Actor with MDCContextAware {
|
||||||
import scala.concurrent.ExecutionContext.Implicits.global
|
import scala.concurrent.ExecutionContext.Implicits.global
|
||||||
clientKeepAlive.cancel
|
clientKeepAlive.cancel
|
||||||
clientKeepAlive = context.system.scheduler.schedule(0 seconds, 500 milliseconds, self, PokeClient())
|
clientKeepAlive = context.system.scheduler.schedule(0 seconds, 500 milliseconds, self, PokeClient())
|
||||||
log.warn(PacketCoding.DecodePacket(hex"d2327e7b8a972b95113881003710").toString)
|
|
||||||
|
|
||||||
case msg @ CharacterCreateRequestMessage(name, head, voice, gender, empire) =>
|
case msg @ CharacterCreateRequestMessage(name, head, voice, gender, empire) =>
|
||||||
log.info("Handling " + msg)
|
log.info("Handling " + msg)
|
||||||
sendResponse(ActionResultMessage(true, None))
|
sendResponse(ActionResultMessage.Pass)
|
||||||
self ! ListAccountCharacters
|
self ! ListAccountCharacters
|
||||||
|
|
||||||
case msg @ CharacterRequestMessage(charId, action) =>
|
case msg @ CharacterRequestMessage(charId, action) =>
|
||||||
log.info("Handling " + msg)
|
log.info("Handling " + msg)
|
||||||
action match {
|
action match {
|
||||||
case CharacterRequestAction.Delete =>
|
case CharacterRequestAction.Delete =>
|
||||||
sendResponse(ActionResultMessage(false, Some(1)))
|
sendResponse(ActionResultMessage.Fail(1))
|
||||||
case CharacterRequestAction.Select =>
|
case CharacterRequestAction.Select =>
|
||||||
//TODO check if can spawn on last continent/location from player?
|
//TODO check if can spawn on last continent/location from player?
|
||||||
//TODO if yes, get continent guid accessors
|
//TODO if yes, get continent guid accessors
|
||||||
|
|
@ -1828,7 +1858,7 @@ class WorldSessionActor extends Actor with MDCContextAware {
|
||||||
import scala.concurrent.duration._
|
import scala.concurrent.duration._
|
||||||
import scala.concurrent.ExecutionContext.Implicits.global
|
import scala.concurrent.ExecutionContext.Implicits.global
|
||||||
context.system.scheduler.scheduleOnce(50 milliseconds, self, UnregisterCorpseOnVehicleDisembark(player))
|
context.system.scheduler.scheduleOnce(50 milliseconds, self, UnregisterCorpseOnVehicleDisembark(player))
|
||||||
//sendResponse(ObjectDetachMessage(vehicle_guid, player.GUID, Vector3.Zero, 0, 0, 0))
|
//sendResponse(ObjectDetachMessage(vehicle_guid, player.GUID, Vector3.Zero, 0))
|
||||||
//sendResponse(PlayerStateShiftMessage(ShiftState(1, Vector3.Zero, 0)))
|
//sendResponse(PlayerStateShiftMessage(ShiftState(1, Vector3.Zero, 0)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1989,8 +2019,8 @@ class WorldSessionActor extends Actor with MDCContextAware {
|
||||||
val tailReloadValue : Int = if(xs.isEmpty) { 0 } else { xs.map(_.obj.asInstanceOf[AmmoBox].Capacity).reduceLeft(_ + _) }
|
val tailReloadValue : Int = if(xs.isEmpty) { 0 } else { xs.map(_.obj.asInstanceOf[AmmoBox].Capacity).reduceLeft(_ + _) }
|
||||||
val sumReloadValue : Int = originalBoxCapacity + tailReloadValue
|
val sumReloadValue : Int = originalBoxCapacity + tailReloadValue
|
||||||
val previousBox = tool.AmmoSlot.Box //current magazine in tool
|
val previousBox = tool.AmmoSlot.Box //current magazine in tool
|
||||||
sendResponse(ObjectDetachMessage(tool.GUID, previousBox.GUID, Vector3(0f, 0f, 0f), 0f, 0f, 0f))
|
sendResponse(ObjectDetachMessage(tool.GUID, previousBox.GUID, Vector3.Zero, 0f))
|
||||||
sendResponse(ObjectDetachMessage(player.GUID, box.GUID, Vector3(0f, 0f, 0f), 0f, 0f, 0f))
|
sendResponse(ObjectDetachMessage(player.GUID, box.GUID, Vector3.Zero, 0f))
|
||||||
obj.Inventory -= x.start //remove replacement ammo from inventory
|
obj.Inventory -= x.start //remove replacement ammo from inventory
|
||||||
val ammoSlotIndex = tool.FireMode.AmmoSlotIndex
|
val ammoSlotIndex = tool.FireMode.AmmoSlotIndex
|
||||||
tool.AmmoSlots(ammoSlotIndex).Box = box //put replacement ammo in tool
|
tool.AmmoSlots(ammoSlotIndex).Box = box //put replacement ammo in tool
|
||||||
|
|
@ -2158,27 +2188,37 @@ class WorldSessionActor extends Actor with MDCContextAware {
|
||||||
sendResponse(EmoteMsg(avatar_guid, emote))
|
sendResponse(EmoteMsg(avatar_guid, emote))
|
||||||
|
|
||||||
case msg @ DropItemMessage(item_guid) =>
|
case msg @ DropItemMessage(item_guid) =>
|
||||||
log.info("DropItem: " + msg)
|
log.info(s"DropItem: $msg")
|
||||||
player.FreeHand.Equipment match {
|
continent.GUID(item_guid) match {
|
||||||
case Some(item) =>
|
case Some(item : Equipment) =>
|
||||||
if(item.GUID == item_guid) {
|
player.FreeHand.Equipment match {
|
||||||
val orient : Vector3 = Vector3(0f, 0f, player.Orientation.z)
|
case Some(_) =>
|
||||||
player.FreeHand.Equipment = None
|
if(item.GUID == item_guid) {
|
||||||
continent.Ground ! Zone.DropItemOnGround(item, player.Position, orient)
|
continent.Ground ! Zone.Ground.DropItem(item, player.Position, player.Orientation)
|
||||||
sendResponse(ObjectDetachMessage(player.GUID, item.GUID, player.Position, 0f, 0f, player.Orientation.z))
|
}
|
||||||
val objDef = item.Definition
|
case None =>
|
||||||
avatarService ! AvatarServiceMessage(player.Continent, AvatarAction.EquipmentOnGround(player.GUID, player.Position, orient, objDef.ObjectId, item.GUID, objDef.Packet.ConstructorData(item).get))
|
log.warn(s"DropItem: $player wanted to drop a $item, but it wasn't at hand")
|
||||||
}
|
|
||||||
else {
|
|
||||||
log.warn(s"item in hand was ${item.GUID} but trying to drop $item_guid; nothing will be dropped")
|
|
||||||
}
|
}
|
||||||
|
case Some(obj) => //TODO LLU
|
||||||
|
log.warn(s"DropItem: $player wanted to drop a $obj, but that isn't possible")
|
||||||
case None =>
|
case None =>
|
||||||
log.error(s"$player wanted to drop an item, but it was not in hand")
|
log.warn(s"DropItem: $player wanted to drop an item ($item_guid), but it was nowhere to be found")
|
||||||
}
|
}
|
||||||
|
|
||||||
case msg @ PickupItemMessage(item_guid, player_guid, unk1, unk2) =>
|
case msg @ PickupItemMessage(item_guid, player_guid, unk1, unk2) =>
|
||||||
log.info("PickupItem: " + msg)
|
log.info(s"PickupItem: $msg")
|
||||||
continent.Ground ! Zone.GetItemOnGround(player, item_guid)
|
continent.GUID(item_guid) match {
|
||||||
|
case Some(item : Equipment) =>
|
||||||
|
player.Fit(item) match {
|
||||||
|
case Some(_) =>
|
||||||
|
continent.Ground ! Zone.Ground.PickupItem(item_guid)
|
||||||
|
case None => //skip
|
||||||
|
sendResponse(ActionResultMessage.Fail(16)) //error code?
|
||||||
|
}
|
||||||
|
case _ =>
|
||||||
|
log.warn(s"PickupItem: $player requested an item that doesn't exist in this zone; assume client-side garbage data")
|
||||||
|
sendResponse(ObjectDeleteMessage(item_guid, 0))
|
||||||
|
}
|
||||||
|
|
||||||
case msg @ ReloadMessage(item_guid, ammo_clip, unk1) =>
|
case msg @ ReloadMessage(item_guid, ammo_clip, unk1) =>
|
||||||
log.info("Reload: " + msg)
|
log.info("Reload: " + msg)
|
||||||
|
|
@ -3847,14 +3887,14 @@ class WorldSessionActor extends Actor with MDCContextAware {
|
||||||
case Some(InventoryItem(item2, destIndex)) => //yes, swap
|
case Some(InventoryItem(item2, destIndex)) => //yes, swap
|
||||||
//cleanly shuffle items around to avoid losing icons
|
//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
|
//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))
|
sendResponse(ObjectDetachMessage(source_guid, item_guid, Vector3.Zero, 0f))
|
||||||
val item2_guid = item2.GUID
|
val item2_guid = item2.GUID
|
||||||
destination.Slot(destIndex).Equipment = None //remove the swap item from destination
|
destination.Slot(destIndex).Equipment = None //remove the swap item from destination
|
||||||
(indexSlot.Equipment = item2) match {
|
(indexSlot.Equipment = item2) match {
|
||||||
case Some(_) => //item and item2 swapped places successfully
|
case Some(_) => //item and item2 swapped places successfully
|
||||||
log.info(s"MoveItem: $item2 swapped to $source @ $index")
|
log.info(s"MoveItem: $item2 swapped to $source @ $index")
|
||||||
//remove item2 from destination
|
//remove item2 from destination
|
||||||
sendResponse(ObjectDetachMessage(destination_guid, item2_guid, Vector3.Zero, 0f, 0f, 0f))
|
sendResponse(ObjectDetachMessage(destination_guid, item2_guid, Vector3.Zero, 0f))
|
||||||
destination match {
|
destination match {
|
||||||
case obj : Vehicle =>
|
case obj : Vehicle =>
|
||||||
vehicleService ! VehicleServiceMessage(s"${obj.Actor}", VehicleAction.UnstowEquipment(player_guid, item2_guid))
|
vehicleService ! VehicleServiceMessage(s"${obj.Actor}", VehicleAction.UnstowEquipment(player_guid, item2_guid))
|
||||||
|
|
@ -3897,8 +3937,8 @@ class WorldSessionActor extends Actor with MDCContextAware {
|
||||||
val pos = source.Position
|
val pos = source.Position
|
||||||
val sourceOrientZ = source.Orientation.z
|
val sourceOrientZ = source.Orientation.z
|
||||||
val orient : Vector3 = Vector3(0f, 0f, sourceOrientZ)
|
val orient : Vector3 = Vector3(0f, 0f, sourceOrientZ)
|
||||||
continent.Actor ! Zone.DropItemOnGround(item2, pos, orient)
|
continent.Ground ! Zone.Ground.DropItem(item2, pos, orient)
|
||||||
sendResponse(ObjectDetachMessage(destination_guid, item2_guid, pos, 0f, 0f, sourceOrientZ)) //ground
|
sendResponse(ObjectDetachMessage(destination_guid, item2_guid, pos, sourceOrientZ)) //ground
|
||||||
val objDef = item2.Definition
|
val objDef = item2.Definition
|
||||||
destination match {
|
destination match {
|
||||||
case obj : Vehicle =>
|
case obj : Vehicle =>
|
||||||
|
|
@ -3956,15 +3996,7 @@ class WorldSessionActor extends Actor with MDCContextAware {
|
||||||
* @param item the item
|
* @param item the item
|
||||||
*/
|
*/
|
||||||
def NormalItemDrop(obj : PlanetSideGameObject with Container, zone : Zone, service : ActorRef)(item : Equipment) : Unit = {
|
def NormalItemDrop(obj : PlanetSideGameObject with Container, zone : Zone, service : ActorRef)(item : Equipment) : Unit = {
|
||||||
val itemGUID = item.GUID
|
continent.Ground ! Zone.Ground.DropItem(item, obj.Position, Vector3(0f, 0f, obj.Orientation.z))
|
||||||
val ang = obj.Orientation.z
|
|
||||||
val pos = obj.Position
|
|
||||||
val orient = Vector3(0f, 0f, ang)
|
|
||||||
item.Position = pos
|
|
||||||
item.Orientation = orient
|
|
||||||
zone.Ground ! Zone.DropItemOnGround(item, pos, orient)
|
|
||||||
val itemDef = item.Definition
|
|
||||||
service ! AvatarServiceMessage(zone.Id, AvatarAction.EquipmentOnGround(Service.defaultPlayerGUID, pos, orient, itemDef.ObjectId, itemGUID, itemDef.Packet.ConstructorData(item).get))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
// Copyright (c) 2017 PSForever
|
// Copyright (c) 2017 PSForever
|
||||||
package services.local
|
package services.local
|
||||||
|
|
||||||
|
import net.psforever.objects.equipment.Equipment
|
||||||
import net.psforever.objects.serverobject.PlanetSideServerObject
|
import net.psforever.objects.serverobject.PlanetSideServerObject
|
||||||
import net.psforever.objects.serverobject.doors.Door
|
import net.psforever.objects.serverobject.doors.Door
|
||||||
import net.psforever.objects.zones.Zone
|
import net.psforever.objects.zones.Zone
|
||||||
|
|
@ -12,6 +13,7 @@ object LocalAction {
|
||||||
|
|
||||||
final case class DoorOpens(player_guid : PlanetSideGUID, continent : Zone, door : Door) extends Action
|
final case class DoorOpens(player_guid : PlanetSideGUID, continent : Zone, door : Door) extends Action
|
||||||
final case class DoorCloses(player_guid : PlanetSideGUID, door_guid : PlanetSideGUID) extends Action
|
final case class DoorCloses(player_guid : PlanetSideGUID, door_guid : PlanetSideGUID) extends Action
|
||||||
|
final case class DropItem(player_guid : PlanetSideGUID, item : Equipment) extends Action
|
||||||
final case class HackClear(player_guid : PlanetSideGUID, target : PlanetSideServerObject, unk1 : Long, unk2 : Long = 8L) extends Action
|
final case class HackClear(player_guid : PlanetSideGUID, target : PlanetSideServerObject, unk1 : Long, unk2 : Long = 8L) extends Action
|
||||||
final case class HackTemporarily(player_guid : PlanetSideGUID, continent : Zone, target : PlanetSideServerObject, unk1 : Long, unk2 : Long = 8L) extends Action
|
final case class HackTemporarily(player_guid : PlanetSideGUID, continent : Zone, target : PlanetSideServerObject, unk1 : Long, unk2 : Long = 8L) extends Action
|
||||||
final case class ProximityTerminalEffect(player_guid : PlanetSideGUID, object_guid : PlanetSideGUID, effectState : Boolean) extends Action
|
final case class ProximityTerminalEffect(player_guid : PlanetSideGUID, object_guid : PlanetSideGUID, effectState : Boolean) extends Action
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
// Copyright (c) 2017 PSForever
|
// Copyright (c) 2017 PSForever
|
||||||
package services.local
|
package services.local
|
||||||
|
|
||||||
|
import net.psforever.packet.game.objectcreate.ConstructorData
|
||||||
import net.psforever.packet.game.{PlanetSideGUID, TriggeredSound}
|
import net.psforever.packet.game.{PlanetSideGUID, TriggeredSound}
|
||||||
import net.psforever.types.Vector3
|
import net.psforever.types.Vector3
|
||||||
|
|
||||||
|
|
@ -9,6 +10,7 @@ object LocalResponse {
|
||||||
|
|
||||||
final case class DoorOpens(door_guid : PlanetSideGUID) extends Response
|
final case class DoorOpens(door_guid : PlanetSideGUID) extends Response
|
||||||
final case class DoorCloses(door_guid : PlanetSideGUID) extends Response
|
final case class DoorCloses(door_guid : PlanetSideGUID) extends Response
|
||||||
|
final case class DropItem(item_id : Int, item_guid : PlanetSideGUID, item_data : ConstructorData) extends Response
|
||||||
final case class HackClear(target_guid : PlanetSideGUID, unk1 : Long, unk2 : Long) extends Response
|
final case class HackClear(target_guid : PlanetSideGUID, unk1 : Long, unk2 : Long) extends Response
|
||||||
final case class HackObject(target_guid : PlanetSideGUID, unk1 : Long, unk2 : Long) extends Response
|
final case class HackObject(target_guid : PlanetSideGUID, unk1 : Long, unk2 : Long) extends Response
|
||||||
final case class ProximityTerminalEffect(object_guid : PlanetSideGUID, effectState : Boolean) extends Response
|
final case class ProximityTerminalEffect(object_guid : PlanetSideGUID, effectState : Boolean) extends Response
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
package services.local
|
package services.local
|
||||||
|
|
||||||
import akka.actor.{Actor, Props}
|
import akka.actor.{Actor, Props}
|
||||||
|
import net.psforever.packet.game.objectcreate.{DroppedItemData, PlacementData}
|
||||||
import services.local.support.{DoorCloseActor, HackClearActor}
|
import services.local.support.{DoorCloseActor, HackClearActor}
|
||||||
import services.{GenericEventBus, Service}
|
import services.{GenericEventBus, Service}
|
||||||
|
|
||||||
|
|
@ -46,6 +47,17 @@ class LocalService extends Actor {
|
||||||
LocalEvents.publish(
|
LocalEvents.publish(
|
||||||
LocalServiceResponse(s"/$forChannel/Local", player_guid, LocalResponse.DoorCloses(door_guid))
|
LocalServiceResponse(s"/$forChannel/Local", player_guid, LocalResponse.DoorCloses(door_guid))
|
||||||
)
|
)
|
||||||
|
case LocalAction.DropItem(player_guid, item) =>
|
||||||
|
val definition = item.Definition
|
||||||
|
val objectData = DroppedItemData(
|
||||||
|
PlacementData(item.Position, item.Orientation),
|
||||||
|
definition.Packet.ConstructorData(item).get
|
||||||
|
)
|
||||||
|
LocalEvents.publish(
|
||||||
|
LocalServiceResponse(s"/$forChannel/Local", player_guid,
|
||||||
|
LocalResponse.DropItem(definition.ObjectId, item.GUID, objectData)
|
||||||
|
)
|
||||||
|
)
|
||||||
case LocalAction.HackClear(player_guid, target, unk1, unk2) =>
|
case LocalAction.HackClear(player_guid, target, unk1, unk2) =>
|
||||||
LocalEvents.publish(
|
LocalEvents.publish(
|
||||||
LocalServiceResponse(s"/$forChannel/Local", player_guid, LocalResponse.HackClear(target.GUID, unk1, unk2))
|
LocalServiceResponse(s"/$forChannel/Local", player_guid, LocalResponse.HackClear(target.GUID, unk1, unk2))
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue