This commit is contained in:
2025-07-29 18:08:39 +08:00
parent 6c3ab94d6c
commit 6b5d9166e7
10 changed files with 238 additions and 34 deletions

Binary file not shown.

View File

@@ -0,0 +1,43 @@
<?xml version="1.0" encoding="utf-8" ?>
<Defs>
<ThingDef ParentName="BuildingBase">
<defName>Wula_EventConsole</defName>
<label>事件控制台</label>
<description>一个可以触发特殊事件的控制台。</description>
<thingClass>Building</thingClass>
<graphicData>
<texPath>Things/Building/Misc/CommsConsole</texPath>
<graphicClass>Graphic_Multi</graphicClass>
<drawSize>(3,3)</drawSize>
</graphicData>
<statBases>
<MaxHitPoints>250</MaxHitPoints>
<WorkToBuild>2000</WorkToBuild>
<Mass>70</Mass>
<Flammability>0.5</Flammability>
</statBases>
<size>(3,1)</size>
<costList>
<Steel>120</Steel>
<ComponentIndustrial>8</ComponentIndustrial>
</costList>
<altitudeLayer>Building</altitudeLayer>
<passability>PassThroughOnly</passability>
<pathCost>50</pathCost>
<designationCategory>Misc</designationCategory>
<comps>
<li Class="CompProperties_Power">
<compClass>CompPowerTrader</compClass>
<basePowerConsumption>100</basePowerConsumption>
</li>
<li Class="CompProperties_Flickable"/>
<li Class="WulaFallenEmpire.CompProperties_OpenCustomUI">
<uiDefName>Wula_ExampleUI</uiDefName>
<label>打开事件</label>
<failReason>无法接触事件控制台。</failReason>
</li>
</comps>
</ThingDef>
</Defs>

View File

@@ -18,6 +18,8 @@
<!-- Virtual Layout Offsets -->
<textNameOffset>0</textNameOffset>
<optionsTextOffset>0</optionsTextOffset>
<defaultWindowSize>(750, 500)</defaultWindowSize>
</WulaFallenEmpire.EventUIConfigDef>

View File

@@ -423,3 +423,37 @@
5. 在弹出的列表中,选择你想要测试的事件的 `defName`。
这会立即打开对应的事件窗口,让你可以在不满足游戏内触发条件的情况下快速预览和测试你的事件。
---
## 10. 组件:从建筑触发事件 (`CompOpenCustomUI`)
我们提供了一个通用的 `ThingComp`,可以附加到任何建筑上,通过右键菜单来打开一个指定的事件窗口。
**如何使用:**
1. 在你的建筑 `ThingDef` 的 `<comps>` 列表中,添加一个新的 `li`。
2. 将 `Class` 属性设置为 `WulaFallenEmpire.CompProperties_OpenCustomUI`。
3. 在 `li` 内部,设置以下字段:
- `uiDefName`: (必须) 要打开的 `CustomUIDef` 的 `defName`。
- `label`: (必须) 显示在右键菜单中的文本。
- `failReason`: (可选) 当殖民者无法到达建筑时显示的提示文本。如果未提供,则默认为 "无法到达"。
**示例 (`Buildings_EventSource.xml`):**
```xml
<ThingDef ParentName="BuildingBase">
<defName>Wula_EventConsole</defName>
<label>事件控制台</label>
...
<comps>
...
<!-- 添加这个组件来提供右键菜单选项 -->
<li Class="WulaFallenEmpire.CompProperties_OpenCustomUI">
<uiDefName>Wula_ExampleUI</uiDefName>
<label>打开事件</label>
<failReason>无法接触事件控制台。</failReason>
</li>
</comps>
</ThingDef>
```
这个组件会自动处理电力检查(如果建筑有 `CompPowerTrader`)和可达性检查。

View File

@@ -1,21 +1,21 @@
{
"Version": 1,
"WorkspaceRootPath": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\WulaFallenEmpireTest\\Source\\WulaFallenEmpire\\",
"WorkspaceRootPath": "C:\\Steam\\steamapps\\common\\RimWorld\\Mods\\3516260226\\Source\\WulaFallenEmpire\\",
"Documents": [
{
"AbsoluteMoniker": "D:0:0:{F5AE8C3B-0221-4C16-A128-9A62D521A8FF}|WulaFallenEmpire.csproj|e:\\steamlibrary\\steamapps\\common\\rimworld\\mods\\wulafallenempiretest\\source\\wulafallenempire\\eventsystem\\dialog_customdisplay.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"AbsoluteMoniker": "D:0:0:{F5AE8C3B-0221-4C16-A128-9A62D521A8FF}|WulaFallenEmpire.csproj|c:\\steam\\steamapps\\common\\rimworld\\mods\\3516260226\\source\\wulafallenempire\\eventsystem\\dialog_customdisplay.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{F5AE8C3B-0221-4C16-A128-9A62D521A8FF}|WulaFallenEmpire.csproj|solutionrelative:eventsystem\\dialog_customdisplay.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
},
{
"AbsoluteMoniker": "D:0:0:{F5AE8C3B-0221-4C16-A128-9A62D521A8FF}|WulaFallenEmpire.csproj|e:\\steamlibrary\\steamapps\\common\\rimworld\\mods\\wulafallenempiretest\\source\\wulafallenempire\\eventsystem\\debugactions.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"AbsoluteMoniker": "D:0:0:{F5AE8C3B-0221-4C16-A128-9A62D521A8FF}|WulaFallenEmpire.csproj|C:\\Steam\\steamapps\\common\\RimWorld\\Mods\\3516260226\\Source\\WulaFallenEmpire\\eventsystem\\debugactions.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{F5AE8C3B-0221-4C16-A128-9A62D521A8FF}|WulaFallenEmpire.csproj|solutionrelative:eventsystem\\debugactions.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
},
{
"AbsoluteMoniker": "D:0:0:{F5AE8C3B-0221-4C16-A128-9A62D521A8FF}|WulaFallenEmpire.csproj|e:\\steamlibrary\\steamapps\\common\\rimworld\\mods\\wulafallenempiretest\\source\\wulafallenempire\\eventsystem\\customuidef.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"AbsoluteMoniker": "D:0:0:{F5AE8C3B-0221-4C16-A128-9A62D521A8FF}|WulaFallenEmpire.csproj|C:\\Steam\\steamapps\\common\\RimWorld\\Mods\\3516260226\\Source\\WulaFallenEmpire\\eventsystem\\customuidef.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{F5AE8C3B-0221-4C16-A128-9A62D521A8FF}|WulaFallenEmpire.csproj|solutionrelative:eventsystem\\customuidef.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
},
{
"AbsoluteMoniker": "D:0:0:{F5AE8C3B-0221-4C16-A128-9A62D521A8FF}|WulaFallenEmpire.csproj|e:\\steamlibrary\\steamapps\\common\\rimworld\\mods\\wulafallenempiretest\\source\\wulafallenempire\\eventsystem\\condition.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"AbsoluteMoniker": "D:0:0:{F5AE8C3B-0221-4C16-A128-9A62D521A8FF}|WulaFallenEmpire.csproj|C:\\Steam\\steamapps\\common\\RimWorld\\Mods\\3516260226\\Source\\WulaFallenEmpire\\eventsystem\\condition.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{F5AE8C3B-0221-4C16-A128-9A62D521A8FF}|WulaFallenEmpire.csproj|solutionrelative:eventsystem\\condition.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
}
],
@@ -26,17 +26,21 @@
"DocumentGroups": [
{
"DockedWidth": 200,
"SelectedChildIndex": 0,
"SelectedChildIndex": 1,
"Children": [
{
"$type": "Bookmark",
"Name": "ST:0:0:{1c4feeaa-4718-4aa9-859d-94ce25d182ba}"
},
{
"$type": "Document",
"DocumentIndex": 0,
"Title": "Dialog_CustomDisplay.cs",
"DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\WulaFallenEmpireTest\\Source\\WulaFallenEmpire\\EventSystem\\Dialog_CustomDisplay.cs",
"DocumentMoniker": "C:\\Steam\\steamapps\\common\\RimWorld\\Mods\\3516260226\\Source\\WulaFallenEmpire\\EventSystem\\Dialog_CustomDisplay.cs",
"RelativeDocumentMoniker": "EventSystem\\Dialog_CustomDisplay.cs",
"ToolTip": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\WulaFallenEmpireTest\\Source\\WulaFallenEmpire\\EventSystem\\Dialog_CustomDisplay.cs",
"ToolTip": "C:\\Steam\\steamapps\\common\\RimWorld\\Mods\\3516260226\\Source\\WulaFallenEmpire\\EventSystem\\Dialog_CustomDisplay.cs",
"RelativeToolTip": "EventSystem\\Dialog_CustomDisplay.cs",
"ViewState": "AgIAAAAAAAAAAAAAAAAAABAAAAAPAAAAAAAAAA==",
"ViewState": "AQIAAAAAAAAAAAAAAADwvwAAAAAAAAAA",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2025-07-27T10:59:13.84Z",
"EditorCaption": ""
@@ -45,44 +49,37 @@
"$type": "Document",
"DocumentIndex": 1,
"Title": "DebugActions.cs",
"DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\WulaFallenEmpireTest\\Source\\WulaFallenEmpire\\EventSystem\\DebugActions.cs",
"DocumentMoniker": "C:\\Steam\\steamapps\\common\\RimWorld\\Mods\\3516260226\\Source\\WulaFallenEmpire\\EventSystem\\DebugActions.cs",
"RelativeDocumentMoniker": "EventSystem\\DebugActions.cs",
"ToolTip": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\WulaFallenEmpireTest\\Source\\WulaFallenEmpire\\EventSystem\\DebugActions.cs",
"ToolTip": "C:\\Steam\\steamapps\\common\\RimWorld\\Mods\\3516260226\\Source\\WulaFallenEmpire\\EventSystem\\DebugActions.cs",
"RelativeToolTip": "EventSystem\\DebugActions.cs",
"ViewState": "AgIAAAAAAAAAAAAAAADwvwAAAAAAAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2025-07-27T10:59:11.817Z",
"EditorCaption": ""
"WhenOpened": "2025-07-27T10:59:11.817Z"
},
{
"$type": "Document",
"DocumentIndex": 2,
"Title": "CustomUIDef.cs",
"DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\WulaFallenEmpireTest\\Source\\WulaFallenEmpire\\EventSystem\\CustomUIDef.cs",
"DocumentMoniker": "C:\\Steam\\steamapps\\common\\RimWorld\\Mods\\3516260226\\Source\\WulaFallenEmpire\\EventSystem\\CustomUIDef.cs",
"RelativeDocumentMoniker": "EventSystem\\CustomUIDef.cs",
"ToolTip": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\WulaFallenEmpireTest\\Source\\WulaFallenEmpire\\EventSystem\\CustomUIDef.cs",
"ToolTip": "C:\\Steam\\steamapps\\common\\RimWorld\\Mods\\3516260226\\Source\\WulaFallenEmpire\\EventSystem\\CustomUIDef.cs",
"RelativeToolTip": "EventSystem\\CustomUIDef.cs",
"ViewState": "AgIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2025-07-27T10:59:01.929Z",
"EditorCaption": ""
"WhenOpened": "2025-07-27T10:59:01.929Z"
},
{
"$type": "Document",
"DocumentIndex": 3,
"Title": "Condition.cs",
"DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\WulaFallenEmpireTest\\Source\\WulaFallenEmpire\\EventSystem\\Condition.cs",
"DocumentMoniker": "C:\\Steam\\steamapps\\common\\RimWorld\\Mods\\3516260226\\Source\\WulaFallenEmpire\\EventSystem\\Condition.cs",
"RelativeDocumentMoniker": "EventSystem\\Condition.cs",
"ToolTip": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\WulaFallenEmpireTest\\Source\\WulaFallenEmpire\\EventSystem\\Condition.cs",
"ToolTip": "C:\\Steam\\steamapps\\common\\RimWorld\\Mods\\3516260226\\Source\\WulaFallenEmpire\\EventSystem\\Condition.cs",
"RelativeToolTip": "EventSystem\\Condition.cs",
"ViewState": "AgIAAAAAAAAAAAAAAAAAAAkAAAAAAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2025-07-27T10:50:26.799Z",
"EditorCaption": ""
},
{
"$type": "Bookmark",
"Name": "ST:0:0:{1c4feeaa-4718-4aa9-859d-94ce25d182ba}"
"WhenOpened": "2025-07-27T10:50:26.799Z"
}
]
}

View File

@@ -0,0 +1,60 @@
using RimWorld;
using Verse;
using System.Collections.Generic;
using Verse.AI;
namespace WulaFallenEmpire
{
public class CompProperties_OpenCustomUI : CompProperties
{
public string uiDefName;
public string label; // The text to display in the float menu
public string failReason; // Optional: Custom text to show if the pawn can't reach the building
public CompProperties_OpenCustomUI()
{
this.compClass = typeof(CompOpenCustomUI);
}
}
public class CompOpenCustomUI : ThingComp
{
public CompProperties_OpenCustomUI Props => (CompProperties_OpenCustomUI)this.props;
public override IEnumerable<FloatMenuOption> CompFloatMenuOptions(Pawn selPawn)
{
// Check if the pawn can interact with the building
if (!selPawn.CanReserveAndReach(this.parent, PathEndMode.InteractionCell, Danger.Deadly))
{
string reason = Props.failReason ?? "CannotUseNoPath".Translate();
yield return new FloatMenuOption(reason, null);
yield break;
}
// Check for power if the building has a power component
CompPowerTrader powerComp = this.parent.GetComp<CompPowerTrader>();
if (powerComp != null && !powerComp.PowerOn)
{
yield return new FloatMenuOption("CannotUseNoPower".Translate(), null);
yield break;
}
string label = Props.label ?? "Open Custom UI"; // Use default label if not provided
FloatMenuOption option = new FloatMenuOption(label, delegate()
{
CustomUIDef uiDef = DefDatabase<CustomUIDef>.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}'.");
}
});
yield return option;
}
}
}

View File

@@ -1,17 +1,51 @@
using System.Collections.Generic;
using UnityEngine;
using Verse;
namespace WulaFallenEmpire
{
public enum DescriptionSelectionMode
{
Random,
Sequential
}
public class CustomUIDef : Def
{
public string portraitPath;
public string characterName;
public new string description;
// New system: list of descriptions
public List<string> descriptions;
public DescriptionSelectionMode descriptionMode = DescriptionSelectionMode.Random;
// Backwards compatibility: old single description field
[System.Obsolete("Use 'descriptions' list instead. This field is for backwards compatibility only.")]
public new string description = null;
public Vector2 windowSize = Vector2.zero;
public List<CustomUIOption> options;
public string backgroundImagePath; // Override default background
public string backgroundImagePath;
public List<Effect> onOpenEffects;
public List<Effect> dismissEffects;
public override void PostLoad()
{
base.PostLoad();
#pragma warning disable 0618
// If the old description field is used, move its value to the new list for processing.
if (!description.NullOrEmpty())
{
if (descriptions.NullOrEmpty())
{
descriptions = new List<string>();
}
descriptions.Insert(0, description);
description = null; // Clear the old field to prevent confusion
}
#pragma warning restore 0618
}
}
public class CustomUIOption
@@ -19,6 +53,6 @@ namespace WulaFallenEmpire
public string label;
public List<Effect> effects;
public List<Condition> conditions;
public string disabledReason; // Custom text to show if conditions aren't met
public string disabledReason;
}
}

View File

@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using Verse;
@@ -10,6 +11,7 @@ namespace WulaFallenEmpire
private CustomUIDef def;
private Texture2D portrait;
private Texture2D background;
private string selectedDescription; // Store the chosen description for this window instance
private static EventUIConfigDef config;
public static EventUIConfigDef Config
@@ -24,14 +26,47 @@ namespace WulaFallenEmpire
}
}
public override Vector2 InitialSize => new Vector2(750f, 500f);
public override Vector2 InitialSize
{
get
{
if (def.windowSize != Vector2.zero)
{
return def.windowSize;
}
return Config.defaultWindowSize; // Fallback to size from config
}
}
public Dialog_CustomDisplay(CustomUIDef def)
{
this.def = def;
this.forcePause = true;
this.absorbInputAroundWindow = true;
this.doCloseX = true; // Add a close button to the window
this.doCloseX = true;
// Select the description text
if (!def.descriptions.NullOrEmpty())
{
if (def.descriptionMode == DescriptionSelectionMode.Random)
{
selectedDescription = def.descriptions.RandomElement();
}
else // Sequential
{
string indexVarName = $"_seq_desc_index_{def.defName}";
int currentIndex = EventContext.GetVariable<int>(indexVarName, 0);
selectedDescription = def.descriptions[currentIndex];
int nextIndex = (currentIndex + 1) % def.descriptions.Count;
EventContext.SetVariable(indexVarName, nextIndex);
}
}
else
{
selectedDescription = "Error: No descriptions found in def.";
}
}
public override void PreOpen()
@@ -127,12 +162,11 @@ namespace WulaFallenEmpire
GUI.color = Color.white;
}
Rect textInnerRect = textRect.ContractedBy(10f * scale);
Widgets.Label(textInnerRect, def.description);
Widgets.Label(textInnerRect, selectedDescription); // Use the selected description
// option (Buttons)
Rect optionRect = new Rect(nameRect.x, textRect.yMax + Config.optionsTextOffset * scale, scaledOptionsWidth, lihuiRect.height - nameRect.height - textRect.height - (Config.textNameOffset + Config.optionsTextOffset) * scale);
// No need to draw a box for the options area, the buttons will be listed inside.
Listing_Standard listing = new Listing_Standard();
listing.Begin(optionRect.ContractedBy(10f * scale));
if (def.options != null)
@@ -151,7 +185,6 @@ namespace WulaFallenEmpire
}
else
{
// Draw a disabled button and add a tooltip
Rect rect = listing.GetRect(30f);
Widgets.ButtonText(rect, option.label, false, true, false);
TooltipHandler.TipRegion(rect, GetDisabledReason(option, reason));

View File

@@ -9,6 +9,7 @@ namespace WulaFallenEmpire
public GameFont labelFont = GameFont.Small;
public bool drawBorders = true;
public string defaultBackgroundImagePath;
public Vector2 defaultWindowSize = new Vector2(750f, 500f);
// Virtual Layout Dimensions
public Vector2 lihuiSize = new Vector2(500f, 800f);