talán fix geic végre big-pickle
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
using Assets.Code;
|
using Assets.Code;
|
||||||
using Riptide;
|
using Riptide;
|
||||||
using Riptide.Transports;
|
using Riptide.Transports;
|
||||||
using Steamworks;
|
using Steamworks;
|
||||||
@@ -189,15 +189,20 @@ namespace KCM.LoadSaveOverrides
|
|||||||
|
|
||||||
Main.helper.Log("Finished unpacking player data");
|
Main.helper.Log("Finished unpacking player data");
|
||||||
|
|
||||||
/*
|
// Fix AI brains save/load system to restore villager AI state
|
||||||
* Not even going to bother fixing AI brains save data yet, not in short-term roadmap
|
bool flag2 = this.AIBrainsSaveData != null;
|
||||||
*/
|
|
||||||
|
|
||||||
/*bool flag2 = this.AIBrainsSaveData != null;
|
|
||||||
if (flag2)
|
if (flag2)
|
||||||
{
|
{
|
||||||
this.AIBrainsSaveData.UnpackPrePlayer(AIBrainsContainer.inst);
|
try
|
||||||
}*/
|
{
|
||||||
|
Main.helper.Log("Unpacking AI brains before player data");
|
||||||
|
this.AIBrainsSaveData.UnpackPrePlayer(AIBrainsContainer.inst);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Main.helper.Log("Error unpacking AI brains pre-player: " + e.Message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Main.helper.Log("Unpacking free resource manager");
|
Main.helper.Log("Unpacking free resource manager");
|
||||||
this.FreeResourceManagerSaveData.Unpack(FreeResourceManager.inst);
|
this.FreeResourceManagerSaveData.Unpack(FreeResourceManager.inst);
|
||||||
@@ -255,7 +260,55 @@ namespace KCM.LoadSaveOverrides
|
|||||||
bool flag10 = this.AIBrainsSaveData != null;
|
bool flag10 = this.AIBrainsSaveData != null;
|
||||||
if (flag10)
|
if (flag10)
|
||||||
{
|
{
|
||||||
this.AIBrainsSaveData.Unpack(AIBrainsContainer.inst);
|
try
|
||||||
|
{
|
||||||
|
this.AIBrainsSaveData.Unpack(AIBrainsContainer.inst);
|
||||||
|
Main.helper.Log("AI brains unpacked successfully");
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Main.helper.Log("Error unpacking AI brains: " + e.Message);
|
||||||
|
Main.helper.Log("Attempting to reinitialize AI systems");
|
||||||
|
try
|
||||||
|
{
|
||||||
|
AIBrainsContainer.inst.ClearAIs();
|
||||||
|
// Force reinitialize AI for all villagers
|
||||||
|
for (int i = 0; i < Villager.villagers.Count; i++)
|
||||||
|
{
|
||||||
|
Villager v = Villager.villagers.data[i];
|
||||||
|
if (v != null && v.brain != null)
|
||||||
|
{
|
||||||
|
v.brain.Restart();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Main.helper.Log("AI systems reinitialized");
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Main.helper.Log("Failed to reinitialize AI systems: " + ex.Message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Main.helper.Log("No AI brains save data found, initializing fresh AI");
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Initialize AI for all villagers if no save data
|
||||||
|
for (int i = 0; i < Villager.villagers.Count; i++)
|
||||||
|
{
|
||||||
|
Villager v = Villager.villagers.data[i];
|
||||||
|
if (v != null && v.brain != null)
|
||||||
|
{
|
||||||
|
v.brain.Restart();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Main.helper.Log("Fresh AI initialization completed");
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Main.helper.Log("Failed fresh AI initialization: " + e.Message);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Main.helper.Log("Unpacking custom save data");
|
Main.helper.Log("Unpacking custom save data");
|
||||||
bool flag11 = this.CustomSaveData != null;
|
bool flag11 = this.CustomSaveData != null;
|
||||||
@@ -287,41 +340,190 @@ namespace KCM.LoadSaveOverrides
|
|||||||
Player.inst.Buildings.data[i].UpdateMaterialSelection();
|
Player.inst.Buildings.data[i].UpdateMaterialSelection();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Player.inst.loadTickDelay = 1;
|
// Increase loadTickDelay values to ensure proper initialization
|
||||||
Type playerType = typeof(Player);
|
Type playerType = typeof(Player);
|
||||||
FieldInfo loadTickDelayField = playerType.GetField("loadTickDelay", BindingFlags.Instance | BindingFlags.NonPublic);
|
FieldInfo loadTickDelayField = playerType.GetField("loadTickDelay", BindingFlags.Instance | BindingFlags.NonPublic);
|
||||||
if (loadTickDelayField != null)
|
if (loadTickDelayField != null)
|
||||||
{
|
{
|
||||||
loadTickDelayField.SetValue(Player.inst, 1);
|
loadTickDelayField.SetValue(Player.inst, 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
// UnitSystem.inst.loadTickDelay = 1;
|
// UnitSystem.inst.loadTickDelay = 3;
|
||||||
Type unitSystemType = typeof(UnitSystem);
|
Type unitSystemType = typeof(UnitSystem);
|
||||||
loadTickDelayField = unitSystemType.GetField("loadTickDelay", BindingFlags.Instance | BindingFlags.NonPublic);
|
loadTickDelayField = unitSystemType.GetField("loadTickDelay", BindingFlags.Instance | BindingFlags.NonPublic);
|
||||||
if (loadTickDelayField != null)
|
if (loadTickDelayField != null)
|
||||||
{
|
{
|
||||||
loadTickDelayField.SetValue(UnitSystem.inst, 1);
|
loadTickDelayField.SetValue(UnitSystem.inst, 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
// JobSystem.inst.loadTickDelay = 1;
|
// JobSystem.inst.loadTickDelay = 3;
|
||||||
Type jobSystemType = typeof(JobSystem);
|
Type jobSystemType = typeof(JobSystem);
|
||||||
loadTickDelayField = jobSystemType.GetField("loadTickDelay", BindingFlags.Instance | BindingFlags.NonPublic);
|
loadTickDelayField = jobSystemType.GetField("loadTickDelay", BindingFlags.Instance | BindingFlags.NonPublic);
|
||||||
if (loadTickDelayField != null)
|
if (loadTickDelayField != null)
|
||||||
{
|
{
|
||||||
loadTickDelayField.SetValue(JobSystem.inst, 1);
|
loadTickDelayField.SetValue(JobSystem.inst, 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
// VillagerSystem.inst.loadTickDelay = 1;
|
// VillagerSystem.inst.loadTickDelay = 3;
|
||||||
Type villagerSystemType = typeof(VillagerSystem);
|
Type villagerSystemType = typeof(VillagerSystem);
|
||||||
loadTickDelayField = villagerSystemType.GetField("loadTickDelay", BindingFlags.Instance | BindingFlags.NonPublic);
|
loadTickDelayField = villagerSystemType.GetField("loadTickDelay", BindingFlags.Instance | BindingFlags.NonPublic);
|
||||||
if (loadTickDelayField != null)
|
if (loadTickDelayField != null)
|
||||||
{
|
{
|
||||||
loadTickDelayField.SetValue(VillagerSystem.inst, 1);
|
loadTickDelayField.SetValue(VillagerSystem.inst, 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Force AI system restart after load
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Main.helper.Log("Forcing AI system restart after load");
|
||||||
|
|
||||||
|
// Restart all villager AI brains
|
||||||
|
for (int i = 0; i < Villager.villagers.Count; i++)
|
||||||
|
{
|
||||||
|
Villager v = Villager.villagers.data[i];
|
||||||
|
if (v != null && v.brain != null)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
v.brain.Restart();
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Main.helper.Log($"Failed to restart villager AI: {e.Message}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Force job system refresh
|
||||||
|
if (JobSystem.inst != null)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Use reflection to call any refresh/rebuild methods
|
||||||
|
var jobSystemType = typeof(JobSystem);
|
||||||
|
var refreshMethods = jobSystemType.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)
|
||||||
|
.Where(m => m.Name.Contains("Refresh") || m.Name.Contains("Rebuild") || m.Name.Contains("Update"));
|
||||||
|
|
||||||
|
foreach (var method in refreshMethods)
|
||||||
|
{
|
||||||
|
if (method.GetParameters().Length == 0)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
method.Invoke(JobSystem.inst, null);
|
||||||
|
Main.helper.Log($"Called JobSystem.{method.Name}()");
|
||||||
|
}
|
||||||
|
catch { }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Main.helper.Log($"Error refreshing job system: {e.Message}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Main.helper.Log("AI system restart completed");
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Main.helper.Log($"Error during AI system restart: {e.Message}");
|
||||||
}
|
}
|
||||||
|
|
||||||
Main.helper.Log($"Setting kingdom name to: {kingdomNames[Main.PlayerSteamID]}");
|
Main.helper.Log($"Setting kingdom name to: {kingdomNames[Main.PlayerSteamID]}");
|
||||||
TownNameUI.inst.SetTownName(kingdomNames[Main.PlayerSteamID]);
|
TownNameUI.inst.SetTownName(kingdomNames[Main.PlayerSteamID]);
|
||||||
|
|
||||||
|
// Perform villager state resync after loading completes
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Main.helper.Log("Starting villager state resync after load");
|
||||||
|
|
||||||
|
// Wait a frame for all systems to initialize
|
||||||
|
System.Threading.Tasks.Task.Delay(100).ContinueWith(_ =>
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Main.helper.Log("Performing delayed villager resync");
|
||||||
|
|
||||||
|
// Resync all villager positions and states
|
||||||
|
for (int i = 0; i < Villager.villagers.Count; i++)
|
||||||
|
{
|
||||||
|
Villager v = Villager.villagers.data[i];
|
||||||
|
if (v != null)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Force position update
|
||||||
|
Vector3 currentPos = v.Pos;
|
||||||
|
v.TeleportTo(currentPos);
|
||||||
|
|
||||||
|
// Restart AI brain if it exists
|
||||||
|
if (v.brain != null)
|
||||||
|
{
|
||||||
|
v.brain.Restart();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure villager is in correct system lists
|
||||||
|
if (v.workerJob != null && Player.inst != null)
|
||||||
|
{
|
||||||
|
if (!Player.inst.Workers.Contains(v))
|
||||||
|
{
|
||||||
|
Player.inst.Workers.Add(v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (v.workerJob == null && Player.inst != null)
|
||||||
|
{
|
||||||
|
if (!Player.inst.Homeless.Contains(v))
|
||||||
|
{
|
||||||
|
Player.inst.Homeless.Add(v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Main.helper.Log($"Error resyncing villager {i}: {e.Message}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Force job system to re-evaluate all jobs
|
||||||
|
if (JobSystem.inst != null)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var jobSystemType = typeof(JobSystem);
|
||||||
|
var updateMethods = jobSystemType.GetMethods(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance)
|
||||||
|
.Where(m => (m.Name.Contains("Update") || m.Name.Contains("Refresh")) && m.GetParameters().Length == 0);
|
||||||
|
|
||||||
|
foreach (var method in updateMethods)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
method.Invoke(JobSystem.inst, null);
|
||||||
|
Main.helper.Log($"Called JobSystem.{method.Name} for resync");
|
||||||
|
}
|
||||||
|
catch { }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Main.helper.Log($"Error updating job system: {e.Message}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Main.helper.Log("Villager state resync completed");
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Main.helper.Log($"Error in delayed villager resync: {e.Message}");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Main.helper.Log($"Error starting villager resync: {e.Message}");
|
||||||
|
}
|
||||||
|
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
6
Main.cs
6
Main.cs
@@ -1,4 +1,4 @@
|
|||||||
using Assets.Code;
|
using Assets.Code;
|
||||||
using Assets.Code.UI;
|
using Assets.Code.UI;
|
||||||
using Assets.Interface;
|
using Assets.Interface;
|
||||||
using Harmony;
|
using Harmony;
|
||||||
@@ -1160,9 +1160,11 @@ namespace KCM
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
Main.helper.Log("SpeedControlUI.SetSpeed (local): " + idx);
|
Main.helper.Log("SpeedControlUI.SetSpeed (local): " + idx);
|
||||||
|
bool isPaused = (idx == 0);
|
||||||
new SetSpeed()
|
new SetSpeed()
|
||||||
{
|
{
|
||||||
speed = idx
|
speed = idx,
|
||||||
|
isPaused = isPaused
|
||||||
}.Send();
|
}.Send();
|
||||||
|
|
||||||
lastTime = DateTimeOffset.Now.ToUnixTimeMilliseconds();
|
lastTime = DateTimeOffset.Now.ToUnixTimeMilliseconds();
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
@@ -11,18 +11,64 @@ namespace KCM.Packets.Game
|
|||||||
public override ushort packetId => (int)Enums.Packets.SetSpeed;
|
public override ushort packetId => (int)Enums.Packets.SetSpeed;
|
||||||
|
|
||||||
public int speed { get; set; }
|
public int speed { get; set; }
|
||||||
|
public bool isPaused { get; set; }
|
||||||
|
|
||||||
public override void HandlePacketClient()
|
public override void HandlePacketClient()
|
||||||
{
|
{
|
||||||
if (clientId == KCClient.client.Id) // Prevent speed softlock
|
if (clientId == KCClient.client.Id) // Prevent speed softlock
|
||||||
return;
|
return;
|
||||||
|
|
||||||
SpeedControlUI.inst.SetSpeed(speed);
|
try
|
||||||
|
{
|
||||||
|
// Apply speed setting
|
||||||
|
SpeedControlUI.inst.SetSpeed(speed);
|
||||||
|
|
||||||
|
// Handle pause/unpause state
|
||||||
|
if (isPaused && Time.timeScale > 0)
|
||||||
|
{
|
||||||
|
// Game should be paused
|
||||||
|
Time.timeScale = 0f;
|
||||||
|
Main.helper.Log("Game paused via network sync");
|
||||||
|
}
|
||||||
|
else if (!isPaused && Time.timeScale == 0)
|
||||||
|
{
|
||||||
|
// Game should be unpaused - restore speed
|
||||||
|
Time.timeScale = 1f;
|
||||||
|
SpeedControlUI.inst.SetSpeed(speed);
|
||||||
|
Main.helper.Log("Game unpaused via network sync");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Force AI system update when speed changes
|
||||||
|
if (speed > 0)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Restart villager AI to ensure they continue working
|
||||||
|
for (int i = 0; i < Villager.villagers.Count; i++)
|
||||||
|
{
|
||||||
|
Villager v = Villager.villagers.data[i];
|
||||||
|
if (v != null && v.brain != null)
|
||||||
|
{
|
||||||
|
v.brain.Restart();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Main.helper.Log($"AI systems restarted for speed change to {speed}");
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Main.helper.Log("Error restarting AI on speed change: " + e.Message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Main.helper.Log("Error handling SetSpeed packet: " + e.Message);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void HandlePacketServer()
|
public override void HandlePacketServer()
|
||||||
{
|
{
|
||||||
//throw new NotImplementedException();
|
// Server doesn't need to handle this packet
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,8 +15,10 @@ namespace KCM.StateManagement.Sync
|
|||||||
private const int ResourceBroadcastIntervalMs = 2000;
|
private const int ResourceBroadcastIntervalMs = 2000;
|
||||||
private const int MaxBuildingSnapshotBytes = 30000;
|
private const int MaxBuildingSnapshotBytes = 30000;
|
||||||
private const int MaxVillagerTeleportsPerResync = 400;
|
private const int MaxVillagerTeleportsPerResync = 400;
|
||||||
|
private const int VillagerValidationIntervalMs = 10000; // 10 seconds
|
||||||
|
|
||||||
private static long lastResourceBroadcastMs;
|
private static long lastResourceBroadcastMs;
|
||||||
|
private static long lastVillagerValidationMs;
|
||||||
|
|
||||||
private static FieldInfo freeResourceAmountField;
|
private static FieldInfo freeResourceAmountField;
|
||||||
private static MethodInfo resourceAmountGetMethod;
|
private static MethodInfo resourceAmountGetMethod;
|
||||||
@@ -30,27 +32,36 @@ namespace KCM.StateManagement.Sync
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
long now = DateTimeOffset.Now.ToUnixTimeMilliseconds();
|
long now = DateTimeOffset.Now.ToUnixTimeMilliseconds();
|
||||||
if ((now - lastResourceBroadcastMs) < ResourceBroadcastIntervalMs)
|
|
||||||
return;
|
// Resource broadcast
|
||||||
|
if ((now - lastResourceBroadcastMs) >= ResourceBroadcastIntervalMs)
|
||||||
lastResourceBroadcastMs = now;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
{
|
||||||
ResourceSnapshotPacket snapshot = BuildResourceSnapshotPacket();
|
lastResourceBroadcastMs = now;
|
||||||
if (snapshot == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
snapshot.clientId = KCClient.client != null ? KCClient.client.Id : (ushort)0;
|
try
|
||||||
|
{
|
||||||
|
ResourceSnapshotPacket snapshot = BuildResourceSnapshotPacket();
|
||||||
|
if (snapshot == null)
|
||||||
|
return;
|
||||||
|
|
||||||
// Exclude host/local client from receiving its own snapshot.
|
snapshot.clientId = KCClient.client != null ? KCClient.client.Id : (ushort)0;
|
||||||
ushort exceptId = KCClient.client != null ? KCClient.client.Id : (ushort)0;
|
|
||||||
snapshot.SendToAll(exceptId);
|
// Exclude host/local client from receiving its own snapshot.
|
||||||
|
ushort exceptId = KCClient.client != null ? KCClient.client.Id : (ushort)0;
|
||||||
|
snapshot.SendToAll(exceptId);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Main.helper.Log("Error broadcasting resource snapshot");
|
||||||
|
Main.helper.Log(ex.ToString());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
|
||||||
|
// Villager state validation
|
||||||
|
if ((now - lastVillagerValidationMs) >= VillagerValidationIntervalMs)
|
||||||
{
|
{
|
||||||
Main.helper.Log("Error broadcasting resource snapshot");
|
lastVillagerValidationMs = now;
|
||||||
Main.helper.Log(ex.ToString());
|
ValidateAndCorrectVillagerStates();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -731,5 +742,92 @@ namespace KCM.StateManagement.Sync
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void ValidateAndCorrectVillagerStates()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
int stuckVillagers = 0;
|
||||||
|
int correctedVillagers = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < Villager.villagers.Count; i++)
|
||||||
|
{
|
||||||
|
Villager v = Villager.villagers.data[i];
|
||||||
|
if (v == null)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
bool needsCorrection = false;
|
||||||
|
|
||||||
|
// Check if villager is stuck (not moving for too long while having a job)
|
||||||
|
if (v.workerJob != null && v.brain != null)
|
||||||
|
{
|
||||||
|
// Check if villager is in invalid state
|
||||||
|
if (v.brain.currentAction == null && v.workerJob.active)
|
||||||
|
{
|
||||||
|
needsCorrection = true;
|
||||||
|
stuckVillagers++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if villager position is invalid
|
||||||
|
if (float.IsNaN(v.Pos.x) || float.IsNaN(v.Pos.y) || float.IsNaN(v.Pos.z))
|
||||||
|
{
|
||||||
|
needsCorrection = true;
|
||||||
|
stuckVillagers++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (needsCorrection)
|
||||||
|
{
|
||||||
|
// Correct villager state
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Restart AI brain
|
||||||
|
if (v.brain != null)
|
||||||
|
{
|
||||||
|
v.brain.Restart();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure valid position
|
||||||
|
if (float.IsNaN(v.Pos.x) || float.IsNaN(v.Pos.y) || float.IsNaN(v.Pos.z))
|
||||||
|
{
|
||||||
|
// Teleport to a safe position near their workplace or home
|
||||||
|
Vector3 safePos = Vector3.zero;
|
||||||
|
if (v.workerJob != null && v.workerJob.employer != null)
|
||||||
|
{
|
||||||
|
safePos = v.workerJob.employer.transform.position;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
safePos = new Vector3(World.inst.GridWidth / 2, 0, World.inst.GridHeight / 2);
|
||||||
|
}
|
||||||
|
v.TeleportTo(safePos);
|
||||||
|
}
|
||||||
|
|
||||||
|
correctedVillagers++;
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Main.helper.Log($"Error correcting villager {i}: {e.Message}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Main.helper.Log($"Error validating villager {i}: {e.Message}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stuckVillagers > 0)
|
||||||
|
{
|
||||||
|
Main.helper.Log($"Villager validation: Found {stuckVillagers} stuck villagers, corrected {correctedVillagers}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Main.helper.Log("Error in villager state validation: " + e.Message);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user