Files
WulaFallenEmpireRW/Source/WulaFallenEmpire/EventSystem/EventVariableManager.cs
ProjectKoi-Kalo\Kalo 1a49972ea0 feat: 扩展事件系统,改进变量处理和调试功能
本次提交对事件系统进行了多项增强和修复,主要包括:

-   为`Effect_SetVariable`添加了类型支持(Int, Float, String, Bool),允许更精确地设置变量类型 [在`EventDef_Wula.xml`, `EventDef_WULA_FE_Spiritualist.xml`, `Effect.cs`中]。
-   改进了`Condition`类,增加了类型检查和错误处理,避免了类型不匹配导致的错误 [在`Condition.cs`中]。
-   修复了`Effect_ModifyVariable`中的错误,允许使用变量名作为修改值,并支持int和float类型的操作 [在`Effect.cs`中]。
-   添加了`Effect_StoreFactionGoodwill`,用于存储派系好感度到变量中 [在`Effect.cs`中]。
-   增加了`Dialog_ManageEventVariables`,用于调试和管理事件变量 [在`DebugActions.cs`, `Dialog_ManageEventVariables.cs`中]。
-   改进了`EventVariableManager`,增加了类型转换的错误处理和日志记录,并添加了获取所有变量的函数 [在`EventVariableManager.cs`中]。

这些改动提高了事件系统的稳定性和可扩展性,并为调试提供了更多工具。
2025-08-16 17:47:31 +08:00

177 lines
6.5 KiB
C#

using System.Collections.Generic;
using Verse;
using RimWorld;
using RimWorld.Planet;
namespace WulaFallenEmpire
{
public class EventVariableManager : WorldComponent
{
private Dictionary<string, int> intVars = new Dictionary<string, int>();
private Dictionary<string, float> floatVars = new Dictionary<string, float>();
private Dictionary<string, string> stringVars = new Dictionary<string, string>();
private Dictionary<string, Pawn> pawnVars = new Dictionary<string, Pawn>();
private Dictionary<string, List<Pawn>> pawnListVars = new Dictionary<string, List<Pawn>>();
// 用于Scribe的辅助列表
private List<string> pawnVarKeys;
private List<Pawn> pawnVarValues;
private List<string> pawnListVarKeys;
private List<List<Pawn>> pawnListVarValues;
// Required for WorldComponent
public EventVariableManager(World world) : base(world)
{
}
public override void ExposeData()
{
base.ExposeData();
Scribe_Collections.Look(ref intVars, "intVars", LookMode.Value, LookMode.Value);
Scribe_Collections.Look(ref floatVars, "floatVars", LookMode.Value, LookMode.Value);
Scribe_Collections.Look(ref stringVars, "stringVars", LookMode.Value, LookMode.Value);
Scribe_Collections.Look(ref pawnVars, "pawnVars", LookMode.Value, LookMode.Reference, ref pawnVarKeys, ref pawnVarValues);
Scribe_Collections.Look(ref pawnListVars, "pawnListVars", LookMode.Value, LookMode.Reference, ref pawnListVarKeys, ref pawnListVarValues);
// Ensure dictionaries are not null after loading
if (Scribe.mode == LoadSaveMode.PostLoadInit)
{
intVars ??= new Dictionary<string, int>();
floatVars ??= new Dictionary<string, float>();
stringVars ??= new Dictionary<string, string>();
pawnVars ??= new Dictionary<string, Pawn>();
pawnListVars ??= new Dictionary<string, List<Pawn>>();
}
}
public void SetVariable(string name, object value)
{
if (string.IsNullOrEmpty(name)) return;
// Log the variable change
Log.Message($"[EventSystem] Setting variable '{name}' to value '{value}' of type {value?.GetType().Name ?? "null"}.");
// Clear any existing variable with the same name to prevent type confusion
ClearVariable(name);
if (value is int intValue)
{
intVars[name] = intValue;
}
else if (value is float floatValue)
{
floatVars[name] = floatValue;
}
else if (value is string stringValue)
{
stringVars[name] = stringValue;
}
else if (value is Pawn pawnValue)
{
pawnVars[name] = pawnValue;
}
else if (value is List<Pawn> pawnListValue)
{
pawnListVars[name] = pawnListValue;
}
else if (value != null)
{
stringVars[name] = value.ToString();
Log.Warning($"[WulaFallenEmpire] EventVariableManager: Variable '{name}' of type {value.GetType()} was converted to string for storage. This may lead to unexpected behavior.");
}
}
public T GetVariable<T>(string name, T defaultValue = default)
{
if (string.IsNullOrEmpty(name)) return defaultValue;
object value = null;
if (pawnListVars.TryGetValue(name, out var pawnListVal))
{
value = pawnListVal;
}
else if (pawnVars.TryGetValue(name, out var pawnVal))
{
value = pawnVal;
}
else if (floatVars.TryGetValue(name, out var floatVal))
{
value = floatVal;
}
else if (intVars.TryGetValue(name, out var intVal))
{
value = intVal;
}
else if (stringVars.TryGetValue(name, out var stringVal))
{
value = stringVal;
}
if (value != null)
{
if (value is T typedValue)
{
return typedValue;
}
try
{
// Handle cases where T is object but the stored value is, e.g., an int
if (typeof(T) == typeof(object))
{
return (T)value;
}
return (T)System.Convert.ChangeType(value, typeof(T));
}
catch (System.Exception e)
{
Log.Warning($"[WulaFallenEmpire] EventVariableManager: Variable '{name}' of type {value.GetType()} could not be converted to {typeof(T)}. Error: {e.Message}");
return defaultValue;
}
}
return defaultValue;
}
public bool HasVariable(string name)
{
return intVars.ContainsKey(name) ||
floatVars.ContainsKey(name) ||
stringVars.ContainsKey(name) ||
pawnVars.ContainsKey(name) ||
pawnListVars.ContainsKey(name);
}
public void ClearVariable(string name)
{
if (HasVariable(name))
{
Log.Message($"[EventSystem] Clearing variable '{name}'.");
}
intVars.Remove(name);
floatVars.Remove(name);
stringVars.Remove(name);
pawnVars.Remove(name);
pawnListVars.Remove(name);
}
public void ClearAll()
{
intVars.Clear();
floatVars.Clear();
stringVars.Clear();
pawnVars.Clear();
pawnListVars.Clear();
}
public Dictionary<string, object> GetAllVariables()
{
var allVars = new Dictionary<string, object>();
foreach (var kvp in intVars) allVars[kvp.Key] = kvp.Value;
foreach (var kvp in floatVars) allVars[kvp.Key] = kvp.Value;
foreach (var kvp in stringVars) allVars[kvp.Key] = kvp.Value;
foreach (var kvp in pawnVars) allVars[kvp.Key] = kvp.Value;
foreach (var kvp in pawnListVars) allVars[kvp.Key] = kvp.Value;
return allVars;
}
}
}