mirror of
https://github.com/psforever/PSF-LoginServer.git
synced 2026-06-26 15:24:20 +00:00
Merge 4afe8550c0 into 83482a7207
This commit is contained in:
commit
e08cde5cd9
227 changed files with 7961 additions and 9091 deletions
54
.codecov.yml
54
.codecov.yml
|
|
@ -9,6 +9,9 @@ coverage:
|
|||
threshold: 0.25%
|
||||
|
||||
ignore:
|
||||
- "src/main/java"
|
||||
- "src/main/resources"
|
||||
- "src/main/scala/akka"
|
||||
- "src/main/scala/net/psforever/objects/ObjectType.scala"
|
||||
- "src/main/scala/net/psforever/objects/avatar/Avatars.scala"
|
||||
- "src/main/scala/net/psforever/objects/ballistics/DamageResolution.scala"
|
||||
|
|
@ -18,7 +21,12 @@ ignore:
|
|||
- "src/main/scala/net/psforever/objects/equipment/EquipmentSize.scala"
|
||||
- "src/main/scala/net/psforever/objects/equipment/Kits.scala"
|
||||
- "src/main/scala/net/psforever/objects/equipment/SItem.scala"
|
||||
- "src/main/scala/net/psforever/objects/global"
|
||||
- "src/main/scala/net/psforever/objects/guid/AvailabilityPolicy.scala"
|
||||
- "src/main/scala/net/psforever/objects/loadouts/EquipmentLoadout.scala"
|
||||
- "src/main/scala/net/psforever/objects/loadouts/InfantryLoadout.scala"
|
||||
- "src/main/scala/net/psforever/objects/loadouts/SquadLoadout.scala"
|
||||
- "src/main/scala/net/psforever/objects/loadouts/VehicleLoadout.scala"
|
||||
- "src/main/scala/net/psforever/objects/serverobject/pad/AutoDriveControls.scala"
|
||||
- "src/main/scala/net/psforever/objects/serverobject/structures/StructureType.scala"
|
||||
- "src/main/scala/net/psforever/objects/serverobject/shuttle/ShuttleAmenity.scala"
|
||||
|
|
@ -56,24 +64,34 @@ ignore:
|
|||
- "src/main/scala/net/psforever/packet/ControlPacketOpcode.scala"
|
||||
- "src/main/scala/net/psforever/packet/CryptoPacketOpcode.scala"
|
||||
- "src/main/scala/net/psforever/packet/GamePacketOpcode.scala"
|
||||
- "src/main/scala/net/psforever/types/Angular.scala"
|
||||
- "src/main/scala/net/psforever/types/CertificationType.scala"
|
||||
- "src/main/scala/net/psforever/types/ChatMessageType.scala"
|
||||
- "src/main/scala/net/psforever/types/DriveState.scala"
|
||||
- "src/main/scala/net/psforever/types/EmoteType.scala"
|
||||
- "src/main/scala/net/psforever/types/ExoSuitType.scala"
|
||||
- "src/main/scala/net/psforever/types/GrenadeState.scala"
|
||||
- "src/main/scala/net/psforever/types/ImplantType.scala"
|
||||
- "src/main/scala/net/psforever/types/MeritCommendation.scala"
|
||||
- "src/main/scala/net/psforever/types/PlanetSideEmpire.scala"
|
||||
- "src/main/scala/net/psforever/types/TransactionType.scala"
|
||||
- "src/main/scala/net/psforever/packet/ResetSequenceOpcode.scala"
|
||||
- "src/main/scala/net/psforever/persistence"
|
||||
- "src/main/scala/net/psforever/services/account/IPAddress.scala"
|
||||
- "src/main/scala/net/psforever/services/account/ReceiveAccountData.scala"
|
||||
- "src/main/scala/net/psforever/services/account/ReceiveIPAddress.scala"
|
||||
- "src/main/scala/net/psforever/services/account/RetrieveAccountData.scala"
|
||||
- "src/main/scala/net/psforever/services/account/RetrieveIPAddress.scala"
|
||||
- "src/main/scala/net/psforever/services/account/StoreAccountData.scala"
|
||||
- "src/main/scala/net/psforever/services/account/StoreIPAddress.scala"
|
||||
- "src/main/scala/net/psforever/services/avatar/AvatarAction.scala"
|
||||
- "src/main/scala/net/psforever/services/avatar/AvatarResponse.scala"
|
||||
- "src/main/scala/net/psforever/services/galaxy/GalaxyAction.scala"
|
||||
- "src/main/scala/net/psforever/services/galaxy/GalaxyResponse.scala"
|
||||
- "src/main/scala/net/psforever/services/avatar/AvatarService.scala"
|
||||
- "src/main/scala/net/psforever/services/base/bus"
|
||||
- "src/main/scala/net/psforever/services/base/envelope"
|
||||
- "src/main/scala/net/psforever/services/chat/ChatChannel.scala"
|
||||
- "src/main/scala/net/psforever/services/galaxy/GalaxyAction"
|
||||
- "src/main/scala/net/psforever/services/galaxy/GalaxyService"
|
||||
- "src/main/scala/net/psforever/services/hart/HartEvent.scala"
|
||||
- "src/main/scala/net/psforever/services/hart/HartTimerActions.scala"
|
||||
- "src/main/scala/net/psforever/services/local/LocalAction.scala"
|
||||
- "src/main/scala/net/psforever/services/local/LocalResponse.scala"
|
||||
- "src/main/scala/net/psforever/services/vehicle/VehicleAction.scala"
|
||||
- "src/main/scala/net/psforever/services/vehicle/VehicleResponse.scala"
|
||||
- "src/main/scala/net/psforever/services/local/LocalAction"
|
||||
- "src/main/scala/net/psforever/services/local/LocalService"
|
||||
- "src/main/scala/net/psforever/services/teamwork/SquadServiceMessage.scala"
|
||||
- "src/main/scala/net/psforever/services/teamwork/SquadServiceResponse.scala"
|
||||
- "src/main/scala/net/psforever/services/vehicle/VehicleAction"
|
||||
- "src/main/scala/net/psforever/services/vehicle/VehicleService"
|
||||
- "src/main/scala/net/psforever/services/Service.scala"
|
||||
- "src/main/scala/net/psforever/types"
|
||||
- "src/main/scala/net/psforever/util"
|
||||
- "src/main/scala/net/psforever/zones"
|
||||
- "src/main/scala/net/psforever/IFinalizable.scala"
|
||||
- "src/main/scala/scodec"
|
||||
- "src/test"
|
||||
|
|
|
|||
|
|
@ -101,7 +101,7 @@ object Server {
|
|||
val zones = Zones.zones :+ Zone.Nowhere
|
||||
val serviceManager = ServiceManager.boot
|
||||
serviceManager ! ServiceManager.Register(classic.Props[AccountIntermediaryService](), "accountIntermediary")
|
||||
serviceManager ! ServiceManager.Register(classic.Props[GalaxyService](), "galaxy")
|
||||
serviceManager ! ServiceManager.Register(GalaxyService(), "galaxy")
|
||||
serviceManager ! ServiceManager.Register(classic.Props[SquadService](), "squad")
|
||||
serviceManager ! ServiceManager.Register(classic.Props[AccountPersistenceService](), "accountPersistence")
|
||||
serviceManager ! ServiceManager.Register(classic.Props[PropertyOverrideManager](), "propertyOverrideManager")
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ import scala.concurrent.duration._
|
|||
class AutoRepairFacilityIntegrationTest extends FreedContextActorTest {
|
||||
import akka.actor.typed.scaladsl.adapter._
|
||||
system.spawn(InterstellarClusterService(Nil), InterstellarClusterService.InterstellarClusterServiceKey.id)
|
||||
ServiceManager.boot(system) ! ServiceManager.Register(Props[GalaxyService](), "galaxy")
|
||||
ServiceManager.boot(system) ! ServiceManager.Register(GalaxyService(), "galaxy")
|
||||
expectNoMessage(1000 milliseconds)
|
||||
val guid = new NumberPoolHub(new MaxNumberSource(max = 10))
|
||||
val avatarProbe = new TestProbe(system)
|
||||
|
|
@ -105,7 +105,7 @@ class AutoRepairFacilityIntegrationTest extends FreedContextActorTest {
|
|||
class AutoRepairFacilityIntegrationGiveNtuTest extends FreedContextActorTest {
|
||||
import akka.actor.typed.scaladsl.adapter._
|
||||
system.spawn(InterstellarClusterService(Nil), InterstellarClusterService.InterstellarClusterServiceKey.id)
|
||||
ServiceManager.boot(system) ! ServiceManager.Register(Props[GalaxyService](), "galaxy")
|
||||
ServiceManager.boot(system) ! ServiceManager.Register(GalaxyService(), "galaxy")
|
||||
expectNoMessage(1000 milliseconds)
|
||||
val guid = new NumberPoolHub(new MaxNumberSource(max = 10))
|
||||
val avatarProbe = new TestProbe(system)
|
||||
|
|
@ -160,7 +160,7 @@ class AutoRepairFacilityIntegrationGiveNtuTest extends FreedContextActorTest {
|
|||
class AutoRepairFacilityIntegrationAntGiveNtuTest extends FreedContextActorTest {
|
||||
import akka.actor.typed.scaladsl.adapter._
|
||||
system.spawn(InterstellarClusterService(Nil), InterstellarClusterService.InterstellarClusterServiceKey.id)
|
||||
ServiceManager.boot(system) ! ServiceManager.Register(Props[GalaxyService](), "galaxy")
|
||||
ServiceManager.boot(system) ! ServiceManager.Register(GalaxyService(), "galaxy")
|
||||
expectNoMessage(1000 milliseconds)
|
||||
var buildingMap = new TrieMap[Int, Building]()
|
||||
val guid = new NumberPoolHub(new MaxNumberSource(max = 10))
|
||||
|
|
@ -251,7 +251,7 @@ class AutoRepairFacilityIntegrationAntGiveNtuTest extends FreedContextActorTest
|
|||
class AutoRepairFacilityIntegrationTerminalDestroyedTerminalAntTest extends FreedContextActorTest {
|
||||
import akka.actor.typed.scaladsl.adapter._
|
||||
system.spawn(InterstellarClusterService(Nil), InterstellarClusterService.InterstellarClusterServiceKey.id)
|
||||
ServiceManager.boot(system) ! ServiceManager.Register(Props[GalaxyService](), "galaxy")
|
||||
ServiceManager.boot(system) ! ServiceManager.Register(GalaxyService(), "galaxy")
|
||||
expectNoMessage(1000 milliseconds)
|
||||
var buildingMap = new TrieMap[Int, Building]()
|
||||
val guid = new NumberPoolHub(new MaxNumberSource(max = 10))
|
||||
|
|
@ -353,7 +353,7 @@ class AutoRepairFacilityIntegrationTerminalDestroyedTerminalAntTest extends Free
|
|||
class AutoRepairFacilityIntegrationTerminalIncompleteRepairTest extends FreedContextActorTest {
|
||||
import akka.actor.typed.scaladsl.adapter._
|
||||
system.spawn(InterstellarClusterService(Nil), InterstellarClusterService.InterstellarClusterServiceKey.id)
|
||||
ServiceManager.boot(system) ! ServiceManager.Register(Props[GalaxyService](), "galaxy")
|
||||
ServiceManager.boot(system) ! ServiceManager.Register(GalaxyService(), "galaxy")
|
||||
expectNoMessage(1000 milliseconds)
|
||||
var buildingMap = new TrieMap[Int, Building]()
|
||||
val guid = new NumberPoolHub(new MaxNumberSource(max = 10))
|
||||
|
|
@ -469,7 +469,7 @@ class AutoRepairFacilityIntegrationTerminalIncompleteRepairTest extends FreedCon
|
|||
class AutoRepairTowerIntegrationTest extends FreedContextActorTest {
|
||||
import akka.actor.typed.scaladsl.adapter._
|
||||
system.spawn(InterstellarClusterService(Nil), InterstellarClusterService.InterstellarClusterServiceKey.id)
|
||||
ServiceManager.boot(system) ! ServiceManager.Register(Props[GalaxyService](), "galaxy")
|
||||
ServiceManager.boot(system) ! ServiceManager.Register(GalaxyService(), "galaxy")
|
||||
expectNoMessage(1000 milliseconds)
|
||||
val guid = new NumberPoolHub(new MaxNumberSource(max = 10))
|
||||
val avatarProbe = new TestProbe(system)
|
||||
|
|
|
|||
|
|
@ -9,11 +9,12 @@ import net.psforever.objects.serverobject.structures.StructureType
|
|||
import net.psforever.objects.{GlobalDefinitions, Player, Vehicle}
|
||||
import net.psforever.objects.zones.Zone
|
||||
import net.psforever.types.{PlanetSideGUID, _}
|
||||
import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage}
|
||||
import net.psforever.services.vehicle.VehicleAction
|
||||
import akka.actor.typed.scaladsl.adapter._
|
||||
import net.psforever.actors.zone.ZoneActor
|
||||
import net.psforever.objects.avatar.Avatar
|
||||
import net.psforever.objects.serverobject.terminals.Terminal
|
||||
import net.psforever.services.base.envelope.GenericMessageEnvelope
|
||||
|
||||
import scala.concurrent.duration._
|
||||
|
||||
|
|
@ -37,7 +38,7 @@ class VehicleSpawnControl2Test extends ActorTest {
|
|||
pad.Actor ! VehicleSpawnPad.VehicleOrder(player, vehicle, terminal) //order
|
||||
|
||||
probe.expectMsgClass(1 minute, classOf[VehicleSpawnPad.ConcealPlayer])
|
||||
probe.expectMsgClass(1 minute, classOf[VehicleServiceMessage])
|
||||
probe.expectMsgClass(1 minute, classOf[GenericMessageEnvelope])
|
||||
probe.expectMsgClass(1 minute, classOf[VehicleSpawnPad.AttachToRails])
|
||||
probe.expectMsgClass(1 minute, classOf[VehicleSpawnPad.StartPlayerSeatedInVehicle])
|
||||
vehicle.Seats(0).mount(player)
|
||||
|
|
@ -69,11 +70,11 @@ class VehicleSpawnControl3Test extends ActorTest {
|
|||
pad.Actor ! VehicleSpawnPad.VehicleOrder(player2, vehicle, terminal) //second order (vehicle shared)
|
||||
|
||||
assert(probe.receiveOne(1 seconds) match {
|
||||
case VehicleSpawnPad.PeriodicReminder(_, VehicleSpawnPad.Reminders.Queue, _) => true
|
||||
case _ => false
|
||||
case VehicleSpawnPad.PeriodicReminder(VehicleSpawnPad.Reminders.Queue, _) => true
|
||||
case _ => false
|
||||
})
|
||||
probe.expectMsgClass(1 minute, classOf[VehicleSpawnPad.ConcealPlayer])
|
||||
probe.expectMsgClass(1 minute, classOf[VehicleServiceMessage])
|
||||
probe.expectMsgClass(1 minute, classOf[GenericMessageEnvelope])
|
||||
probe.expectMsgClass(1 minute, classOf[VehicleSpawnPad.AttachToRails])
|
||||
probe.expectMsgClass(1 minute, classOf[VehicleSpawnPad.StartPlayerSeatedInVehicle])
|
||||
vehicle.Seats(0).mount(player)
|
||||
|
|
@ -82,11 +83,11 @@ class VehicleSpawnControl3Test extends ActorTest {
|
|||
probe.expectMsgClass(1 minute, classOf[VehicleSpawnPad.ServerVehicleOverrideStart])
|
||||
probe.expectMsgClass(1 minute, classOf[VehicleSpawnPad.ServerVehicleOverrideEnd])
|
||||
assert(probe.receiveOne(1 minute) match {
|
||||
case VehicleSpawnPad.PeriodicReminder(_, VehicleSpawnPad.Reminders.Blocked, _) => true
|
||||
case VehicleSpawnPad.PeriodicReminder(VehicleSpawnPad.Reminders.Blocked, _) => true
|
||||
case _ => false
|
||||
})
|
||||
assert(probe.receiveOne(1 minute) match {
|
||||
case VehicleSpawnPad.PeriodicReminder(_, VehicleSpawnPad.Reminders.Blocked, _) => true
|
||||
case VehicleSpawnPad.PeriodicReminder(VehicleSpawnPad.Reminders.Blocked, _) => true
|
||||
case _ => false
|
||||
})
|
||||
|
||||
|
|
@ -110,14 +111,6 @@ class VehicleSpawnControl4Test extends ActorTest {
|
|||
player.Continent = "problem" //problem
|
||||
|
||||
pad.Actor ! VehicleSpawnPad.VehicleOrder(player, vehicle, terminal) //order
|
||||
|
||||
val msg = probe.receiveOne(1 minute)
|
||||
// assert(
|
||||
// msg match {
|
||||
// case VehicleServiceMessage.Decon(RemoverActor.AddTask(v, z, _)) => (v == vehicle) && (z == zone)
|
||||
// case _ => false
|
||||
// }
|
||||
// )
|
||||
probe.expectNoMessage(5 seconds)
|
||||
}
|
||||
}
|
||||
|
|
@ -133,18 +126,18 @@ class VehicleSpawnControl5Test extends ActorTest() {
|
|||
pad.Actor ! VehicleSpawnPad.VehicleOrder(player, vehicle, terminal) //order
|
||||
|
||||
probe.expectMsgClass(1 minute, classOf[VehicleSpawnPad.ConcealPlayer])
|
||||
probe.expectMsgClass(1 minute, classOf[VehicleServiceMessage])
|
||||
probe.expectMsgClass(1 minute, classOf[GenericMessageEnvelope])
|
||||
vehicle.Health = 0 //problem
|
||||
probe.expectMsgClass(1 minute, classOf[VehicleSpawnPad.AttachToRails])
|
||||
probe.expectMsgClass(1 minute, classOf[VehicleSpawnPad.DetachFromRails])
|
||||
probe.expectMsgClass(1 minute, classOf[VehicleSpawnPad.RevealPlayer])
|
||||
assert(probe.receiveOne(1 minute) match {
|
||||
case VehicleServiceMessage(_, VehicleAction.LoadVehicle(_, _, _, _, _)) => true
|
||||
case _ => false
|
||||
case GenericMessageEnvelope(_, _, VehicleAction.LoadVehicle(_, _, _, _)) => true
|
||||
case _ => false
|
||||
})
|
||||
assert(probe.receiveOne(1 minute) match {
|
||||
case VehicleSpawnPad.PeriodicReminder(_, VehicleSpawnPad.Reminders.Blocked, _) => true
|
||||
case _ => false
|
||||
case VehicleSpawnPad.PeriodicReminder(VehicleSpawnPad.Reminders.Blocked, _) => true
|
||||
case _ => false
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
@ -160,18 +153,18 @@ class VehicleSpawnControl6Test extends ActorTest() {
|
|||
pad.Actor ! VehicleSpawnPad.VehicleOrder(player, vehicle, terminal) //order
|
||||
|
||||
probe.expectMsgClass(1 minute, classOf[VehicleSpawnPad.ConcealPlayer])
|
||||
probe.expectMsgClass(1 minute, classOf[VehicleServiceMessage])
|
||||
probe.expectMsgClass(1 minute, classOf[GenericMessageEnvelope])
|
||||
player.Die
|
||||
probe.expectMsgClass(1 minute, classOf[VehicleSpawnPad.AttachToRails])
|
||||
probe.expectMsgClass(1 minute, classOf[VehicleSpawnPad.DetachFromRails])
|
||||
probe.expectMsgClass(1 minute, classOf[VehicleSpawnPad.RevealPlayer])
|
||||
assert(probe.receiveOne(1 minute) match {
|
||||
case VehicleServiceMessage(_, VehicleAction.LoadVehicle(_, _, _, _, _)) => true
|
||||
case _ => false
|
||||
case GenericMessageEnvelope(_, _, VehicleAction.LoadVehicle(_, _, _, _)) => true
|
||||
case _ => false
|
||||
})
|
||||
assert(probe.receiveOne(1 minute) match {
|
||||
case VehicleSpawnPad.PeriodicReminder(_, VehicleSpawnPad.Reminders.Blocked, _) => true
|
||||
case _ => false
|
||||
case VehicleSpawnPad.PeriodicReminder(VehicleSpawnPad.Reminders.Blocked, _) => true
|
||||
case _ => false
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
@ -188,18 +181,18 @@ class VehicleSpawnControl7Test extends ActorTest {
|
|||
pad.Actor ! VehicleSpawnPad.VehicleOrder(player, vehicle, terminal) //order
|
||||
|
||||
probe.expectMsgClass(1 minute, classOf[VehicleSpawnPad.ConcealPlayer])
|
||||
probe.expectMsgClass(1 minute, classOf[VehicleServiceMessage])
|
||||
probe.expectMsgClass(1 minute, classOf[GenericMessageEnvelope])
|
||||
probe.expectMsgClass(1 minute, classOf[VehicleSpawnPad.AttachToRails])
|
||||
probe.expectMsgClass(1 minute, classOf[VehicleSpawnPad.StartPlayerSeatedInVehicle])
|
||||
probe.expectMsgClass(1 minute, classOf[VehicleSpawnPad.DetachFromRails])
|
||||
probe.expectMsgClass(1 minute, classOf[VehicleSpawnPad.RevealPlayer])
|
||||
assert(probe.receiveOne(1 minute) match {
|
||||
case VehicleServiceMessage(_, VehicleAction.LoadVehicle(_, _, _, _, _)) => true
|
||||
case _ => false
|
||||
case GenericMessageEnvelope(_, _, VehicleAction.LoadVehicle(_, _, _, _)) => true
|
||||
case _ => false
|
||||
})
|
||||
assert(probe.receiveOne(1 minute) match {
|
||||
case VehicleSpawnPad.PeriodicReminder(_, VehicleSpawnPad.Reminders.Blocked, _) => true
|
||||
case _ => false
|
||||
case VehicleSpawnPad.PeriodicReminder(VehicleSpawnPad.Reminders.Blocked, _) => true
|
||||
case _ => false
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,651 +0,0 @@
|
|||
// Copyright (c) 2017 PSForever
|
||||
package actor.service
|
||||
|
||||
import akka.actor.Props
|
||||
import akka.testkit.TestProbe
|
||||
import scala.concurrent.duration._
|
||||
|
||||
import actor.base.{ActorTest, FreedContextActorTest}
|
||||
import net.psforever.objects._
|
||||
import net.psforever.objects.avatar.Avatar
|
||||
import net.psforever.objects.guid.NumberPoolHub
|
||||
import net.psforever.objects.guid.source.MaxNumberSource
|
||||
import net.psforever.objects.zones.{Zone, ZoneMap}
|
||||
import net.psforever.packet.game.objectcreate.{DroppedItemData, ObjectClass, ObjectCreateMessageParent, PlacementData}
|
||||
import net.psforever.packet.game.{ObjectCreateMessage, PlayerStateMessageUpstream}
|
||||
import net.psforever.types._
|
||||
import net.psforever.services.{RemoverActor, Service, ServiceManager}
|
||||
import net.psforever.services.avatar._
|
||||
|
||||
class AvatarService1Test extends ActorTest {
|
||||
"AvatarService" should {
|
||||
"construct" in {
|
||||
ServiceManager.boot(system)
|
||||
system.actorOf(Props(classOf[AvatarService], Zone.Nowhere), AvatarServiceTest.TestName)
|
||||
assert(true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class AvatarService2Test extends ActorTest {
|
||||
"AvatarService" should {
|
||||
"subscribe" in {
|
||||
ServiceManager.boot(system)
|
||||
val service = system.actorOf(Props(classOf[AvatarService], Zone.Nowhere), AvatarServiceTest.TestName)
|
||||
service ! Service.Join("test")
|
||||
assert(true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class AvatarService3Test extends ActorTest {
|
||||
"AvatarService" should {
|
||||
ServiceManager.boot(system)
|
||||
"subscribe to a specific channel" in {
|
||||
val service = system.actorOf(Props(classOf[AvatarService], Zone.Nowhere), AvatarServiceTest.TestName)
|
||||
service ! Service.Join("test")
|
||||
service ! Service.Leave()
|
||||
assert(true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class AvatarService4Test extends ActorTest {
|
||||
"AvatarService" should {
|
||||
"subscribe" in {
|
||||
ServiceManager.boot(system)
|
||||
val service = system.actorOf(Props(classOf[AvatarService], Zone.Nowhere), AvatarServiceTest.TestName)
|
||||
service ! Service.Join("test")
|
||||
service ! Service.LeaveAll()
|
||||
assert(true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class AvatarService5Test extends ActorTest {
|
||||
"AvatarService" should {
|
||||
"pass an unhandled message" in {
|
||||
ServiceManager.boot(system)
|
||||
val service = system.actorOf(Props(classOf[AvatarService], Zone.Nowhere), AvatarServiceTest.TestName)
|
||||
service ! Service.Join("test")
|
||||
service ! "hello"
|
||||
expectNoMessage()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class ArmorChangedTest extends ActorTest {
|
||||
"AvatarService" should {
|
||||
"pass ArmorChanged" in {
|
||||
ServiceManager.boot(system)
|
||||
val service = system.actorOf(Props(classOf[AvatarService], Zone.Nowhere), AvatarServiceTest.TestName)
|
||||
service ! Service.Join("test")
|
||||
service ! AvatarServiceMessage("test", AvatarAction.ArmorChanged(PlanetSideGUID(10), ExoSuitType.Reinforced, 0))
|
||||
expectMsg(
|
||||
AvatarServiceResponse(
|
||||
"/test/Avatar",
|
||||
PlanetSideGUID(10),
|
||||
AvatarResponse.ArmorChanged(ExoSuitType.Reinforced, 0)
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class ConcealPlayerTest extends ActorTest {
|
||||
"AvatarService" should {
|
||||
"pass ConcealPlayer" in {
|
||||
ServiceManager.boot(system)
|
||||
val service = system.actorOf(Props(classOf[AvatarService], Zone.Nowhere), AvatarServiceTest.TestName)
|
||||
service ! Service.Join("test")
|
||||
service ! AvatarServiceMessage("test", AvatarAction.ConcealPlayer(PlanetSideGUID(10)))
|
||||
expectMsg(AvatarServiceResponse("/test/Avatar", PlanetSideGUID(10), AvatarResponse.ConcealPlayer()))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class EquipmentInHandTest extends ActorTest {
|
||||
ServiceManager.boot(system)
|
||||
val service = system.actorOf(Props(classOf[AvatarService], Zone.Nowhere), "release-test-service")
|
||||
val toolDef = GlobalDefinitions.beamer
|
||||
val tool = Tool(toolDef)
|
||||
tool.GUID = PlanetSideGUID(40)
|
||||
tool.AmmoSlots.head.Box.GUID = PlanetSideGUID(41)
|
||||
val pkt = ObjectCreateMessage(
|
||||
toolDef.ObjectId,
|
||||
tool.GUID,
|
||||
ObjectCreateMessageParent(PlanetSideGUID(11), 2),
|
||||
toolDef.Packet.ConstructorData(tool).get
|
||||
)
|
||||
|
||||
"AvatarService" should {
|
||||
"pass EquipmentInHand" in {
|
||||
service ! Service.Join("test")
|
||||
service ! AvatarServiceMessage(
|
||||
"test",
|
||||
AvatarAction.EquipmentInHand(PlanetSideGUID(10), PlanetSideGUID(11), 2, tool)
|
||||
)
|
||||
expectMsg(AvatarServiceResponse("/test/Avatar", PlanetSideGUID(10), AvatarResponse.EquipmentInHand(pkt)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class DroptItemTest extends ActorTest {
|
||||
ServiceManager.boot(system)
|
||||
val service = system.actorOf(Props(classOf[AvatarService], Zone.Nowhere), "release-test-service")
|
||||
val toolDef = GlobalDefinitions.beamer
|
||||
val tool = Tool(toolDef)
|
||||
tool.Position = Vector3(1, 2, 3)
|
||||
tool.Orientation = Vector3(4, 5, 6)
|
||||
tool.GUID = PlanetSideGUID(40)
|
||||
tool.AmmoSlots.head.Box.GUID = PlanetSideGUID(41)
|
||||
val pkt = ObjectCreateMessage(
|
||||
toolDef.ObjectId,
|
||||
tool.GUID,
|
||||
DroppedItemData(
|
||||
PlacementData(tool.Position, tool.Orientation),
|
||||
toolDef.Packet.ConstructorData(tool).get
|
||||
)
|
||||
)
|
||||
|
||||
"AvatarService" should {
|
||||
"pass DropItem" in {
|
||||
service ! Service.Join("test")
|
||||
service ! AvatarServiceMessage("test", AvatarAction.DropItem(PlanetSideGUID(10), tool))
|
||||
expectMsg(AvatarServiceResponse("/test/Avatar", PlanetSideGUID(10), AvatarResponse.DropItem(pkt)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class LoadPlayerTest extends ActorTest {
|
||||
val obj = Player(Avatar(0, "TestCharacter1", PlanetSideEmpire.VS, CharacterSex.Female, 1, CharacterVoice.Voice1))
|
||||
obj.GUID = PlanetSideGUID(10)
|
||||
obj.Slot(5).Equipment.get.GUID = PlanetSideGUID(11)
|
||||
val c1data = obj.Definition.Packet.DetailedConstructorData(obj).get
|
||||
val pkt1 = ObjectCreateMessage(ObjectClass.avatar, PlanetSideGUID(10), c1data)
|
||||
val parent = ObjectCreateMessageParent(PlanetSideGUID(12), 0)
|
||||
obj.VehicleSeated = PlanetSideGUID(12)
|
||||
val c2data = obj.Definition.Packet.DetailedConstructorData(obj).get
|
||||
val pkt2 = ObjectCreateMessage(ObjectClass.avatar, PlanetSideGUID(10), parent, c2data)
|
||||
|
||||
"AvatarService" should {
|
||||
"pass LoadPlayer" in {
|
||||
ServiceManager.boot(system)
|
||||
val service = system.actorOf(Props(classOf[AvatarService], Zone.Nowhere), AvatarServiceTest.TestName)
|
||||
service ! Service.Join("test")
|
||||
//no parent data
|
||||
service ! AvatarServiceMessage(
|
||||
"test",
|
||||
AvatarAction.LoadPlayer(PlanetSideGUID(20), ObjectClass.avatar, PlanetSideGUID(10), c1data, None)
|
||||
)
|
||||
expectMsg(AvatarServiceResponse("/test/Avatar", PlanetSideGUID(20), AvatarResponse.LoadPlayer(pkt1)))
|
||||
//parent data
|
||||
service ! AvatarServiceMessage(
|
||||
"test",
|
||||
AvatarAction.LoadPlayer(PlanetSideGUID(20), ObjectClass.avatar, PlanetSideGUID(10), c2data, Some(parent))
|
||||
)
|
||||
expectMsg(AvatarServiceResponse("/test/Avatar", PlanetSideGUID(20), AvatarResponse.LoadPlayer(pkt2)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class ObjectDeleteTest extends ActorTest {
|
||||
"AvatarService" should {
|
||||
"pass ObjectDelete" in {
|
||||
ServiceManager.boot(system)
|
||||
val service = system.actorOf(Props(classOf[AvatarService], Zone.Nowhere), AvatarServiceTest.TestName)
|
||||
service ! Service.Join("test")
|
||||
service ! AvatarServiceMessage("test", AvatarAction.ObjectDelete(PlanetSideGUID(10), PlanetSideGUID(11)))
|
||||
expectMsg(
|
||||
AvatarServiceResponse("/test/Avatar", PlanetSideGUID(10), AvatarResponse.ObjectDelete(PlanetSideGUID(11), 0))
|
||||
)
|
||||
|
||||
service ! AvatarServiceMessage("test", AvatarAction.ObjectDelete(PlanetSideGUID(10), PlanetSideGUID(11), 55))
|
||||
expectMsg(
|
||||
AvatarServiceResponse("/test/Avatar", PlanetSideGUID(10), AvatarResponse.ObjectDelete(PlanetSideGUID(11), 55))
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class ObjectHeldTest extends ActorTest {
|
||||
"AvatarService" should {
|
||||
"pass ObjectHeld" in {
|
||||
ServiceManager.boot(system)
|
||||
val service = system.actorOf(Props(classOf[AvatarService], Zone.Nowhere), AvatarServiceTest.TestName)
|
||||
service ! Service.Join("test")
|
||||
service ! AvatarServiceMessage("test", AvatarAction.ObjectHeld(PlanetSideGUID(10), 1, 2))
|
||||
expectMsg(AvatarServiceResponse("/test/Avatar", PlanetSideGUID(10), AvatarResponse.ObjectHeld(1, 2)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class PutDownFDUTest extends ActorTest {
|
||||
"AvatarService" should {
|
||||
"pass PutDownFDU" in {
|
||||
ServiceManager.boot(system)
|
||||
val service = system.actorOf(Props(classOf[AvatarService], Zone.Nowhere), AvatarServiceTest.TestName)
|
||||
service ! Service.Join("test")
|
||||
service ! AvatarServiceMessage("test", AvatarAction.PutDownFDU(PlanetSideGUID(10)))
|
||||
expectMsg(
|
||||
AvatarServiceResponse("/test/Avatar", PlanetSideGUID(10), AvatarResponse.PutDownFDU(PlanetSideGUID(10)))
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class PlanetsideAttributeTest extends ActorTest {
|
||||
"AvatarService" should {
|
||||
"pass PlanetsideAttribute" in {
|
||||
ServiceManager.boot(system)
|
||||
val service = system.actorOf(Props(classOf[AvatarService], Zone.Nowhere), AvatarServiceTest.TestName)
|
||||
service ! Service.Join("test")
|
||||
service ! AvatarServiceMessage("test", AvatarAction.PlanetsideAttribute(PlanetSideGUID(10), 5, 1200L))
|
||||
expectMsg(AvatarServiceResponse("/test/Avatar", PlanetSideGUID(10), AvatarResponse.PlanetsideAttribute(5, 1200L)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class PlayerStateTest extends ActorTest {
|
||||
val msg = PlayerStateMessageUpstream(
|
||||
PlanetSideGUID(75),
|
||||
Vector3(3694.1094f, 2735.4531f, 90.84375f),
|
||||
Some(Vector3(4.375f, 2.59375f, 0.0f)),
|
||||
61.875f,
|
||||
351.5625f,
|
||||
0.0f,
|
||||
136,
|
||||
0,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
112,
|
||||
0
|
||||
)
|
||||
|
||||
"AvatarService" should {
|
||||
"pass PlayerState" in {
|
||||
ServiceManager.boot(system)
|
||||
val service = system.actorOf(Props(classOf[AvatarService], Zone.Nowhere), AvatarServiceTest.TestName)
|
||||
service ! Service.Join("test")
|
||||
service ! AvatarServiceMessage(
|
||||
"test",
|
||||
AvatarAction.PlayerState(
|
||||
PlanetSideGUID(10),
|
||||
Vector3(3694.1094f, 2735.4531f, 90.84375f),
|
||||
Some(Vector3(4.375f, 2.59375f, 0.0f)),
|
||||
61.875f,
|
||||
351.5625f,
|
||||
0.0f,
|
||||
136,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false
|
||||
)
|
||||
)
|
||||
expectMsg(
|
||||
AvatarServiceResponse(
|
||||
"/test/Avatar",
|
||||
PlanetSideGUID(10),
|
||||
AvatarResponse.PlayerState(
|
||||
Vector3(3694.1094f, 2735.4531f, 90.84375f),
|
||||
Some(Vector3(4.375f, 2.59375f, 0.0f)),
|
||||
61.875f,
|
||||
351.5625f,
|
||||
0.0f,
|
||||
136,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class PickupItemTest extends ActorTest {
|
||||
val obj = Player(Avatar(0, "TestCharacter", PlanetSideEmpire.VS, CharacterSex.Female, 1, CharacterVoice.Voice1))
|
||||
val tool = Tool(GlobalDefinitions.beamer)
|
||||
tool.GUID = PlanetSideGUID(40)
|
||||
|
||||
"pass PickUpItem" in {
|
||||
ServiceManager.boot(system)
|
||||
val service = system.actorOf(Props(classOf[AvatarService], Zone.Nowhere), AvatarServiceTest.TestName)
|
||||
service ! Service.Join("test")
|
||||
service ! AvatarServiceMessage("test", AvatarAction.PickupItem(PlanetSideGUID(10), tool))
|
||||
expectMsg(AvatarServiceResponse("/test/Avatar", PlanetSideGUID(10), AvatarResponse.ObjectDelete(tool.GUID, 0)))
|
||||
}
|
||||
}
|
||||
|
||||
class ReloadTest extends ActorTest {
|
||||
"AvatarService" should {
|
||||
"pass Reload" in {
|
||||
ServiceManager.boot(system)
|
||||
val service = system.actorOf(Props(classOf[AvatarService], Zone.Nowhere), AvatarServiceTest.TestName)
|
||||
service ! Service.Join("test")
|
||||
service ! AvatarServiceMessage("test", AvatarAction.Reload(PlanetSideGUID(10), PlanetSideGUID(40)))
|
||||
expectMsg(AvatarServiceResponse("/test/Avatar", PlanetSideGUID(10), AvatarResponse.Reload(PlanetSideGUID(40))))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class ChangeAmmoTest extends ActorTest {
|
||||
val ammoDef = GlobalDefinitions.energy_cell
|
||||
val ammoBox = AmmoBox(ammoDef)
|
||||
|
||||
"AvatarService" should {
|
||||
"pass ChangeAmmo" in {
|
||||
ServiceManager.boot(system)
|
||||
val service = system.actorOf(Props(classOf[AvatarService], Zone.Nowhere), AvatarServiceTest.TestName)
|
||||
service ! Service.Join("test")
|
||||
service ! AvatarServiceMessage(
|
||||
"test",
|
||||
AvatarAction.ChangeAmmo(
|
||||
PlanetSideGUID(10),
|
||||
PlanetSideGUID(40),
|
||||
0,
|
||||
PlanetSideGUID(40),
|
||||
ammoDef.ObjectId,
|
||||
PlanetSideGUID(41),
|
||||
ammoDef.Packet.ConstructorData(ammoBox).get
|
||||
)
|
||||
)
|
||||
expectMsg(
|
||||
AvatarServiceResponse(
|
||||
"/test/Avatar",
|
||||
PlanetSideGUID(10),
|
||||
AvatarResponse.ChangeAmmo(
|
||||
PlanetSideGUID(40),
|
||||
0,
|
||||
PlanetSideGUID(40),
|
||||
ammoDef.ObjectId,
|
||||
PlanetSideGUID(41),
|
||||
ammoDef.Packet.ConstructorData(ammoBox).get
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class ChangeFireModeTest extends ActorTest {
|
||||
val ammoDef = GlobalDefinitions.energy_cell
|
||||
val ammoBox = AmmoBox(ammoDef)
|
||||
|
||||
"AvatarService" should {
|
||||
"pass ChangeFireMode" in {
|
||||
ServiceManager.boot(system)
|
||||
val service = system.actorOf(Props(classOf[AvatarService], Zone.Nowhere), AvatarServiceTest.TestName)
|
||||
service ! Service.Join("test")
|
||||
service ! AvatarServiceMessage("test", AvatarAction.ChangeFireMode(PlanetSideGUID(10), PlanetSideGUID(40), 0))
|
||||
expectMsg(
|
||||
AvatarServiceResponse("/test/Avatar", PlanetSideGUID(10), AvatarResponse.ChangeFireMode(PlanetSideGUID(40), 0))
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class ChangeFireStateStartTest extends ActorTest {
|
||||
"AvatarService" should {
|
||||
"pass ChangeFireState_Start" in {
|
||||
ServiceManager.boot(system)
|
||||
val service = system.actorOf(Props(classOf[AvatarService], Zone.Nowhere), AvatarServiceTest.TestName)
|
||||
service ! Service.Join("test")
|
||||
service ! AvatarServiceMessage("test", AvatarAction.ChangeFireState_Start(PlanetSideGUID(10), PlanetSideGUID(40)))
|
||||
expectMsg(
|
||||
AvatarServiceResponse(
|
||||
"/test/Avatar",
|
||||
PlanetSideGUID(10),
|
||||
AvatarResponse.ChangeFireState_Start(PlanetSideGUID(40))
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class ChangeFireStateStopTest extends ActorTest {
|
||||
"AvatarService" should {
|
||||
"pass ChangeFireState_Stop" in {
|
||||
ServiceManager.boot(system)
|
||||
val service = system.actorOf(Props(classOf[AvatarService], Zone.Nowhere), AvatarServiceTest.TestName)
|
||||
service ! Service.Join("test")
|
||||
service ! AvatarServiceMessage("test", AvatarAction.ChangeFireState_Stop(PlanetSideGUID(10), PlanetSideGUID(40)))
|
||||
expectMsg(
|
||||
AvatarServiceResponse(
|
||||
"/test/Avatar",
|
||||
PlanetSideGUID(10),
|
||||
AvatarResponse.ChangeFireState_Stop(PlanetSideGUID(40))
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class WeaponDryFireTest extends ActorTest {
|
||||
"AvatarService" should {
|
||||
"pass WeaponDryFire" in {
|
||||
ServiceManager.boot(system)
|
||||
val service = system.actorOf(Props(classOf[AvatarService], Zone.Nowhere), AvatarServiceTest.TestName)
|
||||
service ! Service.Join("test")
|
||||
service ! AvatarServiceMessage("test", AvatarAction.WeaponDryFire(PlanetSideGUID(10), PlanetSideGUID(40)))
|
||||
expectMsg(
|
||||
AvatarServiceResponse("/test/Avatar", PlanetSideGUID(10), AvatarResponse.WeaponDryFire(PlanetSideGUID(40)))
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class AvatarStowEquipmentTest extends ActorTest {
|
||||
val tool = Tool(GlobalDefinitions.beamer)
|
||||
|
||||
"AvatarService" should {
|
||||
"pass StowEquipment" in {
|
||||
ServiceManager.boot(system)
|
||||
val service = system.actorOf(Props(classOf[AvatarService], Zone.Nowhere), 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 be set up correctly.
|
||||
The Zone needs to be set up and initialized properly with a ZoneActor.
|
||||
The ZoneActor builds the GUID Actor and the ZonePopulationActor.
|
||||
|
||||
ALL of these Actors will talk to each other.
|
||||
The lines of communication can short circuit if the next Actor does not have the correct information.
|
||||
Putting Actor startup in the main class, outside of the body of the test, helps.
|
||||
Frequent pauses to allow everything to sort their messages also helps.
|
||||
Even with all this work, the tests have a high chance of failure just due to being asynchronous.
|
||||
*/
|
||||
class AvatarReleaseTest extends FreedContextActorTest {
|
||||
val guid: NumberPoolHub = new NumberPoolHub(new MaxNumberSource(15))
|
||||
val zone = new Zone("test", new ZoneMap("test-map"), 0) {
|
||||
override def SetupNumberPools() : Unit = { }
|
||||
GUID(guid)
|
||||
}
|
||||
zone.init(context)
|
||||
val obj = Player(Avatar(0, "TestCharacter", PlanetSideEmpire.VS, CharacterSex.Female, 1, CharacterVoice.Voice1))
|
||||
guid.register(obj)
|
||||
guid.register(obj.Slot(5).Equipment.get)
|
||||
obj.Zone = zone
|
||||
obj.Release
|
||||
val subscriber = new TestProbe(system)
|
||||
|
||||
"AvatarService" should {
|
||||
"pass Release" in {
|
||||
expectNoMessage(100 milliseconds) //spacer
|
||||
|
||||
zone.AvatarEvents.tell(Service.Join("test"), subscriber.ref)
|
||||
assert(zone.Corpses.isEmpty)
|
||||
zone.Population ! Zone.Corpse.Add(obj)
|
||||
subscriber.expectNoMessage(200 milliseconds) //spacer
|
||||
|
||||
assert(zone.Corpses.size == 1)
|
||||
assert(obj.HasGUID)
|
||||
val guid = obj.GUID
|
||||
zone.AvatarEvents ! AvatarServiceMessage("test", AvatarAction.Release(obj, zone, Some(1 second))) //alive for one second
|
||||
|
||||
val reply1 = subscriber.receiveOne(200 milliseconds)
|
||||
assert(reply1.isInstanceOf[AvatarServiceResponse])
|
||||
val reply1msg = reply1.asInstanceOf[AvatarServiceResponse]
|
||||
assert(reply1msg.channel == "/test/Avatar")
|
||||
assert(reply1msg.avatar_guid == guid)
|
||||
assert(reply1msg.replyMessage.isInstanceOf[AvatarResponse.Release])
|
||||
assert(reply1msg.replyMessage.asInstanceOf[AvatarResponse.Release].player == obj)
|
||||
|
||||
val reply2 = subscriber.receiveOne(2 seconds)
|
||||
assert(reply2.isInstanceOf[AvatarServiceResponse])
|
||||
val reply2msg = reply2.asInstanceOf[AvatarServiceResponse]
|
||||
assert(reply2msg.channel.equals("/test/Avatar"))
|
||||
assert(reply2msg.avatar_guid == Service.defaultPlayerGUID)
|
||||
assert(reply2msg.replyMessage.isInstanceOf[AvatarResponse.ObjectDelete])
|
||||
assert(reply2msg.replyMessage.asInstanceOf[AvatarResponse.ObjectDelete].item_guid == guid)
|
||||
|
||||
subscriber.expectNoMessage(1 seconds)
|
||||
assert(zone.Corpses.isEmpty)
|
||||
assert(!obj.HasGUID)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class AvatarReleaseEarly1Test extends FreedContextActorTest {
|
||||
val guid: NumberPoolHub = new NumberPoolHub(new MaxNumberSource(15))
|
||||
val zone = new Zone("test", new ZoneMap("test-map"), 0) {
|
||||
override def SetupNumberPools() : Unit = { }
|
||||
GUID(guid)
|
||||
}
|
||||
zone.init(context)
|
||||
val obj = Player(Avatar(0, "TestCharacter", PlanetSideEmpire.VS, CharacterSex.Female, 1, CharacterVoice.Voice1))
|
||||
guid.register(obj)
|
||||
guid.register(obj.Slot(5).Equipment.get)
|
||||
obj.Zone = zone
|
||||
obj.Release
|
||||
val subscriber = new TestProbe(system)
|
||||
|
||||
"AvatarService" should {
|
||||
"pass Release" in {
|
||||
expectNoMessage(100 milliseconds) //spacer
|
||||
|
||||
zone.AvatarEvents.tell(Service.Join("test"), subscriber.ref)
|
||||
assert(zone.Corpses.isEmpty)
|
||||
zone.Population ! Zone.Corpse.Add(obj)
|
||||
subscriber.expectNoMessage(200 milliseconds) //spacer
|
||||
|
||||
assert(zone.Corpses.size == 1)
|
||||
assert(obj.HasGUID)
|
||||
val guid = obj.GUID
|
||||
zone.AvatarEvents ! AvatarServiceMessage("test", AvatarAction.Release(obj, zone)) //3+ minutes!
|
||||
|
||||
val reply1 = subscriber.receiveOne(200 milliseconds)
|
||||
assert(reply1.isInstanceOf[AvatarServiceResponse])
|
||||
val reply1msg = reply1.asInstanceOf[AvatarServiceResponse]
|
||||
assert(reply1msg.channel == "/test/Avatar")
|
||||
assert(reply1msg.avatar_guid == guid)
|
||||
assert(reply1msg.replyMessage.isInstanceOf[AvatarResponse.Release])
|
||||
assert(reply1msg.replyMessage.asInstanceOf[AvatarResponse.Release].player == obj)
|
||||
|
||||
zone.AvatarEvents ! AvatarServiceMessage.Corpse(RemoverActor.HurrySpecific(List(obj), zone)) //IMPORTANT: ONE ENTRY
|
||||
val reply2 = subscriber.receiveOne(200 milliseconds)
|
||||
assert(reply2.isInstanceOf[AvatarServiceResponse])
|
||||
val reply2msg = reply2.asInstanceOf[AvatarServiceResponse]
|
||||
assert(reply2msg.channel.equals("/test/Avatar"))
|
||||
assert(reply2msg.avatar_guid == Service.defaultPlayerGUID)
|
||||
assert(reply2msg.replyMessage.isInstanceOf[AvatarResponse.ObjectDelete])
|
||||
assert(reply2msg.replyMessage.asInstanceOf[AvatarResponse.ObjectDelete].item_guid == guid)
|
||||
|
||||
subscriber.expectNoMessage(1 seconds)
|
||||
assert(zone.Corpses.isEmpty)
|
||||
assert(!obj.HasGUID)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class AvatarReleaseEarly2Test extends FreedContextActorTest {
|
||||
val guid: NumberPoolHub = new NumberPoolHub(new MaxNumberSource(15))
|
||||
val zone = new Zone("test", new ZoneMap("test-map"), 0) {
|
||||
override def SetupNumberPools() : Unit = { }
|
||||
GUID(guid)
|
||||
}
|
||||
zone.init(context)
|
||||
val obj = Player(Avatar(0, "TestCharacter", PlanetSideEmpire.VS, CharacterSex.Female, 1, CharacterVoice.Voice1))
|
||||
guid.register(obj)
|
||||
guid.register(obj.Slot(5).Equipment.get)
|
||||
obj.Zone = zone
|
||||
obj.Release
|
||||
val objAlt = Player(
|
||||
Avatar(0, "TestCharacter2", PlanetSideEmpire.NC, CharacterSex.Male, 1, CharacterVoice.Voice1)
|
||||
) //necessary clutter
|
||||
objAlt.GUID = PlanetSideGUID(3)
|
||||
objAlt.Slot(5).Equipment.get.GUID = PlanetSideGUID(4)
|
||||
objAlt.Zone = zone
|
||||
val subscriber = new TestProbe(system)
|
||||
|
||||
"AvatarService" should {
|
||||
"pass Release" in {
|
||||
expectNoMessage(100 milliseconds) //spacer
|
||||
|
||||
zone.AvatarEvents.tell(Service.Join("test"), subscriber.ref)
|
||||
assert(zone.Corpses.isEmpty)
|
||||
zone.Population ! Zone.Corpse.Add(obj)
|
||||
subscriber.expectNoMessage(200 milliseconds) //spacer
|
||||
|
||||
assert(zone.Corpses.size == 1)
|
||||
assert(obj.HasGUID)
|
||||
val guid = obj.GUID
|
||||
zone.AvatarEvents ! AvatarServiceMessage("test", AvatarAction.Release(obj, zone)) //3+ minutes!
|
||||
|
||||
val reply1 = subscriber.receiveOne(200 milliseconds)
|
||||
assert(reply1.isInstanceOf[AvatarServiceResponse])
|
||||
val reply1msg = reply1.asInstanceOf[AvatarServiceResponse]
|
||||
assert(reply1msg.channel == "/test/Avatar")
|
||||
assert(reply1msg.avatar_guid == guid)
|
||||
assert(reply1msg.replyMessage.isInstanceOf[AvatarResponse.Release])
|
||||
assert(reply1msg.replyMessage.asInstanceOf[AvatarResponse.Release].player == obj)
|
||||
|
||||
zone.AvatarEvents ! AvatarServiceMessage.Corpse(
|
||||
RemoverActor.HurrySpecific(List(objAlt, obj), zone)
|
||||
) //IMPORTANT: TWO ENTRIES
|
||||
val reply2 = subscriber.receiveOne(100 milliseconds)
|
||||
assert(reply2.isInstanceOf[AvatarServiceResponse])
|
||||
val reply2msg = reply2.asInstanceOf[AvatarServiceResponse]
|
||||
assert(reply2msg.channel.equals("/test/Avatar"))
|
||||
assert(reply2msg.avatar_guid == Service.defaultPlayerGUID)
|
||||
assert(reply2msg.replyMessage.isInstanceOf[AvatarResponse.ObjectDelete])
|
||||
assert(reply2msg.replyMessage.asInstanceOf[AvatarResponse.ObjectDelete].item_guid == guid)
|
||||
|
||||
subscriber.expectNoMessage(1 seconds)
|
||||
assert(zone.Corpses.isEmpty)
|
||||
assert(!obj.HasGUID)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
object AvatarServiceTest {
|
||||
import java.util.concurrent.atomic.AtomicInteger
|
||||
private val number = new AtomicInteger(1)
|
||||
|
||||
def TestName: String = {
|
||||
s"service${number.getAndIncrement()}"
|
||||
}
|
||||
}
|
||||
|
|
@ -575,6 +575,17 @@ network {
|
|||
# before it is dropped. Can be used as a watchdog for hung server sessions.
|
||||
outbound-grace-time = 1 minute
|
||||
}
|
||||
|
||||
event-caching {
|
||||
# The minimum amount of time a cached message has to wait before being dispatched. (ms)
|
||||
# Ideal circumstances are when message traffic is light.
|
||||
flush-cache-delay = 15
|
||||
# The absolute maximum amount of time a cached message has to wait before being dispatched. (ms)
|
||||
flush-cache-max-delay = 50
|
||||
# The numeric difference between light traffic and heavy traffic.
|
||||
# In this case, the event system's traffic density and the message caching delay are numerically synonymous.
|
||||
message-traffic-threshold = 12
|
||||
}
|
||||
}
|
||||
|
||||
development {
|
||||
|
|
|
|||
|
|
@ -12,7 +12,8 @@ import net.psforever.objects.avatar.ModePermissions
|
|||
import net.psforever.objects.avatar.scoring.{Assist, Death, EquipmentStat, KDAStat, Kill, Life, ScoreCard, SupportActivity}
|
||||
import net.psforever.objects.sourcing.{TurretSource, VehicleSource}
|
||||
import net.psforever.packet.game.ImplantAction
|
||||
import net.psforever.services.avatar.AvatarServiceResponse
|
||||
import net.psforever.services.avatar.AvatarStamp
|
||||
import net.psforever.services.base.envelope.GenericResponseEnvelope
|
||||
import net.psforever.types.{ChatMessageType, StatisticalCategory, StatisticalElement}
|
||||
import net.psforever.zones.Zones
|
||||
import org.joda.time.{LocalDateTime, Seconds}
|
||||
|
|
@ -49,8 +50,9 @@ import net.psforever.objects.vital.{DamagingActivity, HealFromImplant, HealingAc
|
|||
import net.psforever.packet.game.objectcreate.{BasicCharacterData, ObjectClass, RibbonBars}
|
||||
import net.psforever.packet.game.{Friend => GameFriend, _}
|
||||
import net.psforever.persistence
|
||||
import net.psforever.services.Service
|
||||
import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage}
|
||||
import net.psforever.services.base.envelope.MessageEnvelope
|
||||
import net.psforever.services.base.message.{SendResponse, PlanetsideAttribute}
|
||||
import net.psforever.services.avatar.AvatarAction
|
||||
import net.psforever.types.{
|
||||
CharacterSex,
|
||||
CharacterVoice,
|
||||
|
|
@ -585,9 +587,10 @@ object AvatarActor {
|
|||
|
||||
def displayLookingForSquad(session: Session, state: Int): Unit = {
|
||||
val player = session.player
|
||||
session.zone.AvatarEvents ! AvatarServiceMessage(
|
||||
session.zone.AvatarEvents ! MessageEnvelope(
|
||||
player.Faction.toString,
|
||||
AvatarAction.PlanetsideAttribute(player.GUID, 53, state)
|
||||
player.GUID,
|
||||
PlanetsideAttribute(player.GUID, 53, state)
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -1383,9 +1386,10 @@ class AvatarActor(
|
|||
case SetLookingForSquad(lfs) =>
|
||||
avatarCopy(avatar.copy(lookingForSquad = lfs))
|
||||
sessionActor ! SessionActor.SendResponse(PlanetsideAttributeMessage(session.get.player.GUID, 53, 0))
|
||||
session.get.zone.AvatarEvents ! AvatarServiceMessage(
|
||||
session.get.zone.AvatarEvents ! MessageEnvelope(
|
||||
avatar.faction.toString,
|
||||
AvatarAction.PlanetsideAttribute(session.get.player.GUID, 53, if (lfs) 1 else 0)
|
||||
session.get.player.GUID,
|
||||
PlanetsideAttribute(session.get.player.GUID, 53, if (lfs) 1 else 0)
|
||||
)
|
||||
Behaviors.same
|
||||
|
||||
|
|
@ -1794,9 +1798,9 @@ class AvatarActor(
|
|||
)
|
||||
val player = session.get.player
|
||||
val zone = player.Zone
|
||||
zone.AvatarEvents ! AvatarServiceMessage(
|
||||
zone.AvatarEvents ! MessageEnvelope(
|
||||
zone.id,
|
||||
AvatarAction.SendResponse(Service.defaultPlayerGUID, DisplayedAwardMessage(player.GUID, ribbon, bar))
|
||||
SendResponse(DisplayedAwardMessage(player.GUID, ribbon, bar))
|
||||
)
|
||||
Behaviors.same
|
||||
|
||||
|
|
@ -2073,9 +2077,9 @@ class AvatarActor(
|
|||
case Success(_) =>
|
||||
val zone = session.get.zone
|
||||
avatarCopy(avatar.copy(decoration = avatar.decoration.copy(cosmetics = Some(cosmetics))))
|
||||
zone.AvatarEvents ! AvatarServiceMessage(
|
||||
zone.AvatarEvents ! MessageEnvelope(
|
||||
zone.id,
|
||||
AvatarAction.PlanetsideAttributeToAll(
|
||||
PlanetsideAttribute(
|
||||
session.get.player.GUID,
|
||||
106,
|
||||
Cosmetic.valuesToAttributeValue(cosmetics)
|
||||
|
|
@ -3000,13 +3004,13 @@ class AvatarActor(
|
|||
val next = BattleRank.withExperience(newBep).value
|
||||
val br24 = BattleRank.BR24.value
|
||||
sessionActor ! SessionActor.SendResponse(BattleExperienceMessage(pguid, newBep, localModifier))
|
||||
events ! AvatarServiceMessage(zoneId, AvatarAction.PlanetsideAttributeToAll(pguid, 17, newBep))
|
||||
events ! MessageEnvelope(zoneId, PlanetsideAttribute(pguid, 17, newBep))
|
||||
if (current < br24 && next >= br24 || current >= br24 && next < br24) {
|
||||
setCosmetics(Set()).onComplete { _ =>
|
||||
val evts = events
|
||||
val name = player.Name
|
||||
val guid = pguid
|
||||
evts ! AvatarServiceMessage(name, AvatarAction.PlanetsideAttributeToAll(guid, 106, 1)) //set to no helmet
|
||||
evts ! MessageEnvelope(name, PlanetsideAttribute(guid, 106, 1)) //set to no helmet
|
||||
}
|
||||
}
|
||||
// when the level is reduced, take away any implants over the implant slot limit
|
||||
|
|
@ -3051,10 +3055,7 @@ class AvatarActor(
|
|||
val sess = session.get
|
||||
val zone = sess.zone
|
||||
avatar = avatar.copy(cep = cep)
|
||||
zone.AvatarEvents ! AvatarServiceMessage(
|
||||
zone.id,
|
||||
AvatarAction.PlanetsideAttributeToAll(sess.player.GUID, 18, cep)
|
||||
)
|
||||
zone.AvatarEvents ! MessageEnvelope(zone.id, PlanetsideAttribute(sess.player.GUID, 18, cep))
|
||||
case Failure(exception) =>
|
||||
log.error(exception)("db failure")
|
||||
}
|
||||
|
|
@ -3152,7 +3153,7 @@ class AvatarActor(
|
|||
if (exp > 0L) {
|
||||
setBep(exp, msg)
|
||||
zone.actor ! ZoneActor.RewardOurSupporters(playerSource, historyTranscript, killStat, exp)
|
||||
zone.AvatarEvents ! AvatarServiceMessage(
|
||||
zone.AvatarEvents ! MessageEnvelope(
|
||||
player.Name, AvatarAction.ShareKillExperienceWithSquad(player, exp))
|
||||
}
|
||||
}
|
||||
|
|
@ -3163,12 +3164,9 @@ class AvatarActor(
|
|||
val _session = session.get
|
||||
val zone = _session.zone
|
||||
val player = _session.player
|
||||
zone.AvatarEvents ! AvatarServiceMessage(
|
||||
zone.AvatarEvents ! MessageEnvelope(
|
||||
player.Name,
|
||||
AvatarAction.SendResponse(
|
||||
Service.defaultPlayerGUID,
|
||||
AvatarStatisticsMessage(DeathStatistic(ScoreCard.deathCount(avatar.scorecard)))
|
||||
)
|
||||
SendResponse(AvatarStatisticsMessage(DeathStatistic(ScoreCard.deathCount(avatar.scorecard))))
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -3494,8 +3492,8 @@ class AvatarActor(
|
|||
value: Int
|
||||
): Unit = {
|
||||
import akka.actor.typed.scaladsl.adapter.TypedActorRefOps
|
||||
import net.psforever.services.avatar.{AvatarResponse => RESP}
|
||||
sessionActor.toClassic ! AvatarServiceResponse("", guid, RESP.AvatarImplant(action, index, value))
|
||||
val resp = AvatarAction.AvatarImplant(action, index, value)
|
||||
sessionActor.toClassic ! GenericResponseEnvelope(AvatarStamp, "", guid, resp)
|
||||
}
|
||||
|
||||
private def buyImplantAction(
|
||||
|
|
@ -3654,9 +3652,9 @@ class AvatarActor(
|
|||
// Start client-side initialization timer, visible on the character screen
|
||||
// Progress accumulates according to the client's knowledge of the implant initialization time
|
||||
// What is normally a 60s timer that is set to 120s on the server will still visually update as if 60s
|
||||
session.get.zone.AvatarEvents ! AvatarServiceMessage(
|
||||
session.get.zone.AvatarEvents ! MessageEnvelope(
|
||||
avatar.name,
|
||||
AvatarAction.SendResponse(Service.defaultPlayerGUID, ActionProgressMessage(slot + 6, actionProgress))
|
||||
SendResponse(ActionProgressMessage(slot + 6, actionProgress))
|
||||
)
|
||||
implant.copy(initialized = false, active = false, timer = futureDelay)
|
||||
} else {
|
||||
|
|
@ -3703,9 +3701,9 @@ class AvatarActor(
|
|||
def stopImplantInitializationTimer(implant: Implant, slot: Int): Implant = {
|
||||
cancelImplantInitializedTimer(slot)
|
||||
//can not formally stop the initialization time on the character information window; set it to 100 to make it look blank
|
||||
session.get.zone.AvatarEvents ! AvatarServiceMessage(
|
||||
session.get.zone.AvatarEvents ! MessageEnvelope(
|
||||
avatar.name,
|
||||
AvatarAction.SendResponse(Service.defaultPlayerGUID, ActionProgressMessage(slot + 6, 100))
|
||||
SendResponse(ActionProgressMessage(slot + 6, 100))
|
||||
)
|
||||
implant.copy(initialized = false, active = false, timer = 0L)
|
||||
}
|
||||
|
|
@ -3773,9 +3771,10 @@ class AvatarActor(
|
|||
private def deactivateImplant(implant: Implant, slot: Int): Implant = {
|
||||
cancelImplantInitializedTimer(slot)
|
||||
// Deactivation sound / effect
|
||||
session.get.zone.AvatarEvents ! AvatarServiceMessage(
|
||||
session.get.zone.AvatarEvents ! MessageEnvelope(
|
||||
session.get.zone.id,
|
||||
AvatarAction.PlanetsideAttribute(session.get.player.GUID, 28, implant.definition.implantType.value * 2)
|
||||
session.get.player.GUID,
|
||||
PlanetsideAttribute(session.get.player.GUID, 28, implant.definition.implantType.value * 2)
|
||||
)
|
||||
sendAvatarImplantMessageToSelf(session.get.player.GUID, ImplantAction.Activation, slot, value = 0)
|
||||
implant.copy(active = false)
|
||||
|
|
@ -3852,10 +3851,7 @@ class AvatarActor(
|
|||
val newHealth = player.Health = originalHealth + 1
|
||||
val events = zone.AvatarEvents
|
||||
player.LogActivity(HealFromImplant(implant.definition.implantType, 1))
|
||||
events ! AvatarServiceMessage(
|
||||
zone.id,
|
||||
AvatarAction.PlanetsideAttributeToAll(guid, 0, newHealth)
|
||||
)
|
||||
events ! MessageEnvelope(zone.id, PlanetsideAttribute(guid, 0, newHealth))
|
||||
false
|
||||
} else {
|
||||
!aliveAndWounded
|
||||
|
|
@ -3867,9 +3863,10 @@ class AvatarActor(
|
|||
// Activation sound / effect
|
||||
val sess = session.get
|
||||
val zone = sess.zone
|
||||
zone.AvatarEvents ! AvatarServiceMessage(
|
||||
zone.AvatarEvents ! MessageEnvelope(
|
||||
zone.id,
|
||||
AvatarAction.PlanetsideAttribute(
|
||||
sess.player.GUID,
|
||||
PlanetsideAttribute(
|
||||
sess.player.GUID,
|
||||
28,
|
||||
implant.definition.implantType.value * 2 + 1
|
||||
|
|
@ -3892,9 +3889,9 @@ class AvatarActor(
|
|||
case (implantOpt @ Some(implant), slot) =>
|
||||
//update ongoing progress
|
||||
val actionProgress = calculateImplantTimerStats(implant, AvatarActor.initializationTime(implant))._3
|
||||
session.get.zone.AvatarEvents ! AvatarServiceMessage(
|
||||
session.get.zone.AvatarEvents ! MessageEnvelope(
|
||||
avatar.name,
|
||||
AvatarAction.SendResponse(Service.defaultPlayerGUID, ActionProgressMessage(slot + 6, actionProgress))
|
||||
SendResponse(ActionProgressMessage(slot + 6, actionProgress))
|
||||
)
|
||||
implantOpt
|
||||
case (None, _) =>
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ package net.psforever.actors.session
|
|||
|
||||
import akka.actor.{Actor, ActorRef, Cancellable, MDCContextAware, typed}
|
||||
import net.psforever.actors.session.normal.NormalMode
|
||||
import net.psforever.actors.session.support.ZoningOperations
|
||||
import net.psforever.actors.session.support.{CommonHandlerFunctions, CommonHandlerLogic, ZoningOperations}
|
||||
import net.psforever.objects.TurretDeployable
|
||||
import net.psforever.objects.serverobject.CommonMessages
|
||||
import net.psforever.objects.serverobject.containable.Containable
|
||||
|
|
@ -18,12 +18,13 @@ import net.psforever.services.CavernRotationService
|
|||
import net.psforever.services.CavernRotationService.SendCavernRotationUpdates
|
||||
import net.psforever.services.ServiceManager.LookupResult
|
||||
import net.psforever.services.account.{PlayerToken, ReceiveAccountData}
|
||||
import net.psforever.services.avatar.AvatarServiceResponse
|
||||
import net.psforever.services.avatar.AvatarStamp
|
||||
import net.psforever.services.base.envelope.{GenericResponseEnvelope, Undelivered}
|
||||
import net.psforever.services.chat.ChatService
|
||||
import net.psforever.services.galaxy.GalaxyServiceResponse
|
||||
import net.psforever.services.local.LocalServiceResponse
|
||||
import net.psforever.services.galaxy.GalaxyStamp
|
||||
import net.psforever.services.local.LocalStamp
|
||||
import net.psforever.services.teamwork.SquadServiceResponse
|
||||
import net.psforever.services.vehicle.VehicleServiceResponse
|
||||
import net.psforever.services.vehicle.VehicleStamp
|
||||
import org.joda.time.LocalDateTime
|
||||
import org.log4s.MDC
|
||||
|
||||
|
|
@ -94,6 +95,26 @@ object SessionActor {
|
|||
private final case object PokeClient extends Command
|
||||
|
||||
final case class SetMode(mode: PlayerMode) extends Command
|
||||
|
||||
/**
|
||||
* Determine if a response handler would process a given reply message, ignoring its guards.
|
||||
* Treat handlers already ignoring their guards as "determined (will not pass)".
|
||||
* @see `CommonHandlerFunctions.IgnoreFilter_=`
|
||||
* @param reply message
|
||||
* @param handler message handler
|
||||
* @return `true`, if the response handler will process the response;
|
||||
* `false`, if the handler is skipped or if it would not process
|
||||
*/
|
||||
private def HandlerAcceptingMessageTest(reply: Any)(handler: CommonHandlerFunctions): Boolean = {
|
||||
if (handler.IgnoreFilter) {
|
||||
false
|
||||
} else {
|
||||
handler.IgnoreFilter = true
|
||||
val result = handler.isDefinedAt(reply)
|
||||
handler.IgnoreFilter = false
|
||||
result
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], connectionId: String, sessionId: Long)
|
||||
|
|
@ -106,6 +127,9 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con
|
|||
private[this] val data = new SessionData(middlewareActor, context)
|
||||
private[this] var mode: PlayerMode = NormalMode
|
||||
private[this] var logic: ModeLogic = _
|
||||
private[this] var listOfHandlers: Seq[CommonHandlerFunctions] = List.empty
|
||||
|
||||
private val commonHandlerLogic: CommonHandlerLogic = new CommonHandlerLogic(data, context)
|
||||
|
||||
override def postStop(): Unit = {
|
||||
clientKeepAlive.cancel()
|
||||
|
|
@ -119,7 +143,7 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con
|
|||
buffer.addOne(msg)
|
||||
case _ if data.whenAllEventBusesLoaded() =>
|
||||
context.become(inTheGame)
|
||||
logic = mode.setup(data)
|
||||
changeModeSetup(mode)
|
||||
buffer.foreach { self.tell(_, self) } //we forget the original sender, shouldn't be doing callbacks at this point
|
||||
buffer.clear()
|
||||
case _ => ()
|
||||
|
|
@ -160,37 +184,39 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con
|
|||
if (mode != newMode) {
|
||||
logic.switchFrom(data.session)
|
||||
mode = newMode
|
||||
logic = newMode.setup(data)
|
||||
changeModeSetup(newMode)
|
||||
}
|
||||
logic.switchTo(data.session)
|
||||
}
|
||||
|
||||
private def changeModeSetup(newMode: PlayerMode): Unit = {
|
||||
logic = newMode.setup(data)
|
||||
listOfHandlers = List(
|
||||
logic.avatarResponse,
|
||||
logic.local,
|
||||
logic.vehicleResponse,
|
||||
logic.galaxy,
|
||||
commonHandlerLogic
|
||||
)
|
||||
}
|
||||
|
||||
private def parse(sender: ActorRef): Receive = {
|
||||
/* really common messages (very frequently, every life) */
|
||||
case packet: PlanetSideGamePacket =>
|
||||
handleGamePkt(packet)
|
||||
|
||||
case AvatarServiceResponse(toChannel, guid, reply) =>
|
||||
logic.avatarResponse.handle(toChannel, guid, reply)
|
||||
case SquadServiceResponse(_, excluded, reply) =>
|
||||
logic.squad.handle(reply, excluded)
|
||||
|
||||
case GalaxyServiceResponse(_, reply) =>
|
||||
logic.galaxy.handle(reply)
|
||||
|
||||
case LocalServiceResponse(toChannel, guid, reply) =>
|
||||
logic.local.handle(toChannel, guid, reply)
|
||||
case envelope: GenericResponseEnvelope =>
|
||||
handleGenericResponseEnvelope(envelope)
|
||||
|
||||
case Mountable.MountMessages(tplayer, reply) =>
|
||||
logic.mountResponse.handle(tplayer, reply)
|
||||
|
||||
case SquadServiceResponse(_, excluded, response) =>
|
||||
logic.squad.handle(response, excluded)
|
||||
|
||||
case Terminal.TerminalMessage(tplayer, msg, order) =>
|
||||
logic.terminals.handle(tplayer, msg, order)
|
||||
|
||||
case VehicleServiceResponse(toChannel, guid, reply) =>
|
||||
logic.vehicleResponse.handle(toChannel, guid, reply)
|
||||
|
||||
case ChatService.MessageResponse(fromSession, message, _) =>
|
||||
logic.chat.handleIncomingMessage(message, fromSession)
|
||||
|
||||
|
|
@ -369,6 +395,52 @@ class SessionActor(middlewareActor: typed.ActorRef[MiddlewareActor.Command], con
|
|||
logic.general.handleReceiveDefaultMessage(default, sender)
|
||||
}
|
||||
|
||||
private def handleGenericResponseEnvelope(envelope: GenericResponseEnvelope): Unit = {
|
||||
//try use the stamp to match the specific handler
|
||||
envelope.stamp match {
|
||||
case Undelivered =>
|
||||
val GenericResponseEnvelope(_, _, reply) = envelope
|
||||
log.error(s"received a message's response that was not processed by an event system - $reply")
|
||||
case AvatarStamp =>
|
||||
handleEnvelopeWithResponseHandler(logic.avatarResponse, envelope)
|
||||
case LocalStamp =>
|
||||
handleEnvelopeWithResponseHandler(logic.local, envelope)
|
||||
case VehicleStamp =>
|
||||
handleEnvelopeWithResponseHandler(logic.vehicleResponse, envelope)
|
||||
case GalaxyStamp =>
|
||||
handleEnvelopeWithResponseHandler(logic.galaxy, envelope)
|
||||
case unknownStamp =>
|
||||
log.error(s"received a message from an unknown event system - reply: $envelope, stamp: $unknownStamp")
|
||||
}
|
||||
//println(s"event-system-rtt: ${System.currentTimeMillis() - envelope.time} ms")
|
||||
}
|
||||
|
||||
private def handleEnvelopeWithResponseHandler(
|
||||
responseHandler: CommonHandlerFunctions,
|
||||
envelope: GenericResponseEnvelope
|
||||
): Unit = {
|
||||
val GenericResponseEnvelope(toChannel, guid, reply) = envelope
|
||||
//try the expected handler with the input response
|
||||
if (!responseHandler.handle(toChannel, guid, reply)) {
|
||||
//test the expected handler again, ignoring guard booleans; if it would have been handled, stop with this
|
||||
responseHandler.IgnoreFilter = true
|
||||
if (!responseHandler.isDefinedAt(reply)) {
|
||||
//find every handler that might accept the input response, ignoring guard booleans only for the search
|
||||
//try each discovered handler against the input response until one works
|
||||
val test: CommonHandlerFunctions => Boolean = SessionActor.HandlerAcceptingMessageTest(reply)
|
||||
listOfHandlers.filter(test) match {
|
||||
case Nil =>
|
||||
log.error(s"received completely unhandled response message - $reply for ${envelope.stamp}:$toChannel")
|
||||
case first :: Nil =>
|
||||
first.tryToHandle(reply)
|
||||
case first :: others =>
|
||||
first.tryToHandle(reply) || others.exists(_.tryToHandle(reply))
|
||||
}
|
||||
}
|
||||
responseHandler.IgnoreFilter = false
|
||||
}
|
||||
}
|
||||
|
||||
private def handleGamePkt: PlanetSideGamePacket => Unit = {
|
||||
case packet: ConnectToWorldRequestMessage =>
|
||||
logic.general.handleConnectToWorldRequest(packet)
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -16,7 +16,9 @@ import net.psforever.objects.serverobject.structures.Building
|
|||
import net.psforever.objects.zones.Zone
|
||||
import net.psforever.packet.game.{ChatMsg, SetChatFilterMessage}
|
||||
import net.psforever.services.Service
|
||||
import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage}
|
||||
import net.psforever.services.avatar.AvatarAction
|
||||
import net.psforever.services.base.envelope.{BundledEnvelope, MessageEnvelope}
|
||||
import net.psforever.services.base.message.{ObjectDelete, SetEmpire}
|
||||
import net.psforever.services.chat.{ChatChannel, DefaultChannel, SpectatorChannel, SquadChannel}
|
||||
import net.psforever.types.ChatMessageType.{CMT_TOGGLESPECTATORMODE, CMT_TOGGLE_GM}
|
||||
import net.psforever.types.{ChatMessageType, PlanetSideEmpire}
|
||||
|
|
@ -312,17 +314,20 @@ class ChatLogic(val ops: ChatOperations, implicit val context: ActorContext) ext
|
|||
val events = continent.AvatarEvents
|
||||
seeSpectatorsIn = Some(continent)
|
||||
events ! Service.Join(s"spectator")
|
||||
continent
|
||||
.AllPlayers
|
||||
.filter(_.spectator)
|
||||
.foreach { spectator =>
|
||||
val guid = spectator.GUID
|
||||
val definition = spectator.Definition
|
||||
events ! AvatarServiceMessage(
|
||||
channel,
|
||||
AvatarAction.LoadPlayer(guid, definition.ObjectId, guid, definition.Packet.ConstructorData(spectator).get, None)
|
||||
)
|
||||
}
|
||||
events ! BundledEnvelope(
|
||||
continent
|
||||
.AllPlayers
|
||||
.filter(_.spectator)
|
||||
.map { spectator =>
|
||||
val guid = spectator.GUID
|
||||
val definition = spectator.Definition
|
||||
MessageEnvelope(
|
||||
channel,
|
||||
guid,
|
||||
AvatarAction.LoadPlayer(definition.ObjectId, guid, definition.Packet.ConstructorData(spectator).get, None)
|
||||
)
|
||||
}
|
||||
)
|
||||
true
|
||||
}
|
||||
|
||||
|
|
@ -330,17 +335,16 @@ class ChatLogic(val ops: ChatOperations, implicit val context: ActorContext) ext
|
|||
val channel = player.Name
|
||||
val events = continent.AvatarEvents
|
||||
seeSpectatorsIn = None
|
||||
events ! Service.Leave(Some("spectator"))
|
||||
continent
|
||||
.AllPlayers
|
||||
.filter(_.spectator)
|
||||
.foreach { spectator =>
|
||||
val guid = spectator.GUID
|
||||
events ! AvatarServiceMessage(
|
||||
channel,
|
||||
AvatarAction.ObjectDelete(guid, guid)
|
||||
)
|
||||
}
|
||||
events ! Service.Leave("spectator")
|
||||
events ! BundledEnvelope(
|
||||
continent
|
||||
.AllPlayers
|
||||
.filter(_.spectator)
|
||||
.map { spectator =>
|
||||
val guid = spectator.GUID
|
||||
MessageEnvelope(channel, guid, ObjectDelete(guid))
|
||||
}
|
||||
)
|
||||
true
|
||||
}
|
||||
|
||||
|
|
@ -392,9 +396,9 @@ class ChatLogic(val ops: ChatOperations, implicit val context: ActorContext) ext
|
|||
true
|
||||
case o: Deployable =>
|
||||
o.Faction = foundFaction
|
||||
continent.AvatarEvents ! AvatarServiceMessage(
|
||||
continent.AvatarEvents ! MessageEnvelope(
|
||||
continent.id,
|
||||
AvatarAction.SetEmpire(Service.defaultPlayerGUID, o.GUID, foundFaction)
|
||||
SetEmpire(o.GUID, foundFaction)
|
||||
)
|
||||
true
|
||||
case o: Building =>
|
||||
|
|
@ -405,9 +409,9 @@ class ChatLogic(val ops: ChatOperations, implicit val context: ActorContext) ext
|
|||
true
|
||||
case o: PlanetSideGameObject with FactionAffinity =>
|
||||
o.Faction = foundFaction
|
||||
continent.AvatarEvents ! AvatarServiceMessage(
|
||||
continent.AvatarEvents ! MessageEnvelope(
|
||||
continent.id,
|
||||
AvatarAction.SetEmpire(Service.defaultPlayerGUID, o.GUID, foundFaction)
|
||||
SetEmpire(o.GUID, foundFaction)
|
||||
)
|
||||
true
|
||||
}
|
||||
|
|
@ -512,7 +516,7 @@ class ChatLogic(val ops: ChatOperations, implicit val context: ActorContext) ext
|
|||
.foreach {
|
||||
case (_, false, _) => ()
|
||||
case (faction, true, _) =>
|
||||
//events ! AvatarServiceMessage(s"$faction", reloadZoneMsg)
|
||||
//events ! MessageEnvelope(s"$faction", reloadZoneMsg)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,9 +10,10 @@ import net.psforever.objects.vital.Vitality
|
|||
import net.psforever.objects.zones.Zone
|
||||
import net.psforever.packet.game.{ChatMsg, ObjectCreateDetailedMessage, PlanetsideAttributeMessage}
|
||||
import net.psforever.packet.game.objectcreate.RibbonBars
|
||||
import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage}
|
||||
import net.psforever.services.avatar.AvatarAction
|
||||
import net.psforever.services.base.envelope.MessageEnvelope
|
||||
import net.psforever.services.base.message.PlanetsideAttribute
|
||||
import net.psforever.services.chat.{CustomerServiceChannel, SpectatorChannel}
|
||||
import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage}
|
||||
import net.psforever.types.{ChatMessageType, MeritCommendation, PlanetSideGUID}
|
||||
|
||||
class CustomerServiceRepresentativeMode(data: SessionData) extends ModeLogic {
|
||||
|
|
@ -120,6 +121,10 @@ class CustomerServiceRepresentativeMode(data: SessionData) extends ModeLogic {
|
|||
.GUID(player.VehicleSeated)
|
||||
.collect { case obj: PlanetSideGameObject with Vitality =>
|
||||
CustomerServiceRepresentativeMode.topOffHealth(data, obj)
|
||||
obj
|
||||
}
|
||||
.getOrElse {
|
||||
data.updateBlockMap(player, player.Position)
|
||||
}
|
||||
data.squad.updateSquad()
|
||||
} else {
|
||||
|
|
@ -144,13 +149,16 @@ case object CustomerServiceRepresentativeMode extends PlayerMode {
|
|||
packet.DetailedConstructorData(player).get
|
||||
))
|
||||
data.zoning.spawn.HandleSetCurrentAvatar(player)
|
||||
zone.AvatarEvents ! AvatarServiceMessage(zone.id, AvatarAction.LoadPlayer(
|
||||
zone.AvatarEvents ! MessageEnvelope(
|
||||
zone.id,
|
||||
pguid,
|
||||
objectClass,
|
||||
pguid,
|
||||
packet.ConstructorData(player).get,
|
||||
None
|
||||
))
|
||||
AvatarAction.LoadPlayer(
|
||||
objectClass,
|
||||
pguid,
|
||||
packet.ConstructorData(player).get,
|
||||
None
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
def topOffHealth(data: SessionData, obj: PlanetSideGameObject with Vitality): Unit = {
|
||||
|
|
@ -174,14 +182,14 @@ case object CustomerServiceRepresentativeMode extends PlayerMode {
|
|||
player.Health = maxHealthOfPlayer.toInt
|
||||
player.LogActivity(player.ClearHistory().head)
|
||||
data.sendResponse(PlanetsideAttributeMessage(guid, 0, maxHealthOfPlayer))
|
||||
data.continent.AvatarEvents ! AvatarServiceMessage(zoneid, AvatarAction.PlanetsideAttribute(guid, 0, maxHealthOfPlayer))
|
||||
data.continent.AvatarEvents ! MessageEnvelope(zoneid, PlanetsideAttribute(guid, 0, maxHealthOfPlayer))
|
||||
}
|
||||
//below half armor, full armor
|
||||
val maxArmor = player.MaxArmor.toLong
|
||||
if (player.Armor < maxArmor) {
|
||||
player.Armor = maxArmor.toInt
|
||||
data.sendResponse(PlanetsideAttributeMessage(guid, 4, maxArmor))
|
||||
data.continent.AvatarEvents ! AvatarServiceMessage(zoneid, AvatarAction.PlanetsideAttribute(guid, 4, maxArmor))
|
||||
data.continent.AvatarEvents ! MessageEnvelope(zoneid, PlanetsideAttribute(guid, 4, maxArmor))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -194,9 +202,9 @@ case object CustomerServiceRepresentativeMode extends PlayerMode {
|
|||
val guid = vehicle.GUID
|
||||
vehicle.Shields = maxShieldsOfVehicle.toInt
|
||||
data.sendResponse(PlanetsideAttributeMessage(guid, shieldsUi, maxShieldsOfVehicle))
|
||||
data.continent.VehicleEvents ! VehicleServiceMessage(
|
||||
data.continent.VehicleEvents ! MessageEnvelope(
|
||||
data.continent.id,
|
||||
VehicleAction.PlanetsideAttribute(PlanetSideGUID(0), guid, shieldsUi, maxShieldsOfVehicle)
|
||||
PlanetsideAttribute(guid, shieldsUi, maxShieldsOfVehicle)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -208,9 +216,9 @@ case object CustomerServiceRepresentativeMode extends PlayerMode {
|
|||
if (obj.Health < maxHealthOf) {
|
||||
obj.Health = maxHealthOf.toInt
|
||||
data.sendResponse(PlanetsideAttributeMessage(guid, 0, maxHealthOf))
|
||||
data.continent.VehicleEvents ! VehicleServiceMessage(
|
||||
data.continent.VehicleEvents ! MessageEnvelope(
|
||||
data.continent.id,
|
||||
VehicleAction.PlanetsideAttribute(PlanetSideGUID(0), guid, 0, maxHealthOf)
|
||||
PlanetsideAttribute(guid, 0, maxHealthOf)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,9 +33,11 @@ import net.psforever.objects.zones.{ZoneProjectile, Zoning}
|
|||
import net.psforever.packet.PlanetSideGamePacket
|
||||
import net.psforever.packet.game.OutfitEventAction.{Initial, OutfitInfo, OutfitRankNames, Unk1}
|
||||
import net.psforever.packet.game.{ActionCancelMessage, AvatarFirstTimeEventMessage, AvatarImplantMessage, AvatarJumpMessage, BattleplanMessage, BindPlayerMessage, BugReportMessage, ChangeFireModeMessage, ChangeShortcutBankMessage, CharacterCreateRequestMessage, CharacterRequestMessage, ChatMsg, CollisionIs, ConnectToWorldRequestMessage, CreateShortcutMessage, DeadState, DeployObjectMessage, DisplayedAwardMessage, DropItemMessage, EmoteMsg, FacilityBenefitShieldChargeRequestMessage, FriendsRequest, GenericAction, GenericActionMessage, GenericCollisionMsg, GenericObjectActionAtPositionMessage, GenericObjectActionMessage, GenericObjectStateMsg, HitHint, InvalidTerrainMessage, LootItemMessage, MoveItemMessage, ObjectDetectedMessage, ObjectHeldMessage, OutfitEvent, OutfitMemberEvent, OutfitMembershipRequest, OutfitMembershipResponse, OutfitRequest, OutfitRequestAction, PickupItemMessage, PlanetsideAttributeMessage, PlayerStateMessageUpstream, RequestDestroyMessage, TargetingImplantRequest, TerrainCondition, TradeMessage, UnuseItemMessage, UseItemMessage, VoiceHostInfo, VoiceHostRequest, ZipLineMessage}
|
||||
import net.psforever.services.RemoverActor
|
||||
import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage}
|
||||
import net.psforever.services.local.{LocalAction, LocalServiceMessage}
|
||||
import net.psforever.services.avatar.support.CorpseEnvelope
|
||||
import net.psforever.services.avatar.AvatarAction
|
||||
import net.psforever.services.base.envelope.MessageEnvelope
|
||||
import net.psforever.services.base.message.PlanetsideAttribute
|
||||
import net.psforever.services.base.support.RemoverActor
|
||||
import net.psforever.types.{CapacitorStateType, ChatMessageType, Cosmetic, ExoSuitType, PlanetSideEmpire, PlanetSideGUID, Vector3}
|
||||
|
||||
import scala.concurrent.duration._
|
||||
|
|
@ -132,10 +134,10 @@ class GeneralLogic(val ops: GeneralOperations, implicit val context: ActorContex
|
|||
val eagleEye: Boolean = ops.canSeeReallyFar
|
||||
val isNotVisible: Boolean = sessionLogic.zoning.zoningStatus == Zoning.Status.Deconstructing ||
|
||||
(player.isAlive && sessionLogic.zoning.spawn.deadState == DeadState.RespawnTime)
|
||||
continent.AvatarEvents ! AvatarServiceMessage(
|
||||
continent.AvatarEvents ! MessageEnvelope(
|
||||
channel,
|
||||
avatarGuid,
|
||||
AvatarAction.PlayerState(
|
||||
avatarGuid,
|
||||
player.Position,
|
||||
player.Velocity,
|
||||
yaw,
|
||||
|
|
@ -163,15 +165,8 @@ class GeneralLogic(val ops: GeneralOperations, implicit val context: ActorContex
|
|||
}
|
||||
|
||||
def handleEmote(pkt: EmoteMsg): Unit = {
|
||||
val EmoteMsg(avatarGuid, emote) = pkt
|
||||
val pZone = player.Zone
|
||||
sendResponse(EmoteMsg(avatarGuid, emote))
|
||||
pZone.blockMap.sector(player).livePlayerList.collect { case t if t.GUID != player.GUID =>
|
||||
pZone.LocalEvents ! LocalServiceMessage(t.Name, LocalAction.SendResponse(EmoteMsg(avatarGuid, emote)))
|
||||
}
|
||||
pZone.AllPlayers.collect { case t if t.GUID != player.GUID && !t.allowInteraction =>
|
||||
pZone.LocalEvents ! LocalServiceMessage(t.Name, LocalAction.SendResponse(EmoteMsg(avatarGuid, emote)))
|
||||
}
|
||||
sendResponse(pkt)
|
||||
ops.handleEmote(pkt)
|
||||
}
|
||||
|
||||
def handleDropItem(pkt: DropItemMessage): Unit = {
|
||||
|
|
@ -239,7 +234,7 @@ class GeneralLogic(val ops: GeneralOperations, implicit val context: ActorContex
|
|||
|
||||
case Some(obj: Player) if obj.isBackpack =>
|
||||
obj.Position = Vector3.Zero
|
||||
continent.AvatarEvents ! AvatarServiceMessage.Corpse(RemoverActor.ClearSpecific(List(obj), continent))
|
||||
continent.AvatarEvents ! CorpseEnvelope(RemoverActor.ClearSpecific(List(obj), continent))
|
||||
|
||||
case Some(obj: Player) =>
|
||||
sessionLogic.general.suicide(obj)
|
||||
|
|
@ -439,9 +434,10 @@ class GeneralLogic(val ops: GeneralOperations, implicit val context: ActorContex
|
|||
ops.dropSpecialSlotItem()
|
||||
case GenericAction.MaxAnchorsExtend_RCV =>
|
||||
player.UsingSpecial = SpecialExoSuitDefinition.Mode.Anchored
|
||||
continent.AvatarEvents ! AvatarServiceMessage(
|
||||
continent.AvatarEvents ! MessageEnvelope(
|
||||
continent.id,
|
||||
AvatarAction.PlanetsideAttribute(player.GUID, 19, 1)
|
||||
player.GUID,
|
||||
PlanetsideAttribute(player.GUID, 19, 1)
|
||||
)
|
||||
definition match {
|
||||
case GlobalDefinitions.trhev_dualcycler | GlobalDefinitions.trhev_burster =>
|
||||
|
|
@ -459,9 +455,10 @@ class GeneralLogic(val ops: GeneralOperations, implicit val context: ActorContex
|
|||
}
|
||||
case GenericAction.MaxAnchorsRelease_RCV =>
|
||||
player.UsingSpecial = SpecialExoSuitDefinition.Mode.Normal
|
||||
continent.AvatarEvents ! AvatarServiceMessage(
|
||||
continent.AvatarEvents ! MessageEnvelope(
|
||||
continent.id,
|
||||
AvatarAction.PlanetsideAttribute(player.GUID, 19, 0)
|
||||
player.GUID,
|
||||
PlanetsideAttribute(player.GUID, 19, 0)
|
||||
)
|
||||
definition match {
|
||||
case GlobalDefinitions.trhev_dualcycler | GlobalDefinitions.trhev_burster =>
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@ import net.psforever.actors.zone.ZoneActor
|
|||
import net.psforever.objects.{GlobalDefinitions, PlanetSideGameObject, Player, Vehicle, Vehicles}
|
||||
import net.psforever.objects.serverobject.affinity.FactionAffinity
|
||||
import net.psforever.objects.serverobject.environment.interaction.ResetAllEnvironmentInteractions
|
||||
import net.psforever.objects.serverobject.hackable.GenericHackables
|
||||
import net.psforever.objects.serverobject.mount.Mountable
|
||||
import net.psforever.objects.serverobject.structures.WarpGate
|
||||
import net.psforever.objects.serverobject.terminals.implant.ImplantTerminalMech
|
||||
|
|
@ -15,9 +14,9 @@ import net.psforever.objects.serverobject.turret.{FacilityTurret, WeaponTurret}
|
|||
import net.psforever.objects.vehicles.AccessPermissionGroup
|
||||
import net.psforever.objects.vital.InGameHistory
|
||||
import net.psforever.packet.game.{ChatMsg, DelayedPathMountMsg, DismountVehicleCargoMsg, DismountVehicleMsg, GenericObjectActionMessage, MountVehicleCargoMsg, MountVehicleMsg, ObjectDetachMessage, PlanetsideAttributeMessage, PlayerStasisMessage, PlayerStateShiftMessage, ShiftState}
|
||||
import net.psforever.services.Service
|
||||
import net.psforever.services.local.{LocalAction, LocalServiceMessage}
|
||||
import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage}
|
||||
import net.psforever.services.base.envelope.{BundledEnvelope, MessageEnvelope}
|
||||
import net.psforever.services.base.message.{SendResponse, SetEmpire}
|
||||
import net.psforever.services.vehicle.VehicleAction
|
||||
import net.psforever.types.{BailType, ChatMessageType, DriveState, PlanetSideGUID, Vector3}
|
||||
|
||||
object MountHandlerLogic {
|
||||
|
|
@ -160,7 +159,7 @@ class MountHandlerLogic(val ops: SessionMountHandlers, implicit val context: Act
|
|||
case Mountable.CanMount(obj: FacilityTurret, seatNumber, _)
|
||||
if obj.Definition == GlobalDefinitions.vanu_sentry_turret =>
|
||||
sessionLogic.zoning.CancelZoningProcess()
|
||||
obj.Zone.LocalEvents ! LocalServiceMessage(obj.Zone.id, LocalAction.SetEmpire(obj.GUID, player.Faction))
|
||||
obj.Zone.LocalEvents ! MessageEnvelope(obj.Zone.id, SetEmpire(obj.GUID, player.Faction))
|
||||
sendResponse(PlanetsideAttributeMessage(obj.GUID, attribute_type=0, obj.Health))
|
||||
ops.updateWeaponAtSeatPosition(obj, seatNumber)
|
||||
ops.MountingAction(tplayer, obj, seatNumber)
|
||||
|
|
@ -199,9 +198,9 @@ class MountHandlerLogic(val ops: SessionMountHandlers, implicit val context: Act
|
|||
val (pos, zang) = Vehicles.dismountShuttle(obj, mountPoint)
|
||||
tplayer.Position = pos
|
||||
sendResponse(DelayedPathMountMsg(pguid, sguid, u1=60, u2=true))
|
||||
continent.LocalEvents ! LocalServiceMessage(
|
||||
continent.LocalEvents ! MessageEnvelope(
|
||||
continent.id,
|
||||
LocalAction.SendResponse(ObjectDetachMessage(sguid, pguid, pos, roll=0, pitch=0, zang))
|
||||
SendResponse(ObjectDetachMessage(sguid, pguid, pos, roll=0, pitch=0, zang))
|
||||
)
|
||||
sessionLogic.keepAliveFunc = sessionLogic.zoning.NormalKeepAlive
|
||||
|
||||
|
|
@ -213,25 +212,21 @@ class MountHandlerLogic(val ops: SessionMountHandlers, implicit val context: Act
|
|||
ops.DismountAction(tplayer, obj, seatNum)
|
||||
continent.actor ! ZoneActor.RemoveFromBlockMap(player) //character doesn't need it
|
||||
//DismountAction(...) uses vehicle service, so use that service to coordinate the remainder of the messages
|
||||
events ! VehicleServiceMessage(
|
||||
player.Name,
|
||||
VehicleAction.SendResponse(Service.defaultPlayerGUID, PlayerStasisMessage(pguid)) //the stasis message
|
||||
)
|
||||
//when the player dismounts, they will be positioned where the shuttle was when it disappeared in the sky
|
||||
//the player will fall to the ground and is perfectly vulnerable in this state
|
||||
//additionally, our player must exist in the current zone
|
||||
//having no in-game avatar target will throw us out of the map screen when deploying and cause softlock
|
||||
events ! VehicleServiceMessage(
|
||||
player.Name,
|
||||
VehicleAction.SendResponse(
|
||||
Service.defaultPlayerGUID,
|
||||
PlayerStateShiftMessage(ShiftState(unk=0, obj.Position, obj.Orientation.z, vel=None)) //cower in the shuttle bay
|
||||
events ! BundledEnvelope(
|
||||
MessageEnvelope(player.Name,
|
||||
SendResponse(Seq(
|
||||
PlayerStasisMessage(pguid),
|
||||
PlayerStateShiftMessage(ShiftState(unk=0, obj.Position, obj.Orientation.z, vel=None))
|
||||
))
|
||||
),
|
||||
MessageEnvelope(continent.id, pguid,
|
||||
SendResponse(GenericObjectActionMessage(pguid, code=9)) /* conceal the player */
|
||||
)
|
||||
)
|
||||
events ! VehicleServiceMessage(
|
||||
continent.id,
|
||||
VehicleAction.SendResponse(pguid, GenericObjectActionMessage(pguid, code=9)) //conceal the player
|
||||
)
|
||||
sessionLogic.keepAliveFunc = sessionLogic.zoning.NormalKeepAlive
|
||||
|
||||
case Mountable.CanDismount(obj: Vehicle, seatNum, _)
|
||||
|
|
@ -256,9 +251,10 @@ class MountHandlerLogic(val ops: SessionMountHandlers, implicit val context: Act
|
|||
ops.DismountVehicleAction(tplayer, obj, seatNum)
|
||||
|
||||
case Mountable.CanDismount(obj: Vehicle, seat_num, _) =>
|
||||
continent.VehicleEvents ! VehicleServiceMessage(
|
||||
continent.VehicleEvents ! MessageEnvelope(
|
||||
continent.id,
|
||||
VehicleAction.KickPassenger(tplayer.GUID, seat_num, unk2=true, obj.GUID)
|
||||
tplayer.GUID,
|
||||
VehicleAction.KickPassenger(seat_num, unk2=true, obj.GUID)
|
||||
)
|
||||
|
||||
case Mountable.CanDismount(obj: PlanetSideGameObject with PlanetSideGameObject with Mountable with FactionAffinity with InGameHistory, seatNum, _) =>
|
||||
|
|
|
|||
|
|
@ -7,7 +7,9 @@ import net.psforever.objects.serverobject.mount.Mountable
|
|||
import net.psforever.objects.{Player, Session, Vehicle}
|
||||
import net.psforever.objects.zones.Zone
|
||||
import net.psforever.packet.PlanetSidePacket
|
||||
import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage}
|
||||
import net.psforever.services.avatar.AvatarAction
|
||||
import net.psforever.services.base.envelope.MessageEnvelope
|
||||
import net.psforever.services.base.message.ObjectDelete
|
||||
import net.psforever.services.chat.SpectatorChannel
|
||||
import net.psforever.services.teamwork.{SquadAction, SquadServiceMessage}
|
||||
import net.psforever.types.{ChatMessageType, SquadRequestType}
|
||||
|
|
@ -45,7 +47,7 @@ class SpectatorCSRModeLogic(data: SessionData) extends ModeLogic {
|
|||
//
|
||||
player.spectator = true
|
||||
data.chat.JoinChannel(SpectatorChannel)
|
||||
continent.AvatarEvents ! AvatarServiceMessage(continent.id, AvatarAction.ObjectDelete(pguid, pguid))
|
||||
continent.AvatarEvents ! MessageEnvelope(continent.id, pguid, ObjectDelete(pguid))
|
||||
sendResponse(ChatMsg(ChatMessageType.CMT_TOGGLESPECTATORMODE, "on"))
|
||||
sendResponse(ChatMsg(ChatMessageType.UNK_225, "CSR SPECTATOR MODE ON"))
|
||||
}
|
||||
|
|
@ -59,9 +61,10 @@ class SpectatorCSRModeLogic(data: SessionData) extends ModeLogic {
|
|||
//
|
||||
player.spectator = false
|
||||
data.chat.LeaveChannel(SpectatorChannel)
|
||||
continent.AvatarEvents ! AvatarServiceMessage(
|
||||
continent.AvatarEvents ! MessageEnvelope(
|
||||
continent.id,
|
||||
AvatarAction.LoadPlayer(pguid, avatarId, pguid, player.Definition.Packet.ConstructorData(player).get, None)
|
||||
pguid,
|
||||
AvatarAction.LoadPlayer(avatarId, pguid, player.Definition.Packet.ConstructorData(player).get, None)
|
||||
)
|
||||
sendResponse(ChatMsg(ChatMessageType.CMT_TOGGLESPECTATORMODE, "off"))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,7 +12,9 @@ import net.psforever.objects.vehicles.control.BfrFlight
|
|||
import net.psforever.objects.zones.Zone
|
||||
import net.psforever.objects.zones.interaction.InteractsWithZone
|
||||
import net.psforever.packet.game.{ChildObjectStateMessage, DeployRequestMessage, FrameVehicleStateMessage, VehicleStateMessage, VehicleSubStateMessage}
|
||||
import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage}
|
||||
import net.psforever.services.base.CachedEnvelope
|
||||
import net.psforever.services.vehicle.VehicleAction
|
||||
import net.psforever.services.base.envelope.MessageEnvelope
|
||||
import net.psforever.types.{DriveState, Vector3}
|
||||
|
||||
object VehicleLogic {
|
||||
|
|
@ -76,10 +78,10 @@ class VehicleLogic(val ops: VehicleOperations, implicit val context: ActorContex
|
|||
obj.Position = position
|
||||
obj.Orientation = angle
|
||||
//
|
||||
continent.VehicleEvents ! VehicleServiceMessage(
|
||||
continent.VehicleEvents ! MessageEnvelope(
|
||||
continent.id,
|
||||
player.GUID,
|
||||
VehicleAction.VehicleState(
|
||||
player.GUID,
|
||||
vehicle_guid,
|
||||
unk1,
|
||||
position,
|
||||
|
|
@ -92,7 +94,7 @@ class VehicleLogic(val ops: VehicleOperations, implicit val context: ActorContex
|
|||
is_decelerating,
|
||||
obj.Cloaked
|
||||
)
|
||||
)
|
||||
) //todo CachedMessage
|
||||
sessionLogic.squad.updateSquad()
|
||||
case (None, _) =>
|
||||
//log.error(s"VehicleState: no vehicle $vehicle_guid found in zone")
|
||||
|
|
@ -164,26 +166,11 @@ class VehicleLogic(val ops: VehicleOperations, implicit val context: ActorContex
|
|||
obj.Position = position
|
||||
obj.Orientation = angle
|
||||
obj.DeploymentState = if (is_crouched || !notMountedState) DriveState.Kneeling else DriveState.Mobile
|
||||
continent.VehicleEvents ! VehicleServiceMessage(
|
||||
continent.VehicleEvents ! MessageEnvelope(
|
||||
continent.id,
|
||||
VehicleAction.FrameVehicleState(
|
||||
player.GUID,
|
||||
vehicle_guid,
|
||||
unk1,
|
||||
position,
|
||||
angle,
|
||||
velocity,
|
||||
unk2,
|
||||
unk3,
|
||||
unk4,
|
||||
is_crouched,
|
||||
is_airborne,
|
||||
ascending_flight,
|
||||
flight_time,
|
||||
unk9,
|
||||
unkA
|
||||
)
|
||||
)
|
||||
player.GUID,
|
||||
VehicleAction.FrameVehicleState(vehicle_guid, unk1, position, angle, velocity, unk2, unk3, unk4, is_crouched, is_airborne, ascending_flight, flight_time, unk9, unkA)
|
||||
) //todo CachedMessage
|
||||
sessionLogic.squad.updateSquad()
|
||||
case (None, _) =>
|
||||
//log.error(s"VehicleState: no vehicle $vehicle_guid found in zone")
|
||||
|
|
@ -234,10 +221,11 @@ class VehicleLogic(val ops: VehicleOperations, implicit val context: ActorContex
|
|||
val angle = Vector3(0f, pitch, yaw)
|
||||
tool.Orientation = angle
|
||||
player.Orientation = angle
|
||||
continent.VehicleEvents ! VehicleServiceMessage(
|
||||
continent.VehicleEvents ! MessageEnvelope(
|
||||
continent.id,
|
||||
VehicleAction.ChildObjectState(player.GUID, object_guid, pitch, yaw)
|
||||
)
|
||||
player.GUID,
|
||||
VehicleAction.ChildObjectState(object_guid, pitch, yaw)
|
||||
) //todo CachedMessage
|
||||
}
|
||||
//TODO status condition of "playing getting out of vehicle to allow for late packets without warning
|
||||
if (player.death_by == -1) {
|
||||
|
|
@ -256,22 +244,10 @@ class VehicleLogic(val ops: VehicleOperations, implicit val context: ActorContex
|
|||
obj.Velocity = vel
|
||||
sessionLogic.updateBlockMap(obj, pos)
|
||||
obj.zoneInteractions()
|
||||
continent.VehicleEvents ! VehicleServiceMessage(
|
||||
continent.VehicleEvents ! CachedEnvelope(
|
||||
continent.id,
|
||||
VehicleAction.VehicleState(
|
||||
player.GUID,
|
||||
vehicle_guid,
|
||||
unk1,
|
||||
pos,
|
||||
ang,
|
||||
obj.Velocity,
|
||||
obj.Flying,
|
||||
0,
|
||||
0,
|
||||
15,
|
||||
unk5 = false,
|
||||
obj.Cloaked
|
||||
)
|
||||
player.GUID,
|
||||
VehicleAction.VehicleState(vehicle_guid, unk1, pos, ang, obj.Velocity, obj.Flying, 0, 0, 15, unk5 = false, obj.Cloaked)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -328,9 +304,10 @@ class VehicleLogic(val ops: VehicleOperations, implicit val context: ActorContex
|
|||
if (obj.DeploymentState != DriveState.Mobile) {
|
||||
obj.DeploymentState = DriveState.Mobile
|
||||
sendResponse(DeployRequestMessage(player.GUID, obj.GUID, DriveState.Mobile, 0, unk3=false, Vector3.Zero))
|
||||
continent.VehicleEvents ! VehicleServiceMessage(
|
||||
continent.VehicleEvents ! MessageEnvelope(
|
||||
continent.id,
|
||||
VehicleAction.DeployRequest(player.GUID, obj.GUID, DriveState.Mobile, 0, unk2=false, Vector3.Zero)
|
||||
player.GUID,
|
||||
VehicleAction.DeployRequest(obj.GUID, DriveState.Mobile, 0, unk2=false, Vector3.Zero)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -1,11 +1,13 @@
|
|||
// Copyright (c) 2024 PSForever
|
||||
package net.psforever.actors.session.normal
|
||||
|
||||
import akka.actor.Actor.Receive
|
||||
import akka.actor.{ActorContext, ActorRef, typed}
|
||||
import net.psforever.actors.session.AvatarActor
|
||||
import net.psforever.actors.session.support.{GalaxyHandlerFunctions, SessionGalaxyHandlers, SessionData}
|
||||
import net.psforever.actors.session.support.{GalaxyHandlerFunctions, SessionData, SessionGalaxyHandlers}
|
||||
import net.psforever.packet.game.{BroadcastWarpgateUpdateMessage, FriendsResponse, HotSpotUpdateMessage, ZoneInfoMessage, ZonePopulationUpdateMessage, HotSpotInfo => PacketHotSpotInfo}
|
||||
import net.psforever.services.galaxy.{GalaxyAction, GalaxyResponse, GalaxyServiceMessage}
|
||||
import net.psforever.services.base.envelope.MessageEnvelope
|
||||
import net.psforever.services.galaxy.GalaxyAction
|
||||
import net.psforever.types.{MemberAction, PlanetSideEmpire}
|
||||
|
||||
object GalaxyHandlerLogic {
|
||||
|
|
@ -26,68 +28,62 @@ class GalaxyHandlerLogic(val ops: SessionGalaxyHandlers, implicit val context: A
|
|||
def handleUpdateIgnoredPlayers(pkt: FriendsResponse): Unit = {
|
||||
sendResponse(pkt)
|
||||
pkt.friends.foreach { f =>
|
||||
galaxyService ! GalaxyServiceMessage(GalaxyAction.LogStatusChange(f.name))
|
||||
galaxyService ! MessageEnvelope("", GalaxyAction.LogStatusChange(f.name))
|
||||
}
|
||||
}
|
||||
|
||||
/* response handlers */
|
||||
|
||||
def handle(reply: GalaxyResponse.Response): Unit = {
|
||||
reply match {
|
||||
case GalaxyResponse.HotSpotUpdate(zone_index, priority, hot_spot_info) =>
|
||||
sendResponse(
|
||||
HotSpotUpdateMessage(
|
||||
zone_index,
|
||||
priority,
|
||||
hot_spot_info.map { spot => PacketHotSpotInfo(spot.DisplayLocation.x, spot.DisplayLocation.y, 40) }
|
||||
)
|
||||
def receive: Receive = {
|
||||
case GalaxyAction.HotSpotUpdate(zone_index, priority, hot_spot_info) =>
|
||||
sendResponse(
|
||||
HotSpotUpdateMessage(
|
||||
zone_index,
|
||||
priority,
|
||||
hot_spot_info.map { spot => PacketHotSpotInfo(spot.DisplayLocation.x, spot.DisplayLocation.y, 40) }
|
||||
)
|
||||
)
|
||||
|
||||
case GalaxyResponse.MapUpdate(msg) =>
|
||||
sendResponse(msg)
|
||||
import net.psforever.actors.zone.ZoneActor
|
||||
import net.psforever.zones.Zones
|
||||
Zones.zones.find(_.Number == msg.continent_id) match {
|
||||
case Some(zone) =>
|
||||
zone.actor ! ZoneActor.BuildingInfoState(msg)
|
||||
case None =>
|
||||
}
|
||||
case GalaxyAction.MapUpdate(msg) =>
|
||||
sendResponse(msg)
|
||||
import net.psforever.actors.zone.ZoneActor
|
||||
import net.psforever.zones.Zones
|
||||
Zones.zones.find(_.Number == msg.continent_id) match {
|
||||
case Some(zone) =>
|
||||
zone.actor ! ZoneActor.BuildingInfoState(msg)
|
||||
case None =>
|
||||
}
|
||||
|
||||
case GalaxyResponse.UpdateBroadcastPrivileges(zoneId, gateMapId, fromFactions, toFactions) =>
|
||||
val faction = player.Faction
|
||||
val from = fromFactions.contains(faction)
|
||||
val to = toFactions.contains(faction)
|
||||
if (from && !to) {
|
||||
sendResponse(BroadcastWarpgateUpdateMessage(zoneId, gateMapId, PlanetSideEmpire.NEUTRAL))
|
||||
} else if (!from && to) {
|
||||
sendResponse(BroadcastWarpgateUpdateMessage(zoneId, gateMapId, faction))
|
||||
}
|
||||
case GalaxyAction.UpdateBroadcastPrivileges(zoneId, gateMapId, fromFactions, toFactions) =>
|
||||
val faction = player.Faction
|
||||
val from = fromFactions.contains(faction)
|
||||
val to = toFactions.contains(faction)
|
||||
if (from && !to) {
|
||||
sendResponse(BroadcastWarpgateUpdateMessage(zoneId, gateMapId, PlanetSideEmpire.NEUTRAL))
|
||||
} else if (!from && to) {
|
||||
sendResponse(BroadcastWarpgateUpdateMessage(zoneId, gateMapId, faction))
|
||||
}
|
||||
|
||||
case GalaxyResponse.FlagMapUpdate(msg) =>
|
||||
sendResponse(msg)
|
||||
case GalaxyAction.FlagMapUpdate(msg) =>
|
||||
sendResponse(msg)
|
||||
|
||||
case GalaxyResponse.TransferPassenger(temp_channel, vehicle, _, manifest) =>
|
||||
sessionLogic.zoning.handleTransferPassenger(temp_channel, vehicle, manifest)
|
||||
case GalaxyAction.TransferPassenger(_, temp_channel, vehicle, _, manifest) =>
|
||||
sessionLogic.zoning.handleTransferPassenger(temp_channel, vehicle, manifest)
|
||||
|
||||
case GalaxyResponse.LockedZoneUpdate(zone, time) =>
|
||||
sendResponse(ZoneInfoMessage(zone.Number, empire_status=false, lock_time=time))
|
||||
case GalaxyAction.LockedZoneUpdate(zone, time) =>
|
||||
sendResponse(ZoneInfoMessage(zone.Number, empire_status=false, lock_time=time))
|
||||
|
||||
case GalaxyResponse.UnlockedZoneUpdate(zone) =>
|
||||
sendResponse(ZoneInfoMessage(zone.Number, empire_status=true, lock_time=0L))
|
||||
val popBO = 0
|
||||
val pop = zone.LivePlayers.distinctBy(_.CharId)
|
||||
val popTR = pop.count(_.Faction == PlanetSideEmpire.TR)
|
||||
val popNC = pop.count(_.Faction == PlanetSideEmpire.NC)
|
||||
val popVS = pop.count(_.Faction == PlanetSideEmpire.VS)
|
||||
sendResponse(ZonePopulationUpdateMessage(zone.Number, 414, 138, popTR, 138, popNC, 138, popVS, 138, popBO))
|
||||
case GalaxyAction.UnlockedZoneUpdate(zone) =>
|
||||
sendResponse(ZoneInfoMessage(zone.Number, empire_status=true, lock_time=0L))
|
||||
val popBO = 0
|
||||
val pop = zone.LivePlayers.distinctBy(_.CharId)
|
||||
val popTR = pop.count(_.Faction == PlanetSideEmpire.TR)
|
||||
val popNC = pop.count(_.Faction == PlanetSideEmpire.NC)
|
||||
val popVS = pop.count(_.Faction == PlanetSideEmpire.VS)
|
||||
sendResponse(ZonePopulationUpdateMessage(zone.Number, 414, 138, popTR, 138, popNC, 138, popVS, 138, popBO))
|
||||
|
||||
case GalaxyResponse.LogStatusChange(name) if avatar.people.friend.exists(_.name.equals(name)) =>
|
||||
avatarActor ! AvatarActor.MemberListRequest(MemberAction.UpdateFriend, name)
|
||||
|
||||
case GalaxyResponse.SendResponse(msg) =>
|
||||
sendResponse(msg)
|
||||
|
||||
case _ => ()
|
||||
}
|
||||
case GalaxyAction.LogStatusChange(name)
|
||||
if TestFilter(() => avatar.people.friend.exists(_.name.equals(name))) =>
|
||||
avatarActor ! AvatarActor.MemberListRequest(MemberAction.UpdateFriend, name)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -42,8 +42,9 @@ import net.psforever.objects.zones.{ZoneProjectile, Zoning}
|
|||
import net.psforever.packet.PlanetSideGamePacket
|
||||
import net.psforever.packet.game.{ActionCancelMessage, ActionResultMessage, AvatarFirstTimeEventMessage, AvatarImplantMessage, AvatarJumpMessage, BattleplanMessage, BindPlayerMessage, BugReportMessage, ChangeFireModeMessage, ChangeShortcutBankMessage, CharacterCreateRequestMessage, CharacterRequestAction, CharacterRequestMessage, ChatMsg, CollisionIs, ConnectToWorldRequestMessage, CreateShortcutMessage, DeadState, DeployObjectMessage, DisplayedAwardMessage, DropItemMessage, EmoteMsg, FacilityBenefitShieldChargeRequestMessage, FriendsRequest, GenericAction, GenericActionMessage, GenericCollisionMsg, GenericObjectActionAtPositionMessage, GenericObjectActionMessage, GenericObjectStateMsg, HitHint, InvalidTerrainMessage, LootItemMessage, MoveItemMessage, ObjectDetectedMessage, ObjectHeldMessage, OutfitMembershipRequest, OutfitMembershipRequestAction, OutfitMembershipResponse, OutfitRequest, OutfitRequestAction, PickupItemMessage, PlanetsideAttributeMessage, PlayerStateMessageUpstream, RequestDestroyMessage, TargetingImplantRequest, TerrainCondition, TradeMessage, UnuseItemMessage, UseItemMessage, VoiceHostInfo, VoiceHostRequest, ZipLineMessage}
|
||||
import net.psforever.services.account.{AccountPersistenceService, RetrieveAccountData}
|
||||
import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage}
|
||||
import net.psforever.services.local.{LocalAction, LocalServiceMessage}
|
||||
import net.psforever.services.avatar.AvatarAction
|
||||
import net.psforever.services.base.envelope.MessageEnvelope
|
||||
import net.psforever.services.base.message.PlanetsideAttribute
|
||||
import net.psforever.services.local.support.CaptureFlagManager
|
||||
import net.psforever.types.{CapacitorStateType, ChatMessageType, Cosmetic, ExoSuitType, ImplantType, PlanetSideEmpire, PlanetSideGUID, Vector3}
|
||||
import net.psforever.util.Config
|
||||
|
|
@ -179,10 +180,10 @@ class GeneralLogic(val ops: GeneralOperations, implicit val context: ActorContex
|
|||
case _ =>
|
||||
false
|
||||
})
|
||||
continent.AvatarEvents ! AvatarServiceMessage(
|
||||
continent.AvatarEvents ! MessageEnvelope(
|
||||
continent.id,
|
||||
avatarGuid,
|
||||
AvatarAction.PlayerState(
|
||||
avatarGuid,
|
||||
player.Position,
|
||||
player.Velocity,
|
||||
yaw,
|
||||
|
|
@ -196,7 +197,7 @@ class GeneralLogic(val ops: GeneralOperations, implicit val context: ActorContex
|
|||
isNotVisible,
|
||||
eagleEye
|
||||
)
|
||||
)
|
||||
) //todo CachedMessage
|
||||
sessionLogic.squad.updateSquad()
|
||||
if (player.death_by == -1) {
|
||||
sessionLogic.kickedByAdministration()
|
||||
|
|
@ -213,15 +214,8 @@ class GeneralLogic(val ops: GeneralOperations, implicit val context: ActorContex
|
|||
}
|
||||
|
||||
def handleEmote(pkt: EmoteMsg): Unit = {
|
||||
val EmoteMsg(avatarGuid, emote) = pkt
|
||||
val pZone = player.Zone
|
||||
sendResponse(EmoteMsg(avatarGuid, emote))
|
||||
pZone.blockMap.sector(player).livePlayerList.collect { case t if t.GUID != player.GUID =>
|
||||
pZone.LocalEvents ! LocalServiceMessage(t.Name, LocalAction.SendResponse(EmoteMsg(avatarGuid, emote)))
|
||||
}
|
||||
pZone.AllPlayers.collect { case t if t.GUID != player.GUID && !t.allowInteraction =>
|
||||
pZone.LocalEvents ! LocalServiceMessage(t.Name, LocalAction.SendResponse(EmoteMsg(avatarGuid, emote)))
|
||||
}
|
||||
sendResponse(pkt)
|
||||
ops.handleEmote(pkt)
|
||||
}
|
||||
|
||||
def handleDropItem(pkt: DropItemMessage): Unit = {
|
||||
|
|
@ -525,9 +519,10 @@ class GeneralLogic(val ops: GeneralOperations, implicit val context: ActorContex
|
|||
case GenericAction.MaxAnchorsExtend_RCV =>
|
||||
log.info(s"${player.Name} has anchored ${player.Sex.pronounObject}self to the ground")
|
||||
player.UsingSpecial = SpecialExoSuitDefinition.Mode.Anchored
|
||||
continent.AvatarEvents ! AvatarServiceMessage(
|
||||
continent.AvatarEvents ! MessageEnvelope(
|
||||
continent.id,
|
||||
AvatarAction.PlanetsideAttribute(player.GUID, 19, 1)
|
||||
player.GUID,
|
||||
PlanetsideAttribute(player.GUID, 19, 1)
|
||||
)
|
||||
definition match {
|
||||
case GlobalDefinitions.trhev_dualcycler | GlobalDefinitions.trhev_burster =>
|
||||
|
|
@ -546,9 +541,10 @@ class GeneralLogic(val ops: GeneralOperations, implicit val context: ActorContex
|
|||
case GenericAction.MaxAnchorsRelease_RCV =>
|
||||
log.info(s"${player.Name} has released the anchors")
|
||||
player.UsingSpecial = SpecialExoSuitDefinition.Mode.Normal
|
||||
continent.AvatarEvents ! AvatarServiceMessage(
|
||||
continent.AvatarEvents ! MessageEnvelope(
|
||||
continent.id,
|
||||
AvatarAction.PlanetsideAttribute(player.GUID, 19, 0)
|
||||
player.GUID,
|
||||
PlanetsideAttribute(player.GUID, 19, 0)
|
||||
)
|
||||
definition match {
|
||||
case GlobalDefinitions.trhev_dualcycler | GlobalDefinitions.trhev_burster =>
|
||||
|
|
|
|||
|
|
@ -1,17 +1,19 @@
|
|||
// Copyright (c) 2024 PSForever
|
||||
package net.psforever.actors.session.normal
|
||||
|
||||
import akka.actor.Actor.Receive
|
||||
import akka.actor.ActorContext
|
||||
import net.psforever.actors.session.support.SpawnOperations.ActivityQueuedTask
|
||||
import net.psforever.actors.session.support.{LocalHandlerFunctions, SessionData, SessionLocalHandlers, SpawnOperations}
|
||||
import net.psforever.objects.ce.Deployable
|
||||
import net.psforever.objects.serverobject.doors.Door
|
||||
import net.psforever.objects.vehicles.MountableWeapons
|
||||
import net.psforever.objects.{BoomerDeployable, ExplosiveDeployable, TelepadDeployable, Tool, TurretDeployable}
|
||||
import net.psforever.packet.game.{ChatMsg, DeployableObjectsInfoMessage, GenericActionMessage, GenericObjectActionMessage, GenericObjectStateMsg, HackMessage, HackState, HackState1, InventoryStateMessage, ObjectAttachMessage, ObjectCreateMessage, ObjectDeleteMessage, ObjectDetachMessage, OrbitalShuttleTimeMsg, PadAndShuttlePair, PlanetsideAttributeMessage, ProximityTerminalUseMessage, SetEmpireMessage, TriggerEffectMessage, TriggerSoundMessage, TriggeredSound, VehicleStateMessage}
|
||||
import net.psforever.objects.{BoomerDeployable, Default, ExplosiveDeployable, TelepadDeployable, Tool, TurretDeployable}
|
||||
import net.psforever.packet.game.{ChatMsg, DeployableObjectsInfoMessage, GenericActionMessage, GenericObjectActionMessage, GenericObjectStateMsg, HackMessage, HackState, HackState1, InventoryStateMessage, ObjectAttachMessage, ObjectCreateMessage, ObjectDeleteMessage, ObjectDetachMessage, OrbitalShuttleTimeMsg, PadAndShuttlePair, PlanetsideAttributeMessage, ProximityTerminalUseMessage, TriggerEffectMessage, TriggerSoundMessage, TriggeredSound, VehicleStateMessage}
|
||||
import net.psforever.services.base.message.{PlanetsideAttribute, SendResponse}
|
||||
import net.psforever.services.{InterstellarClusterService, Service}
|
||||
import net.psforever.services.local.LocalResponse
|
||||
import net.psforever.types.{ChatMessageType, PlanetSideGUID, SpawnGroup}
|
||||
import net.psforever.services.local.LocalAction
|
||||
import net.psforever.types.{ChatMessageType, SpawnGroup}
|
||||
|
||||
object LocalHandlerLogic {
|
||||
def apply(ops: SessionLocalHandlers): LocalHandlerLogic = {
|
||||
|
|
@ -34,244 +36,218 @@ class LocalHandlerLogic(val ops: SessionLocalHandlers, implicit val context: Act
|
|||
|
||||
/* response handlers */
|
||||
|
||||
/**
|
||||
* na
|
||||
* @param toChannel na
|
||||
* @param guid na
|
||||
* @param reply na
|
||||
*/
|
||||
def handle(toChannel: String, guid: PlanetSideGUID, reply: LocalResponse.Response): Unit = {
|
||||
val resolvedPlayerGuid = if (player.HasGUID) {
|
||||
player.GUID
|
||||
} else {
|
||||
Service.defaultPlayerGUID
|
||||
}
|
||||
val isNotSameTarget = resolvedPlayerGuid != guid
|
||||
reply match {
|
||||
case LocalResponse.DeployableMapIcon(behavior, deployInfo) if isNotSameTarget =>
|
||||
sendResponse(DeployableObjectsInfoMessage(behavior, deployInfo))
|
||||
|
||||
case LocalResponse.DeployableUIFor(item) =>
|
||||
sessionLogic.general.updateDeployableUIElements(avatar.deployables.UpdateUIElement(item))
|
||||
|
||||
case LocalResponse.Detonate(dguid, _: BoomerDeployable) =>
|
||||
sendResponse(TriggerEffectMessage(dguid, "detonate_boomer"))
|
||||
sendResponse(PlanetsideAttributeMessage(dguid, attribute_type=29, attribute_value=1))
|
||||
sendResponse(ObjectDeleteMessage(dguid, unk1=0))
|
||||
|
||||
case LocalResponse.Detonate(dguid, _: ExplosiveDeployable) =>
|
||||
sendResponse(GenericObjectActionMessage(dguid, code=19))
|
||||
sendResponse(PlanetsideAttributeMessage(dguid, attribute_type=29, attribute_value=1))
|
||||
sendResponse(ObjectDeleteMessage(dguid, unk1=0))
|
||||
|
||||
case LocalResponse.Detonate(_, obj) =>
|
||||
log.warn(s"LocalResponse.Detonate: ${obj.Definition.Name} not configured to explode correctly")
|
||||
|
||||
case LocalResponse.DoorOpens(doorGuid) if isNotSameTarget =>
|
||||
val pos = player.Position.xy
|
||||
val range = ops.doorLoadRange()
|
||||
val foundDoor = continent
|
||||
.blockMap
|
||||
.sector(pos, range)
|
||||
.amenityList
|
||||
.collect { case door: Door => door }
|
||||
.find(_.GUID == doorGuid)
|
||||
val doorExistsInRange: Boolean = foundDoor.nonEmpty
|
||||
if (doorExistsInRange) {
|
||||
sendResponse(GenericObjectStateMsg(doorGuid, state=16))
|
||||
}
|
||||
|
||||
case LocalResponse.DoorCloses(doorGuid) => //door closes for everyone
|
||||
sendResponse(GenericObjectStateMsg(doorGuid, state=17))
|
||||
|
||||
case LocalResponse.EliminateDeployable(obj: TurretDeployable, dguid, _, _) if obj.Destroyed =>
|
||||
sendResponse(ObjectDeleteMessage(dguid, unk1=0))
|
||||
|
||||
case LocalResponse.EliminateDeployable(obj: TurretDeployable, dguid, pos, _) =>
|
||||
obj.Destroyed = true
|
||||
ops.DeconstructDeployable(
|
||||
obj,
|
||||
dguid,
|
||||
pos,
|
||||
obj.Orientation,
|
||||
deletionType= if (obj.MountPoints.isEmpty) { 2 } else { 1 }
|
||||
)
|
||||
|
||||
case LocalResponse.EliminateDeployable(obj: ExplosiveDeployable, dguid, _, _)
|
||||
if obj.Destroyed || obj.Jammed || obj.Health == 0 =>
|
||||
sendResponse(ObjectDeleteMessage(dguid, unk1=0))
|
||||
|
||||
case LocalResponse.EliminateDeployable(obj: ExplosiveDeployable, dguid, pos, effect) =>
|
||||
obj.Destroyed = true
|
||||
ops.DeconstructDeployable(obj, dguid, pos, obj.Orientation, effect)
|
||||
|
||||
case LocalResponse.EliminateDeployable(obj: TelepadDeployable, dguid, _, _) if obj.Active && obj.Destroyed =>
|
||||
//if active, deactivate
|
||||
obj.Active = false
|
||||
ops.deactivateTelpadDeployableMessages(dguid)
|
||||
//standard deployable elimination behavior
|
||||
sendResponse(ObjectDeleteMessage(dguid, unk1=0))
|
||||
|
||||
case LocalResponse.EliminateDeployable(obj: TelepadDeployable, dguid, pos, _) if obj.Active =>
|
||||
//if active, deactivate
|
||||
obj.Active = false
|
||||
ops.deactivateTelpadDeployableMessages(dguid)
|
||||
//standard deployable elimination behavior
|
||||
obj.Destroyed = true
|
||||
ops.DeconstructDeployable(obj, dguid, pos, obj.Orientation, deletionType=2)
|
||||
|
||||
case LocalResponse.EliminateDeployable(obj: TelepadDeployable, dguid, _, _) if obj.Destroyed =>
|
||||
//standard deployable elimination behavior
|
||||
sendResponse(ObjectDeleteMessage(dguid, unk1=0))
|
||||
|
||||
case LocalResponse.EliminateDeployable(obj: TelepadDeployable, dguid, pos, _) =>
|
||||
//standard deployable elimination behavior
|
||||
obj.Destroyed = true
|
||||
ops.DeconstructDeployable(obj, dguid, pos, obj.Orientation, deletionType=2)
|
||||
|
||||
case LocalResponse.EliminateDeployable(obj, dguid, _, _) if obj.Destroyed =>
|
||||
sendResponse(ObjectDeleteMessage(dguid, unk1=0))
|
||||
|
||||
case LocalResponse.EliminateDeployable(obj, dguid, pos, effect) =>
|
||||
obj.Destroyed = true
|
||||
ops.DeconstructDeployable(obj, dguid, pos, obj.Orientation, effect)
|
||||
|
||||
case LocalResponse.SendHackMessageHackCleared(targetGuid, unk1, unk2) =>
|
||||
sendResponse(HackMessage(HackState1.Unk0, targetGuid, guid, progress=0, unk1.toFloat, HackState.HackCleared, unk2))
|
||||
|
||||
case LocalResponse.HackObject(targetGuid, unk1, unk2) =>
|
||||
sessionLogic.general.hackObject(targetGuid, unk1, unk2)
|
||||
|
||||
case LocalResponse.PlanetsideAttribute(targetGuid, attributeType, attributeValue) =>
|
||||
sessionLogic.general.sendPlanetsideAttributeMessage(targetGuid, attributeType, attributeValue)
|
||||
|
||||
case LocalResponse.GenericObjectAction(targetGuid, actionNumber) =>
|
||||
sendResponse(GenericObjectActionMessage(targetGuid, actionNumber))
|
||||
|
||||
case LocalResponse.GenericActionMessage(actionNumber) =>
|
||||
sendResponse(GenericActionMessage(actionNumber))
|
||||
|
||||
case LocalResponse.ChatMessage(msg) =>
|
||||
sendResponse(msg)
|
||||
|
||||
case LocalResponse.SendPacket(packet) =>
|
||||
sendResponse(packet)
|
||||
|
||||
case LocalResponse.LluSpawned(llu) =>
|
||||
// Create LLU on client
|
||||
sendResponse(ObjectCreateMessage(
|
||||
llu.Definition.ObjectId,
|
||||
llu.GUID,
|
||||
llu.Definition.Packet.ConstructorData(llu).get
|
||||
))
|
||||
sendResponse(TriggerSoundMessage(TriggeredSound.LLUMaterialize, llu.Position, unk=20, volume=0.8000001f))
|
||||
|
||||
case LocalResponse.LluDespawned(lluGuid, position) =>
|
||||
sendResponse(TriggerSoundMessage(TriggeredSound.LLUDeconstruct, position, unk=20, volume=0.8000001f))
|
||||
sendResponse(ObjectDeleteMessage(lluGuid, unk1=0))
|
||||
// If the player was holding the LLU, remove it from their tracked special item slot
|
||||
sessionLogic.general.specialItemSlotGuid.collect { case guid if guid == lluGuid =>
|
||||
sessionLogic.general.specialItemSlotGuid = None
|
||||
player.Carrying = None
|
||||
}
|
||||
|
||||
case LocalResponse.ObjectDelete(objectGuid, unk) if isNotSameTarget =>
|
||||
sendResponse(ObjectDeleteMessage(objectGuid, unk))
|
||||
|
||||
case LocalResponse.ProximityTerminalEffect(object_guid, true) =>
|
||||
sendResponse(ProximityTerminalUseMessage(Service.defaultPlayerGUID, object_guid, unk=true))
|
||||
|
||||
case LocalResponse.ProximityTerminalEffect(objectGuid, false) =>
|
||||
sendResponse(ProximityTerminalUseMessage(Service.defaultPlayerGUID, objectGuid, unk=false))
|
||||
sessionLogic.terminals.ForgetAllProximityTerminals(objectGuid)
|
||||
|
||||
case LocalResponse.RouterTelepadMessage(msg) =>
|
||||
sendResponse(ChatMsg(ChatMessageType.UNK_229, wideContents=false, recipient="", msg, note=None))
|
||||
|
||||
case LocalResponse.RouterTelepadTransport(passengerGuid, srcGuid, destGuid) =>
|
||||
sessionLogic.general.useRouterTelepadEffect(passengerGuid, srcGuid, destGuid)
|
||||
|
||||
case LocalResponse.SendResponse(msg) =>
|
||||
msg match {
|
||||
case m: GenericObjectActionMessage =>
|
||||
// delay building virus alert if player is dead/respawning
|
||||
if ((m.code == 58 || m.code == 60 || m.code == 61) && !sessionLogic.zoning.spawn.startEnqueueSquadMessages) {
|
||||
sessionLogic.zoning.spawn.enqueueNewActivity(ActivityQueuedTask(
|
||||
SpawnOperations.delaySendGenericObjectActionMessage(msg), 1))
|
||||
}
|
||||
else sendResponse(msg)
|
||||
case _ =>
|
||||
sendResponse(msg)
|
||||
}
|
||||
|
||||
case LocalResponse.SetEmpire(objectGuid, empire) =>
|
||||
sendResponse(SetEmpireMessage(objectGuid, empire))
|
||||
|
||||
case LocalResponse.ShuttleEvent(ev) =>
|
||||
val msg = OrbitalShuttleTimeMsg(
|
||||
ev.u1,
|
||||
ev.u2,
|
||||
ev.t1,
|
||||
ev.t2,
|
||||
ev.t3,
|
||||
pairs=ev.pairs.map { case ((a, b), c) => PadAndShuttlePair(a, b, c) }
|
||||
)
|
||||
sendResponse(msg)
|
||||
|
||||
case LocalResponse.ShuttleDock(pguid, sguid, slot) =>
|
||||
sendResponse(ObjectAttachMessage(pguid, sguid, slot))
|
||||
|
||||
case LocalResponse.ShuttleUndock(pguid, sguid, pos, orient) =>
|
||||
sendResponse(ObjectDetachMessage(pguid, sguid, pos, orient))
|
||||
|
||||
case LocalResponse.ShuttleState(sguid, pos, orient, state) =>
|
||||
sendResponse(VehicleStateMessage(sguid, unk1=0, pos, orient, vel=None, Some(state), unk3=0, unk4=0, wheel_direction=15, is_decelerating=false, is_cloaked=false))
|
||||
|
||||
case LocalResponse.ToggleTeleportSystem(router, systemPlan) =>
|
||||
sessionLogic.general.toggleTeleportSystem(router, systemPlan)
|
||||
|
||||
case LocalResponse.TriggerEffect(targetGuid, effect, effectInfo, triggerLocation) =>
|
||||
sendResponse(TriggerEffectMessage(targetGuid, effect, effectInfo, triggerLocation))
|
||||
|
||||
case LocalResponse.TriggerSound(sound, pos, unk, volume) =>
|
||||
sendResponse(TriggerSoundMessage(sound, pos, unk, volume))
|
||||
|
||||
case LocalResponse.UpdateForceDomeStatus(buildingGuid, true) =>
|
||||
sendResponse(GenericObjectActionMessage(buildingGuid, 11))
|
||||
|
||||
case LocalResponse.UpdateForceDomeStatus(buildingGuid, false) =>
|
||||
sendResponse(GenericObjectActionMessage(buildingGuid, 12))
|
||||
|
||||
case LocalResponse.RechargeVehicleWeapon(vehicleGuid, weaponGuid) if resolvedPlayerGuid == guid =>
|
||||
continent.GUID(vehicleGuid)
|
||||
.collect { case vehicle: MountableWeapons => (vehicle, vehicle.PassengerInSeat(player)) }
|
||||
.collect { case (vehicle, Some(seat_num)) => vehicle.WeaponControlledFromSeat(seat_num) }
|
||||
.getOrElse(Set.empty)
|
||||
.collect { case weapon: Tool if weapon.GUID == weaponGuid =>
|
||||
sendResponse(InventoryStateMessage(weapon.AmmoSlot.Box.GUID, weapon.GUID, weapon.Magazine))
|
||||
}
|
||||
|
||||
case LocalResponse.ForceZoneChange(zone) =>
|
||||
//todo we might be able to piggyback this for squad recalls later
|
||||
if(session.zone eq zone) {
|
||||
sessionLogic.zoning.zoneReload = true
|
||||
zone.AvatarEvents ! Service.Leave()
|
||||
zone.LocalEvents ! Service.Leave()
|
||||
zone.VehicleEvents ! Service.Leave()
|
||||
zone.AvatarEvents ! Service.Join(player.Name) //must manually restore this subscriptions
|
||||
sessionLogic.zoning.spawn.handleNewPlayerLoaded(player) //will restart subscriptions and dispatch a LoadMapMessage
|
||||
} else {
|
||||
import akka.actor.typed.scaladsl.adapter._
|
||||
sessionLogic.cluster ! InterstellarClusterService.GetRandomSpawnPoint(
|
||||
zone.Number,
|
||||
player.Faction,
|
||||
Seq(SpawnGroup.Facility, SpawnGroup.Tower, SpawnGroup.AMS),
|
||||
context.self
|
||||
def receive: Receive = {
|
||||
case SendResponse(msgs) =>
|
||||
msgs.foreach {
|
||||
case msg @ (m: GenericObjectActionMessage)
|
||||
if (m.code == 58 || m.code == 60 || m.code == 61) && !sessionLogic.zoning.spawn.startEnqueueSquadMessages =>
|
||||
// delay building virus alert if player is dead/respawning
|
||||
sessionLogic.zoning.spawn.enqueueNewActivity(ActivityQueuedTask(
|
||||
SpawnOperations.delaySendGenericObjectActionMessage(msg), 1)
|
||||
)
|
||||
case msg =>
|
||||
sendResponse(msg)
|
||||
}
|
||||
|
||||
case LocalAction.DeployableMapIcon(behavior, deployInfo)
|
||||
if TestFilter(NotSameTargetTest) =>
|
||||
sendResponse(DeployableObjectsInfoMessage(behavior, deployInfo))
|
||||
|
||||
case LocalAction.DeployableUIFor(item) =>
|
||||
sessionLogic.general.updateDeployableUIElements(avatar.deployables.UpdateUIElement(item))
|
||||
|
||||
case LocalAction.Detonate(dguid, _: BoomerDeployable) =>
|
||||
sendResponse(TriggerEffectMessage(dguid, "detonate_boomer"))
|
||||
sendResponse(PlanetsideAttributeMessage(dguid, attribute_type=29, attribute_value=1))
|
||||
sendResponse(ObjectDeleteMessage(dguid, unk1=0))
|
||||
|
||||
case LocalAction.Detonate(dguid, _: ExplosiveDeployable) =>
|
||||
sendResponse(GenericObjectActionMessage(dguid, code=19))
|
||||
sendResponse(PlanetsideAttributeMessage(dguid, attribute_type=29, attribute_value=1))
|
||||
sendResponse(ObjectDeleteMessage(dguid, unk1=0))
|
||||
|
||||
case LocalAction.Detonate(_, obj) =>
|
||||
log.warn(s"LocalAction.Detonate: ${obj.Definition.Name} not configured to explode correctly")
|
||||
|
||||
case LocalAction.DoorOpens(_, door)
|
||||
if TestFilter(NotSameTargetTest) =>
|
||||
val doorGuid = door.GUID
|
||||
val pos = player.Position.xy
|
||||
val range = ops.doorLoadRange()
|
||||
val foundDoor = continent
|
||||
.blockMap
|
||||
.sector(pos, range)
|
||||
.amenityList
|
||||
.collect { case door: Door => door }
|
||||
.find(_.GUID == doorGuid)
|
||||
val doorExistsInRange: Boolean = foundDoor.nonEmpty
|
||||
if (doorExistsInRange) {
|
||||
sendResponse(GenericObjectStateMsg(doorGuid, state=16))
|
||||
}
|
||||
|
||||
case LocalAction.DoorCloses(doorGuid) => //door closes for everyone
|
||||
sendResponse(GenericObjectStateMsg(doorGuid, state=17))
|
||||
|
||||
case LocalAction.EliminateDeployable(obj: TurretDeployable, dguid, _, _)
|
||||
if TestFilter(() => obj.Destroyed) =>
|
||||
sendResponse(ObjectDeleteMessage(dguid, unk1=0))
|
||||
|
||||
case LocalAction.EliminateDeployable(obj: TurretDeployable, dguid, pos, _) =>
|
||||
obj.Destroyed = true
|
||||
ops.DeconstructDeployable(
|
||||
obj,
|
||||
dguid,
|
||||
pos,
|
||||
obj.Orientation,
|
||||
deletionType= if (obj.MountPoints.isEmpty) { 2 } else { 1 }
|
||||
)
|
||||
|
||||
case LocalAction.EliminateDeployable(obj: ExplosiveDeployable, dguid, _, _)
|
||||
if TestFilter(() => { obj.Destroyed || obj.Jammed || obj.Health == 0 }) =>
|
||||
sendResponse(ObjectDeleteMessage(dguid, unk1=0))
|
||||
|
||||
case LocalAction.EliminateDeployable(obj: ExplosiveDeployable, dguid, pos, effect) =>
|
||||
obj.Destroyed = true
|
||||
ops.DeconstructDeployable(obj, dguid, pos, obj.Orientation, effect)
|
||||
|
||||
case LocalAction.EliminateDeployable(obj: TelepadDeployable, dguid, _, _)
|
||||
if TestFilter(() => { obj.Active && obj.Destroyed }) =>
|
||||
//if active, deactivate
|
||||
obj.Active = false
|
||||
ops.deactivateTelpadDeployableMessages(dguid)
|
||||
//standard deployable elimination behavior
|
||||
sendResponse(ObjectDeleteMessage(dguid, unk1=0))
|
||||
|
||||
case LocalAction.EliminateDeployable(obj: TelepadDeployable, dguid, pos, _)
|
||||
if TestFilter(() => obj.Active) =>
|
||||
//if active, deactivate
|
||||
obj.Active = false
|
||||
ops.deactivateTelpadDeployableMessages(dguid)
|
||||
//standard deployable elimination behavior
|
||||
obj.Destroyed = true
|
||||
ops.DeconstructDeployable(obj, dguid, pos, obj.Orientation, deletionType=2)
|
||||
|
||||
case LocalAction.EliminateDeployable(obj: TelepadDeployable, dguid, _, _)
|
||||
if TestFilter(() => obj.Destroyed) =>
|
||||
//standard deployable elimination behavior
|
||||
sendResponse(ObjectDeleteMessage(dguid, unk1=0))
|
||||
|
||||
case LocalAction.EliminateDeployable(obj: TelepadDeployable, dguid, pos, _) =>
|
||||
//standard deployable elimination behavior
|
||||
obj.Destroyed = true
|
||||
ops.DeconstructDeployable(obj, dguid, pos, obj.Orientation, deletionType=2)
|
||||
|
||||
case LocalAction.EliminateDeployable(obj, dguid, _, _)
|
||||
if TestFilter(() => obj.Destroyed) =>
|
||||
sendResponse(ObjectDeleteMessage(dguid, unk1=0))
|
||||
|
||||
case LocalAction.EliminateDeployable(obj, dguid, pos, effect) =>
|
||||
obj.Destroyed = true
|
||||
ops.DeconstructDeployable(obj, dguid, pos, obj.Orientation, effect)
|
||||
|
||||
case LocalAction.HackClear(targetGuid, unk1, unk2) =>
|
||||
sendResponse(HackMessage(HackState1.Unk0, targetGuid, FilterGuid, progress=0, unk1.toFloat, HackState.HackCleared, unk2))
|
||||
|
||||
case LocalAction.HackObject(targetGuid, unk1, unk2) =>
|
||||
sessionLogic.general.hackObject(targetGuid, unk1, unk2)
|
||||
|
||||
case LocalAction.GenericActionMessage(actionNumber) =>
|
||||
sendResponse(GenericActionMessage(actionNumber))
|
||||
|
||||
case LocalAction.LluSpawned(llu) =>
|
||||
// Create LLU on client
|
||||
sendResponse(ObjectCreateMessage(
|
||||
llu.Definition.ObjectId,
|
||||
llu.GUID,
|
||||
llu.Definition.Packet.ConstructorData(llu).get
|
||||
))
|
||||
sendResponse(TriggerSoundMessage(TriggeredSound.LLUMaterialize, llu.Position, unk=20, volume=0.8000001f))
|
||||
|
||||
case LocalAction.LluDespawned(lluGuid, position) =>
|
||||
sendResponse(TriggerSoundMessage(TriggeredSound.LLUDeconstruct, position, unk=20, volume=0.8000001f))
|
||||
sendResponse(ObjectDeleteMessage(lluGuid, unk1=0))
|
||||
// If the player was holding the LLU, remove it from their tracked special item slot
|
||||
sessionLogic.general.specialItemSlotGuid.collect { case guid if guid == lluGuid =>
|
||||
sessionLogic.general.specialItemSlotGuid = None
|
||||
player.Carrying = None
|
||||
}
|
||||
|
||||
case LocalAction.ProximityTerminalEffect(object_guid, true) =>
|
||||
sendResponse(ProximityTerminalUseMessage(Default.GUID0, object_guid, unk=true))
|
||||
|
||||
case LocalAction.ProximityTerminalEffect(objectGuid, false) =>
|
||||
sendResponse(ProximityTerminalUseMessage(Default.GUID0, objectGuid, unk=false))
|
||||
sessionLogic.terminals.ForgetAllProximityTerminals(objectGuid)
|
||||
|
||||
case LocalAction.RouterTelepadMessage(msg) =>
|
||||
sendResponse(ChatMsg(ChatMessageType.UNK_229, wideContents=false, recipient="", msg, note=None))
|
||||
|
||||
case LocalAction.RouterTelepadTransport(passengerGuid, srcGuid, destGuid) =>
|
||||
sessionLogic.general.useRouterTelepadEffect(passengerGuid, srcGuid, destGuid)
|
||||
|
||||
case LocalAction.ShuttleEvent(ev) =>
|
||||
val msg = OrbitalShuttleTimeMsg(
|
||||
ev.u1,
|
||||
ev.u2,
|
||||
ev.t1,
|
||||
ev.t2,
|
||||
ev.t3,
|
||||
pairs=ev.pairs.map { case ((a, b), c) => PadAndShuttlePair(a, b, c) }
|
||||
)
|
||||
sendResponse(msg)
|
||||
|
||||
case LocalAction.ShuttleDock(pguid, sguid, slot) =>
|
||||
sendResponse(ObjectAttachMessage(pguid, sguid, slot))
|
||||
|
||||
case LocalAction.ShuttleUndock(pguid, sguid, pos, orient) =>
|
||||
sendResponse(ObjectDetachMessage(pguid, sguid, pos, orient))
|
||||
|
||||
case LocalAction.ShuttleState(sguid, pos, orient, state) =>
|
||||
sendResponse(VehicleStateMessage(sguid, unk1=0, pos, orient, vel=None, Some(state), unk3=0, unk4=0, wheel_direction=15, is_decelerating=false, is_cloaked=false))
|
||||
|
||||
case LocalAction.ToggleTeleportSystem(router, systemPlan) =>
|
||||
sessionLogic.general.toggleTeleportSystem(router, systemPlan)
|
||||
|
||||
case LocalAction.TriggerEffectAtLocation(targetGuid, effect, effectInfo, triggerLocation) =>
|
||||
sendResponse(TriggerEffectMessage(targetGuid, effect, effectInfo, triggerLocation))
|
||||
|
||||
case LocalAction.TriggerSound(sound, pos, unk, volume) =>
|
||||
sendResponse(TriggerSoundMessage(sound, pos, unk, volume))
|
||||
|
||||
case LocalAction.UpdateForceDomeStatus(buildingGuid, true) =>
|
||||
sendResponse(GenericObjectActionMessage(buildingGuid, 11))
|
||||
|
||||
case LocalAction.UpdateForceDomeStatus(buildingGuid, false) =>
|
||||
sendResponse(GenericObjectActionMessage(buildingGuid, 12))
|
||||
|
||||
case LocalAction.RechargeVehicleWeapon(vehicleGuid, weaponGuid)
|
||||
if TestFilter(SameTargetTest) =>
|
||||
continent.GUID(vehicleGuid)
|
||||
.collect { case vehicle: MountableWeapons => (vehicle, vehicle.PassengerInSeat(player)) }
|
||||
.collect { case (vehicle, Some(seat_num)) => vehicle.WeaponControlledFromSeat(seat_num) }
|
||||
.getOrElse(Set.empty)
|
||||
.collect { case weapon: Tool if weapon.GUID == weaponGuid =>
|
||||
sendResponse(InventoryStateMessage(weapon.AmmoSlot.Box.GUID, weapon.GUID, weapon.Magazine))
|
||||
}
|
||||
|
||||
case _ => ()
|
||||
}
|
||||
case LocalAction.ForceZoneChange(zone) =>
|
||||
//todo we might be able to piggyback this for squad recalls later
|
||||
if(session.zone eq zone) {
|
||||
sessionLogic.zoning.zoneReload = true
|
||||
zone.AvatarEvents ! Service.LeaveAll
|
||||
zone.LocalEvents ! Service.LeaveAll
|
||||
zone.VehicleEvents ! Service.LeaveAll
|
||||
zone.AvatarEvents ! Service.Join(player.Name) //must manually restore this subscriptions
|
||||
sessionLogic.zoning.spawn.handleNewPlayerLoaded(player) //will restart subscriptions and dispatch a LoadMapMessage
|
||||
} else {
|
||||
import akka.actor.typed.scaladsl.adapter._
|
||||
sessionLogic.cluster ! InterstellarClusterService.GetRandomSpawnPoint(
|
||||
zone.Number,
|
||||
player.Faction,
|
||||
Seq(SpawnGroup.Facility, SpawnGroup.Tower, SpawnGroup.AMS),
|
||||
context.self
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/* support functions */
|
||||
|
|
|
|||
|
|
@ -16,9 +16,9 @@ import net.psforever.objects.serverobject.turret.{FacilityTurret, WeaponTurret}
|
|||
import net.psforever.objects.vehicles.AccessPermissionGroup
|
||||
import net.psforever.objects.vital.InGameHistory
|
||||
import net.psforever.packet.game.{ChatMsg, DelayedPathMountMsg, DismountVehicleCargoMsg, DismountVehicleMsg, GenericObjectActionMessage, MountVehicleCargoMsg, MountVehicleMsg, ObjectDetachMessage, PlanetsideAttributeMessage, PlayerStasisMessage, PlayerStateShiftMessage, ShiftState}
|
||||
import net.psforever.services.Service
|
||||
import net.psforever.services.local.{LocalAction, LocalServiceMessage}
|
||||
import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage}
|
||||
import net.psforever.services.base.envelope.{BundledEnvelope, MessageEnvelope}
|
||||
import net.psforever.services.base.message.{SendResponse, SetEmpire}
|
||||
import net.psforever.services.vehicle.VehicleAction
|
||||
import net.psforever.types.{BailType, ChatMessageType, DriveState, PlanetSideGUID, Vector3}
|
||||
|
||||
object MountHandlerLogic {
|
||||
|
|
@ -191,7 +191,7 @@ class MountHandlerLogic(val ops: SessionMountHandlers, implicit val context: Act
|
|||
if obj.Definition == GlobalDefinitions.vanu_sentry_turret =>
|
||||
log.info(s"${player.Name} mounts the ${obj.Definition.Name}")
|
||||
sessionLogic.zoning.CancelZoningProcessWithDescriptiveReason("cancel_mount")
|
||||
obj.Zone.LocalEvents ! LocalServiceMessage(obj.Zone.id, LocalAction.SetEmpire(obj.GUID, player.Faction))
|
||||
obj.Zone.LocalEvents ! MessageEnvelope(obj.Zone.id, SetEmpire(obj.GUID, player.Faction))
|
||||
sendResponse(PlanetsideAttributeMessage(obj.GUID, attribute_type=0, obj.Health))
|
||||
ops.updateWeaponAtSeatPosition(obj, seatNumber)
|
||||
ops.MountingAction(tplayer, obj, seatNumber)
|
||||
|
|
@ -234,9 +234,9 @@ class MountHandlerLogic(val ops: SessionMountHandlers, implicit val context: Act
|
|||
val (pos, zang) = Vehicles.dismountShuttle(obj, mountPoint)
|
||||
tplayer.Position = pos
|
||||
sendResponse(DelayedPathMountMsg(pguid, sguid, u1=60, u2=true))
|
||||
continent.LocalEvents ! LocalServiceMessage(
|
||||
continent.LocalEvents ! MessageEnvelope(
|
||||
continent.id,
|
||||
LocalAction.SendResponse(ObjectDetachMessage(sguid, pguid, pos, roll=0, pitch=0, zang))
|
||||
SendResponse(ObjectDetachMessage(sguid, pguid, pos, roll=0, pitch=0, zang))
|
||||
)
|
||||
sessionLogic.keepAliveFunc = sessionLogic.zoning.NormalKeepAlive
|
||||
|
||||
|
|
@ -249,25 +249,21 @@ class MountHandlerLogic(val ops: SessionMountHandlers, implicit val context: Act
|
|||
ops.DismountAction(tplayer, obj, seatNum)
|
||||
continent.actor ! ZoneActor.RemoveFromBlockMap(player) //character doesn't need it
|
||||
//DismountAction(...) uses vehicle service, so use that service to coordinate the remainder of the messages
|
||||
events ! VehicleServiceMessage(
|
||||
player.Name,
|
||||
VehicleAction.SendResponse(Service.defaultPlayerGUID, PlayerStasisMessage(pguid)) //the stasis message
|
||||
)
|
||||
//when the player dismounts, they will be positioned where the shuttle was when it disappeared in the sky
|
||||
//the player will fall to the ground and is perfectly vulnerable in this state
|
||||
//additionally, our player must exist in the current zone
|
||||
//having no in-game avatar target will throw us out of the map screen when deploying and cause softlock
|
||||
events ! VehicleServiceMessage(
|
||||
player.Name,
|
||||
VehicleAction.SendResponse(
|
||||
Service.defaultPlayerGUID,
|
||||
PlayerStateShiftMessage(ShiftState(unk=0, obj.Position, obj.Orientation.z, vel=None)) //cower in the shuttle bay
|
||||
events ! BundledEnvelope(
|
||||
MessageEnvelope(player.Name,
|
||||
SendResponse(Seq(
|
||||
PlayerStasisMessage(pguid),
|
||||
PlayerStateShiftMessage(ShiftState(unk=0, obj.Position, obj.Orientation.z, vel=None))
|
||||
))
|
||||
),
|
||||
MessageEnvelope(continent.id, pguid,
|
||||
SendResponse(GenericObjectActionMessage(pguid, code=9)) /* conceal the player */
|
||||
)
|
||||
)
|
||||
events ! VehicleServiceMessage(
|
||||
continent.id,
|
||||
VehicleAction.SendResponse(pguid, GenericObjectActionMessage(pguid, code=9)) //conceal the player
|
||||
)
|
||||
sessionLogic.keepAliveFunc = sessionLogic.zoning.NormalKeepAlive
|
||||
|
||||
case Mountable.CanDismount(obj: Vehicle, seatNum, _)
|
||||
|
|
@ -293,9 +289,10 @@ class MountHandlerLogic(val ops: SessionMountHandlers, implicit val context: Act
|
|||
ops.DismountVehicleAction(tplayer, obj, seatNum)
|
||||
|
||||
case Mountable.CanDismount(obj: Vehicle, seat_num, _) =>
|
||||
continent.VehicleEvents ! VehicleServiceMessage(
|
||||
continent.VehicleEvents ! MessageEnvelope(
|
||||
continent.id,
|
||||
VehicleAction.KickPassenger(tplayer.GUID, seat_num, unk2=true, obj.GUID)
|
||||
tplayer.GUID,
|
||||
VehicleAction.KickPassenger(seat_num, unk2=true, obj.GUID)
|
||||
)
|
||||
|
||||
case Mountable.CanDismount(obj: PlanetSideGameObject with Mountable with FactionAffinity with InGameHistory, seatNum, _) =>
|
||||
|
|
|
|||
|
|
@ -1,21 +1,23 @@
|
|||
// Copyright (c) 2024 PSForever
|
||||
package net.psforever.actors.session.normal
|
||||
|
||||
import akka.actor.Actor.Receive
|
||||
import akka.actor.{ActorContext, ActorRef, typed}
|
||||
import net.psforever.actors.session.AvatarActor
|
||||
import net.psforever.actors.session.support.{SessionData, SessionVehicleHandlers, VehicleHandlerFunctions}
|
||||
import net.psforever.objects.avatar.SpecialCarry
|
||||
import net.psforever.objects.{GlobalDefinitions, Player, Tool, Vehicle, Vehicles}
|
||||
import net.psforever.objects.{GlobalDefinitions, Player, Vehicle, Vehicles}
|
||||
import net.psforever.objects.equipment.{Equipment, JammableMountedWeapons, JammableUnit}
|
||||
import net.psforever.objects.guid.{GUIDTask, TaskWorkflow}
|
||||
import net.psforever.objects.serverobject.interior.Sidedness.OutsideOf
|
||||
import net.psforever.objects.serverobject.mount.Mountable
|
||||
import net.psforever.objects.serverobject.pad.VehicleSpawnPad
|
||||
import net.psforever.packet.game.objectcreate.ObjectCreateMessageParent
|
||||
import net.psforever.packet.game.{ChangeAmmoMessage, ChangeFireStateMessage_Start, ChangeFireStateMessage_Stop, ChatMsg, ChildObjectStateMessage, DeadState, DeployRequestMessage, DismountVehicleMsg, FrameVehicleStateMessage, GenericObjectActionMessage, HitHint, InventoryStateMessage, ObjectAttachMessage, ObjectCreateDetailedMessage, ObjectCreateMessage, ObjectDeleteMessage, ObjectDetachMessage, PlanetsideAttributeMessage, ReloadMessage, ServerVehicleOverrideMsg, VehicleStateMessage, WeaponDryFireMessage}
|
||||
import net.psforever.packet.game.{ChatMsg, ChildObjectStateMessage, DeadState, DeployRequestMessage, DismountVehicleMsg, FrameVehicleStateMessage, GenericObjectActionMessage, InventoryStateMessage, ObjectAttachMessage, ObjectCreateDetailedMessage, ObjectCreateMessage, ObjectDeleteMessage, ObjectDetachMessage, PlanetsideAttributeMessage, ServerVehicleOverrideMsg, VehicleStateMessage}
|
||||
import net.psforever.services.Service
|
||||
import net.psforever.services.base.envelope.GenericResponseEnvelope
|
||||
import net.psforever.services.local.support.CaptureFlagManager
|
||||
import net.psforever.services.vehicle.{VehicleResponse, VehicleServiceResponse}
|
||||
import net.psforever.services.vehicle.{VehicleAction, VehicleStamp}
|
||||
import net.psforever.types.{BailType, ChatMessageType, PlanetSideGUID, Vector3}
|
||||
|
||||
object VehicleHandlerLogic {
|
||||
|
|
@ -31,365 +33,319 @@ class VehicleHandlerLogic(val ops: SessionVehicleHandlers, implicit val context:
|
|||
|
||||
private val galaxyService: ActorRef = ops.galaxyService
|
||||
|
||||
/**
|
||||
* na
|
||||
*
|
||||
* @param toChannel na
|
||||
* @param guid na
|
||||
* @param reply na
|
||||
*/
|
||||
def handle(toChannel: String, guid: PlanetSideGUID, reply: VehicleResponse.Response): Unit = {
|
||||
val resolvedPlayerGuid = if (player.HasGUID) {
|
||||
player.GUID
|
||||
} else {
|
||||
PlanetSideGUID(-1)
|
||||
}
|
||||
val isNotSameTarget = resolvedPlayerGuid != guid
|
||||
reply match {
|
||||
case VehicleResponse.VehicleState(
|
||||
vehicleGuid,
|
||||
unk1,
|
||||
pos,
|
||||
orient,
|
||||
vel,
|
||||
unk2,
|
||||
unk3,
|
||||
unk4,
|
||||
wheelDirection,
|
||||
unk5,
|
||||
unk6
|
||||
) if isNotSameTarget && player.VehicleSeated.contains(vehicleGuid) =>
|
||||
//player who is also in the vehicle (not driver)
|
||||
sendResponse(VehicleStateMessage(vehicleGuid, unk1, pos, orient, vel, unk2, unk3, unk4, wheelDirection, unk5, unk6))
|
||||
player.Position = pos
|
||||
player.Orientation = orient
|
||||
player.Velocity = vel
|
||||
sessionLogic.updateLocalBlockMap(pos)
|
||||
//llu destruction check
|
||||
if (player.Carrying.contains(SpecialCarry.CaptureFlag)) {
|
||||
continent
|
||||
.GUID(player.VehicleSeated)
|
||||
.collect { case vehicle: Vehicle =>
|
||||
CaptureFlagManager.ReasonToLoseFlagViolently(continent, sessionLogic.general.specialItemSlotGuid, vehicle)
|
||||
}
|
||||
}
|
||||
|
||||
case VehicleResponse.VehicleState(
|
||||
vehicleGuid,
|
||||
unk1,
|
||||
pos,
|
||||
ang,
|
||||
vel,
|
||||
unk2,
|
||||
unk3,
|
||||
unk4,
|
||||
wheelDirection,
|
||||
unk5,
|
||||
unk6
|
||||
) if isNotSameTarget =>
|
||||
//player who is watching the vehicle from the outside
|
||||
sendResponse(VehicleStateMessage(vehicleGuid, unk1, pos, ang, vel, unk2, unk3, unk4, wheelDirection, unk5, unk6))
|
||||
|
||||
case VehicleResponse.ChildObjectState(objectGuid, pitch, yaw) if isNotSameTarget =>
|
||||
sendResponse(ChildObjectStateMessage(objectGuid, pitch, yaw))
|
||||
|
||||
case VehicleResponse.FrameVehicleState(vguid, u1, pos, oient, vel, u2, u3, u4, is_crouched, u6, u7, u8, u9, uA)
|
||||
if isNotSameTarget =>
|
||||
sendResponse(FrameVehicleStateMessage(vguid, u1, pos, oient, vel, u2, u3, u4, is_crouched, u6, u7, u8, u9, uA))
|
||||
|
||||
case VehicleResponse.ChangeFireState_Start(weaponGuid) if isNotSameTarget =>
|
||||
sendResponse(ChangeFireStateMessage_Start(weaponGuid))
|
||||
|
||||
case VehicleResponse.ChangeFireState_Stop(weaponGuid) if isNotSameTarget =>
|
||||
sendResponse(ChangeFireStateMessage_Stop(weaponGuid))
|
||||
|
||||
case VehicleResponse.Reload(itemGuid) if isNotSameTarget =>
|
||||
sendResponse(ReloadMessage(itemGuid, ammo_clip=1, unk1=0))
|
||||
|
||||
case VehicleResponse.ChangeAmmo(weapon_guid, weapon_slot, previous_guid, ammo_id, ammo_guid, ammo_data) if isNotSameTarget =>
|
||||
sendResponse(ObjectDetachMessage(weapon_guid, previous_guid, Vector3.Zero, 0))
|
||||
//TODO? sendResponse(ObjectDeleteMessage(previousAmmoGuid, 0))
|
||||
sendResponse(
|
||||
ObjectCreateMessage(
|
||||
ammo_id,
|
||||
ammo_guid,
|
||||
ObjectCreateMessageParent(weapon_guid, weapon_slot),
|
||||
ammo_data
|
||||
)
|
||||
)
|
||||
sendResponse(ChangeAmmoMessage(weapon_guid, 1))
|
||||
|
||||
case VehicleResponse.WeaponDryFire(weaponGuid) if isNotSameTarget =>
|
||||
continent.GUID(weaponGuid).collect {
|
||||
case tool: Tool if tool.Magazine == 0 =>
|
||||
// check that the magazine is still empty before sending WeaponDryFireMessage
|
||||
// if it has been reloaded since then, other clients will not see it firing
|
||||
sendResponse(WeaponDryFireMessage(weaponGuid))
|
||||
}
|
||||
|
||||
case VehicleResponse.DismountVehicle(bailType, wasKickedByDriver) if isNotSameTarget =>
|
||||
sendResponse(DismountVehicleMsg(guid, bailType, wasKickedByDriver))
|
||||
|
||||
case VehicleResponse.MountVehicle(vehicleGuid, seat) if isNotSameTarget =>
|
||||
sendResponse(ObjectAttachMessage(vehicleGuid, guid, seat))
|
||||
|
||||
case VehicleResponse.DeployRequest(objectGuid, state, unk1, unk2, pos) if isNotSameTarget =>
|
||||
sendResponse(DeployRequestMessage(guid, objectGuid, state, unk1, unk2, pos))
|
||||
|
||||
case VehicleResponse.SendResponse(msg) =>
|
||||
sendResponse(msg)
|
||||
|
||||
case VehicleResponse.AttachToRails(vehicleGuid, padGuid) =>
|
||||
sendResponse(ObjectAttachMessage(padGuid, vehicleGuid, slot=3))
|
||||
|
||||
case VehicleResponse.ConcealPlayer(playerGuid) =>
|
||||
sendResponse(GenericObjectActionMessage(playerGuid, code=9))
|
||||
|
||||
case VehicleResponse.DetachFromRails(vehicleGuid, padGuid, padPosition, padOrientationZ) =>
|
||||
val pad = continent.GUID(padGuid).get.asInstanceOf[VehicleSpawnPad].Definition
|
||||
sendResponse(
|
||||
ObjectDetachMessage(
|
||||
padGuid,
|
||||
vehicleGuid,
|
||||
padPosition + Vector3.z(pad.VehicleCreationZOffset),
|
||||
padOrientationZ + pad.VehicleCreationZOrientOffset
|
||||
)
|
||||
)
|
||||
|
||||
case VehicleResponse.EquipmentInSlot(pkt) if isNotSameTarget =>
|
||||
sendResponse(pkt)
|
||||
|
||||
case VehicleResponse.GenericObjectAction(objectGuid, action) if isNotSameTarget =>
|
||||
sendResponse(GenericObjectActionMessage(objectGuid, action))
|
||||
|
||||
case VehicleResponse.HitHint(sourceGuid) if player.isAlive =>
|
||||
sendResponse(HitHint(sourceGuid, player.GUID))
|
||||
|
||||
case VehicleResponse.InventoryState(obj, parentGuid, start, conData) if isNotSameTarget =>
|
||||
//TODO prefer ObjectDetachMessage, but how to force ammo pools to update properly?
|
||||
val objGuid = obj.GUID
|
||||
sendResponse(ObjectDeleteMessage(objGuid, unk1=0))
|
||||
sendResponse(ObjectCreateDetailedMessage(
|
||||
obj.Definition.ObjectId,
|
||||
objGuid,
|
||||
ObjectCreateMessageParent(parentGuid, start),
|
||||
conData
|
||||
))
|
||||
|
||||
case VehicleResponse.KickPassenger(_, wasKickedByDriver, vehicleGuid) if resolvedPlayerGuid == guid =>
|
||||
//seat number (first field) seems to be correct if passenger is kicked manually by driver
|
||||
//but always seems to return 4 if user is kicked by mount permissions changing
|
||||
sendResponse(DismountVehicleMsg(guid, BailType.Kicked, wasKickedByDriver))
|
||||
val typeOfRide = continent.GUID(vehicleGuid) match {
|
||||
case Some(obj: Vehicle) =>
|
||||
sessionLogic.general.unaccessContainer(obj)
|
||||
s"the ${obj.Definition.Name}'s seat by ${obj.OwnerName.getOrElse("the pilot")}"
|
||||
case _ =>
|
||||
s"${player.Sex.possessive} ride"
|
||||
}
|
||||
log.info(s"${player.Name} has been kicked from $typeOfRide!")
|
||||
player.WhichSide = OutsideOf
|
||||
|
||||
case VehicleResponse.KickPassenger(_, wasKickedByDriver, _) =>
|
||||
//seat number (first field) seems to be correct if passenger is kicked manually by driver
|
||||
//but always seems to return 4 if user is kicked by mount permissions changing
|
||||
sendResponse(DismountVehicleMsg(guid, BailType.Kicked, wasKickedByDriver))
|
||||
|
||||
case VehicleResponse.InventoryState2(objGuid, parentGuid, value) if isNotSameTarget =>
|
||||
sendResponse(InventoryStateMessage(objGuid, unk=0, parentGuid, value))
|
||||
|
||||
case VehicleResponse.LoadVehicle(vehicle, vtype, vguid, vdata) if isNotSameTarget =>
|
||||
//this is not be suitable for vehicles with people who are seated in it before it spawns (if that is possible)
|
||||
sendResponse(ObjectCreateMessage(vtype, vguid, vdata))
|
||||
Vehicles.ReloadAccessPermissions(vehicle, player.Name)
|
||||
|
||||
case VehicleResponse.ObjectDelete(itemGuid) if isNotSameTarget =>
|
||||
sendResponse(ObjectDeleteMessage(itemGuid, unk1=0))
|
||||
|
||||
case VehicleResponse.Ownership(vehicleGuid) if resolvedPlayerGuid == guid =>
|
||||
//Only the player that owns this vehicle needs the ownership packet
|
||||
avatarActor ! AvatarActor.SetVehicle(Some(vehicleGuid))
|
||||
sendResponse(PlanetsideAttributeMessage(resolvedPlayerGuid, attribute_type=21, vehicleGuid))
|
||||
|
||||
case VehicleResponse.LoseOwnership(_, vehicleGuid) =>
|
||||
ops.announceAmsDecay(vehicleGuid,msg = "@ams_decaystarted")
|
||||
|
||||
case VehicleResponse.PlanetsideAttribute(vehicleGuid, attributeType, attributeValue) if isNotSameTarget =>
|
||||
sendResponse(PlanetsideAttributeMessage(vehicleGuid, attributeType, attributeValue))
|
||||
|
||||
case VehicleResponse.ResetSpawnPad(padGuid) =>
|
||||
sendResponse(GenericObjectActionMessage(padGuid, code=23))
|
||||
|
||||
case VehicleResponse.RevealPlayer(playerGuid) =>
|
||||
sendResponse(GenericObjectActionMessage(playerGuid, code=10))
|
||||
|
||||
case VehicleResponse.SeatPermissions(vehicleGuid, seatGroup, permission) if isNotSameTarget =>
|
||||
sendResponse(PlanetsideAttributeMessage(vehicleGuid, seatGroup, permission))
|
||||
|
||||
case VehicleResponse.StowEquipment(vehicleGuid, slot, itemType, itemGuid, itemData) if isNotSameTarget =>
|
||||
//TODO prefer ObjectAttachMessage, but how to force ammo pools to update properly?
|
||||
sendResponse(ObjectCreateDetailedMessage(itemType, itemGuid, ObjectCreateMessageParent(vehicleGuid, slot), itemData))
|
||||
|
||||
case VehicleResponse.UnloadVehicle(_, vehicleGuid) =>
|
||||
sendResponse(ObjectDeleteMessage(vehicleGuid, unk1=1))
|
||||
if (sessionLogic.zoning.spawn.prevSpawnPoint.map(_.Owner).exists {
|
||||
case ams: Vehicle =>
|
||||
ams.GUID == vehicleGuid &&
|
||||
ams.OwnerGuid.isEmpty
|
||||
case _ =>
|
||||
false
|
||||
}) {
|
||||
sessionLogic.zoning.spawn.prevSpawnPoint = None
|
||||
sendResponse(ChatMsg(ChatMessageType.UNK_229, "@ams_decayed"))
|
||||
}
|
||||
|
||||
case VehicleResponse.UnstowEquipment(itemGuid) if isNotSameTarget =>
|
||||
//TODO prefer ObjectDetachMessage, but how to force ammo pools to update properly?
|
||||
sendResponse(ObjectDeleteMessage(itemGuid, unk1=0))
|
||||
|
||||
case VehicleResponse.UpdateAmsSpawnPoint(list) =>
|
||||
sessionLogic.zoning.spawn.amsSpawnPoints = list.filter(tube => tube.Faction == player.Faction)
|
||||
sessionLogic.zoning.spawn.DrawCurrentAmsSpawnPoint()
|
||||
|
||||
case VehicleResponse.TransferPassengerChannel(oldChannel, tempChannel, vehicle, vehicleToDelete) if isNotSameTarget =>
|
||||
sessionLogic.zoning.interstellarFerry = Some(vehicle)
|
||||
sessionLogic.zoning.interstellarFerryTopLevelGUID = Some(vehicleToDelete)
|
||||
continent.VehicleEvents ! Service.Leave(Some(oldChannel)) //old vehicle-specific channel (was s"${vehicle.Actor}")
|
||||
galaxyService ! Service.Join(tempChannel) //temporary vehicle-specific channel
|
||||
log.debug(s"TransferPassengerChannel: ${player.Name} now subscribed to $tempChannel for vehicle gating")
|
||||
|
||||
case VehicleResponse.KickCargo(vehicle, speed, delay)
|
||||
if player.VehicleSeated.nonEmpty && sessionLogic.zoning.spawn.deadState == DeadState.Alive && speed > 0 =>
|
||||
val strafe = 1 + Vehicles.CargoOrientation(vehicle)
|
||||
val reverseSpeed = if (strafe > 1) { 0 } else { speed }
|
||||
//strafe or reverse, not both
|
||||
sessionLogic.vehicles.ServerVehicleOverrideWithPacket(
|
||||
vehicle,
|
||||
ServerVehicleOverrideMsg(
|
||||
lock_accelerator=true,
|
||||
lock_wheel=true,
|
||||
reverse=true,
|
||||
unk4=false,
|
||||
lock_vthrust=0,
|
||||
strafe,
|
||||
reverseSpeed,
|
||||
unk8=Some(0)
|
||||
)
|
||||
)
|
||||
import scala.concurrent.ExecutionContext.Implicits.global
|
||||
import scala.concurrent.duration._
|
||||
context.system.scheduler.scheduleOnce(
|
||||
delay milliseconds,
|
||||
context.self,
|
||||
VehicleServiceResponse(toChannel, PlanetSideGUID(0), VehicleResponse.KickCargo(vehicle, speed=0, delay))
|
||||
)
|
||||
|
||||
case VehicleResponse.KickCargo(cargo, _, _)
|
||||
if player.VehicleSeated.nonEmpty && sessionLogic.zoning.spawn.deadState == DeadState.Alive =>
|
||||
sessionLogic.vehicles.TotalDriverVehicleControl(cargo)
|
||||
|
||||
case VehicleResponse.StartPlayerSeatedInVehicle(vehicle, _)
|
||||
if player.VisibleSlots.contains(player.DrawnSlot) =>
|
||||
player.DrawnSlot = Player.HandsDownSlot
|
||||
startPlayerSeatedInVehicle(vehicle)
|
||||
|
||||
case VehicleResponse.StartPlayerSeatedInVehicle(vehicle, _) =>
|
||||
startPlayerSeatedInVehicle(vehicle)
|
||||
|
||||
case VehicleResponse.PlayerSeatedInVehicle(vehicle, _) =>
|
||||
Vehicles.ReloadAccessPermissions(vehicle, player.Name)
|
||||
sessionLogic.vehicles.ServerVehicleOverrideWithPacket(
|
||||
vehicle,
|
||||
ServerVehicleOverrideMsg(
|
||||
lock_accelerator=true,
|
||||
lock_wheel=true,
|
||||
reverse=true,
|
||||
unk4=false,
|
||||
lock_vthrust=1,
|
||||
lock_strafe=0,
|
||||
movement_speed=0,
|
||||
unk8=Some(0)
|
||||
)
|
||||
)
|
||||
sessionLogic.vehicles.serverVehicleControlVelocity = Some(0)
|
||||
|
||||
case VehicleResponse.ServerVehicleOverrideStart(vehicle, _) =>
|
||||
val vdef = vehicle.Definition
|
||||
sessionLogic.vehicles.ServerVehicleOverrideWithPacket(
|
||||
vehicle,
|
||||
ServerVehicleOverrideMsg(
|
||||
lock_accelerator=true,
|
||||
lock_wheel=true,
|
||||
reverse=false,
|
||||
unk4=false,
|
||||
lock_vthrust=if (GlobalDefinitions.isFlightVehicle(vdef)) { 1 } else { 0 },
|
||||
lock_strafe=0,
|
||||
movement_speed=vdef.AutoPilotSpeed1,
|
||||
unk8=Some(0)
|
||||
)
|
||||
)
|
||||
|
||||
case VehicleResponse.ServerVehicleOverrideEnd(vehicle, _) =>
|
||||
sessionLogic.vehicles.ServerVehicleOverrideStop(vehicle)
|
||||
|
||||
case VehicleResponse.PeriodicReminder(VehicleSpawnPad.Reminders.Blocked, data) =>
|
||||
val str = s"${data.getOrElse("The vehicle spawn pad where you placed your order is blocked.")}"
|
||||
val msg = if (str.contains("@")) {
|
||||
ChatMsg(ChatMessageType.UNK_229, str)
|
||||
} else {
|
||||
ChatMsg(ChatMessageType.CMT_OPEN, wideContents = true, recipient = "", str, note = None)
|
||||
}
|
||||
sendResponse(msg)
|
||||
|
||||
case VehicleResponse.PeriodicReminder(_, data) =>
|
||||
val (isType, flag, msg): (ChatMessageType, Boolean, String) = data match {
|
||||
case Some(msg: String) if msg.startsWith("@") => (ChatMessageType.UNK_227, false, msg)
|
||||
case Some(msg: String) => (ChatMessageType.CMT_OPEN, true, msg)
|
||||
case _ => (ChatMessageType.CMT_OPEN, true, "Your vehicle order has been cancelled.")
|
||||
}
|
||||
sendResponse(ChatMsg(isType, flag, recipient="", msg, None))
|
||||
|
||||
case VehicleResponse.ChangeLoadout(target, oldWeapons, addedWeapons, oldInventory, newInventory)
|
||||
if player.avatar.vehicle.contains(target) =>
|
||||
//TODO when vehicle weapons can be changed without visual glitches, rewrite this
|
||||
continent.GUID(target).collect { case vehicle: Vehicle =>
|
||||
import net.psforever.login.WorldSession.boolToInt
|
||||
//owner: must unregister old equipment, and register and install new equipment
|
||||
(oldWeapons ++ oldInventory).foreach {
|
||||
case (obj, eguid) =>
|
||||
sendResponse(ObjectDeleteMessage(eguid, unk1=0))
|
||||
TaskWorkflow.execute(GUIDTask.unregisterEquipment(continent.GUID, obj))
|
||||
def receive: Receive = {
|
||||
case VehicleAction.VehicleState(
|
||||
vehicleGuid,
|
||||
unk1,
|
||||
pos,
|
||||
orient,
|
||||
vel,
|
||||
unk2,
|
||||
unk3,
|
||||
unk4,
|
||||
wheelDirection,
|
||||
unk5,
|
||||
unk6
|
||||
) if TestFilter(() => { NotSameTarget && player.VehicleSeated.contains(vehicleGuid) }) =>
|
||||
//player who is also in the vehicle (not driver)
|
||||
sendResponse(VehicleStateMessage(vehicleGuid, unk1, pos, orient, vel, unk2, unk3, unk4, wheelDirection, unk5, unk6))
|
||||
player.Position = pos
|
||||
player.Orientation = orient
|
||||
player.Velocity = vel
|
||||
sessionLogic.updateLocalBlockMap(pos)
|
||||
//llu destruction check
|
||||
if (player.Carrying.contains(SpecialCarry.CaptureFlag)) {
|
||||
continent
|
||||
.GUID(player.VehicleSeated)
|
||||
.collect { case vehicle: Vehicle =>
|
||||
CaptureFlagManager.ReasonToLoseFlagViolently(continent, sessionLogic.general.specialItemSlotGuid, vehicle)
|
||||
}
|
||||
sessionLogic.general.applyPurchaseTimersBeforePackingLoadout(player, vehicle, addedWeapons ++ newInventory)
|
||||
//jammer or unjamm new weapons based on vehicle status
|
||||
val vehicleJammered = vehicle.Jammed
|
||||
addedWeapons
|
||||
.map { _.obj }
|
||||
.collect {
|
||||
case jamItem: JammableUnit if jamItem.Jammed != vehicleJammered =>
|
||||
jamItem.Jammed = vehicleJammered
|
||||
JammableMountedWeapons.JammedWeaponStatus(vehicle.Zone, jamItem, vehicleJammered)
|
||||
}
|
||||
changeLoadoutDeleteOldEquipment(vehicle, oldWeapons, oldInventory)
|
||||
}
|
||||
}
|
||||
|
||||
case VehicleResponse.ChangeLoadout(target, oldWeapons, _, oldInventory, _)
|
||||
if sessionLogic.general.accessedContainer.map(_.GUID).contains(target) =>
|
||||
//TODO when vehicle weapons can be changed without visual glitches, rewrite this
|
||||
continent.GUID(target).collect { case vehicle: Vehicle =>
|
||||
//external participant: observe changes to equipment
|
||||
(oldWeapons ++ oldInventory).foreach { case (_, eguid) => sendResponse(ObjectDeleteMessage(eguid, unk1=0)) }
|
||||
changeLoadoutDeleteOldEquipment(vehicle, oldWeapons, oldInventory)
|
||||
}
|
||||
case VehicleAction.VehicleState(
|
||||
vehicleGuid,
|
||||
unk1,
|
||||
pos,
|
||||
ang,
|
||||
vel,
|
||||
unk2,
|
||||
unk3,
|
||||
unk4,
|
||||
wheelDirection,
|
||||
unk5,
|
||||
unk6
|
||||
) if TestFilter(NotSameTargetTest) =>
|
||||
//player who is watching the vehicle from the outside
|
||||
sendResponse(VehicleStateMessage(vehicleGuid, unk1, pos, ang, vel, unk2, unk3, unk4, wheelDirection, unk5, unk6))
|
||||
|
||||
case VehicleResponse.ChangeLoadout(target, oldWeapons, _, oldInventory, _) =>
|
||||
//TODO when vehicle weapons can be changed without visual glitches, rewrite this
|
||||
continent.GUID(target).collect { case vehicle: Vehicle =>
|
||||
changeLoadoutDeleteOldEquipment(vehicle, oldWeapons, oldInventory)
|
||||
}
|
||||
case VehicleAction.ChildObjectState(objectGuid, pitch, yaw)
|
||||
if TestFilter(NotSameTargetTest) =>
|
||||
sendResponse(ChildObjectStateMessage(objectGuid, pitch, yaw))
|
||||
|
||||
case _ => ()
|
||||
}
|
||||
case VehicleAction.FrameVehicleState(vguid, u1, pos, oient, vel, u2, u3, u4, is_crouched, u6, u7, u8, u9, uA)
|
||||
if TestFilter(NotSameTargetTest) =>
|
||||
sendResponse(FrameVehicleStateMessage(vguid, u1, pos, oient, vel, u2, u3, u4, is_crouched, u6, u7, u8, u9, uA))
|
||||
|
||||
case VehicleAction.DismountVehicle(bailType, wasKickedByDriver)
|
||||
if TestFilter(NotSameTargetTest) =>
|
||||
sendResponse(DismountVehicleMsg(FilterGuid, bailType, wasKickedByDriver))
|
||||
|
||||
case VehicleAction.MountVehicle(vehicleGuid, seat)
|
||||
if TestFilter(NotSameTargetTest) =>
|
||||
sendResponse(ObjectAttachMessage(vehicleGuid, FilterGuid, seat))
|
||||
|
||||
case VehicleAction.DeployRequest(objectGuid, state, unk1, unk2, pos)
|
||||
if TestFilter(NotSameTargetTest) =>
|
||||
sendResponse(DeployRequestMessage(FilterGuid, objectGuid, state, unk1, unk2, pos))
|
||||
|
||||
case VehicleAction.EquipmentCreatedInSlot(pkt)
|
||||
if TestFilter(NotSameTargetTest) =>
|
||||
sendResponse(pkt)
|
||||
|
||||
case VehicleAction.InventoryState(obj, parentGuid, start, conData)
|
||||
if TestFilter(NotSameTargetTest) =>
|
||||
//TODO prefer ObjectDetachMessage, but how to force ammo pools to update properly?
|
||||
val objGuid = obj.GUID
|
||||
sendResponse(ObjectDeleteMessage(objGuid, unk1=0))
|
||||
sendResponse(ObjectCreateDetailedMessage(
|
||||
obj.Definition.ObjectId,
|
||||
objGuid,
|
||||
ObjectCreateMessageParent(parentGuid, start),
|
||||
conData
|
||||
))
|
||||
|
||||
case VehicleAction.KickPassenger(_, wasKickedByDriver, vehicleGuid)
|
||||
if TestFilter(SameTargetTest) =>
|
||||
//seat number (first field) seems to be correct if passenger is kicked manually by driver
|
||||
//but always seems to return 4 if user is kicked by mount permissions changing
|
||||
sendResponse(DismountVehicleMsg(FilterGuid, BailType.Kicked, wasKickedByDriver))
|
||||
val typeOfRide = continent.GUID(vehicleGuid) match {
|
||||
case Some(obj: Vehicle) =>
|
||||
sessionLogic.general.unaccessContainer(obj)
|
||||
s"the ${obj.Definition.Name}'s seat by ${obj.OwnerName.getOrElse("the pilot")}"
|
||||
case _ =>
|
||||
s"${player.Sex.possessive} ride"
|
||||
}
|
||||
log.info(s"${player.Name} has been kicked from $typeOfRide!")
|
||||
player.WhichSide = OutsideOf
|
||||
|
||||
case VehicleAction.KickPassenger(_, wasKickedByDriver, _) =>
|
||||
//seat number (first field) seems to be correct if passenger is kicked manually by driver
|
||||
//but always seems to return 4 if user is kicked by mount permissions changing
|
||||
sendResponse(DismountVehicleMsg(FilterGuid, BailType.Kicked, wasKickedByDriver))
|
||||
|
||||
case VehicleAction.InventoryState2(objGuid, parentGuid, value)
|
||||
if TestFilter(NotSameTargetTest) =>
|
||||
sendResponse(InventoryStateMessage(objGuid, unk=0, parentGuid, value))
|
||||
|
||||
case VehicleAction.LoadVehicle(vehicle, vtype, vguid, vdata)
|
||||
if TestFilter(NotSameTargetTest) =>
|
||||
//this is not be suitable for vehicles with people who are seated in it before it spawns (if that is possible)
|
||||
sendResponse(ObjectCreateMessage(vtype, vguid, vdata))
|
||||
Vehicles.ReloadAccessPermissions(vehicle, player.Name)
|
||||
|
||||
case VehicleAction.Ownership(vehicleGuid)
|
||||
if TestFilter(SameTargetTest) =>
|
||||
//Only the player that owns this vehicle needs the ownership packet
|
||||
avatarActor ! AvatarActor.SetVehicle(Some(vehicleGuid))
|
||||
sendResponse(PlanetsideAttributeMessage(ResolvedGuid, attribute_type=21, vehicleGuid))
|
||||
|
||||
case VehicleAction.LoseOwnership(_, vehicleGuid) =>
|
||||
ops.announceAmsDecay(vehicleGuid,msg = "@ams_decaystarted")
|
||||
|
||||
case VehicleAction.SeatPermissions(vehicleGuid, seatGroup, permission)
|
||||
if TestFilter(NotSameTargetTest) =>
|
||||
sendResponse(PlanetsideAttributeMessage(vehicleGuid, seatGroup, permission))
|
||||
|
||||
case VehicleAction.StowCreatedEquipment(vehicleGuid, slot, itemType, itemGuid, itemData)
|
||||
if TestFilter(NotSameTargetTest) =>
|
||||
//TODO prefer ObjectAttachMessage, but how to force ammo pools to update properly?
|
||||
sendResponse(ObjectCreateDetailedMessage(itemType, itemGuid, ObjectCreateMessageParent(vehicleGuid, slot), itemData))
|
||||
|
||||
case VehicleAction.UnloadVehicle(_, vehicleGuid) =>
|
||||
sendResponse(ObjectDeleteMessage(vehicleGuid, unk1=1))
|
||||
if (sessionLogic.zoning.spawn.prevSpawnPoint.map(_.Owner).exists {
|
||||
case ams: Vehicle =>
|
||||
ams.GUID == vehicleGuid &&
|
||||
ams.OwnerGuid.isEmpty
|
||||
case _ =>
|
||||
false
|
||||
}) {
|
||||
sessionLogic.zoning.spawn.prevSpawnPoint = None
|
||||
sendResponse(ChatMsg(ChatMessageType.UNK_229, "@ams_decayed"))
|
||||
}
|
||||
|
||||
case VehicleAction.UnstowEquipment(itemGuid)
|
||||
if TestFilter(NotSameTargetTest) =>
|
||||
//TODO prefer ObjectDetachMessage, but how to force ammo pools to update properly?
|
||||
sendResponse(ObjectDeleteMessage(itemGuid, unk1=0))
|
||||
|
||||
case VehicleAction.UpdateAmsSpawnList(list) =>
|
||||
sessionLogic.zoning.spawn.amsSpawnPoints = list.filter(tube => tube.Faction == player.Faction)
|
||||
sessionLogic.zoning.spawn.DrawCurrentAmsSpawnPoint()
|
||||
|
||||
case VehicleAction.TransferPassengerChannel(oldChannel, tempChannel, vehicle, vehicleToDelete)
|
||||
if TestFilter(NotSameTargetTest) =>
|
||||
sessionLogic.zoning.interstellarFerry = Some(vehicle)
|
||||
sessionLogic.zoning.interstellarFerryTopLevelGUID = Some(vehicleToDelete)
|
||||
continent.VehicleEvents ! Service.Leave(oldChannel) //old vehicle-specific channel (was s"${vehicle.Actor}")
|
||||
galaxyService ! Service.Join(tempChannel) //temporary vehicle-specific channel
|
||||
log.debug(s"TransferPassengerChannel: ${player.Name} now subscribed to $tempChannel for vehicle gating")
|
||||
|
||||
case VehicleAction.KickCargo(vehicle, speed, delay)
|
||||
if TestFilter(() => { player.VehicleSeated.nonEmpty && sessionLogic.zoning.spawn.deadState == DeadState.Alive && speed > 0 }) =>
|
||||
val strafe = 1 + Vehicles.CargoOrientation(vehicle)
|
||||
val reverseSpeed = if (strafe > 1) { 0 } else { speed }
|
||||
//strafe or reverse, not both
|
||||
sessionLogic.vehicles.ServerVehicleOverrideWithPacket(
|
||||
vehicle,
|
||||
ServerVehicleOverrideMsg(
|
||||
lock_accelerator=true,
|
||||
lock_wheel=true,
|
||||
reverse=true,
|
||||
unk4=false,
|
||||
lock_vthrust=0,
|
||||
strafe,
|
||||
reverseSpeed,
|
||||
unk8=Some(0)
|
||||
)
|
||||
)
|
||||
import scala.concurrent.ExecutionContext.Implicits.global
|
||||
import scala.concurrent.duration._
|
||||
val resp = GenericResponseEnvelope(
|
||||
VehicleStamp,
|
||||
"",
|
||||
PlanetSideGUID(0),
|
||||
VehicleAction.KickCargo(vehicle, speed=0, delay)
|
||||
)
|
||||
context.system.scheduler.scheduleOnce(delay milliseconds, context.self, resp)
|
||||
|
||||
case VehicleAction.KickCargo(cargo, _, _)
|
||||
if TestFilter(() => { player.VehicleSeated.nonEmpty && sessionLogic.zoning.spawn.deadState == DeadState.Alive }) =>
|
||||
sessionLogic.vehicles.TotalDriverVehicleControl(cargo)
|
||||
|
||||
case VehicleAction.ChangeLoadout(target, oldWeapons, addedWeapons, oldInventory, newInventory)
|
||||
if TestFilter(() => { player.avatar.vehicle.contains(target) }) =>
|
||||
//TODO when vehicle weapons can be changed without visual glitches, rewrite this
|
||||
continent.GUID(target).collect { case vehicle: Vehicle =>
|
||||
import net.psforever.login.WorldSession.boolToInt
|
||||
//owner: must unregister old equipment, and register and install new equipment
|
||||
(oldWeapons ++ oldInventory).foreach {
|
||||
case (obj, eguid) =>
|
||||
sendResponse(ObjectDeleteMessage(eguid, unk1=0))
|
||||
TaskWorkflow.execute(GUIDTask.unregisterEquipment(continent.GUID, obj))
|
||||
}
|
||||
sessionLogic.general.applyPurchaseTimersBeforePackingLoadout(player, vehicle, addedWeapons ++ newInventory)
|
||||
//jammer or unjamm new weapons based on vehicle status
|
||||
val vehicleJammered = vehicle.Jammed
|
||||
addedWeapons
|
||||
.map { _.obj }
|
||||
.collect {
|
||||
case jamItem: JammableUnit if jamItem.Jammed != vehicleJammered =>
|
||||
jamItem.Jammed = vehicleJammered
|
||||
JammableMountedWeapons.JammedWeaponStatus(vehicle.Zone, jamItem, vehicleJammered)
|
||||
}
|
||||
changeLoadoutDeleteOldEquipment(vehicle, oldWeapons, oldInventory)
|
||||
}
|
||||
|
||||
case VehicleAction.ChangeLoadout(target, oldWeapons, _, oldInventory, _)
|
||||
if TestFilter(() => { sessionLogic.general.accessedContainer.map(_.GUID).contains(target) }) =>
|
||||
//TODO when vehicle weapons can be changed without visual glitches, rewrite this
|
||||
continent.GUID(target).collect { case vehicle: Vehicle =>
|
||||
//external participant: observe changes to equipment
|
||||
(oldWeapons ++ oldInventory).foreach { case (_, eguid) => sendResponse(ObjectDeleteMessage(eguid, unk1=0)) }
|
||||
changeLoadoutDeleteOldEquipment(vehicle, oldWeapons, oldInventory)
|
||||
}
|
||||
|
||||
case VehicleAction.ChangeLoadout(target, oldWeapons, _, oldInventory, _) =>
|
||||
//TODO when vehicle weapons can be changed without visual glitches, rewrite this
|
||||
continent.GUID(target).collect { case vehicle: Vehicle =>
|
||||
changeLoadoutDeleteOldEquipment(vehicle, oldWeapons, oldInventory)
|
||||
}
|
||||
|
||||
case VehicleSpawnPad.AttachToRails(vehicle, pad) =>
|
||||
sendResponse(ObjectAttachMessage(pad.GUID, vehicle.GUID, slot=3))
|
||||
|
||||
case VehicleSpawnPad.ConcealPlayer(playerGuid) =>
|
||||
sendResponse(GenericObjectActionMessage(playerGuid, code=9))
|
||||
|
||||
case VehicleSpawnPad.DetachFromRails(vehicle, pad) =>
|
||||
val padDefinition = pad.Definition
|
||||
sendResponse(
|
||||
ObjectDetachMessage(
|
||||
pad.GUID,
|
||||
vehicle.GUID,
|
||||
pad.Position + Vector3.z(padDefinition.VehicleCreationZOffset),
|
||||
pad.Orientation.z + padDefinition.VehicleCreationZOrientOffset
|
||||
)
|
||||
)
|
||||
|
||||
case VehicleSpawnPad.ResetSpawnPad(pad) =>
|
||||
sendResponse(GenericObjectActionMessage(pad.GUID, code=23))
|
||||
|
||||
case VehicleSpawnPad.RevealPlayer(playerGuid) =>
|
||||
sendResponse(GenericObjectActionMessage(playerGuid, code=10))
|
||||
|
||||
case VehicleSpawnPad.StartPlayerSeatedInVehicle(vehicle, _)
|
||||
if TestFilter(() => { player.VisibleSlots.contains(player.DrawnSlot) }) =>
|
||||
player.DrawnSlot = Player.HandsDownSlot
|
||||
startPlayerSeatedInVehicle(vehicle)
|
||||
|
||||
case VehicleSpawnPad.StartPlayerSeatedInVehicle(vehicle, _) =>
|
||||
startPlayerSeatedInVehicle(vehicle)
|
||||
|
||||
case VehicleSpawnPad.PlayerSeatedInVehicle(vehicle, _) =>
|
||||
Vehicles.ReloadAccessPermissions(vehicle, player.Name)
|
||||
sessionLogic.vehicles.ServerVehicleOverrideWithPacket(
|
||||
vehicle,
|
||||
ServerVehicleOverrideMsg(
|
||||
lock_accelerator=true,
|
||||
lock_wheel=true,
|
||||
reverse=true,
|
||||
unk4=false,
|
||||
lock_vthrust=1,
|
||||
lock_strafe=0,
|
||||
movement_speed=0,
|
||||
unk8=Some(0)
|
||||
)
|
||||
)
|
||||
sessionLogic.vehicles.serverVehicleControlVelocity = Some(0)
|
||||
|
||||
case VehicleSpawnPad.ServerVehicleOverrideStart(vehicle, _) =>
|
||||
val vdef = vehicle.Definition
|
||||
sessionLogic.vehicles.ServerVehicleOverrideWithPacket(
|
||||
vehicle,
|
||||
ServerVehicleOverrideMsg(
|
||||
lock_accelerator=true,
|
||||
lock_wheel=true,
|
||||
reverse=false,
|
||||
unk4=false,
|
||||
lock_vthrust=if (GlobalDefinitions.isFlightVehicle(vdef)) { 1 } else { 0 },
|
||||
lock_strafe=0,
|
||||
movement_speed=vdef.AutoPilotSpeed1,
|
||||
unk8=Some(0)
|
||||
)
|
||||
)
|
||||
|
||||
case VehicleSpawnPad.ServerVehicleOverrideEnd(vehicle, _) =>
|
||||
sessionLogic.vehicles.ServerVehicleOverrideStop(vehicle)
|
||||
|
||||
case VehicleSpawnPad.PeriodicReminder(VehicleSpawnPad.Reminders.Blocked, data) =>
|
||||
val str = s"${data.getOrElse("The vehicle spawn pad where you placed your order is blocked.")}"
|
||||
val msg = if (str.contains("@")) {
|
||||
ChatMsg(ChatMessageType.UNK_229, str)
|
||||
} else {
|
||||
ChatMsg(ChatMessageType.CMT_OPEN, wideContents = true, recipient = "", str, note = None)
|
||||
}
|
||||
sendResponse(msg)
|
||||
|
||||
case VehicleSpawnPad.PeriodicReminder(_, data) =>
|
||||
val (isType, flag, msg): (ChatMessageType, Boolean, String) = data match {
|
||||
case Some(msg: String) if msg.startsWith("@") => (ChatMessageType.UNK_227, false, msg)
|
||||
case Some(msg: String) => (ChatMessageType.CMT_OPEN, true, msg)
|
||||
case _ => (ChatMessageType.CMT_OPEN, true, "Your vehicle order has been cancelled.")
|
||||
}
|
||||
sendResponse(ChatMsg(isType, flag, recipient="", msg, None))
|
||||
}
|
||||
|
||||
private def changeLoadoutDeleteOldEquipment(
|
||||
|
|
|
|||
|
|
@ -12,7 +12,9 @@ import net.psforever.objects.vehicles.control.BfrFlight
|
|||
import net.psforever.objects.zones.Zone
|
||||
import net.psforever.objects.zones.interaction.InteractsWithZone
|
||||
import net.psforever.packet.game.{ChatMsg, ChildObjectStateMessage, DeployRequestMessage, FrameVehicleStateMessage, VehicleStateMessage, VehicleSubStateMessage}
|
||||
import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage}
|
||||
import net.psforever.services.base.CachedEnvelope
|
||||
import net.psforever.services.base.envelope.MessageEnvelope
|
||||
import net.psforever.services.vehicle.VehicleAction
|
||||
import net.psforever.types.{ChatMessageType, DriveState, Vector3}
|
||||
|
||||
object VehicleLogic {
|
||||
|
|
@ -75,10 +77,10 @@ class VehicleLogic(val ops: VehicleOperations, implicit val context: ActorContex
|
|||
obj.Position = position
|
||||
obj.Orientation = angle
|
||||
//
|
||||
continent.VehicleEvents ! VehicleServiceMessage(
|
||||
continent.VehicleEvents ! CachedEnvelope(
|
||||
continent.id,
|
||||
player.GUID,
|
||||
VehicleAction.VehicleState(
|
||||
player.GUID,
|
||||
vehicle_guid,
|
||||
unk1,
|
||||
position,
|
||||
|
|
@ -162,26 +164,11 @@ class VehicleLogic(val ops: VehicleOperations, implicit val context: ActorContex
|
|||
obj.Position = position
|
||||
obj.Orientation = angle
|
||||
obj.DeploymentState = if (is_crouched || !notMountedState) DriveState.Kneeling else DriveState.Mobile
|
||||
continent.VehicleEvents ! VehicleServiceMessage(
|
||||
continent.VehicleEvents ! MessageEnvelope(
|
||||
continent.id,
|
||||
VehicleAction.FrameVehicleState(
|
||||
player.GUID,
|
||||
vehicle_guid,
|
||||
unk1,
|
||||
position,
|
||||
angle,
|
||||
velocity,
|
||||
unk2,
|
||||
unk3,
|
||||
unk4,
|
||||
is_crouched,
|
||||
is_airborne,
|
||||
ascending_flight,
|
||||
flight_time,
|
||||
unk9,
|
||||
unkA
|
||||
)
|
||||
)
|
||||
player.GUID,
|
||||
VehicleAction.FrameVehicleState(vehicle_guid, unk1, position, angle, velocity, unk2, unk3, unk4, is_crouched, is_airborne, ascending_flight, flight_time, unk9, unkA)
|
||||
) //todo CachedMessage
|
||||
sessionLogic.squad.updateSquad()
|
||||
case (None, _) =>
|
||||
//log.error(s"VehicleState: no vehicle $vehicle_guid found in zone")
|
||||
|
|
@ -230,10 +217,11 @@ class VehicleLogic(val ops: VehicleOperations, implicit val context: ActorContex
|
|||
val angle = Vector3(0f, pitch, yaw)
|
||||
tool.Orientation = angle
|
||||
player.Orientation = angle
|
||||
continent.VehicleEvents ! VehicleServiceMessage(
|
||||
continent.VehicleEvents ! MessageEnvelope(
|
||||
continent.id,
|
||||
VehicleAction.ChildObjectState(player.GUID, object_guid, pitch, yaw)
|
||||
)
|
||||
player.GUID,
|
||||
VehicleAction.ChildObjectState(object_guid, pitch, yaw)
|
||||
) //todo CachedMessage
|
||||
}
|
||||
//TODO status condition of "playing getting out of vehicle to allow for late packets without warning
|
||||
if (player.death_by == -1) {
|
||||
|
|
@ -252,22 +240,10 @@ class VehicleLogic(val ops: VehicleOperations, implicit val context: ActorContex
|
|||
obj.Velocity = vel
|
||||
sessionLogic.updateBlockMap(obj, pos)
|
||||
obj.zoneInteractions()
|
||||
continent.VehicleEvents ! VehicleServiceMessage(
|
||||
continent.VehicleEvents ! CachedEnvelope(
|
||||
continent.id,
|
||||
VehicleAction.VehicleState(
|
||||
player.GUID,
|
||||
vehicle_guid,
|
||||
unk1,
|
||||
pos,
|
||||
ang,
|
||||
obj.Velocity,
|
||||
obj.Flying,
|
||||
0,
|
||||
0,
|
||||
15,
|
||||
unk5 = false,
|
||||
obj.Cloaked
|
||||
)
|
||||
player.GUID,
|
||||
VehicleAction.VehicleState(vehicle_guid, unk1, pos, ang, obj.Velocity, obj.Flying, 0, 0, 15, unk5 = false, obj.Cloaked)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -346,9 +322,10 @@ class VehicleLogic(val ops: VehicleOperations, implicit val context: ActorContex
|
|||
val mobileShift: String = if (obj.DeploymentState != DriveState.Mobile) {
|
||||
obj.DeploymentState = DriveState.Mobile
|
||||
sendResponse(DeployRequestMessage(player.GUID, obj.GUID, DriveState.Mobile, 0, unk3=false, Vector3.Zero))
|
||||
continent.VehicleEvents ! VehicleServiceMessage(
|
||||
continent.VehicleEvents ! MessageEnvelope(
|
||||
continent.id,
|
||||
VehicleAction.DeployRequest(player.GUID, obj.GUID, DriveState.Mobile, 0, unk2=false, Vector3.Zero)
|
||||
player.GUID,
|
||||
VehicleAction.DeployRequest(obj.GUID, DriveState.Mobile, 0, unk2=false, Vector3.Zero)
|
||||
)
|
||||
"; enforcing Mobile deployment state"
|
||||
} else {
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -16,7 +16,10 @@ import net.psforever.objects.zones.ZoneProjectile
|
|||
import net.psforever.packet.PlanetSideGamePacket
|
||||
import net.psforever.packet.game.{ActionCancelMessage, AvatarFirstTimeEventMessage, AvatarImplantMessage, AvatarJumpMessage, BattleplanMessage, BindPlayerMessage, BugReportMessage, ChangeFireModeMessage, ChangeShortcutBankMessage, CharacterCreateRequestMessage, CharacterRequestMessage, CollisionIs, ConnectToWorldRequestMessage, CreateShortcutMessage, DeployObjectMessage, DisplayedAwardMessage, DropItemMessage, EmoteMsg, FacilityBenefitShieldChargeRequestMessage, FriendsRequest, GenericAction, GenericActionMessage, GenericCollisionMsg, GenericObjectActionAtPositionMessage, GenericObjectActionMessage, GenericObjectStateMsg, HitHint, ImplantAction, InvalidTerrainMessage, LootItemMessage, MoveItemMessage, ObjectDetectedMessage, ObjectHeldMessage, OutfitMembershipRequest, OutfitMembershipResponse, OutfitRequest, PickupItemMessage, PlanetsideAttributeMessage, PlayerStateMessageUpstream, RequestDestroyMessage, TargetingImplantRequest, TradeMessage, UnuseItemMessage, UseItemMessage, VoiceHostInfo, VoiceHostRequest, ZipLineMessage}
|
||||
import net.psforever.services.account.AccountPersistenceService
|
||||
import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage}
|
||||
import net.psforever.services.avatar.AvatarAction
|
||||
import net.psforever.services.base.CachedEnvelope
|
||||
import net.psforever.services.base.envelope.MessageEnvelope
|
||||
import net.psforever.services.base.message.PlanetsideAttribute
|
||||
import net.psforever.types.{ExoSuitType, Vector3}
|
||||
|
||||
import scala.concurrent.duration.DurationInt
|
||||
|
|
@ -74,10 +77,10 @@ class GeneralLogic(val ops: GeneralOperations, implicit val context: ActorContex
|
|||
player.Crouching = isCrouching
|
||||
player.Jumping = isJumping
|
||||
player.Cloaked = player.ExoSuit == ExoSuitType.Infiltration && isCloaking
|
||||
continent.AvatarEvents ! AvatarServiceMessage(
|
||||
continent.AvatarEvents ! CachedEnvelope(
|
||||
"spectator",
|
||||
avatarGuid,
|
||||
AvatarAction.PlayerState(
|
||||
avatarGuid,
|
||||
player.Position,
|
||||
player.Velocity,
|
||||
yaw,
|
||||
|
|
@ -106,8 +109,7 @@ class GeneralLogic(val ops: GeneralOperations, implicit val context: ActorContex
|
|||
}
|
||||
|
||||
def handleEmote(pkt: EmoteMsg): Unit = {
|
||||
val EmoteMsg(avatarGuid, emote) = pkt
|
||||
sendResponse(EmoteMsg(avatarGuid, emote))
|
||||
sendResponse(pkt)
|
||||
}
|
||||
|
||||
def handleDropItem(pkt: DropItemMessage): Unit = { /* intentionally blank */ }
|
||||
|
|
@ -228,9 +230,10 @@ class GeneralLogic(val ops: GeneralOperations, implicit val context: ActorContex
|
|||
case GenericAction.MaxAnchorsExtend_RCV =>
|
||||
log.info(s"${player.Name} has anchored ${player.Sex.pronounObject}self to the ground")
|
||||
player.UsingSpecial = SpecialExoSuitDefinition.Mode.Anchored
|
||||
continent.AvatarEvents ! AvatarServiceMessage(
|
||||
continent.AvatarEvents ! MessageEnvelope(
|
||||
continent.id,
|
||||
AvatarAction.PlanetsideAttribute(player.GUID, 19, 1)
|
||||
player.GUID,
|
||||
PlanetsideAttribute(player.GUID, 19, 1)
|
||||
)
|
||||
definition match {
|
||||
case GlobalDefinitions.trhev_dualcycler | GlobalDefinitions.trhev_burster =>
|
||||
|
|
@ -249,9 +252,10 @@ class GeneralLogic(val ops: GeneralOperations, implicit val context: ActorContex
|
|||
case GenericAction.MaxAnchorsRelease_RCV =>
|
||||
log.info(s"${player.Name} has released the anchors")
|
||||
player.UsingSpecial = SpecialExoSuitDefinition.Mode.Normal
|
||||
continent.AvatarEvents ! AvatarServiceMessage(
|
||||
continent.AvatarEvents ! MessageEnvelope(
|
||||
continent.id,
|
||||
AvatarAction.PlanetsideAttribute(player.GUID, 19, 0)
|
||||
player.GUID,
|
||||
PlanetsideAttribute(player.GUID, 19, 0)
|
||||
)
|
||||
definition match {
|
||||
case GlobalDefinitions.trhev_dualcycler | GlobalDefinitions.trhev_burster =>
|
||||
|
|
|
|||
|
|
@ -12,9 +12,9 @@ import net.psforever.objects.serverobject.mount.Mountable
|
|||
import net.psforever.objects.serverobject.terminals.implant.ImplantTerminalMech
|
||||
import net.psforever.objects.vital.InGameHistory
|
||||
import net.psforever.packet.game.{DelayedPathMountMsg, DismountVehicleCargoMsg, DismountVehicleMsg, GenericObjectActionMessage, MountVehicleCargoMsg, MountVehicleMsg, ObjectDetachMessage, PlayerStasisMessage, PlayerStateShiftMessage, ShiftState}
|
||||
import net.psforever.services.Service
|
||||
import net.psforever.services.local.{LocalAction, LocalServiceMessage}
|
||||
import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage}
|
||||
import net.psforever.services.base.envelope.{BundledEnvelope, MessageEnvelope}
|
||||
import net.psforever.services.base.message.SendResponse
|
||||
import net.psforever.services.vehicle.VehicleAction
|
||||
|
||||
object MountHandlerLogic {
|
||||
def apply(ops: SessionMountHandlers): MountHandlerLogic = {
|
||||
|
|
@ -61,9 +61,9 @@ class MountHandlerLogic(val ops: SessionMountHandlers, implicit val context: Act
|
|||
val (pos, zang) = Vehicles.dismountShuttle(obj, mountPoint)
|
||||
tplayer.Position = pos
|
||||
sendResponse(DelayedPathMountMsg(pguid, sguid, u1=60, u2=true))
|
||||
continent.LocalEvents ! LocalServiceMessage(
|
||||
continent.LocalEvents ! MessageEnvelope(
|
||||
continent.id,
|
||||
LocalAction.SendResponse(ObjectDetachMessage(sguid, pguid, pos, roll=0, pitch=0, zang))
|
||||
SendResponse(ObjectDetachMessage(sguid, pguid, pos, roll=0, pitch=0, zang))
|
||||
)
|
||||
obj.Zone.actor ! ZoneActor.RemoveFromBlockMap(player)
|
||||
sessionLogic.keepAliveFunc = sessionLogic.zoning.NormalKeepAlive
|
||||
|
|
@ -76,25 +76,21 @@ class MountHandlerLogic(val ops: SessionMountHandlers, implicit val context: Act
|
|||
ops.DismountAction(tplayer, obj, seatNum)
|
||||
continent.actor ! ZoneActor.RemoveFromBlockMap(player) //character doesn't need it
|
||||
//DismountAction(...) uses vehicle service, so use that service to coordinate the remainder of the messages
|
||||
events ! VehicleServiceMessage(
|
||||
player.Name,
|
||||
VehicleAction.SendResponse(Service.defaultPlayerGUID, PlayerStasisMessage(pguid)) //the stasis message
|
||||
)
|
||||
//when the player dismounts, they will be positioned where the shuttle was when it disappeared in the sky
|
||||
//the player will fall to the ground and is perfectly vulnerable in this state
|
||||
//additionally, our player must exist in the current zone
|
||||
//having no in-game avatar target will throw us out of the map screen when deploying and cause softlock
|
||||
events ! VehicleServiceMessage(
|
||||
player.Name,
|
||||
VehicleAction.SendResponse(
|
||||
Service.defaultPlayerGUID,
|
||||
PlayerStateShiftMessage(ShiftState(unk=0, obj.Position, obj.Orientation.z, vel=None)) //cower in the shuttle bay
|
||||
events ! BundledEnvelope(
|
||||
MessageEnvelope(player.Name,
|
||||
SendResponse(Seq(
|
||||
PlayerStasisMessage(pguid),
|
||||
PlayerStateShiftMessage(ShiftState(unk=0, obj.Position, obj.Orientation.z, vel=None))
|
||||
))
|
||||
),
|
||||
MessageEnvelope(continent.id, pguid,
|
||||
SendResponse(GenericObjectActionMessage(pguid, code=9)) /* conceal the player */
|
||||
)
|
||||
)
|
||||
events ! VehicleServiceMessage(
|
||||
continent.id,
|
||||
VehicleAction.SendResponse(pguid, GenericObjectActionMessage(pguid, code=9)) //conceal the player
|
||||
)
|
||||
context.self ! SessionActor.SetMode(NormalMode)
|
||||
sessionLogic.keepAliveFunc = sessionLogic.zoning.NormalKeepAlive
|
||||
|
||||
|
|
@ -111,9 +107,10 @@ class MountHandlerLogic(val ops: SessionMountHandlers, implicit val context: Act
|
|||
ops.DismountVehicleAction(tplayer, obj, seatNum)
|
||||
|
||||
case Mountable.CanDismount(obj: Vehicle, seat_num, _) =>
|
||||
continent.VehicleEvents ! VehicleServiceMessage(
|
||||
continent.VehicleEvents ! MessageEnvelope(
|
||||
continent.id,
|
||||
VehicleAction.KickPassenger(tplayer.GUID, seat_num, unk2=true, obj.GUID)
|
||||
tplayer.GUID,
|
||||
VehicleAction.KickPassenger(seat_num, unk2=true, obj.GUID)
|
||||
)
|
||||
|
||||
case Mountable.CanDismount(obj: PlanetSideGameObject with PlanetSideGameObject with Mountable with FactionAffinity with InGameHistory, seatNum, _) =>
|
||||
|
|
|
|||
|
|
@ -6,12 +6,12 @@ import net.psforever.actors.zone.ZoneActor
|
|||
import net.psforever.objects.avatar.{BattleRank, CommandRank, DeployableToolbox, FirstTimeEvents, Implant, ProgressDecoration, Shortcut => AvatarShortcut}
|
||||
import net.psforever.objects.ce.Deployable
|
||||
import net.psforever.objects.serverobject.ServerObject
|
||||
import net.psforever.objects.{GlobalDefinitions, Player, Session, SimpleItem, Vehicle}
|
||||
import net.psforever.objects.{Default, GlobalDefinitions, Player, Session, SimpleItem, Vehicle}
|
||||
import net.psforever.packet.PlanetSidePacket
|
||||
import net.psforever.packet.game.{DeployableInfo, DeployableObjectsInfoMessage, DeploymentAction, ObjectCreateDetailedMessage, ObjectDeleteMessage}
|
||||
import net.psforever.packet.game.objectcreate.{ObjectClass, ObjectCreateMessageParent, RibbonBars}
|
||||
import net.psforever.services.Service
|
||||
import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage}
|
||||
import net.psforever.services.base.envelope.MessageEnvelope
|
||||
import net.psforever.services.base.message.ObjectDelete
|
||||
import net.psforever.services.chat.SpectatorChannel
|
||||
import net.psforever.services.teamwork.{SquadAction, SquadServiceMessage}
|
||||
import net.psforever.types.{CapacitorStateType, ChatMessageType, ExoSuitType, MeritCommendation, SquadRequestType}
|
||||
|
|
@ -68,7 +68,7 @@ class SpectatorModeLogic(data: SessionData) extends ModeLogic {
|
|||
player.Inventory.Items
|
||||
.foreach { entry => sendResponse(ObjectDeleteMessage(entry.GUID, 0)) }
|
||||
sendResponse(ObjectDeleteMessage(player.avatar.locker.GUID, 0))
|
||||
continent.AvatarEvents ! AvatarServiceMessage(continent.id, AvatarAction.ObjectDelete(pguid, pguid))
|
||||
continent.AvatarEvents ! MessageEnvelope(continent.id, pguid, ObjectDelete(pguid))
|
||||
player.Holsters()
|
||||
.collect { case slot if slot.Equipment.nonEmpty => sendResponse(ObjectDeleteMessage(slot.Equipment.get.GUID, 0)) }
|
||||
val vehicleAndSeat = data.vehicles.GetMountableAndSeat(None, player, continent) match {
|
||||
|
|
@ -111,7 +111,7 @@ class SpectatorModeLogic(data: SessionData) extends ModeLogic {
|
|||
.foreach { obj =>
|
||||
sendResponse(DeployableObjectsInfoMessage(
|
||||
DeploymentAction.Dismiss,
|
||||
DeployableInfo(obj.GUID, Deployable.Icon.apply(obj.Definition.Item), obj.Position, Service.defaultPlayerGUID)
|
||||
DeployableInfo(obj.GUID, Deployable.Icon.apply(obj.Definition.Item), obj.Position, Default.GUID0)
|
||||
))
|
||||
}
|
||||
if (player.silenced) {
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ import net.psforever.objects.avatar.Avatar
|
|||
import net.psforever.packet.game.{CharacterKnowledgeInfo, CharacterKnowledgeMessage, ChatMsg, PlanetsideAttributeMessage, ReplicationStreamMessage, SquadAction, SquadDefinitionActionMessage, SquadDetailDefinitionUpdateMessage, SquadListing, SquadMemberEvent, SquadMembershipRequest, SquadMembershipResponse, SquadState, SquadStateInfo, SquadWaypointEvent, SquadWaypointRequest, WaypointEventAction}
|
||||
import net.psforever.services.chat.SquadChannel
|
||||
import net.psforever.services.teamwork.SquadResponse
|
||||
import net.psforever.types.{ChatMessageType, PlanetSideGUID, SquadListDecoration, SquadResponseType}
|
||||
import net.psforever.types.{PlanetSideGUID, SquadListDecoration, SquadResponseType}
|
||||
|
||||
object SquadHandlerLogic {
|
||||
def apply(ops: SessionSquadHandlers): SquadHandlerLogic = {
|
||||
|
|
|
|||
|
|
@ -1,14 +1,16 @@
|
|||
// Copyright (c) 2024 PSForever
|
||||
package net.psforever.actors.session.spectator
|
||||
|
||||
import akka.actor.Actor.Receive
|
||||
import akka.actor.ActorContext
|
||||
import net.psforever.actors.session.support.{SessionData, SessionVehicleHandlers, VehicleHandlerFunctions}
|
||||
import net.psforever.objects.{Tool, Vehicle, Vehicles}
|
||||
import net.psforever.objects.{Vehicle, Vehicles}
|
||||
import net.psforever.objects.equipment.Equipment
|
||||
import net.psforever.objects.serverobject.pad.VehicleSpawnPad
|
||||
import net.psforever.packet.game.objectcreate.ObjectCreateMessageParent
|
||||
import net.psforever.packet.game.{ChangeAmmoMessage, ChangeFireStateMessage_Start, ChangeFireStateMessage_Stop, ChildObjectStateMessage, DeadState, DeployRequestMessage, DismountVehicleMsg, FrameVehicleStateMessage, GenericObjectActionMessage, HitHint, InventoryStateMessage, ObjectAttachMessage, ObjectCreateDetailedMessage, ObjectCreateMessage, ObjectDeleteMessage, ObjectDetachMessage, PlanetsideAttributeMessage, ReloadMessage, ServerVehicleOverrideMsg, VehicleStateMessage, WeaponDryFireMessage}
|
||||
import net.psforever.services.vehicle.{VehicleResponse, VehicleServiceResponse}
|
||||
import net.psforever.packet.game.{ChildObjectStateMessage, DeadState, DeployRequestMessage, DismountVehicleMsg, FrameVehicleStateMessage, GenericObjectActionMessage, InventoryStateMessage, ObjectAttachMessage, ObjectCreateDetailedMessage, ObjectCreateMessage, ObjectDeleteMessage, ObjectDetachMessage, PlanetsideAttributeMessage, ServerVehicleOverrideMsg, VehicleStateMessage}
|
||||
import net.psforever.services.base.envelope.GenericResponseEnvelope
|
||||
import net.psforever.services.vehicle.{VehicleAction, VehicleStamp}
|
||||
import net.psforever.types.{BailType, PlanetSideGUID, Vector3}
|
||||
|
||||
object VehicleHandlerLogic {
|
||||
|
|
@ -24,230 +26,184 @@ class VehicleHandlerLogic(val ops: SessionVehicleHandlers, implicit val context:
|
|||
|
||||
//private val galaxyService: ActorRef = ops.galaxyService
|
||||
|
||||
/**
|
||||
* na
|
||||
*
|
||||
* @param toChannel na
|
||||
* @param guid na
|
||||
* @param reply na
|
||||
*/
|
||||
def handle(toChannel: String, guid: PlanetSideGUID, reply: VehicleResponse.Response): Unit = {
|
||||
val resolvedPlayerGuid = if (player.HasGUID) {
|
||||
player.GUID
|
||||
} else {
|
||||
PlanetSideGUID(-1)
|
||||
}
|
||||
val isNotSameTarget = resolvedPlayerGuid != guid
|
||||
reply match {
|
||||
case VehicleResponse.VehicleState(
|
||||
vehicleGuid,
|
||||
unk1,
|
||||
pos,
|
||||
orient,
|
||||
vel,
|
||||
unk2,
|
||||
unk3,
|
||||
unk4,
|
||||
wheelDirection,
|
||||
unk5,
|
||||
unk6
|
||||
) if isNotSameTarget && player.VehicleSeated.contains(vehicleGuid) =>
|
||||
//player who is also in the vehicle (not driver)
|
||||
sendResponse(VehicleStateMessage(vehicleGuid, unk1, pos, orient, vel, unk2, unk3, unk4, wheelDirection, unk5, unk6))
|
||||
player.Position = pos
|
||||
player.Orientation = orient
|
||||
player.Velocity = vel
|
||||
sessionLogic.updateLocalBlockMap(pos)
|
||||
def receive: Receive = {
|
||||
case VehicleAction.VehicleState(
|
||||
vehicleGuid,
|
||||
unk1,
|
||||
pos,
|
||||
orient,
|
||||
vel,
|
||||
unk2,
|
||||
unk3,
|
||||
unk4,
|
||||
wheelDirection,
|
||||
unk5,
|
||||
unk6
|
||||
) if TestFilter(() => { NotSameTarget && player.VehicleSeated.contains(vehicleGuid) }) =>
|
||||
//player who is also in the vehicle (not driver)
|
||||
sendResponse(VehicleStateMessage(vehicleGuid, unk1, pos, orient, vel, unk2, unk3, unk4, wheelDirection, unk5, unk6))
|
||||
player.Position = pos
|
||||
player.Orientation = orient
|
||||
player.Velocity = vel
|
||||
sessionLogic.updateLocalBlockMap(pos)
|
||||
|
||||
case VehicleResponse.VehicleState(
|
||||
vehicleGuid,
|
||||
unk1,
|
||||
pos,
|
||||
ang,
|
||||
vel,
|
||||
unk2,
|
||||
unk3,
|
||||
unk4,
|
||||
wheelDirection,
|
||||
unk5,
|
||||
unk6
|
||||
) if isNotSameTarget =>
|
||||
//player who is watching the vehicle from the outside
|
||||
sendResponse(VehicleStateMessage(vehicleGuid, unk1, pos, ang, vel, unk2, unk3, unk4, wheelDirection, unk5, unk6))
|
||||
case VehicleAction.VehicleState(
|
||||
vehicleGuid,
|
||||
unk1,
|
||||
pos,
|
||||
ang,
|
||||
vel,
|
||||
unk2,
|
||||
unk3,
|
||||
unk4,
|
||||
wheelDirection,
|
||||
unk5,
|
||||
unk6
|
||||
) if TestFilter(NotSameTargetTest) =>
|
||||
//player who is watching the vehicle from the outside
|
||||
sendResponse(VehicleStateMessage(vehicleGuid, unk1, pos, ang, vel, unk2, unk3, unk4, wheelDirection, unk5, unk6))
|
||||
|
||||
case VehicleResponse.ChildObjectState(objectGuid, pitch, yaw) if isNotSameTarget =>
|
||||
sendResponse(ChildObjectStateMessage(objectGuid, pitch, yaw))
|
||||
case VehicleAction.ChildObjectState(objectGuid, pitch, yaw)
|
||||
if TestFilter(NotSameTargetTest) =>
|
||||
sendResponse(ChildObjectStateMessage(objectGuid, pitch, yaw))
|
||||
|
||||
case VehicleResponse.FrameVehicleState(vguid, u1, pos, oient, vel, u2, u3, u4, is_crouched, u6, u7, u8, u9, uA)
|
||||
if isNotSameTarget =>
|
||||
sendResponse(FrameVehicleStateMessage(vguid, u1, pos, oient, vel, u2, u3, u4, is_crouched, u6, u7, u8, u9, uA))
|
||||
case VehicleAction.FrameVehicleState(vguid, u1, pos, oient, vel, u2, u3, u4, is_crouched, u6, u7, u8, u9, uA)
|
||||
if TestFilter(NotSameTargetTest) =>
|
||||
sendResponse(FrameVehicleStateMessage(vguid, u1, pos, oient, vel, u2, u3, u4, is_crouched, u6, u7, u8, u9, uA))
|
||||
|
||||
case VehicleResponse.ChangeFireState_Start(weaponGuid) if isNotSameTarget =>
|
||||
sendResponse(ChangeFireStateMessage_Start(weaponGuid))
|
||||
case VehicleAction.DismountVehicle(bailType, wasKickedByDriver)
|
||||
if TestFilter(NotSameTargetTest) =>
|
||||
sendResponse(DismountVehicleMsg(FilterGuid, bailType, wasKickedByDriver))
|
||||
|
||||
case VehicleResponse.ChangeFireState_Stop(weaponGuid) if isNotSameTarget =>
|
||||
sendResponse(ChangeFireStateMessage_Stop(weaponGuid))
|
||||
case VehicleAction.MountVehicle(vehicleGuid, seat)
|
||||
if TestFilter(NotSameTargetTest) =>
|
||||
sendResponse(ObjectAttachMessage(vehicleGuid, FilterGuid, seat))
|
||||
|
||||
case VehicleResponse.Reload(itemGuid) if isNotSameTarget =>
|
||||
sendResponse(ReloadMessage(itemGuid, ammo_clip=1, unk1=0))
|
||||
case VehicleAction.DeployRequest(objectGuid, state, unk1, unk2, pos)
|
||||
if TestFilter(NotSameTargetTest) =>
|
||||
sendResponse(DeployRequestMessage(FilterGuid, objectGuid, state, unk1, unk2, pos))
|
||||
|
||||
case VehicleResponse.ChangeAmmo(weapon_guid, weapon_slot, previous_guid, ammo_id, ammo_guid, ammo_data) if isNotSameTarget =>
|
||||
sendResponse(ObjectDetachMessage(weapon_guid, previous_guid, Vector3.Zero, 0))
|
||||
//TODO? sendResponse(ObjectDeleteMessage(previousAmmoGuid, 0))
|
||||
sendResponse(
|
||||
ObjectCreateMessage(
|
||||
ammo_id,
|
||||
ammo_guid,
|
||||
ObjectCreateMessageParent(weapon_guid, weapon_slot),
|
||||
ammo_data
|
||||
)
|
||||
case VehicleAction.EquipmentCreatedInSlot(pkt)
|
||||
if TestFilter(NotSameTargetTest) =>
|
||||
sendResponse(pkt)
|
||||
|
||||
case VehicleAction.InventoryState(obj, parentGuid, start, conData)
|
||||
if TestFilter(NotSameTargetTest) =>
|
||||
//TODO prefer ObjectDetachMessage, but how to force ammo pools to update properly?
|
||||
val objGuid = obj.GUID
|
||||
sendResponse(ObjectDeleteMessage(objGuid, unk1=0))
|
||||
sendResponse(ObjectCreateDetailedMessage(
|
||||
obj.Definition.ObjectId,
|
||||
objGuid,
|
||||
ObjectCreateMessageParent(parentGuid, start),
|
||||
conData
|
||||
))
|
||||
|
||||
case VehicleAction.KickPassenger(_, wasKickedByDriver, vehicleGuid)
|
||||
if TestFilter(NotSameTargetTest) =>
|
||||
//seat number (first field) seems to be correct if passenger is kicked manually by driver
|
||||
//but always seems to return 4 if user is kicked by mount permissions changing
|
||||
sendResponse(DismountVehicleMsg(FilterGuid, BailType.Kicked, wasKickedByDriver))
|
||||
continent.GUID(vehicleGuid) match {
|
||||
case Some(obj: Vehicle) =>
|
||||
sessionLogic.general.unaccessContainer(obj)
|
||||
case _ => ()
|
||||
}
|
||||
|
||||
case VehicleAction.KickPassenger(_, wasKickedByDriver, _) =>
|
||||
//seat number (first field) seems to be correct if passenger is kicked manually by driver
|
||||
//but always seems to return 4 if user is kicked by mount permissions changing
|
||||
sendResponse(DismountVehicleMsg(FilterGuid, BailType.Kicked, wasKickedByDriver))
|
||||
|
||||
case VehicleAction.InventoryState2(objGuid, parentGuid, value)
|
||||
if TestFilter(NotSameTargetTest) =>
|
||||
sendResponse(InventoryStateMessage(objGuid, unk=0, parentGuid, value))
|
||||
|
||||
case VehicleAction.LoadVehicle(vehicle, vtype, vguid, vdata)
|
||||
if TestFilter(NotSameTargetTest) =>
|
||||
//this is not be suitable for vehicles with people who are seated in it before it spawns (if that is possible)
|
||||
sendResponse(ObjectCreateMessage(vtype, vguid, vdata))
|
||||
Vehicles.ReloadAccessPermissions(vehicle, player.Name)
|
||||
|
||||
case VehicleAction.SeatPermissions(vehicleGuid, seatGroup, permission)
|
||||
if TestFilter(NotSameTargetTest) =>
|
||||
sendResponse(PlanetsideAttributeMessage(vehicleGuid, seatGroup, permission))
|
||||
|
||||
case VehicleAction.UnloadVehicle(_, vehicleGuid) =>
|
||||
sendResponse(ObjectDeleteMessage(vehicleGuid, unk1=1))
|
||||
|
||||
case VehicleAction.UnstowEquipment(itemGuid)
|
||||
if TestFilter(NotSameTargetTest) =>
|
||||
//TODO prefer ObjectDetachMessage, but how to force ammo pools to update properly?
|
||||
sendResponse(ObjectDeleteMessage(itemGuid, unk1=0))
|
||||
|
||||
case VehicleAction.UpdateAmsSpawnList(list) =>
|
||||
sessionLogic.zoning.spawn.amsSpawnPoints = list.filter(tube => tube.Faction == player.Faction)
|
||||
sessionLogic.zoning.spawn.DrawCurrentAmsSpawnPoint()
|
||||
|
||||
case VehicleAction.KickCargo(vehicle, speed, delay)
|
||||
if TestFilter(() => { player.VehicleSeated.nonEmpty && sessionLogic.zoning.spawn.deadState == DeadState.Alive && speed > 0 }) =>
|
||||
val strafe = 1 + Vehicles.CargoOrientation(vehicle)
|
||||
val reverseSpeed = if (strafe > 1) { 0 } else { speed }
|
||||
//strafe or reverse, not both
|
||||
sessionLogic.vehicles.ServerVehicleOverrideWithPacket(
|
||||
vehicle,
|
||||
ServerVehicleOverrideMsg(
|
||||
lock_accelerator=true,
|
||||
lock_wheel=true,
|
||||
reverse=true,
|
||||
unk4=false,
|
||||
lock_vthrust=0,
|
||||
strafe,
|
||||
reverseSpeed,
|
||||
unk8=Some(0)
|
||||
)
|
||||
sendResponse(ChangeAmmoMessage(weapon_guid, 1))
|
||||
)
|
||||
import scala.concurrent.ExecutionContext.Implicits.global
|
||||
import scala.concurrent.duration._
|
||||
val resp = GenericResponseEnvelope(
|
||||
VehicleStamp,
|
||||
"",
|
||||
PlanetSideGUID(0),
|
||||
VehicleAction.KickCargo(vehicle, speed=0, delay)
|
||||
)
|
||||
context.system.scheduler.scheduleOnce(delay milliseconds, context.self, resp)
|
||||
|
||||
case VehicleResponse.WeaponDryFire(weaponGuid) if isNotSameTarget =>
|
||||
continent.GUID(weaponGuid).collect {
|
||||
case tool: Tool if tool.Magazine == 0 =>
|
||||
// check that the magazine is still empty before sending WeaponDryFireMessage
|
||||
// if it has been reloaded since then, other clients will not see it firing
|
||||
sendResponse(WeaponDryFireMessage(weaponGuid))
|
||||
}
|
||||
case VehicleAction.KickCargo(cargo, _, _)
|
||||
if TestFilter(() => { player.VehicleSeated.nonEmpty && sessionLogic.zoning.spawn.deadState == DeadState.Alive }) =>
|
||||
sessionLogic.vehicles.TotalDriverVehicleControl(cargo)
|
||||
|
||||
case VehicleResponse.DismountVehicle(bailType, wasKickedByDriver) if isNotSameTarget =>
|
||||
sendResponse(DismountVehicleMsg(guid, bailType, wasKickedByDriver))
|
||||
case VehicleSpawnPad.AttachToRails(vehicle, pad) =>
|
||||
sendResponse(ObjectAttachMessage(pad.GUID, vehicle.GUID, slot=3))
|
||||
|
||||
case VehicleResponse.MountVehicle(vehicleGuid, seat) if isNotSameTarget =>
|
||||
sendResponse(ObjectAttachMessage(vehicleGuid, guid, seat))
|
||||
case VehicleSpawnPad.ConcealPlayer(playerGuid) =>
|
||||
sendResponse(GenericObjectActionMessage(playerGuid, code=9))
|
||||
|
||||
case VehicleResponse.DeployRequest(objectGuid, state, unk1, unk2, pos) if isNotSameTarget =>
|
||||
sendResponse(DeployRequestMessage(guid, objectGuid, state, unk1, unk2, pos))
|
||||
|
||||
case VehicleResponse.SendResponse(msg) =>
|
||||
sendResponse(msg)
|
||||
|
||||
case VehicleResponse.AttachToRails(vehicleGuid, padGuid) =>
|
||||
sendResponse(ObjectAttachMessage(padGuid, vehicleGuid, slot=3))
|
||||
|
||||
case VehicleResponse.ConcealPlayer(playerGuid) =>
|
||||
sendResponse(GenericObjectActionMessage(playerGuid, code=9))
|
||||
|
||||
case VehicleResponse.DetachFromRails(vehicleGuid, padGuid, padPosition, padOrientationZ) =>
|
||||
val pad = continent.GUID(padGuid).get.asInstanceOf[VehicleSpawnPad].Definition
|
||||
sendResponse(
|
||||
ObjectDetachMessage(
|
||||
padGuid,
|
||||
vehicleGuid,
|
||||
padPosition + Vector3.z(pad.VehicleCreationZOffset),
|
||||
padOrientationZ + pad.VehicleCreationZOrientOffset
|
||||
)
|
||||
case VehicleSpawnPad.DetachFromRails(vehicle, pad) =>
|
||||
val padDefinition = pad.Definition
|
||||
sendResponse(
|
||||
ObjectDetachMessage(
|
||||
pad.GUID,
|
||||
vehicle.GUID,
|
||||
pad.Position + Vector3.z(padDefinition.VehicleCreationZOffset),
|
||||
pad.Orientation.z + padDefinition.VehicleCreationZOrientOffset
|
||||
)
|
||||
)
|
||||
|
||||
case VehicleResponse.EquipmentInSlot(pkt) if isNotSameTarget =>
|
||||
sendResponse(pkt)
|
||||
case VehicleSpawnPad.ResetSpawnPad(pad) =>
|
||||
sendResponse(GenericObjectActionMessage(pad.GUID, code=23))
|
||||
|
||||
case VehicleResponse.GenericObjectAction(objectGuid, action) if isNotSameTarget =>
|
||||
sendResponse(GenericObjectActionMessage(objectGuid, action))
|
||||
case VehicleSpawnPad.RevealPlayer(playerGuid) =>
|
||||
sendResponse(GenericObjectActionMessage(playerGuid, code=10))
|
||||
|
||||
case VehicleResponse.InventoryState(obj, parentGuid, start, conData) if isNotSameTarget =>
|
||||
//TODO prefer ObjectDetachMessage, but how to force ammo pools to update properly?
|
||||
val objGuid = obj.GUID
|
||||
sendResponse(ObjectDeleteMessage(objGuid, unk1=0))
|
||||
sendResponse(ObjectCreateDetailedMessage(
|
||||
obj.Definition.ObjectId,
|
||||
objGuid,
|
||||
ObjectCreateMessageParent(parentGuid, start),
|
||||
conData
|
||||
))
|
||||
case VehicleSpawnPad.ServerVehicleOverrideEnd(vehicle, _) =>
|
||||
sessionLogic.vehicles.ServerVehicleOverrideStop(vehicle)
|
||||
|
||||
case VehicleResponse.KickPassenger(_, wasKickedByDriver, vehicleGuid) if resolvedPlayerGuid == guid =>
|
||||
//seat number (first field) seems to be correct if passenger is kicked manually by driver
|
||||
//but always seems to return 4 if user is kicked by mount permissions changing
|
||||
sendResponse(DismountVehicleMsg(guid, BailType.Kicked, wasKickedByDriver))
|
||||
continent.GUID(vehicleGuid) match {
|
||||
case Some(obj: Vehicle) =>
|
||||
sessionLogic.general.unaccessContainer(obj)
|
||||
case _ => ()
|
||||
}
|
||||
|
||||
case VehicleResponse.KickPassenger(_, wasKickedByDriver, _) =>
|
||||
//seat number (first field) seems to be correct if passenger is kicked manually by driver
|
||||
//but always seems to return 4 if user is kicked by mount permissions changing
|
||||
sendResponse(DismountVehicleMsg(guid, BailType.Kicked, wasKickedByDriver))
|
||||
|
||||
case VehicleResponse.InventoryState2(objGuid, parentGuid, value) if isNotSameTarget =>
|
||||
sendResponse(InventoryStateMessage(objGuid, unk=0, parentGuid, value))
|
||||
|
||||
case VehicleResponse.LoadVehicle(vehicle, vtype, vguid, vdata) if isNotSameTarget =>
|
||||
//this is not be suitable for vehicles with people who are seated in it before it spawns (if that is possible)
|
||||
sendResponse(ObjectCreateMessage(vtype, vguid, vdata))
|
||||
Vehicles.ReloadAccessPermissions(vehicle, player.Name)
|
||||
|
||||
case VehicleResponse.ObjectDelete(itemGuid) if isNotSameTarget =>
|
||||
sendResponse(ObjectDeleteMessage(itemGuid, unk1=0))
|
||||
|
||||
case VehicleResponse.PlanetsideAttribute(vehicleGuid, attributeType, attributeValue) if isNotSameTarget =>
|
||||
sendResponse(PlanetsideAttributeMessage(vehicleGuid, attributeType, attributeValue))
|
||||
|
||||
case VehicleResponse.ResetSpawnPad(padGuid) =>
|
||||
sendResponse(GenericObjectActionMessage(padGuid, code=23))
|
||||
|
||||
case VehicleResponse.RevealPlayer(playerGuid) =>
|
||||
sendResponse(GenericObjectActionMessage(playerGuid, code=10))
|
||||
|
||||
case VehicleResponse.SeatPermissions(vehicleGuid, seatGroup, permission) if isNotSameTarget =>
|
||||
sendResponse(PlanetsideAttributeMessage(vehicleGuid, seatGroup, permission))
|
||||
|
||||
case VehicleResponse.UnloadVehicle(_, vehicleGuid) =>
|
||||
sendResponse(ObjectDeleteMessage(vehicleGuid, unk1=1))
|
||||
|
||||
case VehicleResponse.UnstowEquipment(itemGuid) if isNotSameTarget =>
|
||||
//TODO prefer ObjectDetachMessage, but how to force ammo pools to update properly?
|
||||
sendResponse(ObjectDeleteMessage(itemGuid, unk1=0))
|
||||
|
||||
case VehicleResponse.UpdateAmsSpawnPoint(list) =>
|
||||
sessionLogic.zoning.spawn.amsSpawnPoints = list.filter(tube => tube.Faction == player.Faction)
|
||||
sessionLogic.zoning.spawn.DrawCurrentAmsSpawnPoint()
|
||||
|
||||
case VehicleResponse.KickCargo(vehicle, speed, delay)
|
||||
if player.VehicleSeated.nonEmpty && sessionLogic.zoning.spawn.deadState == DeadState.Alive && speed > 0 =>
|
||||
val strafe = 1 + Vehicles.CargoOrientation(vehicle)
|
||||
val reverseSpeed = if (strafe > 1) { 0 } else { speed }
|
||||
//strafe or reverse, not both
|
||||
sessionLogic.vehicles.ServerVehicleOverrideWithPacket(
|
||||
vehicle,
|
||||
ServerVehicleOverrideMsg(
|
||||
lock_accelerator=true,
|
||||
lock_wheel=true,
|
||||
reverse=true,
|
||||
unk4=false,
|
||||
lock_vthrust=0,
|
||||
strafe,
|
||||
reverseSpeed,
|
||||
unk8=Some(0)
|
||||
)
|
||||
)
|
||||
import scala.concurrent.ExecutionContext.Implicits.global
|
||||
import scala.concurrent.duration._
|
||||
context.system.scheduler.scheduleOnce(
|
||||
delay milliseconds,
|
||||
context.self,
|
||||
VehicleServiceResponse(toChannel, PlanetSideGUID(0), VehicleResponse.KickCargo(vehicle, speed=0, delay))
|
||||
)
|
||||
|
||||
case VehicleResponse.KickCargo(cargo, _, _)
|
||||
if player.VehicleSeated.nonEmpty && sessionLogic.zoning.spawn.deadState == DeadState.Alive =>
|
||||
sessionLogic.vehicles.TotalDriverVehicleControl(cargo)
|
||||
|
||||
case VehicleResponse.ServerVehicleOverrideEnd(vehicle, _) =>
|
||||
sessionLogic.vehicles.ServerVehicleOverrideStop(vehicle)
|
||||
|
||||
case VehicleResponse.ChangeLoadout(target, oldWeapons, _, oldInventory, _) =>
|
||||
//TODO when vehicle weapons can be changed without visual glitches, rewrite this
|
||||
continent.GUID(target).collect { case vehicle: Vehicle =>
|
||||
changeLoadoutDeleteOldEquipment(vehicle, oldWeapons, oldInventory)
|
||||
}
|
||||
|
||||
case _ => ()
|
||||
}
|
||||
case VehicleAction.ChangeLoadout(target, oldWeapons, _, oldInventory, _) =>
|
||||
//TODO when vehicle weapons can be changed without visual glitches, rewrite this
|
||||
continent.GUID(target).collect { case vehicle: Vehicle =>
|
||||
changeLoadoutDeleteOldEquipment(vehicle, oldWeapons, oldInventory)
|
||||
}
|
||||
}
|
||||
|
||||
private def changeLoadoutDeleteOldEquipment(
|
||||
|
|
|
|||
|
|
@ -7,7 +7,9 @@ import net.psforever.objects.serverobject.PlanetSideServerObject
|
|||
import net.psforever.objects.Vehicle
|
||||
import net.psforever.objects.serverobject.deploy.Deployment
|
||||
import net.psforever.packet.game.{ChildObjectStateMessage, DeployRequestMessage, FrameVehicleStateMessage, VehicleStateMessage, VehicleSubStateMessage}
|
||||
import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage}
|
||||
import net.psforever.services.base.CachedEnvelope
|
||||
import net.psforever.services.base.envelope.MessageEnvelope
|
||||
import net.psforever.services.vehicle.VehicleAction
|
||||
import net.psforever.types.{DriveState, Vector3}
|
||||
|
||||
object VehicleLogic {
|
||||
|
|
@ -39,22 +41,10 @@ class VehicleLogic(val ops: VehicleOperations, implicit val context: ActorContex
|
|||
obj.Velocity = vel
|
||||
sessionLogic.updateBlockMap(obj, pos)
|
||||
obj.zoneInteractions()
|
||||
continent.VehicleEvents ! VehicleServiceMessage(
|
||||
continent.VehicleEvents ! CachedEnvelope(
|
||||
continent.id,
|
||||
VehicleAction.VehicleState(
|
||||
player.GUID,
|
||||
vehicle_guid,
|
||||
unk1,
|
||||
pos,
|
||||
ang,
|
||||
obj.Velocity,
|
||||
obj.Flying,
|
||||
0,
|
||||
0,
|
||||
15,
|
||||
unk5 = false,
|
||||
obj.Cloaked
|
||||
)
|
||||
player.GUID,
|
||||
VehicleAction.VehicleState(vehicle_guid, unk1, pos, ang, obj.Velocity, obj.Flying, 0, 0, 15, unk5 = false, obj.Cloaked)
|
||||
)
|
||||
case _ => ()
|
||||
}
|
||||
|
|
@ -92,9 +82,10 @@ class VehicleLogic(val ops: VehicleOperations, implicit val context: ActorContex
|
|||
val mobileShift: String = if (obj.DeploymentState != DriveState.Mobile) {
|
||||
obj.DeploymentState = DriveState.Mobile
|
||||
sendResponse(DeployRequestMessage(player.GUID, obj.GUID, DriveState.Mobile, 0, unk3=false, Vector3.Zero))
|
||||
continent.VehicleEvents ! VehicleServiceMessage(
|
||||
continent.VehicleEvents ! MessageEnvelope(
|
||||
continent.id,
|
||||
VehicleAction.DeployRequest(player.GUID, obj.GUID, DriveState.Mobile, 0, unk2=false, Vector3.Zero)
|
||||
player.GUID,
|
||||
VehicleAction.DeployRequest(obj.GUID, DriveState.Mobile, 0, unk2=false, Vector3.Zero)
|
||||
)
|
||||
"; enforcing Mobile deployment state"
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -17,10 +17,10 @@ import net.psforever.objects.sourcing.PlayerSource
|
|||
import net.psforever.objects.zones.{Zone, ZoneInfo}
|
||||
import net.psforever.packet.game.TimeOfDayMessage.GetTimeOfDayValue
|
||||
import net.psforever.packet.game.{SetChatFilterMessage, TimeOfDayMessage}
|
||||
import net.psforever.services.Service
|
||||
import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage}
|
||||
import net.psforever.services.base.envelope.MessageEnvelope
|
||||
import net.psforever.services.base.message.SendResponse
|
||||
import net.psforever.services.chat.{DefaultChannel, OutfitChannel, SquadChannel}
|
||||
import net.psforever.services.local.{LocalAction, LocalServiceMessage}
|
||||
import net.psforever.services.local.support.{CaptureEnvelope, HackCaptureActor}
|
||||
import net.psforever.services.teamwork.{SquadResponse, SquadService, SquadServiceResponse}
|
||||
import net.psforever.types.ChatMessageType.CMT_QUIT
|
||||
import org.log4s.Logger
|
||||
|
|
@ -405,10 +405,7 @@ class ChatOperations(
|
|||
}
|
||||
else {
|
||||
if (building.CaptureTerminalIsHacked) {
|
||||
zone.LocalEvents ! LocalServiceMessage(
|
||||
zone.id,
|
||||
LocalAction.ResecureCaptureTerminal(terminal, PlayerSource.Nobody)
|
||||
)
|
||||
zone.LocalEvents ! CaptureEnvelope(HackCaptureActor.ResecureCaptureTerminal(terminal, zone, PlayerSource.Nobody))
|
||||
}
|
||||
building.Actor ! BuildingActor.SetFaction(faction)
|
||||
building.Actor ! BuildingActor.AmenityStateChange(terminal, Some(false))
|
||||
|
|
@ -1444,10 +1441,7 @@ class ChatOperations(
|
|||
val msg = TimeOfDayMessage(zone.GetTimeOfDay(), zone.GetTimeOfDaySpeed())
|
||||
|
||||
// update players in zone
|
||||
zone.AvatarEvents ! AvatarServiceMessage(
|
||||
zone.id,
|
||||
AvatarAction.SendResponse(Service.defaultPlayerGUID, msg)
|
||||
)
|
||||
zone.AvatarEvents ! MessageEnvelope(zone.id, SendResponse(msg))
|
||||
|
||||
sendResponse(ChatMsg(messageType = UNK_227, contents = f"@CMT_SETTIME_OK^$hh~^$mm%02d~"))
|
||||
case _ =>
|
||||
|
|
@ -1482,10 +1476,7 @@ class ChatOperations(
|
|||
val msg = TimeOfDayMessage(zone.GetTimeOfDay(), zone.GetTimeOfDaySpeed())
|
||||
|
||||
// update players in zone
|
||||
zone.AvatarEvents ! AvatarServiceMessage(
|
||||
zone.id,
|
||||
AvatarAction.SendResponse(Service.defaultPlayerGUID, msg)
|
||||
)
|
||||
zone.AvatarEvents ! MessageEnvelope(zone.id, SendResponse(msg))
|
||||
|
||||
sendResponse(ChatMsg(messageType = UNK_227, contents = s"@CMT_SETTIMESPEED_OK^$timeSpeed~"))
|
||||
case _ =>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,100 @@
|
|||
// Copyright (c) 2026 PSForever
|
||||
package net.psforever.actors.session.support
|
||||
|
||||
import akka.actor.Actor.Receive
|
||||
import net.psforever.objects.{Default, Player}
|
||||
import net.psforever.services.base.message.EventResponse
|
||||
import net.psforever.types.PlanetSideGUID
|
||||
|
||||
/**
|
||||
* A shared filter container utilized by all response handlers connected by a certain mode.
|
||||
* It is expected that the filters are treated in a true-oriented context -
|
||||
* always check `isNotSameTarget` and not `!isSameTarget`, etc..
|
||||
*/
|
||||
protected[support] class CommonHandlerFilters {
|
||||
var resolvedGuid: PlanetSideGUID = Default.GUID0
|
||||
var filterGuid: PlanetSideGUID = Default.GUID0
|
||||
var isNotSameTarget: Boolean = false
|
||||
var isSameTarget: Boolean = false
|
||||
|
||||
def Configure(player: Player, guid: PlanetSideGUID): Unit = {
|
||||
filterGuid = guid
|
||||
if (player != null && player.HasGUID) {
|
||||
resolvedGuid = player.GUID
|
||||
isNotSameTarget = resolvedGuid != filterGuid
|
||||
isSameTarget = resolvedGuid == filterGuid
|
||||
} else {
|
||||
resolvedGuid = Default.GUID0
|
||||
isNotSameTarget = false
|
||||
isSameTarget = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
trait CommonHandlerFunctions {
|
||||
_: CommonSessionInterfacingFunctionality =>
|
||||
final def ResolvedGuid: PlanetSideGUID = sessionLogic.handlerFilters.resolvedGuid
|
||||
final def FilterGuid: PlanetSideGUID = sessionLogic.handlerFilters.filterGuid
|
||||
final def NotSameTarget: Boolean = sessionLogic.handlerFilters.isNotSameTarget
|
||||
final def SameTarget: Boolean = sessionLogic.handlerFilters.isSameTarget
|
||||
|
||||
val NotSameTargetTest: () => Boolean = () => NotSameTarget
|
||||
|
||||
val SameTargetTest: () => Boolean = () => SameTarget
|
||||
|
||||
private var ignoreFilter: Boolean = false
|
||||
|
||||
final def IgnoreFilter: Boolean = ignoreFilter
|
||||
|
||||
final def IgnoreFilter_=(state: Boolean): Boolean = {
|
||||
ignoreFilter = state
|
||||
IgnoreFilter
|
||||
}
|
||||
|
||||
/**
|
||||
* Process the output of a received response envelope.
|
||||
* Sets the response handler filter.
|
||||
* @param toChannel set of subscribers on an event system bus the envelope should reach
|
||||
* @param guid a specific subscriber endpoint to be excluded
|
||||
* @param reply output payload transported by this envelope
|
||||
* @return `true`, if the response was processed; `false`, otherwise
|
||||
*/
|
||||
final def handle(toChannel: String, guid: PlanetSideGUID, reply: EventResponse): Boolean = {
|
||||
sessionLogic.handlerFilters.Configure(player, guid)
|
||||
tryToHandle(reply)
|
||||
}
|
||||
|
||||
/**
|
||||
* Can the response handler process this message (with the guard boolean permissions set as they currently are).
|
||||
* @see `Actor.isDefinedAt`
|
||||
* @param x payload for processing
|
||||
* @return `true`, if the payload was processed; `false`, otherwise
|
||||
*/
|
||||
def isDefinedAt(x: Any): Boolean = receive.isDefinedAt(x)
|
||||
|
||||
/**
|
||||
* Process the output.
|
||||
* @param x payload for processing
|
||||
* @return `true`, if the payload was processed; `false`, otherwise
|
||||
*/
|
||||
final def tryToHandle(x: Any): Boolean = {
|
||||
var passed = true
|
||||
receive.applyOrElse(x, (_: Any) => { passed = false })
|
||||
passed
|
||||
}
|
||||
|
||||
/**
|
||||
* If ignoring guard booleans (filters), always pass.
|
||||
* If not, test filters using the provided function.
|
||||
* @param filter contained guard booleans
|
||||
* @return `true`. if ignoring filter tests or the filter test passed; `false`, otherwise
|
||||
*/
|
||||
final def TestFilter(filter: () => Boolean): Boolean = {
|
||||
ignoreFilter || filter()
|
||||
}
|
||||
|
||||
/**
|
||||
* @see `Actor.receive`
|
||||
*/
|
||||
def receive: Receive
|
||||
}
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
// Copyright (c) 2026 PSForever
|
||||
package net.psforever.actors.session.support
|
||||
|
||||
import akka.actor.Actor.Receive
|
||||
import akka.actor.ActorContext
|
||||
import net.psforever.objects.Tool
|
||||
import net.psforever.packet.game.{ChangeAmmoMessage, ChangeFireStateMessage_Start, ChangeFireStateMessage_Stop, GenericObjectActionMessage, HitHint, ObjectDeleteMessage, PlanetsideAttributeMessage, ReloadMessage, SetEmpireMessage, WeaponDryFireMessage}
|
||||
import net.psforever.services.base.message.{ChangeAmmo, ChangeFireState_Start, ChangeFireState_Stop, ConcealPlayer, GenericObjectAction, HintsAtAttacker, ObjectDelete, PlanetsideAttribute, ReloadTool, SendResponse, SetEmpire, WeaponDryFire}
|
||||
|
||||
class CommonHandlerLogic(val sessionLogic: SessionData, implicit val context: ActorContext)
|
||||
extends CommonSessionInterfacingFunctionality with CommonHandlerFunctions {
|
||||
|
||||
def receive: Receive = {
|
||||
case PlanetsideAttribute(target_guid, attributeType, attributeValue)
|
||||
if TestFilter(NotSameTargetTest) =>
|
||||
sendResponse(PlanetsideAttributeMessage(target_guid, attributeType, attributeValue))
|
||||
|
||||
case GenericObjectAction(objectGuid, actionCode)
|
||||
if TestFilter(NotSameTargetTest) =>
|
||||
sendResponse(GenericObjectActionMessage(objectGuid, actionCode))
|
||||
|
||||
case ObjectDelete(itemGuid, unk)
|
||||
if TestFilter(NotSameTargetTest) =>
|
||||
sendResponse(ObjectDeleteMessage(itemGuid, unk))
|
||||
|
||||
case ChangeFireState_Start(weaponGuid)
|
||||
if TestFilter(NotSameTargetTest) =>
|
||||
sendResponse(ChangeFireStateMessage_Start(weaponGuid))
|
||||
|
||||
case ChangeFireState_Stop(weaponGuid)
|
||||
if TestFilter(NotSameTargetTest) =>
|
||||
sendResponse(ChangeFireStateMessage_Stop(weaponGuid))
|
||||
|
||||
case ReloadTool(itemGuid)
|
||||
if TestFilter(NotSameTargetTest) =>
|
||||
sendResponse(ReloadMessage(itemGuid, ammo_clip=1, unk1=0))
|
||||
|
||||
case ChangeAmmo(weapon_guid, weapon_slot, previous_guid, ammo_id, ammo_guid, ammo_data)
|
||||
if TestFilter(NotSameTargetTest) =>
|
||||
sessionLogic.avatarResponse.changeAmmoProcedure(weapon_guid, previous_guid, ammo_id, ammo_guid, weapon_slot, ammo_data)
|
||||
sendResponse(ChangeAmmoMessage(weapon_guid, 1))
|
||||
|
||||
case WeaponDryFire(weaponGuid)
|
||||
if TestFilter(NotSameTargetTest) =>
|
||||
continent.GUID(weaponGuid).collect {
|
||||
case tool: Tool if tool.Magazine == 0 =>
|
||||
sendResponse(WeaponDryFireMessage(weaponGuid))
|
||||
}
|
||||
|
||||
case HintsAtAttacker(sourceGuid)
|
||||
if TestFilter(() => { player.isAlive }) =>
|
||||
sendResponse(HitHint(sourceGuid, FilterGuid))
|
||||
sessionLogic.zoning.CancelZoningProcessWithDescriptiveReason("cancel_dmg")
|
||||
|
||||
case SetEmpire(objectGuid, faction)
|
||||
if TestFilter(NotSameTargetTest) =>
|
||||
sendResponse(SetEmpireMessage(objectGuid, faction))
|
||||
|
||||
case ConcealPlayer(_) =>
|
||||
sendResponse(GenericObjectActionMessage(FilterGuid, code=9))
|
||||
|
||||
case SendResponse(msgs) =>
|
||||
msgs.foreach(sendResponse)
|
||||
}
|
||||
}
|
||||
|
|
@ -17,8 +17,12 @@ import net.psforever.objects.sourcing.{DeployableSource, PlayerSource, VehicleSo
|
|||
import net.psforever.objects.vehicles.Utility.InternalTelepad
|
||||
import net.psforever.objects.zones.blockmap.BlockMapEntity
|
||||
import net.psforever.objects.zones.exp.ToDatabase
|
||||
import net.psforever.services.RemoverActor
|
||||
import net.psforever.services.local.{LocalAction, LocalServiceMessage}
|
||||
import net.psforever.services.avatar.support.GroundEnvelope
|
||||
import net.psforever.services.base.envelope.{BundledEnvelope, MessageEnvelope}
|
||||
import net.psforever.services.base.message.{ObjectDelete, PlanetsideAttribute, SendResponse}
|
||||
import net.psforever.services.base.support.RemoverActor
|
||||
import net.psforever.services.local.support.{CaptureEnvelope, HackCaptureActor}
|
||||
import net.psforever.services.local.LocalAction
|
||||
|
||||
import scala.collection.mutable
|
||||
import scala.concurrent.ExecutionContext.Implicits.global
|
||||
|
|
@ -48,9 +52,9 @@ import net.psforever.packet.game.PlanetsideAttributeEnum.PlanetsideAttributeEnum
|
|||
import net.psforever.packet.game.objectcreate._
|
||||
import net.psforever.packet.game._
|
||||
import net.psforever.services.account.AccountPersistenceService
|
||||
import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage}
|
||||
import net.psforever.services.avatar.AvatarAction
|
||||
import net.psforever.services.local.support.CaptureFlagManager
|
||||
import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage}
|
||||
import net.psforever.services.vehicle.VehicleAction
|
||||
import net.psforever.services.Service
|
||||
import net.psforever.types._
|
||||
import net.psforever.util.Config
|
||||
|
|
@ -193,6 +197,32 @@ class GeneralOperations(
|
|||
private[session] var progressBarUpdate: Cancellable = Default.Cancellable
|
||||
private var charSavedTimer: Cancellable = Default.Cancellable
|
||||
|
||||
def handleEmote(pkt: EmoteMsg): Unit = {
|
||||
val guid = player.GUID
|
||||
val zone = player.Zone
|
||||
val events = zone.LocalEvents
|
||||
//todo better way to collect csr players while utilizing the aforementioned benefit of localSector
|
||||
val position = player.Position
|
||||
val rangeSq = {
|
||||
val range = math.sqrt(2 * math.pow(sessionLogic.localSector.rangeX.toDouble, 2))
|
||||
range * range
|
||||
}
|
||||
val msg = SendResponse(pkt)
|
||||
val (localRecipients, localRecipientMessages) = sessionLogic
|
||||
.localSector
|
||||
.livePlayerList
|
||||
.filter(_.GUID != guid)
|
||||
.map { p => (p.Name, MessageEnvelope(p.Name, msg)) }
|
||||
.unzip
|
||||
val otherRecipientMessages = zone
|
||||
.AllPlayers
|
||||
.filter { p =>
|
||||
!p.allowInteraction && p.GUID != guid && !localRecipients.contains(p.Name) && Vector3.DistanceSquared(p.Position, position) < rangeSq
|
||||
}
|
||||
.map(p => MessageEnvelope(p.Name, msg))
|
||||
events ! BundledEnvelope(localRecipientMessages ++ otherRecipientMessages)
|
||||
}
|
||||
|
||||
def handleDropItem(pkt: DropItemMessage): GeneralOperations.ItemDropState.Behavior = {
|
||||
val DropItemMessage(itemGuid) = pkt
|
||||
(sessionLogic.validObject(itemGuid, decorator = "DropItem"), player.FreeHand.Equipment) match {
|
||||
|
|
@ -376,7 +406,7 @@ class GeneralOperations(
|
|||
val detectedTargets = sessionLogic.shooting.FindDetectedProjectileTargets(targets)
|
||||
val mode = 7 + (if (weapon.Projectile == GlobalDefinitions.wasp_rocket_projectile) 1 else 0)
|
||||
detectedTargets.foreach { target =>
|
||||
continent.AvatarEvents ! AvatarServiceMessage(target, AvatarAction.ProjectileAutoLockAwareness(mode))
|
||||
continent.AvatarEvents ! MessageEnvelope(target, AvatarAction.ProjectileAutoLockAwareness(mode))
|
||||
}
|
||||
case _ => ()
|
||||
}
|
||||
|
|
@ -456,7 +486,7 @@ class GeneralOperations(
|
|||
case attacker
|
||||
if attacker.Faction != player.Faction &&
|
||||
System.currentTimeMillis() - llu.LastCollectionTime >= Config.app.game.experience.cep.lluSlayerCreditDuration.toMillis =>
|
||||
continent.AvatarEvents ! AvatarServiceMessage(
|
||||
continent.AvatarEvents ! MessageEnvelope(
|
||||
attacker.Name,
|
||||
AvatarAction.AwardCep(attacker.CharId, Config.app.game.experience.cep.lluSlayerCredit)
|
||||
)
|
||||
|
|
@ -714,7 +744,7 @@ class GeneralOperations(
|
|||
* @param channel the channel name
|
||||
*/
|
||||
private def unaccessContainerChannel(events: ActorRef, channel: String): Unit = {
|
||||
events ! Service.Leave(Some(channel))
|
||||
events ! Service.Leave(channel)
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -851,7 +881,7 @@ class GeneralOperations(
|
|||
case _ if continent.EquipmentOnGround.contains(obj) =>
|
||||
obj.Position = Vector3.Zero
|
||||
continent.Ground ! Zone.Ground.RemoveItem(objectGuid)
|
||||
continent.AvatarEvents ! AvatarServiceMessage.Ground(RemoverActor.ClearSpecific(List(obj), continent))
|
||||
continent.AvatarEvents ! GroundEnvelope(RemoverActor.ClearSpecific(List(obj), continent))
|
||||
true
|
||||
case _ =>
|
||||
Zone.EquipmentIs.Where(obj, objectGuid, continent) match {
|
||||
|
|
@ -876,9 +906,22 @@ class GeneralOperations(
|
|||
* @param unk2 na
|
||||
*/
|
||||
def hackObject(targetGuid: PlanetSideGUID, unk1: Long, unk2: HackState7): Unit = {
|
||||
sendResponse(HackMessage(HackState1.Unk0, targetGuid, player_guid=Service.defaultPlayerGUID, progress=100, unk1.toFloat, HackState.Hacked, unk2))
|
||||
sendResponse(HackMessage(HackState1.Unk0, targetGuid, player_guid=Default.GUID0, progress=100, unk1.toFloat, HackState.Hacked, unk2))
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a PlanetsideAttributeMessage packet to the client
|
||||
* @param targetGuid The target of the attribute
|
||||
* @param attribute The attribute
|
||||
* @param attributeValue The attribute value
|
||||
*/
|
||||
def sendPlanetsideAttributeMessage(
|
||||
targetGuid: PlanetSideGUID,
|
||||
attribute: PlanetsideAttributeEnum,
|
||||
attributeValue: Long
|
||||
): Unit = {
|
||||
sendPlanetsideAttributeMessage(targetGuid, attribute.id, attributeValue)
|
||||
}
|
||||
/**
|
||||
* Send a PlanetsideAttributeMessage packet to the client
|
||||
* @param targetGuid The target of the attribute
|
||||
|
|
@ -887,7 +930,7 @@ class GeneralOperations(
|
|||
*/
|
||||
def sendPlanetsideAttributeMessage(
|
||||
targetGuid: PlanetSideGUID,
|
||||
attributeNumber: PlanetsideAttributeEnum,
|
||||
attributeNumber: Int,
|
||||
attributeValue: Long
|
||||
): Unit = {
|
||||
sendResponse(PlanetsideAttributeMessage(targetGuid, attributeNumber, attributeValue))
|
||||
|
|
@ -986,18 +1029,18 @@ class GeneralOperations(
|
|||
sendResponse(ChatMsg(ChatMessageType.UNK_227, "@ArmorShieldOff"))
|
||||
}
|
||||
player.UsingSpecial = SpecialExoSuitDefinition.Mode.Normal
|
||||
continent.AvatarEvents ! AvatarServiceMessage(
|
||||
continent.AvatarEvents ! MessageEnvelope(
|
||||
continent.id,
|
||||
AvatarAction.PlanetsideAttributeToAll(player.GUID, 8, 0)
|
||||
PlanetsideAttribute(player.GUID, 8, 0)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private def activateMaxSpecialStateMessage(): Unit = {
|
||||
continent.AvatarEvents ! AvatarServiceMessage(
|
||||
continent.AvatarEvents ! MessageEnvelope(
|
||||
continent.id,
|
||||
AvatarAction.PlanetsideAttributeToAll(player.GUID, 8, 1)
|
||||
PlanetsideAttribute(player.GUID, 8, 1)
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -1010,9 +1053,10 @@ class GeneralOperations(
|
|||
case (Some(obj), Some(seatNum)) =>
|
||||
tplayer.VehicleSeated = None
|
||||
obj.Seats(seatNum).unmount(tplayer)
|
||||
continent.VehicleEvents ! VehicleServiceMessage(
|
||||
continent.VehicleEvents ! MessageEnvelope(
|
||||
continent.id,
|
||||
VehicleAction.KickPassenger(tplayer.GUID, seatNum, unk2=false, obj.GUID)
|
||||
tplayer.GUID,
|
||||
VehicleAction.KickPassenger(seatNum, unk2=false, obj.GUID)
|
||||
)
|
||||
case _ => ()
|
||||
}
|
||||
|
|
@ -1249,7 +1293,7 @@ class GeneralOperations(
|
|||
continent.GUID(specialItemSlotGuid) match {
|
||||
case Some(llu: CaptureFlag) =>
|
||||
if (llu.Target.GUID == captureTerminal.Owner.GUID) {
|
||||
continent.LocalEvents ! LocalServiceMessage(continent.id, LocalAction.LluCaptured(llu))
|
||||
continent.LocalEvents ! CaptureEnvelope(HackCaptureActor.FlagCaptured(llu))
|
||||
} else {
|
||||
log.info(
|
||||
s"LLU target is not this base. Target GUID: ${llu.Target.GUID} This base: ${captureTerminal.Owner.GUID}"
|
||||
|
|
@ -1432,23 +1476,21 @@ class GeneralOperations(
|
|||
val events = continent.AvatarEvents
|
||||
val zoneid = continent.id
|
||||
val destinationPosition = dest.Position
|
||||
events ! AvatarServiceMessage(zoneid, AvatarAction.ObjectDelete(pguid, pguid))
|
||||
events ! AvatarServiceMessage(player.Name,
|
||||
AvatarAction.SendResponse(PlanetSideGUID(0), PlayerStateShiftMessage(ShiftState(0, destinationPosition, player.Orientation.z)))
|
||||
)
|
||||
player.Position = destinationPosition
|
||||
events ! AvatarServiceMessage(zoneid, AvatarAction.LoadPlayer(
|
||||
pguid,
|
||||
player.Definition.ObjectId,
|
||||
pguid,
|
||||
player.Definition.Packet.ConstructorData(player).get,
|
||||
None
|
||||
))
|
||||
useRouterTelepadEffect(pguid, sguid, dguid)
|
||||
continent.LocalEvents ! LocalServiceMessage(
|
||||
continent.id,
|
||||
LocalAction.RouterTelepadTransport(pguid, pguid, sguid, dguid)
|
||||
events ! BundledEnvelope(
|
||||
MessageEnvelope(zoneid, pguid, ObjectDelete(pguid)),
|
||||
MessageEnvelope(player.Name,
|
||||
SendResponse(PlayerStateShiftMessage(ShiftState(0, destinationPosition, player.Orientation.z)))
|
||||
),
|
||||
MessageEnvelope(zoneid, pguid, AvatarAction.LoadPlayer(
|
||||
player.Definition.ObjectId,
|
||||
pguid,
|
||||
player.Definition.Packet.ConstructorData(player).get,
|
||||
None
|
||||
)),
|
||||
MessageEnvelope(zoneid, pguid, LocalAction.RouterTelepadTransport(pguid, sguid, dguid))
|
||||
)
|
||||
useRouterTelepadEffect(pguid, sguid, dguid)
|
||||
sessionLogic.zoning.spawn.ShiftPosition = destinationPosition
|
||||
player.LogActivity(TelepadUseActivity(VehicleSource(router), DeployableSource(remoteTelepad), PlayerSource(player)))
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -7,8 +7,9 @@ import net.psforever.objects.{Default, PlanetSideGameObject, Player, Vehicle}
|
|||
import net.psforever.objects.sourcing.{PlayerSource, SourceEntry, UniquePlayer}
|
||||
import net.psforever.packet.game.objectcreate.ConstructorData
|
||||
import net.psforever.objects.zones.exp
|
||||
import net.psforever.services.Service
|
||||
import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage, AvatarServiceResponse}
|
||||
import net.psforever.services.avatar.{AvatarAction, AvatarStamp}
|
||||
import net.psforever.services.base.envelope.{GenericResponseEnvelope, MessageEnvelope}
|
||||
import net.psforever.services.base.message.SendResponse
|
||||
import net.psforever.services.chat.OutfitChannel
|
||||
|
||||
import scala.collection.mutable
|
||||
|
|
@ -16,14 +17,11 @@ import scala.collection.mutable
|
|||
import net.psforever.actors.session.AvatarActor
|
||||
import net.psforever.packet.game.objectcreate.ObjectCreateMessageParent
|
||||
import net.psforever.packet.game._
|
||||
import net.psforever.services.avatar.AvatarResponse
|
||||
import net.psforever.types._
|
||||
import net.psforever.util.Config
|
||||
|
||||
trait AvatarHandlerFunctions extends CommonSessionInterfacingFunctionality {
|
||||
trait AvatarHandlerFunctions extends CommonSessionInterfacingFunctionality with CommonHandlerFunctions {
|
||||
val ops: SessionAvatarHandlers
|
||||
|
||||
def handle(toChannel: String, guid: PlanetSideGUID, reply: AvatarResponse.Response): Unit
|
||||
}
|
||||
|
||||
class SessionAvatarHandlers(
|
||||
|
|
@ -36,7 +34,7 @@ class SessionAvatarHandlers(
|
|||
mutable.LongMap[SessionAvatarHandlers.LastUpstream]()
|
||||
private[session] val hidingPlayerRandomizer = new scala.util.Random
|
||||
|
||||
def changeAmmoProcedures(
|
||||
def changeAmmoProcedure(
|
||||
weaponGuid: PlanetSideGUID,
|
||||
previousAmmoGuid: PlanetSideGUID,
|
||||
ammoTypeId: Int,
|
||||
|
|
@ -45,7 +43,7 @@ class SessionAvatarHandlers(
|
|||
ammoData: ConstructorData
|
||||
): Unit = {
|
||||
sendResponse(ObjectDetachMessage(weaponGuid, previousAmmoGuid, Vector3.Zero, 0))
|
||||
//TODO? sendResponse(ObjectDeleteMessage(previousAmmoGuid, 0))
|
||||
sendResponse(ObjectDeleteMessage(previousAmmoGuid, 0))
|
||||
sendResponse(
|
||||
ObjectCreateMessage(
|
||||
ammoTypeId,
|
||||
|
|
@ -140,7 +138,7 @@ class SessionAvatarHandlers(
|
|||
val playersInZone = killer.Zone.Players.map { avatar => (avatar.id, avatar.basic.name) }
|
||||
val squadMembersHere = playersInZone.filter(member => squadMembers.contains(member._2))
|
||||
squadMembersHere.foreach { member =>
|
||||
killer.Zone.AvatarEvents ! AvatarServiceMessage(
|
||||
killer.Zone.AvatarEvents ! MessageEnvelope(
|
||||
member._2,
|
||||
AvatarAction.AwardBep(member._1, expSplit, ExperienceType.Normal))
|
||||
}
|
||||
|
|
@ -155,7 +153,7 @@ class SessionAvatarHandlers(
|
|||
val playersInZone = vehicle.Zone.Players.map { avatar => (avatar.id, avatar.basic.name) }
|
||||
val squadMembersHere = playersInZone.filter(member => squadMembers.contains(member._2))
|
||||
squadMembersHere.foreach { member =>
|
||||
vehicle.Zone.AvatarEvents ! AvatarServiceMessage(
|
||||
vehicle.Zone.AvatarEvents ! MessageEnvelope(
|
||||
member._2,
|
||||
AvatarAction.AwardBep(member._1, exp, ExperienceType.Normal))
|
||||
}
|
||||
|
|
@ -212,12 +210,11 @@ class SessionAvatarHandlers(
|
|||
def killedWhileMounted(obj: PlanetSideGameObject with Mountable, playerGuid: PlanetSideGUID): Unit = {
|
||||
val playerName = player.Name
|
||||
//boot cadaver from mount on client
|
||||
context.self ! AvatarServiceResponse(
|
||||
context.self ! GenericResponseEnvelope(
|
||||
AvatarStamp,
|
||||
playerName,
|
||||
Service.defaultPlayerGUID,
|
||||
AvatarResponse.SendResponse(
|
||||
ObjectDetachMessage(obj.GUID, playerGuid, player.Position, Vector3.Zero)
|
||||
)
|
||||
Default.GUID0,
|
||||
SendResponse(ObjectDetachMessage(obj.GUID, playerGuid, player.Position, Vector3.Zero))
|
||||
)
|
||||
//player no longer seated
|
||||
obj.PassengerInSeat(player).foreach { seatNumber =>
|
||||
|
|
@ -239,7 +236,7 @@ class SessionAvatarHandlers(
|
|||
|
||||
object SessionAvatarHandlers {
|
||||
private[session] case class LastUpstream(
|
||||
msg: Option[AvatarResponse.PlayerState],
|
||||
msg: Option[AvatarAction.PlayerState],
|
||||
visible: Boolean,
|
||||
shooting: Option[PlanetSideGUID],
|
||||
time: Long
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ package net.psforever.actors.session.support
|
|||
import akka.actor.typed.receptionist.Receptionist
|
||||
import akka.actor.typed.scaladsl.adapter._
|
||||
import akka.actor.{ActorContext, ActorRef, typed}
|
||||
import net.psforever.services.base.envelope.MessageEnvelope
|
||||
import net.psforever.services.chat.ChatService
|
||||
|
||||
import scala.collection.mutable
|
||||
|
|
@ -31,7 +32,7 @@ import net.psforever.packet._
|
|||
import net.psforever.packet.game._
|
||||
import net.psforever.services.account.AccountPersistenceService
|
||||
import net.psforever.services.ServiceManager.LookupResult
|
||||
import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage}
|
||||
import net.psforever.services.vehicle.VehicleAction
|
||||
import net.psforever.services.{Service, InterstellarClusterService => ICS}
|
||||
import net.psforever.types._
|
||||
import net.psforever.util.Config
|
||||
|
|
@ -119,6 +120,8 @@ class SessionData(
|
|||
def zoning: ZoningOperations = zoningOpt.orNull
|
||||
def chat: ChatOperations = chatOpt.orNull
|
||||
|
||||
val handlerFilters: CommonHandlerFilters = new CommonHandlerFilters()
|
||||
|
||||
ServiceManager.serviceManager ! Lookup("accountIntermediary")
|
||||
ServiceManager.serviceManager ! Lookup("accountPersistence")
|
||||
ServiceManager.serviceManager ! Lookup("galaxy")
|
||||
|
|
@ -567,9 +570,10 @@ class SessionData(
|
|||
case (Some(obj), Some(seatNum)) =>
|
||||
tplayer.VehicleSeated = None
|
||||
obj.Seats(seatNum).unmount(tplayer)
|
||||
continent.VehicleEvents ! VehicleServiceMessage(
|
||||
continent.VehicleEvents ! MessageEnvelope(
|
||||
continent.id,
|
||||
VehicleAction.KickPassenger(tplayer.GUID, seatNum, unk2=false, obj.GUID)
|
||||
tplayer.GUID,
|
||||
VehicleAction.KickPassenger(seatNum, unk2=false, obj.GUID)
|
||||
)
|
||||
case _ => ()
|
||||
}
|
||||
|
|
@ -615,12 +619,12 @@ class SessionData(
|
|||
squadResponseOpt.foreach(_.stop())
|
||||
zoningOpt.foreach(_.stop())
|
||||
chatOpt.foreach(_.stop())
|
||||
continent.AvatarEvents ! Service.Leave()
|
||||
continent.LocalEvents ! Service.Leave()
|
||||
continent.VehicleEvents ! Service.Leave()
|
||||
galaxyService ! Service.Leave()
|
||||
continent.AvatarEvents ! Service.LeaveAll
|
||||
continent.LocalEvents ! Service.LeaveAll
|
||||
continent.VehicleEvents ! Service.LeaveAll
|
||||
galaxyService ! Service.LeaveAll
|
||||
if (avatar != null && squadService != Default.Actor) {
|
||||
squadService ! Service.Leave()
|
||||
squadService ! Service.LeaveAll
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,16 +3,13 @@ package net.psforever.actors.session.support
|
|||
|
||||
import akka.actor.{ActorContext, ActorRef, typed}
|
||||
import net.psforever.packet.game.FriendsResponse
|
||||
//
|
||||
import net.psforever.actors.session.AvatarActor
|
||||
import net.psforever.services.galaxy.GalaxyResponse
|
||||
|
||||
trait GalaxyHandlerFunctions extends CommonSessionInterfacingFunctionality {
|
||||
import net.psforever.actors.session.AvatarActor
|
||||
|
||||
trait GalaxyHandlerFunctions extends CommonSessionInterfacingFunctionality with CommonHandlerFunctions {
|
||||
def ops: SessionGalaxyHandlers
|
||||
|
||||
def handleUpdateIgnoredPlayers(pkt: FriendsResponse): Unit
|
||||
|
||||
def handle(reply: GalaxyResponse.Response): Unit
|
||||
}
|
||||
|
||||
class SessionGalaxyHandlers(
|
||||
|
|
|
|||
|
|
@ -7,17 +7,14 @@ import net.psforever.objects.ce.Deployable
|
|||
import net.psforever.objects.guid.{GUIDTask, TaskWorkflow}
|
||||
import net.psforever.objects.serverobject.interior.Sidedness
|
||||
import net.psforever.packet.game.{GenericObjectActionMessage, ObjectDeleteMessage, PlanetsideAttributeMessage, TriggerEffectMessage}
|
||||
import net.psforever.services.local.LocalResponse
|
||||
import net.psforever.types.{PlanetSideGUID, Vector3}
|
||||
|
||||
trait LocalHandlerFunctions extends CommonSessionInterfacingFunctionality {
|
||||
trait LocalHandlerFunctions extends CommonSessionInterfacingFunctionality with CommonHandlerFunctions {
|
||||
def ops: SessionLocalHandlers
|
||||
|
||||
def handleTurretDeployableIsDismissed(obj: TurretDeployable): Unit
|
||||
|
||||
def handleDeployableIsDismissed(obj: Deployable): Unit
|
||||
|
||||
def handle(toChannel: String, guid: PlanetSideGUID, reply: LocalResponse.Response): Unit
|
||||
}
|
||||
|
||||
class SessionLocalHandlers(
|
||||
|
|
|
|||
|
|
@ -5,11 +5,14 @@ import akka.actor.{ActorContext, typed}
|
|||
import net.psforever.objects.serverobject.affinity.FactionAffinity
|
||||
import net.psforever.objects.serverobject.interior.Sidedness.OutsideOf
|
||||
import net.psforever.objects.{PlanetSideGameObject, Tool, Vehicle}
|
||||
import net.psforever.objects.vehicles.{CargoBehavior, MountableWeapons}
|
||||
import net.psforever.objects.vehicles.MountableWeapons
|
||||
import net.psforever.objects.vehicles.control.CargoBehavior
|
||||
import net.psforever.objects.vital.InGameHistory
|
||||
import net.psforever.packet.game.{DismountVehicleCargoMsg, GenericObjectActionMessage, InventoryStateMessage, MountVehicleCargoMsg, MountVehicleMsg, ObjectAttachMessage, ObjectDetachMessage, PlanetsideAttributeMessage}
|
||||
import net.psforever.services.Service
|
||||
import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage}
|
||||
import net.psforever.services.base.CachedEnvelope
|
||||
import net.psforever.services.base.envelope.MessageEnvelope
|
||||
import net.psforever.services.base.message.SendResponse
|
||||
import net.psforever.services.vehicle.VehicleAction
|
||||
import net.psforever.types.{BailType, PlanetSideGUID, Vector3}
|
||||
//
|
||||
import net.psforever.actors.session.AvatarActor
|
||||
|
|
@ -185,9 +188,10 @@ class SessionMountHandlers(
|
|||
avatarActor ! AvatarActor.DeactivateActiveImplants
|
||||
avatarActor ! AvatarActor.SuspendStaminaRegeneration(3.seconds)
|
||||
sendResponse(ObjectAttachMessage(objGuid, playerGuid, seatNum))
|
||||
continent.VehicleEvents ! VehicleServiceMessage(
|
||||
continent.VehicleEvents ! MessageEnvelope(
|
||||
continent.id,
|
||||
VehicleAction.MountVehicle(playerGuid, objGuid, seatNum)
|
||||
playerGuid,
|
||||
VehicleAction.MountVehicle(objGuid, seatNum)
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -202,13 +206,12 @@ class SessionMountHandlers(
|
|||
if (tplayer.BailProtection) {
|
||||
tplayer.ContributionFrom(obj)
|
||||
sessionLogic.keepAliveFunc = sessionLogic.zoning.NormalKeepAlive
|
||||
continent.VehicleEvents ! VehicleServiceMessage(
|
||||
continent.VehicleEvents ! MessageEnvelope(
|
||||
continent.id,
|
||||
VehicleAction.SendResponse(Service.defaultPlayerGUID, PlanetsideAttributeMessage(obj.GUID, 81, 1))
|
||||
)
|
||||
continent.VehicleEvents ! VehicleServiceMessage(
|
||||
continent.id,
|
||||
VehicleAction.SendResponse(Service.defaultPlayerGUID, ObjectDetachMessage(obj.GUID, tplayer.GUID, tplayer.Position, obj.Orientation))
|
||||
SendResponse(
|
||||
PlanetsideAttributeMessage(obj.GUID, 81, 1),
|
||||
ObjectDetachMessage(obj.GUID, tplayer.GUID, tplayer.Position, obj.Orientation)
|
||||
)
|
||||
)
|
||||
}
|
||||
else {
|
||||
|
|
@ -223,22 +226,10 @@ class SessionMountHandlers(
|
|||
sessionLogic.vehicles.ServerVehicleOverrideStop(v)
|
||||
}*/
|
||||
v.Velocity = Vector3.Zero
|
||||
continent.VehicleEvents ! VehicleServiceMessage(
|
||||
continent.VehicleEvents ! CachedEnvelope(
|
||||
continent.id,
|
||||
VehicleAction.VehicleState(
|
||||
tplayer.GUID,
|
||||
v.GUID,
|
||||
unk1 = 0,
|
||||
tplayer.Position,
|
||||
v.Orientation,
|
||||
v.Velocity,
|
||||
v.Flying,
|
||||
unk3 = 0,
|
||||
unk4 = 0,
|
||||
wheel_direction = 15,
|
||||
unk5 = false,
|
||||
unk6 = v.Cloaked
|
||||
)
|
||||
tplayer.GUID,
|
||||
VehicleAction.VehicleState(v.GUID, unk1 = 0, tplayer.Position, v.Orientation, v.Velocity, v.Flying, unk3 = 0, unk4 = 0, wheel_direction = 15, unk5 = false, unk6 = v.Cloaked)
|
||||
)
|
||||
case _ => ()
|
||||
}
|
||||
|
|
@ -260,9 +251,10 @@ class SessionMountHandlers(
|
|||
BailType.Normal
|
||||
}
|
||||
sendResponse(DismountVehicleMsg(playerGuid, bailType, wasKickedByDriver = false))
|
||||
continent.VehicleEvents ! VehicleServiceMessage(
|
||||
continent.VehicleEvents ! MessageEnvelope(
|
||||
continent.id,
|
||||
VehicleAction.DismountVehicle(playerGuid, bailType, unk2 = false)
|
||||
playerGuid,
|
||||
VehicleAction.DismountVehicle(bailType, unk2 = false)
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,9 @@ import net.psforever.objects.Player
|
|||
import net.psforever.packet.game.OutfitEventAction.{Initial, Leaving, OutfitInfo, OutfitRankNames, Unk1, Update, UpdateMemberCount}
|
||||
import net.psforever.packet.game.OutfitMembershipResponse.PacketType.CreateResponse
|
||||
import net.psforever.packet.game._
|
||||
import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage}
|
||||
import net.psforever.services.avatar.AvatarAction
|
||||
import net.psforever.services.base.envelope.{BundledEnvelope, MessageEnvelope}
|
||||
import net.psforever.services.base.message.{PlanetsideAttribute, SendResponse}
|
||||
import net.psforever.services.chat.OutfitChannel
|
||||
import net.psforever.types.ChatMessageType
|
||||
import net.psforever.util.Config
|
||||
|
|
@ -48,58 +50,62 @@ object SessionOutfitHandlers {
|
|||
import scala.concurrent.Future
|
||||
|
||||
def HandleOutfitForm(outfitName: String, player: Player, session: SessionData): Unit = {
|
||||
val zone = player.Zone
|
||||
val zoneid = zone.id
|
||||
val charid = player.CharId
|
||||
val pname = player.Name
|
||||
val cleanedName = sanitizeOutfitName(outfitName)
|
||||
|
||||
cleanedName match {
|
||||
case Some(validName) =>
|
||||
ctx.run(findOutfitByName(validName)).flatMap {
|
||||
case existing if existing.nonEmpty =>
|
||||
PlayerControl.sendResponse(player.Zone, player.Name,
|
||||
ChatMsg(ChatMessageType.UNK_227, "@OutfitErrorNameAlreadyTaken"))
|
||||
PlayerControl.sendResponse(zone, pname,
|
||||
ChatMsg(ChatMessageType.UNK_227, "@OutfitErrorNameAlreadyTaken")
|
||||
)
|
||||
Future.successful(())
|
||||
|
||||
case _ =>
|
||||
createNewOutfit(validName, player.Faction.id, player.CharId).map { outfit =>
|
||||
val seconds: Long =
|
||||
outfit.created.atZone(ZoneId.systemDefault()).toInstant.toEpochMilli / 1000
|
||||
|
||||
PlayerControl.sendResponse(player.Zone, player.Name,
|
||||
OutfitEvent(outfit.id, Update(
|
||||
OutfitInfo(
|
||||
outfit.name, 0, 0, 1,
|
||||
OutfitRankNames("", "", "", "", "", "", "", ""),
|
||||
"",
|
||||
14, unk11 = true, 0, seconds, 0, 0, 0))))
|
||||
|
||||
PlayerControl.sendResponse(player.Zone, player.Name,
|
||||
OutfitMemberUpdate(outfit.id, player.CharId, 7, flag = true))
|
||||
|
||||
PlayerControl.sendResponse(player.Zone, player.Name,
|
||||
ChatMsg(ChatMessageType.UNK_227, "@OutfitCreateSuccess"))
|
||||
|
||||
PlayerControl.sendResponse(player.Zone, player.Name,
|
||||
OutfitMembershipResponse(CreateResponse, 0, 0, player.CharId, 0, "", "", flag = true))
|
||||
|
||||
player.outfit_id = outfit.id
|
||||
player.outfit_name = outfit.name
|
||||
|
||||
player.Zone.AvatarEvents ! AvatarServiceMessage(player.Zone.id,
|
||||
AvatarAction.PlanetsideAttributeToAll(player.GUID, 39, outfit.id))
|
||||
|
||||
player.Zone.AvatarEvents ! AvatarServiceMessage(player.Zone.id,
|
||||
AvatarAction.PlanetsideStringAttribute(player.GUID, 0, outfit.name))
|
||||
|
||||
session.chat.JoinChannel(OutfitChannel(player.outfit_id))
|
||||
createNewOutfit(validName, player.Faction.id, charid).map { outfit =>
|
||||
val outfitId = outfit.id
|
||||
val outfitName = outfit.name
|
||||
val seconds: Long = outfit.created.atZone(ZoneId.systemDefault()).toInstant.toEpochMilli / 1000
|
||||
player.outfit_id = outfitId
|
||||
player.outfit_name = outfitName
|
||||
zone.AvatarEvents ! BundledEnvelope(
|
||||
MessageEnvelope(pname, SendResponse(
|
||||
OutfitEvent(outfitId, Update(
|
||||
OutfitInfo(
|
||||
outfitName, 0, 0, 1,
|
||||
OutfitRankNames("", "", "", "", "", "", "", ""),
|
||||
"",
|
||||
14, unk11 = true, 0, seconds, 0, 0, 0)
|
||||
)),
|
||||
OutfitMemberUpdate(outfitId, charid, 7, flag = true),
|
||||
ChatMsg(ChatMessageType.UNK_227, "@OutfitCreateSuccess"),
|
||||
OutfitMembershipResponse(CreateResponse, 0, 0, charid, 0, "", "", flag = true),
|
||||
)),
|
||||
MessageEnvelope(
|
||||
zoneid,
|
||||
PlanetsideAttribute(player.GUID, 39, outfitId)
|
||||
),
|
||||
MessageEnvelope(
|
||||
zoneid,
|
||||
player.GUID,
|
||||
AvatarAction.PlanetsideStringAttribute(0, outfitName)
|
||||
)
|
||||
)
|
||||
session.chat.JoinChannel(OutfitChannel(outfitId))
|
||||
}
|
||||
.recover { case e =>
|
||||
e.printStackTrace()
|
||||
PlayerControl.sendResponse(player.Zone, player.Name,
|
||||
ChatMsg(ChatMessageType.UNK_227, "@OutfitCreateFailure"))
|
||||
PlayerControl.sendResponse(zone, pname,
|
||||
ChatMsg(ChatMessageType.UNK_227, "@OutfitCreateFailure")
|
||||
)
|
||||
}
|
||||
}
|
||||
case None =>
|
||||
PlayerControl.sendResponse(player.Zone, player.Name,
|
||||
ChatMsg(ChatMessageType.UNK_227, "@OutfitCreateFailure"))
|
||||
PlayerControl.sendResponse(zone, pname, ChatMsg(ChatMessageType.UNK_227, "@OutfitCreateFailure"))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -120,69 +126,80 @@ object SessionOutfitHandlers {
|
|||
}
|
||||
|
||||
def HandleOutfitInviteAccept(invited: Player, session: SessionData): Unit = {
|
||||
OutfitInviteManager.getOutfitInvite(invited.CharId) match {
|
||||
val toName = invited.Name
|
||||
val toCharId = invited.CharId
|
||||
val toZone = invited.Zone
|
||||
val toZoneId = toZone.id
|
||||
val toGuid = invited.GUID
|
||||
OutfitInviteManager.getOutfitInvite(toCharId) match {
|
||||
case Some(outfitInvite) =>
|
||||
val fromName = outfitInvite.sentFrom.Name
|
||||
val fromCharId = outfitInvite.sentFrom.CharId
|
||||
val fromZone = outfitInvite.sentFrom.Zone
|
||||
val outfitId = outfitInvite.sentFrom.outfit_id
|
||||
|
||||
(for {
|
||||
_ <- addMemberToOutfit(outfitId, invited.CharId)
|
||||
_ <- addMemberToOutfit(outfitId, toCharId)
|
||||
outfitOpt <- ctx.run(getOutfitById(outfitId)).map(_.headOption)
|
||||
memberCount <- ctx.run(getOutfitMemberCount(outfitId))
|
||||
points <- ctx.run(getOutfitPoints(outfitId)).map(_.headOption.map(_.points).getOrElse(0L))
|
||||
} yield (outfitOpt, memberCount, points))
|
||||
.map {
|
||||
case (Some(outfit), memberCount, points) =>
|
||||
|
||||
PlayerControl.sendResponse(outfitInvite.sentFrom.Zone, outfitInvite.sentFrom.Name,
|
||||
OutfitMembershipResponse(
|
||||
OutfitMembershipResponse.PacketType.InviteAccepted, 0, 0,
|
||||
invited.CharId, outfitInvite.sentFrom.CharId, invited.Name, outfit.name, flag = false))
|
||||
|
||||
PlayerControl.sendResponse(invited.Zone, invited.Name,
|
||||
OutfitMembershipResponse(
|
||||
OutfitMembershipResponse.PacketType.InviteAccepted, 0, 0,
|
||||
invited.CharId, outfitInvite.sentFrom.CharId, invited.Name, outfit.name, flag = true))
|
||||
|
||||
PlayerControl.sendResponse(outfitInvite.sentFrom.Zone, outfitInvite.sentFrom.Name,
|
||||
OutfitEvent(outfitId, UpdateMemberCount(memberCount)))
|
||||
|
||||
PlayerControl.sendResponse(outfitInvite.sentFrom.Zone, outfitInvite.sentFrom.Name,
|
||||
OutfitMemberEvent(outfitId, invited.CharId,
|
||||
OutfitMemberEventAction.Update(invited.Name, 0, 0, 0,
|
||||
OutfitMemberEventAction.PacketType.Padding, 0)))
|
||||
|
||||
val outfitName = outfit.name
|
||||
val seconds: Long = outfit.created.atZone(ZoneId.systemDefault()).toInstant.toEpochMilli / 1000
|
||||
PlayerControl.sendResponse(invited.Zone, invited.Name,
|
||||
OutfitEvent(outfitId, Initial(OutfitInfo(
|
||||
outfit.name, points, points, memberCount,
|
||||
OutfitRankNames("", "", "", "", "", "", "", ""),
|
||||
outfit.motd.getOrElse(""),
|
||||
14, unk11 = true, 0, seconds, 0, 0, 0))))
|
||||
|
||||
PlayerControl.sendResponse(invited.Zone, invited.Name,
|
||||
OutfitMemberUpdate(outfit.id, invited.CharId, 0, flag=true))
|
||||
|
||||
OutfitInviteManager.removeOutfitInvite(invited.CharId)
|
||||
|
||||
session.chat.JoinChannel(OutfitChannel(outfit.id))
|
||||
invited.outfit_id = outfit.id
|
||||
invited.outfit_name = outfit.name
|
||||
|
||||
invited.Zone.AvatarEvents ! AvatarServiceMessage(invited.Zone.id,
|
||||
AvatarAction.PlanetsideAttributeToAll(invited.GUID, 39, outfit.id))
|
||||
|
||||
invited.Zone.AvatarEvents ! AvatarServiceMessage(invited.Zone.id,
|
||||
AvatarAction.PlanetsideStringAttribute(invited.GUID, 0, outfit.name))
|
||||
case (None, _, _) =>
|
||||
|
||||
PlayerControl.sendResponse(invited.Zone, invited.Name,
|
||||
ChatMsg(ChatMessageType.UNK_227, "Failed to join outfit"))
|
||||
}
|
||||
.recover { case _ =>
|
||||
PlayerControl.sendResponse(invited.Zone, invited.Name,
|
||||
ChatMsg(ChatMessageType.UNK_227, "Failed to join outfit"))
|
||||
fromZone.AvatarEvents ! BundledEnvelope(
|
||||
MessageEnvelope(fromName, SendResponse(
|
||||
OutfitMembershipResponse(
|
||||
OutfitMembershipResponse.PacketType.InviteAccepted, 0, 0,
|
||||
toCharId, fromCharId, toName, outfitName, flag = false
|
||||
),
|
||||
OutfitEvent(outfitId, UpdateMemberCount(memberCount)),
|
||||
OutfitMemberEvent(outfitId, toCharId,
|
||||
OutfitMemberEventAction.Update(toName, 0, 0, 0,
|
||||
OutfitMemberEventAction.PacketType.Padding, 0
|
||||
)
|
||||
)
|
||||
))
|
||||
)
|
||||
toZone.AvatarEvents ! BundledEnvelope(
|
||||
MessageEnvelope(toName, SendResponse(
|
||||
OutfitMembershipResponse(
|
||||
OutfitMembershipResponse.PacketType.InviteAccepted, 0, 0,
|
||||
toCharId, fromCharId, toName, outfitName, flag = true
|
||||
),
|
||||
OutfitEvent(outfitId, Initial(OutfitInfo(
|
||||
outfitName, points, points, memberCount,
|
||||
OutfitRankNames("", "", "", "", "", "", "", ""),
|
||||
outfit.motd.getOrElse(""),
|
||||
14, unk11 = true, 0, seconds, 0, 0, 0
|
||||
))),
|
||||
OutfitMemberUpdate(outfitId, toCharId, 0, flag=true)
|
||||
)),
|
||||
MessageEnvelope(
|
||||
toZoneId,
|
||||
PlanetsideAttribute(toGuid, 39, outfitId)
|
||||
),
|
||||
MessageEnvelope(
|
||||
toZoneId,
|
||||
toGuid,
|
||||
AvatarAction.PlanetsideStringAttribute(0, outfitName)
|
||||
)
|
||||
)
|
||||
OutfitInviteManager.removeOutfitInvite(toCharId)
|
||||
session.chat.JoinChannel(OutfitChannel(outfitId))
|
||||
invited.outfit_id = outfitId
|
||||
invited.outfit_name = outfitName
|
||||
case (None, _, _) => ()
|
||||
PlayerControl.sendResponse(toZone, toName,
|
||||
ChatMsg(ChatMessageType.UNK_227, "Failed to join outfit")
|
||||
)
|
||||
}
|
||||
case None =>
|
||||
.recover { case _ =>
|
||||
PlayerControl.sendResponse(toZone, toName,
|
||||
ChatMsg(ChatMessageType.UNK_227, "Failed to join outfit")
|
||||
)
|
||||
}
|
||||
case None => ()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -206,72 +223,76 @@ object SessionOutfitHandlers {
|
|||
}
|
||||
|
||||
def HandleOutfitKick(zones: Seq[Zone], kickedId: Long, kickedBy: Player, session: SessionData): Unit = {
|
||||
val outfit_id = kickedBy.outfit_id
|
||||
// if same id, player has left the outfit by their own choice
|
||||
if (kickedId == kickedBy.CharId) {
|
||||
|
||||
// store outfit_id since it will be nulled soon
|
||||
val outfit_id = kickedBy.outfit_id
|
||||
|
||||
removeMemberFromOutfit(outfit_id, kickedId).map {
|
||||
case (deleted, _) =>
|
||||
if (deleted > 0) {
|
||||
|
||||
PlayerControl.sendResponse(kickedBy.Zone, kickedBy.Name,
|
||||
OutfitEvent(outfit_id, Leaving())
|
||||
kickedBy.Zone.AvatarEvents ! BundledEnvelope(
|
||||
MessageEnvelope(kickedBy.Name, SendResponse(OutfitEvent(outfit_id, Leaving()))),
|
||||
MessageEnvelope(
|
||||
kickedBy.Zone.id,
|
||||
PlanetsideAttribute(kickedBy.GUID, 39, 0)
|
||||
),
|
||||
MessageEnvelope(
|
||||
kickedBy.Zone.id,
|
||||
kickedBy.GUID,
|
||||
AvatarAction.PlanetsideStringAttribute(0, "")
|
||||
)
|
||||
)
|
||||
|
||||
session.chat.LeaveChannel(OutfitChannel(outfit_id))
|
||||
kickedBy.outfit_name = ""
|
||||
kickedBy.outfit_id = 0
|
||||
|
||||
zones.filter(z => z.AllPlayers.nonEmpty).flatMap(_.AllPlayers)
|
||||
.filter(p => p.outfit_id == outfit_id).foreach(outfitMember =>
|
||||
PlayerControl.sendResponse(outfitMember.Zone, outfitMember.Name,
|
||||
OutfitMemberEvent(outfit_id, kickedId, OutfitMemberEventAction.Kicked()))
|
||||
)
|
||||
|
||||
kickedBy.Zone.AvatarEvents ! AvatarServiceMessage(kickedBy.Zone.id,
|
||||
AvatarAction.PlanetsideAttributeToAll(kickedBy.GUID, 39, 0))
|
||||
|
||||
kickedBy.Zone.AvatarEvents ! AvatarServiceMessage(kickedBy.Zone.id,
|
||||
AvatarAction.PlanetsideStringAttribute(kickedBy.GUID, 0, ""))
|
||||
zones
|
||||
.filter(z => z.AllPlayers.nonEmpty)
|
||||
.flatMap(_.AllPlayers)
|
||||
.filter(p => p.outfit_id == outfit_id)
|
||||
.foreach(outfitMember =>
|
||||
PlayerControl.sendResponse(outfitMember.Zone, outfitMember.Name,
|
||||
OutfitMemberEvent(outfit_id, kickedId, OutfitMemberEventAction.Kicked())
|
||||
)
|
||||
)
|
||||
}
|
||||
}.recover { case e =>
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
else {
|
||||
removeMemberFromOutfit(kickedBy.outfit_id, kickedId).map {
|
||||
removeMemberFromOutfit(outfit_id, kickedId).map {
|
||||
case (deleted, _) =>
|
||||
if (deleted > 0) {
|
||||
findPlayerByIdForOutfitAction(zones, kickedId, kickedBy).foreach { kicked =>
|
||||
|
||||
PlayerControl.sendResponse(kicked.Zone, kicked.Name,
|
||||
OutfitEvent(kickedBy.outfit_id, Leaving())
|
||||
kicked.Zone.AvatarEvents ! BundledEnvelope(
|
||||
MessageEnvelope(kicked.Name, SendResponse(
|
||||
OutfitEvent(outfit_id, Leaving()),
|
||||
OutfitMembershipResponse(
|
||||
OutfitMembershipResponse.PacketType.YouGotKicked, 0, 1,
|
||||
kickedBy.CharId, kicked.CharId, kickedBy.Name, kicked.Name, flag = false
|
||||
)
|
||||
)),
|
||||
MessageEnvelope(kicked.Zone.id,
|
||||
PlanetsideAttribute(kicked.GUID, 39, 0)
|
||||
),
|
||||
MessageEnvelope(
|
||||
kicked.Zone.id,
|
||||
kicked.GUID,
|
||||
AvatarAction.PlanetsideStringAttribute(0, "")
|
||||
),
|
||||
MessageEnvelope(kicked.Name,
|
||||
AvatarAction.RemoveFromOutfitChat(outfit_id)
|
||||
),
|
||||
MessageEnvelope(kicked.Name, SendResponse(
|
||||
OutfitMemberEvent(outfit_id, kickedId, OutfitMemberEventAction.Kicked())
|
||||
))
|
||||
)
|
||||
|
||||
PlayerControl.sendResponse(kicked.Zone, kicked.Name,
|
||||
OutfitMembershipResponse(OutfitMembershipResponse.PacketType.YouGotKicked, 0, 1,
|
||||
kickedBy.CharId, kicked.CharId, kickedBy.Name, kicked.Name, flag = false))
|
||||
|
||||
kicked.Zone.AvatarEvents ! AvatarServiceMessage(kicked.Zone.id,
|
||||
AvatarAction.PlanetsideAttributeToAll(kicked.GUID, 39, 0))
|
||||
|
||||
kicked.Zone.AvatarEvents ! AvatarServiceMessage(kicked.Zone.id,
|
||||
AvatarAction.PlanetsideStringAttribute(kicked.GUID, 0, ""))
|
||||
|
||||
kicked.Zone.AvatarEvents ! AvatarServiceMessage(
|
||||
kicked.Name, AvatarAction.RemoveFromOutfitChat(kickedBy.outfit_id))
|
||||
|
||||
kicked.outfit_id = 0
|
||||
kicked.outfit_name = ""
|
||||
PlayerControl.sendResponse(kicked.Zone, kicked.Name,
|
||||
OutfitMemberEvent(kickedBy.outfit_id, kickedId, OutfitMemberEventAction.Kicked()))
|
||||
}
|
||||
val avatarName: Future[Option[String]] =
|
||||
ctx.run(
|
||||
quote { query[Avatar].filter(_.id == lift(kickedId)).map(_.name) }
|
||||
).map(_.headOption)
|
||||
ctx.run(quote { query[Avatar].filter(_.id == lift(kickedId)).map(_.name) }).map(_.headOption)
|
||||
|
||||
avatarName.foreach {
|
||||
case Some(name) => PlayerControl.sendResponse(kickedBy.Zone, kickedBy.Name,
|
||||
|
|
@ -280,10 +301,14 @@ object SessionOutfitHandlers {
|
|||
case None => PlayerControl.sendResponse(kickedBy.Zone, kickedBy.Name,
|
||||
OutfitMembershipResponse(OutfitMembershipResponse.PacketType.YouKicked, 0, 1, kickedBy.CharId, kickedId, "NameNotFound", "", flag = true))
|
||||
}
|
||||
zones.filter(z => z.AllPlayers.nonEmpty).flatMap(_.AllPlayers)
|
||||
.filter(p => p.outfit_id == kickedBy.outfit_id).foreach(outfitMember =>
|
||||
PlayerControl.sendResponse(outfitMember.Zone, outfitMember.Name,
|
||||
OutfitMemberEvent(kickedBy.outfit_id, kickedId, OutfitMemberEventAction.Kicked()))
|
||||
zones
|
||||
.filter(z => z.AllPlayers.nonEmpty)
|
||||
.flatMap(_.AllPlayers)
|
||||
.filter(p => p.outfit_id == kickedBy.outfit_id)
|
||||
.foreach(outfitMember =>
|
||||
PlayerControl.sendResponse(outfitMember.Zone, outfitMember.Name,
|
||||
OutfitMemberEvent(kickedBy.outfit_id, kickedId, OutfitMemberEventAction.Kicked())
|
||||
)
|
||||
)
|
||||
// this needs to be the kicked player
|
||||
// session.chat.LeaveChannel(OutfitChannel(kickedBy.outfit_id))
|
||||
|
|
@ -297,18 +322,13 @@ object SessionOutfitHandlers {
|
|||
}
|
||||
|
||||
def HandleOutfitPromote(zones: Seq[Zone], promotedId: Long, newRank: Int, promoter: Player): Unit = {
|
||||
|
||||
val outfit_id = promoter.outfit_id
|
||||
|
||||
findPlayerByIdForOutfitAction(zones, promotedId, promoter).foreach { promoted =>
|
||||
|
||||
if (newRank == 7) {
|
||||
|
||||
// demote owner to rank 6
|
||||
// promote promoted to rank 7
|
||||
// update outfit
|
||||
updateOutfitOwner(outfit_id, promoter.avatar.id, promoted.avatar.id)
|
||||
|
||||
// TODO: does every member get the notification like this?
|
||||
getOutfitMemberPoints(outfit_id, promoter.avatar.id).map {
|
||||
owner_points =>
|
||||
|
|
@ -324,7 +344,6 @@ object SessionOutfitHandlers {
|
|||
})
|
||||
})
|
||||
}
|
||||
|
||||
// update promoter rank
|
||||
PlayerControl.sendResponse(
|
||||
promoter.Zone, promoter.Name,
|
||||
|
|
@ -338,17 +357,19 @@ object SessionOutfitHandlers {
|
|||
// TODO: does every member get the notification like this?
|
||||
getOutfitMemberPoints(outfit_id, promoted.avatar.id).map {
|
||||
member_points =>
|
||||
// tell everyone about the new rank of the promoted member
|
||||
zones.foreach(zone => {
|
||||
zone.AllPlayers
|
||||
zones.foreach { zone =>
|
||||
// tell everyone about the new rank of the promoted member
|
||||
val messages = zone.AllPlayers
|
||||
.filter(_.outfit_id == outfit_id)
|
||||
.foreach(player => {
|
||||
PlayerControl.sendResponse(
|
||||
zone, player.Name,
|
||||
.map { player =>
|
||||
MessageEnvelope(player.Name, SendResponse(
|
||||
OutfitMemberEvent(outfit_id, promoted.avatar.id,
|
||||
OutfitMemberEventAction.Update(promoted.Name, newRank, member_points, 0, OutfitMemberEventAction.PacketType.Padding, 0)))
|
||||
})
|
||||
})
|
||||
OutfitMemberEventAction.Update(promoted.Name, newRank, member_points, 0, OutfitMemberEventAction.PacketType.Padding, 0)
|
||||
)
|
||||
))
|
||||
}
|
||||
zone.AvatarEvents ! BundledEnvelope(messages)
|
||||
}
|
||||
}
|
||||
|
||||
// update promoted rank
|
||||
|
|
@ -364,7 +385,6 @@ object SessionOutfitHandlers {
|
|||
memberCount <- ctx.run(query[Outfitmember].filter(_.outfit_id == lift(outfitId)).size)
|
||||
pointsTotal <- ctx.run(querySchema[OutfitpointMv]("outfitpoint_mv").filter(_.outfit_id == lift(outfitId)))
|
||||
} yield (outfitOpt, memberCount, pointsTotal.headOption.map(_.points).getOrElse(0L))
|
||||
|
||||
val membersF = ctx.run(getOutfitMembersWithDetails(outfitId))
|
||||
|
||||
for {
|
||||
|
|
@ -373,43 +393,42 @@ object SessionOutfitHandlers {
|
|||
} yield {
|
||||
outfitOpt.foreach { outfit =>
|
||||
val seconds: Long = outfit.created.atZone(ZoneId.systemDefault()).toInstant.toEpochMilli / 1000
|
||||
|
||||
PlayerControl.sendResponse(player.Zone, player.Name,
|
||||
OutfitEvent(outfit.id, Initial(OutfitInfo(
|
||||
outfit.name,
|
||||
totalPoints,
|
||||
totalPoints,
|
||||
memberCount,
|
||||
OutfitRankNames(
|
||||
outfit.rank0.getOrElse(""),
|
||||
outfit.rank1.getOrElse(""),
|
||||
outfit.rank2.getOrElse(""),
|
||||
outfit.rank3.getOrElse(""),
|
||||
outfit.rank4.getOrElse(""),
|
||||
outfit.rank5.getOrElse(""),
|
||||
outfit.rank6.getOrElse(""),
|
||||
outfit.rank7.getOrElse(""),
|
||||
),
|
||||
outfit.motd.getOrElse(""),
|
||||
14, unk11 = true, 0, seconds, 0, 0, 0))))
|
||||
|
||||
members.foreach { case (avatarId, avatarName, points, rank, login) =>
|
||||
val outfitEventInitial = OutfitEvent(outfit.id, Initial(OutfitInfo(
|
||||
outfit.name,
|
||||
totalPoints,
|
||||
totalPoints,
|
||||
memberCount,
|
||||
OutfitRankNames(
|
||||
outfit.rank0.getOrElse(""),
|
||||
outfit.rank1.getOrElse(""),
|
||||
outfit.rank2.getOrElse(""),
|
||||
outfit.rank3.getOrElse(""),
|
||||
outfit.rank4.getOrElse(""),
|
||||
outfit.rank5.getOrElse(""),
|
||||
outfit.rank6.getOrElse(""),
|
||||
outfit.rank7.getOrElse(""),
|
||||
),
|
||||
outfit.motd.getOrElse(""),
|
||||
14, unk11 = true, 0, seconds, 0, 0, 0))
|
||||
)
|
||||
val memberEventList = members.map { case (avatarId, avatarName, points, rank, login) =>
|
||||
val lastLogin = findPlayerByIdForOutfitAction(zones, avatarId, player) match {
|
||||
case Some(_) => 0L
|
||||
case None if player.Name == avatarName => 0L
|
||||
case None => (System.currentTimeMillis() - login.atZone(ZoneId.systemDefault()).toInstant.toEpochMilli) / 1000
|
||||
}
|
||||
PlayerControl.sendResponse(player.Zone, player.Name,
|
||||
OutfitMemberEvent(outfit.id, avatarId,
|
||||
OutfitMemberEventAction.Update(
|
||||
avatarName,
|
||||
rank,
|
||||
points,
|
||||
lastLogin,
|
||||
OutfitMemberEventAction.PacketType.Padding, 0)))
|
||||
OutfitMemberEvent(outfit.id, avatarId,
|
||||
OutfitMemberEventAction.Update(
|
||||
avatarName,
|
||||
rank,
|
||||
points,
|
||||
lastLogin,
|
||||
OutfitMemberEventAction.PacketType.Padding, 0)
|
||||
)
|
||||
}
|
||||
PlayerControl.sendResponse(player.Zone, player.Name,
|
||||
OutfitEvent(outfit.id, Unk1()))
|
||||
player.Zone.AvatarEvents ! MessageEnvelope(player.Name, SendResponse(
|
||||
outfitEventInitial +: memberEventList :+ OutfitEvent(outfit.id, Unk1())
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -420,16 +439,13 @@ object SessionOutfitHandlers {
|
|||
|
||||
futureResult.onComplete {
|
||||
case Success(rows) =>
|
||||
rows.foreach { case (outfitId, points, name, leaderName, memberCount) =>
|
||||
PlayerControl.sendResponse(player.Zone, player.Name,
|
||||
player.Zone.AvatarEvents ! MessageEnvelope(player.Name, SendResponse(
|
||||
rows.map { case (outfitId, points, name, leaderName, memberCount) =>
|
||||
OutfitListEvent(
|
||||
OutfitListEventAction.ListElementOutfit(
|
||||
outfitId,
|
||||
points,
|
||||
memberCount,
|
||||
name,
|
||||
leaderName)))
|
||||
}
|
||||
OutfitListEventAction.ListElementOutfit(outfitId, points, memberCount, name, leaderName)
|
||||
)
|
||||
}
|
||||
))
|
||||
|
||||
case Failure(_) =>
|
||||
PlayerControl.sendResponse(player.Zone, player.Name,
|
||||
|
|
@ -439,9 +455,7 @@ object SessionOutfitHandlers {
|
|||
}
|
||||
|
||||
def HandleOutfitMotd(zones: Seq[Zone], message: String, player: Player): Unit = {
|
||||
|
||||
val outfit_id = player.outfit_id
|
||||
|
||||
val outfitDetails = for {
|
||||
_ <- updateOutfitMotd(outfit_id, message)
|
||||
outfitOpt <- ctx.run(getOutfitById(outfit_id)).map(_.headOption)
|
||||
|
|
@ -453,9 +467,8 @@ object SessionOutfitHandlers {
|
|||
(outfitOpt, memberCount, totalPoints) <- outfitDetails
|
||||
} yield {
|
||||
outfitOpt.foreach { outfit =>
|
||||
|
||||
// send to all online players in outfit
|
||||
val outfit_event = OutfitEvent(
|
||||
val outfit_event = SendResponse(OutfitEvent(
|
||||
outfit_id,
|
||||
Update(
|
||||
OutfitInfo(
|
||||
|
|
@ -483,19 +496,15 @@ object SessionOutfitHandlers {
|
|||
unk25 = 0
|
||||
)
|
||||
)
|
||||
)
|
||||
))
|
||||
|
||||
zones.foreach(zone => {
|
||||
zone.AllPlayers
|
||||
.filter(_.outfit_id == outfit_id)
|
||||
.filter(_.outfit_window_open)
|
||||
.foreach(player => {
|
||||
PlayerControl.sendResponse(
|
||||
zone, player.Name,
|
||||
outfit_event
|
||||
)
|
||||
})
|
||||
})
|
||||
zones.foreach { zone =>
|
||||
zone.AvatarEvents ! BundledEnvelope(
|
||||
zone.AllPlayers
|
||||
.filter { p => p.outfit_id == outfit_id && p.outfit_window_open }
|
||||
.map(p => MessageEnvelope(p.Name, outfit_event))
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -504,9 +513,7 @@ object SessionOutfitHandlers {
|
|||
}
|
||||
|
||||
def HandleOutfitRank(zones: Seq[Zone], list: List[Option[String]], player: Player): Unit = {
|
||||
|
||||
val outfit_id = player.outfit_id
|
||||
|
||||
val outfitDetails = for {
|
||||
_ <- updateOutfitRanks(outfit_id, list)
|
||||
outfitOpt <- ctx.run(getOutfitById(outfit_id)).map(_.headOption)
|
||||
|
|
@ -518,9 +525,8 @@ object SessionOutfitHandlers {
|
|||
(outfitOpt, memberCount, totalPoints) <- outfitDetails
|
||||
} yield {
|
||||
outfitOpt.foreach { outfit =>
|
||||
|
||||
// send to all online players in outfit with window open
|
||||
val outfit_event = OutfitEvent(
|
||||
val outfit_event = SendResponse(OutfitEvent(
|
||||
outfit_id,
|
||||
Update(
|
||||
OutfitInfo(
|
||||
|
|
@ -548,19 +554,15 @@ object SessionOutfitHandlers {
|
|||
unk25 = 0
|
||||
)
|
||||
)
|
||||
)
|
||||
))
|
||||
|
||||
zones.foreach(zone => {
|
||||
zone.AllPlayers
|
||||
.filter(_.outfit_id == outfit_id)
|
||||
.filter(_.outfit_window_open)
|
||||
.foreach(player => {
|
||||
PlayerControl.sendResponse(
|
||||
zone, player.Name,
|
||||
outfit_event
|
||||
)
|
||||
})
|
||||
})
|
||||
zones.foreach { zone =>
|
||||
zone.AvatarEvents ! BundledEnvelope(
|
||||
zone.AllPlayers
|
||||
.filter { p => p.outfit_id == outfit_id && p.outfit_window_open }
|
||||
.map(p => MessageEnvelope(p.Name, outfit_event))
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -596,29 +598,34 @@ object SessionOutfitHandlers {
|
|||
.map {
|
||||
case (Some(outfit), memberCount, points) =>
|
||||
val seconds: Long = outfit.created.atZone(ZoneId.systemDefault()).toInstant.toEpochMilli / 1000
|
||||
|
||||
PlayerControl.sendResponse(player.Zone, player.Name,
|
||||
OutfitEvent(outfitId, Update(OutfitInfo(
|
||||
outfit.name, points, points, memberCount,
|
||||
OutfitRankNames(outfit.rank0.getOrElse(""), outfit.rank1.getOrElse(""), outfit.rank2.getOrElse(""),
|
||||
outfit.rank3.getOrElse(""), outfit.rank4.getOrElse(""), outfit.rank5.getOrElse(""),
|
||||
outfit.rank6.getOrElse(""), outfit.rank7.getOrElse("")),
|
||||
outfit.motd.getOrElse(""),
|
||||
14, unk11 = true, 0, seconds, 0, 0, 0))))
|
||||
|
||||
PlayerControl.sendResponse(player.Zone, player.Name,
|
||||
OutfitMemberUpdate(outfit.id, player.CharId, membership.rank, flag = true))
|
||||
|
||||
player.Zone.AvatarEvents ! BundledEnvelope(
|
||||
MessageEnvelope(player.Name, SendResponse(
|
||||
OutfitEvent(outfitId, Update(OutfitInfo(
|
||||
outfit.name, points, points, memberCount,
|
||||
OutfitRankNames(
|
||||
outfit.rank0.getOrElse(""), outfit.rank1.getOrElse(""), outfit.rank2.getOrElse(""),
|
||||
outfit.rank3.getOrElse(""), outfit.rank4.getOrElse(""), outfit.rank5.getOrElse(""),
|
||||
outfit.rank6.getOrElse(""), outfit.rank7.getOrElse("")
|
||||
),
|
||||
outfit.motd.getOrElse(""),
|
||||
14, unk11 = true, 0, seconds, 0, 0, 0
|
||||
))),
|
||||
OutfitMemberUpdate(outfit.id, player.CharId, membership.rank, flag = true)
|
||||
)),
|
||||
MessageEnvelope(
|
||||
player.Zone.id,
|
||||
PlanetsideAttribute(player.GUID, 39, outfit.id)
|
||||
),
|
||||
MessageEnvelope(
|
||||
player.Zone.id,
|
||||
player.GUID,
|
||||
AvatarAction.PlanetsideStringAttribute(0, outfit.name)
|
||||
)
|
||||
)
|
||||
session.chat.JoinChannel(OutfitChannel(outfit.id))
|
||||
player.outfit_id = outfit.id
|
||||
player.outfit_name = outfit.name
|
||||
|
||||
player.Zone.AvatarEvents ! AvatarServiceMessage(player.Zone.id,
|
||||
AvatarAction.PlanetsideAttributeToAll(player.GUID, 39, outfit.id))
|
||||
|
||||
player.Zone.AvatarEvents ! AvatarServiceMessage(player.Zone.id,
|
||||
AvatarAction.PlanetsideStringAttribute(player.GUID, 0, outfit.name))
|
||||
|
||||
case (None, _, _) =>
|
||||
PlayerControl.sendResponse(player.Zone, player.Name,
|
||||
ChatMsg(ChatMessageType.UNK_227, "Failed to load outfit"))
|
||||
|
|
@ -849,7 +856,7 @@ object SessionOutfitHandlers {
|
|||
query[Outfit]
|
||||
.filter(_.id == lift(outfit_id))
|
||||
.update(
|
||||
_.rank0 -> lift(colorized(0)),
|
||||
_.rank0 -> lift(colorized.head),
|
||||
_.rank1 -> lift(colorized(1)),
|
||||
_.rank2 -> lift(colorized(2)),
|
||||
_.rank3 -> lift(colorized(3)),
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@
|
|||
package net.psforever.actors.session.support
|
||||
|
||||
import akka.actor.{ActorContext, ActorRef, typed}
|
||||
import net.psforever.services.base.envelope.MessageEnvelope
|
||||
import net.psforever.services.base.message.PlanetsideAttribute
|
||||
import net.psforever.services.teamwork.SquadServiceResponse
|
||||
|
||||
import scala.collection.mutable
|
||||
|
|
@ -10,7 +12,6 @@ import net.psforever.actors.session.AvatarActor
|
|||
import net.psforever.objects.teamwork.Squad
|
||||
import net.psforever.objects.{Default, Player}
|
||||
import net.psforever.packet.game._
|
||||
import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage}
|
||||
import net.psforever.services.teamwork.{SquadResponse, SquadServiceMessage, SquadAction => SquadServiceAction}
|
||||
import net.psforever.types.{PlanetSideEmpire, PlanetSideGUID, Vector3}
|
||||
|
||||
|
|
@ -105,9 +106,10 @@ class SessionSquadHandlers(
|
|||
squadUI.get(player.CharId) match {
|
||||
case Some(elem) =>
|
||||
sendResponse(PlanetsideAttributeMessage(player.GUID, 31, squad_supplement_id))
|
||||
continent.AvatarEvents ! AvatarServiceMessage(
|
||||
continent.AvatarEvents ! MessageEnvelope(
|
||||
s"${player.Faction}",
|
||||
AvatarAction.PlanetsideAttribute(player.GUID, 31, squad_supplement_id)
|
||||
player.GUID,
|
||||
PlanetsideAttribute(player.GUID, 31, squad_supplement_id)
|
||||
)
|
||||
sendResponse(PlanetsideAttributeMessage(player.GUID, 32, elem.index))
|
||||
case _ =>
|
||||
|
|
@ -286,7 +288,7 @@ class SessionSquadHandlers(
|
|||
* @param value value to associate the player
|
||||
*/
|
||||
def GiveSquadColorsForOthers(guid: PlanetSideGUID, factionChannel: String, value: Long): Unit = {
|
||||
continent.AvatarEvents ! AvatarServiceMessage(factionChannel, AvatarAction.PlanetsideAttribute(guid, 31, value))
|
||||
continent.AvatarEvents ! MessageEnvelope(factionChannel, guid, PlanetsideAttribute(guid, 31, value))
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -5,13 +5,10 @@ import akka.actor.{ActorContext, ActorRef, typed}
|
|||
import net.psforever.actors.session.AvatarActor
|
||||
import net.psforever.objects.Vehicle
|
||||
import net.psforever.packet.game.ChatMsg
|
||||
import net.psforever.services.vehicle.VehicleResponse
|
||||
import net.psforever.types.{ChatMessageType, DriveState, PlanetSideGUID}
|
||||
|
||||
trait VehicleHandlerFunctions extends CommonSessionInterfacingFunctionality {
|
||||
trait VehicleHandlerFunctions extends CommonSessionInterfacingFunctionality with CommonHandlerFunctions {
|
||||
def ops: SessionVehicleHandlers
|
||||
|
||||
def handle(toChannel: String, guid: PlanetSideGUID, reply: VehicleResponse.Response): Unit
|
||||
}
|
||||
|
||||
class SessionVehicleHandlers(
|
||||
|
|
|
|||
|
|
@ -27,7 +27,9 @@ import net.psforever.objects.vital.interaction.DamageInteraction
|
|||
import net.psforever.objects.vital.projectile.ProjectileReason
|
||||
import net.psforever.objects.zones.exp.ToDatabase
|
||||
import net.psforever.packet.game.UplinkRequest
|
||||
import net.psforever.services.local.{LocalAction, LocalServiceMessage}
|
||||
import net.psforever.services.base.CachedEnvelope
|
||||
import net.psforever.services.base.envelope.MessageEnvelope
|
||||
import net.psforever.services.base.message.{ChangeAmmo, ChangeFireState_Start, ChangeFireState_Stop, ReloadTool, SendResponse, WeaponDryFire}
|
||||
import net.psforever.types.{ChatMessageType, PlanetSideEmpire, ValidPlanetSideGUID, Vector3}
|
||||
import net.psforever.util.Config
|
||||
|
||||
|
|
@ -45,8 +47,8 @@ import net.psforever.objects.serverobject.mount.Mountable
|
|||
import net.psforever.objects.serverobject.turret.FacilityTurret
|
||||
import net.psforever.objects._
|
||||
import net.psforever.packet.game._
|
||||
import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage}
|
||||
import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage}
|
||||
import net.psforever.services.avatar.AvatarAction
|
||||
import net.psforever.services.vehicle.VehicleAction
|
||||
import net.psforever.types.{ExoSuitType, PlanetSideGUID}
|
||||
|
||||
trait WeaponAndProjectileFunctions extends CommonSessionInterfacingFunctionality {
|
||||
|
|
@ -281,14 +283,12 @@ class WeaponAndProjectileOperations(
|
|||
.orElse { continent.GUID(weapon_guid) }
|
||||
.collect {
|
||||
case _: Equipment if containerOpt.exists(_.isInstanceOf[Player]) =>
|
||||
continent.AvatarEvents ! AvatarServiceMessage(
|
||||
continent.id,
|
||||
AvatarAction.WeaponDryFire(player.GUID, weapon_guid)
|
||||
)
|
||||
continent.AvatarEvents ! MessageEnvelope(continent.id, player.GUID, WeaponDryFire(weapon_guid))
|
||||
case _: Equipment =>
|
||||
continent.VehicleEvents ! VehicleServiceMessage(
|
||||
continent.VehicleEvents ! MessageEnvelope(
|
||||
continent.id,
|
||||
VehicleAction.WeaponDryFire(player.GUID, weapon_guid)
|
||||
player.GUID,
|
||||
WeaponDryFire(weapon_guid)
|
||||
)
|
||||
}
|
||||
.orElse {
|
||||
|
|
@ -348,14 +348,21 @@ class WeaponAndProjectileOperations(
|
|||
sendResponse(UplinkResponse(code.value, 0))
|
||||
sendResponse(PlanetsideAttributeMessage(player.GUID, 59, 1200000))
|
||||
avatarActor ! AvatarActor.UpdateCUDTime("emp_blast")
|
||||
player.Zone.LocalEvents ! LocalServiceMessage(s"${player.Zone.id}",
|
||||
LocalAction.SendPacket(TriggerEffectMessage(ValidPlanetSideGUID(0), empColor, None, Some(TriggeredEffectLocation(player.Position, Vector3(0, 0, 90))))))
|
||||
player.Zone.LocalEvents ! MessageEnvelope(
|
||||
s"${player.Zone.id}",
|
||||
PlanetSideGUID(-1),
|
||||
SendResponse(TriggerEffectMessage(Default.GUID0, empColor, None, Some(TriggeredEffectLocation(player.Position, Vector3(0, 0, 90)))))
|
||||
)
|
||||
context.system.scheduler.scheduleOnce(delay = 1 seconds) {
|
||||
Zone.serverSideDamage(player.Zone, player, empSize, SpecialEmp.createEmpInteraction(empSize, player.Position),
|
||||
ExplosiveDeployableControl.detectionForExplosiveSource(player), Zone.findAllTargets)
|
||||
}
|
||||
case UplinkRequestType.OrbitalStrike =>
|
||||
player.Zone.LocalEvents ! LocalServiceMessage(s"$playerFaction", LocalAction.SendPacket(OrbitalStrikeWaypointMessage(player.GUID, pos.get.x, pos.get.y)))
|
||||
player.Zone.LocalEvents ! MessageEnvelope(
|
||||
s"$playerFaction",
|
||||
PlanetSideGUID(-1),
|
||||
SendResponse(OrbitalStrikeWaypointMessage(player.GUID, pos.get.x, pos.get.y))
|
||||
)
|
||||
sendResponse(UplinkResponse(code.value, 0))
|
||||
orbitalStrikePos = pos
|
||||
case UplinkRequestType.Unknown5 =>
|
||||
|
|
@ -380,9 +387,16 @@ class WeaponAndProjectileOperations(
|
|||
sendResponse(PlanetsideAttributeMessage(player.GUID, 60, 10800000))
|
||||
avatarActor ! AvatarActor.UpdateCUDTime("orbital_strike")
|
||||
context.system.scheduler.scheduleOnce(delay = 5 seconds) {
|
||||
player.Zone.LocalEvents ! LocalServiceMessage(s"${player.Zone.id}",
|
||||
LocalAction.SendPacket(TriggerEffectMessage(ValidPlanetSideGUID(0), strikeType, None, Some(TriggeredEffectLocation(orbitalStrikePos.get, Vector3(0, 0, 90))))))
|
||||
player.Zone.LocalEvents ! LocalServiceMessage(s"$playerFaction", LocalAction.SendPacket(OrbitalStrikeWaypointMessage(player.GUID, None)))
|
||||
player.Zone.LocalEvents ! MessageEnvelope(
|
||||
s"${player.Zone.id}",
|
||||
PlanetSideGUID(-1),
|
||||
SendResponse(TriggerEffectMessage(ValidPlanetSideGUID(0), strikeType, None, Some(TriggeredEffectLocation(orbitalStrikePos.get, Vector3(0, 0, 90)))))
|
||||
)
|
||||
player.Zone.LocalEvents ! MessageEnvelope(
|
||||
s"$playerFaction",
|
||||
PlanetSideGUID(-1),
|
||||
SendResponse(OrbitalStrikeWaypointMessage(player.GUID, None))
|
||||
)
|
||||
context.system.scheduler.scheduleOnce(delay = 5 seconds) {
|
||||
val sectorTargets = Zone.findOrbitalStrikeTargets(player.Zone, orbitalStrikePos.get, osSize.DamageRadius, Zone.getOrbitbalStrikeTargets)
|
||||
val withinRange = sectorTargets.filter { target => Zone.orbitalStrikeDistanceCheck(orbitalStrikePos.get, target.Position, osSize.DamageRadius) }
|
||||
|
|
@ -457,9 +471,10 @@ class WeaponAndProjectileOperations(
|
|||
log.info(s"${player.Name} changed ${player.Sex.possessive} ${obj.Definition.Name}'s fire mode to #$modeIndex")
|
||||
}
|
||||
sendResponse(ChangeFireModeMessage(item_guid, modeIndex))
|
||||
continent.AvatarEvents ! AvatarServiceMessage(
|
||||
continent.AvatarEvents ! MessageEnvelope(
|
||||
sessionLogic.zoning.zoneChannel,
|
||||
AvatarAction.ChangeFireMode(player.GUID, item_guid, modeIndex)
|
||||
player.GUID,
|
||||
AvatarAction.ChangeFireMode(item_guid, modeIndex)
|
||||
)
|
||||
}
|
||||
case Some(_) =>
|
||||
|
|
@ -478,10 +493,10 @@ class WeaponAndProjectileOperations(
|
|||
projectile.Position = shot_pos
|
||||
projectile.Orientation = shot_orient
|
||||
projectile.Velocity = shot_vel
|
||||
continent.AvatarEvents ! AvatarServiceMessage(
|
||||
continent.AvatarEvents ! CachedEnvelope(
|
||||
continent.id,
|
||||
player.GUID,
|
||||
AvatarAction.ProjectileState(
|
||||
player.GUID,
|
||||
projectileGlobalUID,
|
||||
shot_pos,
|
||||
shot_vel,
|
||||
|
|
@ -742,12 +757,9 @@ class WeaponAndProjectileOperations(
|
|||
(target.GUID, (target, proxyCopy, proxyCopy.shot_origin, target.Position))
|
||||
}.unzip
|
||||
//chain lash effect
|
||||
continent.AvatarEvents ! AvatarServiceMessage(
|
||||
continent.AvatarEvents ! MessageEnvelope(
|
||||
continent.id,
|
||||
AvatarAction.SendResponse(
|
||||
PlanetSideGUID(0),
|
||||
ChainLashMessage(hitPos, projectile.profile.ObjectId, guidRefs.toList)
|
||||
)
|
||||
SendResponse(ChainLashMessage(hitPos, projectile.profile.ObjectId, guidRefs.toList))
|
||||
)
|
||||
//chain lash target output
|
||||
outputRefs.toList
|
||||
|
|
@ -931,12 +943,9 @@ class WeaponAndProjectileOperations(
|
|||
tool.Magazine = 0
|
||||
sendResponse(InventoryStateMessage(tool.AmmoSlot.Box.GUID, weapon_guid, 0))
|
||||
sendResponse(ChangeFireStateMessage_Stop(weapon_guid))
|
||||
continent.AvatarEvents ! AvatarServiceMessage(
|
||||
continent.id,
|
||||
AvatarAction.ChangeFireState_Stop(player.GUID, weapon_guid)
|
||||
)
|
||||
continent.AvatarEvents ! MessageEnvelope(continent.id, player.GUID, ChangeFireState_Stop(weapon_guid))
|
||||
sendResponse(WeaponDryFireMessage(weapon_guid))
|
||||
continent.AvatarEvents ! AvatarServiceMessage(continent.id, AvatarAction.WeaponDryFire(player.GUID, weapon_guid))
|
||||
continent.AvatarEvents ! MessageEnvelope(continent.id, player.GUID, WeaponDryFire(weapon_guid))
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -952,7 +961,7 @@ class WeaponAndProjectileOperations(
|
|||
.map { sessionLogic.validObject(_, decorator="FindDetectedProjectileTargets") }
|
||||
.flatMap {
|
||||
case Some(obj: Vehicle) if !obj.Cloaked =>
|
||||
//TODO hint: vehicleService ! VehicleServiceMessage(s"${obj.Actor}", VehicleAction.ProjectileAutoLockAwareness(mode))
|
||||
//TODO hint: vehicleService ! MessageEnvelope(s"${obj.Actor}", VehicleAction.ProjectileAutoLockAwareness(mode))
|
||||
obj.Seats.values.flatMap { seat => seat.occupants.map(_.Name) }
|
||||
case Some(obj: Mountable) =>
|
||||
obj.Seats.values.flatMap { seat => seat.occupants.map(_.Name) }
|
||||
|
|
@ -1077,9 +1086,10 @@ class WeaponAndProjectileOperations(
|
|||
}
|
||||
|
||||
def fireStateStartPlayerMessages(itemGuid: PlanetSideGUID): Unit = {
|
||||
continent.AvatarEvents ! AvatarServiceMessage(
|
||||
continent.AvatarEvents ! MessageEnvelope(
|
||||
sessionLogic.zoning.zoneChannel,
|
||||
AvatarAction.ChangeFireState_Start(player.GUID, itemGuid)
|
||||
player.GUID,
|
||||
ChangeFireState_Start(itemGuid)
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -1088,9 +1098,10 @@ class WeaponAndProjectileOperations(
|
|||
case turret: FacilityTurret if continent.map.cavern =>
|
||||
turret.Actor ! VanuSentry.ChangeFireStart
|
||||
}
|
||||
continent.VehicleEvents ! VehicleServiceMessage(
|
||||
continent.VehicleEvents ! MessageEnvelope(
|
||||
continent.id,
|
||||
VehicleAction.ChangeFireState_Start(player.GUID, itemGuid)
|
||||
player.GUID,
|
||||
ChangeFireState_Start(itemGuid)
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -1116,9 +1127,10 @@ class WeaponAndProjectileOperations(
|
|||
}
|
||||
|
||||
def fireStateStopPlayerMessages(itemGuid: PlanetSideGUID): Unit = {
|
||||
continent.AvatarEvents ! AvatarServiceMessage(
|
||||
continent.AvatarEvents ! MessageEnvelope(
|
||||
sessionLogic.zoning.zoneChannel,
|
||||
AvatarAction.ChangeFireState_Stop(player.GUID, itemGuid)
|
||||
player.GUID,
|
||||
ChangeFireState_Stop(itemGuid)
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -1127,9 +1139,10 @@ class WeaponAndProjectileOperations(
|
|||
case turret: FacilityTurret if continent.map.cavern =>
|
||||
turret.Actor ! VanuSentry.ChangeFireStop
|
||||
}
|
||||
continent.VehicleEvents ! VehicleServiceMessage(
|
||||
continent.VehicleEvents ! MessageEnvelope(
|
||||
continent.id,
|
||||
VehicleAction.ChangeFireState_Stop(player.GUID, itemGuid)
|
||||
player.GUID,
|
||||
ChangeFireState_Stop(itemGuid)
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -1186,16 +1199,14 @@ class WeaponAndProjectileOperations(
|
|||
used by ReloadMessage handling
|
||||
*/
|
||||
def reloadPlayerMessages(itemGuid: PlanetSideGUID): Unit = {
|
||||
continent.AvatarEvents ! AvatarServiceMessage(
|
||||
sessionLogic.zoning.zoneChannel,
|
||||
AvatarAction.Reload(player.GUID, itemGuid)
|
||||
)
|
||||
continent.AvatarEvents ! MessageEnvelope(sessionLogic.zoning.zoneChannel, player.GUID, ReloadTool(itemGuid))
|
||||
}
|
||||
|
||||
def reloadVehicleMessages(itemGuid: PlanetSideGUID): Unit = {
|
||||
continent.VehicleEvents ! VehicleServiceMessage(
|
||||
continent.VehicleEvents ! MessageEnvelope(
|
||||
continent.id,
|
||||
VehicleAction.Reload(player.GUID, itemGuid)
|
||||
player.GUID,
|
||||
ReloadTool(itemGuid)
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -1369,10 +1380,10 @@ class WeaponAndProjectileOperations(
|
|||
val previous_box_guid = previousBox.GUID
|
||||
val boxDef = box.Definition
|
||||
sendResponse(ChangeAmmoMessage(tool_guid, box.Capacity))
|
||||
continent.AvatarEvents ! AvatarServiceMessage(
|
||||
continent.AvatarEvents ! MessageEnvelope(
|
||||
sessionLogic.zoning.zoneChannel,
|
||||
AvatarAction.ChangeAmmo(
|
||||
player.GUID,
|
||||
player.GUID,
|
||||
ChangeAmmo(
|
||||
tool_guid,
|
||||
ammoSlotIndex,
|
||||
previous_box_guid,
|
||||
|
|
@ -1470,15 +1481,10 @@ class WeaponAndProjectileOperations(
|
|||
def modifyAmmunitionInMountable(obj: PlanetSideServerObject with Container)(box: AmmoBox, reloadValue: Int): Unit = {
|
||||
modifyAmmunition(obj)(box, reloadValue)
|
||||
obj.Find(box).collect { index =>
|
||||
continent.VehicleEvents ! VehicleServiceMessage(
|
||||
continent.VehicleEvents ! MessageEnvelope(
|
||||
s"${obj.Actor}",
|
||||
VehicleAction.InventoryState(
|
||||
player.GUID,
|
||||
box,
|
||||
obj.GUID,
|
||||
index,
|
||||
box.Definition.Packet.DetailedConstructorData(box).get
|
||||
)
|
||||
player.GUID,
|
||||
VehicleAction.InventoryState(box, obj.GUID, index, box.Definition.Packet.DetailedConstructorData(box).get)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -1582,10 +1588,7 @@ class WeaponAndProjectileOperations(
|
|||
shootingStop.clear()
|
||||
(prefire ++ shooting).foreach { guid =>
|
||||
sendResponse(ChangeFireStateMessage_Stop(guid))
|
||||
continent.AvatarEvents ! AvatarServiceMessage(
|
||||
continent.id,
|
||||
AvatarAction.ChangeFireState_Stop(player.GUID, guid)
|
||||
)
|
||||
continent.AvatarEvents ! MessageEnvelope(continent.id, player.GUID, ChangeFireState_Stop(guid))
|
||||
}
|
||||
prefire.clear()
|
||||
shooting.clear()
|
||||
|
|
|
|||
|
|
@ -18,10 +18,14 @@ import net.psforever.objects.serverobject.mount.Seat
|
|||
import net.psforever.objects.serverobject.tube.SpawnTube
|
||||
import net.psforever.objects.serverobject.turret.auto.AutomatedTurret
|
||||
import net.psforever.objects.sourcing.{PlayerSource, SourceEntry, VehicleSource}
|
||||
import net.psforever.objects.vehicles.control.{CargoBehavior, CarrierBehavior}
|
||||
import net.psforever.objects.vital.{InGameHistory, IncarnationActivity, ReconstructionActivity, SpawningActivity}
|
||||
import net.psforever.objects.zones.blockmap.BlockMapEntity
|
||||
import net.psforever.packet.game.GenericAction.FirstPersonViewWithEffect
|
||||
import net.psforever.packet.game.{CampaignStatistic, ChangeFireStateMessage_Start, CloudInfo, GenericActionMessage, GenericObjectActionEnum, HackState7, MailMessage, ObjectDetectedMessage, SessionStatistic, StormInfo, TriggeredSound, TrainingZoneMessage, WeatherMessage}
|
||||
import net.psforever.packet.game.{CampaignStatistic, ChangeFireStateMessage_Start, CloudInfo, GenericActionMessage, GenericObjectActionEnum, HackState7, MailMessage, ObjectDetectedMessage, SessionStatistic, StormInfo, TrainingZoneMessage, TriggeredSound, WeatherMessage}
|
||||
import net.psforever.services.avatar.support.{CorpseEnvelope, ReleaseEnvelope}
|
||||
import net.psforever.services.base.envelope.{BundledEnvelope, MessageEnvelope}
|
||||
import net.psforever.services.base.message.{GenericObjectAction, ObjectDelete, PlanetsideAttribute, SendResponse}
|
||||
import net.psforever.services.chat.DefaultChannel
|
||||
|
||||
import scala.concurrent.duration._
|
||||
|
|
@ -62,16 +66,16 @@ import net.psforever.packet.game.objectcreate.{DroppedItemData, ObjectCreateMess
|
|||
import net.psforever.packet.game.objectcreate.ObjectClass
|
||||
import net.psforever.packet.{PlanetSideGamePacket, game}
|
||||
import net.psforever.persistence.Savedplayer
|
||||
import net.psforever.services.RemoverActor
|
||||
import net.psforever.services.ServiceManager.{Lookup, LookupResult}
|
||||
import net.psforever.services.account.{AccountPersistenceService, PlayerToken}
|
||||
import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage}
|
||||
import net.psforever.services.galaxy.{GalaxyAction, GalaxyServiceMessage}
|
||||
import net.psforever.services.avatar.AvatarAction
|
||||
import net.psforever.services.base.support.RemoverActor
|
||||
import net.psforever.services.galaxy.GalaxyAction
|
||||
import net.psforever.services.hart.HartTimer
|
||||
import net.psforever.services.local.support.HackCaptureActor
|
||||
import net.psforever.services.local.{LocalAction, LocalServiceMessage}
|
||||
import net.psforever.services.local.LocalAction
|
||||
import net.psforever.services.properties.PropertyOverrideManager
|
||||
import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage}
|
||||
import net.psforever.services.vehicle.VehicleAction
|
||||
import net.psforever.services.{CavernRotationService, Service, ServiceManager, InterstellarClusterService => ICS}
|
||||
import net.psforever.types._
|
||||
import net.psforever.util.{Config, DefinitionUtil}
|
||||
|
|
@ -118,7 +122,7 @@ object ZoningOperations {
|
|||
additionalChannels: List[String]
|
||||
): Unit = {
|
||||
val events = zone.LocalEvents
|
||||
val effectMessage = LocalAction.TriggerEffectLocation(Service.defaultPlayerGUID, s"respawn_$faction", position, orientation)
|
||||
val effectMessage = LocalAction.TriggerEffectLocation(s"respawn_$faction", position, orientation)
|
||||
(zone
|
||||
.blockMap
|
||||
.sector(position, range = 100f)
|
||||
|
|
@ -126,7 +130,7 @@ object ZoningOperations {
|
|||
.filter(p => Sidedness.equals(side, p.WhichSide))
|
||||
.map(_.Name) ++ additionalChannels)
|
||||
.foreach { target =>
|
||||
events ! LocalServiceMessage(target, effectMessage)
|
||||
events ! MessageEnvelope(target, effectMessage)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -152,13 +156,13 @@ object ZoningOperations {
|
|||
Vector3.DistanceSquared(t.Position.xy, posxy) < 2500f && /* literal 50m */
|
||||
heightDiff < 5f && heightDiff > -1f
|
||||
}
|
||||
val effectMessage = LocalAction.TriggerEffectLocation(Service.defaultPlayerGUID, s"respawn_$faction", position, orientation)
|
||||
val effectMessage = LocalAction.TriggerEffectLocation(s"respawn_$faction", position, orientation)
|
||||
(effectTargets.map(_.Name) ++ additionalChannels).foreach { target =>
|
||||
events ! LocalServiceMessage(target, effectMessage)
|
||||
events ! MessageEnvelope(target, effectMessage)
|
||||
}
|
||||
val soundMessage = LocalAction.TriggerSound(Service.defaultPlayerGUID, TriggeredSound.SpawnInTube, position, 50, 0.69803923f)
|
||||
val soundMessage = LocalAction.TriggerSound(TriggeredSound.SpawnInTube, position, 50, 0.69803923f)
|
||||
(soundTargets.map(_.Name) ++ additionalChannels).foreach { target =>
|
||||
events ! LocalServiceMessage(target, soundMessage)
|
||||
events ! MessageEnvelope(target, soundMessage)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -547,8 +551,8 @@ class ZoningOperations(
|
|||
sendResponse(OCM.apply(projectile))
|
||||
}
|
||||
//spawn point update request
|
||||
continent.VehicleEvents ! VehicleServiceMessage(
|
||||
continent.id,
|
||||
continent.VehicleEvents ! MessageEnvelope(
|
||||
player.Name,
|
||||
VehicleAction.UpdateAmsSpawnPoint(continent)
|
||||
)
|
||||
spawn.upstreamMessageCount = 0
|
||||
|
|
@ -595,14 +599,14 @@ class ZoningOperations(
|
|||
context.self
|
||||
)
|
||||
LivePlayerList.Add(avatar.id, avatar)
|
||||
galaxyService.tell(GalaxyServiceMessage(GalaxyAction.LogStatusChange(avatar.name)), context.parent)
|
||||
galaxyService.tell(MessageEnvelope("", GalaxyAction.LogStatusChange(avatar.name)), context.parent)
|
||||
//PropertyOverrideMessage
|
||||
ServiceManager.serviceManager ! Lookup("propertyOverrideManager")
|
||||
sendResponse(PlanetsideAttributeMessage(PlanetSideGUID(0), 112, 0)) // disable festive backpacks
|
||||
sendResponse(ReplicationStreamMessage(5, Some(6), Vector.empty)) //clear squad list
|
||||
spawn.initializeFriendsAndIgnoredLists()
|
||||
//the following subscriptions last until character switch/logout
|
||||
galaxyService ! Service.Join("galaxy") //for galaxy-wide messages
|
||||
galaxyService ! Service.Join("") //for galaxy-wide messages
|
||||
galaxyService ! Service.Join(s"${avatar.faction}") //for hotspots, etc.
|
||||
sessionLogic.squadService ! Service.Join(s"${avatar.faction}") //channel will be player.Faction
|
||||
sessionLogic.squadService ! Service.Join(s"${avatar.id}") //channel will be player.CharId (in order to work with packets)
|
||||
|
|
@ -618,9 +622,9 @@ class ZoningOperations(
|
|||
//the only zone-level event system subscription necessary before BeginZoningMessage (for persistence purposes)
|
||||
zone.AvatarEvents ! Service.Join(player.Name)
|
||||
sessionLogic.persist()
|
||||
oldZone.AvatarEvents ! Service.Leave()
|
||||
oldZone.LocalEvents ! Service.Leave()
|
||||
oldZone.VehicleEvents ! Service.Leave()
|
||||
oldZone.AvatarEvents ! Service.LeaveAll
|
||||
oldZone.LocalEvents ! Service.LeaveAll
|
||||
oldZone.VehicleEvents ! Service.LeaveAll
|
||||
|
||||
if (player.isAlive && zoningType != Zoning.Method.Reset) {
|
||||
if (player.HasGUID) {
|
||||
|
|
@ -649,9 +653,9 @@ class ZoningOperations(
|
|||
val oldZone = session.zone
|
||||
session = session.copy(zone = foundZone)
|
||||
sessionLogic.persist()
|
||||
oldZone.AvatarEvents ! Service.Leave()
|
||||
oldZone.LocalEvents ! Service.Leave()
|
||||
oldZone.VehicleEvents ! Service.Leave()
|
||||
oldZone.AvatarEvents ! Service.LeaveAll
|
||||
oldZone.LocalEvents ! Service.LeaveAll
|
||||
oldZone.VehicleEvents ! Service.LeaveAll
|
||||
//the only zone-level event system subscription necessary before BeginZoningMessage (for persistence purposes)
|
||||
foundZone.AvatarEvents ! Service.Join(player.Name)
|
||||
foundZone.Population ! Zone.Population.Join(avatar)
|
||||
|
|
@ -760,7 +764,7 @@ class ZoningOperations(
|
|||
case _ =>
|
||||
interstellarFerry match {
|
||||
case None =>
|
||||
galaxyService ! Service.Leave(Some(temp_channel)) //no longer being transferred between zones
|
||||
galaxyService ! Service.Leave(temp_channel) //no longer being transferred between zones
|
||||
interstellarFerryTopLevelGUID = None
|
||||
case Some(_) => () //wait patiently
|
||||
}
|
||||
|
|
@ -768,7 +772,7 @@ class ZoningOperations(
|
|||
}
|
||||
|
||||
private def handleTransferPassengerVehicle(vehicle: Vehicle, temporaryChannel: String): Unit = {
|
||||
galaxyService ! Service.Leave(Some(temporaryChannel)) //temporary vehicle-specific channel (see above)
|
||||
galaxyService ! Service.Leave(temporaryChannel) //temporary vehicle-specific channel (see above)
|
||||
spawn.deadState = DeadState.Release
|
||||
sendResponse(AvatarDeadStateMessage(DeadState.Release, 0, 0, player.Position, player.Faction, unk5=true))
|
||||
interstellarFerry = Some(vehicle) //on the other continent and registered to that continent's GUID system
|
||||
|
|
@ -851,7 +855,7 @@ class ZoningOperations(
|
|||
case None =>
|
||||
spawn.deadState = DeadState.Release // cancel movement updates
|
||||
player.Position = position
|
||||
// continent.AvatarEvents ! AvatarServiceMessage(continent.Id, AvatarAction.ObjectDelete(player.GUID, player.GUID))
|
||||
// continent.AvatarEvents ! MessageEnvelope(continent.Id, ObjectDelete(player.GUID, player.GUID))
|
||||
spawn.LoadZonePhysicalSpawnPoint(zoneId, position, Vector3.Zero, 0 seconds, None)
|
||||
case _ => // seated in something that is not a vehicle or the vehicle is cargo, in which case we can't move
|
||||
}
|
||||
|
|
@ -1121,7 +1125,7 @@ class ZoningOperations(
|
|||
case obj if obj.Destroyed => configAmenityAsDestroyed(obj)
|
||||
case obj => configAmenityAsWorking(obj)
|
||||
}
|
||||
//sendResponse(HackMessage(HackState1.Unk3, guid, Service.defaultPlayerGUID, progress=0, -1f, HackState.HackCleared, HackState7.Unk8))
|
||||
//sendResponse(HackMessage(HackState1.Unk3, guid, Default.GUID0, progress=0, -1f, HackState.HackCleared, HackState7.Unk8))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1205,9 +1209,10 @@ class ZoningOperations(
|
|||
sendResponse(OCM.apply(llu))
|
||||
// Attach it to a player if it has a carrier
|
||||
if (llu.Carrier.nonEmpty) {
|
||||
continent.LocalEvents ! LocalServiceMessage(
|
||||
continent.LocalEvents ! MessageEnvelope(
|
||||
continent.id,
|
||||
LocalAction.SendPacket(ObjectAttachMessage(llu.Carrier.get.GUID, llu.GUID, 252))
|
||||
PlanetSideGUID(-1),
|
||||
SendResponse(ObjectAttachMessage(llu.Carrier.get.GUID, llu.GUID, 252))
|
||||
)
|
||||
}
|
||||
case _ => ()
|
||||
|
|
@ -1349,9 +1354,10 @@ class ZoningOperations(
|
|||
val pguid = player.GUID
|
||||
val toChannel = manifest.file
|
||||
val topLevel = interstellarFerryTopLevelGUID.getOrElse(vehicle.GUID)
|
||||
continent.VehicleEvents ! VehicleServiceMessage(
|
||||
continent.VehicleEvents ! MessageEnvelope(
|
||||
s"${vehicle.Actor}",
|
||||
VehicleAction.TransferPassengerChannel(pguid, s"${vehicle.Actor}", toChannel, vehicle, topLevel)
|
||||
pguid,
|
||||
VehicleAction.TransferPassengerChannel(s"${vehicle.Actor}", toChannel, vehicle, topLevel)
|
||||
)
|
||||
manifest.cargo.foreach {
|
||||
case ManifestPassengerEntry("MISSING_DRIVER", index) =>
|
||||
|
|
@ -1362,9 +1368,10 @@ class ZoningOperations(
|
|||
cargo.Actor ! CargoBehavior.StartCargoDismounting(bailed = false)
|
||||
case entry =>
|
||||
val cargo = vehicle.CargoHolds(entry.mount).occupant.get
|
||||
continent.VehicleEvents ! VehicleServiceMessage(
|
||||
continent.VehicleEvents ! MessageEnvelope(
|
||||
entry.name,
|
||||
VehicleAction.TransferPassengerChannel(pguid, s"${cargo.Actor}", toChannel, cargo, topLevel)
|
||||
pguid,
|
||||
VehicleAction.TransferPassengerChannel(s"${cargo.Actor}", toChannel, cargo, topLevel)
|
||||
)
|
||||
}
|
||||
//
|
||||
|
|
@ -1393,9 +1400,10 @@ class ZoningOperations(
|
|||
interstellarFerryTopLevelGUID =
|
||||
if (manifest.passengers.isEmpty && manifest.cargo.count { !_.name.equals("MISSING_DRIVER") } == 0) {
|
||||
//do not delete if vehicle has passengers or cargo
|
||||
continent.VehicleEvents ! VehicleServiceMessage(
|
||||
continent.VehicleEvents ! MessageEnvelope(
|
||||
continent.id,
|
||||
VehicleAction.UnloadVehicle(pguid, vehicle, topLevel)
|
||||
pguid,
|
||||
VehicleAction.UnloadVehicle(vehicle, topLevel)
|
||||
)
|
||||
None
|
||||
} else {
|
||||
|
|
@ -1470,17 +1478,14 @@ class ZoningOperations(
|
|||
case Some(manifest) =>
|
||||
val toChannel = manifest.file
|
||||
val topLevel = interstellarFerryTopLevelGUID.getOrElse(vehicle.GUID)
|
||||
galaxyService ! GalaxyServiceMessage(
|
||||
toChannel,
|
||||
GalaxyAction.TransferPassenger(player_guid, toChannel, vehicle, topLevel, manifest)
|
||||
)
|
||||
galaxyService ! MessageEnvelope(toChannel, GalaxyAction.TransferPassenger(player_guid, toChannel, vehicle, topLevel, manifest))
|
||||
vehicle.CargoHolds.values
|
||||
.collect {
|
||||
case hold if hold.isOccupied =>
|
||||
val cargo = hold.occupant.get
|
||||
cargo.Continent = toZoneId
|
||||
//point to the cargo vehicle to instigate cargo vehicle driver transportation
|
||||
// galaxyService ! GalaxyServiceMessage(
|
||||
// galaxyService ! MesdsageEnvelope(
|
||||
// toChannel,
|
||||
// GalaxyAction.TransferPassenger(player_guid, toChannel, vehicle, topLevel, manifest)
|
||||
// )
|
||||
|
|
@ -1972,7 +1977,7 @@ class ZoningOperations(
|
|||
guid,
|
||||
Deployable.Icon(obj.Definition.Item),
|
||||
obj.Position,
|
||||
obj.OwnerGuid.getOrElse(Service.defaultPlayerGUID)
|
||||
obj.OwnerGuid.getOrElse(Default.GUID0)
|
||||
)))
|
||||
}
|
||||
}
|
||||
|
|
@ -2191,7 +2196,7 @@ class ZoningOperations(
|
|||
log.info(s"RestoreInfo: player $name is already logged in zone ${inZone.id}; rejoining that character")
|
||||
sessionLogic.persistFunc = UpdatePersistence(from)
|
||||
//tell the old WorldSessionActor to kill itself by using its own subscriptions against itself
|
||||
inZone.AvatarEvents ! AvatarServiceMessage(name, AvatarAction.TeardownConnection())
|
||||
inZone.AvatarEvents ! MessageEnvelope(name, AvatarAction.TeardownConnection)
|
||||
spawn.switchAvatarStatisticsFieldToRefreshAfterRespawn()
|
||||
//find and reload previous player
|
||||
(
|
||||
|
|
@ -2594,9 +2599,10 @@ class ZoningOperations(
|
|||
vehicle.CargoHolds.values
|
||||
.collect { case hold if hold.isOccupied => hold.occupant.get }
|
||||
.foreach { _.MountedIn = vguid }
|
||||
events ! VehicleServiceMessage(
|
||||
events ! MessageEnvelope(
|
||||
zoneid,
|
||||
VehicleAction.LoadVehicle(player.GUID, vehicle, vObjectId, vguid, data)
|
||||
player.GUID,
|
||||
VehicleAction.LoadVehicle(vehicle, vObjectId, vguid, data)
|
||||
)
|
||||
carrierInfo match {
|
||||
case (Some(carrier), Some((index, _))) =>
|
||||
|
|
@ -2621,9 +2627,10 @@ class ZoningOperations(
|
|||
//do not dispatch delete action if any hierarchical occupant has not gotten this far through the summoning process
|
||||
val vehicleToDelete = interstellarFerryTopLevelGUID.orElse(originalSeated).getOrElse(PlanetSideGUID(0))
|
||||
val zone = vehicle.PreviousGatingManifest().get.origin
|
||||
zone.VehicleEvents ! VehicleServiceMessage(
|
||||
zone.VehicleEvents ! MessageEnvelope(
|
||||
zone.id,
|
||||
VehicleAction.UnloadVehicle(player.GUID, vehicle, vehicleToDelete)
|
||||
player.GUID,
|
||||
VehicleAction.UnloadVehicle(vehicle, vehicleToDelete)
|
||||
)
|
||||
log.debug(
|
||||
s"AvatarCreate: cleaning up ghost of transitioning vehicle ${vehicle.Definition.Name}@${vehicleToDelete.guid} in zone ${zone.id}"
|
||||
|
|
@ -2638,9 +2645,10 @@ class ZoningOperations(
|
|||
val definition = player.avatar.definition
|
||||
val guid = player.GUID
|
||||
sendResponse(OCM.detailed(player))
|
||||
continent.AvatarEvents ! AvatarServiceMessage(
|
||||
continent.AvatarEvents ! MessageEnvelope(
|
||||
s"spectator",
|
||||
AvatarAction.LoadPlayer(guid, definition.ObjectId, guid, definition.Packet.ConstructorData(player).get, None)
|
||||
guid,
|
||||
AvatarAction.LoadPlayer(definition.ObjectId, guid, definition.Packet.ConstructorData(player).get, None)
|
||||
)
|
||||
|
||||
case _ =>
|
||||
|
|
@ -2649,9 +2657,10 @@ class ZoningOperations(
|
|||
val guid = player.GUID
|
||||
usingSpawnTubeAnimation()
|
||||
sendResponse(OCM.detailed(player))
|
||||
continent.AvatarEvents ! AvatarServiceMessage(
|
||||
continent.AvatarEvents ! MessageEnvelope(
|
||||
zoneid,
|
||||
AvatarAction.LoadPlayer(guid, definition.ObjectId, guid, definition.Packet.ConstructorData(player).get, None)
|
||||
guid,
|
||||
AvatarAction.LoadPlayer(definition.ObjectId, guid, definition.Packet.ConstructorData(player).get, None)
|
||||
)
|
||||
}
|
||||
continent.Population ! Zone.Population.Spawn(avatar, player, avatarActor)
|
||||
|
|
@ -2721,10 +2730,10 @@ class ZoningOperations(
|
|||
interimUngunnedVehicle = Some(vguid)
|
||||
interimUngunnedVehicleSeat = Some(seat)
|
||||
}
|
||||
continent.AvatarEvents ! AvatarServiceMessage(
|
||||
continent.AvatarEvents ! MessageEnvelope(
|
||||
continent.id,
|
||||
pguid,
|
||||
AvatarAction.LoadPlayer(
|
||||
pguid,
|
||||
pdef.ObjectId,
|
||||
pguid,
|
||||
pdef.Packet.ConstructorData(tplayer).get,
|
||||
|
|
@ -2880,9 +2889,9 @@ class ZoningOperations(
|
|||
case _ => ()
|
||||
}
|
||||
if (player.VisibleSlots.contains(index)) {
|
||||
events ! AvatarServiceMessage(
|
||||
events ! MessageEnvelope(
|
||||
zoneId,
|
||||
AvatarAction.ObjectDelete(Service.defaultPlayerGUID, obj.GUID)
|
||||
ObjectDelete(obj.GUID)
|
||||
)
|
||||
} else {
|
||||
sendResponse(ObjectDeleteMessage(obj.GUID, 0))
|
||||
|
|
@ -2898,7 +2907,6 @@ class ZoningOperations(
|
|||
* To the game, that is a backpack (or some pastry, festive graphical modification allowing).
|
||||
* @see `AvatarAction.ObjectDelete`
|
||||
* @see `AvatarAction.Release`
|
||||
* @see `AvatarServiceMessage`
|
||||
* @see `FriskDeadBody`
|
||||
* @see `GUIDTask.unregisterPlayer`
|
||||
* @see `ObjectDeleteMessage`
|
||||
|
|
@ -2916,7 +2924,7 @@ class ZoningOperations(
|
|||
val pguid = tplayer.GUID
|
||||
zone.Population ! Zone.Population.Release(avatar)
|
||||
sendResponse(ObjectDeleteMessage(pguid, 0))
|
||||
zone.AvatarEvents ! AvatarServiceMessage(zone.id, AvatarAction.ObjectDelete(pguid, pguid))
|
||||
zone.AvatarEvents ! MessageEnvelope(zone.id, pguid, ObjectDelete(pguid))
|
||||
TaskWorkflow.execute(GUIDTask.unregisterPlayer(zone.GUID, tplayer))
|
||||
}
|
||||
}
|
||||
|
|
@ -2926,7 +2934,6 @@ class ZoningOperations(
|
|||
* To the game, that is a backpack (or some pastry, festive graphical modification allowing).
|
||||
* A player who has been kicked may not turn into a corpse.
|
||||
* @see `AvatarAction.Release`
|
||||
* @see `AvatarServiceMessage`
|
||||
* @see `CorpseConverter.converter`
|
||||
* @see `DepictPlayerAsCorpse`
|
||||
* @see `Player.Release`
|
||||
|
|
@ -2939,7 +2946,7 @@ class ZoningOperations(
|
|||
tplayer.Release
|
||||
DepictPlayerAsCorpse(tplayer)
|
||||
zone.Population ! Zone.Corpse.Add(tplayer)
|
||||
zone.AvatarEvents ! AvatarServiceMessage(zone.id, AvatarAction.Release(tplayer, zone))
|
||||
zone.AvatarEvents ! ReleaseEnvelope(zone.id, AvatarAction.Release(tplayer, zone))
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -2978,7 +2985,7 @@ class ZoningOperations(
|
|||
*/
|
||||
def TryDisposeOfLootedCorpse(obj: Player): Boolean = {
|
||||
if (obj.isBackpack && WellLootedDeadBody(obj)) {
|
||||
obj.Zone.AvatarEvents ! AvatarServiceMessage.Corpse(RemoverActor.HurrySpecific(List(obj), obj.Zone))
|
||||
obj.Zone.AvatarEvents ! CorpseEnvelope(RemoverActor.HurrySpecific(List(obj), obj.Zone))
|
||||
true
|
||||
} else {
|
||||
false
|
||||
|
|
@ -3172,9 +3179,10 @@ class ZoningOperations(
|
|||
// entering or exiting VR zones uses a fade-out effect for the player instead of the usual green cloud deconstruction effect
|
||||
val effect = if (player.IsInVRZone || zoneId.startsWith("tz")) 2 else 1
|
||||
sendResponse(ObjectDeleteMessage(player_guid, unk1=effect))
|
||||
continent.AvatarEvents ! AvatarServiceMessage(
|
||||
continent.AvatarEvents ! MessageEnvelope(
|
||||
continent.id,
|
||||
AvatarAction.ObjectDelete(player_guid, player_guid, unk=effect)
|
||||
player_guid,
|
||||
ObjectDelete(player_guid, unk=effect)
|
||||
)
|
||||
InGameHistory.SpawnReconstructionActivity(player, toZoneNumber, betterSpawnPoint)
|
||||
LoadZoneAsPlayerUsing(player, pos, ori, toSide, zoneId)
|
||||
|
|
@ -3338,7 +3346,7 @@ class ZoningOperations(
|
|||
//looking for squad (members)
|
||||
if (tplayer.avatar.lookingForSquad) {
|
||||
sendResponse(PlanetsideAttributeMessage(guid, 53, 1))
|
||||
continent.AvatarEvents ! AvatarServiceMessage(continent.id, AvatarAction.PlanetsideAttribute(guid, 53, 1))
|
||||
continent.AvatarEvents ! MessageEnvelope(continent.id, guid, PlanetsideAttribute(guid, 53, 1))
|
||||
}
|
||||
sendResponse(AvatarSearchCriteriaMessage(guid, List(0, 0, 0, 0, 0, 0)))
|
||||
//these are facilities and towers and bunkers in the zone, but not necessarily all of them for some reason
|
||||
|
|
@ -3364,7 +3372,7 @@ class ZoningOperations(
|
|||
if (tplayer.ExoSuit == ExoSuitType.MAX) {
|
||||
sendResponse(PlanetsideAttributeMessage(guid, 7, tplayer.Capacitor.toLong))
|
||||
sendResponse(PlanetsideAttributeMessage(guid, 4, tplayer.Armor))
|
||||
continent.AvatarEvents ! AvatarServiceMessage(continent.id, AvatarAction.PlanetsideAttributeToAll(guid, 4, tplayer.Armor))
|
||||
continent.AvatarEvents ! MessageEnvelope(continent.id, PlanetsideAttribute(guid, 4, tplayer.Armor))
|
||||
}
|
||||
// for issue #1269
|
||||
continent.AllPlayers.filter(_.ExoSuit == ExoSuitType.MAX).foreach(max => sendResponse(PlanetsideAttributeMessage(max.GUID, 4, max.Armor)))
|
||||
|
|
@ -3388,9 +3396,10 @@ class ZoningOperations(
|
|||
continent.GUID(tplayer.avatar.vehicle) match {
|
||||
case Some(vehicle: Vehicle) if vehicle.OwnerName.contains(tplayer.Name) =>
|
||||
vehicle.OwnerGuid = guid
|
||||
continent.VehicleEvents ! VehicleServiceMessage(
|
||||
continent.VehicleEvents ! MessageEnvelope(
|
||||
s"${tplayer.Faction}",
|
||||
VehicleAction.Ownership(guid, vehicle.GUID)
|
||||
guid,
|
||||
VehicleAction.Ownership(vehicle.GUID)
|
||||
)
|
||||
case _ =>
|
||||
avatarActor ! AvatarActor.SetVehicle(None)
|
||||
|
|
@ -3487,13 +3496,13 @@ class ZoningOperations(
|
|||
case Some(b: Building) if b.hasCavernLockBenefit =>
|
||||
tplayer.MaxHealth = 120
|
||||
tplayer.Health = 120
|
||||
tplayer.Zone.AvatarEvents ! AvatarServiceMessage(
|
||||
tplayer.Zone.id,
|
||||
AvatarAction.PlanetsideAttributeToAll(tplayer.GUID, 0, 120)
|
||||
)
|
||||
tplayer.Zone.AvatarEvents ! AvatarServiceMessage(
|
||||
tplayer.Zone.id,
|
||||
AvatarAction.PlanetsideAttributeToAll(tplayer.GUID, 1, 120)
|
||||
val guid = tplayer.GUID
|
||||
val zone = tplayer.Zone
|
||||
val channel = zone.id
|
||||
val events = zone.AvatarEvents
|
||||
events ! MessageEnvelope(
|
||||
channel,
|
||||
SendResponse(PlanetsideAttributeMessage(guid, 0, 120), PlanetsideAttributeMessage(guid, 1, 120))
|
||||
)
|
||||
case _ => ()
|
||||
}
|
||||
|
|
@ -3996,13 +4005,20 @@ class ZoningOperations(
|
|||
}
|
||||
GoToDeploymentMap()
|
||||
val pZone = player.Zone
|
||||
val msg = GenericObjectAction(player.GUID, GenericObjectActionEnum.PlayerDeconstructs.id)
|
||||
sendResponse(GenericActionMessage(FirstPersonViewWithEffect))
|
||||
pZone.blockMap.sector(player).livePlayerList.collect { case t if t.GUID != player.GUID =>
|
||||
pZone.LocalEvents ! LocalServiceMessage(t.Name, LocalAction.SendGenericObjectActionMessage(t.GUID, player.GUID, GenericObjectActionEnum.PlayerDeconstructs))
|
||||
}
|
||||
pZone.AllPlayers.collect { case t if t.GUID != player.GUID && !t.allowInteraction =>
|
||||
pZone.LocalEvents ! LocalServiceMessage(t.Name, LocalAction.SendGenericObjectActionMessage(t.GUID, player.GUID, GenericObjectActionEnum.PlayerDeconstructs))
|
||||
}
|
||||
val (localMessageRecipients, localMesages) = pZone.blockMap.sector(player).livePlayerList
|
||||
.collect {
|
||||
case t if t.GUID != player.GUID =>
|
||||
(t.Name, MessageEnvelope(t.Name, msg))
|
||||
}
|
||||
.unzip
|
||||
val otherMessages: Seq[MessageEnvelope] = pZone.AllPlayers
|
||||
.collect {
|
||||
case t if t.GUID != player.GUID && !t.allowInteraction && !localMessageRecipients.contains(t.Name) =>
|
||||
MessageEnvelope(t.Name, msg)
|
||||
}
|
||||
pZone.LocalEvents ! BundledEnvelope(localMesages ++ otherMessages)
|
||||
}
|
||||
|
||||
def stopDeconstructing(): Unit = {
|
||||
|
|
|
|||
|
|
@ -11,8 +11,9 @@ import net.psforever.objects.zones.Zone
|
|||
import net.psforever.packet.PlanetSideGamePacket
|
||||
import net.psforever.packet.game.ContinentalLockUpdateMessage
|
||||
import net.psforever.persistence
|
||||
import net.psforever.services.galaxy.{GalaxyAction, GalaxyServiceMessage}
|
||||
import net.psforever.services.local.{LocalAction, LocalServiceMessage}
|
||||
import net.psforever.services.base.envelope.{BundledEnvelope, MessageEnvelope}
|
||||
import net.psforever.services.base.message.{SendResponse, SetEmpire}
|
||||
import net.psforever.services.galaxy.GalaxyAction
|
||||
import net.psforever.services.{InterstellarClusterService, ServiceManager}
|
||||
import net.psforever.types.PlanetSideEmpire
|
||||
import net.psforever.util.Database.ctx
|
||||
|
|
@ -167,7 +168,7 @@ object BuildingActor {
|
|||
val building = details.building
|
||||
val zone = building.Zone
|
||||
building.Faction = faction
|
||||
zone.LocalEvents ! LocalServiceMessage(zone.id, LocalAction.SetEmpire(building.GUID, faction))
|
||||
zone.LocalEvents ! MessageEnvelope(zone.id, SetEmpire(building.GUID, faction))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -231,8 +232,10 @@ class BuildingActor(
|
|||
Behaviors.same
|
||||
|
||||
case MapUpdate() =>
|
||||
details.galaxyService ! GalaxyServiceMessage(GalaxyAction.MapUpdate(details.building.infoUpdateMessage()))
|
||||
details.galaxyService ! GalaxyServiceMessage(GalaxyAction.SendResponse(details.building.densityLevelUpdateMessage(building)))
|
||||
details.galaxyService ! BundledEnvelope(
|
||||
MessageEnvelope("", GalaxyAction.MapUpdate(details.building.infoUpdateMessage())),
|
||||
MessageEnvelope("", SendResponse(details.building.densityLevelUpdateMessage(building)))
|
||||
)
|
||||
Behaviors.same
|
||||
|
||||
case AmenityStateChange(amenity, data) =>
|
||||
|
|
@ -254,15 +257,15 @@ class BuildingActor(
|
|||
logic.ntu(details, msg)
|
||||
|
||||
case DensityLevelUpdate(building) =>
|
||||
details.galaxyService ! GalaxyServiceMessage(GalaxyAction.SendResponse(details.building.densityLevelUpdateMessage(building)))
|
||||
details.galaxyService ! MessageEnvelope("", SendResponse(details.building.densityLevelUpdateMessage(building)))
|
||||
Behaviors.same
|
||||
|
||||
case ContinentalLock(zone) =>
|
||||
details.galaxyService ! GalaxyServiceMessage(GalaxyAction.SendResponse(ContinentalLockUpdateMessage(zone.Number, zone.lockedBy)))
|
||||
details.galaxyService ! MessageEnvelope("", SendResponse(ContinentalLockUpdateMessage(zone.Number, zone.lockedBy)))
|
||||
Behaviors.same
|
||||
|
||||
case HomeLockBenefits(msg) =>
|
||||
details.galaxyService ! GalaxyServiceMessage(GalaxyAction.SendResponse(msg))
|
||||
details.galaxyService ! MessageEnvelope("", SendResponse(msg))
|
||||
Behaviors.same
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,9 +6,10 @@ import net.psforever.objects.{Default, GlobalDefinitions, Tool, Vehicle}
|
|||
import net.psforever.objects.avatar.{AvatarBot, AvatarBotActor}
|
||||
import net.psforever.objects.guid.{GUIDTask, StraightforwardTask, TaskBundle, TaskWorkflow}
|
||||
import net.psforever.objects.zones.Zone
|
||||
import net.psforever.services.local.{LocalAction, LocalServiceMessage}
|
||||
import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage}
|
||||
import net.psforever.types.{CharacterSex, CharacterVoice, ExoSuitType, PlanetSideEmpire, PlanetSideGUID, Vector3}
|
||||
import net.psforever.services.base.envelope.MessageEnvelope
|
||||
import net.psforever.services.local.LocalAction
|
||||
import net.psforever.services.vehicle.VehicleAction
|
||||
import net.psforever.types.{CharacterSex, CharacterVoice, ExoSuitType, PlanetSideEmpire, Vector3}
|
||||
import net.psforever.util.Config
|
||||
|
||||
import scala.collection.mutable.ListBuffer
|
||||
|
|
@ -282,7 +283,6 @@ class ShootingRangeTargetSpawnerActor(zone: Zone) extends Actor {
|
|||
* @param bot the bot to remove
|
||||
*/
|
||||
private def RemoveBot(bot: AvatarBot): Boolean = {
|
||||
import net.psforever.services.Service
|
||||
activeInfantryTargets.indexOf(bot) match {
|
||||
case -1 =>
|
||||
log.warn(s"Failed to remove bot with GUID ${bot.GUID} from ${zone.id}'s active targets list! This shouldn't happen... and probably just caused a leak.")
|
||||
|
|
@ -290,9 +290,9 @@ class ShootingRangeTargetSpawnerActor(zone: Zone) extends Actor {
|
|||
case index =>
|
||||
activeInfantryTargets.remove(index)
|
||||
}
|
||||
zone.LocalEvents ! LocalServiceMessage(
|
||||
zone.LocalEvents ! MessageEnvelope(
|
||||
zone.id,
|
||||
LocalAction.TriggerEffectLocation(Service.defaultPlayerGUID, "bot_destroyed_effect", bot.Position, bot.Orientation)
|
||||
LocalAction.TriggerEffectLocation("bot_destroyed_effect", bot.Position, bot.Orientation)
|
||||
)
|
||||
//spawn a replacement bot
|
||||
context.system.scheduler.scheduleOnce(
|
||||
|
|
@ -356,10 +356,9 @@ class ShootingRangeTargetSpawnerActor(zone: Zone) extends Actor {
|
|||
|
||||
def action(): Future[Any] = {
|
||||
zone.Transport ! Zone.Vehicle.Spawn(localVehicle)
|
||||
zone.VehicleEvents ! VehicleServiceMessage(
|
||||
zone.VehicleEvents ! MessageEnvelope(
|
||||
zone.id,
|
||||
VehicleAction.LoadVehicle(
|
||||
PlanetSideGUID(0),
|
||||
localVehicle,
|
||||
localVehicle.Definition.ObjectId,
|
||||
localVehicle.GUID,
|
||||
|
|
|
|||
|
|
@ -20,7 +20,8 @@ import net.psforever.objects.zones.exp.{ExperienceCalculator, SupportExperienceC
|
|||
import net.psforever.packet.game.{BuildingInfoUpdateMessage, PlanetsideAttributeMessage}
|
||||
import net.psforever.util.Database._
|
||||
import net.psforever.persistence
|
||||
import net.psforever.services.local.{LocalAction, LocalServiceMessage}
|
||||
import net.psforever.services.base.envelope.MessageEnvelope
|
||||
import net.psforever.services.base.message.SendResponse
|
||||
|
||||
import scala.collection.mutable
|
||||
import scala.util.{Failure, Success}
|
||||
|
|
@ -234,26 +235,26 @@ class ZoneActor(
|
|||
}
|
||||
buildingOpt.foreach { building =>
|
||||
if (msg.generator_state == PlanetSideGeneratorState.Normal && building.hasCavernLockBenefit) {
|
||||
zone.LocalEvents ! LocalServiceMessage(
|
||||
zone.LocalEvents ! MessageEnvelope(
|
||||
zone.id,
|
||||
LocalAction.SendResponse(PlanetsideAttributeMessage(building.GUID, 67, 1))
|
||||
SendResponse(PlanetsideAttributeMessage(building.GUID, 67, 1))
|
||||
)
|
||||
}
|
||||
msg.is_hacked match {
|
||||
case true if building.BuildingType == StructureType.Facility && !zone.map.cavern =>
|
||||
zone.LocalEvents ! LocalServiceMessage(
|
||||
zone.LocalEvents ! MessageEnvelope(
|
||||
zone.id,
|
||||
LocalAction.SendResponse(PlanetsideAttributeMessage(building.GUID, 67, 0))
|
||||
SendResponse(PlanetsideAttributeMessage(building.GUID, 67, 0))
|
||||
)
|
||||
case false if building.hasCavernLockBenefit =>
|
||||
zone.LocalEvents ! LocalServiceMessage(
|
||||
zone.LocalEvents ! MessageEnvelope(
|
||||
zone.id,
|
||||
LocalAction.SendResponse(PlanetsideAttributeMessage(building.GUID, 67, 1))
|
||||
SendResponse(PlanetsideAttributeMessage(building.GUID, 67, 1))
|
||||
)
|
||||
case false if building.BuildingType == StructureType.Facility && !zone.map.cavern && !building.hasCavernLockBenefit =>
|
||||
zone.LocalEvents ! LocalServiceMessage(
|
||||
zone.LocalEvents ! MessageEnvelope(
|
||||
zone.id,
|
||||
LocalAction.SendResponse(PlanetsideAttributeMessage(building.GUID, 67, 0))
|
||||
SendResponse(PlanetsideAttributeMessage(building.GUID, 67, 0))
|
||||
)
|
||||
case _ =>
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,9 +7,10 @@ import net.psforever.actors.commands.NtuCommand
|
|||
import net.psforever.actors.zone.{BuildingActor, BuildingControlDetails, ZoneActor}
|
||||
import net.psforever.objects.serverobject.structures.{Amenity, Building, StructureType}
|
||||
import net.psforever.objects.serverobject.terminals.capture.{CaptureTerminal, CaptureTerminalAware, CaptureTerminalAwareBehavior}
|
||||
import net.psforever.services.galaxy.{GalaxyAction, GalaxyServiceMessage}
|
||||
import net.psforever.services.local.{LocalAction, LocalServiceMessage}
|
||||
import net.psforever.types.{PlanetSideEmpire, PlanetSideGUID}
|
||||
import net.psforever.services.base.envelope.MessageEnvelope
|
||||
import net.psforever.services.galaxy.GalaxyAction
|
||||
import net.psforever.services.local.support.{HackClearActor, HackClearEnvelope}
|
||||
import net.psforever.types.PlanetSideEmpire
|
||||
|
||||
/**
|
||||
* The logic that governs facilities and structures found in the cavern regions.
|
||||
|
|
@ -52,12 +53,12 @@ case object CavernFacilityLogic
|
|||
// When a CC is hacked (or resecured) all currently hacked amenities for the base should return to their default unhacked state
|
||||
building.HackableAmenities.foreach(amenity => {
|
||||
if (amenity.HackedBy.isDefined) {
|
||||
building.Zone.LocalEvents ! LocalServiceMessage(amenity.Zone.id,LocalAction.ClearTemporaryHack(PlanetSideGUID(0), amenity))
|
||||
building.Zone.LocalEvents ! HackClearEnvelope(HackClearActor.ObjectIsResecured(amenity))
|
||||
}
|
||||
})
|
||||
// No map update needed - will be sent by `HackCaptureActor` when required
|
||||
case _ =>
|
||||
details.galaxyService ! GalaxyServiceMessage(GalaxyAction.MapUpdate(details.building.infoUpdateMessage()))
|
||||
details.galaxyService ! MessageEnvelope("", GalaxyAction.MapUpdate(details.building.infoUpdateMessage()))
|
||||
}
|
||||
Behaviors.same
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,9 +7,10 @@ import net.psforever.actors.commands.NtuCommand
|
|||
import net.psforever.actors.zone.{BuildingActor, BuildingControlDetails}
|
||||
import net.psforever.objects.serverobject.structures.{Amenity, Building}
|
||||
import net.psforever.objects.serverobject.terminals.capture.{CaptureTerminal, CaptureTerminalAware, CaptureTerminalAwareBehavior}
|
||||
import net.psforever.services.galaxy.{GalaxyAction, GalaxyServiceMessage}
|
||||
import net.psforever.services.local.{LocalAction, LocalServiceMessage}
|
||||
import net.psforever.types.{PlanetSideEmpire, PlanetSideGUID}
|
||||
import net.psforever.services.base.envelope.MessageEnvelope
|
||||
import net.psforever.services.galaxy.GalaxyAction
|
||||
import net.psforever.services.local.support.{HackClearActor, HackClearEnvelope}
|
||||
import net.psforever.types.PlanetSideEmpire
|
||||
|
||||
/**
|
||||
* The logic that governs standard facilities and structures.
|
||||
|
|
@ -52,12 +53,12 @@ case object FacilityLogic
|
|||
// When a CC is hacked (or resecured) all currently hacked amenities for the base should return to their default unhacked state
|
||||
building.HackableAmenities.foreach(amenity => {
|
||||
if (amenity.HackedBy.isDefined) {
|
||||
building.Zone.LocalEvents ! LocalServiceMessage(amenity.Zone.id, LocalAction.ClearTemporaryHack(PlanetSideGUID(0), amenity))
|
||||
building.Zone.LocalEvents ! HackClearEnvelope(HackClearActor.ObjectIsResecured(amenity))
|
||||
}
|
||||
})
|
||||
// No map update needed - will be sent by `HackCaptureActor` when required
|
||||
case _ =>
|
||||
details.galaxyService ! GalaxyServiceMessage(GalaxyAction.MapUpdate(details.building.infoUpdateMessage()))
|
||||
details.galaxyService ! MessageEnvelope("", GalaxyAction.MapUpdate(details.building.infoUpdateMessage()))
|
||||
}
|
||||
Behaviors.same
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,12 +13,13 @@ import net.psforever.objects.serverobject.resourcesilo.ResourceSiloControl
|
|||
import net.psforever.objects.serverobject.structures.{Amenity, Building}
|
||||
import net.psforever.objects.serverobject.terminals.capture.{CaptureTerminal, CaptureTerminalAware, CaptureTerminalAwareBehavior}
|
||||
import net.psforever.objects.sourcing.PlayerSource
|
||||
import net.psforever.packet.game.PlanetsideAttributeMessage
|
||||
import net.psforever.services.{InterstellarClusterService, Service}
|
||||
import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage}
|
||||
import net.psforever.services.galaxy.{GalaxyAction, GalaxyServiceMessage}
|
||||
import net.psforever.services.local.{LocalAction, LocalServiceMessage}
|
||||
import net.psforever.types.{PlanetSideEmpire, PlanetSideGUID}
|
||||
import net.psforever.packet.game.{GenericObjectActionMessage, PlanetsideAttributeMessage}
|
||||
import net.psforever.services.InterstellarClusterService
|
||||
import net.psforever.services.base.envelope.{BundledEnvelope, MessageEnvelope}
|
||||
import net.psforever.services.base.message.{GenericObjectAction, PlanetsideAttribute, SendResponse}
|
||||
import net.psforever.services.galaxy.GalaxyAction
|
||||
import net.psforever.services.local.support.{CaptureEnvelope, HackCaptureActor, HackClearActor, HackClearEnvelope}
|
||||
import net.psforever.types.PlanetSideEmpire
|
||||
|
||||
/**
|
||||
* A package class that conveys the important information for handling facility updates.
|
||||
|
|
@ -101,10 +102,7 @@ case object MajorFacilityLogic
|
|||
hackedAmenities
|
||||
}
|
||||
amenitiesToClear.foreach { amenity =>
|
||||
building.Zone.LocalEvents ! LocalServiceMessage(
|
||||
amenity.Zone.id,
|
||||
LocalAction.ClearTemporaryHack(PlanetSideGUID(0), amenity)
|
||||
)
|
||||
building.Zone.LocalEvents ! HackClearEnvelope(HackClearActor.ObjectIsResecured(amenity))
|
||||
}
|
||||
// No map update needed - will be sent by `HackCaptureActor` when required
|
||||
case dome: ForceDomePhysics =>
|
||||
|
|
@ -120,7 +118,7 @@ case object MajorFacilityLogic
|
|||
.filter(amenity => applicable.contains(amenity.Definition))
|
||||
.foreach { _.Actor ! msg }
|
||||
case _ =>
|
||||
details.galaxyService ! GalaxyServiceMessage(GalaxyAction.MapUpdate(details.building.infoUpdateMessage()))
|
||||
details.galaxyService ! MessageEnvelope("", GalaxyAction.MapUpdate(details.building.infoUpdateMessage()))
|
||||
}
|
||||
Behaviors.same
|
||||
}
|
||||
|
|
@ -205,30 +203,24 @@ case object MajorFacilityLogic
|
|||
case Some(GeneratorControl.Event.UnderAttack) =>
|
||||
val events = zone.AvatarEvents
|
||||
val guid = building.GUID
|
||||
val msg = AvatarAction.GenericObjectAction(Service.defaultPlayerGUID, guid, 15)
|
||||
building.PlayersInSOI.foreach { player =>
|
||||
events ! AvatarServiceMessage(player.Name, msg)
|
||||
}
|
||||
val msg = GenericObjectAction(guid, 15)
|
||||
events ! BundledEnvelope(building.PlayersInSOI.map { player => MessageEnvelope(player.Name, msg) })
|
||||
false
|
||||
case Some(GeneratorControl.Event.Critical) =>
|
||||
val events = zone.AvatarEvents
|
||||
val guid = building.GUID
|
||||
val msg = AvatarAction.PlanetsideAttributeToAll(guid, 46, 1)
|
||||
building.PlayersInSOI.foreach { player =>
|
||||
events ! AvatarServiceMessage(player.Name, msg)
|
||||
}
|
||||
val msg = PlanetsideAttribute(guid, 46, 1)
|
||||
events ! BundledEnvelope(building.PlayersInSOI.map { player => MessageEnvelope(player.Name, msg) })
|
||||
true
|
||||
case Some(GeneratorControl.Event.Destabilized) =>
|
||||
val events = zone.AvatarEvents
|
||||
val guid = building.GUID
|
||||
val msg = AvatarAction.GenericObjectAction(Service.defaultPlayerGUID, guid, 16)
|
||||
building.PlayersInSOI.foreach { player =>
|
||||
events ! AvatarServiceMessage(player.Name, msg)
|
||||
}
|
||||
val msg = GenericObjectAction(guid, 16)
|
||||
events ! BundledEnvelope(building.PlayersInSOI.map { player => MessageEnvelope(player.Name, msg) })
|
||||
if (building.hasCavernLockBenefit) {
|
||||
zone.LocalEvents ! LocalServiceMessage(
|
||||
zone.LocalEvents ! MessageEnvelope(
|
||||
zone.id,
|
||||
LocalAction.SendResponse(PlanetsideAttributeMessage(building.GUID, 67, 0))
|
||||
SendResponse(PlanetsideAttributeMessage(building.GUID, 67, 0))
|
||||
)
|
||||
}
|
||||
false
|
||||
|
|
@ -237,10 +229,9 @@ case object MajorFacilityLogic
|
|||
case Some(GeneratorControl.Event.Offline) =>
|
||||
powerLost(details)
|
||||
val zone = building.Zone
|
||||
val msg = AvatarAction.PlanetsideAttributeToAll(building.GUID, 46, 2)
|
||||
building.PlayersInSOI.foreach { player =>
|
||||
zone.AvatarEvents ! AvatarServiceMessage(player.Name, msg)
|
||||
} //???
|
||||
val events = zone.AvatarEvents
|
||||
val msg = PlanetsideAttribute(building.GUID, 46, 2)
|
||||
events ! BundledEnvelope(building.PlayersInSOI.map { player => MessageEnvelope(player.Name, msg) }) //???
|
||||
true
|
||||
case Some(GeneratorControl.Event.Normal) =>
|
||||
true
|
||||
|
|
@ -249,13 +240,13 @@ case object MajorFacilityLogic
|
|||
powerRestored(details)
|
||||
val events = zone.AvatarEvents
|
||||
val guid = building.GUID
|
||||
val msg1 = AvatarAction.PlanetsideAttributeToAll(guid, 46, 0)
|
||||
val msg2 = AvatarAction.GenericObjectAction(Service.defaultPlayerGUID, guid, 17)
|
||||
building.PlayersInSOI.foreach { player =>
|
||||
val name = player.Name
|
||||
events ! AvatarServiceMessage(name, msg1) //reset ???; might be global?
|
||||
events ! AvatarServiceMessage(name, msg2) //This facility's generator is back on line
|
||||
}
|
||||
//1. reset ???; might be global?
|
||||
//2. This facility's generator is back on line
|
||||
val list = SendResponse(
|
||||
PlanetsideAttributeMessage(guid, 46, 0),
|
||||
GenericObjectActionMessage(guid, 17)
|
||||
)
|
||||
events ! BundledEnvelope(building.PlayersInSOI.map { player => MessageEnvelope(player.Name, list) })
|
||||
true
|
||||
case _ =>
|
||||
false
|
||||
|
|
@ -283,7 +274,7 @@ case object MajorFacilityLogic
|
|||
(bldg.GetFlag, bldg.CaptureTerminal) match {
|
||||
case (Some(flag), Some(terminal)) if (flag.Target eq building) && flag.Faction != building.Faction =>
|
||||
//our hack destination may have been compromised and the hack needs to be cancelled
|
||||
bldg.Zone.LocalEvents ! LocalServiceMessage("", LocalAction.ResecureCaptureTerminal(terminal, PlayerSource.Nobody))
|
||||
bldg.Zone.LocalEvents ! CaptureEnvelope(HackCaptureActor.ResecureCaptureTerminal(terminal, terminal.Zone, PlayerSource.Nobody))
|
||||
case _ => ()
|
||||
}
|
||||
Behaviors.same
|
||||
|
|
@ -305,10 +296,12 @@ case object MajorFacilityLogic
|
|||
building.Amenities.foreach { amenity =>
|
||||
amenity.Actor ! powerMsg
|
||||
}
|
||||
//amenities disabled; red warning lights
|
||||
events ! AvatarServiceMessage(zoneId, AvatarAction.PlanetsideAttributeToAll(guid, 48, 1))
|
||||
//disable spawn target on deployment map
|
||||
events ! AvatarServiceMessage(zoneId, AvatarAction.PlanetsideAttributeToAll(guid, 38, 0))
|
||||
//1. amenities disabled; red warning lights
|
||||
//2 .disable spawn target on deployment map
|
||||
events ! MessageEnvelope(
|
||||
zoneId,
|
||||
SendResponse(PlanetsideAttributeMessage(guid, 48, 1), PlanetsideAttributeMessage(guid, 38, 0))
|
||||
)
|
||||
Behaviors.same
|
||||
}
|
||||
|
||||
|
|
@ -328,10 +321,12 @@ case object MajorFacilityLogic
|
|||
building.Amenities.foreach { amenity =>
|
||||
amenity.Actor ! powerMsg
|
||||
}
|
||||
//amenities enabled; normal lights
|
||||
events ! AvatarServiceMessage(zoneId, AvatarAction.PlanetsideAttributeToAll(guid, 48, 0))
|
||||
//enable spawn target on deployment map
|
||||
events ! AvatarServiceMessage(zoneId, AvatarAction.PlanetsideAttributeToAll(guid, 38, 1))
|
||||
//1. amenities enabled; normal lights
|
||||
//2. enable spawn target on deployment map
|
||||
events ! MessageEnvelope(
|
||||
zoneId,
|
||||
SendResponse(PlanetsideAttributeMessage(guid, 48, 0), PlanetsideAttributeMessage(guid, 38, 1))
|
||||
)
|
||||
Behaviors.same
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,9 +4,10 @@ package net.psforever.actors.zone.building
|
|||
import akka.actor.typed.Behavior
|
||||
import akka.actor.typed.scaladsl.Behaviors
|
||||
import net.psforever.actors.commands.NtuCommand
|
||||
import net.psforever.actors.zone.{BuildingActor, ZoneActor}
|
||||
import net.psforever.actors.zone.BuildingActor
|
||||
import net.psforever.objects.serverobject.structures.{Amenity, Building, WarpGate}
|
||||
import net.psforever.services.galaxy.{GalaxyAction, GalaxyServiceMessage}
|
||||
import net.psforever.services.base.envelope.{BundledEnvelope, MessageEnvelope}
|
||||
import net.psforever.services.galaxy.GalaxyAction
|
||||
import net.psforever.types.PlanetSideEmpire
|
||||
import net.psforever.util.Config
|
||||
|
||||
|
|
@ -182,7 +183,7 @@ case object WarpGateLogic
|
|||
val pairedWgFaction = pairedWg.Faction
|
||||
if (pairedWgFaction != terminalWgFaction) {
|
||||
pairedWg.Faction = terminalWgFaction
|
||||
details.galaxyService ! GalaxyServiceMessage(GalaxyAction.MapUpdate(pairedWg.infoUpdateMessage()))
|
||||
details.galaxyService ! MessageEnvelope("", GalaxyAction.MapUpdate(pairedWg.infoUpdateMessage()))
|
||||
}
|
||||
//the terminal warpgate can not be considered broadcast for other faction
|
||||
if (terminalWg.AllowBroadcastFor.contains(pairedWgFaction)) {
|
||||
|
|
@ -208,9 +209,7 @@ case object WarpGateLogic
|
|||
warpgate.Zone.Number, warpgate.MapId, previousAllowances, setBroadcastTo
|
||||
)
|
||||
warpgate.AllowBroadcastFor = setBroadcastTo
|
||||
(setBroadcastTo ++ previousAllowances).foreach { faction =>
|
||||
events ! GalaxyServiceMessage(faction.toString, msg)
|
||||
}
|
||||
events ! BundledEnvelope((setBroadcastTo ++ previousAllowances).map { faction => MessageEnvelope(faction.toString, msg) })
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -15,8 +15,9 @@ import net.psforever.objects.sourcing.AmenitySource
|
|||
import net.psforever.objects.vital.TerminalUsedActivity
|
||||
import net.psforever.objects.zones.Zone
|
||||
import net.psforever.types.{ExoSuitType, PlanetSideGUID, TransactionType, Vector3}
|
||||
import net.psforever.services.Service
|
||||
import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage}
|
||||
import net.psforever.services.avatar.AvatarAction
|
||||
import net.psforever.services.base.envelope.MessageEnvelope
|
||||
import net.psforever.services.base.message.ObjectDelete
|
||||
|
||||
import scala.concurrent.ExecutionContext.Implicits.global
|
||||
import scala.concurrent.Future
|
||||
|
|
@ -280,7 +281,7 @@ object WorldSession {
|
|||
* @throws `RuntimeException` if slot is not a player visible slot (holsters)
|
||||
* @see `ask`
|
||||
* @see `AvatarAction.ObjectDelete`
|
||||
* @see `AvatarAction.SendResponse`
|
||||
* @see `SendResponse`
|
||||
* @see `Containable.CanNotPutItemInSlot`
|
||||
* @see `Containable.PutItemInSlotOnly`
|
||||
* @see `GUIDTask.registerEquipment`
|
||||
|
|
@ -289,7 +290,7 @@ object WorldSession {
|
|||
* @see `ObjectHeldMessage`
|
||||
* @see `Player.DrawnSlot`
|
||||
* @see `Player.LastDrawnSlot`
|
||||
* @see `Service.defaultPlayerGUID`
|
||||
* @see `Default.GUID0`
|
||||
* @see `TaskBundle`
|
||||
* @see `Zone.AvatarEvents`
|
||||
* @param player the player whose visible slot will be equipped and drawn
|
||||
|
|
@ -326,10 +327,7 @@ object WorldSession {
|
|||
case _ =>
|
||||
forcedTolowerRaisedArm(localPlayer, localPlayer.GUID, localZone)
|
||||
localPlayer.DrawnSlot = localSlot
|
||||
localZone.AvatarEvents ! AvatarServiceMessage(
|
||||
localZone.id,
|
||||
AvatarAction.ObjectHeld(localGUID, localSlot, localSlot)
|
||||
)
|
||||
localZone.AvatarEvents ! MessageEnvelope(localZone.id, localGUID, AvatarAction.ObjectHeld(localSlot, localSlot))
|
||||
}
|
||||
Future(this)
|
||||
}
|
||||
|
|
@ -370,10 +368,7 @@ object WorldSession {
|
|||
localZone.GUID(item_guid) match {
|
||||
case Some(_) => ()
|
||||
case None => //acting on old data?
|
||||
localZone.AvatarEvents ! AvatarServiceMessage(
|
||||
localZone.id,
|
||||
AvatarAction.ObjectDelete(Service.defaultPlayerGUID, item_guid)
|
||||
)
|
||||
localZone.AvatarEvents ! MessageEnvelope(localZone.id, ObjectDelete(item_guid))
|
||||
}
|
||||
case _ => ()
|
||||
}
|
||||
|
|
@ -532,7 +527,6 @@ object WorldSession {
|
|||
* 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`
|
||||
|
|
@ -597,10 +591,7 @@ object WorldSession {
|
|||
localGUID match {
|
||||
case Some(guid) =>
|
||||
//see LockerContainerControl.RemoveItemFromSlotCallback
|
||||
localSource.Zone.AvatarEvents ! AvatarServiceMessage(
|
||||
localChannel,
|
||||
AvatarAction.ObjectDelete(Service.defaultPlayerGUID, guid)
|
||||
)
|
||||
localSource.Zone.AvatarEvents ! MessageEnvelope(localChannel, ObjectDelete(guid))
|
||||
case None => ()
|
||||
}
|
||||
val moveResult = ask(localDestination.Actor, Containable.PutItemInSlotOrAway(localItem, Some(localDestSlot)))
|
||||
|
|
@ -625,8 +616,7 @@ object WorldSession {
|
|||
* 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 `ObjectDelete`
|
||||
* @see `Containable.MoveItem`
|
||||
* @see `Container`
|
||||
* @see `Equipment`
|
||||
|
|
@ -702,10 +692,7 @@ object WorldSession {
|
|||
localGUID match {
|
||||
case Some(guid) =>
|
||||
//see LockerContainerControl.RemoveItemFromSlotCallback
|
||||
localSource.Zone.AvatarEvents ! AvatarServiceMessage(
|
||||
localChannel,
|
||||
AvatarAction.ObjectDelete(Service.defaultPlayerGUID, guid)
|
||||
)
|
||||
localSource.Zone.AvatarEvents ! MessageEnvelope(localChannel, ObjectDelete(guid))
|
||||
case None => ()
|
||||
}
|
||||
val moveResult = ask(localDestination.Actor, Containable.PutItemInSlotOrAway(localItem, Some(localDestSlot)))
|
||||
|
|
@ -742,8 +729,7 @@ object WorldSession {
|
|||
* If the player's already-drawn hand is the same as the one that will hold the grenade (first sidearm holster),
|
||||
* treat it like the sidearm occupier rather than the already-drawn weapon -
|
||||
* the old weapon goes into the backpack or onto the ground.
|
||||
* @see `AvatarAction.ObjectHeld`
|
||||
* @see `AvatarServiceMessage`
|
||||
* @see `ObjectHeld`
|
||||
* @see `Containable.RemoveItemFromSlot`
|
||||
* @see `countRestrictAttempts`
|
||||
* @see `forcedTolowerRaisedArm`
|
||||
|
|
@ -795,10 +781,7 @@ object WorldSession {
|
|||
}
|
||||
//put up hand with grenade in it
|
||||
tplayer.DrawnSlot = slotNum
|
||||
zone.AvatarEvents ! AvatarServiceMessage(
|
||||
zone.id,
|
||||
AvatarAction.ObjectHeld(guid, slotNum, slotNum)
|
||||
)
|
||||
zone.AvatarEvents ! MessageEnvelope(zone.id, guid, AvatarAction.ObjectHeld(slotNum, slotNum))
|
||||
log.info(s"${tplayer.Name} has quickly drawn a ${grenade.Definition.Name}")
|
||||
None
|
||||
case None =>
|
||||
|
|
@ -872,8 +855,7 @@ object WorldSession {
|
|||
/**
|
||||
* If the player has a raised arm, lower it.
|
||||
* Do it manually, bypassing the checks in the normal procedure.
|
||||
* @see `AvatarAction.ObjectHeld`
|
||||
* @see `AvatarServiceMessage`
|
||||
* @see `ObjectHeld`
|
||||
* @see `Player.DrawnSlot`
|
||||
* @see `Player.HandsDownSlot`
|
||||
* @param tplayer the player
|
||||
|
|
@ -885,10 +867,7 @@ object WorldSession {
|
|||
val slot = tplayer.DrawnSlot
|
||||
if (slot != Player.HandsDownSlot) {
|
||||
tplayer.DrawnSlot = Player.HandsDownSlot
|
||||
zone.AvatarEvents ! AvatarServiceMessage(
|
||||
zone.id,
|
||||
AvatarAction.ObjectHeld(guid, Player.HandsDownSlot, slot)
|
||||
)
|
||||
zone.AvatarEvents ! MessageEnvelope(zone.id, guid, AvatarAction.ObjectHeld(Player.HandsDownSlot, slot))
|
||||
true
|
||||
} else {
|
||||
false
|
||||
|
|
@ -951,7 +930,7 @@ object WorldSession {
|
|||
player.ContributionFrom(term)
|
||||
}
|
||||
}
|
||||
player.Zone.AvatarEvents ! AvatarServiceMessage(
|
||||
player.Zone.AvatarEvents ! MessageEnvelope(
|
||||
player.Name,
|
||||
AvatarAction.TerminalOrderResult(guid, transaction, result)
|
||||
)
|
||||
|
|
|
|||
|
|
@ -11,9 +11,9 @@ import net.psforever.objects.vital.Vitality
|
|||
import net.psforever.objects.vital.etc.TriggerUsedReason
|
||||
import net.psforever.objects.vital.interaction.DamageInteraction
|
||||
import net.psforever.objects.zones.Zone
|
||||
import net.psforever.services.Service
|
||||
import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage}
|
||||
import net.psforever.services.local.{LocalAction, LocalServiceMessage}
|
||||
import net.psforever.services.base.envelope.MessageEnvelope
|
||||
import net.psforever.services.base.message.ObjectDelete
|
||||
import net.psforever.services.local.LocalAction
|
||||
import net.psforever.types.PlanetSideEmpire
|
||||
|
||||
import scala.annotation.unused
|
||||
|
|
@ -87,9 +87,9 @@ class BoomerDeployableControl(mine: BoomerDeployable)
|
|||
val events = mine.Zone.LocalEvents
|
||||
val msg = LocalAction.DeployItem(mine)
|
||||
originalOwner.collect { name =>
|
||||
events ! LocalServiceMessage(name, msg)
|
||||
events ! MessageEnvelope(name, msg)
|
||||
}
|
||||
events ! LocalServiceMessage(player.Name, msg)
|
||||
events ! MessageEnvelope(player.Name, msg)
|
||||
}
|
||||
|
||||
override def dismissDeployable() : Unit = {
|
||||
|
|
@ -107,10 +107,7 @@ class BoomerDeployableControl(mine: BoomerDeployable)
|
|||
zone.Ground ! Zone.Ground.RemoveItem(guid)
|
||||
case _ => ()
|
||||
}
|
||||
zone.AvatarEvents! AvatarServiceMessage(
|
||||
zone.id,
|
||||
AvatarAction.ObjectDelete(Service.defaultPlayerGUID, guid)
|
||||
)
|
||||
zone.AvatarEvents! MessageEnvelope(zone.id, ObjectDelete(guid))
|
||||
TaskWorkflow.execute(GUIDTask.unregisterObject(zone.GUID, trigger))
|
||||
case None => ()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,12 @@
|
|||
// Copyright (c) 2017 PSForever
|
||||
package net.psforever.objects
|
||||
|
||||
import net.psforever.types.{PlanetSideGUID, ValidPlanetSideGUID}
|
||||
|
||||
object Default {
|
||||
//'g'lobal 'u'nique 'id'entifier
|
||||
final val GUID0: PlanetSideGUID = ValidPlanetSideGUID(0)
|
||||
|
||||
//cancellable
|
||||
import akka.actor.Cancellable
|
||||
protected class InternalCancellable extends Cancellable {
|
||||
|
|
|
|||
|
|
@ -9,8 +9,9 @@ import net.psforever.objects.ce.{Deployable, DeployedItem}
|
|||
import net.psforever.objects.sourcing.{PlayerSource, SourceEntry}
|
||||
import net.psforever.objects.zones.Zone
|
||||
import net.psforever.packet.game._
|
||||
import net.psforever.services.base.envelope.MessageEnvelope
|
||||
import net.psforever.types.PlanetSideGUID
|
||||
import net.psforever.services.local.{LocalAction, LocalServiceMessage}
|
||||
import net.psforever.services.local.LocalAction
|
||||
|
||||
object Deployables {
|
||||
//private val log = org.log4s.getLogger("Deployables")
|
||||
|
|
@ -92,13 +93,9 @@ object Deployables {
|
|||
}
|
||||
target.AssignOwnership(None)
|
||||
}
|
||||
events ! LocalServiceMessage(
|
||||
events ! MessageEnvelope(
|
||||
s"${target.Faction}",
|
||||
LocalAction.DeployableMapIcon(
|
||||
PlanetSideGUID(0),
|
||||
DeploymentAction.Dismiss,
|
||||
DeployableInfo(target.GUID, Deployable.Icon(item), target.Position, PlanetSideGUID(0))
|
||||
)
|
||||
LocalAction.DeployableMapIcon(DeploymentAction.Dismiss, DeployableInfo(target.GUID, Deployable.Icon(item), target.Position, PlanetSideGUID(0)))
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -17,9 +17,9 @@ import net.psforever.objects.vital.interaction.{DamageInteraction, DamageResult}
|
|||
import net.psforever.objects.vital.projectile.ProjectileReason
|
||||
import net.psforever.objects.zones.Zone
|
||||
import net.psforever.types.Vector3
|
||||
import net.psforever.services.Service
|
||||
import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage}
|
||||
import net.psforever.services.local.{LocalAction, LocalServiceMessage}
|
||||
import net.psforever.services.avatar.AvatarAction
|
||||
import net.psforever.services.base.envelope.MessageEnvelope
|
||||
import net.psforever.services.local.LocalAction
|
||||
|
||||
import scala.annotation.unused
|
||||
import scala.concurrent.duration._
|
||||
|
|
@ -182,7 +182,7 @@ object ExplosiveDeployableControl {
|
|||
target.Health = 1 // short-circuit logic in DestructionAwareness
|
||||
val zone = target.Zone
|
||||
zone.Activity ! Zone.HotSpot.Activity(cause)
|
||||
zone.LocalEvents ! LocalServiceMessage(zone.id, LocalAction.Detonate(target.GUID, target))
|
||||
zone.LocalEvents ! MessageEnvelope(zone.id, LocalAction.Detonate(target.GUID, target))
|
||||
Zone.serverSideDamage(
|
||||
zone,
|
||||
target,
|
||||
|
|
@ -210,14 +210,14 @@ object ExplosiveDeployableControl {
|
|||
Some(if (target.Jammed || target.Destroyed) 0 seconds else 500 milliseconds)
|
||||
)
|
||||
target.Destroyed = true
|
||||
zone.AvatarEvents ! AvatarServiceMessage(
|
||||
zone.AvatarEvents ! MessageEnvelope(
|
||||
zone.id,
|
||||
AvatarAction.Destroy(target.GUID, attribution, Service.defaultPlayerGUID, target.Position)
|
||||
AvatarAction.Destroy(target.GUID, attribution, Default.GUID0, target.Position)
|
||||
)
|
||||
if (target.Health == 0) {
|
||||
zone.LocalEvents ! LocalServiceMessage(
|
||||
zone.LocalEvents ! MessageEnvelope(
|
||||
zone.id,
|
||||
LocalAction.TriggerEffect(Service.defaultPlayerGUID, "detonate_damaged_mine", target.GUID)
|
||||
LocalAction.TriggerEffect("detonate_damaged_mine", target.GUID)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,8 +12,8 @@ import net.psforever.objects.serverobject.{CommonMessages, PlanetSideServerObjec
|
|||
import net.psforever.objects.sourcing.{PlayerSource, SourceEntry, TurretSource}
|
||||
import net.psforever.objects.vital.{DismountingActivity, InGameActivity, MountingActivity, ShieldCharge}
|
||||
import net.psforever.packet.game.HackState1
|
||||
import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage}
|
||||
import net.psforever.types.PlanetSideGUID
|
||||
import net.psforever.services.base.envelope.MessageEnvelope
|
||||
import net.psforever.services.base.message.PlanetsideAttribute
|
||||
|
||||
import scala.annotation.unused
|
||||
|
||||
|
|
@ -98,9 +98,9 @@ class FieldTurretControl(turret: TurretDeployable)
|
|||
if (canChargeShields) {
|
||||
turret.LogActivity(ShieldCharge(amount, motivator))
|
||||
turret.Shields = turret.Shields + amount
|
||||
turret.Zone.VehicleEvents ! VehicleServiceMessage(
|
||||
turret.Zone.VehicleEvents ! MessageEnvelope(
|
||||
s"${turret.Actor}",
|
||||
VehicleAction.PlanetsideAttribute(PlanetSideGUID(0), turret.GUID, turret.Definition.shieldUiAttribute, turret.Shields)
|
||||
PlanetsideAttribute(turret.GUID, turret.Definition.shieldUiAttribute, turret.Shields)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,11 +19,13 @@ import net.psforever.objects.vital.{InGameActivity, InGameHistory, RevivingActiv
|
|||
import net.psforever.objects.zones.Zone
|
||||
import net.psforever.packet.game._
|
||||
import net.psforever.types.{ChatMessageType, ExoSuitType, PlanetSideGUID, Vector3}
|
||||
import net.psforever.services.Service
|
||||
import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage}
|
||||
import net.psforever.services.local.{LocalAction, LocalServiceMessage}
|
||||
import net.psforever.services.avatar.AvatarAction
|
||||
import net.psforever.services.base.envelope.{BundledEnvelope, MessageEnvelope}
|
||||
import net.psforever.services.base.message.{ObjectDelete, SendResponse}
|
||||
import net.psforever.services.local.LocalAction
|
||||
|
||||
import scala.annotation.tailrec
|
||||
import scala.collection.mutable.ArrayBuffer
|
||||
|
||||
object Players {
|
||||
private val log = org.log4s.getLogger("Players")
|
||||
|
|
@ -48,10 +50,7 @@ object Players {
|
|||
) {
|
||||
val events = target.Zone.AvatarEvents
|
||||
val uname = user.Name
|
||||
events ! AvatarServiceMessage(
|
||||
uname,
|
||||
AvatarAction.SendResponse(Service.defaultPlayerGUID, RepairMessage(target.GUID, progress.toInt))
|
||||
)
|
||||
events ! MessageEnvelope(uname, SendResponse(RepairMessage(target.GUID, progress.toInt)))
|
||||
true
|
||||
} else {
|
||||
false
|
||||
|
|
@ -61,7 +60,7 @@ object Players {
|
|||
/**
|
||||
* na
|
||||
* @see `AvatarAction.Revive`
|
||||
* @see `AvatarResponse.Revive`
|
||||
* @see `AvatarAction.Revive`
|
||||
* @param target the player being revived
|
||||
* @param medic the name of the player doing the reviving
|
||||
* @param item the tool being used to revive the target player
|
||||
|
|
@ -76,12 +75,12 @@ object Players {
|
|||
PlayerControl.sendResponse(
|
||||
target.Zone,
|
||||
medicName,
|
||||
AvatarAction.SendResponse(
|
||||
Service.defaultPlayerGUID,
|
||||
Default.GUID0,
|
||||
SendResponse(
|
||||
InventoryStateMessage(item.AmmoSlot.Box.GUID, item.GUID, magazine)
|
||||
)
|
||||
)
|
||||
PlayerControl.sendResponse(target.Zone, name, AvatarAction.Revive(target.GUID))
|
||||
PlayerControl.sendResponse(target.Zone, name, Default.GUID0, AvatarAction.Revive(target.GUID))
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -163,7 +162,7 @@ object Players {
|
|||
ExoSuitDefinition.Select(exosuit, player.Faction).Permissions match {
|
||||
case Nil =>
|
||||
true
|
||||
case permissions if player.IsInVRZone =>
|
||||
case _ if player.IsInVRZone =>
|
||||
true
|
||||
case permissions if subtype != 0 =>
|
||||
val certs = player.avatar.certifications
|
||||
|
|
@ -316,7 +315,7 @@ object Players {
|
|||
): Boolean = {
|
||||
if (player.Zone == obj.Zone && addFunc(obj)) {
|
||||
obj.Actor ! Deployable.Ownership(player)
|
||||
player.Zone.LocalEvents ! LocalServiceMessage(player.Name, LocalAction.DeployableUIFor(obj.Definition.Item))
|
||||
player.Zone.LocalEvents ! MessageEnvelope(player.Name, LocalAction.DeployableUIFor(obj.Definition.Item))
|
||||
true
|
||||
} else {
|
||||
false
|
||||
|
|
@ -333,7 +332,7 @@ object Players {
|
|||
//sent to avatar event bus to preempt additional tool management
|
||||
buildCooldownReset(zone, channel, obj.GUID)
|
||||
//sent to local event bus to cooperate with deployable management
|
||||
zone.LocalEvents ! LocalServiceMessage(
|
||||
zone.LocalEvents ! MessageEnvelope(
|
||||
channel,
|
||||
LocalAction.DeployableUIFor(obj.Definition.Item)
|
||||
)
|
||||
|
|
@ -347,10 +346,7 @@ object Players {
|
|||
*/
|
||||
def buildCooldownReset(zone: Zone, channel: String, guid: PlanetSideGUID): Unit = {
|
||||
//sent to avatar event bus to preempt additional tool management
|
||||
zone.AvatarEvents ! AvatarServiceMessage(
|
||||
channel,
|
||||
AvatarAction.SendResponse(Service.defaultPlayerGUID, GenericObjectActionMessage(guid, 21))
|
||||
)
|
||||
zone.AvatarEvents ! MessageEnvelope(channel, SendResponse(GenericObjectActionMessage(guid, 21)))
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -406,10 +402,7 @@ object Players {
|
|||
}
|
||||
}) {
|
||||
val zone = player.Zone
|
||||
zone.AvatarEvents ! AvatarServiceMessage(
|
||||
zone.id,
|
||||
AvatarAction.ObjectDelete(Service.defaultPlayerGUID, tool.GUID)
|
||||
)
|
||||
zone.AvatarEvents ! MessageEnvelope(zone.id, ObjectDelete(tool.GUID))
|
||||
true
|
||||
} else {
|
||||
false
|
||||
|
|
@ -444,27 +437,20 @@ object Players {
|
|||
if ((player.Slot(index).Equipment = obj).contains(obj)) {
|
||||
val fireMode = tool.FireModeIndex
|
||||
val ammoType = tool.AmmoTypeIndex
|
||||
val list: ArrayBuffer[MessageEnvelope] = ArrayBuffer()
|
||||
player.Inventory -= x.start
|
||||
obj.FireModeIndex = fireMode
|
||||
//TODO any penalty for being handed an OCM version of the tool?
|
||||
events ! AvatarServiceMessage(
|
||||
zone.id,
|
||||
AvatarAction.EquipmentInHand(Service.defaultPlayerGUID, pguid, index, obj)
|
||||
)
|
||||
list.append(MessageEnvelope(zone.id, AvatarAction.EquipmentInHand(pguid, index, obj)))
|
||||
if (obj.AmmoTypeIndex != ammoType) {
|
||||
obj.AmmoTypeIndex = ammoType
|
||||
events ! AvatarServiceMessage(
|
||||
name,
|
||||
AvatarAction.SendResponse(Service.defaultPlayerGUID, ChangeAmmoMessage(obj.GUID, ammoType))
|
||||
)
|
||||
list.append(MessageEnvelope(name, SendResponse(ChangeAmmoMessage(obj.GUID, ammoType))))
|
||||
}
|
||||
if (player.DrawnSlot == Player.HandsDownSlot) {
|
||||
player.DrawnSlot = index
|
||||
events ! AvatarServiceMessage(
|
||||
zone.id,
|
||||
AvatarAction.ObjectHeld(pguid, index, index)
|
||||
)
|
||||
list.append(MessageEnvelope(zone.id, pguid, AvatarAction.ObjectHeld(index, index)))
|
||||
}
|
||||
events ! BundledEnvelope(list)
|
||||
}
|
||||
case Nil => ; //no replacements found
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,10 +12,10 @@ import net.psforever.objects.serverobject.hackable.Hackable
|
|||
import net.psforever.objects.serverobject.repair.RepairableEntity
|
||||
import net.psforever.objects.vital.SimpleResolutions
|
||||
import net.psforever.objects.vital.interaction.DamageResult
|
||||
import net.psforever.services.base.envelope.MessageEnvelope
|
||||
import net.psforever.types.{PlanetSideGUID, Vector3}
|
||||
import net.psforever.services.Service
|
||||
import net.psforever.services.local.{LocalAction, LocalServiceMessage}
|
||||
import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage}
|
||||
import net.psforever.services.base.message.PlanetsideAttribute
|
||||
import net.psforever.services.local.LocalAction
|
||||
|
||||
import scala.annotation.unused
|
||||
import scala.concurrent.duration._
|
||||
|
|
@ -75,9 +75,9 @@ class SensorDeployableControl(sensor: SensorDeployable)
|
|||
override def StartJammeredSound(target: Any, dur: Int): Unit =
|
||||
target match {
|
||||
case obj: PlanetSideServerObject if !jammedSound =>
|
||||
obj.Zone.VehicleEvents ! VehicleServiceMessage(
|
||||
obj.Zone.VehicleEvents ! MessageEnvelope(
|
||||
obj.Zone.id,
|
||||
VehicleAction.PlanetsideAttribute(Service.defaultPlayerGUID, obj.GUID, 54, 1)
|
||||
PlanetsideAttribute(obj.GUID, 54, 1)
|
||||
)
|
||||
super.StartJammeredSound(obj, dur)
|
||||
case _ => ;
|
||||
|
|
@ -87,9 +87,9 @@ class SensorDeployableControl(sensor: SensorDeployable)
|
|||
target match {
|
||||
case obj: PlanetSideServerObject with JammableUnit =>
|
||||
val zone = obj.Zone
|
||||
zone.LocalEvents ! LocalServiceMessage(
|
||||
zone.LocalEvents ! MessageEnvelope(
|
||||
zone.id,
|
||||
LocalAction.TriggerEffectInfo(Service.defaultPlayerGUID, "on", obj.GUID, unk1=false, 1000)
|
||||
LocalAction.TriggerEffectInfo(obj.GUID, "on", unk1=false, 1000)
|
||||
)
|
||||
super.StartJammeredStatus(obj, dur)
|
||||
case _ => ;
|
||||
|
|
@ -99,9 +99,9 @@ class SensorDeployableControl(sensor: SensorDeployable)
|
|||
target match {
|
||||
case obj: PlanetSideServerObject if jammedSound =>
|
||||
val zone = obj.Zone
|
||||
zone.VehicleEvents ! VehicleServiceMessage(
|
||||
zone.VehicleEvents ! MessageEnvelope(
|
||||
zone.id,
|
||||
VehicleAction.PlanetsideAttribute(Service.defaultPlayerGUID, obj.GUID, 54, 0)
|
||||
PlanetsideAttribute(obj.GUID, 54, 0)
|
||||
)
|
||||
case _ => ;
|
||||
}
|
||||
|
|
@ -112,9 +112,9 @@ class SensorDeployableControl(sensor: SensorDeployable)
|
|||
target match {
|
||||
case obj: PlanetSideServerObject with JammableUnit if obj.Jammed =>
|
||||
val zone = sensor.Zone
|
||||
zone.LocalEvents ! LocalServiceMessage(
|
||||
zone.LocalEvents ! MessageEnvelope(
|
||||
zone.id,
|
||||
LocalAction.TriggerEffectInfo(Service.defaultPlayerGUID, "on", obj.GUID, unk1=true, 1000)
|
||||
LocalAction.TriggerEffectInfo(obj.GUID, "on", unk1=true, 1000)
|
||||
)
|
||||
case _ => ;
|
||||
}
|
||||
|
|
@ -124,9 +124,9 @@ class SensorDeployableControl(sensor: SensorDeployable)
|
|||
override def finalizeDeployable(callback: ActorRef) : Unit = {
|
||||
super.finalizeDeployable(callback)
|
||||
val zone = sensor.Zone
|
||||
zone.LocalEvents ! LocalServiceMessage(
|
||||
zone.LocalEvents ! MessageEnvelope(
|
||||
zone.id,
|
||||
LocalAction.TriggerEffectInfo(Service.defaultPlayerGUID, "on", sensor.GUID, unk1=true, 1000)
|
||||
LocalAction.TriggerEffectInfo(sensor.GUID, "on", unk1=true, 1000)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -141,9 +141,9 @@ object SensorDeployableControl {
|
|||
def DestructionAwareness(target: Deployable, attribution: PlanetSideGUID): Unit = {
|
||||
Deployables.AnnounceDestroyDeployable(target, Some(1 seconds))
|
||||
val zone = target.Zone
|
||||
zone.LocalEvents ! LocalServiceMessage(
|
||||
zone.LocalEvents ! MessageEnvelope(
|
||||
zone.id,
|
||||
LocalAction.TriggerEffectInfo(Service.defaultPlayerGUID, "on", target.GUID, unk1=false, 1000)
|
||||
LocalAction.TriggerEffectInfo(target.GUID, "on", unk1=false, 1000)
|
||||
)
|
||||
//position the explosion effect near the bulky area of the sensor stalk
|
||||
val ang = target.Orientation
|
||||
|
|
@ -157,9 +157,9 @@ object SensorDeployableControl {
|
|||
pos.z + math.cos(yRadians).toFloat * 0.875f
|
||||
)
|
||||
}
|
||||
zone.LocalEvents ! LocalServiceMessage(
|
||||
zone.LocalEvents ! MessageEnvelope(
|
||||
zone.id,
|
||||
LocalAction.TriggerEffectLocation(Service.defaultPlayerGUID, "motion_sensor_destroyed", explosionPos, ang)
|
||||
LocalAction.TriggerEffectLocation("motion_sensor_destroyed", explosionPos, ang)
|
||||
)
|
||||
//TODO replaced by an alternate model (charred stub)?
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,21 +13,21 @@ import net.psforever.objects.serverobject.hackable.Hackable
|
|||
import net.psforever.objects.serverobject.repair.RepairableEntity
|
||||
import net.psforever.objects.vital.interaction.DamageResult
|
||||
import net.psforever.objects.vital.resolution.ResolutionCalculations
|
||||
import net.psforever.services.base.envelope.MessageEnvelope
|
||||
import net.psforever.services.base.message.PlanetsideAttribute
|
||||
import net.psforever.types.PlanetSideGUID
|
||||
import net.psforever.services.Service
|
||||
import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage}
|
||||
|
||||
class ShieldGeneratorDeployable(cdef: ShieldGeneratorDefinition)
|
||||
extends Deployable(cdef)
|
||||
with Hackable
|
||||
with JammableUnit
|
||||
|
||||
class ShieldGeneratorDefinition extends DeployableDefinition(240)
|
||||
class ShieldGeneratorDefinition extends DeployableDefinition(objectId = 240)
|
||||
with WithShields {
|
||||
Packet = new ShieldGeneratorConverter
|
||||
DeployCategory = DeployableCategory.ShieldGenerators
|
||||
|
||||
override def Initialize(obj: Deployable, context: ActorContext) = {
|
||||
override def Initialize(obj: Deployable, context: ActorContext): Unit = {
|
||||
obj.Actor =
|
||||
context.actorOf(Props(classOf[ShieldGeneratorControl], obj), PlanetSideServerObject.UniqueActorName(obj))
|
||||
}
|
||||
|
|
@ -39,10 +39,10 @@ class ShieldGeneratorControl(gen: ShieldGeneratorDeployable)
|
|||
with JammableBehavior
|
||||
with DamageableEntity
|
||||
with RepairableEntity {
|
||||
def DeployableObject = gen
|
||||
def JammableObject = gen
|
||||
def DamageableObject = gen
|
||||
def RepairableObject = gen
|
||||
def DeployableObject: ShieldGeneratorDeployable = gen
|
||||
def JammableObject: ShieldGeneratorDeployable = gen
|
||||
def DamageableObject: ShieldGeneratorDeployable = gen
|
||||
def RepairableObject: ShieldGeneratorDeployable = gen
|
||||
deletionType = 1 //from DeployableBehavior
|
||||
|
||||
override def postStop(): Unit = {
|
||||
|
|
@ -125,9 +125,9 @@ class ShieldGeneratorControl(gen: ShieldGeneratorDeployable)
|
|||
override def StartJammeredStatus(target: Any, dur: Int): Unit =
|
||||
target match {
|
||||
case obj: PlanetSideServerObject with JammableUnit =>
|
||||
obj.Zone.VehicleEvents ! VehicleServiceMessage(
|
||||
obj.Zone.VehicleEvents ! MessageEnvelope(
|
||||
obj.Zone.id,
|
||||
VehicleAction.PlanetsideAttribute(Service.defaultPlayerGUID, obj.GUID, 27, 1)
|
||||
PlanetsideAttribute(obj.GUID, 27, 1)
|
||||
)
|
||||
super.StartJammeredStatus(obj, dur)
|
||||
case _ => ;
|
||||
|
|
@ -138,9 +138,9 @@ class ShieldGeneratorControl(gen: ShieldGeneratorDeployable)
|
|||
override def CancelJammeredStatus(target: Any): Unit = {
|
||||
target match {
|
||||
case obj: PlanetSideServerObject with JammableUnit if obj.Jammed =>
|
||||
obj.Zone.VehicleEvents ! VehicleServiceMessage(
|
||||
obj.Zone.VehicleEvents ! MessageEnvelope(
|
||||
obj.Zone.id,
|
||||
VehicleAction.PlanetsideAttribute(Service.defaultPlayerGUID, obj.GUID, 27, 0)
|
||||
PlanetsideAttribute(obj.GUID, 27, 0)
|
||||
)
|
||||
case _ => ;
|
||||
}
|
||||
|
|
@ -160,9 +160,9 @@ object ShieldGeneratorControl {
|
|||
//shields
|
||||
if (damageToShields) {
|
||||
val zone = target.Zone
|
||||
zone.VehicleEvents ! VehicleServiceMessage(
|
||||
zone.VehicleEvents ! MessageEnvelope(
|
||||
zone.id,
|
||||
VehicleAction.PlanetsideAttribute(Service.defaultPlayerGUID, target.GUID, 68, target.Shields)
|
||||
PlanetsideAttribute(target.GUID, 68, target.Shields)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,7 +11,8 @@ import net.psforever.objects.vehicles.Utility.InternalTelepad
|
|||
import net.psforever.objects.vital.SimpleResolutions
|
||||
import net.psforever.objects.vital.interaction.DamageResult
|
||||
import net.psforever.objects.zones.Zone
|
||||
import net.psforever.services.local.{LocalAction, LocalServiceMessage}
|
||||
import net.psforever.services.base.envelope.MessageEnvelope
|
||||
import net.psforever.services.local.LocalAction
|
||||
|
||||
import scala.concurrent.duration._
|
||||
|
||||
|
|
@ -133,6 +134,6 @@ object TelepadControl {
|
|||
}
|
||||
|
||||
def TelepadError(zone: Zone, channel: String, msg: String): Unit = {
|
||||
zone.LocalEvents ! LocalServiceMessage(channel, LocalAction.RouterTelepadMessage(msg))
|
||||
zone.LocalEvents ! MessageEnvelope(channel, LocalAction.RouterTelepadMessage(msg))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@ package net.psforever.objects
|
|||
|
||||
import net.psforever.objects.equipment.ChargeFireModeDefinition
|
||||
import net.psforever.packet.game.QuantityUpdateMessage
|
||||
import net.psforever.services.Service
|
||||
import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage}
|
||||
import net.psforever.services.base.envelope.MessageEnvelope
|
||||
import net.psforever.services.base.message.SendResponse
|
||||
|
||||
object Tools {
|
||||
/**
|
||||
|
|
@ -22,12 +22,9 @@ object Tools {
|
|||
tool.FireMode match {
|
||||
case mode: ChargeFireModeDefinition if tool.Magazine > 0 =>
|
||||
val magazine = tool.Magazine -= mode.RoundsPerInterval
|
||||
player.Zone.AvatarEvents ! AvatarServiceMessage(
|
||||
player.Zone.AvatarEvents ! MessageEnvelope(
|
||||
player.Name,
|
||||
AvatarAction.SendResponse(
|
||||
Service.defaultPlayerGUID,
|
||||
QuantityUpdateMessage(tool.AmmoSlot.Box.GUID, magazine)
|
||||
)
|
||||
SendResponse(QuantityUpdateMessage(tool.AmmoSlot.Box.GUID, magazine))
|
||||
)
|
||||
player.isAlive
|
||||
case _ =>
|
||||
|
|
|
|||
|
|
@ -20,7 +20,8 @@ import net.psforever.objects.vital.resistance.StandardResistanceProfile
|
|||
import net.psforever.objects.vital.{SimpleResolutions, StandardVehicleResistance}
|
||||
import net.psforever.objects.zones.interaction.InteractsWithZone
|
||||
import net.psforever.packet.game.TriggeredSound
|
||||
import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage}
|
||||
import net.psforever.services.base.envelope.MessageEnvelope
|
||||
import net.psforever.services.vehicle.VehicleAction
|
||||
|
||||
import scala.concurrent.duration.FiniteDuration
|
||||
|
||||
|
|
@ -109,9 +110,10 @@ abstract class TurretDeployableControl
|
|||
case player: Player =>
|
||||
seat.unmount(player)
|
||||
player.VehicleSeated = None
|
||||
zone.VehicleEvents ! VehicleServiceMessage(
|
||||
zone.VehicleEvents ! MessageEnvelope(
|
||||
zone.id,
|
||||
VehicleAction.KickPassenger(player.GUID, 4, wasKickedByDriver, TurretObject.GUID)
|
||||
player.GUID,
|
||||
VehicleAction.KickPassenger(4, wasKickedByDriver, TurretObject.GUID)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,13 +9,16 @@ import net.psforever.objects.serverobject.resourcesilo.ResourceSilo
|
|||
import net.psforever.objects.serverobject.transfer.TransferContainer
|
||||
import net.psforever.objects.serverobject.structures.WarpGate
|
||||
import net.psforever.objects.vehicles._
|
||||
import net.psforever.objects.vehicles.control.CargoBehavior
|
||||
import net.psforever.objects.zones.Zone
|
||||
import net.psforever.packet.game.{ChatMsg, FrameVehicleStateMessage, GenericObjectActionEnum, GenericObjectActionMessage, HackMessage, HackState, HackState1, HackState7, TriggeredSound, VehicleStateMessage}
|
||||
import net.psforever.packet.game.{ChatMsg, FrameVehicleStateMessage, GenericObjectActionEnum, HackMessage, HackState, HackState1, HackState7, TriggeredSound, VehicleStateMessage}
|
||||
import net.psforever.types.{ChatMessageType, DriveState, PlanetSideEmpire, PlanetSideGUID, Vector3}
|
||||
import net.psforever.services.Service
|
||||
import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage}
|
||||
import net.psforever.services.local.{LocalAction, LocalServiceMessage}
|
||||
import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage}
|
||||
import net.psforever.services.base.envelope.{BundledEnvelope, MessageEnvelope}
|
||||
import net.psforever.services.base.message.{GenericObjectAction, PlanetsideAttribute, SendResponse, SetEmpire}
|
||||
import net.psforever.services.local.LocalAction
|
||||
import net.psforever.services.vehicle.VehicleAction
|
||||
|
||||
import scala.collection.mutable.ArrayBuffer
|
||||
|
||||
//import scala.concurrent.duration._
|
||||
|
||||
|
|
@ -45,9 +48,10 @@ object Vehicles {
|
|||
val locked = VehicleLockState.Locked.id
|
||||
Array(0, 3).foreach(group => vehicle.PermissionGroup(group, locked))
|
||||
Vehicles.ReloadAccessPermissions(vehicle, tplayer.Faction.toString)
|
||||
vehicle.Zone.VehicleEvents ! VehicleServiceMessage(
|
||||
vehicle.Zone.VehicleEvents ! MessageEnvelope(
|
||||
vehicle.Zone.id,
|
||||
VehicleAction.Ownership(tplayer.GUID, vehicle.GUID)
|
||||
tplayer.GUID,
|
||||
VehicleAction.Ownership(vehicle.GUID)
|
||||
)
|
||||
Some(vehicle)
|
||||
case None =>
|
||||
|
|
@ -88,9 +92,9 @@ object Vehicles {
|
|||
val empire = VehicleLockState.Empire.id
|
||||
(0 to 2).foreach(group => vehicle.PermissionGroup(group, empire))
|
||||
ReloadAccessPermissions(vehicle, vehicle.Faction.toString)
|
||||
zone.VehicleEvents ! VehicleServiceMessage(
|
||||
zone.VehicleEvents ! MessageEnvelope(
|
||||
zone.id,
|
||||
VehicleAction.LoseOwnership(ownerGuid.getOrElse(Service.defaultPlayerGUID), guid)
|
||||
VehicleAction.LoseOwnership(ownerGuid.getOrElse(Default.GUID0), guid)
|
||||
)
|
||||
result
|
||||
}
|
||||
|
|
@ -138,13 +142,14 @@ object Vehicles {
|
|||
val pguid = player.GUID
|
||||
if (vehicle.OwnerGuid.contains(pguid)) {
|
||||
vehicle.AssignOwnership(None)
|
||||
//vehicle.Zone.VehicleEvents ! VehicleServiceMessage(player.Name, VehicleAction.Ownership(pguid, PlanetSideGUID(0)))
|
||||
//vehicle.Zone.VehicleEvents ! MessageEnvelope(player.Name, pguid, VehicleAction.Ownership(pguid, PlanetSideGUID(0)))
|
||||
//val vguid = vehicle.GUID
|
||||
val empire = VehicleLockState.Empire.id
|
||||
(0 to 2).foreach(group => {
|
||||
vehicle.PermissionGroup(group, empire)
|
||||
/*vehicle.Zone.VehicleEvents ! VehicleServiceMessage(
|
||||
/*vehicle.Zone.VehicleEvents ! MessageEnvelope(
|
||||
s"${vehicle.Faction}",
|
||||
pguid,
|
||||
VehicleAction.SeatPermissions(pguid, vguid, group, empire)
|
||||
)*/
|
||||
})
|
||||
|
|
@ -167,9 +172,9 @@ object Vehicles {
|
|||
def ReloadAccessPermissions(vehicle: Vehicle, toChannel: String): Unit = {
|
||||
val vehicle_guid = vehicle.GUID
|
||||
(0 to 3).foreach(group => {
|
||||
vehicle.Zone.AvatarEvents ! AvatarServiceMessage(
|
||||
vehicle.Zone.AvatarEvents ! MessageEnvelope(
|
||||
toChannel,
|
||||
AvatarAction.PlanetsideAttributeToAll(vehicle_guid, group + 10, vehicle.PermissionGroup(group).get.id)
|
||||
PlanetsideAttribute(vehicle_guid, group + 10, vehicle.PermissionGroup(group).get.id)
|
||||
)
|
||||
})
|
||||
}
|
||||
|
|
@ -246,16 +251,15 @@ object Vehicles {
|
|||
val hFaction = hacker.Faction
|
||||
val zone = target.Zone
|
||||
val zoneid = zone.id
|
||||
val avatarEvents = zone.AvatarEvents
|
||||
val vehicleEvents = zone.VehicleEvents
|
||||
val localEvents = zone.LocalEvents
|
||||
val previousOwnerName = target.OwnerName.getOrElse("")
|
||||
vehicleEvents ! VehicleServiceMessage(
|
||||
val occupantMessages: ArrayBuffer[MessageEnvelope] = ArrayBuffer()
|
||||
val vehicleMessages: ArrayBuffer[MessageEnvelope] = ArrayBuffer()
|
||||
vehicleMessages.append(MessageEnvelope(
|
||||
zoneid,
|
||||
VehicleAction.SendResponse(
|
||||
Service.defaultPlayerGUID,
|
||||
HackMessage(HackState1.Unk2, tGuid, hGuid, 100, 0f, HackState.Hacked, HackState7.Unk8)
|
||||
)
|
||||
)
|
||||
SendResponse(HackMessage(HackState1.Unk2, tGuid, hGuid, 100, 0f, HackState.Hacked, HackState7.Unk8))
|
||||
))
|
||||
target.Actor ! CommonMessages.Hack(hacker, target)
|
||||
// Forcefully dismount any cargo
|
||||
target.CargoHolds.foreach { case (_, cargoHold) =>
|
||||
|
|
@ -269,24 +273,29 @@ object Vehicles {
|
|||
player: Player =>
|
||||
seat.unmount(player)
|
||||
player.VehicleSeated = None
|
||||
vehicleEvents ! VehicleServiceMessage(
|
||||
occupantMessages.append(MessageEnvelope(
|
||||
zoneid,
|
||||
VehicleAction.KickPassenger(player.GUID, 4, unk2 = false, tGuid)
|
||||
)
|
||||
player.GUID,
|
||||
VehicleAction.KickPassenger(4, unk2 = false, tGuid)
|
||||
))
|
||||
}
|
||||
// In case BFR is occupied and may or may not be crouched
|
||||
if (GlobalDefinitions.isBattleFrameVehicle(target.Definition) && target.Seat(0).isDefined) {
|
||||
zone.LocalEvents ! LocalServiceMessage(
|
||||
zoneid,
|
||||
LocalAction.SendGenericObjectActionMessage(PlanetSideGUID(-1), target.GUID, GenericObjectActionEnum.BFRShieldsDown))
|
||||
zone.LocalEvents ! LocalServiceMessage(
|
||||
zoneid,
|
||||
LocalAction.SendResponse(
|
||||
FrameVehicleStateMessage(target.GUID, 0, target.Position, target.Orientation, Some(Vector3(0f, 0f, 0f)), unk2=false, 0, 0, is_crouched=true, is_airborne=false, ascending_flight=false, 10, 0, 0)))
|
||||
zone.LocalEvents ! LocalServiceMessage(
|
||||
zoneid,
|
||||
LocalAction.SendResponse(
|
||||
VehicleStateMessage(target.GUID, 0, target.Position, target.Orientation, Some(Vector3(0f, 0f, 0f)), None, 0, 0, 15, is_decelerating=false, is_cloaked=false)))
|
||||
vehicleMessages.appendAll(List(
|
||||
MessageEnvelope(zoneid,
|
||||
GenericObjectAction(target.GUID, GenericObjectActionEnum.BFRShieldsDown.id)
|
||||
),
|
||||
MessageEnvelope(zoneid,
|
||||
SendResponse(
|
||||
FrameVehicleStateMessage(target.GUID, 0, target.Position, target.Orientation, Some(Vector3(0f, 0f, 0f)), unk2=false, 0, 0, is_crouched=true, is_airborne=false, ascending_flight=false, 10, 0, 0)
|
||||
)
|
||||
),
|
||||
MessageEnvelope(zoneid,
|
||||
SendResponse(
|
||||
VehicleStateMessage(target.GUID, 0, target.Position, target.Orientation, Some(Vector3(0f, 0f, 0f)), None, 0, 0, 15, is_decelerating=false, is_cloaked=false)
|
||||
)
|
||||
)
|
||||
))
|
||||
}
|
||||
})
|
||||
// If the vehicle can fly and is flying: deconstruct it; and well played to whomever managed to hack a plane in mid air
|
||||
|
|
@ -311,25 +320,17 @@ object Vehicles {
|
|||
Vehicles.Own(target, hacker)
|
||||
//todo: Send HackMessage -> HackCleared to vehicle? can be found in packet captures. Not sure if necessary.
|
||||
// And broadcast the faction change to other clients
|
||||
zone.AvatarEvents ! AvatarServiceMessage(
|
||||
zoneid,
|
||||
AvatarAction.SetEmpire(Service.defaultPlayerGUID, tGuid, hFaction)
|
||||
)
|
||||
vehicleMessages.append(MessageEnvelope(zoneid, SetEmpire(tGuid, hFaction)))
|
||||
}
|
||||
localEvents ! LocalServiceMessage(
|
||||
vehicleMessages.append(MessageEnvelope(
|
||||
zoneid,
|
||||
LocalAction.TriggerSound(hGuid, TriggeredSound.HackVehicle, target.Position, 30, 0.49803925f)
|
||||
)
|
||||
hGuid,
|
||||
LocalAction.TriggerSound(TriggeredSound.HackVehicle, target.Position, 30, 0.49803925f)
|
||||
))
|
||||
if (zone.Players.exists(_.name.equals(previousOwnerName))) {
|
||||
localEvents ! LocalServiceMessage(
|
||||
previousOwnerName,
|
||||
LocalAction.SendResponse(ChatMsg(ChatMessageType.UNK_226, "@JackStolen"))
|
||||
)
|
||||
vehicleMessages.append(MessageEnvelope(previousOwnerName, SendResponse(ChatMsg(ChatMessageType.UNK_226, "@JackStolen"))))
|
||||
}
|
||||
localEvents ! LocalServiceMessage(
|
||||
hacker.Name,
|
||||
LocalAction.SendResponse(ChatMsg(ChatMessageType.UNK_226, "@JackVehicleOwned"))
|
||||
)
|
||||
occupantMessages.append(MessageEnvelope(hacker.Name, SendResponse(ChatMsg(ChatMessageType.UNK_226, "@JackVehicleOwned"))))
|
||||
// Clean up after specific vehicles, e.g. remove router telepads
|
||||
// If AMS is deployed, swap it to the new faction
|
||||
target.Definition match {
|
||||
|
|
@ -341,16 +342,15 @@ object Vehicles {
|
|||
util.Actor ! TelepadLike.Activate(util)
|
||||
}
|
||||
case GlobalDefinitions.ams if target.DeploymentState == DriveState.Deployed =>
|
||||
vehicleEvents ! VehicleServiceMessage.AMSDeploymentChange(zone)
|
||||
vehicleMessages.append(MessageEnvelope(zone.id, VehicleAction.AMSDeploymentChange(zone)))
|
||||
case _ => ()
|
||||
}
|
||||
vehicleEvents ! VehicleServiceMessage(
|
||||
vehicleMessages.append(MessageEnvelope(
|
||||
zoneid,
|
||||
VehicleAction.SendResponse(
|
||||
Service.defaultPlayerGUID,
|
||||
HackMessage(HackState1.Unk2, tGuid, tGuid, 0, 1L, HackState.HackCleared, HackState7.Unk8)
|
||||
)
|
||||
)
|
||||
SendResponse(HackMessage(HackState1.Unk2, tGuid, tGuid, 0, 1L, HackState.HackCleared, HackState7.Unk8))
|
||||
))
|
||||
avatarEvents ! BundledEnvelope(occupantMessages)
|
||||
vehicleEvents ! BundledEnvelope(vehicleMessages)
|
||||
target.Actor ! CommonMessages.ClearHack()
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ package net.psforever.objects.avatar
|
|||
import akka.actor.{Actor, ActorRef}
|
||||
import net.psforever.actors.zone.ShootingRangeTargetSpawner
|
||||
import net.psforever.objects.{GlobalDefinitions, Tool}
|
||||
import net.psforever.objects.avatar.AvatarBot
|
||||
import net.psforever.objects.equipment._
|
||||
import net.psforever.objects.serverobject.aura.{Aura, AuraEffectBehavior}
|
||||
import net.psforever.objects.serverobject.CommonMessages
|
||||
|
|
@ -14,18 +13,17 @@ import net.psforever.objects.vital.resolution.ResolutionCalculations.Output
|
|||
import net.psforever.objects.zones._
|
||||
import net.psforever.packet.game._
|
||||
import net.psforever.types._
|
||||
import net.psforever.services.Service
|
||||
import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage}
|
||||
import net.psforever.services.local.{LocalAction, LocalServiceMessage}
|
||||
import net.psforever.services.avatar.AvatarAction
|
||||
import net.psforever.objects.serverobject.environment.interaction.RespondsToZoneEnvironment
|
||||
import net.psforever.objects.serverobject.repair.Repairable
|
||||
import net.psforever.objects.sourcing.PlayerSource
|
||||
import net.psforever.objects.vital.{HealFromEquipment, RepairFromEquipment}
|
||||
import net.psforever.objects.vital.etc.SuicideReason
|
||||
import net.psforever.objects.vital.interaction.{DamageInteraction, DamageResult}
|
||||
import net.psforever.services.base.envelope.MessageEnvelope
|
||||
import net.psforever.services.base.message.{PlanetsideAttribute, SendResponse}
|
||||
|
||||
import java.util.concurrent.{Executors, TimeUnit}
|
||||
|
||||
import scala.concurrent.ExecutionContext.Implicits.global
|
||||
import scala.concurrent.duration._
|
||||
import scala.util.Random
|
||||
|
|
@ -53,7 +51,7 @@ class AvatarBotActor(bot: AvatarBot, spawnerActor: ActorRef)
|
|||
|
||||
def InteractiveObject: AvatarBot = bot
|
||||
|
||||
private[this] val log = org.log4s.getLogger(bot.Name)
|
||||
//private[this] val log = org.log4s.getLogger(bot.Name)
|
||||
private[this] val damageLog = org.log4s.getLogger(Damageable.LogChannel)
|
||||
private val scheduler = Executors.newScheduledThreadPool(2)
|
||||
/** suffocating, or regaining breath? */
|
||||
|
|
@ -107,14 +105,13 @@ class AvatarBotActor(bot: AvatarBot, spawnerActor: ActorRef)
|
|||
if (!(bot.isMoving || user.isMoving)) { //only allow stationary heals
|
||||
val newHealth = bot.Health = originalHealth + 10
|
||||
val magazine = item.Discharge()
|
||||
events ! AvatarServiceMessage(
|
||||
events ! MessageEnvelope(
|
||||
uname,
|
||||
AvatarAction.SendResponse(
|
||||
Service.defaultPlayerGUID,
|
||||
SendResponse(
|
||||
InventoryStateMessage(item.AmmoSlot.Box.GUID, item.GUID, magazine.toLong)
|
||||
)
|
||||
)
|
||||
events ! AvatarServiceMessage(zone.id, AvatarAction.PlanetsideAttributeToAll(guid, 0, newHealth))
|
||||
events ! MessageEnvelope(zone.id, PlanetsideAttribute(guid, 0, newHealth))
|
||||
bot.LogActivity(
|
||||
HealFromEquipment(
|
||||
PlayerSource(user),
|
||||
|
|
@ -124,10 +121,9 @@ class AvatarBotActor(bot: AvatarBot, spawnerActor: ActorRef)
|
|||
)
|
||||
}
|
||||
//progress bar remains visible for all heal attempts
|
||||
events ! AvatarServiceMessage(
|
||||
events ! MessageEnvelope(
|
||||
uname,
|
||||
AvatarAction.SendResponse(
|
||||
Service.defaultPlayerGUID,
|
||||
SendResponse(
|
||||
RepairMessage(guid, bot.Health * 100 / definition.MaxHealth)
|
||||
)
|
||||
)
|
||||
|
|
@ -150,14 +146,13 @@ class AvatarBotActor(bot: AvatarBot, spawnerActor: ActorRef)
|
|||
val newArmor = bot.Armor =
|
||||
originalArmor + Repairable.applyLevelModifier(user, item, RepairToolValue(item)).toInt + definition.RepairMod
|
||||
val magazine = item.Discharge()
|
||||
events ! AvatarServiceMessage(
|
||||
events ! MessageEnvelope(
|
||||
uname,
|
||||
AvatarAction.SendResponse(
|
||||
Service.defaultPlayerGUID,
|
||||
SendResponse(
|
||||
InventoryStateMessage(item.AmmoSlot.Box.GUID, item.GUID, magazine.toLong)
|
||||
)
|
||||
)
|
||||
events ! AvatarServiceMessage(zone.id, AvatarAction.PlanetsideAttributeToAll(guid, 4, bot.Armor))
|
||||
events ! MessageEnvelope(zone.id, PlanetsideAttribute(guid, 4, bot.Armor))
|
||||
bot.LogActivity(
|
||||
RepairFromEquipment(
|
||||
PlayerSource(user),
|
||||
|
|
@ -167,10 +162,9 @@ class AvatarBotActor(bot: AvatarBot, spawnerActor: ActorRef)
|
|||
)
|
||||
}
|
||||
//progress bar remains visible for all repair attempts
|
||||
events ! AvatarServiceMessage(
|
||||
events ! MessageEnvelope(
|
||||
uname,
|
||||
AvatarAction
|
||||
.SendResponse(Service.defaultPlayerGUID, RepairMessage(guid, bot.Armor * 100 / bot.MaxArmor))
|
||||
SendResponse(RepairMessage(guid, bot.Armor * 100 / bot.MaxArmor))
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -231,9 +225,9 @@ class AvatarBotActor(bot: AvatarBot, spawnerActor: ActorRef)
|
|||
//always do armor update
|
||||
if (damageToArmor > 0) {
|
||||
val zone = target.Zone
|
||||
zone.AvatarEvents ! AvatarServiceMessage(
|
||||
zone.AvatarEvents ! MessageEnvelope(
|
||||
zone.id,
|
||||
AvatarAction.PlanetsideAttributeToAll(target.GUID, 4, target.Armor)
|
||||
PlanetsideAttribute(target.GUID, 4, target.Armor)
|
||||
)
|
||||
}
|
||||
//choose
|
||||
|
|
@ -280,16 +274,13 @@ class AvatarBotActor(bot: AvatarBot, spawnerActor: ActorRef)
|
|||
announceConfrontation = true //TODO should we?
|
||||
}
|
||||
if (damageToHealth > 0) {
|
||||
events ! AvatarServiceMessage(zoneId, AvatarAction.PlanetsideAttributeToAll(targetGUID, 0, health))
|
||||
events ! MessageEnvelope(zoneId, PlanetsideAttribute(targetGUID, 0, health))
|
||||
announceConfrontation = true
|
||||
}
|
||||
val countableDamage = damageToHealth + damageToArmor
|
||||
if(announceConfrontation) {
|
||||
if (aggravated) {
|
||||
events ! AvatarServiceMessage(
|
||||
zoneId,
|
||||
AvatarAction.SendResponse(targetGUID, AggravatedDamageMessage(targetGUID, countableDamage))
|
||||
)
|
||||
events ! MessageEnvelope(zoneId, targetGUID, SendResponse(AggravatedDamageMessage(targetGUID, countableDamage)))
|
||||
} else {
|
||||
//activity on map
|
||||
zone.Activity ! Zone.HotSpot.Activity(cause)
|
||||
|
|
@ -332,22 +323,22 @@ class AvatarBotActor(bot: AvatarBot, spawnerActor: ActorRef)
|
|||
cause.adversarial match {
|
||||
case Some(a) =>
|
||||
damageLog.info(s"${a.defender.Name} was killed by ${a.attacker.Name}")
|
||||
events ! AvatarServiceMessage(
|
||||
events ! MessageEnvelope(
|
||||
zoneChannel,
|
||||
AvatarAction.DestroyDisplay(a.attacker, a.defender, a.implement)
|
||||
)
|
||||
case _ =>
|
||||
damageLog.info(s"${bot.Name} killed ${bot.Sex.pronounObject}self")
|
||||
events ! AvatarServiceMessage(zoneChannel, AvatarAction.DestroyDisplay(cause.interaction.target, cause.interaction.target, 0))
|
||||
events ! MessageEnvelope(zoneChannel, AvatarAction.DestroyDisplay(cause.interaction.target, cause.interaction.target, 0))
|
||||
}
|
||||
|
||||
events ! AvatarServiceMessage(nameChannel, AvatarAction.Killed(bot_guid, cause, None)) //align client interface fields with state
|
||||
events ! AvatarServiceMessage(zoneChannel, AvatarAction.PlanetsideAttributeToAll(bot_guid, 0, 0)) //health
|
||||
events ! MessageEnvelope(nameChannel, bot_guid, AvatarAction.Killed(cause, None)) //align client interface fields with state
|
||||
events ! MessageEnvelope(zoneChannel, PlanetsideAttribute(bot_guid, 0, 0)) //health
|
||||
val attribute = DamageableEntity.attributionTo(cause, target.Zone, bot_guid)
|
||||
events ! AvatarServiceMessage(
|
||||
events ! MessageEnvelope(
|
||||
nameChannel,
|
||||
AvatarAction.SendResponse(
|
||||
bot_guid,
|
||||
bot_guid,
|
||||
SendResponse(
|
||||
DestroyMessage(bot_guid, attribute, bot_guid, pos)
|
||||
) //how many players get this message?
|
||||
)
|
||||
|
|
@ -402,13 +393,13 @@ class AvatarBotActor(bot: AvatarBot, spawnerActor: ActorRef)
|
|||
private def performEmote(): Unit = {
|
||||
val zone = bot.Zone
|
||||
zone.blockMap.sector(bot).livePlayerList.collect { t =>
|
||||
zone.LocalEvents ! LocalServiceMessage(t.Name, LocalAction.SendResponse(TriggerBotAction(bot.GUID)))
|
||||
zone.LocalEvents ! MessageEnvelope(t.Name, SendResponse(TriggerBotAction(bot.GUID)))
|
||||
}
|
||||
}
|
||||
|
||||
private def tickLogic(): Unit = {
|
||||
val zone = bot.Zone
|
||||
if (!bot.Destroyed && zone.AllPlayers.size > 0) {
|
||||
if (!bot.Destroyed && zone.AllPlayers.nonEmpty) {
|
||||
bot.zoneInteractions()
|
||||
val rotateRNG = Random.nextDouble()
|
||||
if (canRotate) {
|
||||
|
|
@ -424,10 +415,10 @@ class AvatarBotActor(bot: AvatarBot, spawnerActor: ActorRef)
|
|||
)
|
||||
}
|
||||
}
|
||||
zone.AvatarEvents ! AvatarServiceMessage(
|
||||
zone.AvatarEvents ! MessageEnvelope(
|
||||
zone.id,
|
||||
bot.GUID,
|
||||
AvatarAction.PlayerState(
|
||||
bot.GUID,
|
||||
bot.Position,
|
||||
bot.Velocity,
|
||||
bot.Orientation.z,
|
||||
|
|
@ -436,10 +427,10 @@ class AvatarBotActor(bot: AvatarBot, spawnerActor: ActorRef)
|
|||
0,
|
||||
bot.Crouching,
|
||||
bot.Jumping,
|
||||
false,
|
||||
bot.Cloaked,
|
||||
false,
|
||||
false
|
||||
jump_thrust = false,
|
||||
is_cloaked = bot.Cloaked,
|
||||
spectator = false,
|
||||
weaponInHand = false
|
||||
)
|
||||
)
|
||||
if (canEmote) {
|
||||
|
|
@ -469,9 +460,9 @@ class AvatarBotActor(bot: AvatarBot, spawnerActor: ActorRef)
|
|||
override def StartJammeredSound(target: Any, dur: Int): Unit =
|
||||
target match {
|
||||
case obj: AvatarBot if !jammedSound =>
|
||||
obj.Zone.AvatarEvents ! AvatarServiceMessage(
|
||||
obj.Zone.AvatarEvents ! MessageEnvelope(
|
||||
obj.Zone.id,
|
||||
AvatarAction.PlanetsideAttributeToAll(obj.GUID, 27, 1)
|
||||
PlanetsideAttribute(obj.GUID, 27, 1)
|
||||
)
|
||||
super.StartJammeredSound(obj, 3000)
|
||||
case _ => ;
|
||||
|
|
@ -502,9 +493,9 @@ class AvatarBotActor(bot: AvatarBot, spawnerActor: ActorRef)
|
|||
override def CancelJammeredSound(target: Any): Unit =
|
||||
target match {
|
||||
case obj: AvatarBot if jammedSound =>
|
||||
obj.Zone.AvatarEvents ! AvatarServiceMessage(
|
||||
obj.Zone.AvatarEvents ! MessageEnvelope(
|
||||
obj.Zone.id,
|
||||
AvatarAction.PlanetsideAttributeToAll(obj.GUID, 27, 0)
|
||||
PlanetsideAttribute(obj.GUID, 27, 0)
|
||||
)
|
||||
super.CancelJammeredSound(obj)
|
||||
case _ => ;
|
||||
|
|
@ -521,10 +512,9 @@ class AvatarBotActor(bot: AvatarBot, spawnerActor: ActorRef)
|
|||
}
|
||||
|
||||
def UpdateAuraEffect(target: AuraEffectBehavior.Target) : Unit = {
|
||||
import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage}
|
||||
val zone = target.Zone
|
||||
val value = target.Aura.foldLeft(0)(_ + AvatarBotActor.auraEffectToAttributeValue(_))
|
||||
zone.AvatarEvents ! AvatarServiceMessage(zone.id, AvatarAction.PlanetsideAttributeToAll(target.GUID, 54, value))
|
||||
zone.AvatarEvents ! MessageEnvelope(zone.id, PlanetsideAttribute(target.GUID, 54, value))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -8,8 +8,8 @@ import net.psforever.objects.serverobject.containable.{Containable, ContainableB
|
|||
import net.psforever.packet.game.{ObjectAttachMessage, ObjectCreateDetailedMessage, ObjectDetachMessage}
|
||||
import net.psforever.packet.game.objectcreate.ObjectCreateMessageParent
|
||||
import net.psforever.types.{PlanetSideEmpire, Vector3}
|
||||
import net.psforever.services.Service
|
||||
import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage}
|
||||
import net.psforever.services.base.envelope.MessageEnvelope
|
||||
import net.psforever.services.base.message.{ObjectDelete, SendResponse}
|
||||
|
||||
class CorpseControl(player: Player) extends Actor with ContainableBehavior {
|
||||
def ContainerObject = player
|
||||
|
|
@ -25,9 +25,9 @@ class CorpseControl(player: Player) extends Actor with ContainableBehavior {
|
|||
val obj = ContainerObject
|
||||
obj.Find(item) match {
|
||||
case Some(slot) =>
|
||||
obj.Zone.AvatarEvents ! AvatarServiceMessage(
|
||||
obj.Zone.AvatarEvents ! MessageEnvelope(
|
||||
player.Zone.id,
|
||||
AvatarAction.SendResponse(Service.defaultPlayerGUID, ObjectAttachMessage(obj.GUID, item.GUID, slot))
|
||||
SendResponse(ObjectAttachMessage(obj.GUID, item.GUID, slot))
|
||||
)
|
||||
case None => ;
|
||||
}
|
||||
|
|
@ -40,7 +40,7 @@ class CorpseControl(player: Player) extends Actor with ContainableBehavior {
|
|||
val zone = obj.Zone
|
||||
val events = zone.AvatarEvents
|
||||
item.Faction = PlanetSideEmpire.NEUTRAL
|
||||
events ! AvatarServiceMessage(zone.id, AvatarAction.ObjectDelete(Service.defaultPlayerGUID, item.GUID))
|
||||
events ! MessageEnvelope(zone.id, ObjectDelete(item.GUID))
|
||||
}
|
||||
|
||||
def PutItemInSlotCallback(item: Equipment, slot: Int): Unit = {
|
||||
|
|
@ -48,10 +48,9 @@ class CorpseControl(player: Player) extends Actor with ContainableBehavior {
|
|||
val zone = obj.Zone
|
||||
val events = zone.AvatarEvents
|
||||
val definition = item.Definition
|
||||
events ! AvatarServiceMessage(
|
||||
events ! MessageEnvelope(
|
||||
zone.id,
|
||||
AvatarAction.SendResponse(
|
||||
Service.defaultPlayerGUID,
|
||||
SendResponse(
|
||||
ObjectCreateDetailedMessage(
|
||||
definition.ObjectId,
|
||||
item.GUID,
|
||||
|
|
@ -65,12 +64,9 @@ class CorpseControl(player: Player) extends Actor with ContainableBehavior {
|
|||
def SwapItemCallback(item: Equipment, fromSlot: Int): Unit = {
|
||||
val obj = ContainerObject
|
||||
val zone = obj.Zone
|
||||
zone.AvatarEvents ! AvatarServiceMessage(
|
||||
zone.AvatarEvents ! MessageEnvelope(
|
||||
zone.id,
|
||||
AvatarAction.SendResponse(
|
||||
Service.defaultPlayerGUID,
|
||||
ObjectDetachMessage(obj.GUID, item.GUID, Vector3.Zero, 0f)
|
||||
)
|
||||
SendResponse(ObjectDetachMessage(obj.GUID, item.GUID, Vector3.Zero, 0f))
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,9 +25,8 @@ import net.psforever.objects.zones._
|
|||
import net.psforever.packet.game._
|
||||
import net.psforever.packet.game.objectcreate.ObjectCreateMessageParent
|
||||
import net.psforever.types._
|
||||
import net.psforever.services.Service
|
||||
import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage}
|
||||
import net.psforever.services.local.{LocalAction, LocalServiceMessage}
|
||||
import net.psforever.services.avatar.AvatarAction
|
||||
import net.psforever.services.local.LocalAction
|
||||
import net.psforever.objects.locker.LockerContainerControl
|
||||
import net.psforever.objects.serverobject.environment.interaction.RespondsToZoneEnvironment
|
||||
import net.psforever.objects.serverobject.repair.Repairable
|
||||
|
|
@ -36,6 +35,8 @@ import net.psforever.objects.vital.collision.CollisionReason
|
|||
import net.psforever.objects.vital.etc.{PainboxReason, SuicideReason}
|
||||
import net.psforever.objects.vital.interaction.{DamageInteraction, DamageResult}
|
||||
import net.psforever.packet.PlanetSideGamePacket
|
||||
import net.psforever.services.base.envelope.MessageEnvelope
|
||||
import net.psforever.services.base.message.{EventMessage, HintsAtAttacker, ObjectDelete, PlanetsideAttribute, SendResponse}
|
||||
import org.joda.time.{LocalDateTime, Seconds}
|
||||
|
||||
import scala.concurrent.duration._
|
||||
|
|
@ -125,7 +126,7 @@ class PlayerControl(player: Player, avatarActor: typed.ActorRef[AvatarActor.Comm
|
|||
val zoneId = zone.id
|
||||
sendResponse(zone, zoneId, PlanetsideAttributeMessage(revivalTargetGuid, attribute_type=0, health))
|
||||
sendResponse(zone, zoneId, AvatarDeadStateMessage(DeadState.Alive, timer_max=0, timer=0, player.Position, player.Faction, unk5=true))
|
||||
sendResponse(zone, zoneId, AvatarAction.PlanetsideAttributeToAll(revivalTargetGuid, attribute_type=0, health))
|
||||
sendResponse(zone, zoneId, PlanetsideAttributeMessage(revivalTargetGuid, attribute_type=0, health))
|
||||
avatarActor ! AvatarActor.InitializeImplants
|
||||
avatarActor ! AvatarActor.SuspendStaminaRegeneration(Duration(1, "second"))
|
||||
|
||||
|
|
@ -147,14 +148,11 @@ class PlayerControl(player: Player, avatarActor: typed.ActorRef[AvatarActor.Comm
|
|||
if (!(player.isMoving || user.isMoving)) { //only allow stationary heals
|
||||
val newHealth = player.Health = originalHealth + 10
|
||||
val magazine = item.Discharge()
|
||||
events ! AvatarServiceMessage(
|
||||
events ! MessageEnvelope(
|
||||
uname,
|
||||
AvatarAction.SendResponse(
|
||||
Service.defaultPlayerGUID,
|
||||
InventoryStateMessage(item.AmmoSlot.Box.GUID, item.GUID, magazine.toLong)
|
||||
)
|
||||
SendResponse(InventoryStateMessage(item.AmmoSlot.Box.GUID, item.GUID, magazine.toLong))
|
||||
)
|
||||
events ! AvatarServiceMessage(zone.id, AvatarAction.PlanetsideAttributeToAll(guid, 0, newHealth))
|
||||
events ! MessageEnvelope(zone.id, PlanetsideAttribute(guid, 0, newHealth))
|
||||
player.LogActivity(
|
||||
HealFromEquipment(
|
||||
PlayerSource(user),
|
||||
|
|
@ -174,14 +172,11 @@ class PlayerControl(player: Player, avatarActor: typed.ActorRef[AvatarActor.Comm
|
|||
}
|
||||
if (player != user) {
|
||||
//"Someone is trying to heal you"
|
||||
events ! AvatarServiceMessage(player.Name, AvatarAction.PlanetsideAttributeToAll(guid, 55, 1))
|
||||
events ! MessageEnvelope(player.Name, PlanetsideAttribute(guid, 55, 1))
|
||||
//progress bar remains visible for all heal attempts
|
||||
events ! AvatarServiceMessage(
|
||||
events ! MessageEnvelope(
|
||||
uname,
|
||||
AvatarAction.SendResponse(
|
||||
Service.defaultPlayerGUID,
|
||||
RepairMessage(guid, player.Health * 100 / definition.MaxHealth)
|
||||
)
|
||||
SendResponse(RepairMessage(guid, player.Health * 100 / definition.MaxHealth))
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -219,14 +214,11 @@ class PlayerControl(player: Player, avatarActor: typed.ActorRef[AvatarActor.Comm
|
|||
val newArmor = player.Armor =
|
||||
originalArmor + Repairable.applyLevelModifier(user, item, RepairToolValue(item)).toInt + definition.RepairMod
|
||||
val magazine = item.Discharge()
|
||||
events ! AvatarServiceMessage(
|
||||
events ! MessageEnvelope(
|
||||
uname,
|
||||
AvatarAction.SendResponse(
|
||||
Service.defaultPlayerGUID,
|
||||
InventoryStateMessage(item.AmmoSlot.Box.GUID, item.GUID, magazine.toLong)
|
||||
)
|
||||
SendResponse(InventoryStateMessage(item.AmmoSlot.Box.GUID, item.GUID, magazine.toLong))
|
||||
)
|
||||
events ! AvatarServiceMessage(zone.id, AvatarAction.PlanetsideAttributeToAll(guid, 4, player.Armor))
|
||||
events ! MessageEnvelope(zone.id, PlanetsideAttribute(guid, 4, player.Armor))
|
||||
player.LogActivity(
|
||||
RepairFromEquipment(
|
||||
PlayerSource(user),
|
||||
|
|
@ -247,16 +239,15 @@ class PlayerControl(player: Player, avatarActor: typed.ActorRef[AvatarActor.Comm
|
|||
if (player != user) {
|
||||
if (player.isAlive) {
|
||||
//"Someone is trying to repair you" gets strobed twice for visibility
|
||||
val msg = AvatarServiceMessage(player.Name, AvatarAction.PlanetsideAttributeToAll(guid, 56, 1))
|
||||
val msg = MessageEnvelope(player.Name, PlanetsideAttribute(guid, 56, 1))
|
||||
events ! msg
|
||||
import scala.concurrent.ExecutionContext.Implicits.global
|
||||
context.system.scheduler.scheduleOnce(250 milliseconds, events, msg)
|
||||
}
|
||||
//progress bar remains visible for all repair attempts
|
||||
events ! AvatarServiceMessage(
|
||||
events ! MessageEnvelope(
|
||||
uname,
|
||||
AvatarAction
|
||||
.SendResponse(Service.defaultPlayerGUID, RepairMessage(guid, player.Armor * 100 / player.MaxArmor))
|
||||
SendResponse(RepairMessage(guid, player.Armor * 100 / player.MaxArmor))
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -321,16 +312,16 @@ class PlayerControl(player: Player, avatarActor: typed.ActorRef[AvatarActor.Comm
|
|||
avatarActor ! AvatarActor.UpdateUseTime(kdef)
|
||||
player.Slot(slot).Equipment = None //remove from slot immediately; must exist on client for now
|
||||
TaskWorkflow.execute(GUIDTask.unregisterEquipment(zone.GUID, kit))
|
||||
zone.AvatarEvents ! AvatarServiceMessage(
|
||||
zone.AvatarEvents ! MessageEnvelope(
|
||||
zone.id,
|
||||
AvatarAction.PlanetsideAttributeToAll(player.GUID, attribute, value)
|
||||
PlanetsideAttribute(player.GUID, attribute, value)
|
||||
)
|
||||
zone.AvatarEvents ! AvatarServiceMessage(
|
||||
zone.AvatarEvents ! MessageEnvelope(
|
||||
player.Name,
|
||||
AvatarAction.UseKit(kguid, kdef.ObjectId)
|
||||
)
|
||||
case _ =>
|
||||
player.Zone.AvatarEvents ! AvatarServiceMessage(
|
||||
player.Zone.AvatarEvents ! MessageEnvelope(
|
||||
player.Name,
|
||||
AvatarAction.KitNotUsed(kit.GUID, msg)
|
||||
)
|
||||
|
|
@ -344,15 +335,17 @@ class PlayerControl(player: Player, avatarActor: typed.ActorRef[AvatarActor.Comm
|
|||
val events = player.Zone.AvatarEvents
|
||||
val resistance = player.TestArmMotion(slot)
|
||||
if (resistance && !updateMyHolsterArm) {
|
||||
events ! AvatarServiceMessage(
|
||||
events ! MessageEnvelope(
|
||||
player.Name,
|
||||
AvatarAction.ObjectHeld(player.GUID, before, -1)
|
||||
player.GUID,
|
||||
AvatarAction.ObjectHeld(before, -1)
|
||||
)
|
||||
} else if ((!resistance && before != slot && (player.DrawnSlot = slot) != before) && ItemSwapSlot != before) {
|
||||
val mySlot = if (updateMyHolsterArm) slot else -1 //use as a short-circuit
|
||||
events ! AvatarServiceMessage(
|
||||
events ! MessageEnvelope(
|
||||
Players.ZoneChannelIfSpectating(player),
|
||||
AvatarAction.ObjectHeld(player.GUID, mySlot, player.LastDrawnSlot)
|
||||
player.GUID,
|
||||
AvatarAction.ObjectHeld(mySlot, player.LastDrawnSlot)
|
||||
)
|
||||
val isHolsters = player.VisibleSlots.contains(slot)
|
||||
val equipment = player.Slot(slot).Equipment.orElse { player.Slot(before).Equipment }
|
||||
|
|
@ -362,9 +355,10 @@ class PlayerControl(player: Player, avatarActor: typed.ActorRef[AvatarActor.Comm
|
|||
log.info(s"${player.Name} has drawn a ${unholsteredItem.Definition.Name} from its holster")
|
||||
if (unholsteredItem.Definition == GlobalDefinitions.remote_electronics_kit) {
|
||||
//rek beam/icon colour must match the player's correct hack level
|
||||
events ! AvatarServiceMessage(
|
||||
events ! MessageEnvelope(
|
||||
Players.ZoneChannelIfSpectating(player),
|
||||
AvatarAction.PlanetsideAttribute(unholsteredItem.GUID, 116, player.avatar.hackingSkillLevel())
|
||||
unholsteredItem.GUID,
|
||||
PlanetsideAttribute(unholsteredItem.GUID, 116, player.avatar.hackingSkillLevel())
|
||||
)
|
||||
}
|
||||
case None => ()
|
||||
|
|
@ -376,7 +370,11 @@ class PlayerControl(player: Player, avatarActor: typed.ActorRef[AvatarActor.Comm
|
|||
//make sure the player didn't just initialte an orbital strike. If not (the if below is true), make sure waypoint is removed
|
||||
if (holsteredEquipment.Definition == GlobalDefinitions.command_detonater && player.avatar.cr.value > 3 &&
|
||||
!player.avatar.cooldowns.purchase.exists(os => os._1 == "orbital_strike" && Seconds.secondsBetween(os._2, LocalDateTime.now()).getSeconds < 12)) {
|
||||
player.Zone.LocalEvents ! LocalServiceMessage(s"${player.Faction}", LocalAction.SendPacket(OrbitalStrikeWaypointMessage(player.GUID, None)))
|
||||
player.Zone.LocalEvents ! MessageEnvelope(
|
||||
s"${player.Faction}",
|
||||
PlanetSideGUID(-1),
|
||||
SendResponse(OrbitalStrikeWaypointMessage(player.GUID, None))
|
||||
)
|
||||
}
|
||||
case None =>
|
||||
log.info(s"${player.Name} lowers ${player.Sex.possessive} hand")
|
||||
|
|
@ -400,7 +398,7 @@ class PlayerControl(player: Player, avatarActor: typed.ActorRef[AvatarActor.Comm
|
|||
if (exosuit == ExoSuitType.MAX) {
|
||||
player.ResistArmMotion(PlayerControl.maxRestriction)
|
||||
}
|
||||
player.Zone.AvatarEvents ! AvatarServiceMessage(
|
||||
player.Zone.AvatarEvents ! MessageEnvelope(
|
||||
player.Name,
|
||||
AvatarAction.TerminalOrderResult(msg.terminal_guid, msg.transaction_type, result)
|
||||
)
|
||||
|
|
@ -532,7 +530,7 @@ class PlayerControl(player: Player, avatarActor: typed.ActorRef[AvatarActor.Comm
|
|||
Deployables.initializeConstructionItem(player.avatar.certifications, citem)
|
||||
}
|
||||
val zone = player.Zone
|
||||
zone.AvatarEvents ! AvatarServiceMessage(
|
||||
zone.AvatarEvents ! MessageEnvelope(
|
||||
Players.ZoneChannelIfSpectating(player),
|
||||
AvatarAction.ChangeLoadout(
|
||||
player.GUID,
|
||||
|
|
@ -548,7 +546,7 @@ class PlayerControl(player: Player, avatarActor: typed.ActorRef[AvatarActor.Comm
|
|||
itemsToDrop
|
||||
)
|
||||
)
|
||||
zone.AvatarEvents ! AvatarServiceMessage(
|
||||
zone.AvatarEvents ! MessageEnvelope(
|
||||
player.Name,
|
||||
AvatarAction.TerminalOrderResult(msg.terminal_guid, msg.transaction_type, result=true)
|
||||
)
|
||||
|
|
@ -577,9 +575,9 @@ class PlayerControl(player: Player, avatarActor: typed.ActorRef[AvatarActor.Comm
|
|||
case Zone.Ground.CanNotPickupItem(_, item_guid, reason) =>
|
||||
log.warn(s"${player.Name} failed to pick up an item ($item_guid) from the ground because $reason")
|
||||
if (reason.startsWith("@")) {
|
||||
player.Zone.AvatarEvents ! AvatarServiceMessage(
|
||||
player.Zone.AvatarEvents ! MessageEnvelope(
|
||||
player.Name,
|
||||
AvatarAction.SendResponse(Service.defaultPlayerGUID, ChatMsg(ChatMessageType.UNK_227, reason))
|
||||
SendResponse(ChatMsg(ChatMessageType.UNK_227, reason))
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -597,7 +595,7 @@ class PlayerControl(player: Player, avatarActor: typed.ActorRef[AvatarActor.Comm
|
|||
val trigger = new BoomerTrigger
|
||||
trigger.Companion = obj.GUID
|
||||
obj.Trigger = trigger
|
||||
zone.AvatarEvents ! AvatarServiceMessage(zone.id, AvatarAction.ObjectDelete(Service.defaultPlayerGUID, tool.GUID))
|
||||
zone.AvatarEvents ! MessageEnvelope(zone.id, ObjectDelete(tool.GUID))
|
||||
TaskWorkflow.execute(GUIDTask.unregisterEquipment(zone.GUID, tool))
|
||||
player.Find(tool) match {
|
||||
case Some(index) if player.VisibleSlots.contains(index) =>
|
||||
|
|
@ -649,7 +647,7 @@ class PlayerControl(player: Player, avatarActor: typed.ActorRef[AvatarActor.Comm
|
|||
|
||||
case Player.LoseDeployable(obj) =>
|
||||
if (player.avatar.deployables.Remove(obj)) {
|
||||
player.Zone.LocalEvents ! LocalServiceMessage(player.Name, LocalAction.DeployableUIFor(obj.Definition.Item))
|
||||
player.Zone.LocalEvents ! MessageEnvelope(player.Name, LocalAction.DeployableUIFor(obj.Definition.Item))
|
||||
}
|
||||
|
||||
case _ => ;
|
||||
|
|
@ -722,7 +720,7 @@ class PlayerControl(player: Player, avatarActor: typed.ActorRef[AvatarActor.Comm
|
|||
//insert
|
||||
afterHolsters.foreach(elem => player.Slot(elem.start).Equipment = elem.obj)
|
||||
afterInventory.foreach(elem => player.Inventory.InsertQuickly(elem.start, elem.obj))
|
||||
player.Zone.AvatarEvents ! AvatarServiceMessage(
|
||||
player.Zone.AvatarEvents ! MessageEnvelope(
|
||||
Players.ZoneChannelIfSpectating(player),
|
||||
AvatarAction.ChangeExosuit(
|
||||
player.GUID,
|
||||
|
|
@ -748,7 +746,7 @@ class PlayerControl(player: Player, avatarActor: typed.ActorRef[AvatarActor.Comm
|
|||
def loseDeployableOwnership(obj: Deployable): Boolean = {
|
||||
if (player.avatar.deployables.Remove(obj)) {
|
||||
obj.Actor ! Deployable.Ownership(None)
|
||||
player.Zone.LocalEvents ! LocalServiceMessage(player.Name, LocalAction.DeployableUIFor(obj.Definition.Item))
|
||||
player.Zone.LocalEvents ! MessageEnvelope(player.Name, LocalAction.DeployableUIFor(obj.Definition.Item))
|
||||
true
|
||||
}
|
||||
else {
|
||||
|
|
@ -769,18 +767,15 @@ class PlayerControl(player: Player, avatarActor: typed.ActorRef[AvatarActor.Comm
|
|||
case GlobalDefinitions.router_telepad => () /* no special animation */
|
||||
case GlobalDefinitions.ace
|
||||
if obj.Definition.deployAnimation == DeployAnimation.Standard =>
|
||||
zone.LocalEvents ! LocalServiceMessage(
|
||||
val ownerGuid = obj.OwnerGuid.getOrElse(Default.GUID0)
|
||||
zone.LocalEvents ! MessageEnvelope(
|
||||
zone.id,
|
||||
LocalAction.TriggerEffectLocation(
|
||||
obj.OwnerGuid.getOrElse(Service.defaultPlayerGUID),
|
||||
"spawn_object_effect",
|
||||
obj.Position,
|
||||
obj.Orientation
|
||||
)
|
||||
ownerGuid,
|
||||
LocalAction.TriggerEffectLocation("spawn_object_effect", obj.Position, obj.Orientation)
|
||||
)
|
||||
case GlobalDefinitions.advanced_ace
|
||||
if obj.Definition.deployAnimation == DeployAnimation.Fdu =>
|
||||
zone.AvatarEvents ! AvatarServiceMessage(zone.id, AvatarAction.PutDownFDU(player.GUID))
|
||||
zone.AvatarEvents ! MessageEnvelope(zone.id, AvatarAction.PutDownFDU(player.GUID))
|
||||
case _ =>
|
||||
org.log4s
|
||||
.getLogger(name = "Deployables")
|
||||
|
|
@ -883,9 +878,9 @@ class PlayerControl(player: Player, avatarActor: typed.ActorRef[AvatarActor.Comm
|
|||
//always do armor update
|
||||
if (damageToArmor > 0) {
|
||||
val zone = target.Zone
|
||||
zone.AvatarEvents ! AvatarServiceMessage(
|
||||
zone.AvatarEvents ! MessageEnvelope(
|
||||
zone.id,
|
||||
AvatarAction.PlanetsideAttributeToAll(target.GUID, 4, target.Armor)
|
||||
PlanetsideAttribute(target.GUID, 4, target.Armor)
|
||||
)
|
||||
}
|
||||
//choose
|
||||
|
|
@ -941,10 +936,7 @@ class PlayerControl(player: Player, avatarActor: typed.ActorRef[AvatarActor.Comm
|
|||
target.LogActivity(cause)
|
||||
//stat changes
|
||||
if (damageToCapacitor > 0) {
|
||||
events ! AvatarServiceMessage(
|
||||
target.Name,
|
||||
AvatarAction.PlanetsideAttributeSelf(targetGUID, 7, target.Capacitor.toLong)
|
||||
)
|
||||
events ! MessageEnvelope(target.Name, PlanetsideAttribute(targetGUID, 7, target.Capacitor.toLong))
|
||||
announceConfrontation = true //TODO should we?
|
||||
}
|
||||
if (damageToStamina > 0) {
|
||||
|
|
@ -952,15 +944,15 @@ class PlayerControl(player: Player, avatarActor: typed.ActorRef[AvatarActor.Comm
|
|||
announceConfrontation = true //TODO should we?
|
||||
}
|
||||
if (damageToHealth > 0) {
|
||||
events ! AvatarServiceMessage(zoneId, AvatarAction.PlanetsideAttributeToAll(targetGUID, 0, health))
|
||||
events ! MessageEnvelope(zoneId, PlanetsideAttribute(targetGUID, 0, health))
|
||||
announceConfrontation = true
|
||||
}
|
||||
val countableDamage = damageToHealth + damageToArmor
|
||||
if(announceConfrontation) {
|
||||
if (aggravated) {
|
||||
events ! AvatarServiceMessage(
|
||||
events ! MessageEnvelope(
|
||||
zoneId,
|
||||
AvatarAction.SendResponse(Service.defaultPlayerGUID, AggravatedDamageMessage(targetGUID, countableDamage))
|
||||
SendResponse(AggravatedDamageMessage(targetGUID, countableDamage))
|
||||
)
|
||||
} else {
|
||||
//activity on map
|
||||
|
|
@ -973,42 +965,37 @@ class PlayerControl(player: Player, avatarActor: typed.ActorRef[AvatarActor.Comm
|
|||
val name = pSource.Name
|
||||
zone.LivePlayers.find(_.Name == name).orElse(zone.Corpses.find(_.Name == name)) match {
|
||||
case Some(tplayer) =>
|
||||
zone.AvatarEvents ! AvatarServiceMessage(
|
||||
zone.AvatarEvents ! MessageEnvelope(
|
||||
target.Name,
|
||||
AvatarAction.HitHint(tplayer.GUID, target.GUID)
|
||||
target.GUID,
|
||||
HintsAtAttacker(tplayer.GUID)
|
||||
)
|
||||
case None =>
|
||||
zone.AvatarEvents ! AvatarServiceMessage(
|
||||
zone.AvatarEvents ! MessageEnvelope(
|
||||
target.Name,
|
||||
AvatarAction.SendResponse(
|
||||
Service.defaultPlayerGUID,
|
||||
DamageWithPositionMessage(countableDamage, pSource.Position)
|
||||
)
|
||||
SendResponse(DamageWithPositionMessage(countableDamage, pSource.Position))
|
||||
)
|
||||
}
|
||||
case source =>
|
||||
zone.AvatarEvents ! AvatarServiceMessage(
|
||||
zone.AvatarEvents ! MessageEnvelope(
|
||||
target.Name,
|
||||
AvatarAction.SendResponse(
|
||||
Service.defaultPlayerGUID,
|
||||
DamageWithPositionMessage(countableDamage, source.Position)
|
||||
)
|
||||
SendResponse(DamageWithPositionMessage(countableDamage, source.Position))
|
||||
)
|
||||
}
|
||||
case None =>
|
||||
cause.interaction.cause match {
|
||||
case o: PainboxReason =>
|
||||
zone.AvatarEvents ! AvatarServiceMessage(
|
||||
zone.AvatarEvents ! MessageEnvelope(
|
||||
target.Name,
|
||||
AvatarAction.EnvironmentalDamage(target.GUID, o.entity.GUID, countableDamage)
|
||||
)
|
||||
case _: CollisionReason =>
|
||||
events ! AvatarServiceMessage(
|
||||
events ! MessageEnvelope(
|
||||
zoneId,
|
||||
AvatarAction.SendResponse(Service.defaultPlayerGUID, AggravatedDamageMessage(targetGUID, countableDamage))
|
||||
SendResponse(AggravatedDamageMessage(targetGUID, countableDamage))
|
||||
)
|
||||
case _ =>
|
||||
zone.AvatarEvents ! AvatarServiceMessage(
|
||||
zone.AvatarEvents ! MessageEnvelope(
|
||||
target.Name,
|
||||
AvatarAction.EnvironmentalDamage(target.GUID, ValidPlanetSideGUID(0), countableDamage)
|
||||
)
|
||||
|
|
@ -1064,19 +1051,16 @@ class PlayerControl(player: Player, avatarActor: typed.ActorRef[AvatarActor.Comm
|
|||
damageLog.info(s"${player.Name} killed ${player.Sex.pronounObject}self")
|
||||
}
|
||||
|
||||
events ! AvatarServiceMessage(nameChannel, AvatarAction.Killed(player_guid, cause, target.VehicleSeated)) //align client interface fields with state
|
||||
events ! AvatarServiceMessage(zoneChannel, AvatarAction.PlanetsideAttributeToAll(player_guid, 0, 0)) //health
|
||||
events ! MessageEnvelope(nameChannel, player_guid, AvatarAction.Killed(cause, target.VehicleSeated)) //align client interface fields with state
|
||||
events ! MessageEnvelope(zoneChannel, PlanetsideAttribute(player_guid, 0, 0)) //health
|
||||
if (target.Capacitor > 0) {
|
||||
target.Capacitor = 0
|
||||
events ! AvatarServiceMessage(nameChannel, AvatarAction.PlanetsideAttributeToAll(player_guid, 7, 0)) // capacitor
|
||||
events ! MessageEnvelope(nameChannel, PlanetsideAttribute(player_guid, 7, 0)) // capacitor
|
||||
}
|
||||
val attribute = DamageableEntity.attributionTo(cause, target.Zone, player_guid)
|
||||
events ! AvatarServiceMessage(
|
||||
events ! MessageEnvelope(
|
||||
nameChannel,
|
||||
AvatarAction.SendResponse(
|
||||
Service.defaultPlayerGUID,
|
||||
DestroyMessage(player_guid, attribute, Service.defaultPlayerGUID, pos)
|
||||
) //how many players get this message?
|
||||
SendResponse(DestroyMessage(player_guid, attribute, Default.GUID0, pos)) //how many players get this message?
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -1105,12 +1089,12 @@ class PlayerControl(player: Player, avatarActor: typed.ActorRef[AvatarActor.Comm
|
|||
override def StartJammeredSound(target: Any, dur: Int): Unit =
|
||||
target match {
|
||||
case obj: Player if !jammedSound =>
|
||||
obj.Zone.AvatarEvents ! AvatarServiceMessage(
|
||||
obj.Zone.AvatarEvents ! MessageEnvelope(
|
||||
obj.Zone.id,
|
||||
AvatarAction.PlanetsideAttributeToAll(obj.GUID, 27, 1)
|
||||
PlanetsideAttribute(obj.GUID, 27, 1)
|
||||
)
|
||||
super.StartJammeredSound(obj, 3000)
|
||||
case _ => ;
|
||||
case _ => ()
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1141,12 +1125,12 @@ class PlayerControl(player: Player, avatarActor: typed.ActorRef[AvatarActor.Comm
|
|||
override def CancelJammeredSound(target: Any): Unit =
|
||||
target match {
|
||||
case obj: Player if jammedSound =>
|
||||
obj.Zone.AvatarEvents ! AvatarServiceMessage(
|
||||
obj.Zone.AvatarEvents ! MessageEnvelope(
|
||||
obj.Zone.id,
|
||||
AvatarAction.PlanetsideAttributeToAll(obj.GUID, 27, 0)
|
||||
PlanetsideAttribute(obj.GUID, 27, 0)
|
||||
)
|
||||
super.CancelJammeredSound(obj)
|
||||
case _ => ;
|
||||
case _ => ()
|
||||
}
|
||||
|
||||
def RepairToolValue(item: Tool): Float = {
|
||||
|
|
@ -1167,9 +1151,9 @@ class PlayerControl(player: Player, avatarActor: typed.ActorRef[AvatarActor.Comm
|
|||
obj.Find(item) match {
|
||||
case Some(slot) =>
|
||||
PutItemInSlotCallback(item, slot)
|
||||
case None => ;
|
||||
case None => ()
|
||||
}
|
||||
case _ => ;
|
||||
case _ => ()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1188,7 +1172,7 @@ class PlayerControl(player: Player, avatarActor: typed.ActorRef[AvatarActor.Comm
|
|||
if (slot == obj.DrawnSlot) {
|
||||
obj.DrawnSlot = Player.HandsDownSlot
|
||||
}
|
||||
events ! AvatarServiceMessage(toChannel, AvatarAction.ObjectDelete(Service.defaultPlayerGUID, item.GUID))
|
||||
events ! MessageEnvelope(toChannel, ObjectDelete(item.GUID))
|
||||
}
|
||||
|
||||
def PutItemInSlotCallback(item: Equipment, slot: Int): Unit = {
|
||||
|
|
@ -1209,10 +1193,10 @@ class PlayerControl(player: Player, avatarActor: typed.ActorRef[AvatarActor.Comm
|
|||
case Some(obj: BoomerDeployable) =>
|
||||
val deployables = player.avatar.deployables
|
||||
if (!deployables.Contains(obj) && deployables.Valid(obj)) {
|
||||
events ! AvatarServiceMessage(toChannel, AvatarAction.SendResponse(
|
||||
Service.defaultPlayerGUID,
|
||||
GenericObjectAction2Message(1, player.GUID, trigger.GUID)
|
||||
))
|
||||
events ! MessageEnvelope(
|
||||
toChannel,
|
||||
SendResponse(GenericObjectAction2Message(1, player.GUID, trigger.GUID))
|
||||
)
|
||||
Players.gainDeployableOwnership(player, obj, deployables.AddOverLimit)
|
||||
}
|
||||
case _ => ()
|
||||
|
|
@ -1228,15 +1212,12 @@ class PlayerControl(player: Player, avatarActor: typed.ActorRef[AvatarActor.Comm
|
|||
|
||||
case _ => ()
|
||||
}
|
||||
events ! AvatarServiceMessage(
|
||||
events ! MessageEnvelope(
|
||||
toChannel,
|
||||
AvatarAction.SendResponse(
|
||||
Service.defaultPlayerGUID,
|
||||
OCM.detailed(item, ObjectCreateMessageParent(guid, slot))
|
||||
)
|
||||
SendResponse(OCM.detailed(item, ObjectCreateMessageParent(guid, slot)))
|
||||
)
|
||||
if (!player.isBackpack && willBeVisible) {
|
||||
events ! AvatarServiceMessage(zone.id, AvatarAction.EquipmentInHand(guid, guid, slot, item))
|
||||
events ! MessageEnvelope(zone.id, guid, AvatarAction.EquipmentInHand(guid, slot, item))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1250,17 +1231,16 @@ class PlayerControl(player: Player, avatarActor: typed.ActorRef[AvatarActor.Comm
|
|||
} else {
|
||||
player.Name
|
||||
}
|
||||
zone.AvatarEvents ! AvatarServiceMessage(
|
||||
zone.AvatarEvents ! MessageEnvelope(
|
||||
toChannel,
|
||||
AvatarAction.ObjectDelete(Service.defaultPlayerGUID, item.GUID)
|
||||
ObjectDelete(item.GUID)
|
||||
)
|
||||
}
|
||||
|
||||
def UpdateAuraEffect(target: AuraEffectBehavior.Target) : Unit = {
|
||||
import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage}
|
||||
val zone = target.Zone
|
||||
val value = target.Aura.foldLeft(0)(_ + PlayerControl.auraEffectToAttributeValue(_))
|
||||
zone.AvatarEvents ! AvatarServiceMessage(zone.id, AvatarAction.PlanetsideAttributeToAll(target.GUID, 54, value))
|
||||
zone.AvatarEvents ! MessageEnvelope(zone.id, PlanetsideAttribute(target.GUID, 54, value))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1290,11 +1270,11 @@ object PlayerControl {
|
|||
}
|
||||
|
||||
def sendResponse(zone: Zone, channel: String, msg: PlanetSideGamePacket): Unit = {
|
||||
zone.AvatarEvents ! AvatarServiceMessage(channel, AvatarAction.SendResponse(Service.defaultPlayerGUID, msg))
|
||||
zone.AvatarEvents ! MessageEnvelope(channel, SendResponse(msg))
|
||||
}
|
||||
|
||||
def sendResponse(zone: Zone, channel: String, msg: AvatarAction.Action): Unit = {
|
||||
zone.AvatarEvents ! AvatarServiceMessage(channel, msg)
|
||||
def sendResponse(zone: Zone, channel: String, filter: PlanetSideGUID, msg: EventMessage): Unit = {
|
||||
zone.AvatarEvents ! MessageEnvelope(channel, filter, msg)
|
||||
}
|
||||
|
||||
def maxRestriction(player: Player, slot: Int): Boolean = {
|
||||
|
|
|
|||
|
|
@ -6,6 +6,8 @@ import net.psforever.objects.serverobject.environment.{EnvironmentAttribute, Env
|
|||
import net.psforever.objects.serverobject.environment.interaction.{InteractionWith, RespondsToZoneEnvironment}
|
||||
import net.psforever.objects.serverobject.interior.{Sidedness, TraditionalInteriorAware}
|
||||
import net.psforever.objects.zones.interaction.InteractsWithZone
|
||||
import net.psforever.services.base.envelope.MessageEnvelope
|
||||
import net.psforever.services.base.message.SendResponse
|
||||
import net.psforever.types.Vector3
|
||||
|
||||
import scala.annotation.unused
|
||||
|
|
@ -90,33 +92,32 @@ class WithEntrance()
|
|||
): Sidedness = {
|
||||
import net.psforever.objects.{Player, Vehicle}
|
||||
import net.psforever.packet.game.ChatMsg
|
||||
import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage}
|
||||
import net.psforever.types.{ChatMessageType, PlanetSideGUID}
|
||||
import net.psforever.types.ChatMessageType
|
||||
val channel = obj match {
|
||||
case p: Player => p.Name
|
||||
case v: Vehicle => v.Actor.toString()
|
||||
case _ => ""
|
||||
}
|
||||
if (door.Outwards == Vector3.Zero) {
|
||||
obj.Zone.AvatarEvents ! AvatarServiceMessage(
|
||||
obj.Zone.AvatarEvents ! MessageEnvelope(
|
||||
channel,
|
||||
AvatarAction.SendResponse(PlanetSideGUID(0), ChatMsg(ChatMessageType.UNK_229, "Door not configured."))
|
||||
SendResponse(ChatMsg(ChatMessageType.UNK_229, "Door not configured."))
|
||||
)
|
||||
WhichSide
|
||||
} else {
|
||||
val result = Vector3.DotProduct(Vector3.Unit(obj.Position - door.Position), door.Outwards) > 0f
|
||||
if (result && WhichSide != Sidedness.OutsideOf) {
|
||||
//outside
|
||||
obj.Zone.AvatarEvents ! AvatarServiceMessage(
|
||||
obj.Zone.AvatarEvents ! MessageEnvelope(
|
||||
channel,
|
||||
AvatarAction.SendResponse(PlanetSideGUID(0), ChatMsg(ChatMessageType.UNK_229, "You are now outside"))
|
||||
SendResponse(ChatMsg(ChatMessageType.UNK_229, "You are now outside"))
|
||||
)
|
||||
Sidedness.OutsideOf
|
||||
} else if (!result && WhichSide != Sidedness.InsideOf) {
|
||||
//inside
|
||||
obj.Zone.AvatarEvents ! AvatarServiceMessage(
|
||||
obj.Zone.AvatarEvents ! MessageEnvelope(
|
||||
channel,
|
||||
AvatarAction.SendResponse(PlanetSideGUID(0), ChatMsg(ChatMessageType.UNK_229, "You are now inside"))
|
||||
SendResponse(ChatMsg(ChatMessageType.UNK_229, "You are now inside"))
|
||||
)
|
||||
Sidedness.InsideOf
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -7,8 +7,8 @@ import net.psforever.objects.serverobject.environment.{EnvironmentAttribute, Env
|
|||
import net.psforever.objects.serverobject.shuttle.OrbitalShuttlePad
|
||||
import net.psforever.objects.zones.interaction.InteractsWithZone
|
||||
import net.psforever.packet.game.{ChatMsg, PlayerStateShiftMessage, ShiftState}
|
||||
import net.psforever.services.Service
|
||||
import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage}
|
||||
import net.psforever.services.base.envelope.MessageEnvelope
|
||||
import net.psforever.services.base.message.SendResponse
|
||||
import net.psforever.services.hart.ShuttleState
|
||||
import net.psforever.types.ChatMessageType
|
||||
|
||||
|
|
@ -35,18 +35,12 @@ class WithGantry(val channel: String)
|
|||
player.VehicleSeated.isEmpty =>
|
||||
val (pos, ang) = Vehicles.dismountShuttle(shuttle, field.mountPoint)
|
||||
val events = shuttle.Zone.AvatarEvents
|
||||
events ! AvatarServiceMessage(
|
||||
events ! MessageEnvelope(
|
||||
channel,
|
||||
AvatarAction.SendResponse(
|
||||
Service.defaultPlayerGUID,
|
||||
PlayerStateShiftMessage(ShiftState(0, pos, ang, None)))
|
||||
)
|
||||
events ! AvatarServiceMessage(
|
||||
SendResponse(PlayerStateShiftMessage(ShiftState(0, pos, ang, None))))
|
||||
events ! MessageEnvelope(
|
||||
channel,
|
||||
AvatarAction.SendResponse(
|
||||
Service.defaultPlayerGUID,
|
||||
ChatMsg(ChatMessageType.UNK_227, "@Vehicle_OS_PlacedOutsideHallway")
|
||||
)
|
||||
SendResponse(ChatMsg(ChatMessageType.UNK_227, "@Vehicle_OS_PlacedOutsideHallway"))
|
||||
)
|
||||
case (Some(_: Vehicle) , _)=>
|
||||
obj.Actor ! RespondsToZoneEnvironment.Timer(
|
||||
|
|
|
|||
|
|
@ -7,7 +7,8 @@ import net.psforever.objects.serverobject.environment.interaction.common.Watery
|
|||
import net.psforever.objects.serverobject.environment.interaction.common.Watery.OxygenStateTarget
|
||||
import net.psforever.objects.serverobject.environment.{EnvironmentTrait, PieceOfEnvironment, interaction}
|
||||
import net.psforever.objects.zones.interaction.InteractsWithZone
|
||||
import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage}
|
||||
import net.psforever.services.avatar.AvatarAction
|
||||
import net.psforever.services.base.envelope.MessageEnvelope
|
||||
import net.psforever.types.OxygenState
|
||||
|
||||
import scala.concurrent.duration._
|
||||
|
|
@ -299,7 +300,7 @@ class WithWater(val channel: String)
|
|||
cond: OxygenStateTarget,
|
||||
data: Option[OxygenStateTarget]
|
||||
): Unit = {
|
||||
obj.Zone.AvatarEvents ! AvatarServiceMessage(channel, AvatarAction.OxygenState(cond, data))
|
||||
obj.Zone.AvatarEvents ! MessageEnvelope(channel, AvatarAction.OxygenState(cond, data))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
package net.psforever.objects.avatar.scoring
|
||||
|
||||
/**
|
||||
* Organizes the eight fields one would find in an `AvatarServiceMessage` statistic field.
|
||||
* Organizes the eight fields one would find in an statistic field.
|
||||
* The `_c` fields and the `_s` fields are paired when the values populate the packet
|
||||
* where `c` stands for "campaign" and `s` stands for "session".
|
||||
* "Session" values reflect on the UI as the K in K/D
|
||||
|
|
|
|||
|
|
@ -6,9 +6,9 @@ import net.psforever.objects.guid.{GUIDTask, TaskWorkflow}
|
|||
import net.psforever.objects._
|
||||
import net.psforever.objects.zones.Zone
|
||||
import net.psforever.packet.game._
|
||||
import net.psforever.services.Service
|
||||
import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage}
|
||||
import net.psforever.services.local.{LocalAction, LocalServiceMessage}
|
||||
import net.psforever.services.base.envelope.{BundledEnvelope, MessageEnvelope}
|
||||
import net.psforever.services.base.message.SetEmpire
|
||||
import net.psforever.services.local.LocalAction
|
||||
import net.psforever.types.PlanetSideEmpire
|
||||
|
||||
import scala.concurrent.duration._
|
||||
|
|
@ -111,7 +111,7 @@ trait DeployableBehavior {
|
|||
obj,
|
||||
toOwner = "",
|
||||
toFaction,
|
||||
DeployableInfo(obj.GUID, Deployable.Icon.apply(obj.Definition.Item), obj.Position, Service.defaultPlayerGUID)
|
||||
DeployableInfo(obj.GUID, Deployable.Icon.apply(obj.Definition.Item), obj.Position, Default.GUID0)
|
||||
)
|
||||
startOwnerlessDecay()
|
||||
}
|
||||
|
|
@ -198,14 +198,13 @@ trait DeployableBehavior {
|
|||
None
|
||||
}
|
||||
//zone build
|
||||
localEvents ! LocalServiceMessage(zone.id, LocalAction.DeployItem(obj))
|
||||
//zone map icon
|
||||
localEvents ! LocalServiceMessage(
|
||||
obj.Faction.toString,
|
||||
LocalAction.DeployableMapIcon(
|
||||
Service.defaultPlayerGUID,
|
||||
DeploymentAction.Build,
|
||||
DeployableInfo(obj.GUID, Deployable.Icon(obj.Definition.Item), obj.Position, obj.OwnerGuid.getOrElse(Service.defaultPlayerGUID))
|
||||
localEvents ! BundledEnvelope(
|
||||
/* zone build */
|
||||
MessageEnvelope(zone.id, LocalAction.DeployItem(obj)),
|
||||
/* zone map icon */
|
||||
MessageEnvelope(
|
||||
obj.Faction.toString,
|
||||
LocalAction.DeployableMapIcon(DeploymentAction.Build, DeployableInfo(obj.GUID, Deployable.Icon(obj.Definition.Item), obj.Position, obj.OwnerGuid.getOrElse(Default.GUID0)))
|
||||
)
|
||||
)
|
||||
//local build management
|
||||
|
|
@ -250,7 +249,7 @@ trait DeployableBehavior {
|
|||
//there's no special meaning behind directing any replies from from zone governance straight back to zone governance
|
||||
//this deployable control agency, however, will be expiring and can not be a recipient
|
||||
zone.Deployables ! Zone.Deployable.Dismiss(obj)
|
||||
zone.LocalEvents ! LocalServiceMessage(
|
||||
zone.LocalEvents ! MessageEnvelope(
|
||||
zone.id,
|
||||
LocalAction.EliminateDeployable(obj, obj.GUID, obj.Position, deletionType)
|
||||
)
|
||||
|
|
@ -285,27 +284,21 @@ object DeployableBehavior {
|
|||
val localEvents = zone.LocalEvents
|
||||
if (originalFaction != toFaction) {
|
||||
obj.Faction = toFaction
|
||||
//visual tells in regards to ownership by faction
|
||||
zone.AvatarEvents ! AvatarServiceMessage(
|
||||
zone.id,
|
||||
AvatarAction.SetEmpire(Service.defaultPlayerGUID, dGuid, toFaction)
|
||||
)
|
||||
//remove knowledge by the previous owner's faction
|
||||
localEvents ! LocalServiceMessage(
|
||||
originalFaction.toString,
|
||||
LocalAction.DeployableMapIcon(Service.defaultPlayerGUID, DeploymentAction.Dismiss, info)
|
||||
localEvents ! BundledEnvelope(
|
||||
/* visual tells in regards to ownership by faction */
|
||||
MessageEnvelope(zone.id, SetEmpire(dGuid, toFaction)),
|
||||
/* remove knowledge by the previous owner's faction */
|
||||
MessageEnvelope(originalFaction.toString, LocalAction.DeployableMapIcon(DeploymentAction.Dismiss, info)),
|
||||
/* display to the given faction */
|
||||
MessageEnvelope(toFaction.toString, LocalAction.DeployableMapIcon(DeploymentAction.Build, info))
|
||||
)
|
||||
//remove deployable from original owner's toolbox and UI counter
|
||||
zone.AllPlayers.filter(p => obj.OriginalOwnerName.contains(p.Name))
|
||||
.foreach { originalOwner =>
|
||||
localEvents ! BundledEnvelope(zone.AllPlayers
|
||||
.filter(p => obj.OriginalOwnerName.contains(p.Name))
|
||||
.map { originalOwner =>
|
||||
originalOwner.avatar.deployables.Remove(obj)
|
||||
originalOwner.Zone.LocalEvents ! LocalServiceMessage(originalOwner.Name, LocalAction.DeployableUIFor(obj.Definition.Item))
|
||||
}
|
||||
//display to the given faction
|
||||
localEvents ! LocalServiceMessage(
|
||||
toFaction.toString,
|
||||
LocalAction.DeployableMapIcon(Service.defaultPlayerGUID, DeploymentAction.Build, info)
|
||||
)
|
||||
MessageEnvelope(originalOwner.Name, LocalAction.DeployableUIFor(obj.Definition.Item))
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,7 +9,9 @@ import net.psforever.objects.vehicles.Utility.InternalTelepad
|
|||
import net.psforever.objects.zones.Zone
|
||||
import net.psforever.packet.game.{GenericObjectActionMessage, ObjectCreateMessage, ObjectDeleteMessage}
|
||||
import net.psforever.packet.game.objectcreate.ObjectCreateMessageParent
|
||||
import net.psforever.services.local.{LocalAction, LocalServiceMessage}
|
||||
import net.psforever.services.base.envelope.{BundledEnvelope, MessageEnvelope}
|
||||
import net.psforever.services.base.message.SendResponse
|
||||
import net.psforever.services.local.LocalAction
|
||||
import net.psforever.types.PlanetSideGUID
|
||||
|
||||
trait TelepadLike {
|
||||
|
|
@ -113,24 +115,22 @@ object TelepadLike {
|
|||
normally dispatched while the Router is transitioned into its Deploying state
|
||||
it is safe, however, to perform these actions at any time during and after the Deploying state
|
||||
*/
|
||||
events ! LocalServiceMessage(
|
||||
zoneId,
|
||||
LocalAction.SendResponse(
|
||||
ObjectCreateMessage(
|
||||
udef.ObjectId,
|
||||
utilityGUID,
|
||||
ObjectCreateMessageParent(routerGUID, 2), //TODO stop assuming slot number
|
||||
udef.Packet.ConstructorData(obj).get
|
||||
events ! BundledEnvelope(
|
||||
MessageEnvelope(
|
||||
zoneId,
|
||||
SendResponse(
|
||||
ObjectCreateMessage(
|
||||
udef.ObjectId,
|
||||
utilityGUID,
|
||||
ObjectCreateMessageParent(routerGUID, 2), //TODO stop assuming slot number
|
||||
udef.Packet.ConstructorData(obj).get
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
events ! LocalServiceMessage(
|
||||
zoneId,
|
||||
LocalAction.SendResponse(GenericObjectActionMessage(utilityGUID, 27))
|
||||
)
|
||||
events ! LocalServiceMessage(
|
||||
zoneId,
|
||||
LocalAction.SendResponse(GenericObjectActionMessage(utilityGUID, 30))
|
||||
),
|
||||
MessageEnvelope(zoneId, SendResponse(Seq(
|
||||
GenericObjectActionMessage(utilityGUID, 27),
|
||||
GenericObjectActionMessage(utilityGUID, 30)
|
||||
)))
|
||||
)
|
||||
LinkTelepad(zone, utilityGUID)
|
||||
}
|
||||
|
|
@ -138,14 +138,10 @@ object TelepadLike {
|
|||
def LinkTelepad(zone: Zone, telepadGUID: PlanetSideGUID): Unit = {
|
||||
val events = zone.LocalEvents
|
||||
val zoneId = zone.id
|
||||
events ! LocalServiceMessage(
|
||||
zoneId,
|
||||
LocalAction.SendResponse(GenericObjectActionMessage(telepadGUID, 27))
|
||||
)
|
||||
events ! LocalServiceMessage(
|
||||
zoneId,
|
||||
LocalAction.SendResponse(GenericObjectActionMessage(telepadGUID, 28))
|
||||
)
|
||||
events ! MessageEnvelope(zoneId, SendResponse(Seq(
|
||||
GenericObjectActionMessage(telepadGUID, 27),
|
||||
GenericObjectActionMessage(telepadGUID, 28)
|
||||
)))
|
||||
}
|
||||
|
||||
def InitializeTelepadDeployable(zone: Zone, internal: InternalTelepad, pad: TelepadDeployable): Unit = {
|
||||
|
|
@ -175,7 +171,7 @@ class TelepadControl(obj: InternalTelepad) extends akka.actor.Actor {
|
|||
oldTpad.Actor ! TelepadLike.SeverLink(obj)
|
||||
}
|
||||
obj.Telepad = None
|
||||
zone.LocalEvents ! LocalServiceMessage(zone.id, LocalAction.SendResponse(ObjectDeleteMessage(obj.GUID, 0)))
|
||||
zone.LocalEvents ! MessageEnvelope(zone.id, SendResponse(ObjectDeleteMessage(obj.GUID, 0)))
|
||||
|
||||
case TelepadLike.RequestLink(tpad: TelepadDeployable) =>
|
||||
val zone = obj.Zone
|
||||
|
|
@ -196,7 +192,7 @@ class TelepadControl(obj: InternalTelepad) extends akka.actor.Actor {
|
|||
}
|
||||
} else {
|
||||
val channel = obj.Owner.asInstanceOf[Vehicle].OwnerName.getOrElse("")
|
||||
zone.LocalEvents ! LocalServiceMessage(channel, LocalAction.RouterTelepadMessage("@Teleport_NotDeployed"))
|
||||
zone.LocalEvents ! MessageEnvelope(channel, LocalAction.RouterTelepadMessage("@Teleport_NotDeployed"))
|
||||
tpad.Actor ! TelepadLike.SeverLink(obj)
|
||||
}
|
||||
|
||||
|
|
@ -204,7 +200,7 @@ class TelepadControl(obj: InternalTelepad) extends akka.actor.Actor {
|
|||
if (obj.Telepad.contains(tpad.GUID)) {
|
||||
obj.Telepad = None
|
||||
val zone = obj.Zone
|
||||
zone.LocalEvents ! LocalServiceMessage(zone.id, LocalAction.SendResponse(ObjectDeleteMessage(obj.GUID, 0)))
|
||||
zone.LocalEvents ! MessageEnvelope(zone.id, SendResponse(ObjectDeleteMessage(obj.GUID, 0)))
|
||||
}
|
||||
|
||||
case _ => ()
|
||||
|
|
|
|||
|
|
@ -10,8 +10,8 @@ import net.psforever.objects.vital.RepairFromArmorSiphon
|
|||
import net.psforever.objects.vital.etc.{ArmorSiphonModifiers, ArmorSiphonReason}
|
||||
import net.psforever.objects.vital.interaction.DamageInteraction
|
||||
import net.psforever.packet.game.QuantityUpdateMessage
|
||||
import net.psforever.services.Service
|
||||
import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage}
|
||||
import net.psforever.services.base.envelope.MessageEnvelope
|
||||
import net.psforever.services.base.message.{PlanetsideAttribute, SendResponse}
|
||||
import net.psforever.types.PlanetSideGUID
|
||||
|
||||
import scala.collection.mutable
|
||||
|
|
@ -78,9 +78,9 @@ object ArmorSiphonBehavior {
|
|||
if(before < after) {
|
||||
obj.LogActivity(RepairFromArmorSiphon(asr.siphon.Definition, VehicleSource(obj), before - after))
|
||||
val zone = obj.Zone
|
||||
zone.VehicleEvents ! VehicleServiceMessage(
|
||||
zone.VehicleEvents ! MessageEnvelope(
|
||||
zone.id,
|
||||
VehicleAction.PlanetsideAttribute(Service.defaultPlayerGUID, obj.GUID, 0, after)
|
||||
PlanetsideAttribute(obj.GUID, 0, after)
|
||||
)
|
||||
}
|
||||
case _ => ;
|
||||
|
|
@ -97,9 +97,9 @@ object ArmorSiphonBehavior {
|
|||
val siphon = siphonSlot.Equipment.get.asInstanceOf[Tool]
|
||||
val zone = obj.Zone
|
||||
//update current charge level
|
||||
zone.VehicleEvents ! VehicleServiceMessage(
|
||||
zone.VehicleEvents ! MessageEnvelope(
|
||||
obj.Actor.toString,
|
||||
VehicleAction.SendResponse(Service.defaultPlayerGUID, QuantityUpdateMessage(siphon.AmmoSlot.Box.GUID, siphon.Magazine))
|
||||
SendResponse(QuantityUpdateMessage(siphon.AmmoSlot.Box.GUID, siphon.Magazine))
|
||||
)
|
||||
siphonRecharge.put(guid, context.system.scheduler.scheduleWithFixedDelay(
|
||||
initialDelay = 3000 milliseconds,
|
||||
|
|
@ -119,9 +119,9 @@ object ArmorSiphonBehavior {
|
|||
val before = siphon.Magazine
|
||||
val after = siphon.Magazine = before + 1
|
||||
if (after > before) {
|
||||
zone.VehicleEvents ! VehicleServiceMessage(
|
||||
zone.VehicleEvents ! MessageEnvelope(
|
||||
obj.Actor.toString,
|
||||
VehicleAction.SendResponse(Service.defaultPlayerGUID, QuantityUpdateMessage(siphon.AmmoSlot.Box.GUID, after))
|
||||
SendResponse(QuantityUpdateMessage(siphon.AmmoSlot.Box.GUID, after))
|
||||
)
|
||||
if (after == siphon.MaxMagazine) {
|
||||
endSiphonRecharge(guid)
|
||||
|
|
|
|||
|
|
@ -8,9 +8,9 @@ import net.psforever.objects.vehicles.MountedWeapons
|
|||
import net.psforever.objects.vital.interaction.DamageResult
|
||||
import net.psforever.objects.vital.projectile.ProjectileReason
|
||||
import net.psforever.objects.zones.{Zone, ZoneAware}
|
||||
import net.psforever.services.base.envelope.MessageEnvelope
|
||||
import net.psforever.services.base.message.PlanetsideAttribute
|
||||
import net.psforever.types.Vector3
|
||||
import net.psforever.services.Service
|
||||
import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage}
|
||||
|
||||
import scala.collection.mutable
|
||||
import scala.concurrent.duration._
|
||||
|
|
@ -234,7 +234,6 @@ trait JammableBehavior {
|
|||
* @see `Service`
|
||||
* @see `VehicleAction`
|
||||
* @see `VehicleService`
|
||||
* @see `VehicleServiceMessage`
|
||||
* @see `Zone.VehicleEvents`
|
||||
*/
|
||||
trait JammableMountedWeapons extends JammableBehavior {
|
||||
|
|
@ -243,9 +242,9 @@ trait JammableMountedWeapons extends JammableBehavior {
|
|||
override def StartJammeredSound(target: Any, dur: Int): Unit = {
|
||||
target match {
|
||||
case obj: PlanetSideServerObject with MountedWeapons with JammableUnit if !jammedSound =>
|
||||
obj.Zone.VehicleEvents ! VehicleServiceMessage(
|
||||
obj.Zone.VehicleEvents ! MessageEnvelope(
|
||||
obj.Zone.id,
|
||||
VehicleAction.PlanetsideAttribute(Service.defaultPlayerGUID, obj.GUID, 27, 1)
|
||||
PlanetsideAttribute(obj.GUID, 27, 1)
|
||||
)
|
||||
super.StartJammeredSound(target, dur)
|
||||
case _ => ;
|
||||
|
|
@ -264,9 +263,9 @@ trait JammableMountedWeapons extends JammableBehavior {
|
|||
override def CancelJammeredSound(target: Any): Unit = {
|
||||
target match {
|
||||
case obj: PlanetSideServerObject if jammedSound =>
|
||||
obj.Zone.VehicleEvents ! VehicleServiceMessage(
|
||||
obj.Zone.VehicleEvents ! MessageEnvelope(
|
||||
obj.Zone.id,
|
||||
VehicleAction.PlanetsideAttribute(Service.defaultPlayerGUID, obj.GUID, 27, 0)
|
||||
PlanetsideAttribute(obj.GUID, 27, 0)
|
||||
)
|
||||
case _ => ;
|
||||
}
|
||||
|
|
@ -308,9 +307,9 @@ object JammableMountedWeapons {
|
|||
|
||||
def JammedWeaponStatus(zone: Zone, target: Equipment with JammableUnit, statusCode: Int): Unit = {
|
||||
target.Jammed = statusCode == 1
|
||||
zone.VehicleEvents ! VehicleServiceMessage(
|
||||
zone.VehicleEvents ! MessageEnvelope(
|
||||
zone.id,
|
||||
VehicleAction.PlanetsideAttribute(Service.defaultPlayerGUID, target.GUID, 27, statusCode)
|
||||
PlanetsideAttribute(target.GUID, 27, statusCode)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -702,15 +702,18 @@ object GridInventory {
|
|||
*/
|
||||
private def sortKnapsack(list: List[InventoryItem], width: Int, height: Int): Unit = {
|
||||
val root = new KnapsackNode(0, 0, width, height)
|
||||
list.foreach(item => {
|
||||
findKnapsackSpace(root, item.obj.Tile.Width, item.obj.Tile.Height) match {
|
||||
list.foreach { item =>
|
||||
val tile = item.obj.Tile
|
||||
val twidth = tile.Width
|
||||
val theight = tile.Height
|
||||
findKnapsackSpace(root, twidth, theight) match {
|
||||
case Some(node) =>
|
||||
splitKnapsackSpace(node, item.obj.Tile.Width, item.obj.Tile.Height)
|
||||
splitKnapsackSpace(node, twidth, theight)
|
||||
item.start = node.y * width + node.x
|
||||
case _ => ;
|
||||
case _ =>
|
||||
item.start = -1
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -720,42 +723,32 @@ object GridInventory {
|
|||
* Horizontal space for the `down` child is emphasized over vertical space for the `right` child.
|
||||
* By dividing and reducing a defined space like this, it can be tightly packed with a given number of elements.<br>
|
||||
* <br>
|
||||
* Due to the nature of the knapsack problem and the naivette of the algorithm, small holes in the solution are bound to crop-up.
|
||||
* Due to the nature of the knapsack problem and the naivete of the algorithm, small holes in the solution are bound to crop-up.
|
||||
* @param x the x-coordinate, upper left corner
|
||||
* @param y the y-coordinate, upper left corner
|
||||
* @param width the width
|
||||
* @param height the height
|
||||
*/
|
||||
private class KnapsackNode(var x: Int, var y: Int, var width: Int, var height: Int) {
|
||||
private var used: Boolean = false
|
||||
var down: Option[KnapsackNode] = None
|
||||
var right: Option[KnapsackNode] = None
|
||||
private class KnapsackNode(val x: Int, val y: Int, val width: Int, val height: Int) {
|
||||
private var used: Boolean = false
|
||||
private var down: Option[KnapsackNode] = None
|
||||
private var right: Option[KnapsackNode] = None
|
||||
|
||||
def Used: Boolean = used
|
||||
|
||||
/**
|
||||
* Initialize the `down` and `right` children of this node.
|
||||
*/
|
||||
def Split(): Unit = {
|
||||
used = true
|
||||
down = Some(new KnapsackNode(0, 0, 0, 0))
|
||||
right = Some(new KnapsackNode(0, 0, 0, 0))
|
||||
}
|
||||
def Down: Option[KnapsackNode] = down
|
||||
|
||||
def Right: Option[KnapsackNode] = right
|
||||
|
||||
/**
|
||||
* Change the dimensions of the node.<br>
|
||||
* <br>
|
||||
* Use: `{node}(nx, ny, nw, nh)`
|
||||
* @param nx the new x-coordinate, upper left corner
|
||||
* @param ny the new y-coordinate, upper left corner
|
||||
* @param nw the new width
|
||||
* @param nh the new height
|
||||
*/
|
||||
def apply(nx: Int, ny: Int, nw: Int, nh: Int): Unit = {
|
||||
x = nx
|
||||
y = ny
|
||||
width = nw
|
||||
height = nh
|
||||
* Initialize the `down` and `right` children of this node.
|
||||
* @param insertDown new "down" knapsack division
|
||||
* @param insertRight new "right" knapsack division
|
||||
*/
|
||||
def Split(insertDown: KnapsackNode, insertRight: KnapsackNode): Unit = {
|
||||
used = true
|
||||
down = Some(insertDown)
|
||||
right = Some(insertRight)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -768,7 +761,7 @@ object GridInventory {
|
|||
*/
|
||||
private def findKnapsackSpace(node: KnapsackNode, width: Int, height: Int): Option[KnapsackNode] = {
|
||||
if (node.Used) {
|
||||
findKnapsackSpace(node.right.get, width, height).orElse(findKnapsackSpace(node.down.get, width, height))
|
||||
findKnapsackSpace(node.Right.get, width, height).orElse(findKnapsackSpace(node.Down.get, width, height))
|
||||
} else if (width <= node.width && height <= node.height) {
|
||||
Some(node)
|
||||
} else {
|
||||
|
|
@ -787,13 +780,14 @@ object GridInventory {
|
|||
* @param height height of the element
|
||||
*/
|
||||
private def splitKnapsackSpace(node: KnapsackNode, width: Int, height: Int): Unit = {
|
||||
node.Split()
|
||||
node.down.get(node.x, node.y + height, node.width, node.height - height)
|
||||
node.right.get(node.x + width, node.y, node.width - width, height)
|
||||
node.Split(
|
||||
new KnapsackNode(node.x, node.y + height, node.width, node.height - height),
|
||||
new KnapsackNode(node.x + width, node.y, node.width - width, height)
|
||||
)
|
||||
}
|
||||
|
||||
def toPrintedList(inv: GridInventory): String = {
|
||||
val list = new StringBuilder
|
||||
val list = new mutable.StringBuilder
|
||||
list.append("\n")
|
||||
inv.Items.zipWithIndex.foreach {
|
||||
case (InventoryItem(obj, start), index) =>
|
||||
|
|
@ -803,6 +797,6 @@ object GridInventory {
|
|||
}
|
||||
|
||||
def toPrintedGrid(inv: GridInventory): String = {
|
||||
new StringBuilder().append("\n").append(inv.grid.toSeq.grouped(inv.width).mkString("\n")).toString
|
||||
new mutable.StringBuilder().append("\n").append(inv.grid.toSeq.grouped(inv.width).mkString("\n")).toString
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,8 +6,8 @@ import net.psforever.objects.equipment.Equipment
|
|||
import net.psforever.objects.serverobject.containable.{Containable, ContainableBehavior}
|
||||
import net.psforever.packet.game.objectcreate.ObjectCreateMessageParent
|
||||
import net.psforever.packet.game.{ObjectAttachMessage, ObjectCreateDetailedMessage, ObjectDetachMessage}
|
||||
import net.psforever.services.Service
|
||||
import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage}
|
||||
import net.psforever.services.base.envelope.MessageEnvelope
|
||||
import net.psforever.services.base.message.{ObjectDelete, SendResponse}
|
||||
import net.psforever.types.{PlanetSideEmpire, Vector3}
|
||||
|
||||
/**
|
||||
|
|
@ -19,7 +19,7 @@ import net.psforever.types.{PlanetSideEmpire, Vector3}
|
|||
class LockerContainerControl(locker: LockerContainer, toChannel: String)
|
||||
extends Actor
|
||||
with ContainableBehavior {
|
||||
def ContainerObject = locker
|
||||
def ContainerObject: LockerContainer = locker
|
||||
|
||||
def receive: Receive =
|
||||
containerBehavior
|
||||
|
|
@ -34,9 +34,9 @@ class LockerContainerControl(locker: LockerContainer, toChannel: String)
|
|||
val obj = ContainerObject
|
||||
obj.Find(item) match {
|
||||
case Some(slot) =>
|
||||
obj.Zone.AvatarEvents ! AvatarServiceMessage(
|
||||
obj.Zone.AvatarEvents ! MessageEnvelope(
|
||||
toChannel,
|
||||
AvatarAction.SendResponse(Service.defaultPlayerGUID, ObjectAttachMessage(obj.GUID, item.GUID, slot))
|
||||
SendResponse(ObjectAttachMessage(obj.GUID, item.GUID, slot))
|
||||
)
|
||||
case None => ;
|
||||
}
|
||||
|
|
@ -46,17 +46,16 @@ class LockerContainerControl(locker: LockerContainer, toChannel: String)
|
|||
|
||||
def RemoveItemFromSlotCallback(item: Equipment, slot: Int): Unit = {
|
||||
val zone = locker.Zone
|
||||
zone.AvatarEvents ! AvatarServiceMessage(toChannel, AvatarAction.ObjectDelete(Service.defaultPlayerGUID, item.GUID))
|
||||
zone.AvatarEvents ! MessageEnvelope(toChannel, ObjectDelete(item.GUID))
|
||||
}
|
||||
|
||||
def PutItemInSlotCallback(item: Equipment, slot: Int): Unit = {
|
||||
val zone = locker.Zone
|
||||
val definition = item.Definition
|
||||
item.Faction = PlanetSideEmpire.NEUTRAL
|
||||
zone.AvatarEvents ! AvatarServiceMessage(
|
||||
zone.AvatarEvents ! MessageEnvelope(
|
||||
toChannel,
|
||||
AvatarAction.SendResponse(
|
||||
Service.defaultPlayerGUID,
|
||||
SendResponse(
|
||||
ObjectCreateDetailedMessage(
|
||||
definition.ObjectId,
|
||||
item.GUID,
|
||||
|
|
@ -69,12 +68,9 @@ class LockerContainerControl(locker: LockerContainer, toChannel: String)
|
|||
|
||||
def SwapItemCallback(item: Equipment, fromSlot: Int): Unit = {
|
||||
val zone = locker.Zone
|
||||
zone.AvatarEvents ! AvatarServiceMessage(
|
||||
zone.AvatarEvents ! MessageEnvelope(
|
||||
toChannel,
|
||||
AvatarAction.SendResponse(
|
||||
Service.defaultPlayerGUID,
|
||||
ObjectDetachMessage(locker.GUID, item.GUID, Vector3.Zero, 0f)
|
||||
)
|
||||
SendResponse(ObjectDetachMessage(locker.GUID, item.GUID, Vector3.Zero, 0f))
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,9 @@ package net.psforever.objects.serverobject.damage
|
|||
|
||||
import net.psforever.objects.serverobject.structures.Amenity
|
||||
import net.psforever.objects.vital.interaction.DamageResult
|
||||
import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage}
|
||||
import net.psforever.packet.game.PlanetsideAttributeMessage
|
||||
import net.psforever.services.base.envelope.MessageEnvelope
|
||||
import net.psforever.services.base.message.SendResponse
|
||||
|
||||
/**
|
||||
* The "control" `Actor` mixin for damage-handling code
|
||||
|
|
@ -25,8 +27,7 @@ object DamageableAmenity {
|
|||
* A destroyed `Amenity` target dispatches two messages to chance its model and operational states.
|
||||
* The common manifestation is a sparking entity that will no longer report being accessible.
|
||||
* These `PlanetSideAttributeMessage` attributes are the same as reported during zone load client configuration.
|
||||
* @see `AvatarAction.PlanetsideAttributeToAll`
|
||||
* @see `AvatarServiceMessage`
|
||||
* @see `PlanetsideAttribute`
|
||||
* @see `Zone.AvatarEvents`
|
||||
* @param target the entity being destroyed
|
||||
* @param cause historical information about the damage
|
||||
|
|
@ -36,7 +37,9 @@ object DamageableAmenity {
|
|||
val zoneId = zone.id
|
||||
val events = zone.AvatarEvents
|
||||
val targetGUID = target.GUID
|
||||
events ! AvatarServiceMessage(zoneId, AvatarAction.PlanetsideAttributeToAll(targetGUID, 50, 1))
|
||||
events ! AvatarServiceMessage(zoneId, AvatarAction.PlanetsideAttributeToAll(targetGUID, 51, 1))
|
||||
events ! MessageEnvelope(
|
||||
zoneId,
|
||||
SendResponse(PlanetsideAttributeMessage(targetGUID, 50, 1), PlanetsideAttributeMessage(targetGUID, 51, 1))
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,14 +1,16 @@
|
|||
//Copyright (c) 2020 PSForever
|
||||
package net.psforever.objects.serverobject.damage
|
||||
|
||||
import net.psforever.objects.Default
|
||||
import net.psforever.objects.equipment.JammableUnit
|
||||
import net.psforever.objects.serverobject.tube.SpawnTube
|
||||
import net.psforever.objects.vital.interaction.DamageResult
|
||||
import net.psforever.objects.vital.resolution.ResolutionCalculations
|
||||
import net.psforever.objects.zones.Zone
|
||||
import net.psforever.types.PlanetSideGUID
|
||||
import net.psforever.services.Service
|
||||
import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage}
|
||||
import net.psforever.services.avatar.AvatarAction
|
||||
import net.psforever.services.base.envelope.MessageEnvelope
|
||||
import net.psforever.services.base.message.PlanetsideAttribute
|
||||
|
||||
/**
|
||||
* The "control" `Actor` mixin for damage-handling code,
|
||||
|
|
@ -140,12 +142,11 @@ object DamageableEntity {
|
|||
* - reports its adjusted its health;
|
||||
* - alert the activity monitor for that `Zone` about the damage; and,
|
||||
* - provide a feedback message regarding the damage.
|
||||
* @see `AvatarAction.PlanetsideAttributeToAll`
|
||||
* @see `AvatarAction.SendResponse`
|
||||
* @see `AvatarServiceMessage`
|
||||
* @see `PlanetsideAttribute`
|
||||
* @see `SendResponse`
|
||||
* @see `DamageFeedbackMessage`
|
||||
* @see `JammableUnit.Jammered`
|
||||
* @see `Service.defaultPlayerGUID`
|
||||
* @see `Default.GUID0`
|
||||
* @see `Zone.Activity`
|
||||
* @see `Zone.AvatarEvents`
|
||||
* @see `Zone.HotSpot.Activity`
|
||||
|
|
@ -165,9 +166,9 @@ object DamageableEntity {
|
|||
def DamageToHealth(target: Damageable.Target, cause: DamageResult, amount: Int): Boolean = {
|
||||
if (amount > 0 && !target.Destroyed) {
|
||||
val zone = target.Zone
|
||||
zone.AvatarEvents ! AvatarServiceMessage(
|
||||
zone.AvatarEvents ! MessageEnvelope(
|
||||
zone.id,
|
||||
AvatarAction.PlanetsideAttributeToAll(target.GUID, 0, target.Health)
|
||||
PlanetsideAttribute(target.GUID, 0, target.Health)
|
||||
)
|
||||
true
|
||||
}
|
||||
|
|
@ -181,8 +182,7 @@ object DamageableEntity {
|
|||
* - reports its adjusted its health; and,
|
||||
* - report about its destruction.
|
||||
* @see `AvatarAction.Destroy`
|
||||
* @see `AvatarAction.PlanetsideAttribute`
|
||||
* @see `AvatarServiceMessage`
|
||||
* @see `PlanetsideAttribute`
|
||||
* @see `DamageFeedbackMessage`
|
||||
* @see `JammableUnit.ClearJammeredSound`
|
||||
* @see `JammableUnit.ClearJammeredStatus`
|
||||
|
|
@ -199,12 +199,12 @@ object DamageableEntity {
|
|||
val zoneId = zone.id
|
||||
val tguid = target.GUID
|
||||
val attribution = attributionTo(cause, target.Zone)
|
||||
zone.AvatarEvents ! AvatarServiceMessage(zoneId, AvatarAction.PlanetsideAttributeToAll(tguid, 0, target.Health))
|
||||
zone.AvatarEvents ! MessageEnvelope(zoneId, PlanetsideAttribute(tguid, 0, target.Health))
|
||||
if (target.isInstanceOf[SpawnTube]) {}//do nothing to prevent issue #1057
|
||||
else {
|
||||
zone.AvatarEvents ! AvatarServiceMessage(
|
||||
zone.AvatarEvents ! MessageEnvelope(
|
||||
zoneId,
|
||||
AvatarAction.Destroy(tguid, attribution, Service.defaultPlayerGUID, target.Position)
|
||||
AvatarAction.Destroy(tguid, attribution, Default.GUID0, target.Position)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,13 +1,14 @@
|
|||
//Copyright (c) 2020 PSForever
|
||||
package net.psforever.objects.serverobject.damage
|
||||
|
||||
import net.psforever.objects.Player
|
||||
import net.psforever.objects.{Default, Player}
|
||||
import net.psforever.objects.serverobject.mount.Mountable
|
||||
import net.psforever.objects.sourcing.{PlayerSource, SourceEntry}
|
||||
import net.psforever.objects.vital.interaction.{DamageInteraction, DamageResult}
|
||||
import net.psforever.packet.game.DamageWithPositionMessage
|
||||
import net.psforever.services.Service
|
||||
import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage}
|
||||
import net.psforever.services.avatar.AvatarAction
|
||||
import net.psforever.services.base.envelope.{BundledEnvelope, MessageEnvelope}
|
||||
import net.psforever.services.base.message.{HintsAtAttacker, SendResponse}
|
||||
|
||||
/**
|
||||
* Functions to assist other damage-dealing code for objects that contain users.
|
||||
|
|
@ -17,12 +18,11 @@ object DamageableMountable {
|
|||
/**
|
||||
* A damaged target alerts its occupants (as it is a `Mountable` object) of the source of the damage.
|
||||
*
|
||||
* @see `AvatarAction.HitHint`
|
||||
* @see `AvatarAction.SendResponse`
|
||||
* @see `AvatarServiceMessage`
|
||||
* @see `HitHint`
|
||||
* @see `SendResponse`
|
||||
* @see `DamageWithPositionMessage`
|
||||
* @see `Mountable.Seats`
|
||||
* @see `Service.defaultPlayerGUID`
|
||||
* @see `Default.GUID0`
|
||||
* @see `Zone.AvatarEvents`
|
||||
* @see `Zone.LivePlayers`
|
||||
* @param target the entity being damaged
|
||||
|
|
@ -37,32 +37,34 @@ object DamageableMountable {
|
|||
val zone = target.Zone
|
||||
val events = zone.AvatarEvents
|
||||
val occupants = target.Seats.values.toSeq.flatMap { seat => seat.occupants.filter(_.isAlive) }
|
||||
((cause.adversarial match {
|
||||
case Some(adversarial) => Some(adversarial.attacker)
|
||||
case None => None
|
||||
}) match {
|
||||
case Some(pSource: PlayerSource) => //player damage
|
||||
val name = pSource.Name
|
||||
(zone.LivePlayers.find(_.Name == name).orElse(zone.Corpses.find(_.Name == name)) match {
|
||||
case Some(player) =>
|
||||
AvatarAction.HitHint(player.GUID, player.GUID)
|
||||
case None =>
|
||||
AvatarAction.SendResponse(Service.defaultPlayerGUID, DamageWithPositionMessage(countableDamage, pSource.Position))
|
||||
}) match {
|
||||
case AvatarAction.HitHint(_, guid) =>
|
||||
occupants.map { tplayer => (tplayer.Name, AvatarAction.HitHint(guid, tplayer.GUID)) }
|
||||
case msg =>
|
||||
occupants.map { tplayer => (tplayer.Name, msg) }
|
||||
}
|
||||
case Some(source) => //object damage
|
||||
val msg = AvatarAction.SendResponse(Service.defaultPlayerGUID, DamageWithPositionMessage(countableDamage, source.Position))
|
||||
occupants.map { tplayer => (tplayer.Name, msg) }
|
||||
case None =>
|
||||
List.empty
|
||||
}).foreach {
|
||||
case (channel, msg) =>
|
||||
events ! AvatarServiceMessage(channel, msg)
|
||||
}
|
||||
events ! BundledEnvelope(
|
||||
((cause.adversarial match {
|
||||
case Some(adversarial) => Some(adversarial.attacker)
|
||||
case None => None
|
||||
}) match {
|
||||
case Some(pSource: PlayerSource) => //player damage
|
||||
val name = pSource.Name
|
||||
(zone.LivePlayers.find(_.Name == name).orElse(zone.Corpses.find(_.Name == name)) match {
|
||||
case Some(player) =>
|
||||
HintsAtAttacker(player.GUID)
|
||||
case None =>
|
||||
SendResponse(DamageWithPositionMessage(countableDamage, pSource.Position))
|
||||
}) match {
|
||||
case msg @ HintsAtAttacker(guid) =>
|
||||
occupants.map { tplayer => (tplayer.Name, guid, msg) }
|
||||
case msg =>
|
||||
occupants.map { tplayer => (tplayer.Name, Default.GUID0, msg) }
|
||||
}
|
||||
case Some(source) => //object damage
|
||||
val msg = SendResponse(DamageWithPositionMessage(countableDamage, source.Position))
|
||||
occupants.map { tplayer => (tplayer.Name, Default.GUID0, msg) }
|
||||
case None =>
|
||||
List.empty
|
||||
}).map {
|
||||
case (channel, filter, msg) =>
|
||||
MessageEnvelope(channel, filter, msg)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -78,7 +80,7 @@ object DamageableMountable {
|
|||
val targets = target.Seats.values.flatMap(_.occupant).filter(_.isAlive)
|
||||
targets.foreach { player =>
|
||||
//make llu visible to others in zone if passenger is carrying one
|
||||
player.Zone.AvatarEvents ! AvatarServiceMessage(player.Name, AvatarAction.DropSpecialItem())
|
||||
player.Zone.AvatarEvents ! MessageEnvelope(player.Name, AvatarAction.DropSpecialItem())
|
||||
//player.LogActivity(cause)
|
||||
player.Actor ! Player.Die(
|
||||
DamageInteraction(interaction.resolution, SourceEntry(player), interaction.cause, interaction.hitPos)
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
package net.psforever.objects.serverobject.damage
|
||||
|
||||
import akka.actor.{Actor, Cancellable}
|
||||
import net.psforever.objects.{Vehicle, Vehicles}
|
||||
import net.psforever.objects.{Default, Vehicle, Vehicles}
|
||||
import net.psforever.objects.equipment.JammableUnit
|
||||
import net.psforever.objects.serverobject.damage.Damageable.Target
|
||||
import net.psforever.objects.sourcing.VehicleSource
|
||||
|
|
@ -12,8 +12,8 @@ import net.psforever.objects.vital.resolution.ResolutionCalculations
|
|||
import net.psforever.objects.zones.Zone
|
||||
import net.psforever.objects.zones.exp.ToDatabase
|
||||
import net.psforever.packet.game.DamageWithPositionMessage
|
||||
import net.psforever.services.Service
|
||||
import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage}
|
||||
import net.psforever.services.base.envelope.MessageEnvelope
|
||||
import net.psforever.services.base.message.{PlanetsideAttribute, SendResponse}
|
||||
import net.psforever.types.Vector3
|
||||
|
||||
import scala.concurrent.duration._
|
||||
|
|
@ -102,10 +102,9 @@ trait DamageableVehicle
|
|||
* Most all vehicles and the weapons mounted to them can jam
|
||||
* if the projectile that strikes (near) them has jammering properties.
|
||||
* If this vehicle has shields that were affected by previous damage, that is also reported to the clients.
|
||||
* @see `Service.defaultPlayerGUID`
|
||||
* @see `Default.GUID0`
|
||||
* @see `Vehicle.CargoHolds`
|
||||
* @see `VehicleAction.PlanetsideAttribute`
|
||||
* @see `VehicleServiceMessage`
|
||||
* @see `PlanetsideAttribute`
|
||||
* @param target the entity being destroyed
|
||||
* @param cause historical information about the damage
|
||||
* @param amount how much damage was performed
|
||||
|
|
@ -142,27 +141,27 @@ trait DamageableVehicle
|
|||
}
|
||||
//stat changes
|
||||
if (damageToShields > 0) {
|
||||
events ! VehicleServiceMessage(
|
||||
events ! MessageEnvelope(
|
||||
shieldChannel,
|
||||
VehicleAction.PlanetsideAttribute(Service.defaultPlayerGUID, targetGUID, obj.Definition.shieldUiAttribute, obj.Shields)
|
||||
PlanetsideAttribute(targetGUID, obj.Definition.shieldUiAttribute, obj.Shields)
|
||||
)
|
||||
announceConfrontation = true
|
||||
}
|
||||
if (damageToHealth > 0) {
|
||||
events ! VehicleServiceMessage(
|
||||
events ! MessageEnvelope(
|
||||
healthChannel,
|
||||
VehicleAction.PlanetsideAttribute(Service.defaultPlayerGUID, targetGUID, 0, obj.Health)
|
||||
PlanetsideAttribute(targetGUID, 0, obj.Health)
|
||||
)
|
||||
announceConfrontation = true
|
||||
}
|
||||
}
|
||||
if (announceConfrontation) {
|
||||
if (showAsAggravated) {
|
||||
val msg = VehicleAction.SendResponse(Service.defaultPlayerGUID, DamageWithPositionMessage(totalDamage, Vector3.Zero))
|
||||
val msg = SendResponse(DamageWithPositionMessage(totalDamage, Vector3.Zero))
|
||||
obj.Seats.values
|
||||
.collect { case seat if seat.occupant.nonEmpty => seat.occupant.get.Name }
|
||||
.foreach { channel =>
|
||||
events ! VehicleServiceMessage(channel, msg)
|
||||
events ! MessageEnvelope(channel, msg)
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
|
@ -180,13 +179,11 @@ trait DamageableVehicle
|
|||
* Finally, the vehicle is tasked for deconstruction.
|
||||
* @see `Deployment.TryDeploymentChange`
|
||||
* @see `DriveState.Undeploying`
|
||||
* @see `Service.defaultPlayerGUID`
|
||||
* @see `Default.GUID0`
|
||||
* @see `Vehicle.CargoHolds`
|
||||
* @see `VehicleAction.PlanetsideAttribute`
|
||||
* @see `PlanetsideAttribute`
|
||||
* @see `RemoverActor.AddTask`
|
||||
* @see `RemoverActor.ClearSpecific`
|
||||
* @see `VehicleServiceMessage`
|
||||
* @see `VehicleServiceMessage.Decon`
|
||||
* @see `Zone.VehicleEvents`
|
||||
* @param target the entity being destroyed
|
||||
* @param cause historical information about the damage
|
||||
|
|
@ -217,9 +214,9 @@ trait DamageableVehicle
|
|||
//shields
|
||||
if (obj.Shields > 0) {
|
||||
obj.Shields = 0
|
||||
zone.VehicleEvents ! VehicleServiceMessage(
|
||||
zone.VehicleEvents ! MessageEnvelope(
|
||||
zone.id,
|
||||
VehicleAction.PlanetsideAttribute(Service.defaultPlayerGUID, target.GUID, obj.Definition.shieldUiAttribute, 0)
|
||||
PlanetsideAttribute(target.GUID, obj.Definition.shieldUiAttribute, 0)
|
||||
)
|
||||
}
|
||||
//database entry
|
||||
|
|
@ -243,22 +240,22 @@ trait DamageableVehicle
|
|||
import scala.concurrent.ExecutionContext.Implicits.global
|
||||
import scala.concurrent.duration._
|
||||
val obj = DamageableObject
|
||||
val guid0 = Service.defaultPlayerGUID
|
||||
val guid0 = Default.GUID0
|
||||
val zone = obj.Zone
|
||||
val zoneid = zone.id
|
||||
val events = zone.VehicleEvents
|
||||
//health to 1, shields to 0
|
||||
obj.Health = 1
|
||||
val guid = obj.GUID
|
||||
events ! VehicleServiceMessage(
|
||||
events ! MessageEnvelope(
|
||||
zoneid,
|
||||
VehicleAction.PlanetsideAttribute(guid0, guid, 0, 1)
|
||||
PlanetsideAttribute(guid, 0, 1)
|
||||
)
|
||||
if (obj.Shields > 0) {
|
||||
obj.Shields = 0
|
||||
zone.VehicleEvents ! VehicleServiceMessage(
|
||||
events ! MessageEnvelope(
|
||||
zone.id,
|
||||
VehicleAction.PlanetsideAttribute(Service.defaultPlayerGUID, obj.GUID, obj.Definition.shieldUiAttribute, 0)
|
||||
PlanetsideAttribute(obj.GUID, obj.Definition.shieldUiAttribute, 0)
|
||||
)
|
||||
}
|
||||
//aggravation cancel
|
||||
|
|
|
|||
|
|
@ -9,10 +9,10 @@ import net.psforever.objects.vital.interaction.DamageResult
|
|||
import net.psforever.objects.zones.Zone
|
||||
import net.psforever.packet.game.DamageWithPositionMessage
|
||||
import net.psforever.types.Vector3
|
||||
import net.psforever.services.Service
|
||||
import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage}
|
||||
import net.psforever.services.vehicle.support.TurretUpgrader
|
||||
import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage}
|
||||
import net.psforever.services.base.envelope.{BundledEnvelope, MessageEnvelope}
|
||||
import net.psforever.services.base.message.{ObjectDelete, PlanetsideAttribute, SendResponse}
|
||||
import net.psforever.services.base.support.SupportActor
|
||||
import net.psforever.services.vehicle.support.{TurretEnvelope, TurretUpgrader}
|
||||
|
||||
/**
|
||||
* The "control" `Actor` mixin for damage-handling code for `WeaponTurret` objects.
|
||||
|
|
@ -62,21 +62,22 @@ trait DamageableWeaponTurret
|
|||
//TODO some turrets have shields
|
||||
if (damageToHealth > 0) {
|
||||
DamageableMountable.DamageAwareness(DamageableObject, cause, damageToHealth)
|
||||
events ! VehicleServiceMessage(
|
||||
events ! MessageEnvelope(
|
||||
zoneId,
|
||||
VehicleAction.PlanetsideAttribute(Service.defaultPlayerGUID, targetGUID, 0, obj.Health)
|
||||
PlanetsideAttribute(targetGUID, 0, obj.Health)
|
||||
)
|
||||
announceConfrontation = true
|
||||
}
|
||||
}
|
||||
if (announceConfrontation) {
|
||||
if (aggravated) {
|
||||
val msg = VehicleAction.SendResponse(Service.defaultPlayerGUID, DamageWithPositionMessage(damageToHealth, Vector3.Zero))
|
||||
obj.Seats.values
|
||||
val msg = SendResponse(DamageWithPositionMessage(damageToHealth, Vector3.Zero))
|
||||
events ! BundledEnvelope(obj.Seats.values
|
||||
.collect { case seat if seat.occupant.nonEmpty => seat.occupant.get.Name }
|
||||
.foreach { channel =>
|
||||
events ! VehicleServiceMessage(channel, msg)
|
||||
.map { channel =>
|
||||
MessageEnvelope(channel, msg)
|
||||
}
|
||||
)
|
||||
}
|
||||
else {
|
||||
//activity on map
|
||||
|
|
@ -103,16 +104,15 @@ object DamageableWeaponTurret {
|
|||
* A destroyed target dispatches a message to conceal (delete) its weapons from users.
|
||||
* If affected by a jammer property, the jammer propoerty will be removed.
|
||||
* If the type of entity is a `WeaponTurret`, the weapons are converted to their "normal" upgrade state.
|
||||
* @see `AvatarAction.DeleteObject`
|
||||
* @see `AvatarServiceMessage`
|
||||
* @see `DeleteObject`
|
||||
* @see `MountedWeapons`
|
||||
* @see `MountedWeapons.Weapons`
|
||||
* @see `Service.defaultPlayerGUID`
|
||||
* @see `Default.GUID0`
|
||||
* @see `TurretUpgrade.None`
|
||||
* @see `TurretUpgrader.AddTask`
|
||||
* @see `TurretUpgrader.ClearSpecific`
|
||||
* @see `WeaponTurret`
|
||||
* @see `VehicleServiceMessage.TurretUpgrade`
|
||||
* @see `TurretMessage`
|
||||
* @see `Zone.AvatarEvents`
|
||||
* @see `Zone.VehicleEvents`
|
||||
* @param target the entity being destroyed;
|
||||
|
|
@ -125,20 +125,18 @@ object DamageableWeaponTurret {
|
|||
val zone = target.Zone
|
||||
val zoneId = zone.id
|
||||
val avatarEvents = zone.AvatarEvents
|
||||
target.Weapons.values
|
||||
.filter {
|
||||
_.Equipment.nonEmpty
|
||||
avatarEvents ! BundledEnvelope(target.Weapons.values
|
||||
.filter(_.Equipment.nonEmpty)
|
||||
.map { slot =>
|
||||
MessageEnvelope(zoneId, ObjectDelete(slot.Equipment.get.GUID))
|
||||
}
|
||||
.foreach(slot => {
|
||||
val wep = slot.Equipment.get
|
||||
avatarEvents ! AvatarServiceMessage(zoneId, AvatarAction.ObjectDelete(Service.defaultPlayerGUID, wep.GUID))
|
||||
})
|
||||
)
|
||||
target match {
|
||||
case turret: WeaponTurret =>
|
||||
if (turret.Upgrade != TurretUpgrade.None) {
|
||||
val vehicleEvents = zone.VehicleEvents
|
||||
vehicleEvents ! VehicleServiceMessage.TurretUpgrade(TurretUpgrader.ClearSpecific(List(turret), zone))
|
||||
vehicleEvents ! VehicleServiceMessage.TurretUpgrade(TurretUpgrader.AddTask(turret, zone, TurretUpgrade.None))
|
||||
vehicleEvents ! TurretEnvelope(SupportActor.ClearSpecific(List(turret), zone))
|
||||
vehicleEvents ! TurretEnvelope(TurretUpgrader.AddTask(turret, zone, TurretUpgrade.None))
|
||||
}
|
||||
case _ =>
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,8 +4,8 @@ package net.psforever.objects.serverobject.deploy
|
|||
import akka.actor.{Actor, ActorRef, Cancellable}
|
||||
import net.psforever.objects.Default
|
||||
import net.psforever.types.{DriveState, Vector3}
|
||||
import net.psforever.services.Service
|
||||
import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage}
|
||||
import net.psforever.services.base.envelope.MessageEnvelope
|
||||
import net.psforever.services.vehicle.VehicleAction
|
||||
|
||||
import scala.concurrent.ExecutionContext.Implicits.global
|
||||
import scala.concurrent.duration._
|
||||
|
|
@ -97,16 +97,15 @@ trait DeploymentBehavior {
|
|||
val guid = obj.GUID
|
||||
val zone = obj.Zone
|
||||
val zoneChannel = zone.id
|
||||
val GUID0 = Service.defaultPlayerGUID
|
||||
//TODO remove this arbitrary allowance angle when no longer helpful
|
||||
if (obj.Orientation.x > 30 && obj.Orientation.x < 330) {
|
||||
obj.DeploymentState = prevState
|
||||
prevState
|
||||
} else if (state == DriveState.Deploying) {
|
||||
obj.Velocity = Some(Vector3.Zero) //no velocity
|
||||
zone.VehicleEvents ! VehicleServiceMessage(
|
||||
zone.VehicleEvents ! MessageEnvelope(
|
||||
zoneChannel,
|
||||
VehicleAction.DeployRequest(GUID0, guid, state, 0, unk2=false, Vector3.Zero)
|
||||
VehicleAction.DeployRequest(guid, state, 0, unk2=false, Vector3.Zero)
|
||||
)
|
||||
deploymentTimer.cancel()
|
||||
deploymentTimer = context.system.scheduler.scheduleOnce(obj.DeployTime.milliseconds)({
|
||||
|
|
@ -115,9 +114,9 @@ trait DeploymentBehavior {
|
|||
state
|
||||
} else if (state == DriveState.Deployed) {
|
||||
obj.Velocity = Some(Vector3.Zero) //no velocity
|
||||
zone.VehicleEvents ! VehicleServiceMessage(
|
||||
zone.VehicleEvents ! MessageEnvelope(
|
||||
zoneChannel,
|
||||
VehicleAction.DeployRequest(GUID0, guid, state, 0, unk2=false, Vector3.Zero)
|
||||
VehicleAction.DeployRequest(guid, state, 0, unk2=false, Vector3.Zero)
|
||||
)
|
||||
state
|
||||
} else {
|
||||
|
|
@ -134,11 +133,10 @@ trait DeploymentBehavior {
|
|||
val guid = obj.GUID
|
||||
val zone = obj.Zone
|
||||
val zoneChannel = zone.id
|
||||
val GUID0 = Service.defaultPlayerGUID
|
||||
if (state == DriveState.Undeploying) {
|
||||
zone.VehicleEvents ! VehicleServiceMessage(
|
||||
zone.VehicleEvents ! MessageEnvelope(
|
||||
zoneChannel,
|
||||
VehicleAction.DeployRequest(GUID0, guid, state, 0, unk2=false, Vector3.Zero)
|
||||
VehicleAction.DeployRequest(guid, state, 0, unk2=false, Vector3.Zero)
|
||||
)
|
||||
import scala.concurrent.ExecutionContext.Implicits.global
|
||||
deploymentTimer.cancel()
|
||||
|
|
@ -147,9 +145,9 @@ trait DeploymentBehavior {
|
|||
})
|
||||
state
|
||||
} else if (state == DriveState.Mobile) {
|
||||
zone.VehicleEvents ! VehicleServiceMessage(
|
||||
zone.VehicleEvents ! MessageEnvelope(
|
||||
zoneChannel,
|
||||
VehicleAction.DeployRequest(GUID0, guid, state, 0, unk2=false, Vector3.Zero)
|
||||
VehicleAction.DeployRequest(guid, state, 0, unk2=false, Vector3.Zero)
|
||||
)
|
||||
state
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -14,8 +14,9 @@ import net.psforever.objects.vital.interaction.DamageInteraction
|
|||
import net.psforever.objects.vital.prop.DamageWithPosition
|
||||
import net.psforever.objects.zones.Zone
|
||||
import net.psforever.packet.game.ChatMsg
|
||||
import net.psforever.services.Service
|
||||
import net.psforever.services.local.{LocalAction, LocalServiceMessage}
|
||||
import net.psforever.services.base.envelope.{BundledEnvelope, MessageEnvelope}
|
||||
import net.psforever.services.base.message.SendResponse
|
||||
import net.psforever.services.local.LocalAction
|
||||
import net.psforever.types.{ChatMessageType, PlanetSideEmpire, PlanetSideGeneratorState, Vector3}
|
||||
|
||||
import scala.annotation.unused
|
||||
|
|
@ -45,9 +46,9 @@ object ForceDomeControl {
|
|||
val owner = dome.Owner
|
||||
val zone = owner.Zone
|
||||
owner.Actor ! BuildingActor.AmenityStateChange(dome)
|
||||
zone.LocalEvents ! LocalServiceMessage(
|
||||
zone.LocalEvents ! MessageEnvelope(
|
||||
zone.id,
|
||||
LocalAction.UpdateForceDomeStatus(Service.defaultPlayerGUID, owner.GUID, activationState)
|
||||
LocalAction.UpdateForceDomeStatus(owner.GUID, activationState)
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -124,11 +125,11 @@ object ForceDomeControl {
|
|||
state: Boolean
|
||||
): Unit = {
|
||||
val zone = building.Zone
|
||||
val message = LocalAction.SendResponse(ChatMsg(
|
||||
val message = SendResponse(ChatMsg(
|
||||
ChatMessageType.UNK_229,
|
||||
s"The Capitol force dome at ${building.Name} will remain ${if (state) "activated" else "deactivated"}."
|
||||
))
|
||||
zone.LocalEvents ! LocalServiceMessage(zone.id, message)
|
||||
zone.LocalEvents ! MessageEnvelope(zone.id, message)
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -138,13 +139,13 @@ object ForceDomeControl {
|
|||
*/
|
||||
def NormalDomeStateMessage(building: Building): Unit = {
|
||||
val events = building.Zone.LocalEvents
|
||||
val message = LocalAction.SendResponse(ChatMsg(
|
||||
val message = SendResponse(ChatMsg(
|
||||
ChatMessageType.UNK_227,
|
||||
"Expected capitol force dome state change will resume."
|
||||
))
|
||||
building.PlayersInSOI.foreach { player =>
|
||||
events ! LocalServiceMessage(player.Name, message)
|
||||
}
|
||||
events ! BundledEnvelope(building.PlayersInSOI.map { player =>
|
||||
MessageEnvelope(player.Name, message)
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -67,37 +67,10 @@ object Door {
|
|||
*/
|
||||
sealed trait Exchange
|
||||
|
||||
/**
|
||||
* Message that carries the result of the processed request message back to the original user (`player`).
|
||||
* @param player the player who sent this request message
|
||||
* @param msg the original packet carrying the request
|
||||
* @param response the result of the processed request
|
||||
*/
|
||||
final case class DoorMessage(player: Player, msg: UseItemMessage, response: Exchange)
|
||||
|
||||
/**
|
||||
* This door will open.
|
||||
*/
|
||||
final case class OpenEvent() extends Exchange
|
||||
|
||||
/**
|
||||
* This door will close.
|
||||
*/
|
||||
final case class CloseEvent() extends Exchange
|
||||
|
||||
/**
|
||||
* This door will do nothing.
|
||||
*/
|
||||
final case class NoEvent() extends Exchange
|
||||
|
||||
type LockingMechanismLogic = (PlanetSideServerObject, Door) => Boolean
|
||||
|
||||
final case class UpdateMechanism(mechanism: LockingMechanismLogic) extends Exchange
|
||||
|
||||
case object Lock extends Exchange
|
||||
|
||||
case object Unlock extends Exchange
|
||||
|
||||
/**
|
||||
* Overloaded constructor.
|
||||
* @param tdef the `ObjectDefinition` that constructs this object and maintains some of its immutable fields
|
||||
|
|
|
|||
|
|
@ -7,8 +7,10 @@ import net.psforever.objects.serverobject.{CommonMessages, PlanetSideServerObjec
|
|||
import net.psforever.objects.serverobject.affinity.{FactionAffinity, FactionAffinityBehavior}
|
||||
import net.psforever.objects.serverobject.locks.IFFLock
|
||||
import net.psforever.objects.serverobject.structures.PoweredAmenityControl
|
||||
import net.psforever.services.Service
|
||||
import net.psforever.services.local.{LocalAction, LocalResponse, LocalServiceMessage, LocalServiceResponse}
|
||||
import net.psforever.services.base.envelope.GenericResponseEnvelope
|
||||
import net.psforever.services.base.support.SupportActor
|
||||
import net.psforever.services.local.support.{DoorCloseActor, DoorMessage}
|
||||
import net.psforever.services.local.{LocalAction, LocalStamp}
|
||||
|
||||
/**
|
||||
* An `Actor` that handles messages being dispatched to a specific `Door`.
|
||||
|
|
@ -19,24 +21,21 @@ class DoorControl(door: Door)
|
|||
with FactionAffinityBehavior.Check {
|
||||
def FactionObject: FactionAffinity = door
|
||||
|
||||
private var isLocked: Boolean = false
|
||||
private var lockingMechanism: Door.LockingMechanismLogic = DoorControl.alwaysOpen
|
||||
|
||||
def commonBehavior: Receive = checkBehavior
|
||||
.orElse {
|
||||
case Door.Lock =>
|
||||
isLocked = true
|
||||
case Door.UpdateMechanism(logic) =>
|
||||
lockingMechanism = logic
|
||||
if (door.isOpen) {
|
||||
val zone = door.Zone
|
||||
door.Open = None
|
||||
zone.LocalEvents ! LocalServiceMessage(zone.id, LocalAction.DoorSlamsShut(door))
|
||||
zone.LocalEvents ! DoorMessage(
|
||||
zone.id,
|
||||
LocalAction.DoorCloses(door.GUID),
|
||||
SupportActor.ClearSpecific(List(door), zone)
|
||||
)
|
||||
}
|
||||
|
||||
case Door.Unlock =>
|
||||
isLocked = false
|
||||
|
||||
case Door.UpdateMechanism(logic) =>
|
||||
lockingMechanism = logic
|
||||
}
|
||||
|
||||
def poweredStateLogic: Receive =
|
||||
|
|
@ -48,7 +47,7 @@ class DoorControl(door: Door)
|
|||
case CommonMessages.Use(player, _) =>
|
||||
testToOpenDoor(player, door, door.Definition.initialOpeningDistance, sender())
|
||||
|
||||
case IFFLock.DoorOpenResponse(target: Player) if !isLocked =>
|
||||
case IFFLock.DoorOpenResponse(target: Player) =>
|
||||
DoorControl.openDoor(target, door)
|
||||
|
||||
case _ => ()
|
||||
|
|
@ -57,7 +56,7 @@ class DoorControl(door: Door)
|
|||
def unpoweredStateLogic: Receive = {
|
||||
commonBehavior
|
||||
.orElse {
|
||||
case CommonMessages.Use(player, _) if !isLocked =>
|
||||
case CommonMessages.Use(player, _) =>
|
||||
//without power, the door opens freely
|
||||
DoorControl.openDoor(player, door)
|
||||
|
||||
|
|
@ -83,7 +82,7 @@ class DoorControl(door: Door)
|
|||
): Unit = {
|
||||
if (
|
||||
Doors.testForSpecificTargetHoldingDoorOpen(player, door, maximumDistance * maximumDistance).contains(player) &&
|
||||
lockingMechanism(player, door) && !isLocked
|
||||
lockingMechanism(player, door)
|
||||
) {
|
||||
DoorControl.openDoor(player, door, replyTo)
|
||||
}
|
||||
|
|
@ -107,20 +106,21 @@ object DoorControl {
|
|||
*/
|
||||
private def openDoor(player: Player, door: Door, replyTo: ActorRef = Default.Actor): Unit = {
|
||||
val zone = door.Zone
|
||||
val doorGUID = door.GUID
|
||||
if (!door.isOpen) {
|
||||
//global open
|
||||
door.Open = player
|
||||
zone.LocalEvents ! LocalServiceMessage(
|
||||
zone.LocalEvents ! DoorMessage(
|
||||
zone.id,
|
||||
LocalAction.DoorOpens(Service.defaultPlayerGUID, zone, door)
|
||||
LocalAction.DoorOpens(zone, door),
|
||||
DoorCloseActor.DoorIsOpen(door, zone, System.currentTimeMillis())
|
||||
)
|
||||
} else {
|
||||
//the door should already open, but the requesting player does not see it as open
|
||||
replyTo ! LocalServiceResponse(
|
||||
replyTo ! GenericResponseEnvelope(
|
||||
LocalStamp,
|
||||
player.Name,
|
||||
Service.defaultPlayerGUID,
|
||||
LocalResponse.DoorOpens(doorGUID)
|
||||
Default.GUID0,
|
||||
LocalAction.DoorOpens(door.Zone, door)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,9 +12,9 @@ import net.psforever.objects.serverobject.terminals.{GeneratorTerminalDefinition
|
|||
import net.psforever.objects.vital.interaction.DamageResult
|
||||
import net.psforever.objects.zones.Zone
|
||||
import net.psforever.packet.game.TriggerEffectMessage
|
||||
import net.psforever.services.base.envelope.MessageEnvelope
|
||||
import net.psforever.types.{PlanetSideGeneratorState, Vector3}
|
||||
import net.psforever.services.Service
|
||||
import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage}
|
||||
import net.psforever.services.base.message.SendResponse
|
||||
|
||||
import scala.concurrent.duration._
|
||||
import scala.concurrent.ExecutionContext.Implicits.global
|
||||
|
|
@ -111,12 +111,9 @@ class GeneratorControl(gen: Generator)
|
|||
super.DestructionAwareness(gen, gen.LastDamage.get)
|
||||
GeneratorControl.UpdateOwner(gen, Some(GeneratorControl.Event.Destroyed))
|
||||
//kaboom
|
||||
zone.AvatarEvents ! AvatarServiceMessage(
|
||||
zone.AvatarEvents ! MessageEnvelope(
|
||||
zone.id,
|
||||
AvatarAction.SendResponse(
|
||||
Service.defaultPlayerGUID,
|
||||
TriggerEffectMessage(gen.GUID, "explosion_generator", None, None)
|
||||
)
|
||||
SendResponse(TriggerEffectMessage(gen.GUID, "explosion_generator", None, None))
|
||||
)
|
||||
queuedExplosion.cancel()
|
||||
queuedExplosion = Default.Cancellable
|
||||
|
|
|
|||
|
|
@ -11,9 +11,10 @@ import net.psforever.objects.serverobject.{CommonMessages, PlanetSideServerObjec
|
|||
import net.psforever.objects.zones.blockmap.BlockMapEntity
|
||||
import net.psforever.packet.game.{GenericObjectActionMessage, HackMessage, HackState, HackState1, HackState7, TriggeredSound}
|
||||
import net.psforever.types.{PlanetSideEmpire, PlanetSideGUID}
|
||||
import net.psforever.services.Service
|
||||
import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage}
|
||||
import net.psforever.services.local.{LocalAction, LocalServiceMessage}
|
||||
import net.psforever.services.base.envelope.MessageEnvelope
|
||||
import net.psforever.services.base.message.SendResponse
|
||||
import net.psforever.services.local.support.{HackClearActor, HackClearEnvelope, HackEntityEnvelope}
|
||||
import net.psforever.services.local.LocalAction
|
||||
|
||||
import scala.annotation.unused
|
||||
import scala.util.{Failure, Success}
|
||||
|
|
@ -88,10 +89,9 @@ object GenericHackables {
|
|||
} else {
|
||||
(HackState.Ongoing, progress.toInt)
|
||||
}
|
||||
target.Zone.AvatarEvents ! AvatarServiceMessage(
|
||||
target.Zone.AvatarEvents ! MessageEnvelope(
|
||||
hacker.Name,
|
||||
AvatarAction.SendResponse(
|
||||
Service.defaultPlayerGUID,
|
||||
SendResponse(
|
||||
HackMessage(progressType, target.GUID, hacker.GUID, progressGrade, 0L, progressState, HackState7.Unk8)
|
||||
)
|
||||
)
|
||||
|
|
@ -171,14 +171,17 @@ object GenericHackables {
|
|||
val zoneId = zone.id
|
||||
val pguid = tplayer.GUID
|
||||
log.info(s"${user.Name} hacked a ${target.Definition.Name}")
|
||||
zone.LocalEvents ! LocalServiceMessage(
|
||||
zone.LocalEvents ! MessageEnvelope(
|
||||
zoneId,
|
||||
LocalAction.TriggerSound(pguid, target.HackSound, tplayer.Position, 30, 0.49803925f)
|
||||
pguid,
|
||||
LocalAction.TriggerSound(target.HackSound, tplayer.Position, 30, 0.49803925f)
|
||||
)
|
||||
zone.LocalEvents ! LocalServiceMessage(
|
||||
val duration = target.HackEffectDuration(user.avatar.hackingSkillLevel())
|
||||
zone.LocalEvents ! HackEntityEnvelope(
|
||||
zoneId,
|
||||
LocalAction
|
||||
.HackTemporarily(pguid, zone, target, hackValue, hackClearValue, target.HackEffectDuration(user.avatar.hackingSkillLevel()))
|
||||
pguid,
|
||||
LocalAction.HackObject(target.GUID, hackValue, HackState7.Unk8),
|
||||
HackClearActor.ObjectIsHacked(target, zone, hackClearValue, HackState7.Unk8, duration)
|
||||
)
|
||||
case Failure(_) =>
|
||||
log.warn(s"Hack message failed on target: ${target.Definition.Name}@${target.GUID.guid}")
|
||||
|
|
@ -203,29 +206,19 @@ object GenericHackables {
|
|||
val currVirus = building.virusId
|
||||
building.virusId = 8
|
||||
building.virusInstalledBy = None
|
||||
zone.LocalEvents ! LocalServiceMessage(
|
||||
zoneId,
|
||||
LocalAction
|
||||
.ClearTemporaryHack(pguid, target)
|
||||
)
|
||||
zone.LocalEvents ! LocalServiceMessage(
|
||||
zone.LocalEvents ! HackClearEnvelope(HackClearActor.ObjectIsResecured(target))
|
||||
zone.LocalEvents ! MessageEnvelope(
|
||||
zone.id,
|
||||
LocalAction.SendResponse(GenericObjectActionMessage(target.GUID, 60))
|
||||
SendResponse(GenericObjectActionMessage(target.GUID, 60))
|
||||
)
|
||||
currVirus match {
|
||||
case 0L =>
|
||||
building.HackableAmenities.filter(d => d.Definition == GlobalDefinitions.lock_external).foreach { iff =>
|
||||
zone.LocalEvents ! LocalServiceMessage(
|
||||
zoneId,
|
||||
LocalAction.ClearTemporaryHack(PlanetSideGUID(0), iff)
|
||||
)
|
||||
zone.LocalEvents ! HackClearEnvelope(HackClearActor.ObjectIsResecured(iff))
|
||||
}
|
||||
case 4L =>
|
||||
building.HackableAmenities.filter(d => d.Definition == GlobalDefinitions.order_terminal).foreach { term =>
|
||||
zone.LocalEvents ! LocalServiceMessage(
|
||||
zoneId,
|
||||
LocalAction.ClearTemporaryHack(PlanetSideGUID(0), term)
|
||||
)
|
||||
zone.LocalEvents ! HackClearEnvelope(HackClearActor.ObjectIsResecured(term))
|
||||
}
|
||||
case _ => ()
|
||||
}
|
||||
|
|
@ -239,19 +232,13 @@ object GenericHackables {
|
|||
case 0L =>
|
||||
if (virus != 0) {
|
||||
building.HackableAmenities.filter(d => d.Definition == GlobalDefinitions.lock_external).foreach { iff =>
|
||||
zone.LocalEvents ! LocalServiceMessage(
|
||||
zoneId,
|
||||
LocalAction.ClearTemporaryHack(PlanetSideGUID(0), iff)
|
||||
)
|
||||
zone.LocalEvents ! HackClearEnvelope(HackClearActor.ObjectIsResecured(iff))
|
||||
}
|
||||
}
|
||||
case 4L =>
|
||||
if (virus != 4) {
|
||||
building.HackableAmenities.filter(d => d.Definition == GlobalDefinitions.order_terminal).foreach { term =>
|
||||
zone.LocalEvents ! LocalServiceMessage(
|
||||
zoneId,
|
||||
LocalAction.ClearTemporaryHack(PlanetSideGUID(0), term)
|
||||
)
|
||||
zone.LocalEvents ! HackClearEnvelope(HackClearActor.ObjectIsResecured(term))
|
||||
}
|
||||
}
|
||||
case _ => ()
|
||||
|
|
@ -274,42 +261,42 @@ object GenericHackables {
|
|||
val hackState = hackStateMap.getOrElse(virus, HackState7.Unk8)
|
||||
building.virusId = virus
|
||||
building.virusInstalledBy = Some(tplayer.Faction.id)
|
||||
zone.LocalEvents ! LocalServiceMessage(
|
||||
zone.LocalEvents ! MessageEnvelope(
|
||||
zoneId,
|
||||
LocalAction.TriggerSound(pguid, TriggeredSound.TREKSuccessful, tplayer.Position, 30, 0.49803925f)
|
||||
pguid,
|
||||
LocalAction.TriggerSound(TriggeredSound.TREKSuccessful, tplayer.Position, 30, 0.49803925f)
|
||||
)
|
||||
zone.LocalEvents ! LocalServiceMessage(
|
||||
zone.LocalEvents ! HackEntityEnvelope(
|
||||
zoneId,
|
||||
LocalAction
|
||||
.HackTemporarily(pguid, zone, target, installedVirusDuration, hackClearValue, installedVirusDuration, unk2=hackState)
|
||||
pguid,
|
||||
LocalAction.HackObject(target.GUID, installedVirusDuration.toLong, hackState),
|
||||
HackClearActor.ObjectIsHacked(target, zone, hackClearValue, hackState, installedVirusDuration)
|
||||
)
|
||||
zone.LocalEvents ! LocalServiceMessage(
|
||||
zone.LocalEvents ! MessageEnvelope(
|
||||
zone.id,
|
||||
LocalAction.SendResponse(GenericObjectActionMessage(target.GUID, 61))
|
||||
)
|
||||
zone.LocalEvents ! LocalServiceMessage(
|
||||
zone.id,
|
||||
LocalAction.SendResponse(GenericObjectActionMessage(target.GUID, 58))
|
||||
SendResponse(GenericObjectActionMessage(target.GUID, 61), GenericObjectActionMessage(target.GUID, 58))
|
||||
)
|
||||
//amenities if applicable
|
||||
virus match {
|
||||
case 0L =>
|
||||
building.HackableAmenities.filter(d => d.Definition == GlobalDefinitions.lock_external).foreach{ iff =>
|
||||
var setHacked = iff.asInstanceOf[PlanetSideServerObject with Hackable]
|
||||
setHacked.HackedBy = tplayer
|
||||
zone.LocalEvents ! LocalServiceMessage(
|
||||
zoneId,
|
||||
LocalAction.HackTemporarily(pguid, zone, iff, hackValue, hackClearValue, installedVirusDuration)
|
||||
)
|
||||
iff.HackedBy = tplayer
|
||||
zone.LocalEvents ! HackEntityEnvelope(
|
||||
zoneId,
|
||||
pguid,
|
||||
LocalAction.HackObject(target.GUID, hackValue.toLong, HackState7.Unk8),
|
||||
HackClearActor.ObjectIsHacked(target, zone, hackClearValue, HackState7.Unk8, installedVirusDuration)
|
||||
)
|
||||
}
|
||||
case 4L =>
|
||||
building.HackableAmenities.filter(d => d.Definition == GlobalDefinitions.order_terminal).foreach{ term =>
|
||||
var setHacked = term.asInstanceOf[PlanetSideServerObject with Hackable]
|
||||
setHacked.HackedBy = tplayer
|
||||
zone.LocalEvents ! LocalServiceMessage(
|
||||
zoneId,
|
||||
LocalAction.HackTemporarily(pguid, zone, term, hackValue, hackClearValue, installedVirusDuration)
|
||||
)
|
||||
term.HackedBy = tplayer
|
||||
zone.LocalEvents ! HackEntityEnvelope(
|
||||
zoneId,
|
||||
pguid,
|
||||
LocalAction.HackObject(term.GUID, hackValue.toLong, HackState7.Unk8),
|
||||
HackClearActor.ObjectIsHacked(target, zone, hackClearValue, HackState7.Unk8, installedVirusDuration)
|
||||
)
|
||||
}
|
||||
case _ => ()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,7 @@
|
|||
// Copyright (c) 2020 PSForever
|
||||
package net.psforever.objects.serverobject.locks
|
||||
|
||||
import net.psforever.services.Service
|
||||
import net.psforever.services.local.{LocalAction, LocalServiceMessage}
|
||||
import net.psforever.services.local.support.{HackClearActor, HackClearEnvelope}
|
||||
|
||||
object IFFLocks {
|
||||
|
||||
|
|
@ -14,9 +13,6 @@ object IFFLocks {
|
|||
*/
|
||||
def FinishResecuringIFFLock(lock: IFFLock)(): Unit = {
|
||||
val zone = lock.Zone
|
||||
lock.Zone.LocalEvents ! LocalServiceMessage(
|
||||
zone.id,
|
||||
LocalAction.ClearTemporaryHack(Service.defaultPlayerGUID, lock)
|
||||
)
|
||||
lock.Zone.LocalEvents ! HackClearEnvelope(HackClearActor.ObjectIsResecured(lock))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ import net.psforever.objects.sourcing.AmenitySource
|
|||
import net.psforever.objects.vital.TerminalUsedActivity
|
||||
import net.psforever.objects.zones.{Zone, ZoneAware, Zoning}
|
||||
import net.psforever.objects.{Default, PlanetSideGameObject, Player, Vehicle}
|
||||
import net.psforever.services.base.envelope.MessageEnvelope
|
||||
import net.psforever.types.{PlanetSideGUID, TransactionType, Vector3}
|
||||
|
||||
import scala.annotation.tailrec
|
||||
|
|
@ -128,7 +129,7 @@ class VehicleSpawnControl(pad: VehicleSpawnPad)
|
|||
}
|
||||
trackedOrder = None
|
||||
handleOrderFunc = NewTasking
|
||||
pad.Zone.VehicleEvents ! VehicleSpawnPad.ResetSpawnPad(pad) //cautious animation reset
|
||||
pad.Zone.VehicleEvents ! MessageEnvelope(pad.Zone.id, VehicleSpawnPad.ResetSpawnPad(pad)) //cautious animation reset
|
||||
self ! akka.actor.Kill //should cause the actor to restart, which will abort any trapped messages
|
||||
|
||||
case _ => ()
|
||||
|
|
@ -164,19 +165,17 @@ class VehicleSpawnControl(pad: VehicleSpawnPad)
|
|||
//first queued order
|
||||
orders = List(order)
|
||||
queueManagementTask()
|
||||
pad.Zone.VehicleEvents ! VehicleSpawnPad.PeriodicReminder(
|
||||
pad.Zone.VehicleEvents ! MessageEnvelope(
|
||||
name,
|
||||
VehicleSpawnPad.Reminders.Queue,
|
||||
Some(s"@SVCP_PositionInQueue^2~^2~")
|
||||
VehicleSpawnPad.PeriodicReminder(VehicleSpawnPad.Reminders.Queue, Some(s"@SVCP_PositionInQueue^2~^2~"))
|
||||
)
|
||||
case -1 =>
|
||||
//new order
|
||||
orders = orders :+ order
|
||||
val size = orders.size + 1
|
||||
pad.Zone.VehicleEvents ! VehicleSpawnPad.PeriodicReminder(
|
||||
pad.Zone.VehicleEvents ! MessageEnvelope(
|
||||
name,
|
||||
VehicleSpawnPad.Reminders.Queue,
|
||||
Some(s"@SVCP_PositionInQueue^$size~^$size~")
|
||||
VehicleSpawnPad.PeriodicReminder(VehicleSpawnPad.Reminders.Queue, Some(s"@SVCP_PositionInQueue^$size~^$size~"))
|
||||
)
|
||||
case n if orders(n).vehicle.Definition ne order.vehicle.Definition =>
|
||||
//replace existing order with new order
|
||||
|
|
@ -185,10 +184,9 @@ class VehicleSpawnControl(pad: VehicleSpawnPad)
|
|||
val originalVehicle = originalOrder.vehicle.Definition.Name
|
||||
orders = (orders.take(n) :+ order) ++ orders.drop(n+1)
|
||||
VehicleSpawnControl.DisposeVehicle(originalOrder.vehicle, zone)
|
||||
zone.VehicleEvents ! VehicleSpawnPad.PeriodicReminder(
|
||||
zone.VehicleEvents ! MessageEnvelope(
|
||||
name,
|
||||
VehicleSpawnPad.Reminders.Queue,
|
||||
Some(s"@SVCP_ReplacedVehicleWithVehicle^@$originalVehicle~^@${order.vehicle.Definition.Name}~")
|
||||
VehicleSpawnPad.PeriodicReminder(VehicleSpawnPad.Reminders.Queue, Some(s"@SVCP_ReplacedVehicleWithVehicle^@$originalVehicle~^@${order.vehicle.Definition.Name}~"))
|
||||
)
|
||||
case _ =>
|
||||
//order is the duplicate of an existing order; do nothing to the queue
|
||||
|
|
@ -245,10 +243,9 @@ class VehicleSpawnControl(pad: VehicleSpawnPad)
|
|||
val newOrder = VehicleSpawnControl.Order(driver, vehicle)
|
||||
recursiveOrderReminder(orders.iterator, size)
|
||||
trace(s"processing next order - a ${vehicle.Definition.Name} for $name")
|
||||
pad.Zone.VehicleEvents ! VehicleSpawnPad.PeriodicReminder(
|
||||
pad.Zone.VehicleEvents ! MessageEnvelope(
|
||||
name,
|
||||
VehicleSpawnPad.Reminders.Queue,
|
||||
Some(s"@SVCP_PositionInQueue^1~^$size~")
|
||||
VehicleSpawnPad.PeriodicReminder(VehicleSpawnPad.Reminders.Queue, Some(s"@SVCP_PositionInQueue^1~^$size~"))
|
||||
)
|
||||
trackedOrder = Some(newOrder) //guard on
|
||||
context.system.scheduler.scheduleOnce(2000 milliseconds, concealPlayer, newOrder)
|
||||
|
|
@ -324,7 +321,10 @@ class VehicleSpawnControl(pad: VehicleSpawnPad)
|
|||
private def CancelOrder(vehicle: Vehicle, player: Player, msg: Option[String]): Unit = {
|
||||
if (vehicle.Seats.values.count(_.isOccupied) == 0) {
|
||||
VehicleSpawnControl.DisposeSpawnedVehicle(vehicle, player, pad.Zone)
|
||||
pad.Zone.VehicleEvents ! VehicleSpawnPad.PeriodicReminder(player.Name, VehicleSpawnPad.Reminders.Cancelled, msg)
|
||||
pad.Zone.VehicleEvents ! MessageEnvelope(
|
||||
player.Name,
|
||||
VehicleSpawnPad.PeriodicReminder(VehicleSpawnPad.Reminders.Cancelled, msg)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -451,10 +451,9 @@ class VehicleSpawnControl(pad: VehicleSpawnPad)
|
|||
entry: VehicleSpawnPad.VehicleOrder,
|
||||
cause: Option[Any]
|
||||
): Unit = {
|
||||
pad.Zone.VehicleEvents ! VehicleSpawnPad.PeriodicReminder(
|
||||
pad.Zone.VehicleEvents ! MessageEnvelope(
|
||||
entry.player.Name,
|
||||
VehicleSpawnPad.Reminders.Blocked,
|
||||
cause
|
||||
VehicleSpawnPad.PeriodicReminder(VehicleSpawnPad.Reminders.Blocked, cause)
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -465,10 +464,9 @@ class VehicleSpawnControl(pad: VehicleSpawnPad)
|
|||
): Unit = {
|
||||
if (iter.hasNext) {
|
||||
val recipient = iter.next()
|
||||
pad.Zone.VehicleEvents ! VehicleSpawnPad.PeriodicReminder(
|
||||
pad.Zone.VehicleEvents ! MessageEnvelope(
|
||||
recipient.player.Name,
|
||||
VehicleSpawnPad.Reminders.Queue,
|
||||
Some(s"@SVCP_PositionInQueue^$position~^$size~")
|
||||
VehicleSpawnPad.PeriodicReminder(VehicleSpawnPad.Reminders.Queue, Some(s"@SVCP_PositionInQueue^$position~^$size~"))
|
||||
)
|
||||
recursiveOrderReminder(iter, size, position + 1)
|
||||
}
|
||||
|
|
@ -564,7 +562,7 @@ object VehicleSpawnControl {
|
|||
*/
|
||||
private def DisposeSpawnedVehicle(vehicle: Vehicle, player: Player, zone: Zone): Unit = {
|
||||
DisposeVehicle(vehicle, zone)
|
||||
zone.VehicleEvents ! VehicleSpawnPad.RevealPlayer(player.GUID)
|
||||
zone.VehicleEvents ! MessageEnvelope(zone.id, VehicleSpawnPad.RevealPlayer(player.GUID))
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import net.psforever.objects.serverobject.interior.Sidedness
|
|||
import net.psforever.objects.{Player, Vehicle}
|
||||
import net.psforever.objects.serverobject.structures.Amenity
|
||||
import net.psforever.objects.serverobject.terminals.Terminal
|
||||
import net.psforever.services.base.message.SelfRespondingEvent
|
||||
import net.psforever.types.PlanetSideGUID
|
||||
|
||||
/**
|
||||
|
|
@ -25,7 +26,6 @@ class VehicleSpawnPad(spDef: VehicleSpawnPadDefinition) extends Amenity {
|
|||
}
|
||||
|
||||
object VehicleSpawnPad {
|
||||
|
||||
/**
|
||||
* Message to the spawn pad to enqueue the following vehicle order.
|
||||
* This is the entry point to vehicle spawn pad functionality.
|
||||
|
|
@ -39,14 +39,14 @@ object VehicleSpawnPad {
|
|||
* @see `GenericObjectActionMessage`
|
||||
* @param player_guid the player
|
||||
*/
|
||||
final case class ConcealPlayer(player_guid: PlanetSideGUID)
|
||||
final case class ConcealPlayer(player_guid: PlanetSideGUID) extends SelfRespondingEvent
|
||||
|
||||
/**
|
||||
* Message is intended to undo the effects of the above message, `ConcealPlayer`.
|
||||
* @see `ConcealPlayer`
|
||||
* @param player_guid the player
|
||||
*/
|
||||
final case class RevealPlayer(player_guid: PlanetSideGUID)
|
||||
final case class RevealPlayer(player_guid: PlanetSideGUID) extends SelfRespondingEvent
|
||||
|
||||
/**
|
||||
* Message to attach the vehicle to the spawn pad's lifting platform ("put on rails").
|
||||
|
|
@ -55,7 +55,7 @@ object VehicleSpawnPad {
|
|||
* @param vehicle the vehicle being spawned
|
||||
* @param pad the spawn pad
|
||||
*/
|
||||
final case class AttachToRails(vehicle: Vehicle, pad: VehicleSpawnPad)
|
||||
final case class AttachToRails(vehicle: Vehicle, pad: VehicleSpawnPad) extends SelfRespondingEvent
|
||||
|
||||
/**
|
||||
* Message to detach the vehicle from the spawn pad's lifting platform ("put on rails").
|
||||
|
|
@ -63,72 +63,64 @@ object VehicleSpawnPad {
|
|||
* @param vehicle the vehicle being spawned
|
||||
* @param pad the spawn pad
|
||||
*/
|
||||
final case class DetachFromRails(vehicle: Vehicle, pad: VehicleSpawnPad)
|
||||
final case class DetachFromRails(vehicle: Vehicle, pad: VehicleSpawnPad) extends SelfRespondingEvent
|
||||
|
||||
/**
|
||||
* Message that resets the spawn pad for its next order fulfillment operation by lowering the lifting platform.
|
||||
* @see `GenericObjectActionMessage`
|
||||
* @param pad the spawn pad
|
||||
*/
|
||||
final case class ResetSpawnPad(pad: VehicleSpawnPad)
|
||||
final case class ResetSpawnPad(pad: VehicleSpawnPad) extends SelfRespondingEvent
|
||||
|
||||
/**
|
||||
* Message that acts as callback to the driver that the process of sitting in the driver mount will be initiated soon.
|
||||
* This information should only be communicated to the driver's client only.
|
||||
* @param driver_name the person who will drive the vehicle
|
||||
* @param vehicle the vehicle being spawned
|
||||
* @param pad the spawn pad
|
||||
*/
|
||||
final case class StartPlayerSeatedInVehicle(driver_name: String, vehicle: Vehicle, pad: VehicleSpawnPad)
|
||||
final case class StartPlayerSeatedInVehicle(vehicle: Vehicle, pad: VehicleSpawnPad) extends SelfRespondingEvent
|
||||
|
||||
/**
|
||||
* Message that acts as callback to the driver that the process of sitting in the driver mount should be finished.
|
||||
* This information should only be communicated to the driver's client only.
|
||||
* @param driver_name the person who will drive the vehicle
|
||||
* @param vehicle the vehicle being spawned
|
||||
* @param pad the spawn pad
|
||||
*/
|
||||
final case class PlayerSeatedInVehicle(
|
||||
driver_name: String,
|
||||
vehicle: Vehicle,
|
||||
pad: VehicleSpawnPad
|
||||
) //TODO while using fake rails
|
||||
//TODO while using fake rails (later edit: what does this mean?)
|
||||
final case class PlayerSeatedInVehicle(vehicle: Vehicle, pad: VehicleSpawnPad) extends SelfRespondingEvent
|
||||
|
||||
/**
|
||||
* Message that starts the newly-spawned vehicle to begin driving away from the spawn pad.
|
||||
* Information about the driving process is available on the vehicle itself.
|
||||
* This information should only be communicated to the driver's client only.
|
||||
* @see `VehicleDefinition`
|
||||
* @param driver_name the person who will drive the vehicle
|
||||
* @param vehicle the vehicle
|
||||
* @param pad the spawn pad
|
||||
*/
|
||||
final case class ServerVehicleOverrideStart(driver_name: String, vehicle: Vehicle, pad: VehicleSpawnPad)
|
||||
final case class ServerVehicleOverrideStart(vehicle: Vehicle, pad: VehicleSpawnPad) extends SelfRespondingEvent
|
||||
|
||||
/**
|
||||
* Message that transitions the newly-spawned vehicle into a cancellable auto-drive state.
|
||||
* Information about the driving process is available on the vehicle itself.
|
||||
* This information should only be communicated to the driver's client only.
|
||||
* @see `VehicleDefinition`
|
||||
* @param driver_name the person who will drive the vehicle
|
||||
* @param vehicle the vehicle
|
||||
* @param pad the spawn pad
|
||||
*/
|
||||
final case class ServerVehicleOverrideEnd(driver_name: String, vehicle: Vehicle, pad: VehicleSpawnPad)
|
||||
final case class ServerVehicleOverrideEnd(vehicle: Vehicle, pad: VehicleSpawnPad) extends SelfRespondingEvent
|
||||
|
||||
/**
|
||||
* Message to initiate the process of properly disposing of the vehicle that may have been or was spawned into the game world.
|
||||
* @param vehicle the vehicle
|
||||
*/
|
||||
final case class DisposeVehicle(vehicle: Vehicle)
|
||||
final case class DisposeVehicle(vehicle: Vehicle) extends SelfRespondingEvent
|
||||
|
||||
/**
|
||||
* Message to send targeted messages to the clients of specific users.
|
||||
* @param driver_name the person who will drive the vehicle
|
||||
* @param reason the nature of the message
|
||||
* @param data optional information for rendering the message to the client
|
||||
*/
|
||||
final case class PeriodicReminder(driver_name: String, reason: Reminders.Value, data: Option[Any] = None)
|
||||
final case class PeriodicReminder(reason: Reminders.Value, data: Option[Any] = None) extends SelfRespondingEvent
|
||||
|
||||
/**
|
||||
* An `Enumeration` of reasons for sending a periodic reminder to the user.
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ package net.psforever.objects.serverobject.pad.process
|
|||
|
||||
import akka.actor.Props
|
||||
import net.psforever.objects.serverobject.pad.{VehicleSpawnControl, VehicleSpawnPad}
|
||||
import net.psforever.services.base.envelope.MessageEnvelope
|
||||
|
||||
import scala.concurrent.ExecutionContext.Implicits.global
|
||||
import scala.concurrent.duration._
|
||||
|
|
@ -28,7 +29,7 @@ class VehicleSpawnControlConcealPlayer(pad: VehicleSpawnPad) extends VehicleSpaw
|
|||
case order @ VehicleSpawnControl.Order(driver, vehicle) =>
|
||||
if (VehicleSpawnControl.validateOrderCredentials(pad, driver, vehicle).isEmpty) {
|
||||
trace(s"hiding ${driver.Name}")
|
||||
pad.Zone.VehicleEvents ! VehicleSpawnPad.ConcealPlayer(driver.GUID)
|
||||
pad.Zone.VehicleEvents ! MessageEnvelope(pad.Zone.id, VehicleSpawnPad.ConcealPlayer(driver.GUID))
|
||||
context.system.scheduler.scheduleOnce(2000 milliseconds, loadVehicle, order)
|
||||
} else {
|
||||
trace(s"integral component lost; abort order fulfillment")
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ package net.psforever.objects.serverobject.pad.process
|
|||
|
||||
import akka.actor.Props
|
||||
import net.psforever.objects.serverobject.pad.{VehicleSpawnControl, VehicleSpawnPad}
|
||||
import net.psforever.services.base.envelope.MessageEnvelope
|
||||
|
||||
/**
|
||||
* An `Actor` that handles vehicle spawning orders for a `VehicleSpawnPad`.
|
||||
|
|
@ -24,7 +25,7 @@ class VehicleSpawnControlDriverControl(pad: VehicleSpawnPad) extends VehicleSpaw
|
|||
case order @ VehicleSpawnControl.Order(driver, vehicle) =>
|
||||
trace(s"returning control of ${vehicle.Definition.Name} to its current driver")
|
||||
if (vehicle.PassengerInSeat(driver).nonEmpty) {
|
||||
pad.Zone.VehicleEvents ! VehicleSpawnPad.ServerVehicleOverrideEnd(driver.Name, vehicle, pad)
|
||||
pad.Zone.VehicleEvents ! MessageEnvelope(driver.Name, VehicleSpawnPad.ServerVehicleOverrideEnd(vehicle, pad))
|
||||
}
|
||||
finalClear ! order
|
||||
|
||||
|
|
|
|||
|
|
@ -4,8 +4,9 @@ package net.psforever.objects.serverobject.pad.process
|
|||
import akka.actor.Cancellable
|
||||
import net.psforever.objects.Default
|
||||
import net.psforever.objects.serverobject.pad.{VehicleSpawnControl, VehicleSpawnPad}
|
||||
import net.psforever.types.{PlanetSideGUID, Vector3}
|
||||
import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage}
|
||||
import net.psforever.services.base.envelope.MessageEnvelope
|
||||
import net.psforever.types.Vector3
|
||||
import net.psforever.services.vehicle.VehicleAction
|
||||
|
||||
import scala.concurrent.ExecutionContext.Implicits.global
|
||||
import scala.concurrent.duration._
|
||||
|
|
@ -35,15 +36,9 @@ class VehicleSpawnControlFinalClearance(pad: VehicleSpawnPad) extends VehicleSpa
|
|||
//ensure the vacant vehicle is above the trench and the doors
|
||||
vehicle.Position = pad.Position + Vector3.z(pad.Definition.VehicleCreationZOffset)
|
||||
val definition = vehicle.Definition
|
||||
pad.Zone.VehicleEvents ! VehicleServiceMessage(
|
||||
pad.Zone.VehicleEvents ! MessageEnvelope(
|
||||
s"${pad.Continent}",
|
||||
VehicleAction.LoadVehicle(
|
||||
PlanetSideGUID(0),
|
||||
vehicle,
|
||||
definition.ObjectId,
|
||||
vehicle.GUID,
|
||||
definition.Packet.ConstructorData(vehicle).get
|
||||
)
|
||||
VehicleAction.LoadVehicle(vehicle, definition.ObjectId, vehicle.GUID, definition.Packet.ConstructorData(vehicle).get)
|
||||
)
|
||||
}
|
||||
context.parent ! VehicleSpawnControl.ProcessControl.Reminder
|
||||
|
|
@ -70,7 +65,7 @@ class VehicleSpawnControlFinalClearance(pad: VehicleSpawnPad) extends VehicleSpa
|
|||
}
|
||||
|
||||
case VehicleSpawnControlFinalClearance.NextOrder =>
|
||||
pad.Zone.VehicleEvents ! VehicleSpawnPad.ResetSpawnPad(pad)
|
||||
pad.Zone.VehicleEvents ! MessageEnvelope(pad.Zone.id, VehicleSpawnPad.ResetSpawnPad(pad))
|
||||
context.parent ! VehicleSpawnControl.ProcessControl.GetNewOrder
|
||||
|
||||
case _ => ()
|
||||
|
|
|
|||
|
|
@ -7,8 +7,8 @@ import akka.util.Timeout
|
|||
import net.psforever.objects.GlobalDefinitions
|
||||
import net.psforever.objects.serverobject.pad.{VehicleSpawnControl, VehicleSpawnPad}
|
||||
import net.psforever.objects.zones.Zone
|
||||
import net.psforever.services.Service
|
||||
import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage}
|
||||
import net.psforever.services.base.envelope.MessageEnvelope
|
||||
import net.psforever.services.vehicle.VehicleAction
|
||||
import net.psforever.types.Vector3
|
||||
import net.psforever.zones.Zones
|
||||
|
||||
|
|
@ -68,9 +68,9 @@ class VehicleSpawnControlLoadVehicle(pad: VehicleSpawnPad) extends VehicleSpawnC
|
|||
val vtype = definition.ObjectId
|
||||
val vguid = v.GUID
|
||||
val vdata = definition.Packet.ConstructorData(v).get
|
||||
zone.VehicleEvents ! VehicleServiceMessage(
|
||||
zone.VehicleEvents ! MessageEnvelope(
|
||||
zone.id,
|
||||
VehicleAction.LoadVehicle(Service.defaultPlayerGUID, v, vtype, vguid, vdata)
|
||||
VehicleAction.LoadVehicle(v, vtype, vguid, vdata)
|
||||
)
|
||||
railJack ! temp.get
|
||||
temp = None
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ import net.psforever.objects.vital.interaction.{DamageInteraction, DamageResult}
|
|||
import net.psforever.objects.vital.prop.DamageProperties
|
||||
import net.psforever.objects.vital.Vitality
|
||||
import net.psforever.objects.zones.Zone
|
||||
import net.psforever.services.base.envelope.MessageEnvelope
|
||||
|
||||
import scala.concurrent.ExecutionContext.Implicits.global
|
||||
import scala.concurrent.duration._
|
||||
|
|
@ -40,7 +41,7 @@ class VehicleSpawnControlRailJack(pad: VehicleSpawnPad) extends VehicleSpawnCont
|
|||
pad.Definition.killBox(pad, vehicle.Definition.CanFly),
|
||||
Zone.findAllTargets
|
||||
)
|
||||
pad.Zone.VehicleEvents ! VehicleSpawnPad.AttachToRails(vehicle, pad)
|
||||
pad.Zone.VehicleEvents ! MessageEnvelope(pad.Zone.id, VehicleSpawnPad.AttachToRails(vehicle, pad))
|
||||
context.system.scheduler.scheduleOnce(10 milliseconds, seatDriver, order)
|
||||
|
||||
case msg @ (VehicleSpawnControl.ProcessControl.Reminder | VehicleSpawnControl.ProcessControl.GetNewOrder) =>
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ package net.psforever.objects.serverobject.pad.process
|
|||
import akka.actor.{ActorRef, Props}
|
||||
import net.psforever.objects.{Default, Vehicle}
|
||||
import net.psforever.objects.serverobject.pad.{VehicleSpawnControl, VehicleSpawnPad}
|
||||
import net.psforever.services.base.envelope.MessageEnvelope
|
||||
|
||||
import scala.concurrent.ExecutionContext.Implicits.global
|
||||
import scala.concurrent.duration._
|
||||
|
|
@ -46,7 +47,7 @@ class VehicleSpawnControlSeatDriver(pad: VehicleSpawnPad) extends VehicleSpawnCo
|
|||
vehicle.Actor ! Vehicle.Deconstruct(Some(pad.Definition.VehicleCreationDeconstructTime.seconds))
|
||||
if (VehicleSpawnControl.validateOrderCredentials(pad, driver, vehicle).isEmpty) {
|
||||
trace("driver to be made seated in vehicle")
|
||||
pad.Zone.VehicleEvents ! VehicleSpawnPad.StartPlayerSeatedInVehicle(driver.Name, vehicle, pad)
|
||||
pad.Zone.VehicleEvents ! MessageEnvelope(driver.Name, VehicleSpawnPad.StartPlayerSeatedInVehicle(vehicle, pad))
|
||||
} else {
|
||||
trace("driver lost; vehicle stranded on pad")
|
||||
}
|
||||
|
|
@ -58,7 +59,7 @@ class VehicleSpawnControlSeatDriver(pad: VehicleSpawnPad) extends VehicleSpawnCo
|
|||
if (VehicleSpawnControl.validateOrderCredentials(pad, driver, vehicle).isEmpty &&
|
||||
entry.vehicle.PassengerInSeat(entry.driver).contains(0)) {
|
||||
trace(s"driver ${entry.driver.Name} has taken the wheel")
|
||||
pad.Zone.VehicleEvents ! VehicleSpawnPad.PlayerSeatedInVehicle(entry.driver.Name, entry.vehicle, pad)
|
||||
pad.Zone.VehicleEvents ! MessageEnvelope(entry.driver.Name, VehicleSpawnPad.PlayerSeatedInVehicle(entry.vehicle, pad))
|
||||
} else {
|
||||
trace("driver lost, but operations can continue")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ package net.psforever.objects.serverobject.pad.process
|
|||
|
||||
import akka.actor.Props
|
||||
import net.psforever.objects.serverobject.pad.{VehicleSpawnControl, VehicleSpawnPad}
|
||||
import net.psforever.services.base.envelope.MessageEnvelope
|
||||
import net.psforever.types.Vector3
|
||||
|
||||
import scala.concurrent.ExecutionContext.Implicits.global
|
||||
|
|
@ -31,18 +32,18 @@ class VehicleSpawnControlServerVehicleOverride(pad: VehicleSpawnPad) extends Veh
|
|||
val driverFailState =
|
||||
!driver.isAlive || driver.Continent != pad.Continent || !vehicle.PassengerInSeat(driver).contains(0)
|
||||
vehicle.MountedIn = None
|
||||
pad.Zone.VehicleEvents ! VehicleSpawnPad.DetachFromRails(vehicle, pad)
|
||||
pad.Zone.VehicleEvents ! MessageEnvelope(pad.Zone.id, VehicleSpawnPad.DetachFromRails(vehicle, pad))
|
||||
if (vehicleFailState || driverFailState) {
|
||||
if (vehicleFailState) {
|
||||
trace(s"vehicle was already destroyed")
|
||||
} else {
|
||||
trace(s"driver is not ready")
|
||||
}
|
||||
pad.Zone.VehicleEvents ! VehicleSpawnPad.RevealPlayer(order.DriverGUID)
|
||||
pad.Zone.VehicleEvents ! MessageEnvelope(pad.Zone.id, VehicleSpawnPad.RevealPlayer(order.DriverGUID))
|
||||
driverControl ! order
|
||||
} else {
|
||||
trace(s"telling ${driver.Name} that the server is assuming control of the ${vehicle.Definition.Name}")
|
||||
pad.Zone.VehicleEvents ! VehicleSpawnPad.ServerVehicleOverrideStart(driver.Name, vehicle, pad)
|
||||
pad.Zone.VehicleEvents ! MessageEnvelope(driver.Name, VehicleSpawnPad.ServerVehicleOverrideStart(vehicle, pad))
|
||||
context.system.scheduler.scheduleOnce(4000 milliseconds, driverControl, order)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@ class PainboxControl(painbox: Painbox) extends PoweredAmenityControl {
|
|||
}
|
||||
|
||||
var commonBehavior: Receive = {
|
||||
case Service.Startup() =>
|
||||
case Service.Startup =>
|
||||
if (!disabled && domain.midpoint == Vector3.Zero) {
|
||||
initialStartup()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,9 @@ import net.psforever.objects.Tool
|
|||
import net.psforever.objects.serverobject.structures.Amenity
|
||||
import net.psforever.objects.sourcing.{SourceEntry, SourceWithHealthEntry}
|
||||
import net.psforever.objects.vital.{DamagingActivity, RepairFromEquipment, SpawningActivity}
|
||||
import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage}
|
||||
import net.psforever.packet.game.PlanetsideAttributeMessage
|
||||
import net.psforever.services.base.envelope.MessageEnvelope
|
||||
import net.psforever.services.base.message.SendResponse
|
||||
|
||||
/**
|
||||
* The "control" `Actor` mixin for repair-handling code
|
||||
|
|
@ -27,8 +29,7 @@ object RepairableAmenity {
|
|||
/**
|
||||
* A restored `Amenity` target dispatches two messages to chance its model and operational states.
|
||||
* These `PlanetSideAttributeMessage` attributes are the same as reported during zone load client configuration.
|
||||
* @see `AvatarAction.PlanetsideAttributeToAll`
|
||||
* @see `AvatarServiceMessage`
|
||||
* @see `PlanetsideAttribute`
|
||||
* @see `Zone.AvatarEvents`
|
||||
* @param target the entity being destroyed
|
||||
*/
|
||||
|
|
@ -37,8 +38,10 @@ object RepairableAmenity {
|
|||
val zoneId = zone.id
|
||||
val events = zone.AvatarEvents
|
||||
val targetGUID = target.GUID
|
||||
events ! AvatarServiceMessage(zoneId, AvatarAction.PlanetsideAttributeToAll(targetGUID, 50, 0))
|
||||
events ! AvatarServiceMessage(zoneId, AvatarAction.PlanetsideAttributeToAll(targetGUID, 51, 0))
|
||||
events ! MessageEnvelope(
|
||||
zoneId,
|
||||
SendResponse(PlanetsideAttributeMessage(targetGUID, 50, 0), PlanetsideAttributeMessage(targetGUID, 51, 0))
|
||||
)
|
||||
RestorationOfHistory(target)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -8,8 +8,8 @@ import net.psforever.objects.vital.RepairFromEquipment
|
|||
import net.psforever.objects.{Player, Tool}
|
||||
import net.psforever.packet.game.{ChatMsg, InventoryStateMessage, RepairMessage}
|
||||
import net.psforever.types.{ChatMessageType, PlanetSideEmpire, Vector3}
|
||||
import net.psforever.services.Service
|
||||
import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage}
|
||||
import net.psforever.services.base.envelope.MessageEnvelope
|
||||
import net.psforever.services.base.message.{PlanetsideAttribute, SendResponse}
|
||||
|
||||
/**
|
||||
* The "control" `Actor` mixin for repair-handling code,
|
||||
|
|
@ -67,13 +67,13 @@ trait RepairableEntity extends Repairable {
|
|||
* Calculate the health points change and enact that repair action if the targets are stationary.
|
||||
* Restore the target entity to a not destroyed state if applicable.
|
||||
* Always show the repair progress bar window by using the appropriate packet.
|
||||
* @see `AvatarAction.PlanetsideAttributeToAll`
|
||||
* @see `AvatarAction.SendResponse`
|
||||
* @see `PlanetsideAttribute`
|
||||
* @see `SendResponse`
|
||||
* @see `AvatarService`
|
||||
* @see `InventoryStateMessage`
|
||||
* @see `PlanetSideGameObject.isMoving`
|
||||
* @see `RepairMessage`
|
||||
* @see `Service.defaultPlayerGUID`
|
||||
* @see `Default.GUID0`
|
||||
* @see `Tool.Discharge`
|
||||
* @see `Zone.AvatarEvents`
|
||||
* @param target the entity being repaired
|
||||
|
|
@ -89,12 +89,9 @@ trait RepairableEntity extends Repairable {
|
|||
if (!(player.isMoving(test = 1f) || target.isMoving(test = 1f))) { //only allow stationary repairs within margin of error
|
||||
val repairValue = Repairable.applyLevelModifier(player, item, RepairToolValue(item)).toInt + target.Definition.RepairMod
|
||||
val magazine = item.Discharge()
|
||||
events ! AvatarServiceMessage(
|
||||
events ! MessageEnvelope(
|
||||
player.Name,
|
||||
AvatarAction.SendResponse(
|
||||
Service.defaultPlayerGUID,
|
||||
InventoryStateMessage(item.AmmoSlot.Box.GUID, item.GUID, magazine.toLong)
|
||||
)
|
||||
SendResponse(InventoryStateMessage(item.AmmoSlot.Box.GUID, item.GUID, magazine.toLong))
|
||||
)
|
||||
target.LogActivity(
|
||||
RepairFromEquipment(
|
||||
|
|
@ -108,12 +105,9 @@ trait RepairableEntity extends Repairable {
|
|||
originalHealth
|
||||
}
|
||||
//progress bar remains visible
|
||||
events ! AvatarServiceMessage(
|
||||
events ! MessageEnvelope(
|
||||
name,
|
||||
AvatarAction.SendResponse(
|
||||
Service.defaultPlayerGUID,
|
||||
RepairMessage(target.GUID, updatedHealth * 100 / definition.MaxHealth)
|
||||
)
|
||||
SendResponse(RepairMessage(target.GUID, updatedHealth * 100 / definition.MaxHealth))
|
||||
)
|
||||
//if vehicle and vehicle is owned by another player, send repair chat message to the vehicle's owner
|
||||
if (target.Zone.Vehicles.exists(_.GUID == target.GUID)) {
|
||||
|
|
@ -146,11 +140,11 @@ trait RepairableEntity extends Repairable {
|
|||
val newHealth = target.Health = target.Health + amount
|
||||
if (target.Destroyed) {
|
||||
if (newHealth >= target.Definition.RepairRestoresAt) {
|
||||
events ! AvatarServiceMessage(zoneId, AvatarAction.PlanetsideAttributeToAll(tguid, 0, newHealth))
|
||||
events ! MessageEnvelope(zoneId, PlanetsideAttribute(tguid, 0, newHealth))
|
||||
Restoration(target)
|
||||
}
|
||||
} else {
|
||||
events ! AvatarServiceMessage(zoneId, AvatarAction.PlanetsideAttributeToAll(tguid, 0, newHealth))
|
||||
events ! MessageEnvelope(zoneId, PlanetsideAttribute(tguid, 0, newHealth))
|
||||
}
|
||||
newHealth
|
||||
}
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue