public static void SaveOffline(Colony colony) { if (colony.OwnerIsOnline()) { return; } try { var folder = $"{GameLoader.GAMEDATA_FOLDER}/savegames/{ServerManager.WorldName}/NPCArchive/"; if (!Directory.Exists(folder)) { Directory.CreateDirectory(folder); } var file = $"{folder}{colony.ColonyID}.json"; if (!Configuration.OfflineColonies) { if (!JSON.Deserialize(file, out var followers, false)) { followers = new JSONNode(NodeType.Array); } followers.ClearChildren(); PandaLogger.Log(ChatColor.cyan, $"All players from {colony.ColonyID} have disconnected. Clearing colony until reconnect."); var copyOfFollowers = new List <NPCBase>(); foreach (var follower in colony.Followers) { JSONNode jobloc = null; if (follower.IsValid) { var job = follower.Job; if (job != null && job.GetJobLocation() != Vector3Int.invalidPos) { jobloc = (JSONNode)job.GetJobLocation(); job.SetNPC(null); follower.ClearJob(); } } if (follower.TryGetJSON(out var node)) { if (jobloc != null) { node.SetAs("JobPoS", jobloc); } ModLoader.TriggerCallbacks(ModLoader.EModCallbackType.OnNPCSaved, follower, node); followers.AddToArray(node); copyOfFollowers.Add(follower); } } JSON.Serialize(file, followers); foreach (var deadMan in copyOfFollowers) { deadMan.OnDeath(); } colony.ForEachOwner(o => MonsterTracker.KillAllZombies(o)); } } catch (Exception ex) { PandaLogger.LogError(ex); } }