From 0148f6d1fc2a42f61cd2346661465ba1867e743d Mon Sep 17 00:00:00 2001 From: WarrentyExpired Date: Tue, 20 Oct 2026 19:13:16 -0400 Subject: [PATCH] #W# Added: Taskmanager now has a 4 hour timer running. --- Projects/UOContent/Engines/TaskManager.cs | 154 +++++++++++++--------- 1 file changed, 90 insertions(+), 64 deletions(-) diff --git a/Projects/UOContent/Engines/TaskManager.cs b/Projects/UOContent/Engines/TaskManager.cs index bc22a5d01..a8cb80e4a 100644 --- a/Projects/UOContent/Engines/TaskManager.cs +++ b/Projects/UOContent/Engines/TaskManager.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.IO; using Server; using Server.Commands; using Server.Engines.Spawners; @@ -12,82 +13,23 @@ public static class TaskManager { private static Timer _timer30Min; private static Timer _timer1Hour; + private static Timer _timer4Hour; private static Timer _timer24Hour; public static void Initialize() { EventSink.ServerStarted += OnServerBoot; - _timer30Min = Timer.DelayCall(TimeSpan.FromMinutes(30), TimeSpan.FromMinutes(30), () => On30MinuteTick(null)); - _timer1Hour = Timer.DelayCall(TimeSpan.FromHours(1), TimeSpan.FromHours(1), () => On1HourTick(null)); - + _timer4Hour = Timer.DelayCall(TimeSpan.FromHours(4), TimeSpan.FromHours(4), () => On4HourTick(null)); _timer24Hour = Timer.DelayCall(TimeSpan.FromHours(24), TimeSpan.FromHours(24), () => On24HourTick(null)); CommandSystem.Register("ForceTask30", AccessLevel.Developer, e => On30MinuteTick(e.Mobile)); CommandSystem.Register("ForceTask1H", AccessLevel.Developer, e => On1HourTick(e.Mobile)); + CommandSystem.Register("ForceTask4H", AccessLevel.Developer, e => On4HourTick(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) // ========================================== @@ -100,14 +42,98 @@ public static class TaskManager // ========================================== public static void On1HourTick(Mobile from = null) { - // Add hourly tasks here } + // ========================================== + // 4-HOUR INTERVAL LOGIC + // ========================================== + public static void On4HourTick(Mobile from = null) + { + RespawnPedestals(from); + } + + // ========================================== // 24-HOUR INTERVAL LOGIC // ========================================== public static void On24HourTick(Mobile from = null) { - // Add daily tasks here + } + + // ========================================== + // RUN ONCE ON SERVER BOOT + // ========================================== + private static void OnServerBoot() + { + // Check if dungeon traps are disabled globally and if true deletes any spawners and traps. + if (!Settings.S_DungeonTraps) + { + List toDelete = new List(); + foreach (Item item in World.Items.Values) + { + if (item is BaseTrap) + { + toDelete.Add(item); + continue; + } + if (item is BaseSpawner spawner) + { + bool spawnsTraps = false; + 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); + } + } + } + int count = toDelete.Count; + for (int i = 0; i < count; i++) + { + if (toDelete[i] != null && !toDelete[i].Deleted) + { + toDelete[i].Delete(); + } + } + if (count > 0) + { + Console.WriteLine($"TaskManager: S_DungeonTraps is FALSE. Purged {count} physical traps and trap spawners."); + } + } + } + + private static void RespawnPedestals(Mobile from = null) + { + string targetFolder = Path.Combine(Core.BaseDirectory, "Data", "Spawns", "Pedestals"); + if (!Directory.Exists(targetFolder)) + { + Directory.CreateDirectory(targetFolder); + return; + } + string[] jsonFiles = Directory.GetFiles(targetFolder, "*.json", SearchOption.AllDirectories); + if (jsonFiles.Length == 0) + { + return; + } + Utility.PushColor(ConsoleColor.Green); + Console.WriteLine($"[PedestalBootTask] Refreshing {jsonFiles.Length} pedestal spawner file(s)..."); + Utility.PopColor(); + Mobile executer = from ?? World.Mobiles.Values.FirstOrDefault(m => m.AccessLevel >= AccessLevel.GameMaster); + if (executer == null) + { + Console.WriteLine("[TaskManager] Automated pedestal respawn skipped. A GM must be online to execute the [is command."); + return; + } + foreach (string filePath in jsonFiles) + { + string relativePath = Path.GetRelativePath(Core.BaseDirectory, filePath); + CommandSystem.Handle(executer, $"[is {relativePath}"); + } } }