From a4d7500518f571f5a4398efed670bba81746a1ec Mon Sep 17 00:00:00 2001 From: WarrentyExpired Date: Fri, 16 Oct 2026 12:57:41 -0400 Subject: [PATCH] #W# Fix: Dungeon traps and there spawners now get deleted if they where prevously enabled. --- Projects/UOContent/Engines/TaskManager.cs | 66 +++++++++++++++++++++-- Projects/UOContent/Gumps/BuildWorld.cs | 4 +- 2 files changed, 64 insertions(+), 6 deletions(-) diff --git a/Projects/UOContent/Engines/TaskManager.cs b/Projects/UOContent/Engines/TaskManager.cs index f3c508ed8..bc22a5d01 100644 --- a/Projects/UOContent/Engines/TaskManager.cs +++ b/Projects/UOContent/Engines/TaskManager.cs @@ -4,6 +4,7 @@ using System.Linq; using Server; using Server.Commands; using Server.Engines.Spawners; +using Server.Items; namespace Server.Engines.Tasks; @@ -15,21 +16,78 @@ public static class TaskManager public static void Initialize() { - // 30-Minute Recurring Timer + EventSink.ServerStarted += OnServerBoot; + _timer30Min = Timer.DelayCall(TimeSpan.FromMinutes(30), TimeSpan.FromMinutes(30), () => On30MinuteTick(null)); - // 1-Hour Recurring Timer _timer1Hour = Timer.DelayCall(TimeSpan.FromHours(1), TimeSpan.FromHours(1), () => On1HourTick(null)); - // 24-Hour Recurring Timer _timer24Hour = Timer.DelayCall(TimeSpan.FromHours(24), TimeSpan.FromHours(24), () => On24HourTick(null)); - // Register developer commands for manual testing CommandSystem.Register("ForceTask30", AccessLevel.Developer, e => On30MinuteTick(e.Mobile)); CommandSystem.Register("ForceTask1H", AccessLevel.Developer, e => On1HourTick(e.Mobile)); CommandSystem.Register("ForceTask24H", AccessLevel.Developer, e => On24HourTick(e.Mobile)); } + // ========================================== + // RUN ONCE ON SERVER BOOT + // ========================================== + private static void OnServerBoot() + { + // 1. Check if dungeon traps are disabled globally + if (!Settings.S_DungeonTraps) + { + List toDelete = new List(); + + foreach (Item item in World.Items.Values) + { + // 2. Mark any physical BaseTrap items on the floor + if (item is BaseTrap) + { + toDelete.Add(item); + continue; + } + + // 3. Mark any type of Spawner (Standard or RegionSpawner) that spawns traps + if (item is BaseSpawner spawner) + { + bool spawnsTraps = false; + + // Loop through the actual SpawnerEntry objects to check their SpawnedName + foreach (var entry in spawner.Entries) + { + if (entry?.SpawnedName != null && entry.SpawnedName.IndexOf("Trap", StringComparison.OrdinalIgnoreCase) >= 0) + { + spawnsTraps = true; + break; + } + } + + if (spawnsTraps) + { + toDelete.Add(item); + } + } + } + + // 4. Safely delete everything we collected + int count = toDelete.Count; + for (int i = 0; i < count; i++) + { + if (toDelete[i] != null && !toDelete[i].Deleted) + { + toDelete[i].Delete(); + } + } + + // Output a console log so you know it ran successfully on boot + if (count > 0) + { + Console.WriteLine($"TaskManager: S_DungeonTraps is FALSE. Purged {count} physical traps and trap spawners."); + } + } + } + // ========================================== // 30-MINUTE INTERVAL LOGIC (Trap Reshuffle) // ========================================== diff --git a/Projects/UOContent/Gumps/BuildWorld.cs b/Projects/UOContent/Gumps/BuildWorld.cs index 1ef39d98b..e82e9ba43 100644 --- a/Projects/UOContent/Gumps/BuildWorld.cs +++ b/Projects/UOContent/Gumps/BuildWorld.cs @@ -115,7 +115,7 @@ namespace Server.Gumps case 4: if (Settings.S_DungeonTraps) { - InvokeCommand("IS Data/Spawns/traps.json", from); + InvokeCommand("IS Data/Spawns/Underworld/traps.json", from); } InvokeCommand("IS Data/Spawns/Chests/**.json", from); break; @@ -137,7 +137,7 @@ namespace Server.Gumps InvokeCommand("IS Data/Spawns/Underworld/**.json", from); if (Settings.S_DungeonTraps) { - InvokeCommand("IS Data/Spawns/traps.json", from); + InvokeCommand("IS Data/Spawns/Underworld/traps.json", from); } InvokeCommand("IS Data/Spawns/Chests/**.json", from);