feat(event): 实现延迟事件的持久化
重构 `DelayedActionManager` 以支持游戏存档和读档。 `DelayedAction` 类现在存储 `eventDefName` 字符串,而不是无法序列化的 `Action` 委托。通过实现 `IExposable` 接口,延迟动作列表现在可以被正确保存和加载,确保计划中的事件不会因重新加载游戏而丢失。
This commit is contained in:
Binary file not shown.
@@ -1,5 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using RimWorld;
|
||||||
using RimWorld.Planet;
|
using RimWorld.Planet;
|
||||||
using Verse;
|
using Verse;
|
||||||
|
|
||||||
@@ -7,10 +8,26 @@ namespace WulaFallenEmpire
|
|||||||
{
|
{
|
||||||
public class DelayedActionManager : WorldComponent
|
public class DelayedActionManager : WorldComponent
|
||||||
{
|
{
|
||||||
private class DelayedAction
|
// Nested class must be public to be accessible for serialization
|
||||||
|
public class DelayedAction : IExposable
|
||||||
{
|
{
|
||||||
public int TicksRemaining;
|
public int TicksRemaining;
|
||||||
public Action Action;
|
public string eventDefName;
|
||||||
|
|
||||||
|
// Parameterless constructor for Scribe
|
||||||
|
public DelayedAction() { }
|
||||||
|
|
||||||
|
public DelayedAction(string eventDefName, int ticks)
|
||||||
|
{
|
||||||
|
this.eventDefName = eventDefName;
|
||||||
|
this.TicksRemaining = ticks;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ExposeData()
|
||||||
|
{
|
||||||
|
Scribe_Values.Look(ref TicksRemaining, "ticksRemaining", 0);
|
||||||
|
Scribe_Values.Look(ref eventDefName, "eventDefName");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<DelayedAction> actions = new List<DelayedAction>();
|
private List<DelayedAction> actions = new List<DelayedAction>();
|
||||||
@@ -19,13 +36,13 @@ namespace WulaFallenEmpire
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddAction(Action action, int delayTicks)
|
public void AddAction(string eventDefName, int delayTicks)
|
||||||
{
|
{
|
||||||
if (action == null || delayTicks <= 0)
|
if (string.IsNullOrEmpty(eventDefName) || delayTicks <= 0)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
actions.Add(new DelayedAction { TicksRemaining = delayTicks, Action = action });
|
actions.Add(new DelayedAction(eventDefName, delayTicks));
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void WorldComponentTick()
|
public override void WorldComponentTick()
|
||||||
@@ -39,23 +56,40 @@ namespace WulaFallenEmpire
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
delayedAction.Action();
|
ExecuteAction(delayedAction.eventDefName);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Log.Error($"[WulaFallenEmpire] Error executing delayed action: {ex}");
|
Log.Error($"[WulaFallenEmpire] Error executing delayed action for event '{delayedAction.eventDefName}': {ex}");
|
||||||
}
|
}
|
||||||
actions.RemoveAt(i);
|
actions.RemoveAt(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void ExecuteAction(string defName)
|
||||||
|
{
|
||||||
|
EventDef nextDef = DefDatabase<EventDef>.GetNamed(defName, false);
|
||||||
|
if (nextDef != null)
|
||||||
|
{
|
||||||
|
// This logic is simplified from Effect_OpenCustomUI.OpenUI
|
||||||
|
// It assumes delayed actions always open a new dialog.
|
||||||
|
Find.WindowStack.Add(new Dialog_CustomDisplay(nextDef));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Log.Error($"[WulaFallenEmpire] DelayedActionManager could not find EventDef named '{defName}'");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public override void ExposeData()
|
public override void ExposeData()
|
||||||
{
|
{
|
||||||
// This simple manager does not save scheduled actions across game loads.
|
|
||||||
// If you need actions to persist, you would need a more complex system
|
|
||||||
// to serialize the action's target and parameters.
|
|
||||||
base.ExposeData();
|
base.ExposeData();
|
||||||
|
Scribe_Collections.Look(ref actions, "delayedActions", LookMode.Deep);
|
||||||
|
if (actions == null)
|
||||||
|
{
|
||||||
|
actions = new List<DelayedAction>();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -24,7 +24,7 @@ namespace WulaFallenEmpire
|
|||||||
var actionManager = Find.World.GetComponent<DelayedActionManager>();
|
var actionManager = Find.World.GetComponent<DelayedActionManager>();
|
||||||
if (actionManager != null)
|
if (actionManager != null)
|
||||||
{
|
{
|
||||||
actionManager.AddAction(() => OpenUI(), delayTicks);
|
actionManager.AddAction(defName, delayTicks);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user