diff --git a/1.6/1.6/Assemblies/WulaFallenEmpire.dll b/1.6/1.6/Assemblies/WulaFallenEmpire.dll index bb793e00..836d4a12 100644 Binary files a/1.6/1.6/Assemblies/WulaFallenEmpire.dll and b/1.6/1.6/Assemblies/WulaFallenEmpire.dll differ diff --git a/1.6/1.6/Defs/EventDefs/EventDef_Examples.xml b/1.6/1.6/Defs/EventDefs/EventDef_Examples.xml index 6534a0ad..ba3128f1 100644 --- a/1.6/1.6/Defs/EventDefs/EventDef_Examples.xml +++ b/1.6/1.6/Defs/EventDefs/EventDef_Examples.xml @@ -1,6 +1,57 @@ + + Wula_UI_Anisia_1_NewWindow + + Wula/Events/Portraits/WULA_Anisia_1 + URa-1138「艾妮西娅」 + WulaFallenEmpire.Dialog_NewLayoutDisplay + +
  • 很高兴看到你们的殖民地没有变成荒野中的烂泥。那么,今天找我有什么事情?
  • +
  • 宇宙生存法则第一条:不要惹平胸火气大的女人。
  • +
  • 什么样的结局,才配得上这一路的颠沛流离?无论你们走向何方,我都将见证你们。
  • +
    + +
  • + + +
  • + +
  • + Wula_UI_Anisia_10 +
  • +
  • + +
  • + + +
  • + + +
  • + +
  • + Wula_UI_Anisia_200 +
  • +
  • + +
  • + + +
  • + + +
  • + +
  • + +
  • + + +
    +
    + Wula_Test_Raid_Event diff --git a/1.6/1.6/Defs/WulaMiscSettingDefs/EventUIConfig.xml b/1.6/1.6/Defs/WulaMiscSettingDefs/EventUIConfig.xml index 275c587b..de3811f9 100644 --- a/1.6/1.6/Defs/WulaMiscSettingDefs/EventUIConfig.xml +++ b/1.6/1.6/Defs/WulaMiscSettingDefs/EventUIConfig.xml @@ -22,6 +22,15 @@ 0 (750, 600) + + + (200, 50) + (600, 200) + (600, 200) + 600 + 20 + 20 + 20 diff --git a/Source/Documentation/new_layout_preview.html b/Source/Documentation/new_layout_preview.html new file mode 100644 index 00000000..fb434fe5 --- /dev/null +++ b/Source/Documentation/new_layout_preview.html @@ -0,0 +1,178 @@ + + + + + + 事件UI布局预览 (动态版) + + + +
    +

    动态布局预览

    +

    请将您的 EventUIConfig.xml 文件内容完整粘贴到下面的文本框中,然后点击“生成预览”按钮。

    + + +
    +
    + +
    + + + + diff --git a/Source/WulaFallenEmpire/WULA_EventSystem/CompOpenCustomUI.cs b/Source/WulaFallenEmpire/WULA_EventSystem/CompOpenCustomUI.cs index 4aa7d8ec..2281ab41 100644 --- a/Source/WulaFallenEmpire/WULA_EventSystem/CompOpenCustomUI.cs +++ b/Source/WulaFallenEmpire/WULA_EventSystem/CompOpenCustomUI.cs @@ -1,3 +1,4 @@ +using System; // Required for Activator using RimWorld; using Verse; using System.Collections.Generic; @@ -46,7 +47,7 @@ namespace WulaFallenEmpire EventDef uiDef = DefDatabase.GetNamed(Props.uiDefName, false); if (uiDef != null) { - Find.WindowStack.Add(new Dialog_CustomDisplay(uiDef)); + Find.WindowStack.Add((Window)Activator.CreateInstance(uiDef.windowType, uiDef)); } else { diff --git a/Source/WulaFallenEmpire/WULA_EventSystem/DebugActions.cs b/Source/WulaFallenEmpire/WULA_EventSystem/DebugActions.cs index 34de6b23..fb172382 100644 --- a/Source/WulaFallenEmpire/WULA_EventSystem/DebugActions.cs +++ b/Source/WulaFallenEmpire/WULA_EventSystem/DebugActions.cs @@ -1,3 +1,4 @@ +using System; // Required for Activator using System.Collections.Generic; using LudeonTK; using Verse; @@ -45,7 +46,7 @@ namespace WulaFallenEmpire } else { - Find.WindowStack.Add(new Dialog_CustomDisplay(currentDef)); + Find.WindowStack.Add((Window)Activator.CreateInstance(currentDef.windowType, currentDef)); } })); } diff --git a/Source/WulaFallenEmpire/WULA_EventSystem/DelayedActionManager.cs b/Source/WulaFallenEmpire/WULA_EventSystem/DelayedActionManager.cs index cb13070f..1a91e009 100644 --- a/Source/WulaFallenEmpire/WULA_EventSystem/DelayedActionManager.cs +++ b/Source/WulaFallenEmpire/WULA_EventSystem/DelayedActionManager.cs @@ -74,7 +74,7 @@ namespace WulaFallenEmpire { // This logic is simplified from Effect_OpenCustomUI.OpenUI // It assumes delayed actions always open a new dialog. - Find.WindowStack.Add(new Dialog_CustomDisplay(nextDef)); + Find.WindowStack.Add((Window)Activator.CreateInstance(nextDef.windowType, nextDef)); } else { diff --git a/Source/WulaFallenEmpire/WULA_EventSystem/Dialog_NewLayoutDisplay.cs b/Source/WulaFallenEmpire/WULA_EventSystem/Dialog_NewLayoutDisplay.cs new file mode 100644 index 00000000..3816ecf8 --- /dev/null +++ b/Source/WulaFallenEmpire/WULA_EventSystem/Dialog_NewLayoutDisplay.cs @@ -0,0 +1,277 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text.RegularExpressions; +using UnityEngine; +using Verse; + +namespace WulaFallenEmpire +{ + public class Dialog_NewLayoutDisplay : Window + { + private EventDef def; + private Texture2D portrait; + private Texture2D background; + private string selectedDescription; + + private static EventUIConfigDef config; + public static EventUIConfigDef Config + { + get + { + if (config == null) + { + config = DefDatabase.GetNamed("Wula_EventUIConfig"); + } + return config; + } + } + + public override Vector2 InitialSize + { + get + { + if (def.windowSize != Vector2.zero) + { + return def.windowSize; + } + return Config.defaultWindowSize; + } + } + + public Dialog_NewLayoutDisplay(EventDef def) + { + this.def = def; + this.forcePause = true; + this.absorbInputAroundWindow = true; + this.doCloseX = true; + + var eventVarManager = Find.World.GetComponent(); + if (!def.descriptions.NullOrEmpty()) + { + if (def.descriptionMode == DescriptionSelectionMode.Random) + { + selectedDescription = def.descriptions.RandomElement(); + } + else + { + string indexVarName = $"_seq_desc_index_{def.defName}"; + int currentIndex = eventVarManager.GetVariable(indexVarName, 0); + + selectedDescription = def.descriptions[currentIndex]; + + int nextIndex = (currentIndex + 1) % def.descriptions.Count; + eventVarManager.SetVariable(indexVarName, nextIndex); + } + } + else + { + selectedDescription = "Error: No descriptions found in def."; + } + } + + public override void PreOpen() + { + base.PreOpen(); + if (!def.portraitPath.NullOrEmpty()) + { + portrait = ContentFinder.Get(def.portraitPath); + } + + string bgPath = !def.backgroundImagePath.NullOrEmpty() ? def.backgroundImagePath : Config.defaultBackgroundImagePath; + if (!bgPath.NullOrEmpty()) + { + background = ContentFinder.Get(bgPath); + } + + HandleAction(def.immediateEffects); + + if (!def.conditionalDescriptions.NullOrEmpty()) + { + foreach (var condDesc in def.conditionalDescriptions) + { + string reason; + if (AreConditionsMet(condDesc.conditions, out reason)) + { + selectedDescription += "\n\n" + condDesc.text; + } + } + } + + selectedDescription = FormatDescription(selectedDescription); + } + + public override void DoWindowContents(Rect inRect) + { + if (background != null) + { + GUI.DrawTexture(inRect, background, ScaleMode.ScaleToFit); + } + + if (Config.showDefName) + { + Text.Font = GameFont.Tiny; + GUI.color = Color.gray; + Widgets.Label(new Rect(5, 5, inRect.width - 10, 20f), def.defName); + GUI.color = Color.white; + } + + if (Config.showLabel) + { + Text.Font = Config.labelFont; + Widgets.Label(new Rect(5, 20f, inRect.width - 10, 30f), def.label); + Text.Font = GameFont.Small; + } + + // 假设一个统一的边距 + float padding = Config.newLayoutPadding; + + // 名称区域 + float nameHeight = Config.newLayoutNameSize.y; + float nameWidth = Config.newLayoutNameSize.x; + Rect nameRect = new Rect(inRect.x + (inRect.width - nameWidth) / 2f, inRect.y + padding, nameWidth, nameHeight); + if (Config.drawBorders) + { + Widgets.DrawBox(nameRect); + } + Text.Anchor = TextAnchor.MiddleCenter; + Text.Font = GameFont.Medium; + Widgets.Label(nameRect, def.characterName); + Text.Font = GameFont.Small; + Text.Anchor = TextAnchor.UpperLeft; + + // 立绘区域 + float lihuiWidth = Config.newLayoutLihuiSize.x; + float lihuiHeight = Config.newLayoutLihuiSize.y; + Rect lihuiRect = new Rect(inRect.x + (inRect.width - lihuiWidth) / 2f, nameRect.yMax + padding, lihuiWidth, lihuiHeight); + if (portrait != null) + { + GUI.DrawTexture(lihuiRect, portrait, ScaleMode.ScaleToFit); + } + if (Config.drawBorders) + { + Widgets.DrawBox(lihuiRect); + } + + // 选项区域 (预先计算高度) + float optionButtonHeight = 30f; // 每个按钮的高度 + float optionSpacing = 5f; // 按钮之间的间距 + float calculatedOptionHeight = 0f; + if (def.options != null && def.options.Any()) + { + calculatedOptionHeight = def.options.Count * optionButtonHeight + (def.options.Count - 1) * optionSpacing; + } + calculatedOptionHeight = Mathf.Max(calculatedOptionHeight, 100f); // 最小高度 + + float optionsWidth = Config.newLayoutOptionsWidth; + Rect optionRect = new Rect(inRect.x + (inRect.width - optionsWidth) / 2f, inRect.yMax - padding - calculatedOptionHeight, optionsWidth, calculatedOptionHeight); + + // 描述区域 + float textWidth = Config.newLayoutTextSize.x; + Rect textRect = new Rect(inRect.x + (inRect.width - textWidth) / 2f, lihuiRect.yMax + padding, textWidth, optionRect.y - (lihuiRect.yMax + padding) - padding); + if (Config.drawBorders) + { + Widgets.DrawBox(textRect); + } + Rect textInnerRect = textRect.ContractedBy(padding); + Widgets.Label(textInnerRect, selectedDescription); + + // 选项列表的绘制 + Listing_Standard listing = new Listing_Standard(); + listing.Begin(optionRect); // 使用完整的 optionRect + if (def.options != null) + { + foreach (var option in def.options) + { + string reason; + bool conditionsMet = AreConditionsMet(option.conditions, out reason); + + if (conditionsMet) + { + if (listing.ButtonText(option.label)) + { + HandleAction(option.optionEffects); + } + } + else + { + if (option.hideWhenDisabled) + { + continue; + } + Rect rect = listing.GetRect(30f); + Widgets.ButtonText(rect, option.label, false, true, false); + TooltipHandler.TipRegion(rect, GetDisabledReason(option, reason)); + } + } + } + listing.End(); + } + + private void HandleAction(List conditionalEffects) + { + if (conditionalEffects.NullOrEmpty()) + { + return; + } + + foreach (var ce in conditionalEffects) + { + if (AreConditionsMet(ce.conditions, out _)) + { + ce.Execute(this); + } + } + } + + private bool AreConditionsMet(List conditions, out string reason) + { + reason = ""; + if (conditions.NullOrEmpty()) + { + return true; + } + + foreach (var condition in conditions) + { + if (!condition.IsMet(out string singleReason)) + { + reason = singleReason; + return false; + } + } + return true; + } + + private string GetDisabledReason(EventOption option, string reason) + { + if (!option.disabledReason.NullOrEmpty()) + { + return option.disabledReason; + } + return reason; + } + + public override void PostClose() + { + base.PostClose(); + HandleAction(def.dismissEffects); + } + + private string FormatDescription(string description) + { + var eventVarManager = Find.World.GetComponent(); + // Use regex to find all placeholders like {variableName} + return Regex.Replace(description, @"\{(.+?)\}", match => + { + string varName = match.Groups[1].Value; + if (eventVarManager.HasVariable(varName)) + { + // Important: GetVariable to get any type + return eventVarManager.GetVariable(varName)?.ToString() ?? ""; + } + return match.Value; // Keep placeholder if variable not found + }); + } + } +} diff --git a/Source/WulaFallenEmpire/WULA_EventSystem/Effect.cs b/Source/WulaFallenEmpire/WULA_EventSystem/Effect.cs index 1d74a72f..1645269b 100644 --- a/Source/WulaFallenEmpire/WULA_EventSystem/Effect.cs +++ b/Source/WulaFallenEmpire/WULA_EventSystem/Effect.cs @@ -1,3 +1,4 @@ +using System; // Required for Activator using System.Collections.Generic; using System.Linq; using UnityEngine; @@ -9,7 +10,7 @@ namespace WulaFallenEmpire public abstract class Effect { public float weight = 1.0f; - public abstract void Execute(Dialog_CustomDisplay dialog = null); + public abstract void Execute(Window dialog = null); } public class Effect_OpenCustomUI : Effect @@ -17,7 +18,7 @@ namespace WulaFallenEmpire public string defName; public int delayTicks = 0; - public override void Execute(Dialog_CustomDisplay dialog = null) + public override void Execute(Window dialog = null) { if (delayTicks > 0) { @@ -58,7 +59,7 @@ namespace WulaFallenEmpire } else { - Find.WindowStack.Add(new Dialog_CustomDisplay(nextDef)); + Find.WindowStack.Add((Window)Activator.CreateInstance(nextDef.windowType, nextDef)); } } else @@ -89,7 +90,7 @@ namespace WulaFallenEmpire public class Effect_CloseDialog : Effect { - public override void Execute(Dialog_CustomDisplay dialog = null) + public override void Execute(Window dialog = null) { dialog?.Close(); } @@ -100,7 +101,7 @@ namespace WulaFallenEmpire public string message; public MessageTypeDef messageTypeDef; - public override void Execute(Dialog_CustomDisplay dialog = null) + public override void Execute(Window dialog = null) { if (messageTypeDef == null) { @@ -114,7 +115,7 @@ namespace WulaFallenEmpire { public IncidentDef incident; - public override void Execute(Dialog_CustomDisplay dialog = null) + public override void Execute(Window dialog = null) { if (incident == null) { @@ -140,7 +141,7 @@ namespace WulaFallenEmpire public FactionDef faction; public int goodwillChange; - public override void Execute(Dialog_CustomDisplay dialog = null) + public override void Execute(Window dialog = null) { if (faction == null) { @@ -166,7 +167,7 @@ namespace WulaFallenEmpire public string type; // Int, Float, String, Bool public bool forceSet = false; - public override void Execute(Dialog_CustomDisplay dialog = null) + public override void Execute(Window dialog = null) { var eventVarManager = Find.World.GetComponent(); if (!forceSet && eventVarManager.HasVariable(name)) @@ -199,7 +200,7 @@ namespace WulaFallenEmpire public FactionDef faction; public string goodwillVariableName; - public override void Execute(Dialog_CustomDisplay dialog = null) + public override void Execute(Window dialog = null) { if (faction == null) { @@ -225,7 +226,7 @@ namespace WulaFallenEmpire public int count = 1; public string storeAs; - public override void Execute(Dialog_CustomDisplay dialog = null) + public override void Execute(Window dialog = null) { if (kindDef == null) { @@ -264,7 +265,7 @@ namespace WulaFallenEmpire public ThingDef thingDef; public int count = 1; - public override void Execute(Dialog_CustomDisplay dialog = null) + public override void Execute(Window dialog = null) { if (thingDef == null) { @@ -298,7 +299,7 @@ namespace WulaFallenEmpire public string letterText; public LetterDef letterDef; - public override void Execute(Dialog_CustomDisplay dialog = null) + public override void Execute(Window dialog = null) { if (kindDef == null) { @@ -356,7 +357,7 @@ namespace WulaFallenEmpire public string valueVariableName; public VariableOperation operation; - public override void Execute(Dialog_CustomDisplay dialog = null) + public override void Execute(Window dialog = null) { if (string.IsNullOrEmpty(name)) { @@ -434,7 +435,7 @@ namespace WulaFallenEmpire { public string name; - public override void Execute(Dialog_CustomDisplay dialog = null) + public override void Execute(Window dialog = null) { if (string.IsNullOrEmpty(name)) { @@ -449,7 +450,7 @@ namespace WulaFallenEmpire { public QuestScriptDef quest; - public override void Execute(Dialog_CustomDisplay dialog = null) + public override void Execute(Window dialog = null) { if (quest == null) { @@ -468,7 +469,7 @@ namespace WulaFallenEmpire { public ResearchProjectDef research; - public override void Execute(Dialog_CustomDisplay dialog = null) + public override void Execute(Window dialog = null) { if (research == null) { @@ -490,7 +491,7 @@ namespace WulaFallenEmpire public string letterLabel; public string letterText; - public override void Execute(Dialog_CustomDisplay dialog = null) + public override void Execute(Window dialog = null) { Map map = Find.CurrentMap; if (map == null) @@ -563,7 +564,7 @@ namespace WulaFallenEmpire public FactionDef factionDef; public string variableName; - public override void Execute(Dialog_CustomDisplay dialog = null) + public override void Execute(Window dialog = null) { if (factionDef == null || string.IsNullOrEmpty(variableName)) { @@ -592,7 +593,7 @@ namespace WulaFallenEmpire { public string variableName; - public override void Execute(Dialog_CustomDisplay dialog = null) + public override void Execute(Window dialog = null) { if (string.IsNullOrEmpty(variableName)) { @@ -611,7 +612,7 @@ namespace WulaFallenEmpire { public string variableName; - public override void Execute(Dialog_CustomDisplay dialog = null) + public override void Execute(Window dialog = null) { if (string.IsNullOrEmpty(variableName)) { @@ -630,7 +631,7 @@ namespace WulaFallenEmpire { public string variableName; - public override void Execute(Dialog_CustomDisplay dialog = null) + public override void Execute(Window dialog = null) { if (string.IsNullOrEmpty(variableName)) { diff --git a/Source/WulaFallenEmpire/WULA_EventSystem/EventDef.cs b/Source/WulaFallenEmpire/WULA_EventSystem/EventDef.cs index 1c2945ad..25c26190 100644 --- a/Source/WulaFallenEmpire/WULA_EventSystem/EventDef.cs +++ b/Source/WulaFallenEmpire/WULA_EventSystem/EventDef.cs @@ -1,3 +1,4 @@ +using System; // Add this line using System.Collections.Generic; using System.Linq; using UnityEngine; @@ -26,6 +27,7 @@ namespace WulaFallenEmpire public Vector2 windowSize = Vector2.zero; + public Type windowType = typeof(Dialog_CustomDisplay); // 默认窗口类型 public List options; public string backgroundImagePath; public List immediateEffects; @@ -83,7 +85,7 @@ namespace WulaFallenEmpire public List randomlistEffects; public List loopEffects; - public void Execute(Dialog_CustomDisplay dialog) + public void Execute(Window dialog) { // Execute all standard effects if (!effects.NullOrEmpty()) diff --git a/Source/WulaFallenEmpire/WULA_EventSystem/EventUIConfigDef.cs b/Source/WulaFallenEmpire/WULA_EventSystem/EventUIConfigDef.cs index bfc19f9b..6cbaf70c 100644 --- a/Source/WulaFallenEmpire/WULA_EventSystem/EventUIConfigDef.cs +++ b/Source/WulaFallenEmpire/WULA_EventSystem/EventUIConfigDef.cs @@ -22,5 +22,13 @@ namespace WulaFallenEmpire // Virtual Layout Offsets public float textNameOffset = 20f; public float optionsTextOffset = 20f; + // New Layout Dimensions + public Vector2 newLayoutNameSize = new Vector2(200f, 50f); + public Vector2 newLayoutLihuiSize = new Vector2(300f, 400f); + public Vector2 newLayoutTextSize = new Vector2(600f, 200f); + public float newLayoutOptionsWidth = 600f; + public float newLayoutPadding = 20f; + public float newLayoutTextNameOffset = 20f; + public float newLayoutOptionsTextOffset = 20f; } } diff --git a/Source/WulaFallenEmpire/WulaFallenEmpire.csproj b/Source/WulaFallenEmpire/WulaFallenEmpire.csproj index 33ab40c6..75b8bf8b 100644 --- a/Source/WulaFallenEmpire/WulaFallenEmpire.csproj +++ b/Source/WulaFallenEmpire/WulaFallenEmpire.csproj @@ -90,6 +90,7 @@ +