diff --git a/.kilocode/rules/rimworld.md b/.kilocode/rules/rimworld.md new file mode 100644 index 00000000..ee6013b9 --- /dev/null +++ b/.kilocode/rules/rimworld.md @@ -0,0 +1,10 @@ +# rimworld.md + +你当前正在制作一个名为乌拉堕落帝国的rimworld1.6游戏mod。你的知识库所使用的代码无一例外全部是过时的。在你思考和做出修改时必须查阅我的本地文件作为知识库,否则你不允许依靠网络搜索或是猜测进行修改代码。 + +## 指导原则 + +- C:\Steam\steamapps\common\RimWorld\Data路径是原版游戏所有XML实现的路径 +- C:\Steam\steamapps\common\RimWorld\Data\dll1.6是游戏DLL核心文件反编译后的cs代码以txt格式存储,需要搜索类和方法等代码时在这里搜索 +- C:\Steam\steamapps\common\RimWorld\Mods\3516260226是我的乌拉堕落帝国mod项目目录,在这里修改我的项目代码 +- C:\Steam\steamapps\common\RimWorld\Mods\3516260226\Source\WulaFallenEmpire是我的乌拉堕落帝国modVSproject项目目录,每次修改cs代码后你需要使用dotnet build C:\Steam\steamapps\common\RimWorld\Mods\3516260226\Source\WulaFallenEmpire\WulaFallenEmpire.csproj命令编译并检查错误日志,只有成功编译才能认为任务完成。 \ No newline at end of file diff --git a/1.6/Assemblies/WulaFallenEmpire.dll b/1.6/Assemblies/WulaFallenEmpire.dll index c923ee85..bd2044e6 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 new file mode 100644 index 00000000..cb92a8b0 --- /dev/null +++ b/1.6/Defs/EventDefs/EventDef_Examples.xml @@ -0,0 +1,45 @@ + + + + + Wula_Test_Raid_Event + + 这是一个测试,用于触发一个带有自定义 pawn 组的袭击。 + +
  • + 10000 + Wula_Broken_Personality_Faction + ImmediateAttack + EdgeWalkIn + Combat + +
  • + Combat + 100 + + 20 + 20 + 2 + 1 + +
  • + + +
    + +
  • + + +
  • + +
  • +
  • + + +
  • + +
  • +
    +
    + +
    \ No newline at end of file diff --git a/1.6/Defs/EventDefs/CustomUI_Wula.xml b/1.6/Defs/EventDefs/EventDef_Wula.xml similarity index 96% rename from 1.6/Defs/EventDefs/CustomUI_Wula.xml rename to 1.6/Defs/EventDefs/EventDef_Wula.xml index 1ca5e009..c76eea83 100644 --- a/1.6/Defs/EventDefs/CustomUI_Wula.xml +++ b/1.6/Defs/EventDefs/EventDef_Wula.xml @@ -1,7 +1,7 @@ - + Wula_UI_Main_1 Wula/Events/Portraits/Wula_insignal @@ -51,9 +51,9 @@ - + - + Wula_UI_Anisia_1 Wula/Events/Portraits/WULA_Anisia_1 @@ -97,8 +97,8 @@ - - + + Wula_UI_Anisia_10 Wula/Events/Portraits/WULA_Anisia_6 @@ -141,8 +141,8 @@ - - + + Wula_UI_Anisia_100 Wula/Events/Portraits/WULA_Anisia_3 @@ -165,8 +165,8 @@ - - + + Wula_UI_Anisia_101 Wula/Events/Portraits/WULA_Anisia_3 @@ -216,8 +216,8 @@ - - + + Wula_UI_Anisia_102 Wula/Events/Portraits/WULA_Anisia_2 @@ -252,8 +252,8 @@ - - + + Wula_UI_Anisia_103 Wula/Events/Portraits/WULA_Anisia_1 @@ -288,8 +288,8 @@ - - + + Wula_UI_Anisia_104 Wula/Events/Portraits/WULA_Anisia_6 @@ -323,10 +323,10 @@ - + - + Wula_ExampleUI_Next UI/HeroArt/Storytellers/Cassandra @@ -369,6 +369,6 @@ - + diff --git a/1.6/Defs/IncidentDefs/Wula_ScheduledIncidents.xml b/1.6/Defs/IncidentDefs/Wula_ScheduledIncidents.xml new file mode 100644 index 00000000..dd02ef25 --- /dev/null +++ b/1.6/Defs/IncidentDefs/Wula_ScheduledIncidents.xml @@ -0,0 +1,25 @@ + + + + + Wula_Incident_ExampleEvent + + Misc + +
  • Map_PlayerHome
  • +
    + + + IncidentWorker_GiveQuest + + + Wula_Quest_ExampleEvent + + +
    + +
    \ No newline at end of file diff --git a/1.6/Defs/Misc/LetterDefs/EventLetter.xml b/1.6/Defs/Misc/LetterDefs/EventLetter.xml new file mode 100644 index 00000000..789cea86 --- /dev/null +++ b/1.6/Defs/Misc/LetterDefs/EventLetter.xml @@ -0,0 +1,9 @@ + + + + Wula_EventChoiceLetter + WulaFallenEmpire.Letter_EventChoice + LetterArrive_Good + (120, 150, 255) + + \ No newline at end of file diff --git a/1.6/Defs/QuestScriptDefs/Wula_ScheduledEvents.xml b/1.6/Defs/QuestScriptDefs/Wula_ScheduledEvents.xml new file mode 100644 index 00000000..76ba580b --- /dev/null +++ b/1.6/Defs/QuestScriptDefs/Wula_ScheduledEvents.xml @@ -0,0 +1,55 @@ + + + + + Wula_Quest_ExampleEvent + + 一个强大的心灵实体将它的意志强加于你的意识之中。 + + +
  • + + +
  • questName->乌拉的呼唤
  • + + + +
  • + + +
  • questDescription->一个强大的心灵实体将它的意志强加于你的意识之中。
  • + + + +
  • + 乌拉需要你的注意 + 乌拉需要你的注意 + 一个强大的心灵实体将它的意志强加于你的意识之中。它自称为“乌拉”,并要求你阅览它的消息。这股力量是压倒性的,不容拒绝。 + +
  • + + +
  • + Wula_UI_Anisia_1 +
  • + + +
  • + + +
  • + Wula_UI_Anisia_1 +
  • +
  • + 你试图抵抗心灵入侵,但这股力量过于强大。无论如何,消息还是涌入了你的脑海。 + NegativeEvent +
  • + + + + +
    +
    +
    + +
    \ No newline at end of file diff --git a/1.6/Defs/Scenarios/Scenarios_WULA.xml b/1.6/Defs/Scenarios/Scenarios_WULA.xml index d7b14a2e..7e3a5aab 100644 --- a/1.6/Defs/Scenarios/Scenarios_WULA.xml +++ b/1.6/Defs/Scenarios/Scenarios_WULA.xml @@ -135,6 +135,12 @@ 《堕落乌拉帝国》mod游玩前提示——机械乌拉和常规殖民者、机械体有何不同?\n\n1.机械乌拉不需要睡觉,卧室和床并不是刚需——除非你需要执行手术;\n\n2.机械乌拉需要补充能量,但是不能使用普通的充电站,她们可以接受的唯一能源来源,便是由钢铁和化合燃料制作的乌拉帝国能源核心。\n\n3.机械乌拉不会自然繁衍,如果想要增加殖民地的人口,需要通过生产建筑乌拉帝国机械工厂进行生产。\n\n4.机械乌拉被生产出来的时候是没有任何技能等级的——你需要在生产建筑乌拉帝国服务器系统制造数据包,并让新合成人使用这些数据包以获得经验。\n\n5.机械乌拉难以自愈,你需要进行科研解锁修复手术并通过手术修复受损部位。\n\n维持乌拉帝国殖民地正常运转所需要的因素比常规殖民地更少,不必过于担忧暴毙,放开想象力游玩吧! GameStartSting + +
  • + CreateIncident + Wula_Incident_ExampleEvent + 0.04 +
  • @@ -274,6 +280,12 @@ 《堕落乌拉帝国》mod游玩前提示——机械乌拉和常规殖民者、机械体有何不同?\n\n1.机械乌拉不需要睡觉,卧室和床并不是刚需——除非你需要执行手术;\n\n2.机械乌拉需要补充能量,但是不能使用普通的充电站,她们可以接受的唯一能源来源,便是由钢铁和化合燃料制作的乌拉帝国能源核心。\n\n3.机械乌拉不会自然繁衍,如果想要增加殖民地的人口,需要通过生产建筑乌拉帝国机械工厂进行生产。\n\n4.机械乌拉被生产出来的时候是没有任何技能等级的——你需要在生产建筑乌拉帝国服务器系统制造数据包,并让新合成人使用这些数据包以获得经验。\n\n5.机械乌拉难以自愈,你需要进行科研解锁修复手术并通过手术修复受损部位。\n\n维持乌拉帝国殖民地正常运转所需要的因素比常规殖民地更少,不必过于担忧暴毙,放开想象力游玩吧! GameStartSting + +
  • + CreateIncident + Wula_Incident_ExampleEvent + 0.04 +
  • diff --git a/Documentation/EventSystem_Documentation.md b/Documentation/EventSystem_Documentation.md index 0257f778..f245cf4a 100644 --- a/Documentation/EventSystem_Documentation.md +++ b/Documentation/EventSystem_Documentation.md @@ -1,459 +1,406 @@ -# 自定义UI事件系统文档 +# Wula Fallen Empire - 事件系统文档 -## 1. 简介 +这是一个用于在RimWorld中创建复杂、带选项的事件和对话框的强大系统。它由两个主要部分组成:**任务事件** 和 **EventDef事件**。 -本事件系统旨在为RimWorld提供一个强大的、数据驱动的、类似视觉小说的事件和事件链创建框架。它的设计灵感来源于Stellaris等策略游戏,允许开发者在XML中定义复杂的UI窗口、交互选项、事件效果和触发条件。 +## 核心概念 -系统的核心由四个部分组成: -- **`CustomUIDef`**: 定义一个独立事件(UI窗口)的所有内容。 -- **`Effect`**: 定义一个选项被点击后执行的具体动作(例如,给予物品、改变关系、打开新窗口等)。 -- **`Condition`**: 定义一个选项是否可选的前提条件(例如,需要某个变量达到特定值)。 -- **`EventContext`**: 一个全局的静态变量存储系统,允许在不同事件和效果之间传递数据。 -- **`EventUIConfigDef`**: 一个全局的外观和布局配置文件,用于统一管理所有事件窗口的视觉风格。 +- **Effect(效果)**: 一个原子操作,例如生成一个Pawn、给予一个物品、改变派系关系或打开另一个UI。 +- **Condition(条件)**: 一个用于决定一个选项是否可用的逻辑检查(例如,检查一个变量的值)。 +- **EventContext(事件上下文)**: 一个全局的静态类,用于存储和检索变量,允许在不同的事件和UI之间传递数据。 --- -## 2. 全局UI配置 (`EventUIConfigDef`) +## 1. 任务事件 (`QuestNode_Root_EventLetter`) -为了方便统一修改所有事件窗口的外观和布局,系统使用一个单例的 `EventUIConfigDef`。你应该在 `Defs` 文件夹下创建一个XML文件来定义它。 +这是通过RimWorld的原版任务系统触发的事件。它会生成一个带有选项的信件。 + +### 如何使用 + +1. 在你的 `QuestScriptDef` 中,使用 `WulaFallenEmpire.QuestNode_Root_EventLetter` 作为根节点。 +2. 在XML中定义 `letterLabel`, `letterTitle`, `letterText`。 +3. 在 `` 列表中定义多个选项。每个选项都有一个 `label` 和一个或多个 `effects`。 + +### 示例 (`QuestScriptDef`) -**文件示例 (`1.6/Defs/ConfigDefs/EventUIConfig.xml`):** ```xml + - - Wula_EventUIConfig - - - Small - true - UI/Backgrounds/DefaultBG - - - (500, 800) - (260, 130) - (650, 500) - 610 - - - 20 - 20 - - + + Wula_ExampleQuestEvent + + 一个抉择 + 远方的呼唤 + 一个来自遥远星系的信号抵达了你们的通讯站。他们似乎想和你们谈谈。 + +
  • + + +
  • + Wula_ExampleEvent +
  • + + +
  • + + +
  • + 你决定无视这个信号。宇宙的寂静再次笼罩着你。 + NeutralEvent +
  • + + +
    +
    +
    ``` -**字段说明:** -- `labelFont`: 事件标题 (`label`) 的字体大小。可选值: `Tiny`, `Small`, `Medium`, `Large`。 -- `drawBorders`: 是否为立绘、名称和描述区域绘制白色边框。 -- `defaultBackgroundImagePath`: 所有事件窗口默认使用的背景图路径。**注意**: 为了完美适配默认的 1000x750 像素窗口,推荐使用宽高比为 4:3 的图片 (例如 1000x750, 800x600 等)。 -- `lihuiSize`, `nameSize`, `textSize`, `optionsWidth`: 定义了UI各部分的基础虚拟尺寸,代码会根据窗口大小按比例缩放它们。 -- `textNameOffset`, `optionsTextOffset`: 定义了各部分之间的垂直间距。 - -**布局预览工具:** -为了帮助您设计背景图片,我们提供了一个动态的可视化布局预览工具。您可以将 `EventUIConfig.xml` 的内容粘贴进去,它会根据您的配置实时生成布局参考图。 -- [**打开动态布局预览 (layout_preview.html)**](./layout_preview.html) - --- -## 3. 如何创建事件 (`CustomUIDef`) +## 2. EventDef事件 (`Dialog_CustomDisplay`) -每个事件都是一个 `CustomUIDef`。你需要在一个 `Defs` XML文件中定义它。 +这是一个高度可定制的对话框窗口,可以显示角色肖像、背景、文本和多个带条件的选项。 -**基本结构:** -```xml - - - MyEvent_UniqueName - - Textures/UI/MyCharacter - 角色名称 - 这里是事件的描述文本。 - - - - - -``` +### 如何使用 -**字段说明:** -- `defName`: 事件的唯一ID,用于在代码或其他事件中引用它。 -- `label`: 显示在窗口左上角的标题。 -- `portraitPath`: 立绘的纹理路径(相对于`Resources`或`Textures`目录)。 -- `characterName`: 显示在名称框中的文本。 -- `backgroundImagePath`: (可选)为此特定事件指定的背景图路径,它会覆盖 `EventUIConfigDef` 中的默认背景。 -- `description`: 显示在描述框中的主要文本。 -- `onOpenEffects`: (可选) 一个 `
  • ` 列表,定义了在事件窗口**打开时**立即执行的所有 `Effect`。 -- `dismissEffects`: (可选) 一个 `
  • ` 列表,定义了在事件窗口**关闭时**(通过选项或关闭按钮)执行的所有 `Effect`。 -- `options`: 一个 `
  • ` 列表,定义了所有的交互选项。 +1. 创建一个 `EventDef`。 +2. 定义 `label`, `characterName`, `portraitPath`, `descriptions` 等。 +3. 在 `` 列表中定义选项。每个选项可以有关联的 `effects` 和 `conditions`。 +4. 你可以通过 `Effect_OpenCustomUI` 效果来打开这个UI(从任务事件或其他EventDef)。 +5. 你也可以通过将 `CompOpenCustomUI` 附加到一个建筑上来从游戏中直接打开它。 ---- - -## 4. 核心概念:选项 (`CustomUIOption`) - -每个选项都在 `` 列表中的一个 `
  • ` 标签内定义。 - -**字段说明:** -- `label`: (必须) 按钮上显示的文本。 -- `effects`: (可选) 一个 `
  • ` 列表,定义了点击此按钮后按顺序执行的所有 `Effect`。 -- `conditions`: (可选) 一个 `
  • ` 列表,定义了此按钮可选所必须满足的所有 `Condition`。只有所有条件都满足,按钮才能被点击。 -- `disabledReason`: (可选) 一个字符串。当按钮因不满足`conditions`而禁用时,鼠标悬停在按钮上会显示此文本。如果未提供,则会自动显示第一个未满足的条件的原因。 - ---- - -## 5. 核心概念:效果 (`Effect`) - -效果定义了“做什么”。每个效果都在 `effects` 列表中的一个 `
  • ` 标签内定义,并且必须有一个 `Class` 属性。 - -### 已实现的 `Effect` 列表 - -#### 5.1 `Effect_OpenCustomUI` -- **功能**: 打开另一个自定义UI事件窗口。 -- **Class**: `WulaFallenEmpire.Effect_OpenCustomUI` -- **字段**: - - `defName`: (必须) 要打开的 `CustomUIDef` 的 `defName`。 -- **示例**: - ```xml -
  • - MyEvent_Step2 -
  • - ``` - -#### 5.2 `Effect_CloseDialog` -- **功能**: 关闭当前的事件窗口。 -- **Class**: `WulaFallenEmpire.Effect_CloseDialog` -- **字段**: 无 -- **示例**: - ```xml -
  • - ``` - -#### 5.3 `Effect_ShowMessage` -- **功能**: 在屏幕左上角显示一条游戏消息。 -- **Class**: `WulaFallenEmpire.Effect_ShowMessage` -- **字段**: - - `message`: (必须) 要显示的文本。 - - `messageTypeDef`: (可选) 消息类型 (例如 `PositiveEvent`, `NegativeEvent`, `NeutralEvent`)。默认为 `PositiveEvent`。 -- **示例**: - ```xml -
  • - 你获得了一个物品! - PositiveEvent -
  • - ``` - -#### 5.4 `Effect_FireIncident` -- **功能**: 触发一个原版或Mod添加的游戏内事件。 -- **Class**: `WulaFallenEmpire.Effect_FireIncident` -- **字段**: - - `incident`: (必须) 要触发的 `IncidentDef` 的 `defName`。 -- **示例**: - ```xml -
  • - RaidEnemy -
  • - ``` - -#### 5.5 `Effect_ChangeFactionRelation` -- **功能**: 改变与指定派系的好感度。 -- **Class**: `WulaFallenEmpire.Effect_ChangeFactionRelation` -- **字段**: - - `faction`: (必须) 目标 `FactionDef` 的 `defName`。 - - `goodwillChange`: (必须) 好感度的改变量,可以是正数或负数。 -- **示例**: - ```xml -
  • - Empire - 15 -
  • - ``` - -#### 5.6 `Effect_SetVariable` -- **功能**: 在 `EventContext` 中设置或修改一个变量的值。 -- **Class**: `WulaFallenEmpire.Effect_SetVariable` -- **字段**: - - `name`: (必须) 变量的名称。 - - `value`: (必须) 变量的值。系统会尝试将其解析为整数或浮点数,如果失败则存为字符串。 -- **示例**: - ```xml -
  • - my_quest_progress - 1 -
  • - ``` - -#### 5.7 `Effect_GiveThing` -- **功能**: 给予玩家一个或多个物品。 -- **Class**: `WulaFallenEmpire.Effect_GiveThing` -- **字段**: - - `thingDef`: (必须) 要给予物品的 `ThingDef` 的 `defName`。 - - `count`: (可选) 给予的数量,默认为 1。 -- **示例**: - ```xml -
  • - Silver - 100 -
  • - ``` - -#### 5.8 `Effect_SpawnPawn` -- **功能**: 在地图上生成一个或多个Pawn,并可选地发送一封信件通知玩家。 -- **Class**: `WulaFallenEmpire.Effect_SpawnPawn` -- **字段**: - - `kindDef`: (必须) 要生成Pawn的 `PawnKindDef` 的 `defName`。 - - `count`: (可选) 生成的数量,默认为 1。 - - `joinPlayerFaction`: (可选) Pawn是否加入玩家派系,默认为 `true`。 - - `letterLabel`: (可选) 通知信件的标题。 - - `letterText`: (可选) 通知信件的内容。 - - `letterDef`: (可选) 通知信件的类型 (例如 `PositiveEvent`, `NegativeEvent`)。默认为 `PositiveEvent`。 -- **示例**: - ```xml -
  • - Colonist - 1 - true - A New Colonist - {PAWN_nameDef} has decided to join your colony. -
  • - ``` - -#### 5.9 `Effect_ModifyVariable` -- **功能**: 对一个数值类型的变量进行数学运算(加、减、乘、除)。 -- **Class**: `WulaFallenEmpire.Effect_ModifyVariable` -- **字段**: - - `name`: (必须) 要修改的变量的名称。 - - `value`: (必须) 用于运算的数值。 - - `operation`: (必须) 执行的运算类型。可选值: `Add`, `Subtract`, `Multiply`, `Divide`。 -- **示例**: - ```xml - -
  • - player_score - 10 - Add -
  • - ``` - -#### 5.10 `Effect_ClearVariable` -- **功能**: 从事件上下文中移除一个变量。 -- **Class**: `WulaFallenEmpire.Effect_ClearVariable` -- **字段**: - - `name`: (必须) 要移除的变量的名称。 -- **示例**: - ```xml -
  • - quest_completed_flag -
  • - ``` - -#### 5.11 `Effect_AddQuest` -- **功能**: 给予玩家一个由游戏核心任务系统生成的任务。 -- **Class**: `WulaFallenEmpire.Effect_AddQuest` -- **字段**: - - `quest`: (必须) 要给予的 `QuestScriptDef` 的 `defName`。 -- **示例**: - ```xml -
  • - OpportunitySite_BanditCamp -
  • - ``` - -#### 5.12 `Effect_FinishResearch` -- **功能**: 立即完成一个指定的科技研究项目。 -- **Class**: `WulaFallenEmpire.Effect_FinishResearch` -- **字段**: - - `research`: (必须) 要完成的 `ResearchProjectDef` 的 `defName`。 -- **示例**: - ```xml -
  • - MicroelectronicsBasics -
  • - ``` - ---- - -## 6. 核心概念:条件 (`Condition`) - -条件定义了选项是否可选的“前提”。每个条件都在 `conditions` 列表中的一个 `
  • ` 标签内定义,并且必须有一个 `Class` 属性。 - -### 已实现的 `Condition` 列表 - -#### 6.1 `Condition_VariableEquals` -- **功能**: 检查一个变量是否等于指定的值。支持字符串和数字的比较。 -- **Class**: `WulaFallenEmpire.Condition_VariableEquals` -- **字段**: - - `name`: (必须) 要检查的变量的名称。 - - `value`: (可选) 要比较的固定值。 - - `valueVariableName`: (可选) 存储比较值的变量的名称。如果同时提供了 `value` 和 `valueVariableName`,则优先使用 `valueVariableName`。 -- **示例 (与固定值比较)**: - ```xml -
  • - quest_status - completed -
  • - ``` -- **示例 (与另一个变量比较)**: - ```xml -
  • - player_choice - correct_answer -
  • - ``` - -#### 6.2 数值比较条件 -以下所有条件都用于数值比较,并共享相同的字段。 - -- **通用字段**: - - `name`: (必须) 要检查的变量的名称。 - - `value`: (可选) 要比较的固定数值。 - - `valueVariableName`: (可选) 存储比较数值的变量的名称。如果同时提供了 `value` 和 `valueVariableName`,则优先使用 `valueVariableName`。 - -- **`Condition_VariableGreaterThan`**: 检查变量是否 **大于** 比较值。 -- **`Condition_VariableLessThan`**: 检查变量是否 **小于** 比较值。 -- **`Condition_VariableGreaterThanOrEqual`**: 检查变量是否 **大于或等于** 比较值。 -- **`Condition_VariableLessThanOrEqual`**: 检查变量是否 **小于或等于** 比较值。 - -- **示例 (大于固定值)**: - ```xml -
  • - player_reputation - 50 -
  • - ``` -- **示例 (小于或等于另一个变量)**: - ```xml -
  • - current_threat_level - max_allowed_threat -
  • - ``` - ---- - -## 7. 核心概念:变量系统 (`EventContext`) - -`EventContext` 是一个全局的静态字典,用于在事件链的不同部分之间传递信息。 - -- **设置变量**: 使用 `Effect_SetVariable` 在XML中设置变量。 -- **检查变量**: 使用 `Condition_VariableEquals` 或其他条件类来检查变量的值,从而控制事件流程。 -- **使用变量**: 一些特殊的 `Effect` (例如 `Effect_ChangeFactionRelation_FromVariable`) 可以被设计为从 `EventContext` 中读取值来执行操作。 - -**注意**: 当前 `EventContext` 是全局共享的。在一个事件链结束后,最好能有一个 `Effect` 来清理掉设置的变量,以避免对其他不相关的事件产生影响(此功能待实现)。 - ---- - -## 8. 完整示例 - -以下是一个演示了事件链、变量和条件的完整示例。 +### `EventDef` 示例 ```xml + - - - - Wula_ExampleUI - - 这是一个事件链的开端。 + + Wula_ExampleEvent + + 特使 + Textures/Wula/Events/Portraits/Envoy + +
  • “你好,来自边缘世界的陌生人。我们观察你很久了。你的挣扎……很有趣。”
  • +
  • - - - -
  • - wula_event_progress - 1 -
  • - -
  • - Wula_ExampleUI_Next -
  • - -
  • - -
  • -
    -
    - - - - Wula_ExampleUI_Next - - 这是事件链的第二部分。 - -
  • - +
  • - 事件链已完成! + “我们是观察者。我们是见证者。现在,我们是你的未来。”
  • - - 需要事件进度=1 - + + 他们似乎对你不够信任。 -
  • - wula_event_progress - 1 +
  • + EmpireGoodwill + 50
  • -
  • - 你触发了特殊选项! +
  • + Gold + 100
  • -
  • - +
  • +
  • -
    - + +
  • + MetTheEnvoy + true +
  • +
    + +
  • + 通讯结束了。 +
  • +
    +
    ---- - -## 9. 调试工具 - -为了方便测试,我们提供了一个开发者调试命令来快速打开任何一个事件窗口。 - -**如何使用:** -1. 在游戏中打开开发者模式。 -2. 点击屏幕上方的第四个按钮 "Open the debug actions menu"。 -3. 在搜索框中输入 "Custom UI"。 -4. 点击 "Wula Fallen Empire - Open Custom UI..." 选项。 -5. 在弹出的列表中,选择你想要测试的事件的 `defName`。 - -这会立即打开对应的事件窗口,让你可以在不满足游戏内触发条件的情况下快速预览和测试你的事件。 ---- - -## 10. 组件:从建筑触发事件 (`CompOpenCustomUI`) - -我们提供了一个通用的 `ThingComp`,可以附加到任何建筑上,通过右键菜单来打开一个指定的事件窗口。 - -**如何使用:** - -1. 在你的建筑 `ThingDef` 的 `` 列表中,添加一个新的 `li`。 -2. 将 `Class` 属性设置为 `WulaFallenEmpire.CompProperties_OpenCustomUI`。 -3. 在 `li` 内部,设置以下字段: - - `uiDefName`: (必须) 要打开的 `CustomUIDef` 的 `defName`。 - - `label`: (必须) 显示在右键菜单中的文本。 - - `failReason`: (可选) 当殖民者无法到达建筑时显示的提示文本。如果未提供,则默认为 "无法到达"。 - -**示例 (`Buildings_EventSource.xml`):** -```xml - - Wula_EventConsole - - ... - - ... - -
  • - Wula_ExampleUI - - 无法接触事件控制台。 -
  • -
    -
    ``` -这个组件会自动处理电力检查(如果建筑有 `CompPowerTrader`)和可达性检查。 +### UI 布局配置 (`EventUIConfigDef`) + +你可以在 `1.6/Defs/WulaMiscSettingDefs/EventUIConfig.xml` 中调整所有EventDef窗口的默认外观和布局。 + +--- + +## 3. 可用的效果 (`Effect`) + +这些是可以在 `effects` 列表中使用的类。 + +### `Effect_OpenCustomUI` +打开一个指定的 `EventDef`。 +- **defName**: (string) 要打开的 `EventDef` 的 `defName`。 +```xml +
  • + Wula_AnotherEvent +
  • +``` + +### `Effect_CloseDialog` +关闭当前的EventDef窗口。没有参数。 +```xml +
  • +``` + +### `Effect_ShowMessage` +在屏幕上显示一条消息。 +- **message**: (string) 要显示的消息文本。 +- **messageTypeDef**: (MessageTypeDef) 消息的类型 (例如 `PositiveEvent`, `NegativeEvent`, `NeutralEvent`)。默认为 `PositiveEvent`。 +```xml +
  • + 你获得了一个新的盟友。 + PositiveEvent +
  • +``` + +### `Effect_FireIncident` +触发一个指定的事件。 +- **incident**: (IncidentDef) 要触发的事件的 `defName`。 +```xml +
  • + RaidEnemy +
  • +``` + +### `Effect_ChangeFactionRelation` +改变玩家与某个派系的关系。 +- **faction**: (FactionDef) 目标派系的 `defName`。 +- **goodwillChange**: (int) 关系值的变化量(可以是负数)。 +```xml +
  • + WulaFallenEmpire_Player + 15 +
  • +``` + +### `Effect_ChangeFactionRelation_FromVariable` +根据一个变量的值改变派系关系。 +- **faction**: (FactionDef) 目标派系的 `defName`。 +- **goodwillVariableName**: (string) 存储关系变化值的变量名。 +```xml +
  • + WulaFallenEmpire_Player + ReputationChange +
  • +``` + +### `Effect_GiveThing` +给玩家一些物品(通过空投)。 +- **thingDef**: (ThingDef) 要给予的物品的 `defName`。 +- **count**: (int) 给予的数量。默认为 1。 +```xml +
  • + Plasteel + 150 +
  • +``` + +### `Effect_SpawnPawn` +生成一个Pawn。 +- **kindDef**: (PawnKindDef) 要生成的Pawn的 `defName`。 +- **count**: (int) 生成的数量。默认为 1。 +- **joinPlayerFaction**: (bool) 是否加入玩家派系。默认为 `true`。 +- **letterLabel**: (string) 可选,生成时附带的信件标题。 +- **letterText**: (string) 可选,生成时附带的信件内容。 +- **letterDef**: (LetterDef) 可选,信件的类型。 +```xml +
  • + Colonist + 1 + true + 一个新人加入了! + 一个流浪者被你们的善举所吸引,决定加入你们的殖民地。 +
  • +``` + +### `Effect_SpawnPawnAndStore` +生成一个Pawn并将其存储在一个变量中以备后用。 +- **kindDef**: (PawnKindDef) 要生成的Pawn的 `defName`。 +- **count**: (int) 生成的数量。默认为 1。 +- **storeAs**: (string) 用于存储生成Pawn的变量名。如果 `count` 大于1,则存储一个Pawn列表。 +```xml +
  • + Wula_Elite_Warrior + spawnedWarrior +
  • +``` + +### `Effect_AddQuest` +触发一个新的任务。 +- **quest**: (QuestScriptDef) 要开始的任务的 `defName`。 +```xml +
  • + Wula_AnotherQuest +
  • +``` + +### `Effect_FinishResearch` +立即完成一个研究项目。 +- **research**: (ResearchProjectDef) 要完成的研究的 `defName`。 +```xml +
  • + MicroelectronicsBasics +
  • +``` + +### `Effect_TriggerRaid` +触发一次袭击。这个效果有两种模式: +1. **简单模式**: 使用派系默认的袭击队伍。 +2. **高级模式**: 使用动态定义的 `pawnGroupMakers` 来生成自定义的袭击队伍。 + +- **points**: (float) 袭击的点数。 +- **faction**: (FactionDef) 袭击者的派系 `defName`。 +- **raidStrategy**: (RaidStrategyDef) 袭击策略的 `defName` (例如 `ImmediateAttack`)。 +- **raidArrivalMode**: (PawnsArrivalModeDef) 袭击者到达方式的 `defName` (例如 `EdgeWalkIn`)。 +- **groupKind**: (PawnGroupKindDef) (高级模式) 定义队伍类型,例如 `Combat` 或 `Trader`。默认为 `Combat`。 +- **pawnGroupMakers**: (List) (高级模式) 一个 `PawnGroupMaker` 列表,用于动态定义袭击队伍的构成。 + +**简单模式示例:** +```xml +
  • + 500 + Pirate + ImmediateAttack + EdgeWalkIn +
  • +``` + +**高级模式示例:** +```xml +
  • + 1000 + WulaFallenEmpire_Player + ImmediateAttack + EdgeWalkIn + Combat + +
  • + Combat + 100 + + 20 + 20 + 2 + 1 + +
  • + + +``` + +### `Effect_SetVariable` +设置一个 `EventContext` 变量的值。 +- **name**: (string) 变量名。 +- **value**: (string) 变量的值。系统会自动尝试将其解析为 `int` 或 `float`,如果失败则作为 `string` 存储。 +```xml +
  • + PlayerChoice + AcceptedOffer +
  • +``` + +### `Effect_ModifyVariable` +对一个数字变量进行加、减、乘、除操作。 +- **name**: (string) 变量名。 +- **value**: (float) 用于操作的数值。 +- **operation**: (VariableOperation) 操作类型,可以是 `Add`, `Subtract`, `Multiply`, `Divide`。 +```xml +
  • + ResourceCount + -10 + Add +
  • +``` + +### `Effect_ClearVariable` +从 `EventContext` 中移除一个变量。 +- **name**: (string) 要清除的变量名。 +```xml +
  • + PlayerChoice +
  • +``` + +--- + +## 4. 可用的条件 (`Condition`) + +这些是可以在 `conditions` 列表中使用的类,用于控制选项的可用性。 + +### `Condition_VariableEquals` +检查一个变量是否等于一个特定值。 +- **name**: (string) 要检查的变量名。 +- **value**: (string) 要比较的字面值。 +- **valueVariableName**: (string) (可选) 要比较的另一个变量的名称。如果提供此项,则忽略 `value`。 +```xml +
  • + PlayerChoice + AcceptedOffer +
  • +``` + +### `Condition_CompareVariable` (基类) +这是一个抽象基类,不应直接使用。以下所有比较条件(大于、小于等)都继承自这个基类,并共享其参数。 + +**基类参数:** +- **name**: (string) 要检查的变量名。 +- **value**: (float) 要比较的字面数值。 +- **valueVariableName**: (string) (可选) 要比较的另一个变量的名称。如果提供此项,则会忽略 `value` 字段。 + +**工作原理:** +当你使用例如 `Condition_VariableGreaterThan` 时,你实际上是在使用一个 `Condition_CompareVariable` 的特定版本。你可以提供 `value` 来与一个固定的数字比较,或者提供 `valueVariableName` 来与另一个变量的值进行比较。 + +**变量与变量比较示例:** +下面的例子使用了 `Condition_VariableGreaterThanOrEqual`(它是 `Condition_CompareVariable` 的子类),来检查 `PlayerWealth` 变量是否大于或等于 `RequiredWealth` 变量。 +```xml +
  • + PlayerWealth + RequiredWealth +
  • +``` + +### `Condition_VariableGreaterThan` +检查一个变量是否 **大于** 一个特定值。 +```xml +
  • + ColonistCount + 5 +
  • +``` + +### `Condition_VariableLessThan` +检查一个变量是否 **小于** 一个特定值。 +```xml +
  • + ThreatPoints + 1000 +
  • +``` + +### `Condition_VariableGreaterThanOrEqual` +检查一个变量是否 **大于或等于** 一个特定值。 +```xml +
  • + EmpireGoodwill + 50 +
  • +``` + +### `Condition_VariableLessThanOrEqual` +检查一个变量是否 **小于或等于** 一个特定值。 +```xml +
  • + YearsPassed + 2 +
  • +``` + +--- diff --git a/Source/WulaFallenEmpire/.vs/WulaFallenEmpire/v17/.suo b/Source/WulaFallenEmpire/.vs/WulaFallenEmpire/v17/.suo index ed461aec..c7f2d06e 100644 Binary files a/Source/WulaFallenEmpire/.vs/WulaFallenEmpire/v17/.suo and b/Source/WulaFallenEmpire/.vs/WulaFallenEmpire/v17/.suo differ diff --git a/Source/WulaFallenEmpire/.vs/WulaFallenEmpire/v17/DocumentLayout.json b/Source/WulaFallenEmpire/.vs/WulaFallenEmpire/v17/DocumentLayout.json index e56e3d21..13ce6a2e 100644 --- a/Source/WulaFallenEmpire/.vs/WulaFallenEmpire/v17/DocumentLayout.json +++ b/Source/WulaFallenEmpire/.vs/WulaFallenEmpire/v17/DocumentLayout.json @@ -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": "" diff --git a/Source/WulaFallenEmpire/EventSystem/CompOpenCustomUI.cs b/Source/WulaFallenEmpire/EventSystem/CompOpenCustomUI.cs index af251dcf..4aa7d8ec 100644 --- a/Source/WulaFallenEmpire/EventSystem/CompOpenCustomUI.cs +++ b/Source/WulaFallenEmpire/EventSystem/CompOpenCustomUI.cs @@ -43,14 +43,14 @@ namespace WulaFallenEmpire FloatMenuOption option = new FloatMenuOption(label, delegate() { - CustomUIDef uiDef = DefDatabase.GetNamed(Props.uiDefName, false); + EventDef uiDef = DefDatabase.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}'."); } }); diff --git a/Source/WulaFallenEmpire/EventSystem/DebugActions.cs b/Source/WulaFallenEmpire/EventSystem/DebugActions.cs index 0fcc1ed5..5f83cc69 100644 --- a/Source/WulaFallenEmpire/EventSystem/DebugActions.cs +++ b/Source/WulaFallenEmpire/EventSystem/DebugActions.cs @@ -11,10 +11,10 @@ namespace WulaFallenEmpire private static void OpenCustomUI() { List list = new List(); - foreach (CustomUIDef localDef in DefDatabase.AllDefs) + foreach (EventDef localDef in DefDatabase.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)); diff --git a/Source/WulaFallenEmpire/EventSystem/Dialog_CustomDisplay.cs b/Source/WulaFallenEmpire/EventSystem/Dialog_CustomDisplay.cs index 0ccf67a2..c1202d1e 100644 --- a/Source/WulaFallenEmpire/EventSystem/Dialog_CustomDisplay.cs +++ b/Source/WulaFallenEmpire/EventSystem/Dialog_CustomDisplay.cs @@ -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()) { diff --git a/Source/WulaFallenEmpire/EventSystem/Effect.cs b/Source/WulaFallenEmpire/EventSystem/Effect.cs index 3bda014e..ce70d404 100644 --- a/Source/WulaFallenEmpire/EventSystem/Effect.cs +++ b/Source/WulaFallenEmpire/EventSystem/Effect.cs @@ -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.GetNamed(defName); + EventDef nextDef = DefDatabase.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 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 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); + } + } + } } diff --git a/Source/WulaFallenEmpire/EventSystem/CustomUIDef.cs b/Source/WulaFallenEmpire/EventSystem/EventDef.cs similarity index 93% rename from Source/WulaFallenEmpire/EventSystem/CustomUIDef.cs rename to Source/WulaFallenEmpire/EventSystem/EventDef.cs index 90652a44..40affb94 100644 --- a/Source/WulaFallenEmpire/EventSystem/CustomUIDef.cs +++ b/Source/WulaFallenEmpire/EventSystem/EventDef.cs @@ -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 options; + public List options; public string backgroundImagePath; public List onOpenEffects; public List dismissEffects; @@ -48,7 +48,7 @@ namespace WulaFallenEmpire } } - public class CustomUIOption + public class EventOption { public string label; public List effects; diff --git a/Source/WulaFallenEmpire/EventSystem/Letter_EventChoice.cs b/Source/WulaFallenEmpire/EventSystem/Letter_EventChoice.cs new file mode 100644 index 00000000..72ffed00 --- /dev/null +++ b/Source/WulaFallenEmpire/EventSystem/Letter_EventChoice.cs @@ -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 options; + public new Quest quest; + + public override IEnumerable 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"); + } + } +} \ No newline at end of file diff --git a/Source/WulaFallenEmpire/EventSystem/QuestNode_Root_EventLetter.cs b/Source/WulaFallenEmpire/EventSystem/QuestNode_Root_EventLetter.cs new file mode 100644 index 00000000..6961e700 --- /dev/null +++ b/Source/WulaFallenEmpire/EventSystem/QuestNode_Root_EventLetter.cs @@ -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 letterLabel; + public SlateRef letterTitle; + public SlateRef letterText; + public List