mirror of
https://github.com/psforever/PSF-LoginServer.git
synced 2026-03-03 12:30:24 +00:00
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:
parent
4ac7c0b3fd
commit
6a1412a71b
6 changed files with 85 additions and 43 deletions
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue