This commit is contained in:
2025-07-31 15:06:36 +08:00
parent be745d9a9f
commit f46e589727
20 changed files with 808 additions and 466 deletions

View File

@@ -40,7 +40,7 @@
"RelativeDocumentMoniker": "EventSystem\\Dialog_CustomDisplay.cs",
"ToolTip": "C:\\Steam\\steamapps\\common\\RimWorld\\Mods\\3516260226\\Source\\WulaFallenEmpire\\EventSystem\\Dialog_CustomDisplay.cs",
"RelativeToolTip": "EventSystem\\Dialog_CustomDisplay.cs",
"ViewState": "AQIAAAAAAAAAAAAAAADwvwAAAAAAAAAA",
"ViewState": "AQIAAOUAAAAAAAAAAAAiwAAAAAAAAAAA",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2025-07-27T10:59:13.84Z",
"EditorCaption": ""

View File

@@ -43,14 +43,14 @@ namespace WulaFallenEmpire
FloatMenuOption option = new FloatMenuOption(label, delegate()
{
CustomUIDef uiDef = DefDatabase<CustomUIDef>.GetNamed(Props.uiDefName, false);
EventDef uiDef = DefDatabase<EventDef>.GetNamed(Props.uiDefName, false);
if (uiDef != null)
{
Find.WindowStack.Add(new Dialog_CustomDisplay(uiDef));
}
else
{
Log.Error($"[CompOpenCustomUI] Could not find CustomUIDef named '{Props.uiDefName}'.");
Log.Error($"[CompOpenCustomUI] Could not find EventDef named '{Props.uiDefName}'.");
}
});

View File

@@ -11,10 +11,10 @@ namespace WulaFallenEmpire
private static void OpenCustomUI()
{
List<DebugMenuOption> list = new List<DebugMenuOption>();
foreach (CustomUIDef localDef in DefDatabase<CustomUIDef>.AllDefs)
foreach (EventDef localDef in DefDatabase<EventDef>.AllDefs)
{
// Capture the local variable for the lambda
CustomUIDef currentDef = localDef;
EventDef currentDef = localDef;
list.Add(new DebugMenuOption(currentDef.defName, DebugMenuOptionMode.Action, delegate
{
Find.WindowStack.Add(new Dialog_CustomDisplay(currentDef));

View File

@@ -8,7 +8,7 @@ namespace WulaFallenEmpire
{
public class Dialog_CustomDisplay : Window
{
private CustomUIDef def;
private EventDef def;
private Texture2D portrait;
private Texture2D background;
private string selectedDescription; // Store the chosen description for this window instance
@@ -38,7 +38,7 @@ namespace WulaFallenEmpire
}
}
public Dialog_CustomDisplay(CustomUIDef def)
public Dialog_CustomDisplay(EventDef def)
{
this.def = def;
this.forcePause = true;
@@ -226,7 +226,7 @@ namespace WulaFallenEmpire
return true;
}
private string GetDisabledReason(CustomUIOption option, string reason)
private string GetDisabledReason(EventOption option, string reason)
{
if (!option.disabledReason.NullOrEmpty())
{

View File

@@ -1,5 +1,6 @@
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using Verse;
using RimWorld;
@@ -7,32 +8,34 @@ namespace WulaFallenEmpire
{
public abstract class Effect
{
public abstract void Execute(Dialog_CustomDisplay dialog);
// Allow the dialog to be null for contexts where there isn't one (like quests)
public abstract void Execute(Dialog_CustomDisplay dialog = null);
}
public class Effect_OpenCustomUI : Effect
{
public string defName;
public override void Execute(Dialog_CustomDisplay dialog)
public override void Execute(Dialog_CustomDisplay dialog = null)
{
CustomUIDef nextDef = DefDatabase<CustomUIDef>.GetNamed(defName);
EventDef nextDef = DefDatabase<EventDef>.GetNamed(defName);
if (nextDef != null)
{
Find.WindowStack.Add(new Dialog_CustomDisplay(nextDef));
}
else
{
Log.Error($"[WulaFallenEmpire] Effect_OpenCustomUI could not find CustomUIDef named '{defName}'");
Log.Error($"[WulaFallenEmpire] Effect_OpenCustomUI could not find EventDef named '{defName}'");
}
}
}
public class Effect_CloseDialog : Effect
{
public override void Execute(Dialog_CustomDisplay dialog)
public override void Execute(Dialog_CustomDisplay dialog = null)
{
dialog.Close();
// Only close the dialog if it exists
dialog?.Close();
}
}
@@ -41,7 +44,7 @@ namespace WulaFallenEmpire
public string message;
public MessageTypeDef messageTypeDef;
public override void Execute(Dialog_CustomDisplay dialog)
public override void Execute(Dialog_CustomDisplay dialog = null)
{
if (messageTypeDef == null)
{
@@ -55,7 +58,7 @@ namespace WulaFallenEmpire
{
public IncidentDef incident;
public override void Execute(Dialog_CustomDisplay dialog)
public override void Execute(Dialog_CustomDisplay dialog = null)
{
if (incident == null)
{
@@ -81,7 +84,7 @@ namespace WulaFallenEmpire
public FactionDef faction;
public int goodwillChange;
public override void Execute(Dialog_CustomDisplay dialog)
public override void Execute(Dialog_CustomDisplay dialog = null)
{
if (faction == null)
{
@@ -105,7 +108,7 @@ namespace WulaFallenEmpire
public string name;
public string value;
public override void Execute(Dialog_CustomDisplay dialog)
public override void Execute(Dialog_CustomDisplay dialog = null)
{
// Try to parse as int, then float, otherwise keep as string
if (int.TryParse(value, out int intValue))
@@ -128,7 +131,7 @@ namespace WulaFallenEmpire
public FactionDef faction;
public string goodwillVariableName;
public override void Execute(Dialog_CustomDisplay dialog)
public override void Execute(Dialog_CustomDisplay dialog = null)
{
if (faction == null)
{
@@ -154,7 +157,7 @@ namespace WulaFallenEmpire
public int count = 1;
public string storeAs;
public override void Execute(Dialog_CustomDisplay dialog)
public override void Execute(Dialog_CustomDisplay dialog = null)
{
if (kindDef == null)
{
@@ -192,7 +195,7 @@ namespace WulaFallenEmpire
public ThingDef thingDef;
public int count = 1;
public override void Execute(Dialog_CustomDisplay dialog)
public override void Execute(Dialog_CustomDisplay dialog = null)
{
if (thingDef == null)
{
@@ -226,7 +229,7 @@ namespace WulaFallenEmpire
public string letterText;
public LetterDef letterDef;
public override void Execute(Dialog_CustomDisplay dialog)
public override void Execute(Dialog_CustomDisplay dialog = null)
{
if (kindDef == null)
{
@@ -282,7 +285,7 @@ namespace WulaFallenEmpire
public float value;
public VariableOperation operation;
public override void Execute(Dialog_CustomDisplay dialog)
public override void Execute(Dialog_CustomDisplay dialog = null)
{
if (string.IsNullOrEmpty(name))
{
@@ -323,7 +326,7 @@ namespace WulaFallenEmpire
{
public string name;
public override void Execute(Dialog_CustomDisplay dialog)
public override void Execute(Dialog_CustomDisplay dialog = null)
{
if (string.IsNullOrEmpty(name))
{
@@ -338,7 +341,7 @@ namespace WulaFallenEmpire
{
public QuestScriptDef quest;
public override void Execute(Dialog_CustomDisplay dialog)
public override void Execute(Dialog_CustomDisplay dialog = null)
{
if (quest == null)
{
@@ -357,7 +360,7 @@ namespace WulaFallenEmpire
{
public ResearchProjectDef research;
public override void Execute(Dialog_CustomDisplay dialog)
public override void Execute(Dialog_CustomDisplay dialog = null)
{
if (research == null)
{
@@ -369,4 +372,94 @@ namespace WulaFallenEmpire
}
}
}
public class Effect_TriggerRaid : Effect
{
public float points;
public FactionDef faction;
public RaidStrategyDef raidStrategy;
public PawnsArrivalModeDef raidArrivalMode;
public PawnGroupKindDef groupKind;
public List<PawnGroupMaker> pawnGroupMakers;
public override void Execute(Dialog_CustomDisplay dialog = null)
{
Map map = Find.CurrentMap;
if (map == null)
{
Log.Error("[WulaFallenEmpire] Effect_TriggerRaid cannot execute without a current map.");
return;
}
Faction factionInst = Find.FactionManager.FirstFactionOfDef(this.faction);
if (factionInst == null)
{
Log.Error($"[WulaFallenEmpire] Effect_TriggerRaid could not find an active faction for FactionDef '{this.faction?.defName}'.");
return;
}
// If custom pawn groups are defined, use them.
if (!pawnGroupMakers.NullOrEmpty())
{
IncidentParms parms = new IncidentParms
{
target = map,
points = this.points,
faction = factionInst,
raidStrategy = this.raidStrategy,
raidArrivalMode = this.raidArrivalMode,
pawnGroupMakerSeed = Rand.Int,
forced = true
};
PawnGroupMakerParms groupMakerParms = new PawnGroupMakerParms
{
groupKind = this.groupKind ?? PawnGroupKindDefOf.Combat,
tile = map.Tile,
points = this.points,
faction = factionInst,
seed = parms.pawnGroupMakerSeed
};
if (!pawnGroupMakers.TryRandomElement(out var chosenGroupMaker))
{
Log.Error($"[WulaFallenEmpire] Effect_TriggerRaid could not find a suitable PawnGroupMaker for {points} points with groupKind {groupMakerParms.groupKind.defName} from the provided list.");
return;
}
List<Pawn> pawns = chosenGroupMaker.GeneratePawns(groupMakerParms).ToList();
if (!pawns.Any())
{
Log.Error("[WulaFallenEmpire] Effect_TriggerRaid generated no pawns with the custom pawnGroupMakers.");
return;
}
parms.raidArrivalMode.Worker.Arrive(pawns, parms);
TaggedString letterLabel = "LetterLabelRaid".Translate(factionInst.def.label).CapitalizeFirst();
TaggedString letterText = "LetterRaid".Translate(
factionInst.Name,
factionInst.def.pawnsPlural,
parms.raidStrategy.arrivalTextEnemy
).CapitalizeFirst();
Pawn mostImportantPawn = pawns.FirstOrDefault();
TargetInfo target = mostImportantPawn != null ? new TargetInfo(mostImportantPawn) : new TargetInfo(parms.spawnCenter, map);
Find.LetterStack.ReceiveLetter(letterLabel, letterText, LetterDefOf.ThreatBig, target, factionInst);
}
else // Fallback to default raid incident worker
{
IncidentParms parms = new IncidentParms
{
target = map,
points = this.points,
faction = factionInst,
raidStrategy = this.raidStrategy,
raidArrivalMode = this.raidArrivalMode,
forced = true
};
IncidentDefOf.RaidEnemy.Worker.TryExecute(parms);
}
}
}
}

View File

@@ -10,7 +10,7 @@ namespace WulaFallenEmpire
Sequential
}
public class CustomUIDef : Def
public class EventDef : Def
{
public string portraitPath;
public string characterName;
@@ -25,7 +25,7 @@ namespace WulaFallenEmpire
public Vector2 windowSize = Vector2.zero;
public List<CustomUIOption> options;
public List<EventOption> options;
public string backgroundImagePath;
public List<Effect> onOpenEffects;
public List<Effect> dismissEffects;
@@ -48,7 +48,7 @@ namespace WulaFallenEmpire
}
}
public class CustomUIOption
public class EventOption
{
public string label;
public List<Effect> effects;

View File

@@ -0,0 +1,68 @@
using RimWorld;
using RimWorld.QuestGen;
using System;
using System.Collections.Generic;
using Verse;
namespace WulaFallenEmpire
{
public class Letter_EventChoice : ChoiceLetter
{
// These fields are now inherited from the base Letter class
// public string letterLabel;
// public string letterTitle;
// public string letterText;
public List<QuestNode_Root_EventLetter.Option> options;
public new Quest quest;
public override IEnumerable<DiaOption> Choices
{
get
{
if (options.NullOrEmpty())
{
yield break;
}
foreach (var optionDef in options)
{
var currentOption = optionDef;
Action choiceAction = delegate
{
if (!currentOption.effects.NullOrEmpty())
{
foreach (var effect in currentOption.effects)
{
effect.Execute(null);
}
}
if (quest != null && !quest.hidden && !quest.Historical)
{
quest.End(QuestEndOutcome.Success);
}
Find.LetterStack.RemoveLetter(this);
};
var diaOption = new DiaOption(currentOption.label)
{
action = choiceAction,
resolveTree = true
};
yield return diaOption;
}
}
}
public override bool CanDismissWithRightClick => false;
public override void ExposeData()
{
base.ExposeData();
// Scribe_Values.Look(ref letterLabel, "letterLabel"); // Now uses base.label
// Scribe_Values.Look(ref letterTitle, "letterTitle"); // Now uses base.title
// Scribe_Values.Look(ref letterText, "letterText"); // Now uses base.text
Scribe_Collections.Look(ref options, "options", LookMode.Deep);
Scribe_References.Look(ref quest, "quest");
}
}
}

View File

@@ -0,0 +1,49 @@
using RimWorld;
using RimWorld.QuestGen;
using System;
using System.Collections.Generic;
using Verse;
namespace WulaFallenEmpire
{
public class QuestNode_Root_EventLetter : QuestNode
{
// Fields to be set from the QuestScriptDef XML
public SlateRef<string> letterLabel;
public SlateRef<string> letterTitle;
public SlateRef<string> letterText;
public List<Option> options = new List<Option>();
// This is a root node, so it doesn't have a parent signal.
// It runs immediately when the quest starts.
protected override void RunInt()
{
// Get the current slate
Slate slate = QuestGen.slate;
var letter = (Letter_EventChoice)LetterMaker.MakeLetter(DefDatabase<LetterDef>.GetNamed("Wula_EventChoiceLetter"));
letter.Label = letterLabel.GetValue(slate);
letter.title = letterTitle.GetValue(slate);
letter.Text = letterText.GetValue(slate);
letter.options = options;
letter.quest = QuestGen.quest;
letter.lookTargets = slate.Get<LookTargets>("lookTargets");
Find.LetterStack.ReceiveLetter(letter);
}
protected override bool TestRunInt(Slate slate)
{
// This node can always run as long as the slate refs are valid.
// We can add more complex checks here if needed.
return true;
}
// Inner class to hold option data from XML
public class Option
{
public string label;
public List<Effect> effects;
}
}
}

View File

@@ -104,12 +104,14 @@
<Compile Include="MentalBreakWorker_BrokenPersonality.cs" />
<Compile Include="EventSystem\DebugActions.cs" />
<Compile Include="EventSystem\Condition.cs" />
<Compile Include="EventSystem\CustomUIDef.cs" />
<Compile Include="EventSystem\EventDef.cs" />
<Compile Include="EventSystem\Dialog_CustomDisplay.cs" />
<Compile Include="EventSystem\Effect.cs" />
<Compile Include="EventSystem\EventContext.cs" />
<Compile Include="EventSystem\EventUIConfigDef.cs" />
<Compile Include="EventSystem\CompOpenCustomUI.cs" />
<Compile Include="EventSystem\QuestNode_Root_EventLetter.cs" />
<Compile Include="EventSystem\Letter_EventChoice.cs" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- 自定义清理任务删除obj文件夹中的临时文件 -->