diff --git a/1.6/Assemblies/WulaFallenEmpire.dll b/1.6/Assemblies/WulaFallenEmpire.dll index 8d1d9af2..9bb36975 100644 Binary files a/1.6/Assemblies/WulaFallenEmpire.dll and b/1.6/Assemblies/WulaFallenEmpire.dll differ diff --git a/1.6/Defs/EventDefs/EventDef_Examples.xml b/1.6/Defs/EventDefs/EventDef_Examples.xml index 2faa2674..07c12caa 100644 --- a/1.6/Defs/EventDefs/EventDef_Examples.xml +++ b/1.6/Defs/EventDefs/EventDef_Examples.xml @@ -6,7 +6,11 @@ 这是一个测试,用于触发一个带有自定义 pawn 组的袭击。 -
  • +
  • + + + +
  • 侦测到失控乌拉! 我们的传感器侦测到一伙来自 {FACTION_name} 的袭击者!他们看起来充满敌意,正朝着我们的殖民地前进。 10000 @@ -27,21 +31,51 @@
  • + +
  • - -
  • - + +
  • + +
  • + +
  • +
  • - -
  • - + +
  • + +
  • + +
  • +
    + + + Wula_HiddenEvent_TriggerRaid + true + +
  • + +
  • + 500 + Pirate + ImmediateAttack + EdgeWalkIn + 警报! + 一个隐藏的信号被触发,吸引了一群海盗前来! +
  • + + +
    +
    + \ No newline at end of file diff --git a/1.6/Defs/EventDefs/EventDef_Wula.xml b/1.6/Defs/EventDefs/EventDef_Wula.xml index c76eea83..25abdbdf 100644 --- a/1.6/Defs/EventDefs/EventDef_Wula.xml +++ b/1.6/Defs/EventDefs/EventDef_Wula.xml @@ -7,48 +7,49 @@ Wula/Events/Portraits/Wula_insignal 基站运转正常,通讯程序已启动。\n\n需要联络乌拉帝国的哪个派系? - - - -
  • - - - -
  • - Wula_UI_Anisia_1 + +
  • + +
  • + Wula_UI_Anisia_1 +
  • +
  • +
  • -
  • - +
  • - - -
  • - + +
  • + +
  • + +
  • +
  • - -
  • - + +
  • + +
  • + +
  • +
  • - -
  • - + +
  • + +
  • + +
  • +
    @@ -66,35 +67,39 @@
  • - - -
  • - Wula_UI_Anisia_10 -
  • -
  • - +
  • - -
  • - WandererJoin + +
  • + +
  • + WandererJoin +
  • +
  • +
  • -
  • - +
  • - -
  • - + +
  • + +
  • + +
  • +
    @@ -108,37 +113,45 @@
  • 可以啊,问吧?
  • 这次就不收你们咨询费了,想问什么?
  • - - - -
  • - -
  • - Wula_UI_Anisia_100 + +
  • + +
  • + Wula_UI_Anisia_100 +
  • +
  • +
  • -
  • - +
  • - -
  • - Wula_UI_Anisia_101 + +
  • + +
  • + Wula_UI_Anisia_101 +
  • +
  • +
  • -
  • - +
  • - -
  • - Wula_UI_Anisia_1 + +
  • + +
  • + Wula_UI_Anisia_1 +
  • +
  • +
  • -
  • - +
  • @@ -150,19 +163,19 @@
  • 什么啊,我没有给你们做过自我介绍吗?难道是我记错了?\n\n咳,你们可以叫我守密者,我是负责看护乌拉帝国知识库的编目司书。然后如你们所见——我是乌拉帝国的合成人,诞生于乌拉帝国最恢弘的黄金时代,承载着先祖的意志,阻止乌拉帝国散佚的先进科技泄露到一些宵小之辈手中。
  • - - - -
  • - -
  • - Wula_UI_Anisia_1 + +
  • + +
  • + Wula_UI_Anisia_1 +
  • +
  • +
  • -
  • - +
  • @@ -174,46 +187,58 @@
  • 那么,你们的殖民地现在发展的怎么样了?基于我的立场,我只会给出关于乌拉帝国科技方面的建议噢?
  • - - - -
  • - -
  • - Wula_UI_Anisia_102 + +
  • + +
  • + Wula_UI_Anisia_102 +
  • +
  • +
  • -
  • - +
  • - -
  • - Wula_UI_Anisia_103 + +
  • + +
  • + Wula_UI_Anisia_103 +
  • +
  • +
  • -
  • - +
  • - -
  • - Wula_UI_Anisia_104 + +
  • + +
  • + Wula_UI_Anisia_104 +
  • +
  • +
  • -
  • - +
  • - -
  • - Wula_UI_Anisia_1 + +
  • + +
  • + Wula_UI_Anisia_1 +
  • +
  • +
  • -
  • - +
  • @@ -228,28 +253,32 @@
  • 啊,原来是刚被唤醒吗?好吧,希望你们没有在漫长的沉睡中忘记了自己的技能。\n\n黄金时代的机械乌拉在经历乌拉帝国人工智能网络崩溃后,人格矩阵都不太稳定——当然,我是特例。注意殖民地的整体心情,任何崩溃的机械乌拉都会被边缘世界上的反常网络识别并监管,她们将直接叛变殖民地!尽量不要把事情闹到那一边,好吗?
  • 啊,原来是刚被唤醒吗?好吧,希望你们没有在漫长的沉睡中忘记了自己的技能。\n\n乌拉猫猫是机械乌拉的得力助手,它们是一个拥有多种型号的机械助手,可以承担很多工作。机械乌拉与生俱来的设计使得她们可以控制少量的乌拉猫猫为其效命。你可以研究科技「机械体构建套件」,以组装更多的小小劳工。
  • - - - -
  • - -
  • - Wula_UI_Anisia_102 + +
  • + +
  • + Wula_UI_Anisia_102 +
  • +
  • +
  • -
  • - +
  • - -
  • - Wula_UI_Anisia_101 + +
  • + +
  • + Wula_UI_Anisia_101 +
  • +
  • +
  • -
  • - +
  • @@ -264,28 +293,32 @@
  • 很高兴听到这样的自我评价,自信是这块烂地生存的资本。\n\n或许你们已经筹划好增添新丁了?研究「合成人构建套件」,以解锁在乌拉帝国机械工厂建造新合成人的权限。新诞生的合成人是没有任何技能熟练度的,记得提前研究「数据下载套件」,准备好乌拉帝国数据包!
  • 很高兴听到这样的自我评价,自信是这块烂地生存的资本。\n\n如果乌拉帝国的遗孤们已经抵达这颗星球,则你们可以试着接触她们——更高级的科技需要依靠她们解锁,提前接触未尝不是未雨绸缪。
  • - - - -
  • - -
  • - Wula_UI_Anisia_103 + +
  • + +
  • + Wula_UI_Anisia_103 +
  • +
  • +
  • -
  • - +
  • - -
  • - Wula_UI_Anisia_101 + +
  • + +
  • + Wula_UI_Anisia_101 +
  • +
  • +
  • -
  • - +
  • @@ -299,28 +332,32 @@
  • 已经凌驾于这片土地之上了,正在寻求终局的意义吗?\n\n有尝试过制造乌拉帝国的大型机械体吗?它们是强大的战场支柱,每一台都拥有改变战局的力量。不过,机械乌拉的初始带宽无法控制大型机械体,你们需要准备一些扩充带宽的改件和装备,或者干脆植入机控中枢以利用边缘世界的本土科技。
  • 已经凌驾于这片土地之上了,正在寻求终局的意义吗?\n\n小心友军火力!乌拉帝国的高级装备基本上都是能将敌人炸的血肉横飞的区域性伤害武器,它们的破坏力毋庸置疑,但是同时也会导致战利品丢失和频繁的误伤——或许该考虑给殖民者配一套装甲了。
  • - - - -
  • - -
  • - Wula_UI_Anisia_104 + +
  • + +
  • + Wula_UI_Anisia_104 +
  • +
  • +
  • -
  • - +
  • - -
  • - Wula_UI_Anisia_101 + +
  • + +
  • + Wula_UI_Anisia_101 +
  • +
  • +
  • -
  • - +
  • @@ -335,16 +372,20 @@
  • - -
  • - 事件链已完成!一位流浪者加入了你的殖民地,帝国对你的行为表示赞赏。 + +
  • + +
  • + 事件链已完成!一位流浪者加入了你的殖民地,帝国对你的行为表示赞赏。 +
  • +
  • + Empire + 15 +
  • +
  • +
  • -
  • - Empire - 15 -
  • -
  • - +
  • @@ -355,18 +396,26 @@ 1
  • - -
  • - 你触发了特殊选项! + +
  • + +
  • + 你触发了特殊选项! +
  • +
  • +
  • -
  • - +
  • - -
  • - + +
  • + +
  • + +
  • +
    diff --git a/Documentation/EventSystem_Documentation.md b/Documentation/EventSystem_Documentation.md index 32500a69..d9014522 100644 --- a/Documentation/EventSystem_Documentation.md +++ b/Documentation/EventSystem_Documentation.md @@ -34,20 +34,20 @@
  • - +
  • Wula_ExampleEvent
  • - +
  • - +
  • 你决定无视这个信号。宇宙的寂静再次笼罩着你。 NeutralEvent
  • - +
    @@ -69,6 +69,19 @@ 4. 你可以通过 `Effect_OpenCustomUI` 效果来打开这个UI(从任务事件或其他EventDef)。 5. 你也可以通过将 `CompOpenCustomUI` 附加到一个建筑上来从游戏中直接打开它。 +### `EventDef` 参数 + +- **label**: (string) 窗口的标题。 +- **characterName**: (string) 显示在肖像下方的角色名称。 +- **portraitPath**: (string) 角色肖像的纹理路径。 +- **descriptions**: (List) 一个描述文本列表。可以通过 `descriptionMode` 控制是随机选择一个还是按顺序显示。 +- **options**: (List) 对话框中显示的选项列表。 +- **immediateEffects**: (List) 当对话框打开时立即执行的效果列表。 +- **dismissEffects**: (List) 当对话框关闭时(通过关闭按钮或`Effect_CloseDialog`)执行的效果列表。 +- **backgroundImagePath**: (string) (可选) 对话框的背景图片路径。 +- **windowSize**: (Vector2) (可选) 自定义窗口大小。 +- **hiddenWindow**: (bool) (可选) 如果为 `true`,则不会显示窗口。在这种模式下,`immediateEffects` 的内容会在加载时自动合并到 `dismissEffects` 中,然后在事件触发时作为单个效果链统一执行。这对于创建纯粹的后台“效果链”事件非常有用。默认为 `false`。 + ### `EventDef` 示例 ```xml @@ -82,45 +95,87 @@
  • “你好,来自边缘世界的陌生人。我们观察你很久了。你的挣扎……很有趣。”
  • + + +
  • + + +
  • + MetTheEnvoy + true +
  • + + +
    + + +
  • + +
  • + PlayerMadeChoice + false +
  • + + +
  • + 你没有做出选择就关闭了通讯。 +
  • +
    + +
  • - -
  • - “我们是观察者。我们是见证者。现在,我们是你的未来。” + +
  • + +
  • + “我们是观察者。我们是见证者。现在,我们是你的未来。” +
  • +
  • +
  • -
  • - +
  • - + 他们似乎对你不够信任。 +
  • EmpireGoodwill 50
  • - -
  • - Gold - 100 + +
  • + + +
  • + IsGenerous + true +
  • + + +
  • + Gold + 200 +
  • +
  • +
  • -
  • - +
  • + +
  • + Gold + 100 +
  • +
  • + +
  • +
    - -
  • - MetTheEnvoy - true -
  • -
    - -
  • - 通讯结束了。 -
  • -
    ``` @@ -131,9 +186,44 @@ --- -## 3. 可用的效果 (`Effect`) +## 3. 核心结构: 条件化效果 (`ConditionalEffects`) -这些是可以在 `effects` 列表中使用的类。 +所有执行效果的地方 (`immediateEffects`, `dismissEffects`, 以及每个选项的 `optionEffects`) 都是一个 `ConditionalEffects` 块的列表。 + +这允许你将一组效果与一组条件绑定在一起。 + +### `ConditionalEffects` 结构 + +每个 `
  • ` 代表一个 `ConditionalEffects` 块。它包含两个可选部分: +- **``**: 一个条件列表。只有当这里的所有条件都满足时,对应的效果才会执行。如果省略这个部分,效果将总是执行。 +- **``**: 一个效果列表。当条件满足时,这些效果会被执行。 + +```xml + +
  • + +
  • + PlayerChoice + AcceptedOffer +
  • + + +
  • + 你接受了提议! +
  • +
  • + Silver + 500 +
  • +
    + +``` + +--- + +## 4. 可用的效果 (`Effect`) + +这些是可以在 `ConditionalEffects` 块的 `` 列表中使用的类。 ### `Effect_OpenCustomUI` 打开一个指定的 `EventDef`。 diff --git a/Source/WulaFallenEmpire/EventSystem/Dialog_CustomDisplay.cs b/Source/WulaFallenEmpire/EventSystem/Dialog_CustomDisplay.cs index 6ef3144f..2184bd81 100644 --- a/Source/WulaFallenEmpire/EventSystem/Dialog_CustomDisplay.cs +++ b/Source/WulaFallenEmpire/EventSystem/Dialog_CustomDisplay.cs @@ -83,7 +83,7 @@ namespace WulaFallenEmpire background = ContentFinder.Get(bgPath); } - HandleAction(def.onOpenEffects); + HandleAction(def.immediateEffects); } public override void DoWindowContents(Rect inRect) @@ -186,7 +186,7 @@ namespace WulaFallenEmpire { if (listing.ButtonText(option.label)) { - HandleAction(option.effects); + HandleAction(option.optionEffects); } } else @@ -200,16 +200,26 @@ namespace WulaFallenEmpire listing.End(); } - private void HandleAction(List effects) + private void HandleAction(List conditionalEffects) { - if (effects.NullOrEmpty()) + if (conditionalEffects.NullOrEmpty()) { return; } - foreach (var effect in effects) + foreach (var ce in conditionalEffects) { - effect.Execute(this); + string reason; + if (AreConditionsMet(ce.conditions, out reason)) + { + if (!ce.effects.NullOrEmpty()) + { + foreach (var effect in ce.effects) + { + effect.Execute(this); + } + } + } } } diff --git a/Source/WulaFallenEmpire/EventSystem/Effect.cs b/Source/WulaFallenEmpire/EventSystem/Effect.cs index 095b207f..a3568502 100644 --- a/Source/WulaFallenEmpire/EventSystem/Effect.cs +++ b/Source/WulaFallenEmpire/EventSystem/Effect.cs @@ -21,13 +21,56 @@ namespace WulaFallenEmpire EventDef nextDef = DefDatabase.GetNamed(defName); if (nextDef != null) { - Find.WindowStack.Add(new Dialog_CustomDisplay(nextDef)); + if (nextDef.hiddenWindow) + { + // Since effects are merged in PostLoad, we only need to execute dismissEffects here. + if (!nextDef.dismissEffects.NullOrEmpty()) + { + foreach (var conditionalEffect in nextDef.dismissEffects) + { + string reason; + if (AreConditionsMet(conditionalEffect.conditions, out reason)) + { + if (!conditionalEffect.effects.NullOrEmpty()) + { + foreach (var effect in conditionalEffect.effects) + { + effect.Execute(null); + } + } + } + } + } + } + else + { + Find.WindowStack.Add(new Dialog_CustomDisplay(nextDef)); + } } else { Log.Error($"[WulaFallenEmpire] Effect_OpenCustomUI could not find EventDef named '{defName}'"); } } + + 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; + } } public class Effect_CloseDialog : Effect diff --git a/Source/WulaFallenEmpire/EventSystem/EventDef.cs b/Source/WulaFallenEmpire/EventSystem/EventDef.cs index 8814c6b4..16691cde 100644 --- a/Source/WulaFallenEmpire/EventSystem/EventDef.cs +++ b/Source/WulaFallenEmpire/EventSystem/EventDef.cs @@ -18,6 +18,7 @@ namespace WulaFallenEmpire // New system: list of descriptions public List descriptions; public DescriptionSelectionMode descriptionMode = DescriptionSelectionMode.Random; + public bool hiddenWindow = false; // Backwards compatibility: old single description field public new string description = null; @@ -26,9 +27,8 @@ namespace WulaFallenEmpire public List options; public string backgroundImagePath; - public List onOpenEffects; - public List dismissEffects; - + public List immediateEffects; + public List dismissEffects; public override void PostLoad() { base.PostLoad(); @@ -44,14 +44,30 @@ namespace WulaFallenEmpire description = null; // Clear the old field to prevent confusion } #pragma warning restore 0618 + // If hiddenWindow is true, merge immediateEffects into dismissEffects at load time. + if (hiddenWindow && !immediateEffects.NullOrEmpty()) + { + if (dismissEffects.NullOrEmpty()) + { + dismissEffects = new List(); + } + dismissEffects.AddRange(immediateEffects); + immediateEffects = null; // Clear to prevent double execution + } } } public class EventOption { public string label; - public List effects; + public List optionEffects; public List conditions; public string disabledReason; } + + public class ConditionalEffects + { + public List conditions; + public List effects; + } } diff --git a/Source/WulaFallenEmpire/EventSystem/Letter_EventChoice.cs b/Source/WulaFallenEmpire/EventSystem/Letter_EventChoice.cs index d6a16b96..9e753643 100644 --- a/Source/WulaFallenEmpire/EventSystem/Letter_EventChoice.cs +++ b/Source/WulaFallenEmpire/EventSystem/Letter_EventChoice.cs @@ -29,11 +29,21 @@ namespace WulaFallenEmpire var currentOption = optionDef; Action choiceAction = delegate { - if (!currentOption.effects.NullOrEmpty()) + if (!currentOption.optionEffects.NullOrEmpty()) { - foreach (var effect in currentOption.effects) + foreach (var conditionalEffect in currentOption.optionEffects) { - effect.Execute(null); + string reason; + if (AreConditionsMet(conditionalEffect.conditions, out reason)) + { + if (!conditionalEffect.effects.NullOrEmpty()) + { + foreach (var effect in conditionalEffect.effects) + { + effect.Execute(null); + } + } + } } } if (quest != null && !quest.hidden && !quest.Historical) @@ -55,6 +65,25 @@ namespace WulaFallenEmpire public override bool CanDismissWithRightClick => false; + 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; + } + public override void ExposeData() { base.ExposeData(); diff --git a/Source/WulaFallenEmpire/EventSystem/QuestNode_Root_EventLetter.cs b/Source/WulaFallenEmpire/EventSystem/QuestNode_Root_EventLetter.cs index 6961e700..5142eff6 100644 --- a/Source/WulaFallenEmpire/EventSystem/QuestNode_Root_EventLetter.cs +++ b/Source/WulaFallenEmpire/EventSystem/QuestNode_Root_EventLetter.cs @@ -43,7 +43,7 @@ namespace WulaFallenEmpire public class Option { public string label; - public List effects; + public List optionEffects; } } } \ No newline at end of file