From 9698ddd5a2c7651dacb7f6e387dfc435a6460443 Mon Sep 17 00:00:00 2001 From: Fate-JH Date: Fri, 15 May 2026 01:02:52 -0400 Subject: [PATCH] O I C Which Side (#1368) * oicw little buddy proxy damage carrier class did not project sidedness to the server side damage protocol, skipping sidedness check altogether * oicw allowed * set proper projectile origin * unrelated to the oicw, when a csr uses warp with coordinate literals, a reminder to set the sidedness correctly is issued; additionally, when using warp with a poi, the sidedness is set to outside of --- .../resources/overrides/game_objects0.adb.lst | 2 +- .../actors/session/csr/ChatLogic.scala | 4 +-- .../actors/session/normal/ChatLogic.scala | 26 +++++++++++++++++++ .../session/support/ChatOperations.scala | 15 +++++++++++ .../WeaponAndProjectileOperations.scala | 2 +- .../objects/DummyExplodingEntity.scala | 21 ++++++++++++--- .../net/psforever/objects/zones/Zone.scala | 4 +-- 7 files changed, 64 insertions(+), 10 deletions(-) diff --git a/server/src/main/resources/overrides/game_objects0.adb.lst b/server/src/main/resources/overrides/game_objects0.adb.lst index 0bc9a4c3f..12745e33d 100644 --- a/server/src/main/resources/overrides/game_objects0.adb.lst +++ b/server/src/main/resources/overrides/game_objects0.adb.lst @@ -64,7 +64,7 @@ add_property mini_chaingun equiptime 750 add_property mini_chaingun holstertime 750 add_property nano_dispenser equiptime 750 add_property nano_dispenser holstertime 750 -add_property oicw allowed false +add_property oicw allowed true add_property pellet_gun equiptime 600 add_property pellet_gun holstertime 600 add_property peregrine_flight requirement_award0 false diff --git a/src/main/scala/net/psforever/actors/session/csr/ChatLogic.scala b/src/main/scala/net/psforever/actors/session/csr/ChatLogic.scala index d36fbafbb..3d5d4c45b 100644 --- a/src/main/scala/net/psforever/actors/session/csr/ChatLogic.scala +++ b/src/main/scala/net/psforever/actors/session/csr/ChatLogic.scala @@ -558,9 +558,9 @@ class ChatLogic(val ops: ChatOperations, implicit val context: ActorContext) ext var postUsageMessage: Boolean = false contents.headOption match { case Some(side) if side.matches("i|in|inside") => - session.player.WhichSide = Sidedness.InsideOf + ops.customSetSidednessOfTarget(session.player, Sidedness.InsideOf) case Some(side) if side.matches("o|out|outside") => - session.player.WhichSide = Sidedness.OutsideOf + ops.customSetSidednessOfTarget(session.player, Sidedness.OutsideOf) case Some("check") => val whichSide = if (session.player.WhichSide == Sidedness.OutsideOf) { "outside" diff --git a/src/main/scala/net/psforever/actors/session/normal/ChatLogic.scala b/src/main/scala/net/psforever/actors/session/normal/ChatLogic.scala index 552063184..d989103a9 100644 --- a/src/main/scala/net/psforever/actors/session/normal/ChatLogic.scala +++ b/src/main/scala/net/psforever/actors/session/normal/ChatLogic.scala @@ -6,6 +6,7 @@ import net.psforever.actors.session.SessionActor import net.psforever.actors.session.spectator.SpectatorMode import net.psforever.actors.session.support.{ChatFunctions, ChatOperations, SessionData} import net.psforever.objects.Session +import net.psforever.objects.serverobject.interior.Sidedness import net.psforever.packet.game.{ChatMsg, ServerType, SetChatFilterMessage} import net.psforever.services.chat.{DefaultChannel, OutfitChannel, SquadChannel} import net.psforever.types.ChatMessageType @@ -142,6 +143,7 @@ class ChatLogic(val ops: ChatOperations, implicit val context: ActorContext) ext case "macro" => ops.customCommandMacro(session, params) case "progress" => ops.customCommandProgress(session, params) case "squad" => ops.customCommandSquad(params) + case "setside" => customSetSidedness(session, params) case _ => // command was not handled sendResponse( @@ -208,4 +210,28 @@ class ChatLogic(val ops: ChatOperations, implicit val context: ActorContext) ext } } } + + private def customSetSidedness(session: Session, contents: Seq[String]): Boolean = { + var postUsageMessage: Boolean = false + contents.headOption match { + case Some("check") => + val whichSide = if (session.player.WhichSide == Sidedness.OutsideOf) { + "outside" + } else { + "inside" + } + sendResponse(ChatMsg(ChatMessageType.UNK_227, s"You are $whichSide.")) + case Some("help") | Some("usage") => + postUsageMessage = true + case Some(token) => + sendResponse(ChatMsg(ChatMessageType.UNK_227, s"unknown command - $token")) + postUsageMessage = true + case None => + postUsageMessage = true + } + if (postUsageMessage) { + sendResponse(ChatMsg(ChatMessageType.UNK_227, "!setside check")) + } + true + } } diff --git a/src/main/scala/net/psforever/actors/session/support/ChatOperations.scala b/src/main/scala/net/psforever/actors/session/support/ChatOperations.scala index a08090b17..b721628b3 100644 --- a/src/main/scala/net/psforever/actors/session/support/ChatOperations.scala +++ b/src/main/scala/net/psforever/actors/session/support/ChatOperations.scala @@ -11,6 +11,8 @@ import net.psforever.actors.session.spectator.SpectatorMode import net.psforever.actors.session.{AvatarActor, SessionActor} import net.psforever.actors.zone.ZoneActor import net.psforever.objects.LivePlayerList +import net.psforever.objects.serverobject.interior.{InteriorAware, Sidedness} +import net.psforever.objects.serverobject.mount.Mountable import net.psforever.objects.sourcing.PlayerSource import net.psforever.objects.zones.{Zone, ZoneInfo} import net.psforever.packet.game.TimeOfDayMessage.GetTimeOfDayValue @@ -517,6 +519,7 @@ class ChatOperations( ) case (Some(zone), Some(gate), false) => context.self ! SessionActor.SetZone(zone.zonename, gate) + customSetSidednessOfTarget(session.player, Sidedness.OutsideOf) //todo atm all locations are outside case (_, None, false) => sendResponse( ChatMsg(UNK_229, wideContents=true, "", "Gate id not defined (use '/zone -list')", None) @@ -544,6 +547,7 @@ class ChatOperations( coordinate.isDefined && coordinate.get >= 0 && coordinate.get <= 8191 } => context.self ! SessionActor.SetPosition(Vector3(x.toFloat, y.toFloat, z.toFloat)) + sendResponse(ChatMsg(ChatMessageType.CMT_QUIT, s"Please ensure that the sidedness of target is correct for destination.")) case (None, Some(waypoint)) if waypoint == "-list" => val zone = PointOfInterest.get(session.player.Zone.id) zone match { @@ -560,6 +564,7 @@ class ChatOperations( PointOfInterest.getWarpLocation(session.zone.id, waypoint) match { case Some(location) => context.self ! SessionActor.SetPosition(location) + customSetSidednessOfTarget(session.player, Sidedness.OutsideOf) //todo atm all quick locations are outside case None => sendResponse( ChatMsg(UNK_229, wideContents=true, "", s"unknown location '$waypoint'", None) @@ -1450,6 +1455,16 @@ class ChatOperations( } } + def customSetSidednessOfTarget(target: Player, side: Sidedness): Boolean = { + target.WhichSide = side + target.Zone.GUID(player.VehicleSeated) match { + case v: Mountable with InteriorAware => + v.WhichSide = side + case _ => () + } + true + } + def commandSetTimeSpeed(session: Session, contents: String): Unit = { val FloatPattern = """-?\d+(\.\d{1,2})?""".r diff --git a/src/main/scala/net/psforever/actors/session/support/WeaponAndProjectileOperations.scala b/src/main/scala/net/psforever/actors/session/support/WeaponAndProjectileOperations.scala index 987331c4c..790343fc8 100644 --- a/src/main/scala/net/psforever/actors/session/support/WeaponAndProjectileOperations.scala +++ b/src/main/scala/net/psforever/actors/session/support/WeaponAndProjectileOperations.scala @@ -1606,7 +1606,7 @@ class WeaponAndProjectileOperations( object WeaponAndProjectileOperations { def updateProjectileSidednessAfterHit(zone: Zone, projectile: Projectile, hitPosition: Vector3): Unit = { - val origin = projectile.Position + val origin = projectile.shot_origin val distance = Vector3.Magnitude(hitPosition - origin) zone .blockMap diff --git a/src/main/scala/net/psforever/objects/DummyExplodingEntity.scala b/src/main/scala/net/psforever/objects/DummyExplodingEntity.scala index a10c474cb..3d39faca0 100644 --- a/src/main/scala/net/psforever/objects/DummyExplodingEntity.scala +++ b/src/main/scala/net/psforever/objects/DummyExplodingEntity.scala @@ -4,6 +4,7 @@ package net.psforever.objects import net.psforever.objects.ballistics.Projectile import net.psforever.objects.definition.{ObjectDefinition, ProjectileDefinition} import net.psforever.objects.serverobject.affinity.FactionAffinity +import net.psforever.objects.serverobject.interior.{InteriorAware, Sidedness} import net.psforever.objects.vital.resolution.{DamageAndResistance, DamageResistanceModel} import net.psforever.objects.vital.{Vitality, VitalityDefinition} import net.psforever.types.{PlanetSideEmpire, PlanetSideGUID, Vector3} @@ -14,7 +15,10 @@ class DummyExplodingEntity( ) extends PlanetSideGameObject with FactionAffinity - with Vitality { + with Vitality + with InteriorAware { + lazy private val vdefin: DefinitionWrappedInVitality = new DefinitionWrappedInVitality(obj) + override def GUID: PlanetSideGUID = obj.GUID override def Position: Vector3 = { @@ -37,13 +41,22 @@ class DummyExplodingEntity( super.Velocity.orElse(obj.Velocity) } + def WhichSide_=(thisSide: Sidedness): Sidedness = WhichSide + + def WhichSide: Sidedness = { + obj match { + case awareSource: InteriorAware => + awareSource.WhichSide + case _ => + Sidedness.StrictlyBetweenSides + } + } + def Faction: PlanetSideEmpire.Value = faction def DamageModel: DamageAndResistance = DummyExplodingEntity.DefaultDamageResistanceModel - def Definition: ObjectDefinition with VitalityDefinition = { - new DefinitionWrappedInVitality(obj) - } + def Definition: ObjectDefinition with VitalityDefinition = vdefin } private class DefinitionWrappedInVitality(private val entity: PlanetSideGameObject) diff --git a/src/main/scala/net/psforever/objects/zones/Zone.scala b/src/main/scala/net/psforever/objects/zones/Zone.scala index 61ee9a1fc..c01c41f05 100644 --- a/src/main/scala/net/psforever/objects/zones/Zone.scala +++ b/src/main/scala/net/psforever/objects/zones/Zone.scala @@ -599,7 +599,7 @@ class Zone(val id: String, val map: ZoneMap, zoneNumber: Int) { elapsedTime % 86400 } - def SetTimeOfDay(requestedTime: Float) = { + def SetTimeOfDay(requestedTime: Float): Unit = { val now = System.currentTimeMillis() val requestedTimeDiff = requestedTime / timeOfDaySpeed @@ -611,7 +611,7 @@ class Zone(val id: String, val map: ZoneMap, zoneNumber: Int) { timeOfDaySpeed } - def SetTimeOfDaySpeed(requestedSpeed: Float) = { + def SetTimeOfDaySpeed(requestedSpeed: Float): Unit = { // store current time val timeOfDay = GetTimeOfDay()