restored commands setbr and setcr; deployables are erased from spectator map; projectiles destruction only just in case

This commit is contained in:
Fate-JH 2024-05-10 09:36:48 -04:00
parent 00a76deda0
commit 61c34d040c
5 changed files with 67 additions and 156 deletions

View file

@ -4,28 +4,21 @@ package net.psforever.actors.session.spectator
import akka.actor.{ActorContext, typed} import akka.actor.{ActorContext, typed}
import net.psforever.actors.session.AvatarActor import net.psforever.actors.session.AvatarActor
import net.psforever.actors.session.support.{GeneralFunctions, GeneralOperations, SessionData} import net.psforever.actors.session.support.{GeneralFunctions, GeneralOperations, SessionData}
import net.psforever.login.WorldSession.RemoveOldEquipmentFromInventory import net.psforever.objects.{Account, GlobalDefinitions, LivePlayerList, PlanetSideGameObject, Player, TelepadDeployable, Tool, Vehicle}
import net.psforever.objects.{Account, BoomerDeployable, BoomerTrigger, GlobalDefinitions, LivePlayerList, PlanetSideGameObject, Player, TelepadDeployable, Tool, Vehicle}
import net.psforever.objects.avatar.{Avatar, Implant} import net.psforever.objects.avatar.{Avatar, Implant}
import net.psforever.objects.ballistics.Projectile import net.psforever.objects.ballistics.Projectile
import net.psforever.objects.ce.{Deployable, TelepadLike} import net.psforever.objects.ce.{Deployable, TelepadLike}
import net.psforever.objects.definition.{BasicDefinition, KitDefinition, SpecialExoSuitDefinition} import net.psforever.objects.definition.{BasicDefinition, KitDefinition, SpecialExoSuitDefinition}
import net.psforever.objects.equipment.Equipment import net.psforever.objects.equipment.Equipment
import net.psforever.objects.guid.{GUIDTask, TaskWorkflow} import net.psforever.objects.serverobject.CommonMessages
import net.psforever.objects.inventory.Container
import net.psforever.objects.serverobject.{CommonMessages, PlanetSideServerObject}
import net.psforever.objects.serverobject.doors.Door import net.psforever.objects.serverobject.doors.Door
import net.psforever.objects.sourcing.{PlayerSource, VehicleSource}
import net.psforever.objects.vehicles.{Utility, UtilityType} import net.psforever.objects.vehicles.{Utility, UtilityType}
import net.psforever.objects.vehicles.Utility.InternalTelepad import net.psforever.objects.vehicles.Utility.InternalTelepad
import net.psforever.objects.vital.{VehicleDismountActivity, VehicleMountActivity} import net.psforever.objects.zones.ZoneProjectile
import net.psforever.objects.zones.{Zone, ZoneProjectile}
import net.psforever.packet.PlanetSideGamePacket import net.psforever.packet.PlanetSideGamePacket
import net.psforever.packet.game.{ActionCancelMessage, AvatarFirstTimeEventMessage, AvatarImplantMessage, AvatarJumpMessage, BattleplanMessage, BindPlayerMessage, BugReportMessage, ChangeFireModeMessage, ChangeShortcutBankMessage, CharacterCreateRequestMessage, CharacterRequestMessage, ChatMsg, ConnectToWorldRequestMessage, CreateShortcutMessage, DeployObjectMessage, DisplayedAwardMessage, DropItemMessage, EmoteMsg, FacilityBenefitShieldChargeRequestMessage, FriendsRequest, GenericAction, GenericActionMessage, GenericCollisionMsg, GenericObjectActionAtPositionMessage, GenericObjectActionMessage, GenericObjectStateMsg, HitHint, ImplantAction, InvalidTerrainMessage, LootItemMessage, MoveItemMessage, ObjectDeleteMessage, ObjectDetectedMessage, ObjectHeldMessage, PickupItemMessage, PlanetsideAttributeMessage, PlayerStateMessageUpstream, PlayerStateShiftMessage, RequestDestroyMessage, ShiftState, TargetInfo, TargetingImplantRequest, TargetingInfoMessage, TradeMessage, UnuseItemMessage, UseItemMessage, VoiceHostInfo, VoiceHostKill, VoiceHostRequest, ZipLineMessage} import net.psforever.packet.game.{ActionCancelMessage, AvatarFirstTimeEventMessage, AvatarImplantMessage, AvatarJumpMessage, BattleplanMessage, BindPlayerMessage, BugReportMessage, ChangeFireModeMessage, ChangeShortcutBankMessage, CharacterCreateRequestMessage, CharacterRequestMessage, ChatMsg, ConnectToWorldRequestMessage, CreateShortcutMessage, DeployObjectMessage, DisplayedAwardMessage, DropItemMessage, EmoteMsg, FacilityBenefitShieldChargeRequestMessage, FriendsRequest, GenericAction, GenericActionMessage, GenericCollisionMsg, GenericObjectActionAtPositionMessage, GenericObjectActionMessage, GenericObjectStateMsg, HitHint, ImplantAction, InvalidTerrainMessage, LootItemMessage, MoveItemMessage, ObjectDetectedMessage, ObjectHeldMessage, PickupItemMessage, PlanetsideAttributeMessage, PlayerStateMessageUpstream, PlayerStateShiftMessage, RequestDestroyMessage, ShiftState, TargetInfo, TargetingImplantRequest, TargetingInfoMessage, TradeMessage, UnuseItemMessage, UseItemMessage, VoiceHostInfo, VoiceHostKill, VoiceHostRequest, ZipLineMessage}
import net.psforever.services.RemoverActor
import net.psforever.services.account.AccountPersistenceService import net.psforever.services.account.AccountPersistenceService
import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage}
import net.psforever.services.local.{LocalAction, LocalServiceMessage}
import net.psforever.types.{ChatMessageType, DriveState, ExoSuitType, PlanetSideGUID, Vector3} import net.psforever.types.{ChatMessageType, DriveState, ExoSuitType, PlanetSideGUID, Vector3}
import net.psforever.util.Config import net.psforever.util.Config
@ -158,18 +151,6 @@ class GeneralLogic(val ops: GeneralOperations, implicit val context: ActorContex
} }
continent.Projectile ! ZoneProjectile.Remove(objectGuid) continent.Projectile ! ZoneProjectile.Remove(objectGuid)
case Some(obj: BoomerTrigger) =>
if (findEquipmentToDelete(objectGuid, obj)) {
continent.GUID(obj.Companion) match {
case Some(boomer: BoomerDeployable) =>
boomer.Trigger = None
boomer.Actor ! Deployable.Deconstruct()
case Some(thing) =>
log.warn(s"RequestDestroy: BoomerTrigger object connected to wrong object - $thing")
case None => ()
}
}
case _ => () case _ => ()
} }
} }
@ -538,78 +519,6 @@ class GeneralLogic(val ops: GeneralOperations, implicit val context: ActorContex
} }
} }
/**
* Get the current `Vehicle` object that the player is riding/driving.
* The vehicle must be found solely through use of `player.VehicleSeated`.
* @return the vehicle
*/
private def findLocalVehicle: Option[Vehicle] = {
continent.GUID(player.VehicleSeated) match {
case Some(obj: Vehicle) => Some(obj)
case _ => None
}
}
/**
* A simple object searching algorithm that is limited to containers currently known and accessible by the player.
* If all relatively local containers are checked and the object is not found,
* the player's locker inventory will be checked, and then
* the game environment (items on the ground) will be checked too.
* If the target object is discovered, it is removed from its current location and is completely destroyed.
* @see `RequestDestroyMessage`
* @see `Zone.ItemIs.Where`
* @param objectGuid the target object's globally unique identifier;
* it is not expected that the object will be unregistered, but it is also not gauranteed
* @param obj the target object
* @return `true`, if the target object was discovered and removed;
* `false`, otherwise
*/
private def findEquipmentToDelete(objectGuid: PlanetSideGUID, obj: Equipment): Boolean = {
val findFunc
: PlanetSideServerObject with Container => Option[(PlanetSideServerObject with Container, Option[Int])] =
ops.findInLocalContainer(objectGuid)
findFunc(player)
.orElse(ops.accessedContainer match {
case Some(parent: PlanetSideServerObject) =>
findFunc(parent)
case _ =>
None
})
.orElse(findLocalVehicle match {
case Some(parent: PlanetSideServerObject) =>
findFunc(parent)
case _ =>
None
}) match {
case Some((parent, Some(_))) =>
obj.Position = Vector3.Zero
RemoveOldEquipmentFromInventory(parent)(obj)
true
case _ if player.avatar.locker.Inventory.Remove(objectGuid) =>
sendResponse(ObjectDeleteMessage(objectGuid, 0))
true
case _ if continent.EquipmentOnGround.contains(obj) =>
obj.Position = Vector3.Zero
continent.Ground ! Zone.Ground.RemoveItem(objectGuid)
continent.AvatarEvents ! AvatarServiceMessage.Ground(RemoverActor.ClearSpecific(List(obj), continent))
true
case _ =>
Zone.EquipmentIs.Where(obj, objectGuid, continent) match {
case None =>
true
case Some(Zone.EquipmentIs.Orphaned()) if obj.HasGUID =>
TaskWorkflow.execute(GUIDTask.unregisterEquipment(continent.GUID, obj))
true
case Some(Zone.EquipmentIs.Orphaned()) =>
true
case _ =>
log.warn(s"RequestDestroy: equipment $obj exists, but ${player.Name} can not reach it to dispose of it")
false
}
}
}
/** /**
* A player uses a fully-linked Router teleportation system. * A player uses a fully-linked Router teleportation system.
* @param router the Router vehicle * @param router the Router vehicle
@ -636,15 +545,7 @@ class GeneralLogic(val ops: GeneralOperations, implicit val context: ActorContex
val dguid = dest.GUID val dguid = dest.GUID
sendResponse(PlayerStateShiftMessage(ShiftState(0, dest.Position, player.Orientation.z))) sendResponse(PlayerStateShiftMessage(ShiftState(0, dest.Position, player.Orientation.z)))
ops.useRouterTelepadEffect(pguid, sguid, dguid) ops.useRouterTelepadEffect(pguid, sguid, dguid)
continent.LocalEvents ! LocalServiceMessage(
continent.id,
LocalAction.RouterTelepadTransport(pguid, pguid, sguid, dguid)
)
val vSource = VehicleSource(router)
val zoneNumber = continent.Number
player.LogActivity(VehicleMountActivity(vSource, PlayerSource(player), zoneNumber))
player.Position = dest.Position player.Position = dest.Position
player.LogActivity(VehicleDismountActivity(vSource, PlayerSource(player), zoneNumber))
} else { } else {
log.warn(s"UseRouterTelepadSystem: ${player.Name} can not teleport") log.warn(s"UseRouterTelepadSystem: ${player.Name} can not teleport")
} }

View file

@ -6,11 +6,13 @@ import akka.actor.ActorRef
import net.psforever.actors.session.support.{AvatarHandlerFunctions, ChatFunctions, GalaxyHandlerFunctions, GeneralFunctions, LocalHandlerFunctions, MountHandlerFunctions, SquadHandlerFunctions, TerminalHandlerFunctions, VehicleFunctions, VehicleHandlerFunctions, WeaponAndProjectileFunctions} import net.psforever.actors.session.support.{AvatarHandlerFunctions, ChatFunctions, GalaxyHandlerFunctions, GeneralFunctions, LocalHandlerFunctions, MountHandlerFunctions, SquadHandlerFunctions, TerminalHandlerFunctions, VehicleFunctions, VehicleHandlerFunctions, WeaponAndProjectileFunctions}
import net.psforever.actors.zone.ZoneActor import net.psforever.actors.zone.ZoneActor
import net.psforever.objects.avatar.{BattleRank, CommandRank, DeployableToolbox, FirstTimeEvents, Implant, ProgressDecoration, Shortcut => AvatarShortcut} import net.psforever.objects.avatar.{BattleRank, CommandRank, DeployableToolbox, FirstTimeEvents, Implant, ProgressDecoration, Shortcut => AvatarShortcut}
import net.psforever.objects.ce.Deployable
import net.psforever.objects.serverobject.ServerObject import net.psforever.objects.serverobject.ServerObject
import net.psforever.objects.{GlobalDefinitions, Player, Session, SimpleItem, Vehicle} import net.psforever.objects.{GlobalDefinitions, Player, Session, SimpleItem, Vehicle}
import net.psforever.packet.PlanetSidePacket import net.psforever.packet.PlanetSidePacket
import net.psforever.packet.game.{ObjectCreateDetailedMessage, ObjectDeleteMessage} import net.psforever.packet.game.{DeployableInfo, DeployableObjectsInfoMessage, DeploymentAction, ObjectCreateDetailedMessage, ObjectDeleteMessage}
import net.psforever.packet.game.objectcreate.{ObjectClass, ObjectCreateMessageParent, RibbonBars} import net.psforever.packet.game.objectcreate.{ObjectClass, ObjectCreateMessageParent, RibbonBars}
import net.psforever.services.Service
import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage}
import net.psforever.services.chat.{ChatService, SpectatorChannel} import net.psforever.services.chat.{ChatService, SpectatorChannel}
import net.psforever.services.teamwork.{SquadAction, SquadServiceMessage} import net.psforever.services.teamwork.{SquadAction, SquadServiceMessage}
@ -122,6 +124,16 @@ class SpectatorModeLogic(data: SessionData) extends ModeLogic {
.collect { case Some(implant) if implant.active => .collect { case Some(implant) if implant.active =>
data.general.avatarActor ! AvatarActor.DeactivateImplant(implant.definition.implantType) data.general.avatarActor ! AvatarActor.DeactivateImplant(implant.definition.implantType)
} }
val playerFaction = player.Faction
continent
.DeployableList
.filter(_.Faction == playerFaction)
.foreach { obj =>
sendResponse(DeployableObjectsInfoMessage(
DeploymentAction.Dismiss,
DeployableInfo(obj.GUID, Deployable.Icon.apply(obj.Definition.Item), obj.Position, Service.defaultPlayerGUID)
))
}
if (player.silenced) { if (player.silenced) {
data.chat.commandIncomingSilence(session, ChatMsg(ChatMessageType.CMT_SILENCE, "player 0")) data.chat.commandIncomingSilence(session, ChatMsg(ChatMessageType.CMT_SILENCE, "player 0"))
} }

View file

@ -911,7 +911,7 @@ class ChatOperations(
} }
(target, rank) match { (target, rank) match {
case (_, Some(rank)) if rank.value <= Config.app.game.maxBattleRank => case (_, Some(rank)) if rank.value <= Config.app.game.maxBattleRank =>
context.self ! msgFunc(rank.experience) avatarActor ! msgFunc(rank.experience)
true true
case _ => case _ =>
false false
@ -941,7 +941,7 @@ class ChatOperations(
} }
(target, rank) match { (target, rank) match {
case (_, Some(rank)) => case (_, Some(rank)) =>
context.self ! AvatarActor.SetCep(rank.experience) avatarActor ! AvatarActor.SetCep(rank.experience)
true true
case _ => case _ =>
false false

View file

@ -13,6 +13,8 @@ import net.psforever.services.Service
import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage} import net.psforever.services.avatar.{AvatarAction, AvatarServiceMessage}
import net.psforever.types.PlanetSideEmpire import net.psforever.types.PlanetSideEmpire
import scala.annotation.unused
class BoomerDeployable(cdef: ExplosiveDeployableDefinition) class BoomerDeployable(cdef: ExplosiveDeployableDefinition)
extends ExplosiveDeployable(cdef) { extends ExplosiveDeployable(cdef) {
private var trigger: Option[BoomerTrigger] = None private var trigger: Option[BoomerTrigger] = None
@ -70,8 +72,8 @@ class BoomerDeployableControl(mine: BoomerDeployable)
case _ => ; case _ => ;
} }
override def loseOwnership(faction: PlanetSideEmpire.Value): Unit = { def loseOwnership(@unused faction: PlanetSideEmpire.Value): Unit = {
super.loseOwnership(PlanetSideEmpire.NEUTRAL) super.loseOwnership(mine, PlanetSideEmpire.NEUTRAL)
val guid = mine.OwnerGuid val guid = mine.OwnerGuid
mine.AssignOwnership(None) mine.AssignOwnership(None)
mine.OwnerGuid = guid mine.OwnerGuid = guid

View file

@ -69,7 +69,7 @@ trait DeployableBehavior {
if DeployableObject.OwnerGuid.nonEmpty => if DeployableObject.OwnerGuid.nonEmpty =>
val obj = DeployableObject val obj = DeployableObject
if (constructed.contains(true)) { if (constructed.contains(true)) {
loseOwnership(obj.Faction) loseOwnership(obj, obj.Faction)
} else { } else {
obj.OwnerGuid = None obj.OwnerGuid = None
} }
@ -98,35 +98,16 @@ trait DeployableBehavior {
* Losing ownership involves updating map screen UI, to remove management rights from the now-previous owner, * Losing ownership involves updating map screen UI, to remove management rights from the now-previous owner,
* and may involve concealing the deployable from the map screen for the entirety of the previous owner's faction. * and may involve concealing the deployable from the map screen for the entirety of the previous owner's faction.
* Displaying the deployable on the map screen of another faction may be required. * Displaying the deployable on the map screen of another faction may be required.
* @param obj na
* @param toFaction the faction to which to set the deployable to be visualized on the map and in the game world; * @param toFaction the faction to which to set the deployable to be visualized on the map and in the game world;
* may also affect deployable operation * may also affect deployable operation
*/ */
def loseOwnership(toFaction: PlanetSideEmpire.Value): Unit = { def loseOwnership(obj: Deployable, toFaction: PlanetSideEmpire.Value): Unit = {
val obj = DeployableObject DeployableBehavior.changeOwership(
val guid = obj.GUID obj,
val zone = obj.Zone obj.Faction,
val localEvents = zone.LocalEvents DeployableInfo(obj.GUID, Deployable.Icon.apply(obj.Definition.Item), obj.Position, Service.defaultPlayerGUID)
val originalFaction = obj.Faction )
val changeFaction = originalFaction != toFaction
val info = DeployableInfo(guid, DeployableIcon.Boomer, obj.Position, Service.defaultPlayerGUID)
if (changeFaction) {
obj.Faction = toFaction
//visual tells in regards to ownership by faction
zone.AvatarEvents ! AvatarServiceMessage(
zone.id,
AvatarAction.SetEmpire(Service.defaultPlayerGUID, guid, toFaction)
)
//remove knowledge by the previous owner's faction
localEvents ! LocalServiceMessage(
originalFaction.toString,
LocalAction.DeployableMapIcon(Service.defaultPlayerGUID, DeploymentAction.Dismiss, info)
)
//display to the given faction
localEvents ! LocalServiceMessage(
toFaction.toString,
LocalAction.DeployableMapIcon(Service.defaultPlayerGUID, DeploymentAction.Build, info)
)
}
startOwnerlessDecay() startOwnerlessDecay()
} }
@ -159,27 +140,11 @@ trait DeployableBehavior {
val obj = DeployableObject val obj = DeployableObject
obj.AssignOwnership(player) obj.AssignOwnership(player)
decay.cancel() decay.cancel()
DeployableBehavior.changeOwership(
val guid = obj.GUID obj,
val zone = obj.Zone toFaction,
val originalFaction = obj.Faction DeployableInfo(obj.GUID, Deployable.Icon.apply(obj.Definition.Item), obj.Position, obj.OwnerGuid.get)
val info = DeployableInfo(guid, DeployableIcon.Boomer, obj.Position, obj.OwnerGuid.get) )
if (originalFaction != toFaction) {
obj.Faction = toFaction
val localEvents = zone.LocalEvents
zone.AvatarEvents ! AvatarServiceMessage(
zone.id,
AvatarAction.SetEmpire(Service.defaultPlayerGUID, guid, toFaction)
)
localEvents ! LocalServiceMessage(
originalFaction.toString,
LocalAction.DeployableMapIcon(Service.defaultPlayerGUID, DeploymentAction.Dismiss, info)
)
localEvents ! LocalServiceMessage(
toFaction.toString,
LocalAction.DeployableMapIcon(Service.defaultPlayerGUID, DeploymentAction.Build, info)
)
}
} }
/** /**
@ -318,4 +283,35 @@ object DeployableBehavior {
/** internal message for progresisng the deconstruction process */ /** internal message for progresisng the deconstruction process */
private case class FinalizeElimination() private case class FinalizeElimination()
/**
* na
* @param obj na
* @param toFaction na
* @param info na
*/
def changeOwership(obj: Deployable, toFaction: PlanetSideEmpire.Value, info: DeployableInfo): Unit = {
val guid = obj.GUID
val zone = obj.Zone
val localEvents = zone.LocalEvents
val originalFaction = obj.Faction
if (originalFaction != toFaction) {
obj.Faction = toFaction
//visual tells in regards to ownership by faction
zone.AvatarEvents ! AvatarServiceMessage(
zone.id,
AvatarAction.SetEmpire(Service.defaultPlayerGUID, guid, toFaction)
)
//remove knowledge by the previous owner's faction
localEvents ! LocalServiceMessage(
originalFaction.toString,
LocalAction.DeployableMapIcon(Service.defaultPlayerGUID, DeploymentAction.Dismiss, info)
)
//display to the given faction
localEvents ! LocalServiceMessage(
toFaction.toString,
LocalAction.DeployableMapIcon(Service.defaultPlayerGUID, DeploymentAction.Build, info)
)
}
}
} }