From ece4a014064aefec0cdf45f2842541e66377670c Mon Sep 17 00:00:00 2001 From: icedchai <70030002+icedchai@users.noreply.github.com> Date: Fri, 9 May 2025 22:42:24 -0500 Subject: [PATCH 1/9] basic implement --- Features/Enums/ToolGunObjectType.cs | 3 +- Features/Objects/MapEditorObject.cs | 2 +- Features/Objects/TeleporterObject.cs | 70 +++++++++++++++++++ Features/Serializable/MapSchematic.cs | 10 +++ .../Serializable/SerializableTeleporter.cs | 70 +++++++++++++++++++ Features/Serializable/TargetTeleporter.cs | 26 +++++++ Features/ToolGun/ToolGunItem.cs | 1 + 7 files changed, 180 insertions(+), 2 deletions(-) create mode 100644 Features/Objects/TeleporterObject.cs create mode 100644 Features/Serializable/SerializableTeleporter.cs create mode 100644 Features/Serializable/TargetTeleporter.cs diff --git a/Features/Enums/ToolGunObjectType.cs b/Features/Enums/ToolGunObjectType.cs index 702e035..a5095be 100644 --- a/Features/Enums/ToolGunObjectType.cs +++ b/Features/Enums/ToolGunObjectType.cs @@ -8,5 +8,6 @@ public enum ToolGunObjectType Workstation = 3, PlayerSpawnpoint = 4, Capybara = 5, - Schematic = 6 + Schematic = 6, + Teleporter = 7, } diff --git a/Features/Objects/MapEditorObject.cs b/Features/Objects/MapEditorObject.cs index 2e094d5..e1eb615 100644 --- a/Features/Objects/MapEditorObject.cs +++ b/Features/Objects/MapEditorObject.cs @@ -17,7 +17,7 @@ public class MapEditorObject : MonoBehaviour public Room Room { get; protected set; } - public MapEditorObject Init(SerializableObject serializableObject, string mapName, string id, Room room) + public virtual MapEditorObject Init(SerializableObject serializableObject, string mapName, string id, Room room) { Base = serializableObject; MapName = mapName; diff --git a/Features/Objects/TeleporterObject.cs b/Features/Objects/TeleporterObject.cs new file mode 100644 index 0000000..5bc041a --- /dev/null +++ b/Features/Objects/TeleporterObject.cs @@ -0,0 +1,70 @@ +using GameCore; +using LabApi.Features.Wrappers; +using Mirror; +using ProjectMER.Features.Serializable; +using UnityEngine; + +namespace ProjectMER.Features.Objects; + +public class TeleporterObject : MapEditorObject +{ + // TODO: + // Implement OnTeleporting event + // Implement conditional teleport + // Implement pickup teleport + + public new SerializableTeleporter Base; + + public override MapEditorObject Init(SerializableObject serializableObject, string mapName, string id, Room room) + { + MapName = mapName; + Id = id; + Room = room; + + if (serializableObject is not SerializableTeleporter serializableTeleporter) + { + return this; + } + + Base = serializableTeleporter; + + GetComponent().isTrigger = true; + + return this; + } + + private TeleporterObject GetTarget() + { + return null; + } + + private bool TryGetTarget(out TeleporterObject teleporterObject) + { + teleporterObject = GetTarget(); + + return teleporterObject != null; + } + + private void OnTriggerEnter(Collider collider) + { + if (!CanBeTeleported(collider)) + return; + + Player? player = Player.Get(collider.gameObject); + if (player is null) + return; + + if (!TryGetTarget(out TeleporterObject target)) + { + return; + } + + player.Position = target.transform.position; + } + + private bool CanBeTeleported(Collider collider) + { + return true; + } +} + diff --git a/Features/Serializable/MapSchematic.cs b/Features/Serializable/MapSchematic.cs index 818549d..3a266df 100644 --- a/Features/Serializable/MapSchematic.cs +++ b/Features/Serializable/MapSchematic.cs @@ -33,6 +33,8 @@ public MapSchematic(string mapName) public Dictionary Capybaras { get; set; } = []; public Dictionary Schematics { get; set; } = []; + + public Dictionary Teleporters { get; set; } = []; public List SpawnedObjects = []; @@ -45,6 +47,7 @@ public MapSchematic Merge(MapSchematic other) PlayerSpawnpoints.AddRange(other.PlayerSpawnpoints); Capybaras.AddRange(other.Capybaras); Schematics.AddRange(other.Schematics); + Teleporters.AddRange(other.Teleporters); return this; } @@ -73,6 +76,7 @@ public void Reload() PlayerSpawnpoints.ForEach(kVP => SpawnObject(kVP.Key, kVP.Value)); Capybaras.ForEach(kVP => SpawnObject(kVP.Key, kVP.Value)); Schematics.ForEach(kVP => SpawnObject(kVP.Key, kVP.Value)); + Teleporters.ForEach(kVP => SpawnObject(kVP.Key, kVP.Value)); } public void SpawnObject(string id, T serializableObject) where T : SerializableObject @@ -128,6 +132,9 @@ public bool TryAddElement(string id, T serializableObject) where T : Serializ if (Schematics.TryAdd(id, serializableObject)) return true; + + if (Teleporters.TryAdd(id, serializableObject)) + return true; return false; } @@ -154,6 +161,9 @@ public bool TryRemoveElement(string id) if (Schematics.Remove(id)) return true; + + if (Teleporters.Remove(id)) + return true; return false; } diff --git a/Features/Serializable/SerializableTeleporter.cs b/Features/Serializable/SerializableTeleporter.cs new file mode 100644 index 0000000..de4fd47 --- /dev/null +++ b/Features/Serializable/SerializableTeleporter.cs @@ -0,0 +1,70 @@ +using AdminToys; +using LabApi.Features.Wrappers; +using Mirror; +using ProjectMER.Features.Extensions; +using ProjectMER.Features.Interfaces; +using ProjectMER.Features.Objects; +using UnityEngine; +using static HarmonyLib.Code; +using PrimitiveObjectToy = AdminToys.PrimitiveObjectToy; + +namespace ProjectMER.Features.Serializable; + +public class SerializableTeleporter : SerializableObject, IIndicatorDefinition +{ + public int TeleporterId { get; set; } + + public List TargetTeleporters { get; set; } = new List() + { + new TargetTeleporter(), + }; + + public float Cooldown { get; set; } = 10f; + + public override GameObject SpawnOrUpdateObject(Room? room = null, GameObject? instance = null) + { + PrimitiveObjectToy primitive = instance == null ? UnityEngine.Object.Instantiate(PrefabManager.PrimitiveObjectPrefab) : instance.GetComponent(); + Vector3 position = room.GetAbsolutePosition(Position); + Quaternion rotation = room.GetAbsoluteRotation(Rotation); + _prevIndex = Index; + + primitive.transform.SetPositionAndRotation(position, rotation); + primitive.transform.localScale = Scale; + primitive.NetworkMovementSmoothing = 60; + + primitive.NetworkMaterialColor = Color.white; + primitive.PrimitiveType = PrimitiveType.Cube; + primitive.PrimitiveFlags = PrimitiveFlags.Collidable; + + if (instance == null) + { + NetworkServer.Spawn(primitive.gameObject); + } + + return primitive.gameObject; + } + + public GameObject SpawnOrUpdateIndicator(Room room, GameObject? instance = null) + { + PrimitiveObjectToy primitive = instance == null ? UnityEngine.Object.Instantiate(PrefabManager.PrimitiveObjectPrefab) : instance.GetComponent(); + Vector3 position = room.GetAbsolutePosition(Position); + Quaternion rotation = room.GetAbsoluteRotation(Rotation); + _prevIndex = Index; + + primitive.transform.SetPositionAndRotation(position, rotation); + primitive.transform.localScale = Scale; + primitive.NetworkMovementSmoothing = 60; + + primitive.PrimitiveFlags = PrimitiveFlags.Visible; + primitive.PrimitiveType = PrimitiveType.Cube; + Color transparentColor = new Color(0.1f, 0.1f, 0.7f, 0.5f); + + primitive.NetworkMaterialColor = transparentColor; + + if (instance == null) + NetworkServer.Spawn(primitive.gameObject); + + return primitive.gameObject; + } +} + diff --git a/Features/Serializable/TargetTeleporter.cs b/Features/Serializable/TargetTeleporter.cs new file mode 100644 index 0000000..ee851a4 --- /dev/null +++ b/Features/Serializable/TargetTeleporter.cs @@ -0,0 +1,26 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ProjectMER.Features.Serializable; + +public class TargetTeleporter +{ + public TargetTeleporter() + { + + } + + public TargetTeleporter(int id, float chance) + { + Id = id; + Chance = chance; + } + + public int Id { get; set; } + + public float Chance { get; set; } = 100.0f; +} + diff --git a/Features/ToolGun/ToolGunItem.cs b/Features/ToolGun/ToolGunItem.cs index 153208e..76b0da8 100644 --- a/Features/ToolGun/ToolGunItem.cs +++ b/Features/ToolGun/ToolGunItem.cs @@ -26,6 +26,7 @@ public class ToolGunItem { ToolGunObjectType.PlayerSpawnpoint, typeof(SerializablePlayerSpawnpoint) }, { ToolGunObjectType.Capybara, typeof(SerializableCapybara) }, { ToolGunObjectType.Schematic, typeof(SerializableSchematic) }, + { ToolGunObjectType.Teleporter, typeof(SerializableTeleporter) }, }; private ToolGunObjectType _selectedObjectToSpawn; From 3fb3c435969832f8e59b1ab3b134eafb7c572299 Mon Sep 17 00:00:00 2001 From: icedchai <70030002+icedchai@users.noreply.github.com> Date: Fri, 9 May 2025 23:11:59 -0500 Subject: [PATCH 2/9] Colored indicator cyan, changed spawn method --- Features/Serializable/SerializableTeleporter.cs | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/Features/Serializable/SerializableTeleporter.cs b/Features/Serializable/SerializableTeleporter.cs index de4fd47..cf2a185 100644 --- a/Features/Serializable/SerializableTeleporter.cs +++ b/Features/Serializable/SerializableTeleporter.cs @@ -23,25 +23,15 @@ public class SerializableTeleporter : SerializableObject, IIndicatorDefinition public override GameObject SpawnOrUpdateObject(Room? room = null, GameObject? instance = null) { - PrimitiveObjectToy primitive = instance == null ? UnityEngine.Object.Instantiate(PrefabManager.PrimitiveObjectPrefab) : instance.GetComponent(); + GameObject primitive = instance == null ? GameObject.CreatePrimitive(PrimitiveType.Cube) : instance; Vector3 position = room.GetAbsolutePosition(Position); Quaternion rotation = room.GetAbsoluteRotation(Rotation); _prevIndex = Index; primitive.transform.SetPositionAndRotation(position, rotation); primitive.transform.localScale = Scale; - primitive.NetworkMovementSmoothing = 60; - - primitive.NetworkMaterialColor = Color.white; - primitive.PrimitiveType = PrimitiveType.Cube; - primitive.PrimitiveFlags = PrimitiveFlags.Collidable; - if (instance == null) - { - NetworkServer.Spawn(primitive.gameObject); - } - - return primitive.gameObject; + return primitive; } public GameObject SpawnOrUpdateIndicator(Room room, GameObject? instance = null) @@ -57,7 +47,7 @@ public GameObject SpawnOrUpdateIndicator(Room room, GameObject? instance = null) primitive.PrimitiveFlags = PrimitiveFlags.Visible; primitive.PrimitiveType = PrimitiveType.Cube; - Color transparentColor = new Color(0.1f, 0.1f, 0.7f, 0.5f); + Color transparentColor = "#03fcec".GetColorFromString(); primitive.NetworkMaterialColor = transparentColor; From 4a12b1528b0d0d0bd7acb5b12200a81548f3cc4a Mon Sep 17 00:00:00 2001 From: icedchai <70030002+icedchai@users.noreply.github.com> Date: Sat, 10 May 2025 16:24:02 -0500 Subject: [PATCH 3/9] Added teleport functionality, no chance yet --- Features/Objects/MapEditorObject.cs | 2 +- Features/Objects/TeleporterObject.cs | 115 +++++++++++++++--- .../Serializable/SerializableTeleporter.cs | 30 ++++- Features/Serializable/TargetTeleporter.cs | 7 +- 4 files changed, 128 insertions(+), 26 deletions(-) diff --git a/Features/Objects/MapEditorObject.cs b/Features/Objects/MapEditorObject.cs index e1eb615..2e094d5 100644 --- a/Features/Objects/MapEditorObject.cs +++ b/Features/Objects/MapEditorObject.cs @@ -17,7 +17,7 @@ public class MapEditorObject : MonoBehaviour public Room Room { get; protected set; } - public virtual MapEditorObject Init(SerializableObject serializableObject, string mapName, string id, Room room) + public MapEditorObject Init(SerializableObject serializableObject, string mapName, string id, Room room) { Base = serializableObject; MapName = mapName; diff --git a/Features/Objects/TeleporterObject.cs b/Features/Objects/TeleporterObject.cs index 5bc041a..1498d6b 100644 --- a/Features/Objects/TeleporterObject.cs +++ b/Features/Objects/TeleporterObject.cs @@ -6,36 +6,101 @@ namespace ProjectMER.Features.Objects; -public class TeleporterObject : MapEditorObject +public class TeleporterObject : MonoBehaviour { // TODO: // Implement OnTeleporting event // Implement conditional teleport // Implement pickup teleport + // Implement chance-based target select. + + /// + /// Gets a indicating when this teleporter will next be usable. + /// + public DateTime WhenWillBeUsable { get; private set; } + + /// + /// Gets a value indicating whether this teleporter is currently usable. + /// + public bool IsUsable { get => DateTime.Now > WhenWillBeUsable; } + + /// + /// Gets or sets the base for this object. + /// + public SerializableTeleporter Base { get; set; } + + /// + /// Gets or sets the global position of this object. + /// + public Vector3 Position + { + get + { + return transform.position; + } - public new SerializableTeleporter Base; + set + { + transform.position = value; + } + } - public override MapEditorObject Init(SerializableObject serializableObject, string mapName, string id, Room room) + /// + /// Gets or sets the global rotation of this object. + /// + public Quaternion Rotation { - MapName = mapName; - Id = id; - Room = room; + get + { + return transform.rotation; + } - if (serializableObject is not SerializableTeleporter serializableTeleporter) + set { - return this; + transform.rotation = value; } + } - Base = serializableTeleporter; + /// + /// Gets or sets the global euler angles of this object. + /// + public Vector3 EulerAngles + { + get + { + return Rotation.eulerAngles; + } - GetComponent().isTrigger = true; + set + { + Rotation = Quaternion.Euler(value); + } + } - return this; + /// + /// Gets or sets the localScale for this object. + /// + public Vector3 Scale + { + get + { + return transform.localScale; + } + + set + { + transform.localScale = value; + } } + /// + /// Gets a Dictionary to access teleporters by their ID. + /// + internal static Dictionary TeleportersFromId { get; private set; } = new (); + private TeleporterObject GetTarget() { - return null; + return TeleportersFromId[Base.TargetTeleporters.RandomItem().Id]; } private bool TryGetTarget(out TeleporterObject teleporterObject) @@ -45,21 +110,32 @@ private bool TryGetTarget(out TeleporterObject teleporterObject) return teleporterObject != null; } - private void OnTriggerEnter(Collider collider) + private void OnTriggerEnter(Collider other) { - if (!CanBeTeleported(collider)) + if (!IsUsable || !CanBeTeleported(other) || !TryGetTarget(out TeleporterObject target)) + { return; + } - Player? player = Player.Get(collider.gameObject); + Player? player = Player.Get(other.gameObject); if (player is null) - return; - - if (!TryGetTarget(out TeleporterObject target)) { return; } - player.Position = target.transform.position; + player.Position = target.Position; + WhenWillBeUsable = DateTime.Now.AddSeconds(Base.Cooldown); + target.WhenWillBeUsable = DateTime.Now.AddSeconds(target.Base.Cooldown); + } + + private void Start() + { + TeleportersFromId.Add(Base.TeleporterId, this); + } + + private void OnDestroy() + { + TeleportersFromId.Remove(Base.TeleporterId); } private bool CanBeTeleported(Collider collider) @@ -67,4 +143,3 @@ private bool CanBeTeleported(Collider collider) return true; } } - diff --git a/Features/Serializable/SerializableTeleporter.cs b/Features/Serializable/SerializableTeleporter.cs index cf2a185..62eb01f 100644 --- a/Features/Serializable/SerializableTeleporter.cs +++ b/Features/Serializable/SerializableTeleporter.cs @@ -12,7 +12,23 @@ namespace ProjectMER.Features.Serializable; public class SerializableTeleporter : SerializableObject, IIndicatorDefinition { - public int TeleporterId { get; set; } + + private int teleporterId; + + /// + /// Gets or sets the teleporter ID for this teleporter. + /// + public int TeleporterId + { + get => teleporterId; + set + { + if (TeleporterObject.TeleportersFromId.ContainsKey(value)) + { + teleporterId = value; + } + } + } public List TargetTeleporters { get; set; } = new List() { @@ -31,6 +47,13 @@ public override GameObject SpawnOrUpdateObject(Room? room = null, GameObject? in primitive.transform.SetPositionAndRotation(position, rotation); primitive.transform.localScale = Scale; + primitive.AddComponent().Base = this; + + if (primitive.TryGetComponent(out BoxCollider collider)) + { + collider.isTrigger = true; + } + return primitive; } @@ -47,7 +70,7 @@ public GameObject SpawnOrUpdateIndicator(Room room, GameObject? instance = null) primitive.PrimitiveFlags = PrimitiveFlags.Visible; primitive.PrimitiveType = PrimitiveType.Cube; - Color transparentColor = "#03fcec".GetColorFromString(); + Color transparentColor = new Color(0.11f, 0.98f, 0.92f, 0.5f); primitive.NetworkMaterialColor = transparentColor; @@ -56,5 +79,4 @@ public GameObject SpawnOrUpdateIndicator(Room room, GameObject? instance = null) return primitive.gameObject; } -} - +} \ No newline at end of file diff --git a/Features/Serializable/TargetTeleporter.cs b/Features/Serializable/TargetTeleporter.cs index ee851a4..c10a9de 100644 --- a/Features/Serializable/TargetTeleporter.cs +++ b/Features/Serializable/TargetTeleporter.cs @@ -8,6 +8,11 @@ namespace ProjectMER.Features.Serializable; public class TargetTeleporter { + public override string ToString() + { + return $"ID: {Id}, Chance: {Chance}"; + } + public TargetTeleporter() { @@ -19,7 +24,7 @@ public TargetTeleporter(int id, float chance) Chance = chance; } - public int Id { get; set; } + public int Id { get; set; } = -1; public float Chance { get; set; } = 100.0f; } From 5cacbe3050c6fdb02897fd3e6fe6c0f2b8d5a02a Mon Sep 17 00:00:00 2001 From: icedchai <70030002+icedchai@users.noreply.github.com> Date: Sat, 10 May 2025 16:37:58 -0500 Subject: [PATCH 4/9] Modified target system --- Features/Objects/TeleporterObject.cs | 6 ++-- .../Serializable/SerializableTeleporter.cs | 12 ++++--- Features/Serializable/TargetTeleporter.cs | 31 ------------------- 3 files changed, 10 insertions(+), 39 deletions(-) delete mode 100644 Features/Serializable/TargetTeleporter.cs diff --git a/Features/Objects/TeleporterObject.cs b/Features/Objects/TeleporterObject.cs index 1498d6b..081e882 100644 --- a/Features/Objects/TeleporterObject.cs +++ b/Features/Objects/TeleporterObject.cs @@ -100,7 +100,7 @@ public Vector3 Scale private TeleporterObject GetTarget() { - return TeleportersFromId[Base.TargetTeleporters.RandomItem().Id]; + return TeleportersFromId[Base.Targets.RandomItem()]; } private bool TryGetTarget(out TeleporterObject teleporterObject) @@ -130,12 +130,12 @@ private void OnTriggerEnter(Collider other) private void Start() { - TeleportersFromId.Add(Base.TeleporterId, this); + TeleportersFromId.Add(Base.Id, this); } private void OnDestroy() { - TeleportersFromId.Remove(Base.TeleporterId); + TeleportersFromId.Remove(Base.Id); } private bool CanBeTeleported(Collider collider) diff --git a/Features/Serializable/SerializableTeleporter.cs b/Features/Serializable/SerializableTeleporter.cs index 62eb01f..4943ed2 100644 --- a/Features/Serializable/SerializableTeleporter.cs +++ b/Features/Serializable/SerializableTeleporter.cs @@ -18,21 +18,23 @@ public class SerializableTeleporter : SerializableObject, IIndicatorDefinition /// /// Gets or sets the teleporter ID for this teleporter. /// - public int TeleporterId + public int Id { get => teleporterId; set { - if (TeleporterObject.TeleportersFromId.ContainsKey(value)) + if (TeleporterObject.TeleportersFromId.ContainsKey(value) || value < 1) { - teleporterId = value; + return; } + + teleporterId = value; } } - public List TargetTeleporters { get; set; } = new List() + public List Targets { get; set; } = new List() { - new TargetTeleporter(), + }; public float Cooldown { get; set; } = 10f; diff --git a/Features/Serializable/TargetTeleporter.cs b/Features/Serializable/TargetTeleporter.cs deleted file mode 100644 index c10a9de..0000000 --- a/Features/Serializable/TargetTeleporter.cs +++ /dev/null @@ -1,31 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace ProjectMER.Features.Serializable; - -public class TargetTeleporter -{ - public override string ToString() - { - return $"ID: {Id}, Chance: {Chance}"; - } - - public TargetTeleporter() - { - - } - - public TargetTeleporter(int id, float chance) - { - Id = id; - Chance = chance; - } - - public int Id { get; set; } = -1; - - public float Chance { get; set; } = 100.0f; -} - From 03862d884e5bda626903eeaec30d2a543315c11b Mon Sep 17 00:00:00 2001 From: icedchai <70030002+icedchai@users.noreply.github.com> Date: Sat, 10 May 2025 21:58:47 -0500 Subject: [PATCH 5/9] Fixed timing related bug (fixes direct 2-way tps) --- Features/Objects/TeleporterObject.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Features/Objects/TeleporterObject.cs b/Features/Objects/TeleporterObject.cs index 081e882..d5a23dc 100644 --- a/Features/Objects/TeleporterObject.cs +++ b/Features/Objects/TeleporterObject.cs @@ -3,6 +3,7 @@ using Mirror; using ProjectMER.Features.Serializable; using UnityEngine; +using MEC; namespace ProjectMER.Features.Objects; @@ -123,9 +124,10 @@ private void OnTriggerEnter(Collider other) return; } - player.Position = target.Position; WhenWillBeUsable = DateTime.Now.AddSeconds(Base.Cooldown); target.WhenWillBeUsable = DateTime.Now.AddSeconds(target.Base.Cooldown); + + Timing.CallDelayed(0.1f, () => player.Position = target.Position); } private void Start() From 0d77ee9b20d8754a42496a672f26375362e19b9f Mon Sep 17 00:00:00 2001 From: icedchai <70030002+icedchai@users.noreply.github.com> Date: Sun, 11 May 2025 11:50:11 -0500 Subject: [PATCH 6/9] Updated properties, yoinked transform accessors from SchematicObject --- Features/Objects/TeleporterObject.cs | 39 +++++++--------------------- 1 file changed, 10 insertions(+), 29 deletions(-) diff --git a/Features/Objects/TeleporterObject.cs b/Features/Objects/TeleporterObject.cs index d5a23dc..5dcc1b6 100644 --- a/Features/Objects/TeleporterObject.cs +++ b/Features/Objects/TeleporterObject.cs @@ -23,7 +23,7 @@ public class TeleporterObject : MonoBehaviour /// /// Gets a value indicating whether this teleporter is currently usable. /// - public bool IsUsable { get => DateTime.Now > WhenWillBeUsable; } + public bool IsUsable => DateTime.Now > WhenWillBeUsable; /// /// Gets or sets the base for this object. @@ -31,15 +31,11 @@ public class TeleporterObject : MonoBehaviour public SerializableTeleporter Base { get; set; } /// - /// Gets or sets the global position of this object. + /// Gets or sets the global position of the object. /// public Vector3 Position { - get - { - return transform.position; - } - + get => transform.position; set { transform.position = value; @@ -47,15 +43,11 @@ public Vector3 Position } /// - /// Gets or sets the global rotation of this object. + /// Gets or sets the global rotation of the object. /// public Quaternion Rotation { - get - { - return transform.rotation; - } - + get => transform.rotation; set { transform.rotation = value; @@ -63,31 +55,20 @@ public Quaternion Rotation } /// - /// Gets or sets the global euler angles of this object. + /// Gets or sets the global euler angles of the object. /// public Vector3 EulerAngles { - get - { - return Rotation.eulerAngles; - } - - set - { - Rotation = Quaternion.Euler(value); - } + get => Rotation.eulerAngles; + set => Rotation = Quaternion.Euler(value); } /// - /// Gets or sets the localScale for this object. + /// Gets or sets the scale of the object. /// public Vector3 Scale { - get - { - return transform.localScale; - } - + get => transform.localScale; set { transform.localScale = value; From d1f56ade1d1f28d6b66532a5667f463d8db35f2b Mon Sep 17 00:00:00 2001 From: icedchai <70030002+icedchai@users.noreply.github.com> Date: Thu, 15 May 2025 16:30:16 -0500 Subject: [PATCH 7/9] Update SerializableTeleporter.cs --- Features/Serializable/SerializableTeleporter.cs | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/Features/Serializable/SerializableTeleporter.cs b/Features/Serializable/SerializableTeleporter.cs index 4943ed2..ce9b06f 100644 --- a/Features/Serializable/SerializableTeleporter.cs +++ b/Features/Serializable/SerializableTeleporter.cs @@ -5,14 +5,14 @@ using ProjectMER.Features.Interfaces; using ProjectMER.Features.Objects; using UnityEngine; -using static HarmonyLib.Code; using PrimitiveObjectToy = AdminToys.PrimitiveObjectToy; namespace ProjectMER.Features.Serializable; public class SerializableTeleporter : SerializableObject, IIndicatorDefinition { - + // TODO: + // Add proper ID management private int teleporterId; /// @@ -32,10 +32,7 @@ public int Id } } - public List Targets { get; set; } = new List() - { - - }; + public List Targets { get; set; } = new List(); public float Cooldown { get; set; } = 10f; @@ -49,7 +46,12 @@ public override GameObject SpawnOrUpdateObject(Room? room = null, GameObject? in primitive.transform.SetPositionAndRotation(position, rotation); primitive.transform.localScale = Scale; - primitive.AddComponent().Base = this; + if (!primitive.TryGetComponent(out TeleporterObject teleporter)) + { + teleporter = primitive.AddComponent(); + } + + teleporter.Base = this; if (primitive.TryGetComponent(out BoxCollider collider)) { From 68723f0d0f00e7603e49dbb77b1ecaaae8f359c4 Mon Sep 17 00:00:00 2001 From: icedchai <70030002+icedchai@users.noreply.github.com> Date: Sat, 17 May 2025 16:37:18 -0500 Subject: [PATCH 8/9] Changed ID manager to use LINQ --- Features/Objects/TeleporterObject.cs | 8 ++++---- Features/Serializable/SerializableTeleporter.cs | 5 ----- 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/Features/Objects/TeleporterObject.cs b/Features/Objects/TeleporterObject.cs index 5dcc1b6..45b815a 100644 --- a/Features/Objects/TeleporterObject.cs +++ b/Features/Objects/TeleporterObject.cs @@ -78,11 +78,11 @@ public Vector3 Scale /// /// Gets a Dictionary to access teleporters by their ID. /// - internal static Dictionary TeleportersFromId { get; private set; } = new (); + internal static List Teleporters { get; private set; } = new (); private TeleporterObject GetTarget() { - return TeleportersFromId[Base.Targets.RandomItem()]; + return Teleporters.FirstOrDefault(t => t.Base.Id == Base.Targets.RandomItem()); } private bool TryGetTarget(out TeleporterObject teleporterObject) @@ -113,12 +113,12 @@ private void OnTriggerEnter(Collider other) private void Start() { - TeleportersFromId.Add(Base.Id, this); + Teleporters.Add(this); } private void OnDestroy() { - TeleportersFromId.Remove(Base.Id); + Teleporters.Remove(this); } private bool CanBeTeleported(Collider collider) diff --git a/Features/Serializable/SerializableTeleporter.cs b/Features/Serializable/SerializableTeleporter.cs index ce9b06f..baaa93d 100644 --- a/Features/Serializable/SerializableTeleporter.cs +++ b/Features/Serializable/SerializableTeleporter.cs @@ -23,11 +23,6 @@ public int Id get => teleporterId; set { - if (TeleporterObject.TeleportersFromId.ContainsKey(value) || value < 1) - { - return; - } - teleporterId = value; } } From 64f7dc43b4054b563914c34938ff7ac28f39e738 Mon Sep 17 00:00:00 2001 From: icedchai <70030002+icedchai@users.noreply.github.com> Date: Sat, 17 May 2025 20:03:49 -0500 Subject: [PATCH 9/9] Changed teleport indicator to match playerspawnpoint, added rotation support to teleporters --- Features/Objects/TeleporterObject.cs | 14 ++- .../Serializable/SerializableTeleporter.cs | 85 ++++++++++++++++--- Features/ToolGun/ToolGunHandler.cs | 6 ++ 3 files changed, 91 insertions(+), 14 deletions(-) diff --git a/Features/Objects/TeleporterObject.cs b/Features/Objects/TeleporterObject.cs index 45b815a..33636a0 100644 --- a/Features/Objects/TeleporterObject.cs +++ b/Features/Objects/TeleporterObject.cs @@ -108,7 +108,19 @@ private void OnTriggerEnter(Collider other) WhenWillBeUsable = DateTime.Now.AddSeconds(Base.Cooldown); target.WhenWillBeUsable = DateTime.Now.AddSeconds(target.Base.Cooldown); - Timing.CallDelayed(0.1f, () => player.Position = target.Position); + + Timing.CallDelayed(0.05f, () => + { + player.Position = target.Position; + try + { + player.LookRotation = target.EulerAngles; + } + catch (Exception e) + { + Logger.Error(e); + } + }); } private void Start() diff --git a/Features/Serializable/SerializableTeleporter.cs b/Features/Serializable/SerializableTeleporter.cs index baaa93d..7269bb5 100644 --- a/Features/Serializable/SerializableTeleporter.cs +++ b/Features/Serializable/SerializableTeleporter.cs @@ -1,6 +1,7 @@ using AdminToys; using LabApi.Features.Wrappers; using Mirror; +using PlayerRoles; using ProjectMER.Features.Extensions; using ProjectMER.Features.Interfaces; using ProjectMER.Features.Objects; @@ -58,24 +59,82 @@ public override GameObject SpawnOrUpdateObject(Room? room = null, GameObject? in public GameObject SpawnOrUpdateIndicator(Room room, GameObject? instance = null) { - PrimitiveObjectToy primitive = instance == null ? UnityEngine.Object.Instantiate(PrefabManager.PrimitiveObjectPrefab) : instance.GetComponent(); - Vector3 position = room.GetAbsolutePosition(Position); + PrimitiveObjectToy root; + PrimitiveObjectToy trigger; + PrimitiveObjectToy cylinder; + PrimitiveObjectToy arrowY; + PrimitiveObjectToy arrowX; + PrimitiveObjectToy arrow; + + Vector3 position = room.GetAbsolutePosition(Position - new Vector3(0, 0.5f, 0)); Quaternion rotation = room.GetAbsoluteRotation(Rotation); - _prevIndex = Index; - primitive.transform.SetPositionAndRotation(position, rotation); - primitive.transform.localScale = Scale; - primitive.NetworkMovementSmoothing = 60; + if (instance == null) + { + root = UnityEngine.Object.Instantiate(PrefabManager.PrimitiveObjectPrefab); + root.NetworkPrimitiveFlags = PrimitiveFlags.None; + root.name = "Indicator"; + root.transform.position = position; + + trigger = UnityEngine.Object.Instantiate(PrefabManager.PrimitiveObjectPrefab); + trigger.NetworkPrimitiveFlags = PrimitiveFlags.Visible; + trigger.name = "Trigger"; + trigger.NetworkPrimitiveType = PrimitiveType.Cube; + trigger.transform.localScale = Scale; + trigger.transform.position = position + new Vector3(0, 0.5f, 0); + trigger.transform.parent = root.transform; + + cylinder = GameObject.Instantiate(PrefabManager.PrimitiveObjectPrefab, root.transform); + cylinder.transform.localPosition = Vector3.zero; + cylinder.NetworkPrimitiveType = PrimitiveType.Cylinder; + cylinder.NetworkPrimitiveFlags = PrimitiveFlags.Visible; + cylinder.transform.localScale = new Vector3(1f, 0.001f, 1f); + + arrowY = UnityEngine.Object.Instantiate(PrefabManager.PrimitiveObjectPrefab); + arrowY.NetworkPrimitiveFlags = PrimitiveFlags.None; + arrowY.name = "Arrow Y Axis"; + arrowY.transform.parent = root.transform; + + arrowX = UnityEngine.Object.Instantiate(PrefabManager.PrimitiveObjectPrefab); + arrowX.NetworkPrimitiveFlags = PrimitiveFlags.None; + arrowX.name = "Arrow X Axis"; + arrowX.transform.parent = arrowY.transform; + + arrow = GameObject.Instantiate(PrefabManager.PrimitiveObjectPrefab, arrowX.transform); + arrow.transform.localPosition = root.transform.forward; + arrow.NetworkPrimitiveType = PrimitiveType.Cube; + arrow.NetworkPrimitiveFlags = PrimitiveFlags.Visible; + arrow.transform.localScale = new Vector3(0.1f, 0.1f, 1f); + } + else + { + root = instance.GetComponent(); - primitive.PrimitiveFlags = PrimitiveFlags.Visible; - primitive.PrimitiveType = PrimitiveType.Cube; - Color transparentColor = new Color(0.11f, 0.98f, 0.92f, 0.5f); + trigger = root.transform.Find("Trigger").GetComponent(); + arrowY = root.transform.Find("Arrow Y Axis").GetComponent(); + arrowX = arrowY.transform.Find("Arrow X Axis").GetComponent(); - primitive.NetworkMaterialColor = transparentColor; + trigger.transform.localScale = Scale; + } - if (instance == null) - NetworkServer.Spawn(primitive.gameObject); + root.transform.position = position; + arrowY.transform.localPosition = Vector3.up * 1.6f; + arrowY.transform.localEulerAngles = new Vector3(0f, rotation.eulerAngles.y, 0f); + arrowX.transform.localPosition = Vector3.zero; + arrowX.transform.localEulerAngles = new Vector3(-rotation.eulerAngles.x, 0f, 0f); + + foreach (PrimitiveObjectToy primitive in root.GetComponentsInChildren()) + { + if (Targets.Count > 0) + { + primitive.NetworkMaterialColor = new Color(0.11f, 0.98f, 0.92f, 0.5f); + } + else + { + primitive.NetworkMaterialColor = new Color(1f, 1f, 1f, 0.25f); + } + } - return primitive.gameObject; + return root.gameObject; } } \ No newline at end of file diff --git a/Features/ToolGun/ToolGunHandler.cs b/Features/ToolGun/ToolGunHandler.cs index 0181426..89da760 100644 --- a/Features/ToolGun/ToolGunHandler.cs +++ b/Features/ToolGun/ToolGunHandler.cs @@ -47,6 +47,12 @@ public static void CreateObject(Vector3 position, ToolGunObjectType objectType, break; } + case SerializableTeleporter _: + { + serializableObject.Position = position + Vector3.up * 0.5f; + break; + } + case SerializableSchematic serializableSchematic: { serializableObject.Position = position;