diff --git a/Events/Handlers/Internal/ToolGunEventsHandler.cs b/Events/Handlers/Internal/ToolGunEventsHandler.cs index 0989c43..ade89c7 100644 --- a/Events/Handlers/Internal/ToolGunEventsHandler.cs +++ b/Events/Handlers/Internal/ToolGunEventsHandler.cs @@ -2,18 +2,24 @@ 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"; + private bool? lastIndicatorState = null; + + public override void OnServerRoundStarted() { Timing.RunCoroutine(ToolGunGUI()); - } + Timing.RunCoroutine(ToolGunMapController()); + } private static IEnumerator ToolGunGUI() { @@ -42,7 +48,95 @@ private static IEnumerator ToolGunGUI() } } - public override void OnPlayerDryFiringWeapon(PlayerDryFiringWeaponEventArgs ev) + private IEnumerator ToolGunMapController() + { + 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, 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; + + 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/Objects/TeleportObject.cs b/Features/Objects/TeleportObject.cs index 309f149..df9bddc 100644 --- a/Features/Objects/TeleportObject.cs +++ b/Features/Objects/TeleportObject.cs @@ -42,7 +42,13 @@ public void OnTriggerEnter(Collider other) if (NextTimeUse > DateTime.Now) return; - TeleportObject? target = GetRandomTarget(); + 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 00dc294..0ee4338 100644 --- a/Features/Serializable/SerializableTeleport.cs +++ b/Features/Serializable/SerializableTeleport.cs @@ -13,23 +13,59 @@ public class SerializableTeleport : SerializableObject, IIndicatorDefinition { public List Targets { get; set; } = []; - public float Cooldown { get; set; } = 5f; - - public override GameObject? SpawnOrUpdateObject(Room? room = null, GameObject? instance = null) + 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) { GameObject gameObject = instance ?? new GameObject("Teleport"); Vector3 position = room.GetAbsolutePosition(Position); 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) diff --git a/Features/ToolGun/ToolGunItem.cs b/Features/ToolGun/ToolGunItem.cs index 2d26ec1..22d1cd0 100644 --- a/Features/ToolGun/ToolGunItem.cs +++ b/Features/ToolGun/ToolGunItem.cs @@ -80,11 +80,20 @@ 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"), - ServerSpecificSettingsSync.SendToPlayersConditionally(x => x.inventory.UserInventory.Items.Values.Any(x => x.IsToolGun(out ToolGunItem _))); + 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"), + ]; + + ResetSettings(player); + ServerSpecificSettingsSync.SendToPlayersConditionally(x => x.inventory.UserInventory.Items.Values.Any(x => x.IsToolGun(out ToolGunItem _))); return true; } @@ -97,14 +106,42 @@ public static bool Remove(Player player) { ItemDictionary.Remove(itemBase.ItemSerial); player.RemoveItem(itemBase); - return true; + ResetSettings(player); + return true; } } 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;