From 5b52d74a46421f68ff41a5d4b5a46fa9a9fabd99 Mon Sep 17 00:00:00 2001 From: PaRRoT_tm Date: Wed, 28 May 2025 20:38:35 +0200 Subject: [PATCH 1/5] Changes that allow considering the range of a Teleport using a custom Scale --- Features/Serializable/SerializableTeleport.cs | 27 +++++++++++++------ 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/Features/Serializable/SerializableTeleport.cs b/Features/Serializable/SerializableTeleport.cs index 00dc294..d447ff7 100644 --- a/Features/Serializable/SerializableTeleport.cs +++ b/Features/Serializable/SerializableTeleport.cs @@ -22,14 +22,25 @@ public class SerializableTeleport : SerializableObject, IIndicatorDefinition Quaternion rotation = room.GetAbsoluteRotation(Rotation); _prevIndex = Index; gameObject.transform.SetLocalPositionAndRotation(position, rotation); - - if (instance == null) - { - gameObject.AddComponent().isTrigger = true; - gameObject.AddComponent(); - } - - return gameObject; + BoxCollider collider; + + if (instance == null) + { + collider = gameObject.AddComponent(); + collider.isTrigger = true; + gameObject.AddComponent(); + } + else + { + collider = gameObject.GetComponent(); + } + + if (collider != null) + { + collider.size = Scale; + } + + return gameObject; } public GameObject SpawnOrUpdateIndicator(Room room, GameObject? instance = null) From 20d21965f20b6aeacb2bf756cd45186f2556a587 Mon Sep 17 00:00:00 2001 From: PaRRoT_tm Date: Wed, 28 May 2025 22:49:29 +0200 Subject: [PATCH 2/5] Added the Chance --- Features/Objects/TeleportObject.cs | 5 ++++- Features/Serializable/SerializableTeleport.cs | 6 ++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/Features/Objects/TeleportObject.cs b/Features/Objects/TeleportObject.cs index 309f149..6e13c0e 100644 --- a/Features/Objects/TeleportObject.cs +++ b/Features/Objects/TeleportObject.cs @@ -42,7 +42,10 @@ public void OnTriggerEnter(Collider other) if (NextTimeUse > DateTime.Now) return; - TeleportObject? target = GetRandomTarget(); + if (UnityEngine.Random.Range(0, 100) >= Base.Chance) + return; + + TeleportObject? target = GetRandomTarget(); if (target == null) return; diff --git a/Features/Serializable/SerializableTeleport.cs b/Features/Serializable/SerializableTeleport.cs index d447ff7..ed1d886 100644 --- a/Features/Serializable/SerializableTeleport.cs +++ b/Features/Serializable/SerializableTeleport.cs @@ -13,9 +13,11 @@ public class SerializableTeleport : SerializableObject, IIndicatorDefinition { public List Targets { get; set; } = []; - public float Cooldown { get; set; } = 5f; + public int Chance { get; set; } = 100; - public override GameObject? SpawnOrUpdateObject(Room? room = null, GameObject? instance = null) + public float Cooldown { get; set; } = 5f; + + public override GameObject? SpawnOrUpdateObject(Room? room = null, GameObject? instance = null) { GameObject gameObject = instance ?? new GameObject("Teleport"); Vector3 position = room.GetAbsolutePosition(Position); From e3779b3a3989f8e3ee1a5fdfa677fdc3117344e6 Mon Sep 17 00:00:00 2001 From: PaRRoT_tm Date: Thu, 29 May 2025 02:12:02 +0200 Subject: [PATCH 3/5] Implemented AllowedRoles --- Features/Objects/TeleportObject.cs | 3 +++ Features/Serializable/SerializableTeleport.cs | 23 +++++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/Features/Objects/TeleportObject.cs b/Features/Objects/TeleportObject.cs index 6e13c0e..df9bddc 100644 --- a/Features/Objects/TeleportObject.cs +++ b/Features/Objects/TeleportObject.cs @@ -45,6 +45,9 @@ public void OnTriggerEnter(Collider other) if (UnityEngine.Random.Range(0, 100) >= Base.Chance) return; + if (!Base.AllowedRoles.Contains(player.Role.ToString())) + return; + TeleportObject? target = GetRandomTarget(); if (target == null) return; diff --git a/Features/Serializable/SerializableTeleport.cs b/Features/Serializable/SerializableTeleport.cs index ed1d886..0ee4338 100644 --- a/Features/Serializable/SerializableTeleport.cs +++ b/Features/Serializable/SerializableTeleport.cs @@ -15,6 +15,29 @@ public class SerializableTeleport : SerializableObject, IIndicatorDefinition public int Chance { get; set; } = 100; + public List AllowedRoles { get; set; } = new List() + { + "Scp0492", + "Scp049", + "Scp096", + "Scp106", + "Scp173", + "Scp939", + "Scp3114", + "ClassD", + "Scientist", + "FacilityGuard", + "NtfPrivate", + "NtfSergeant", + "NtfSpecialist", + "NtfCaptain", + "ChaosConscript", + "ChaosRifleman", + "ChaosRepressor", + "ChaosMarauder", + "Tutorial", + }; + public float Cooldown { get; set; } = 5f; public override GameObject? SpawnOrUpdateObject(Room? room = null, GameObject? instance = null) From 9151ae414a30e8c83d3bc3d2ecb051ddbab935ee Mon Sep 17 00:00:00 2001 From: PaRRoT_tm Date: Sun, 1 Jun 2025 04:11:20 +0200 Subject: [PATCH 4/5] Added Server Specific Settings that allow selecting the map to load and unload during the game --- .../Handlers/Internal/ToolGunEventsHandler.cs | 80 ++++++++++++++++++- Features/MapUtils.cs | 3 +- Features/ToolGun/ToolGunItem.cs | 50 ++++++++++-- 3 files changed, 124 insertions(+), 9 deletions(-) diff --git a/Events/Handlers/Internal/ToolGunEventsHandler.cs b/Events/Handlers/Internal/ToolGunEventsHandler.cs index 0989c43..ecb678d 100644 --- a/Events/Handlers/Internal/ToolGunEventsHandler.cs +++ b/Events/Handlers/Internal/ToolGunEventsHandler.cs @@ -2,18 +2,23 @@ using LabApi.Events.CustomHandlers; using LabApi.Features.Wrappers; using MEC; +using ProjectMER.Features; using ProjectMER.Features.Extensions; using ProjectMER.Features.Objects; using ProjectMER.Features.ToolGun; +using UserSettings.ServerSpecific; namespace ProjectMER.Events.Handlers.Internal; public class ToolGunEventsHandler : CustomEventsHandler { - public override void OnServerRoundStarted() + private string lastLoadedMap = "None"; + + public override void OnServerRoundStarted() { Timing.RunCoroutine(ToolGunGUI()); - } + Timing.RunCoroutine(ToolGunLoadUnloadMap()); + } private static IEnumerator ToolGunGUI() { @@ -42,7 +47,76 @@ private static IEnumerator ToolGunGUI() } } - public override void OnPlayerDryFiringWeapon(PlayerDryFiringWeaponEventArgs ev) + private IEnumerator ToolGunLoadUnloadMap() + { + while (true) + { + yield return Timing.WaitForSeconds(0.5f); + + foreach (Player player in Player.List) + { + if (!player.CurrentItem.IsToolGun(out ToolGunItem toolGun)) + continue; + + if (!ServerSpecificSettingsSync.TryGetSettingOfUser(player.ReferenceHub, 1, out SSDropdownSetting dropdown)) + continue; + + string selectedMap = dropdown.TryGetSyncSelectionText(out string mapName) ? mapName : "None"; + + if (ServerSpecificSettingsSync.TryGetSettingOfUser(player.ReferenceHub, 2, out SSButton loadButton) && loadButton.SyncLastPress.IsRunning) + { + if (!string.IsNullOrEmpty(selectedMap) && selectedMap != "None") + { + if (lastLoadedMap != "None") + { + try + { + MapUtils.UnloadMap(lastLoadedMap); + } + catch (Exception ex) + { + Logger.Error($"Failed to Unload Map {lastLoadedMap}: {ex}"); + lastLoadedMap = "None"; + } + } + + try + { + MapUtils.LoadMap(selectedMap); + lastLoadedMap = selectedMap; + } + catch (Exception ex) + { + Logger.Error($"Failed to Load Map {selectedMap}: {ex}"); + lastLoadedMap = "None"; + } + } + + loadButton.SyncLastPress.Reset(); + } + + if (ServerSpecificSettingsSync.TryGetSettingOfUser(player.ReferenceHub, 3, out SSButton unloadButton) && unloadButton.SyncLastPress.IsRunning) + { + if (lastLoadedMap != "None") + { + try + { + MapUtils.UnloadMap(lastLoadedMap); + } + catch (Exception ex) + { + Logger.Error($"Failed to Unload Map {lastLoadedMap}: {ex}"); + } + lastLoadedMap = "None"; + } + + unloadButton.SyncLastPress.Reset(); + } + } + } + } + + public override void OnPlayerDryFiringWeapon(PlayerDryFiringWeaponEventArgs ev) { if (!ev.Weapon.IsToolGun(out ToolGunItem toolGun)) return; diff --git a/Features/MapUtils.cs b/Features/MapUtils.cs index 9f0b69e..e379a4a 100644 --- a/Features/MapUtils.cs +++ b/Features/MapUtils.cs @@ -166,8 +166,9 @@ public static SchematicObjectDataList GetSchematicDataByName(string schematicNam } public static string[] GetAvailableSchematicNames() => Directory.GetFiles(ProjectMER.SchematicsDir, "*.json", SearchOption.AllDirectories).Select(Path.GetFileNameWithoutExtension).Where(x => !x.Contains('-')).ToArray(); + public static string[] GetAvailableMapNames() => Directory.GetFiles(ProjectMER.MapsDir, "*.yml", SearchOption.AllDirectories).Select(Path.GetFileNameWithoutExtension).Where(x => !x.Contains('-')).ToArray(); - public static string GetColoredMapName(string mapName) + public static string GetColoredMapName(string mapName) { if (mapName == UntitledMapName) return $"{UntitledMapName}"; diff --git a/Features/ToolGun/ToolGunItem.cs b/Features/ToolGun/ToolGunItem.cs index 2d26ec1..ac18838 100644 --- a/Features/ToolGun/ToolGunItem.cs +++ b/Features/ToolGun/ToolGunItem.cs @@ -81,10 +81,31 @@ public static bool TryAdd(Player player) ServerSpecificSettingsSync.DefinedSettings = [ new SSGroupHeader("MapEditorReborn"), - new SSDropdownSetting(0, "Schematic Name", MapUtils.GetAvailableSchematicNames()) - ]; - - ServerSpecificSettingsSync.SendToPlayersConditionally(x => x.inventory.UserInventory.Items.Values.Any(x => x.IsToolGun(out ToolGunItem _))); + new SSDropdownSetting(0, "Schematic Name", MapUtils.GetAvailableSchematicNames()), + new SSDropdownSetting(1, "Map Name", new[] { "None" }.Concat(MapUtils.GetAvailableMapNames()).ToArray()), + new SSButton(2, "Load Map", "Load"), + new SSButton(3, "Unload Map", "Unload") + ]; + + if (ServerSpecificSettingsSync.TryGetSettingOfUser(player.ReferenceHub, 1, out SSDropdownSetting dropdown)) + { + dropdown.SyncSelectionIndexRaw = 0; + ServerSpecificSettingsSync.SendToPlayer(player.ReferenceHub, new[] { dropdown }); + } + + if (ServerSpecificSettingsSync.TryGetSettingOfUser(player.ReferenceHub, 2, out SSButton loadButton)) + { + loadButton.SyncLastPress.Reset(); + ServerSpecificSettingsSync.SendToPlayer(player.ReferenceHub, new[] { loadButton }); + } + + if (ServerSpecificSettingsSync.TryGetSettingOfUser(player.ReferenceHub, 3, out SSButton unloadButton)) + { + unloadButton.SyncLastPress.Reset(); + ServerSpecificSettingsSync.SendToPlayer(player.ReferenceHub, new[] { unloadButton }); + } + + ServerSpecificSettingsSync.SendToPlayersConditionally(x => x.inventory.UserInventory.Items.Values.Any(x => x.IsToolGun(out ToolGunItem _))); return true; } @@ -97,7 +118,26 @@ public static bool Remove(Player player) { ItemDictionary.Remove(itemBase.ItemSerial); player.RemoveItem(itemBase); - return true; + + if (ServerSpecificSettingsSync.TryGetSettingOfUser(player.ReferenceHub, 1, out SSDropdownSetting dropdown)) + { + dropdown.SyncSelectionIndexRaw = 0; + ServerSpecificSettingsSync.SendToPlayer(player.ReferenceHub, new[] { dropdown }); + } + + if (ServerSpecificSettingsSync.TryGetSettingOfUser(player.ReferenceHub, 2, out SSButton loadButton)) + { + loadButton.SyncLastPress.Reset(); + ServerSpecificSettingsSync.SendToPlayer(player.ReferenceHub, new[] { loadButton }); + } + + if (ServerSpecificSettingsSync.TryGetSettingOfUser(player.ReferenceHub, 3, out SSButton unloadButton)) + { + unloadButton.SyncLastPress.Reset(); + ServerSpecificSettingsSync.SendToPlayer(player.ReferenceHub, new[] { unloadButton }); + } + + return true; } } From 87319f14b23bb360a9c53462ce8736b4a6e6500c Mon Sep 17 00:00:00 2001 From: PaRRoT_tm Date: Sun, 1 Jun 2025 11:55:33 +0200 Subject: [PATCH 5/5] Modified and fixed some functions in ToolGunItem Implemented the "Indicator Object" setting in Server Specific Settings --- .../Handlers/Internal/ToolGunEventsHandler.cs | 24 +++++- Features/ToolGun/ToolGunItem.cs | 79 +++++++++---------- 2 files changed, 60 insertions(+), 43 deletions(-) diff --git a/Events/Handlers/Internal/ToolGunEventsHandler.cs b/Events/Handlers/Internal/ToolGunEventsHandler.cs index ecb678d..ade89c7 100644 --- a/Events/Handlers/Internal/ToolGunEventsHandler.cs +++ b/Events/Handlers/Internal/ToolGunEventsHandler.cs @@ -13,11 +13,12 @@ namespace ProjectMER.Events.Handlers.Internal; public class ToolGunEventsHandler : CustomEventsHandler { private string lastLoadedMap = "None"; + private bool? lastIndicatorState = null; public override void OnServerRoundStarted() { Timing.RunCoroutine(ToolGunGUI()); - Timing.RunCoroutine(ToolGunLoadUnloadMap()); + Timing.RunCoroutine(ToolGunMapController()); } private static IEnumerator ToolGunGUI() @@ -47,7 +48,7 @@ private static IEnumerator ToolGunGUI() } } - private IEnumerator ToolGunLoadUnloadMap() + private IEnumerator ToolGunMapController() { while (true) { @@ -58,6 +59,25 @@ private IEnumerator ToolGunLoadUnloadMap() if (!player.CurrentItem.IsToolGun(out ToolGunItem toolGun)) continue; + if (ServerSpecificSettingsSync.TryGetSettingOfUser(player.ReferenceHub, 4, out SSTwoButtonsSetting indicatorToggle)) + { + bool currentState = indicatorToggle.SyncIsA; + + if (lastIndicatorState == null || currentState != lastIndicatorState.Value) + { + if (currentState) + { + IndicatorObject.ClearIndicators(); + } + else + { + IndicatorObject.RefreshIndicators(); + } + + lastIndicatorState = currentState; + } + } + if (!ServerSpecificSettingsSync.TryGetSettingOfUser(player.ReferenceHub, 1, out SSDropdownSetting dropdown)) continue; diff --git a/Features/ToolGun/ToolGunItem.cs b/Features/ToolGun/ToolGunItem.cs index ac18838..22d1cd0 100644 --- a/Features/ToolGun/ToolGunItem.cs +++ b/Features/ToolGun/ToolGunItem.cs @@ -80,31 +80,19 @@ public static bool TryAdd(Player player) ServerSpecificSettingsSync.SendOnJoinFilter = (_) => false; // Prevent all users from receiving the tools after joining the server. ServerSpecificSettingsSync.DefinedSettings = [ - new SSGroupHeader("MapEditorReborn"), - new SSDropdownSetting(0, "Schematic Name", MapUtils.GetAvailableSchematicNames()), + new SSGroupHeader("MapEditorReborn"), + + new SSGroupHeader("Schematic Section"), + new SSDropdownSetting(0, "Schematic Name", MapUtils.GetAvailableSchematicNames()), + new SSTwoButtonsSetting(4, "Indicator Object", "Invisible", "Show", defaultIsB: false, hint: "Toggles visibility of Indicator Object."), + + new SSGroupHeader("Map Section"), new SSDropdownSetting(1, "Map Name", new[] { "None" }.Concat(MapUtils.GetAvailableMapNames()).ToArray()), new SSButton(2, "Load Map", "Load"), - new SSButton(3, "Unload Map", "Unload") + new SSButton(3, "Unload Map", "Unload"), ]; - if (ServerSpecificSettingsSync.TryGetSettingOfUser(player.ReferenceHub, 1, out SSDropdownSetting dropdown)) - { - dropdown.SyncSelectionIndexRaw = 0; - ServerSpecificSettingsSync.SendToPlayer(player.ReferenceHub, new[] { dropdown }); - } - - if (ServerSpecificSettingsSync.TryGetSettingOfUser(player.ReferenceHub, 2, out SSButton loadButton)) - { - loadButton.SyncLastPress.Reset(); - ServerSpecificSettingsSync.SendToPlayer(player.ReferenceHub, new[] { loadButton }); - } - - if (ServerSpecificSettingsSync.TryGetSettingOfUser(player.ReferenceHub, 3, out SSButton unloadButton)) - { - unloadButton.SyncLastPress.Reset(); - ServerSpecificSettingsSync.SendToPlayer(player.ReferenceHub, new[] { unloadButton }); - } - + ResetSettings(player); ServerSpecificSettingsSync.SendToPlayersConditionally(x => x.inventory.UserInventory.Items.Values.Any(x => x.IsToolGun(out ToolGunItem _))); return true; @@ -118,25 +106,7 @@ public static bool Remove(Player player) { ItemDictionary.Remove(itemBase.ItemSerial); player.RemoveItem(itemBase); - - if (ServerSpecificSettingsSync.TryGetSettingOfUser(player.ReferenceHub, 1, out SSDropdownSetting dropdown)) - { - dropdown.SyncSelectionIndexRaw = 0; - ServerSpecificSettingsSync.SendToPlayer(player.ReferenceHub, new[] { dropdown }); - } - - if (ServerSpecificSettingsSync.TryGetSettingOfUser(player.ReferenceHub, 2, out SSButton loadButton)) - { - loadButton.SyncLastPress.Reset(); - ServerSpecificSettingsSync.SendToPlayer(player.ReferenceHub, new[] { loadButton }); - } - - if (ServerSpecificSettingsSync.TryGetSettingOfUser(player.ReferenceHub, 3, out SSButton unloadButton)) - { - unloadButton.SyncLastPress.Reset(); - ServerSpecificSettingsSync.SendToPlayer(player.ReferenceHub, new[] { unloadButton }); - } - + ResetSettings(player); return true; } } @@ -144,7 +114,34 @@ public static bool Remove(Player player) return false; } - public bool CreateMode => Firearm.IsEmittingLight && !AdsModule.AdsTarget; + public static void ResetSettings(Player player) + { + if (ServerSpecificSettingsSync.TryGetSettingOfUser(player.ReferenceHub, 1, out SSDropdownSetting dropdown)) + { + dropdown.SyncSelectionIndexRaw = 0; + ServerSpecificSettingsSync.SendToPlayer(player.ReferenceHub, new[] { dropdown }); + } + + if (ServerSpecificSettingsSync.TryGetSettingOfUser(player.ReferenceHub, 2, out SSButton loadButton)) + { + loadButton.SyncLastPress.Reset(); + ServerSpecificSettingsSync.SendToPlayer(player.ReferenceHub, new[] { loadButton }); + } + + if (ServerSpecificSettingsSync.TryGetSettingOfUser(player.ReferenceHub, 3, out SSButton unloadButton)) + { + unloadButton.SyncLastPress.Reset(); + ServerSpecificSettingsSync.SendToPlayer(player.ReferenceHub, new[] { unloadButton }); + } + + if (ServerSpecificSettingsSync.TryGetSettingOfUser(player.ReferenceHub, 4, out SSTwoButtonsSetting indicatorsSetting)) + { + indicatorsSetting.SyncIsB = false; + ServerSpecificSettingsSync.SendToPlayer(player.ReferenceHub, new[] { indicatorsSetting }); + } + } + + public bool CreateMode => Firearm.IsEmittingLight && !AdsModule.AdsTarget; public bool DeleteMode => !Firearm.IsEmittingLight && !AdsModule.AdsTarget; public bool SelectMode => Firearm.IsEmittingLight && AdsModule.AdsTarget;