diff --git a/src/main/scala/net/psforever/actors/session/support/SessionAvatarHandlers.scala b/src/main/scala/net/psforever/actors/session/support/SessionAvatarHandlers.scala index 1dc8c616..6c9f9ea0 100644 --- a/src/main/scala/net/psforever/actors/session/support/SessionAvatarHandlers.scala +++ b/src/main/scala/net/psforever/actors/session/support/SessionAvatarHandlers.scala @@ -425,12 +425,14 @@ class SessionAvatarHandlers( sessionData.zoning.zoningStatus = Zoning.Status.None sessionData.zoning.spawn.deadState = DeadState.Dead continent.GUID(mount).collect { case obj: Vehicle => - sessionData.vehicles.DriverVehicleControl(obj) + sessionData.vehicles.ConditionalDriverVehicleControl(obj) sessionData.unaccessContainer(obj) } sessionData.playerActionsToCancel() sessionData.terminals.CancelAllProximityUnits() + sessionData.zoning AvatarActor.savePlayerLocation(player) + sessionData.zoning.spawn.shiftPosition = Some(player.Position) //respawn val respawnTimer = 300.seconds diff --git a/src/main/scala/net/psforever/actors/session/support/SessionVehicleHandlers.scala b/src/main/scala/net/psforever/actors/session/support/SessionVehicleHandlers.scala index 96c5b23f..fb06acc1 100644 --- a/src/main/scala/net/psforever/actors/session/support/SessionVehicleHandlers.scala +++ b/src/main/scala/net/psforever/actors/session/support/SessionVehicleHandlers.scala @@ -276,7 +276,7 @@ class SessionVehicleHandlers( lock_wheel=true, reverse=false, unk4=false, - lock_vthrust=0, + lock_vthrust=1, lock_strafe=0, movement_speed=0, unk8=Some(0) diff --git a/src/main/scala/net/psforever/actors/session/support/VehicleOperations.scala b/src/main/scala/net/psforever/actors/session/support/VehicleOperations.scala index 4cce7001..f062043c 100644 --- a/src/main/scala/net/psforever/actors/session/support/VehicleOperations.scala +++ b/src/main/scala/net/psforever/actors/session/support/VehicleOperations.scala @@ -538,7 +538,19 @@ class VehicleOperations( def ServerVehicleOverrideStop(vehicle: Vehicle): Unit = { val vehicleGuid = vehicle.GUID session = session.copy(avatar = avatar.copy(vehicle = Some(vehicleGuid))) - sessionData.vehicles.DriverVehicleControl(vehicle, vehicle.Definition.AutoPilotSpeed2) + TotalDriverVehicleControlWithPacket( + vehicle, + ServerVehicleOverrideMsg( + lock_accelerator=false, + lock_wheel=false, + reverse=false, + unk4=true, + lock_vthrust=0, + lock_strafe=0, + movement_speed=vehicle.Definition.AutoPilotSpeed2, + unk8=None + ) + ) sendResponse(PlanetsideAttributeMessage(vehicleGuid, attribute_type=22, attribute_value=0L)) //mount points on } @@ -554,31 +566,6 @@ class VehicleOperations( sendResponse(pkt) } - /** - * Place the current vehicle under the control of the driver's commands, - * but leave it in a cancellable auto-drive. - * @param vehicle the vehicle - * @param speed how fast the vehicle is moving forward - * @param flight whether the vehicle is ascending or not, if the vehicle is an applicable type - */ - def DriverVehicleControl(vehicle: Vehicle, speed: Int = 0, flight: Int = 0): Unit = { - if (vehicle.DeploymentState == DriveState.AutoPilot) { - TotalDriverVehicleControlWithPacket( - vehicle, - ServerVehicleOverrideMsg( - lock_accelerator=false, - lock_wheel=false, - reverse=false, - unk4=true, - lock_vthrust=flight, - lock_strafe=0, - movement_speed=speed, - unk8=None - ) - ) - } - } - /** * Place the current vehicle under the control of the driver's commands, * but leave it in a cancellable auto-drive. diff --git a/src/main/scala/net/psforever/actors/session/support/ZoningOperations.scala b/src/main/scala/net/psforever/actors/session/support/ZoningOperations.scala index 856eaf44..1553d932 100644 --- a/src/main/scala/net/psforever/actors/session/support/ZoningOperations.scala +++ b/src/main/scala/net/psforever/actors/session/support/ZoningOperations.scala @@ -127,7 +127,7 @@ class ZoningOperations( spawn.deadState = DeadState.RespawnTime cluster ! ICS.GetSpawnPoint( destinationZoneGuid.guid, - player, + player.Faction, destinationBuildingGuid, continent.Number, building_guid, @@ -651,7 +651,8 @@ class ZoningOperations( zoneReload = true cluster ! ICS.GetNearbySpawnPoint( zone.Number, - player, + player.Faction, + player.Position, Seq(SpawnGroup.Facility, SpawnGroup.Tower), context.self ) @@ -1668,10 +1669,12 @@ class ZoningOperations( case _ => zoneNumber }, - player, + player.Faction, + shiftPosition.getOrElse(player.Position), Seq(spawnGroup), context.self ) + shiftPosition = None } else { log.warn(s"SpawnRequestMessage: request consumed because ${player.Name} is already respawning ...") } @@ -1937,7 +1940,8 @@ class ZoningOperations( //look for different spawn point in same zone cluster ! ICS.GetNearbySpawnPoint( zone.Number, - tplayer, + tplayer.Faction, + tplayer.Position, Seq(SpawnGroup.Facility, SpawnGroup.Tower, SpawnGroup.AMS), context.self ) @@ -1971,7 +1975,8 @@ class ZoningOperations( //look for different spawn point in same zone cluster ! ICS.GetNearbySpawnPoint( continent.Number, - tplayer, + tplayer.Faction, + tplayer.Position, Seq(SpawnGroup.Facility, SpawnGroup.Tower, SpawnGroup.AMS), context.self ) diff --git a/src/main/scala/net/psforever/objects/zones/Zone.scala b/src/main/scala/net/psforever/objects/zones/Zone.scala index b9e01657..ad0e8d3b 100644 --- a/src/main/scala/net/psforever/objects/zones/Zone.scala +++ b/src/main/scala/net/psforever/objects/zones/Zone.scala @@ -358,34 +358,21 @@ class Zone(val id: String, val map: ZoneMap, zoneNumber: Int) { ): List[(AmenityOwner, Iterable[SpawnPoint])] = { val ams = spawnGroups.contains(SpawnGroup.AMS) val structures = spawnGroups.collect { - case SpawnGroup.Facility => - StructureType.Facility - case SpawnGroup.Tower => - StructureType.Tower - case SpawnGroup.WarpGate => - StructureType.WarpGate - case SpawnGroup.Sanctuary => - StructureType.Building + case SpawnGroup.Facility => StructureType.Facility + case SpawnGroup.Tower => StructureType.Tower + case SpawnGroup.WarpGate => StructureType.WarpGate + case SpawnGroup.Sanctuary => StructureType.Building } - SpawnGroups() - .filter { - case (building, spawns) => - spawns.nonEmpty && - spawns.exists(_.isOffline == false) && - structures.contains(building.BuildingType) - } - .filter { - case (building, _) => - building match { - case warpGate: WarpGate => - warpGate.Faction == faction || warpGate.Broadcast(faction) - case _ => - building.Faction == faction - } - } - .map { - case (building, spawns: List[SpawnPoint]) => + .collect { + case (building, spawns) + if (building match { + case warpGate: WarpGate => warpGate.Faction == faction || warpGate.Broadcast(faction) + case _ => building.Faction == faction + }) && + structures.contains(building.BuildingType) && + spawns.nonEmpty && + spawns.exists(_.isOffline == false) => (building, spawns.filter(!_.isOffline)) } .concat( @@ -406,7 +393,6 @@ class Zone(val id: String, val map: ZoneMap, zoneNumber: Int) { ) ) .toList - } def findNearestSpawnPoints( diff --git a/src/main/scala/net/psforever/services/InterstellarClusterService.scala b/src/main/scala/net/psforever/services/InterstellarClusterService.scala index c95ea702..781ace2b 100644 --- a/src/main/scala/net/psforever/services/InterstellarClusterService.scala +++ b/src/main/scala/net/psforever/services/InterstellarClusterService.scala @@ -6,7 +6,7 @@ import akka.actor.typed.scaladsl.{AbstractBehavior, ActorContext, Behaviors} import akka.actor.typed.{ActorRef, Behavior, SupervisorStrategy} import net.psforever.actors.zone.ZoneActor import net.psforever.objects.avatar.Avatar -import net.psforever.objects.{Player, SpawnPoint, Vehicle} +import net.psforever.objects.{SpawnPoint, Vehicle} import net.psforever.objects.serverobject.structures.{Building, WarpGate} import net.psforever.objects.zones.{HotSpotInfo, Zone} import net.psforever.packet.game.DroppodError @@ -51,7 +51,7 @@ object InterstellarClusterService { final case class GetSpawnPoint( zoneNumber: Int, - player: Player, + faction: PlanetSideEmpire.Value, target: PlanetSideGUID, fromZoneNumber: Int, fromGateGuid: PlanetSideGUID, @@ -60,7 +60,8 @@ object InterstellarClusterService { final case class GetNearbySpawnPoint( zoneNumber: Int, - player: Player, + faction: PlanetSideEmpire.Value, + position: Vector3, spawnGroups: Seq[SpawnGroup], replyTo: ActorRef[SpawnPointResponse] ) extends Command @@ -219,11 +220,11 @@ class InterstellarClusterService(context: ActorContext[InterstellarClusterServic } replyTo ! SpawnPointResponse(response) - case GetSpawnPoint(zoneNumber, player, target, fromZoneNumber, fromOriginGuid, replyTo) => + case GetSpawnPoint(zoneNumber, faction, target, fromZoneNumber, fromOriginGuid, replyTo) => zones.find(_.Number == zoneNumber) match { case Some(zone) => //found target zone; find a spawn point in target zone - zone.findSpawns(player.Faction, SpawnGroup.values).find { + zone.findSpawns(faction, SpawnGroup.values).find { case (spawn: Building, spawnPoints) => spawn.MapId == target.guid || spawnPoints.exists(_.GUID == target) case (spawn: Vehicle, spawnPoints) => @@ -259,10 +260,10 @@ class InterstellarClusterService(context: ActorContext[InterstellarClusterServic } } - case GetNearbySpawnPoint(zoneNumber, player, spawnGroups, replyTo) => + case GetNearbySpawnPoint(zoneNumber, faction, position, spawnGroups, replyTo) => zones.find(_.Number == zoneNumber) match { case Some(zone) => - zone.findNearestSpawnPoints(player.Faction, player.Position, spawnGroups) match { + zone.findNearestSpawnPoints(faction, position, spawnGroups) match { case None | Some(Nil) => replyTo ! SpawnPointResponse(None) case Some(spawnPoints) =>