diff --git a/src/main/scala/net/psforever/objects/zones/ZoneVehicleActor.scala b/src/main/scala/net/psforever/objects/zones/ZoneVehicleActor.scala
index fd243cdcd..b0b1ed6b2 100644
--- a/src/main/scala/net/psforever/objects/zones/ZoneVehicleActor.scala
+++ b/src/main/scala/net/psforever/objects/zones/ZoneVehicleActor.scala
@@ -3,10 +3,11 @@ package net.psforever.objects.zones
import akka.actor.Actor
import net.psforever.actors.zone.ZoneActor
+import net.psforever.objects.definition.VehicleDefinition
import net.psforever.objects.serverobject.deploy.{Deployment, Interference}
import net.psforever.objects.vital.InGameHistory
import net.psforever.objects.{Default, Vehicle}
-import net.psforever.types.{DriveState, Vector3}
+import net.psforever.types.{DriveState, PlanetSideEmpire, Vector3}
import scala.annotation.tailrec
import scala.collection.mutable
@@ -14,27 +15,12 @@ import scala.collection.mutable
/**
* Synchronize management of the list of `Vehicles` maintained by some `Zone`.
*/
-//COMMENTS IMPORTED FROM FORMER VehicleContextActor:
- /*
- * Provide a context for a `Vehicle` `Actor` - the `VehicleControl`.
- *
- * A vehicle can be passed between different zones and, therefore, does not belong to the zone.
- * A vehicle cna be given to different players and can persist and change though players have gone.
- * Therefore, also does not belong to `WorldSessionActor`.
- * A vehicle must anchored to something that exists outside of the `InterstellarCluster` and its agents.
- *
- * The only purpose of this `Actor` is to allow vehicles to borrow a context for the purpose of `Actor` creation.
- * It is also be allowed to be responsible for cleaning up that context.
- * (In reality, it can be cleaned up anywhere a `PoisonPill` can be sent.)
- *
- * This `Actor` is intended to sit on top of the event system that handles broadcast messaging.
- */
class ZoneVehicleActor(
zone: Zone,
vehicleList: mutable.ListBuffer[Vehicle],
turretToMount: mutable.HashMap[Int, Int]
) extends Actor {
- //private[this] val log = org.log4s.getLogger
+ private var temporaryInterference: Seq[(Vector3, PlanetSideEmpire.Value, VehicleDefinition)] = Seq()
def receive: Receive = {
case Zone.Vehicle.Spawn(vehicle) =>
@@ -79,9 +65,23 @@ class ZoneVehicleActor(
}
case Zone.Vehicle.TryDeploymentChange(vehicle, toDeployState)
- if toDeployState > DriveState.Undeploying && Interference.Test(zone, vehicle).nonEmpty =>
+ if toDeployState == DriveState.Deploying &&
+ (ZoneVehicleActor.temporaryInterferenceTest(vehicle,temporaryInterference) || Interference.Test(zone, vehicle).nonEmpty) =>
sender() ! Zone.Vehicle.CanNotDeploy(zone, vehicle, toDeployState, "blocked by a nearby entity")
+ case Zone.Vehicle.TryDeploymentChange(vehicle, toDeployState)
+ if toDeployState == DriveState.Deploying =>
+ import scala.concurrent.duration._
+ import scala.concurrent.ExecutionContext.Implicits.global
+ val position = vehicle.Position
+ temporaryInterference = temporaryInterference :+ (position, vehicle.Faction, vehicle.Definition)
+ context.system.scheduler.scheduleOnce(
+ vehicle.Definition.DeployTime.milliseconds,
+ self,
+ ZoneVehicleActor.ClearInterference(position)
+ )
+ vehicle.Actor.tell(Deployment.TryDeploymentChange(toDeployState), sender())
+
case Zone.Vehicle.TryDeploymentChange(vehicle, toDeployState) =>
vehicle.Actor.tell(Deployment.TryDeploymentChange(toDeployState), sender())
@@ -89,13 +89,20 @@ class ZoneVehicleActor(
case Zone.Vehicle.CanNotDespawn(_, _, _) => ()
- case Zone.Vehicle.CanNotDeploy(_, _, _, _) => ()
+ case Zone.Vehicle.CanNotDeploy(_, vehicle, _, _) => ()
+ val pos = vehicle.Position
+ temporaryInterference = temporaryInterference.filterNot(_._1 == pos)
+
+ case ZoneVehicleActor.ClearInterference(pos) =>
+ temporaryInterference = temporaryInterference.filterNot(_._1 == pos)
case _ => ()
}
}
object ZoneVehicleActor {
+ private case class ClearInterference(pos: Vector3)
+
@tailrec final def recursiveFindVehicle(iter: Iterator[Vehicle], target: Vehicle, index: Int = 0): Option[Int] = {
if (!iter.hasNext) {
None
@@ -107,4 +114,22 @@ object ZoneVehicleActor {
}
}
}
+
+ private def temporaryInterferenceTest(
+ vehicle: Vehicle,
+ existingInterferences: Seq[(Vector3, PlanetSideEmpire.Value, VehicleDefinition)]
+ ): Boolean = {
+ val vPosition = vehicle.Position
+ val vFaction = vehicle.Faction
+ val vDefinition = vehicle.Definition
+ existingInterferences
+ .collect { case (p, faction, d) if faction == vFaction => (p, d) }
+ .exists { case (position, definition) =>
+ val interference = definition.interference
+ (interference ne Interference.AllowAll) && {
+ lazy val distanceSq = Vector3.DistanceSquared(position, vPosition)
+ definition == vDefinition && distanceSq < interference.main * interference.main
+ }
+ }
+ }
}