fixed vehicle interference; added missing ArmorShieldOff message; clearing countdown after vehicle spawn should stop countdown from appearing in subsequent vehicle spawns

This commit is contained in:
Fate-JH 2024-09-04 00:04:43 -04:00
parent 4ac7c0b3fd
commit 6a1412a71b
6 changed files with 85 additions and 43 deletions

View file

@ -673,6 +673,9 @@ class GeneralOperations(
case _ => ()
}
} else {
if (player.Capacitor < 1f && player.UsingSpecial == SpecialExoSuitDefinition.Mode.Shielded) {
sendResponse(ChatMsg(ChatMessageType.UNK_227, "@ArmorShieldOff"))
}
player.UsingSpecial = SpecialExoSuitDefinition.Mode.Normal
continent.AvatarEvents ! AvatarServiceMessage(
continent.id,

View file

@ -2,17 +2,12 @@
package net.psforever.actors.session.support
import akka.actor.ActorContext
import net.psforever.objects.{PlanetSideGameObject, Players, TurretDeployable}
import net.psforever.objects.{Players, TurretDeployable}
import net.psforever.objects.ce.Deployable
import net.psforever.objects.guid.{GUIDTask, TaskWorkflow}
import net.psforever.objects.serverobject.environment.EnvironmentAttribute
import net.psforever.objects.serverobject.environment.interaction.InteractWithEnvironment
import net.psforever.objects.serverobject.environment.interaction.common.Watery
import net.psforever.objects.serverobject.interior.Sidedness
import net.psforever.objects.serverobject.llu.CaptureFlag
import net.psforever.objects.zones.InteractsWithZone
import net.psforever.packet.game.GenericObjectActionMessage
import net.psforever.services.local.{LocalAction, LocalResponse, LocalServiceMessage}
import net.psforever.services.local.LocalResponse
import net.psforever.types.PlanetSideGUID
trait LocalHandlerFunctions extends CommonSessionInterfacingFunctionality {

View file

@ -801,7 +801,7 @@ object GlobalDefinitionsMiscellaneous {
AutoRanges(
detection = 125f,
trigger = 100f,
escape = 200f
escape = 150f
),
AutoChecks(
validation = List(
@ -813,7 +813,7 @@ object GlobalDefinitionsMiscellaneous {
),
retaliatoryDelay = 4000L, //8000L
cylindrical = true,
cylindricalExtraHeight = 50f,
cylindricalExtraHeight = 25f,
detectionSweepTime = 2.seconds,
refireTime = 362.milliseconds //312.milliseconds
)

View file

@ -46,11 +46,11 @@ object Interference {
* @param zone game world in which this test will be conducted;
* entity should be `ZoneAware`, but it may not be set correctly during this part of its internal process
* @param obj entity that may be interfered with
* @return a different entity that causes the test entity to suffer interference
* @return other entities that causes the test entity to suffer interference
*/
def Test(zone: Zone, obj: PlanetSideGameObject with FactionAffinity): Option[PlanetSideGameObject with FactionAffinity] = {
def Test(zone: Zone, obj: PlanetSideGameObject with FactionAffinity): Seq[PlanetSideGameObject with FactionAffinity] = {
val (data, filterFunc) = SetupForTest(zone, obj)
data.find(filterFunc)
data.filter(filterFunc)
}
/**

View file

@ -80,7 +80,7 @@ class VehicleSpawnControl(pad: VehicleSpawnPad)
}
override def postStop() : Unit = {
periodicReminder.cancel()
discontinueCurrentReminder()
queueManagement.cancel()
}
@ -120,7 +120,7 @@ class VehicleSpawnControl(pad: VehicleSpawnPad)
evaluateBlockedReminder()
case VehicleSpawnControl.ProcessControl.Flush =>
periodicReminder.cancel()
discontinueCurrentReminder()
orders.foreach { CancelOrder(_, Some("@SVCP_RemovedFromVehicleQueue_Generic")) }
orders = Nil
trackedOrder.foreach {
@ -237,7 +237,7 @@ class VehicleSpawnControl(pad: VehicleSpawnPad)
* `None`, if no order found or submitted
*/
private def ProcessOrder(order: Option[VehicleSpawnPad.VehicleOrder]): Unit = {
periodicReminder.cancel()
discontinueCurrentReminder()
order.collect {
case VehicleSpawnPad.VehicleOrder(driver, vehicle, terminal) =>
val size = orders.size + 1
@ -347,32 +347,39 @@ class VehicleSpawnControl(pad: VehicleSpawnPad)
retimePeriodicReminder(
shaveOffFirstElementAndDiffSecondElement(pad.Definition.BlockedReminderMessageDelays)
)
trackedOrder
} else if (reminderSeq.size == 1) {
//end reminder
standaloneBlockedReminder(
VehicleSpawnPad.VehicleOrder(entry.driver, entry.vehicle, null),
Some("@PadDeconstruct_Done")
)
periodicReminder.cancel()
periodicReminder = Default.Cancellable
reminderSeq = List()
None
} else {
//continue reminder
BlockedReminder(entry, orders)
retimePeriodicReminder(
shaveOffFirstElementAndDiffSecondElement(reminderSeq)
)
trackedOrder
}
trackedOrder
}
.orElse {
periodicReminder.cancel()
periodicReminder = Default.Cancellable
reminderSeq = List()
discontinueCurrentReminder()
None
}
}
/**
* The periodic reminder will no longer be repeated.
* Sequences tied to the periodic reminder should be reset.
*/
private def discontinueCurrentReminder(): Unit = {
periodicReminder.cancel()
periodicReminder = Default.Cancellable
reminderSeq = List()
}
/**
* na
* @param blockedOrder the previous order whose vehicle is blocking the spawn pad from operating

View file

@ -3,10 +3,10 @@ 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.definition.{ObjectDefinition, VehicleDefinition}
import net.psforever.objects.serverobject.deploy.{Deployment, Interference}
import net.psforever.objects.vital.InGameHistory
import net.psforever.objects.{Default, GlobalDefinitions, Vehicle}
import net.psforever.objects.{Default, Vehicle}
import net.psforever.packet.game.ChatMsg
import net.psforever.services.Service
import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage}
@ -69,15 +69,18 @@ class ZoneVehicleActor(
sender() ! Zone.Vehicle.CanNotDespawn(zone, vehicle, "can not find")
}
case Zone.Vehicle.TryDeploymentChange(vehicle, toDeployState)
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 =>
tryAddToInterferenceField(vehicle.Position, vehicle.Faction, vehicle.Definition)
vehicle.Actor.tell(Deployment.TryDeploymentChange(toDeployState), sender())
case Zone.Vehicle.TryDeploymentChange(vehicle, DriveState.Deploying) =>
if (ZoneVehicleActor.ReportOnInterferenceResults(
zone,
vehicle,
ZoneVehicleActor.temporaryInterferenceTest(vehicle, temporaryInterference) ++
Interference.Test(zone, vehicle).map(_.Definition)
)) {
sender() ! Zone.Vehicle.CanNotDeploy(zone, vehicle, DriveState.Deploying, "blocked by a nearby entity")
} else {
tryAddToInterferenceField(vehicle.Position, vehicle.Faction, vehicle.Definition)
vehicle.Actor.tell(Deployment.TryDeploymentChange(DriveState.Deploying), sender())
}
case Zone.Vehicle.TryDeploymentChange(vehicle, toDeployState) =>
vehicle.Actor.tell(Deployment.TryDeploymentChange(toDeployState), sender())
@ -86,14 +89,16 @@ class ZoneVehicleActor(
case Zone.Vehicle.CanNotDespawn(_, _, _) => ()
case Zone.Vehicle.CanNotDeploy(_, vehicle, toState, _)
if vehicle.Definition == GlobalDefinitions.ams &&
(toState == DriveState.Deploying || toState == DriveState.Deployed) =>
val pos = vehicle.Position
zone.VehicleEvents ! VehicleServiceMessage(
vehicle.Seats.headOption.flatMap(_._2.occupant).map(_.Name).getOrElse("Driver"),
VehicleAction.SendResponse(Service.defaultPlayerGUID, ChatMsg(ChatMessageType.UNK_227, "@nodeploy_ams"))
case Zone.Vehicle.CanNotDeploy(_, vehicle, DriveState.Deploying, reason) =>
ZoneVehicleActor.ReportOnInterferenceResults(
zone,
vehicle,
ZoneVehicleActor.temporaryInterferenceTest(vehicle, temporaryInterference) ++
Interference.Test(zone, vehicle).map(_.Definition)
)
val pos = vehicle.Position
val driverMoniker = vehicle.Seats.headOption.flatMap(_._2.occupant).map(_.Name).getOrElse("Driver")
log.warn(s"$driverMoniker's ${vehicle.Definition.Name} can not deploy in ${zone.id} because $reason")
temporaryInterference = temporaryInterference.filterNot(_._1 == pos)
case Zone.Vehicle.CanNotDeploy(_, vehicle, _, reason) =>
@ -146,22 +151,54 @@ object ZoneVehicleActor {
private def temporaryInterferenceTest(
vehicle: Vehicle,
existingInterferences: Seq[(Vector3, PlanetSideEmpire.Value, VehicleDefinition)]
): Boolean = {
): Seq[VehicleDefinition] = {
val vPosition = vehicle.Position
val vFaction = vehicle.Faction
val vDefinition = vehicle.Definition
if (vDefinition.interference eq Interference.AllowAll) {
false
Nil
} else {
existingInterferences
.collect { case (p, faction, d) if faction == vFaction => (p, d) }
.exists { case (position, definition) =>
.filter { 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
}
}
.map(_._2)
}
}
private def ReportOnInterferenceResults(
zone: Zone,
vehicle: Vehicle,
reportedInterferenceList: Seq[ObjectDefinition]
): Boolean = {
if (reportedInterferenceList.nonEmpty) {
reportedInterferenceList
.find(_.isInstanceOf[VehicleDefinition])
.map { definition => s"@nodeploy_${definition.Name}" }
.orElse {
val sharedGroupId = vehicle.Definition.interference.sharedGroupId
if (sharedGroupId > 0) {
reportedInterferenceList
.find(_.interference.sharedGroupId == sharedGroupId)
.map(_ => "@nodeploy_sharedinterference")
} else {
None
}
}
.foreach { msg =>
zone.VehicleEvents ! VehicleServiceMessage(
vehicle.Seats.headOption.flatMap(_._2.occupant).map(_.Name).getOrElse(""),
VehicleAction.SendResponse(Service.defaultPlayerGUID, ChatMsg(ChatMessageType.UNK_227, msg))
)
}
true
} else {
false
}
}
}