From 9f2c170cf5ba397c4375a7e0b50cc61b8dd453fc Mon Sep 17 00:00:00 2001 From: Fate-JH Date: Mon, 27 Apr 2026 17:25:30 -0400 Subject: [PATCH] retain sidedness on player relog --- .../db/migration/V017__Sidedness.sql | 3 ++ .../actors/session/AvatarActor.scala | 10 +++++-- .../actors/session/csr/ChatLogic.scala | 30 +++++++++++++++++++ .../session/support/ZoningOperations.scala | 1 + .../persistence/SavedCharacter.scala | 1 + 5 files changed, 42 insertions(+), 3 deletions(-) create mode 100644 server/src/main/resources/db/migration/V017__Sidedness.sql diff --git a/server/src/main/resources/db/migration/V017__Sidedness.sql b/server/src/main/resources/db/migration/V017__Sidedness.sql new file mode 100644 index 000000000..8aff30290 --- /dev/null +++ b/server/src/main/resources/db/migration/V017__Sidedness.sql @@ -0,0 +1,3 @@ +/* New */ +ALTER TABLE savedplayer + ADD COLUMN sidedness BOOLEAN NOT NULL DEFAULT FALSE; \ No newline at end of file diff --git a/src/main/scala/net/psforever/actors/session/AvatarActor.scala b/src/main/scala/net/psforever/actors/session/AvatarActor.scala index 32da5a6de..2b72d42ff 100644 --- a/src/main/scala/net/psforever/actors/session/AvatarActor.scala +++ b/src/main/scala/net/psforever/actors/session/AvatarActor.scala @@ -43,6 +43,7 @@ import net.psforever.objects.equipment.{Equipment, EquipmentSlot} import net.psforever.objects.inventory.{Container, InventoryItem} import net.psforever.objects.loadouts.{InfantryLoadout, Loadout, VehicleLoadout} import net.psforever.objects.locker.LockerContainer +import net.psforever.objects.serverobject.interior.Sidedness import net.psforever.objects.sourcing.{PlayerSource,SourceWithHealthEntry} import net.psforever.objects.vital.{DamagingActivity, HealFromImplant, HealingActivity, SpawningActivity} import net.psforever.packet.game.objectcreate.{BasicCharacterData, ObjectClass, RibbonBars} @@ -739,6 +740,7 @@ object AvatarActor { _.py -> lift(0), _.pz -> lift(0), _.orientation -> lift(0), + _.sidedness -> lift(false), _.zoneNum -> lift(0), _.health -> lift(0), _.armor -> lift(0), @@ -746,7 +748,7 @@ object AvatarActor { _.loadout -> lift("") ) ) - out.completeWith(Future(persistence.Savedplayer(avatarId, 0, 0, 0, 0, 0, 0, 0, 0, ""))) + out.completeWith(Future(persistence.Savedplayer(avatarId, 0, 0, 0, 0, false, 0, 0, 0, 0, ""))) } out.future } @@ -826,6 +828,7 @@ object AvatarActor { _.py -> lift((position.y * 1000).toInt), _.pz -> lift((position.z * 1000).toInt), _.orientation -> lift((player.Orientation.z * 1000).toInt), + _.sidedness -> lift(Sidedness.equals(player.WhichSide, Sidedness.InsideOf)), _.zoneNum -> lift(player.Zone.Number), _.health -> lift(health), _.armor -> lift(player.Armor), @@ -865,6 +868,7 @@ object AvatarActor { _.py -> lift((position.y * 1000).toInt), _.pz -> lift((position.z * 1000).toInt), _.orientation -> lift((player.Orientation.z * 1000).toInt), + _.sidedness -> lift(player.WhichSide == Sidedness.InsideOf), _.zoneNum -> lift(player.Zone.Number) ) ) @@ -2195,14 +2199,14 @@ class AvatarActor( val player = new Player(avatar) val zoneNum = saveOpt .collect { - case persistence.Savedplayer(_, _, _, _, _, zoneNum, _, _, exosuitNum, loadout) => + case persistence.Savedplayer(_, _, _, _, _, _, inZoneNum, _, _, exosuitNum, loadout) => val exo = ExoSuitType(exosuitNum) player.ExoSuit = exo AvatarActor.buildHolsterEquipmentFromClob(player, loadout, log) if (exo == ExoSuitType.MAX) { player.DrawnSlot = 0 //max arm up } - zoneNum + inZoneNum } .getOrElse { player.ExoSuit = ExoSuitType.Standard 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 eee8cb565..5250b6293 100644 --- a/src/main/scala/net/psforever/actors/session/csr/ChatLogic.scala +++ b/src/main/scala/net/psforever/actors/session/csr/ChatLogic.scala @@ -11,6 +11,7 @@ import net.psforever.objects.serverobject.affinity.FactionAffinity import net.psforever.objects.serverobject.dome.ForceDomeControl import net.psforever.objects.serverobject.{CommonMessages, PlanetSideServerObject} import net.psforever.objects.serverobject.hackable.Hackable +import net.psforever.objects.serverobject.interior.Sidedness import net.psforever.objects.serverobject.structures.Building import net.psforever.objects.zones.Zone import net.psforever.packet.game.{ChatMsg, SetChatFilterMessage} @@ -229,6 +230,7 @@ class ChatLogic(val ops: ChatOperations, implicit val context: ActorContext) ext case "setempire" => customCommandSetEmpire(params) case "weaponlock" => customCommandZoneWeaponUnlock(session, params) case "forcedome" => customForceDomeCommand(session, params) + case "setside" => customSetSidedness(session, params) case _ => // command was not handled sendResponse( @@ -546,6 +548,34 @@ class ChatLogic(val ops: ChatOperations, implicit val context: ActorContext) ext true } + private def customSetSidedness(session: Session, contents: Seq[String]): Boolean = { + var postUsageMessage: Boolean = false + contents.headOption match { + case Some(side) if side.matches("i|in|inside") => + session.player.WhichSide = Sidedness.InsideOf + case Some(side) if side.matches("o|out|outside") => + session.player.WhichSide = Sidedness.OutsideOf + 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 i[n[side]]|o[ut[side]]|check")) + } + true + } + private def customCommandOnOffStateOrNone(stateOpt: Option[String]): Option[Boolean] = { stateOpt match { case None => diff --git a/src/main/scala/net/psforever/actors/session/support/ZoningOperations.scala b/src/main/scala/net/psforever/actors/session/support/ZoningOperations.scala index b7d6162b7..dbcd82af8 100644 --- a/src/main/scala/net/psforever/actors/session/support/ZoningOperations.scala +++ b/src/main/scala/net/psforever/actors/session/support/ZoningOperations.scala @@ -2080,6 +2080,7 @@ class ZoningOperations( val position = Vector3(results.px * 0.001f, results.py * 0.001f, results.pz * 0.001f) player.Position = position player.Orientation = Vector3(0f, 0f, results.orientation * 0.001f) + player.WhichSide = if (results.sidedness) Sidedness.InsideOf else Sidedness.OutsideOf /* @reset_sanctuary=You have been returned to the sanctuary because you played another character. */ diff --git a/src/main/scala/net/psforever/persistence/SavedCharacter.scala b/src/main/scala/net/psforever/persistence/SavedCharacter.scala index 23f57c7f3..ffffa8c00 100644 --- a/src/main/scala/net/psforever/persistence/SavedCharacter.scala +++ b/src/main/scala/net/psforever/persistence/SavedCharacter.scala @@ -9,6 +9,7 @@ case class Savedplayer( py: Int, //Position.y * 1000 pz: Int, //Position.z * 1000 orientation: Int, //Orientation.z * 1000 + sidedness: Boolean, zoneNum: Int, health: Int, armor: Int,