mirror of
https://github.com/psforever/PSF-LoginServer.git
synced 2026-07-16 08:55:18 +00:00
vehicle pad deconstruction complete message; message when nc max shield deactivates when out of capacitor power or when max opens fire; message when ams can not deploy because it is blocked by other entities; message when facility capture requires ntu
This commit is contained in:
parent
d67e09bcbd
commit
9f4452a36a
6 changed files with 143 additions and 28 deletions
|
|
@ -120,11 +120,8 @@ class GeneralLogic(val ops: GeneralOperations, implicit val context: ActorContex
|
||||||
ops.fallHeightTracker(pos.z)
|
ops.fallHeightTracker(pos.z)
|
||||||
if (isCrouching && !player.Crouching) {
|
if (isCrouching && !player.Crouching) {
|
||||||
//dev stuff goes here
|
//dev stuff goes here
|
||||||
sendResponse(ChatMsg(ChatMessageType.UNK_228, "@login_reposition_to_sanctuary"))
|
//sendResponse(ChatMsg(ChatMessageType.UNK_227, "@fav_light_infantry")) //Light Infantry / Vehicle Driver
|
||||||
sendResponse(ChatMsg(ChatMessageType.UNK_229, "@PadDeconstruct_Done"))
|
//sendResponse(ChatMsg(ChatMessageType.UNK_227, "@fav_heavy_infantry")) //Heavy Infantry
|
||||||
//sendResponse(ChatMsg(ChatMessageType.UNK_227, "@NoMount_Permission"))
|
|
||||||
//sendResponse(ChatMsg(ChatMessageType.UNK_227, "@ArmorShieldOff"))
|
|
||||||
//sendResponse(ChatMsg(ChatMessageType.UNK_227, "@ArmorShieldOverride"))
|
|
||||||
}
|
}
|
||||||
player.Position = pos
|
player.Position = pos
|
||||||
player.Velocity = vel
|
player.Velocity = vel
|
||||||
|
|
@ -1455,6 +1452,10 @@ class GeneralLogic(val ops: GeneralOperations, implicit val context: ActorContex
|
||||||
val drainAmount = player.ExoSuitDef.CapacitorDrainPerSecond.toFloat * timeDiff
|
val drainAmount = player.ExoSuitDef.CapacitorDrainPerSecond.toFloat * timeDiff
|
||||||
player.Capacitor -= drainAmount
|
player.Capacitor -= drainAmount
|
||||||
sendResponse(PlanetsideAttributeMessage(player.GUID, 7, player.Capacitor.toInt))
|
sendResponse(PlanetsideAttributeMessage(player.GUID, 7, player.Capacitor.toInt))
|
||||||
|
if (player.Capacitor <= 0 && player.UsingSpecial == SpecialExoSuitDefinition.Mode.Shielded) {
|
||||||
|
ops.toggleMaxSpecialState(enable = false)
|
||||||
|
sendResponse(ChatMsg(ChatMessageType.UNK_227, "@ArmorShieldOff"))
|
||||||
|
}
|
||||||
} else if (player.Capacitor < player.ExoSuitDef.MaxCapacitor) {
|
} else if (player.Capacitor < player.ExoSuitDef.MaxCapacitor) {
|
||||||
if (player.Faction != PlanetSideEmpire.VS) {
|
if (player.Faction != PlanetSideEmpire.VS) {
|
||||||
ops.toggleMaxSpecialState(enable = false)
|
ops.toggleMaxSpecialState(enable = false)
|
||||||
|
|
|
||||||
|
|
@ -2,9 +2,11 @@
|
||||||
package net.psforever.actors.session.support
|
package net.psforever.actors.session.support
|
||||||
|
|
||||||
import akka.actor.{ActorContext, typed}
|
import akka.actor.{ActorContext, typed}
|
||||||
|
import net.psforever.objects.definition.SpecialExoSuitDefinition
|
||||||
import net.psforever.objects.zones.Zoning
|
import net.psforever.objects.zones.Zoning
|
||||||
import net.psforever.objects.serverobject.turret.VanuSentry
|
import net.psforever.objects.serverobject.turret.VanuSentry
|
||||||
import net.psforever.objects.zones.exp.ToDatabase
|
import net.psforever.objects.zones.exp.ToDatabase
|
||||||
|
import net.psforever.types.ChatMessageType
|
||||||
|
|
||||||
import scala.collection.mutable
|
import scala.collection.mutable
|
||||||
import scala.concurrent.duration._
|
import scala.concurrent.duration._
|
||||||
|
|
@ -83,9 +85,10 @@ class WeaponAndProjectileOperations(
|
||||||
if (player.ZoningRequest != Zoning.Method.None) {
|
if (player.ZoningRequest != Zoning.Method.None) {
|
||||||
sessionLogic.zoning.CancelZoningProcessWithDescriptiveReason("cancel_fire")
|
sessionLogic.zoning.CancelZoningProcessWithDescriptiveReason("cancel_fire")
|
||||||
}
|
}
|
||||||
if (player.isShielded) {
|
if (player.UsingSpecial == SpecialExoSuitDefinition.Mode.Shielded) {
|
||||||
// Cancel NC MAX shield if it's active
|
// Cancel NC MAX shield if it's active
|
||||||
sessionLogic.general.toggleMaxSpecialState(enable = false)
|
sessionLogic.general.toggleMaxSpecialState(enable = false)
|
||||||
|
sendResponse(ChatMsg(ChatMessageType.UNK_227, "@ArmorShieldOverride"))
|
||||||
}
|
}
|
||||||
val (o, tools) = FindContainedWeapon
|
val (o, tools) = FindContainedWeapon
|
||||||
val (_, enabledTools) = FindEnabledWeaponsToHandleWeaponFireAccountability(o, tools)
|
val (_, enabledTools) = FindEnabledWeaponsToHandleWeaponFireAccountability(o, tools)
|
||||||
|
|
|
||||||
|
|
@ -349,6 +349,10 @@ class VehicleSpawnControl(pad: VehicleSpawnPad)
|
||||||
)
|
)
|
||||||
} else if (reminderSeq.size == 1) {
|
} else if (reminderSeq.size == 1) {
|
||||||
//end reminder
|
//end reminder
|
||||||
|
standaloneBlockedReminder(
|
||||||
|
VehicleSpawnPad.VehicleOrder(entry.driver, entry.vehicle, null),
|
||||||
|
Some("@PadDeconstruct_Done")
|
||||||
|
)
|
||||||
periodicReminder.cancel()
|
periodicReminder.cancel()
|
||||||
periodicReminder = Default.Cancellable
|
periodicReminder = Default.Cancellable
|
||||||
reminderSeq = List()
|
reminderSeq = List()
|
||||||
|
|
@ -374,7 +378,10 @@ class VehicleSpawnControl(pad: VehicleSpawnPad)
|
||||||
* @param blockedOrder the previous order whose vehicle is blocking the spawn pad from operating
|
* @param blockedOrder the previous order whose vehicle is blocking the spawn pad from operating
|
||||||
* @param recipients all of the other customers who will be receiving the message
|
* @param recipients all of the other customers who will be receiving the message
|
||||||
*/
|
*/
|
||||||
private def BlockedReminder(blockedOrder: VehicleSpawnControl.Order, recipients: Seq[VehicleSpawnPad.VehicleOrder]): Unit = {
|
private def BlockedReminder(
|
||||||
|
blockedOrder: VehicleSpawnControl.Order,
|
||||||
|
recipients: Seq[VehicleSpawnPad.VehicleOrder]
|
||||||
|
): Unit = {
|
||||||
//everyone else
|
//everyone else
|
||||||
recursiveBlockedReminder(
|
recursiveBlockedReminder(
|
||||||
recipients.iterator,
|
recipients.iterator,
|
||||||
|
|
@ -389,12 +396,8 @@ class VehicleSpawnControl(pad: VehicleSpawnPad)
|
||||||
.orElse(pad.Zone.GUID(blockedOrder.vehicle.OwnerGuid))
|
.orElse(pad.Zone.GUID(blockedOrder.vehicle.OwnerGuid))
|
||||||
.orElse(pad.Zone.GUID(blockedOrder.DriverGUID)) collect {
|
.orElse(pad.Zone.GUID(blockedOrder.DriverGUID)) collect {
|
||||||
case p: Player if p.isAlive =>
|
case p: Player if p.isAlive =>
|
||||||
recursiveBlockedReminder(
|
standaloneBlockedReminder(
|
||||||
Seq(VehicleSpawnPad.VehicleOrder(
|
VehicleSpawnPad.VehicleOrder(blockedOrder.driver, blockedOrder.vehicle, null),
|
||||||
blockedOrder.driver,
|
|
||||||
blockedOrder.vehicle,
|
|
||||||
null //permissible
|
|
||||||
)).iterator,
|
|
||||||
Some(s"@PadDeconstruct_secsA^${reminderSeq.head}~")
|
Some(s"@PadDeconstruct_secsA^${reminderSeq.head}~")
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
@ -432,16 +435,22 @@ class VehicleSpawnControl(pad: VehicleSpawnPad)
|
||||||
cause: Option[Any]
|
cause: Option[Any]
|
||||||
): Unit = {
|
): Unit = {
|
||||||
if (iter.hasNext) {
|
if (iter.hasNext) {
|
||||||
val recipient = iter.next()
|
standaloneBlockedReminder(iter.next(), cause)
|
||||||
pad.Zone.VehicleEvents ! VehicleSpawnPad.PeriodicReminder(
|
|
||||||
recipient.player.Name,
|
|
||||||
VehicleSpawnPad.Reminders.Blocked,
|
|
||||||
cause
|
|
||||||
)
|
|
||||||
recursiveBlockedReminder(iter, cause)
|
recursiveBlockedReminder(iter, cause)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private def standaloneBlockedReminder(
|
||||||
|
entry: VehicleSpawnPad.VehicleOrder,
|
||||||
|
cause: Option[Any]
|
||||||
|
): Unit = {
|
||||||
|
pad.Zone.VehicleEvents ! VehicleSpawnPad.PeriodicReminder(
|
||||||
|
entry.player.Name,
|
||||||
|
VehicleSpawnPad.Reminders.Blocked,
|
||||||
|
cause
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
@tailrec private final def recursiveOrderReminder(
|
@tailrec private final def recursiveOrderReminder(
|
||||||
iter: Iterator[VehicleSpawnPad.VehicleOrder],
|
iter: Iterator[VehicleSpawnPad.VehicleOrder],
|
||||||
size: Int,
|
size: Int,
|
||||||
|
|
|
||||||
|
|
@ -5,12 +5,16 @@ import net.psforever.objects.serverobject.structures.{Building, StructureType}
|
||||||
import net.psforever.objects.sourcing.{PlayerSource, UniquePlayer}
|
import net.psforever.objects.sourcing.{PlayerSource, UniquePlayer}
|
||||||
import net.psforever.objects.zones.{HotSpotInfo, ZoneHotSpotProjector}
|
import net.psforever.objects.zones.{HotSpotInfo, ZoneHotSpotProjector}
|
||||||
import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage}
|
import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage}
|
||||||
import net.psforever.types.{PlanetSideEmpire, Vector3}
|
import net.psforever.types.{ChatMessageType, PlanetSideEmpire, Vector3}
|
||||||
import net.psforever.util.Config
|
import net.psforever.util.Config
|
||||||
import akka.pattern.ask
|
import akka.pattern.ask
|
||||||
import akka.util.Timeout
|
import akka.util.Timeout
|
||||||
|
import net.psforever.objects.Player
|
||||||
import net.psforever.objects.avatar.scoring.Kill
|
import net.psforever.objects.avatar.scoring.Kill
|
||||||
|
import net.psforever.objects.serverobject.hackable.Hackable
|
||||||
import net.psforever.objects.zones.exp.ToDatabase
|
import net.psforever.objects.zones.exp.ToDatabase
|
||||||
|
import net.psforever.packet.game.ChatMsg
|
||||||
|
import net.psforever.services.local.{LocalAction, LocalServiceMessage}
|
||||||
|
|
||||||
import scala.collection.mutable
|
import scala.collection.mutable
|
||||||
import scala.concurrent.duration._
|
import scala.concurrent.duration._
|
||||||
|
|
@ -31,6 +35,20 @@ final case class MajorFacilityHackParticipation(building: Building) extends Faci
|
||||||
updateHotSpotInfoOverTime()
|
updateHotSpotInfoOverTime()
|
||||||
updateTime(now)
|
updateTime(now)
|
||||||
}
|
}
|
||||||
|
building.CaptureTerminal
|
||||||
|
.map(_.HackedBy)
|
||||||
|
.collect {
|
||||||
|
case Some(info@Hackable.HackInfo(_, _, start, length, _))
|
||||||
|
if building.NtuLevel == 0 && {
|
||||||
|
val approximateHackTimeRemaining = math.max(0, start + length - System.currentTimeMillis())
|
||||||
|
approximateHackTimeRemaining <= 300.seconds.toMillis && approximateHackTimeRemaining > 295.seconds.toMillis
|
||||||
|
} =>
|
||||||
|
MajorFacilityHackParticipation.warningMessageForHackOccupiers(
|
||||||
|
building,
|
||||||
|
info,
|
||||||
|
ChatMsg(ChatMessageType.UNK_227, "@FacilityRequiresResourcesForHackCriticalWarning")
|
||||||
|
)
|
||||||
|
}
|
||||||
lastInfoRequest = now
|
lastInfoRequest = now
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -287,8 +305,8 @@ final case class MajorFacilityHackParticipation(building: Building) extends Faci
|
||||||
if (isResecured) {
|
if (isResecured) {
|
||||||
hackerScore
|
hackerScore
|
||||||
} else {
|
} else {
|
||||||
val flagCarrierScore = flagCarrier.map (p => List((p.CharId, 0L, "llu"))).getOrElse(Nil)
|
val flagCarrierScore = flagCarrier.map(p => List((p.CharId, 0L, "llu"))).getOrElse(Nil)
|
||||||
if (playersInSoi.exists(_.CharId == hackerId) && !flagCarrierScore.exists { case (charId, _,_) => charId == hackerId }) {
|
if (playersInSoi.exists(_.CharId == hackerId) && !flagCarrierScore.exists { case (charId, _, _) => charId == hackerId }) {
|
||||||
hackerScore ++ flagCarrierScore
|
hackerScore ++ flagCarrierScore
|
||||||
} else {
|
} else {
|
||||||
flagCarrierScore
|
flagCarrierScore
|
||||||
|
|
@ -326,3 +344,61 @@ final case class MajorFacilityHackParticipation(building: Building) extends Faci
|
||||||
.getOrElse(list)
|
.getOrElse(list)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
object MajorFacilityHackParticipation {
|
||||||
|
/**
|
||||||
|
* Dispatch a message to clients affected by some change.
|
||||||
|
* Establish the hack information by referencing the capture terminal.
|
||||||
|
* @param building building entity
|
||||||
|
* @param msg message to send to affected clients
|
||||||
|
*/
|
||||||
|
def warningMessageForHackOccupiers(
|
||||||
|
building: Building,
|
||||||
|
msg: ChatMsg
|
||||||
|
): Unit = {
|
||||||
|
building
|
||||||
|
.CaptureTerminal
|
||||||
|
.flatMap(_.HackedBy)
|
||||||
|
.foreach { hackedInfo =>
|
||||||
|
warningMessageForHackOccupiers(building, hackedInfo, msg)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dispatch a message to clients affected by some change.
|
||||||
|
* Select individuals belonging to the hacking faction to be targets for the message.
|
||||||
|
* @param building building entity
|
||||||
|
* @param hackedInfo confirmed information about the hack state
|
||||||
|
* @param msg message to send to affected clients
|
||||||
|
*/
|
||||||
|
def warningMessageForHackOccupiers(
|
||||||
|
building: Building,
|
||||||
|
hackedInfo: Hackable.HackInfo,
|
||||||
|
msg: ChatMsg
|
||||||
|
): Unit = {
|
||||||
|
val hackerFaction = hackedInfo.hackerFaction
|
||||||
|
warningMessageForHackOccupiers(
|
||||||
|
building,
|
||||||
|
building.PlayersInSOI.filter(_.Faction == hackerFaction),
|
||||||
|
msg
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dispatch a message to clients affected by some change.
|
||||||
|
* @param building building entity
|
||||||
|
* @param targets affected clients by player
|
||||||
|
* @param msg message to send to affected clients
|
||||||
|
*/
|
||||||
|
private def warningMessageForHackOccupiers(
|
||||||
|
building: Building,
|
||||||
|
targets: Iterable[Player],
|
||||||
|
msg: ChatMsg
|
||||||
|
): Unit = {
|
||||||
|
val events = building.Zone.LocalEvents
|
||||||
|
val message = LocalAction.SendResponse(msg)
|
||||||
|
targets.foreach { player =>
|
||||||
|
events ! LocalServiceMessage(player.Name, message)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,8 +6,11 @@ import net.psforever.actors.zone.ZoneActor
|
||||||
import net.psforever.objects.definition.VehicleDefinition
|
import net.psforever.objects.definition.VehicleDefinition
|
||||||
import net.psforever.objects.serverobject.deploy.{Deployment, Interference}
|
import net.psforever.objects.serverobject.deploy.{Deployment, Interference}
|
||||||
import net.psforever.objects.vital.InGameHistory
|
import net.psforever.objects.vital.InGameHistory
|
||||||
import net.psforever.objects.{Default, Vehicle}
|
import net.psforever.objects.{Default, GlobalDefinitions, Vehicle}
|
||||||
import net.psforever.types.{DriveState, PlanetSideEmpire, Vector3}
|
import net.psforever.packet.game.ChatMsg
|
||||||
|
import net.psforever.services.Service
|
||||||
|
import net.psforever.services.vehicle.{VehicleAction, VehicleServiceMessage}
|
||||||
|
import net.psforever.types.{ChatMessageType, DriveState, PlanetSideEmpire, Vector3}
|
||||||
|
|
||||||
import scala.annotation.tailrec
|
import scala.annotation.tailrec
|
||||||
import scala.collection.mutable
|
import scala.collection.mutable
|
||||||
|
|
@ -83,7 +86,17 @@ class ZoneVehicleActor(
|
||||||
|
|
||||||
case Zone.Vehicle.CanNotDespawn(_, _, _) => ()
|
case Zone.Vehicle.CanNotDespawn(_, _, _) => ()
|
||||||
|
|
||||||
case Zone.Vehicle.CanNotDeploy(_, vehicle, _, reason) => ()
|
case Zone.Vehicle.CanNotDeploy(_, vehicle, toState, _)
|
||||||
|
if vehicle.Definition == GlobalDefinitions.ams &&
|
||||||
|
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"))
|
||||||
|
)
|
||||||
|
temporaryInterference = temporaryInterference.filterNot(_._1 == pos)
|
||||||
|
|
||||||
|
case Zone.Vehicle.CanNotDeploy(_, vehicle, _, reason) =>
|
||||||
val pos = vehicle.Position
|
val pos = vehicle.Position
|
||||||
val driverMoniker = vehicle.Seats.headOption.flatMap(_._2.occupant).map(_.Name).getOrElse("Driver")
|
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")
|
log.warn(s"$driverMoniker's ${vehicle.Definition.Name} can not deploy in ${zone.id} because $reason")
|
||||||
|
|
|
||||||
|
|
@ -6,16 +6,17 @@ import net.psforever.actors.zone.{BuildingActor, ZoneActor}
|
||||||
import net.psforever.objects.serverobject.CommonMessages
|
import net.psforever.objects.serverobject.CommonMessages
|
||||||
import net.psforever.objects.serverobject.hackable.Hackable
|
import net.psforever.objects.serverobject.hackable.Hackable
|
||||||
import net.psforever.objects.serverobject.llu.CaptureFlag
|
import net.psforever.objects.serverobject.llu.CaptureFlag
|
||||||
import net.psforever.objects.serverobject.structures.Building
|
import net.psforever.objects.serverobject.structures.{Building, StructureType}
|
||||||
import net.psforever.objects.serverobject.terminals.capture.CaptureTerminal
|
import net.psforever.objects.serverobject.terminals.capture.CaptureTerminal
|
||||||
import net.psforever.objects.zones.Zone
|
import net.psforever.objects.zones.Zone
|
||||||
import net.psforever.objects.Default
|
import net.psforever.objects.Default
|
||||||
import net.psforever.packet.game.{GenericAction, HackState7, PlanetsideAttributeEnum}
|
import net.psforever.objects.serverobject.structures.participation.MajorFacilityHackParticipation
|
||||||
|
import net.psforever.packet.game.{ChatMsg, GenericAction, HackState7, PlanetsideAttributeEnum}
|
||||||
import net.psforever.objects.sourcing.PlayerSource
|
import net.psforever.objects.sourcing.PlayerSource
|
||||||
import net.psforever.services.Service
|
import net.psforever.services.Service
|
||||||
import net.psforever.services.local.support.HackCaptureActor.GetHackingFaction
|
import net.psforever.services.local.support.HackCaptureActor.GetHackingFaction
|
||||||
import net.psforever.services.local.{LocalAction, LocalServiceMessage}
|
import net.psforever.services.local.{LocalAction, LocalServiceMessage}
|
||||||
import net.psforever.types.{PlanetSideEmpire, PlanetSideGUID}
|
import net.psforever.types.{ChatMessageType, PlanetSideEmpire, PlanetSideGUID}
|
||||||
|
|
||||||
import scala.concurrent.duration.{FiniteDuration, _}
|
import scala.concurrent.duration.{FiniteDuration, _}
|
||||||
import scala.util.Random
|
import scala.util.Random
|
||||||
|
|
@ -234,6 +235,18 @@ class HackCaptureActor extends Actor {
|
||||||
val owner = terminal.Owner.asInstanceOf[Building]
|
val owner = terminal.Owner.asInstanceOf[Building]
|
||||||
// Notify parent building that state has changed
|
// Notify parent building that state has changed
|
||||||
owner.Actor ! BuildingActor.AmenityStateChange(terminal, Some(isResecured))
|
owner.Actor ! BuildingActor.AmenityStateChange(terminal, Some(isResecured))
|
||||||
|
// If major facility, check NTU
|
||||||
|
owner.CaptureTerminal
|
||||||
|
.map(_.HackedBy)
|
||||||
|
.collect {
|
||||||
|
case Some(info: Hackable.HackInfo)
|
||||||
|
if owner.BuildingType == StructureType.Facility && owner.NtuLevel == 0 =>
|
||||||
|
MajorFacilityHackParticipation.warningMessageForHackOccupiers(
|
||||||
|
owner,
|
||||||
|
info,
|
||||||
|
ChatMsg(ChatMessageType.UNK_227, "@FacilityRequiresResourcesForHackWarning")
|
||||||
|
)
|
||||||
|
}
|
||||||
// Push map update to clients
|
// Push map update to clients
|
||||||
owner.Zone.actor ! ZoneActor.ZoneMapUpdate()
|
owner.Zone.actor ! ZoneActor.ZoneMapUpdate()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue