announce ams decay to players who have just spawned on an ams, when they spawn on that ams, and for the last round of spawnees when the vehicle finally deconstructs; due to use of the word 'bound' this may be an incorrect application, but matrixing doesn't work anyway

This commit is contained in:
Fate-JH 2024-08-22 00:00:25 -04:00
parent 00e985516a
commit 2e901ae904
8 changed files with 91 additions and 38 deletions

View file

@ -14,7 +14,7 @@ import net.psforever.packet.game.objectcreate.ObjectCreateMessageParent
import net.psforever.packet.game.{ChangeAmmoMessage, ChangeFireStateMessage_Start, ChangeFireStateMessage_Stop, ChatMsg, ChildObjectStateMessage, DeadState, DeployRequestMessage, DismountVehicleMsg, FrameVehicleStateMessage, GenericObjectActionMessage, HitHint, InventoryStateMessage, ObjectAttachMessage, ObjectCreateDetailedMessage, ObjectCreateMessage, ObjectDeleteMessage, ObjectDetachMessage, PlanetsideAttributeMessage, ReloadMessage, ServerVehicleOverrideMsg, VehicleStateMessage, WeaponDryFireMessage}
import net.psforever.services.Service
import net.psforever.services.vehicle.{VehicleResponse, VehicleServiceResponse}
import net.psforever.types.{BailType, ChatMessageType, PlanetSideGUID, Vector3}
import net.psforever.types.{BailType, ChatMessageType, DriveState, PlanetSideGUID, Vector3}
object VehicleHandlerLogic {
def apply(ops: SessionVehicleHandlers): VehicleHandlerLogic = {
@ -207,6 +207,9 @@ class VehicleHandlerLogic(val ops: SessionVehicleHandlers, implicit val context:
avatarActor ! AvatarActor.SetVehicle(Some(vehicleGuid))
sendResponse(PlanetsideAttributeMessage(resolvedPlayerGuid, attribute_type=21, vehicleGuid))
case VehicleResponse.LoseOwnership(_, vehicleGuid) =>
ops.announceAmsDecay(vehicleGuid,msg = "@ams_decaystarted")
case VehicleResponse.PlanetsideAttribute(vehicleGuid, attributeType, attributeValue) if isNotSameTarget =>
sendResponse(PlanetsideAttributeMessage(vehicleGuid, attributeType, attributeValue))
@ -225,6 +228,16 @@ class VehicleHandlerLogic(val ops: SessionVehicleHandlers, implicit val context:
case VehicleResponse.UnloadVehicle(_, vehicleGuid) =>
sendResponse(ObjectDeleteMessage(vehicleGuid, unk1=0))
if (sessionLogic.zoning.spawn.prevSpawnPoint.map(_.Owner).exists {
case ams: Vehicle =>
ams.GUID == vehicleGuid &&
ams.OwnerGuid.isEmpty
case _ =>
false
}) {
sessionLogic.zoning.spawn.prevSpawnPoint = None
sendResponse(ChatMsg(ChatMessageType.UNK_229, "@ams_decayed"))
}
case VehicleResponse.UnstowEquipment(itemGuid) if isNotSameTarget =>
//TODO prefer ObjectDetachMessage, but how to force ammo pools to update properly?

View file

@ -3,8 +3,10 @@ package net.psforever.actors.session.support
import akka.actor.{ActorContext, ActorRef, typed}
import net.psforever.actors.session.AvatarActor
import net.psforever.objects.Vehicle
import net.psforever.packet.game.ChatMsg
import net.psforever.services.vehicle.VehicleResponse
import net.psforever.types.PlanetSideGUID
import net.psforever.types.{ChatMessageType, DriveState, PlanetSideGUID}
trait VehicleHandlerFunctions extends CommonSessionInterfacingFunctionality {
def ops: SessionVehicleHandlers
@ -17,4 +19,17 @@ class SessionVehicleHandlers(
val avatarActor: typed.ActorRef[AvatarActor.Command],
val galaxyService: ActorRef,
implicit val context: ActorContext
) extends CommonSessionInterfacingFunctionality
) extends CommonSessionInterfacingFunctionality {
def announceAmsDecay(vehicleGuid: PlanetSideGUID, msg: String): Unit = {
if (sessionLogic.zoning.spawn.prevSpawnPoint.map(_.Owner).exists {
case ams: Vehicle =>
ams.GUID == vehicleGuid &&
ams.DeploymentState == DriveState.Deployed &&
ams.OwnerGuid.isEmpty
case _ =>
false
}) {
sendResponse(ChatMsg(ChatMessageType.UNK_229, msg))
}
}
}

View file

@ -1792,6 +1792,7 @@ class ZoningOperations(
private[session] var setupAvatarFunc: () => Unit = AvatarCreate
private[session] var setCurrentAvatarFunc: Player => Unit = SetCurrentAvatarNormally
private[session] var nextSpawnPoint: Option[SpawnPoint] = None
private[session] var prevSpawnPoint: Option[SpawnPoint] = None
private[session] var interimUngunnedVehicle: Option[PlanetSideGUID] = None
private[session] var interimUngunnedVehicleSeat: Option[Int] = None
/** Upstream message counter<br>
@ -2811,6 +2812,7 @@ class ZoningOperations(
)
)
nextSpawnPoint = physSpawnPoint
prevSpawnPoint = physSpawnPoint
shiftPosition = Some(pos)
shiftOrientation = Some(ori)
val toZoneNumber = if (continent.id.equals(zoneId)) {
@ -2819,10 +2821,14 @@ class ZoningOperations(
Zones.zones.find { _.id.equals(zoneId) }.orElse(Some(Zone.Nowhere)).get.Number
}
val toSide = physSpawnPoint.map(_.Owner) match {
case Some(_: WarpGate) => Sidedness.OutsideOf
case Some(_: Building) => Sidedness.InsideOf
case Some(v: Vehicle) => v.WhichSide //though usually OutsideOf
case _ => Sidedness.StrictlyBetweenSides //todo needs better determination
case Some(_: WarpGate) =>
Sidedness.OutsideOf
case Some(_: Building) =>
Sidedness.InsideOf
case Some(v: Vehicle) =>
v.WhichSide //though usually OutsideOf
case _ =>
Sidedness.StrictlyBetweenSides //todo needs better determination
}
val toSpawnPoint = physSpawnPoint.collect { case o: PlanetSideGameObject with FactionAffinity => SourceEntry(o) }
respawnTimer = context.system.scheduler.scheduleOnce(respawnTime) {
@ -3124,11 +3130,17 @@ class ZoningOperations(
Config.app.game.savedMsg.short.fixed,
Config.app.game.savedMsg.short.variable
)
val effortBy = nextSpawnPoint
val effortBy = prevSpawnPoint
.collect { case sp: SpawnTube => (sp, continent.GUID(sp.Owner.GUID)) }
.collect {
case (_, Some(v: Vehicle)) => continent.GUID(v.OwnerGuid)
case (sp, Some(_: Building)) => Some(sp)
case (_, Some(v: Vehicle)) =>
sessionLogic.vehicleResponseOperations.announceAmsDecay(
v.GUID,
msg = "The AMS you were bound to has lost its' owner. It will auto-deconstruct soon."
)
continent.GUID(v.OwnerGuid)
case (sp, Some(_: Building)) =>
Some(sp)
}
.collect { case Some(thing: PlanetSideGameObject with FactionAffinity) => Some(SourceEntry(thing)) }
.flatten

View file

@ -46,7 +46,7 @@ object Vehicles {
vehicle.Zone.id,
VehicleAction.Ownership(tplayer.GUID, vehicle.GUID)
)
Vehicles.ReloadAccessPermissions(vehicle, tplayer.Name)
Vehicles.ReloadAccessPermissions(vehicle, tplayer.Faction.toString)
Some(vehicle)
case None =>
None
@ -61,31 +61,37 @@ object Vehicles {
* @return the vehicle, if it had a previous owner;
* `None`, otherwise
*/
def Disown(guid: PlanetSideGUID, vehicle: Vehicle): Option[Vehicle] =
vehicle.Zone.GUID(vehicle.OwnerGuid) match {
case Some(player: Player) =>
if (player.avatar.vehicle.contains(guid)) {
player.avatar.vehicle = None
// vehicle.Zone.VehicleEvents ! VehicleServiceMessage(
// player.Name,
// VehicleAction.Ownership(player.GUID, PlanetSideGUID(0))
// )
}
vehicle.AssignOwnership(None)
val empire = VehicleLockState.Empire.id
//val factionChannel = s"${vehicle.Faction}"
(0 to 2).foreach(group => {
vehicle.PermissionGroup(group, empire)
/*vehicle.Zone.VehicleEvents ! VehicleServiceMessage(
factionChannel,
VehicleAction.SeatPermissions(Service.defaultPlayerGUID, guid, group, empire)
)*/
})
ReloadAccessPermissions(vehicle, player.Name)
Some(vehicle)
case _ =>
None
}
def Disown(guid: PlanetSideGUID, vehicle: Vehicle): Option[Vehicle] = {
val zone = vehicle.Zone
val ownerGuid = vehicle.OwnerGuid
val ownerName = vehicle.OwnerName
vehicle.AssignOwnership(None)
val result = zone
.GUID(ownerGuid)
.collect {
case player: Player => player.avatar
}
.orElse {
zone
.Players
.collectFirst {
case avatar if ownerName.contains(avatar.name) => avatar
}
}
.collect {
case avatar if avatar.vehicle.contains(guid) =>
avatar.vehicle = None
vehicle
}
val empire = VehicleLockState.Empire.id
(0 to 2).foreach(group => vehicle.PermissionGroup(group, empire))
ReloadAccessPermissions(vehicle, vehicle.Faction.toString)
zone.VehicleEvents ! VehicleServiceMessage(
zone.id,
VehicleAction.LoseOwnership(ownerGuid.getOrElse(Service.defaultPlayerGUID), guid)
)
result
}
/**
* Disassociate a player from a vehicle that he owns.
@ -140,7 +146,7 @@ object Vehicles {
VehicleAction.SeatPermissions(pguid, vguid, group, empire)
)*/
})
ReloadAccessPermissions(vehicle, player.Name)
ReloadAccessPermissions(vehicle, vehicle.Faction.toString)
Some(vehicle)
} else {
None

View file

@ -971,7 +971,7 @@ object GlobalDefinitionsVehicle {
ams.DeployTime = 2000
ams.UndeployTime = 2000
ams.interference = InterferenceRange(main = 125f, sharedGroupId = 3, shared = 30f)
ams.DeconstructionTime = Some(20 minutes)
ams.DeconstructionTime = Some(15 minutes)
ams.AutoPilotSpeeds = (18, 6)
ams.Packet = utilityConverter
ams.DestroyedModel = Some(DestroyedVehicle.Ams)

View file

@ -184,6 +184,10 @@ class VehicleService(zone: Zone) extends Actor {
VehicleResponse.MountVehicle(vehicle_guid, seat)
)
)
case VehicleAction.LoseOwnership(owner_guid, vehicle_guid) =>
VehicleEvents.publish(
VehicleServiceResponse(s"/$forChannel/Vehicle", Service.defaultPlayerGUID, VehicleResponse.LoseOwnership(owner_guid, vehicle_guid))
)
case VehicleAction.Ownership(player_guid, vehicle_guid) =>
VehicleEvents.publish(
VehicleServiceResponse(s"/$forChannel/Vehicle", player_guid, VehicleResponse.Ownership(vehicle_guid))

View file

@ -93,6 +93,7 @@ object VehicleAction {
) extends Action
final case class MountVehicle(player_guid: PlanetSideGUID, object_guid: PlanetSideGUID, seat: Int) extends Action
final case class ObjectDelete(guid: PlanetSideGUID) extends Action
final case class LoseOwnership(owner_guid: PlanetSideGUID, vehicle_guid: PlanetSideGUID) extends Action
final case class Ownership(player_guid: PlanetSideGUID, vehicle_guid: PlanetSideGUID) extends Action
final case class PlanetsideAttribute(
player_guid: PlanetSideGUID,

View file

@ -74,6 +74,8 @@ object VehicleResponse {
final case class MountVehicle(object_guid: PlanetSideGUID, seat: Int) extends Response
final case class ObjectDelete(guid: PlanetSideGUID) extends Response
final case class Ownership(vehicle_guid: PlanetSideGUID) extends Response
final case class LoseOwnership(owner_guid: PlanetSideGUID, vehicle_guid: PlanetSideGUID)
extends Response
final case class PlanetsideAttribute(vehicle_guid: PlanetSideGUID, attribute_type: Int, attribute_value: Long)
extends Response
final case class Reload(weapon_guid: PlanetSideGUID) extends Response