diff --git a/1.6/1.6/Assemblies/WulaFallenEmpire.dll b/1.6/1.6/Assemblies/WulaFallenEmpire.dll index bb793e00..444d06d8 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/IncidentDefs/Wula_ScheduledIncidents.xml b/1.6/1.6/Defs/IncidentDefs/Wula_ScheduledIncidents.xml index dd02ef25..90d0ebb2 100644 --- a/1.6/1.6/Defs/IncidentDefs/Wula_ScheduledIncidents.xml +++ b/1.6/1.6/Defs/IncidentDefs/Wula_ScheduledIncidents.xml @@ -22,4 +22,18 @@ --> + + Wula_Incident_RecoverItem + + Misc + +
  • Map_PlayerHome
  • +
    + IncidentWorker_GiveQuest + Wula_Quest_RecoverItem + 0.4 + 15 + 20 +
    + \ No newline at end of file diff --git a/1.6/1.6/Defs/QuestScriptDefs/Wula_ScheduledEvents.xml b/1.6/1.6/Defs/QuestScriptDefs/Wula_ScheduledEvents.xml index 32a34ca8..6dbb39d4 100644 --- a/1.6/1.6/Defs/QuestScriptDefs/Wula_ScheduledEvents.xml +++ b/1.6/1.6/Defs/QuestScriptDefs/Wula_ScheduledEvents.xml @@ -1,61 +1,136 @@ - Wula_Quest_ExampleEvent - - 一个强大的心灵实体将它的意志强加于你的意识之中。 + Wula_Quest_RecoverItem -
  • - - -
  • questName->乌拉的呼唤
  • - - + +
  • + Util_RandomizePointsChallengeRating
  • -
  • - - -
  • questDescription->一个强大的心灵实体将它的意志强加于你的意识之中。
  • - - +
  • +
  • + asker + false
  • -
  • - 乌拉需要你的注意 - 乌拉需要你的注意 - 一个强大的心灵实体将它的意志强加于你的意识之中。它自称为“乌拉”,并要求你阅览它的消息。这股力量是压倒性的,不容拒绝。 - + + +
  • + siteTile + true +
  • +
  • + sitePartDefs + siteFaction +
  • - - -
  • - -
  • - Wula_UI_Anisia_1 -
  • - - - + ItemStash
  • - - -
  • - -
  • - Wula_UI_Anisia_1 -
  • -
  • - 你试图抵抗心灵入侵,但这股力量过于强大。无论如何,消息还是涌入了你的脑海。 - NegativeEvent -
  • - - - + ItemStashQuestThreat + 0.85 - + +
  • + $siteTile + $siteFaction + $sitePartDefs + sitePartsParams +
  • +
  • + Util_GenerateSite +
  • +
  • + $site +
  • + + +
  • + Wula_QuestItem_AncientDataDevice + itemStashContents +
  • +
  • + $itemStashContents + itemStashContents +
  • + + +
  • +
  • + + +
  • + + [questDescription] +
  • + + +
  • + site.MapGenerated + + $site + $itemStashContents + +
  • + +
  • + itemStashContents.PickedUp + + + 你的人已经拿到了[itemStashContents_label]。现在需要将它安全带回殖民地,乌拉族会派穿梭机来取走它。 + +
  • + +
  • + WulaFallenEmpire.Quest.RecoverItem.ItemRecoveredToHome + + $itemStashContents.Map + $itemStashContents + +
  • + +
  • + WulaFallenEmpire.Quest.RecoverItem.ItemLoadedOnShuttle + + +
  • + + $(800 * questPointFactor) + +
  • +
  • + Success +
  • +
    + + + + +
  • + $site + true + $(randInt(12,28)*60000) + site.MapGenerated + QuestTimeout +
  • +
  • + QuestTimeout + Fail +
  • +
    + + +
  • questName->回收[itemStashContents_label]
  • +
    +
    + + +
  • questDescription->[asker_nameDef]希望你前往[site_tile_label]附近的一个地点,取回一个[itemStashContents_label]。\n\n该地点由[siteFaction_name]的[siteFaction_pawnsPlural]看守。
  • +
    +
    +
    \ No newline at end of file diff --git a/1.6/1.6/Defs/ThingDefs_Misc/Wula_QuestItems.xml b/1.6/1.6/Defs/ThingDefs_Misc/Wula_QuestItems.xml new file mode 100644 index 00000000..f44e50a0 --- /dev/null +++ b/1.6/1.6/Defs/ThingDefs_Misc/Wula_QuestItems.xml @@ -0,0 +1,33 @@ + + + + + Wula_QuestItem_AncientDataDevice + + 一个古老的、无法破译的数据存储设备。它不包含任何有价值的信息,但乌拉族似乎对回收它很感兴趣。 + + Things/Item/Resource/ComponentSpacer + Graphic_Single + + First + Silver_Drop + Silver_Drop + true + + 0 + 2 + 100 + 0.2 + + +
  • Items
  • +
    + None + +
  • Quest
  • +
    + 1 + Ultra +
    + +
    \ No newline at end of file diff --git a/1.6/1.6/Languages/ChineseSimplified/Keyed/Wula_Quest_Keys.xml b/1.6/1.6/Languages/ChineseSimplified/Keyed/Wula_Quest_Keys.xml new file mode 100644 index 00000000..ec9bfba9 --- /dev/null +++ b/1.6/1.6/Languages/ChineseSimplified/Keyed/Wula_Quest_Keys.xml @@ -0,0 +1,14 @@ + + + + + 回收:{0} + 乌拉族的一个代理人联系了你。他们发现了一个装有{0}的古代遗迹,但是被{1}的{2}看守着。\n\n他们希望你派人去取回这个物品。作为回报,他们会提供奖励。\n\n地点在[site_tile_label],位于[site_tile_label]方向[site_tile_distance]天路程。 + 任务:回收物品 + 你收到了一个来自乌拉族的任务请求。 + 已取回物品 + 你的人已经拿到了{0}。现在需要将它安全带回殖民地,乌拉族会派穿梭机来取走它。 + 回收穿梭机已抵达 + 乌拉族的回收穿梭机已经抵达。请将{0}装载到穿梭机中以完成任务。 + + \ No newline at end of file diff --git a/Source/WulaFallenEmpire/Quests/CustomQuestNodes.cs b/Source/WulaFallenEmpire/Quests/CustomQuestNodes.cs new file mode 100644 index 00000000..0509c1d6 --- /dev/null +++ b/Source/WulaFallenEmpire/Quests/CustomQuestNodes.cs @@ -0,0 +1,97 @@ +using RimWorld; +using RimWorld.Planet; +using RimWorld.QuestGen; +using Verse; +using Verse.Grammar; + +namespace WulaFallenEmpire.Quests +{ + public class QuestNode_DropShuttleForRecovery : QuestNode + { + [NoTranslate] + public SlateRef map; + + [NoTranslate] + public SlateRef itemToRecover; + + protected override void RunInt() + { + Slate slate = QuestGen.slate; + Map targetMap = map.GetValue(slate); + Thing item = itemToRecover.GetValue(slate); + + if (targetMap == null || item == null) return; + + var shuttle = ThingMaker.MakeThing(ThingDefOf.Shuttle) as ThingWithComps; + if (shuttle == null) return; + + var comp = shuttle.TryGetComp(); + if (comp != null) + { + comp.groupID = Find.UniqueIDsManager.GetNextTransporterGroupID(); + var questComponent = Current.Game.GetComponent(); + questComponent?.RegisterRecoveryQuest(item, comp.groupID); + } + + DropCellFinder.TryFindDropSpotNear(targetMap.Center, targetMap, out var spot, allowFogged: false, canRoofPunch: false); + DropPodUtility.DropThingsNear(spot, targetMap, new[] { shuttle }); + } + + protected override bool TestRunInt(Slate slate) + { + return map.GetValue(slate) != null && itemToRecover.GetValue(slate) != null; + } + } + + public class QuestNode_AddThingRules : QuestNode + { + [NoTranslate] + public SlateRef thing; + + [NoTranslate] + public SlateRef prefix; + + protected override void RunInt() + { + Slate slate = QuestGen.slate; + Thing value = thing.GetValue(slate); + if (value != null) + { + var rulePack = new RulePack(); + rulePack.Rules.Add(new Rule_String(prefix.GetValue(slate) + "_label", value.Label)); + QuestGen.AddQuestDescriptionRules(rulePack); + } + } + + protected override bool TestRunInt(Slate slate) + { + return thing.GetValue(slate) != null; + } + } + + public class QuestNode_SpawnThing_Wula : QuestNode + { + [NoTranslate] + public SlateRef mapParent; + [NoTranslate] + public SlateRef thing; + [NoTranslate] + public SlateRef faction; + + protected override void RunInt() + { + Slate slate = QuestGen.slate; + var part = new QuestPart_SpawnThing(); + part.mapParent = mapParent.GetValue(slate); + part.thing = thing.GetValue(slate); + part.factionForFindingSpot = faction.GetValue(slate); + part.inSignal = QuestGen.slate.Get("inSignal"); + QuestGen.quest.AddPart(part); + } + + protected override bool TestRunInt(Slate slate) + { + return mapParent.GetValue(slate) != null && thing.GetValue(slate) != null; + } + } +} \ No newline at end of file diff --git a/Source/WulaFallenEmpire/Quests/QuestUtility.cs b/Source/WulaFallenEmpire/Quests/QuestUtility.cs new file mode 100644 index 00000000..ae05d008 --- /dev/null +++ b/Source/WulaFallenEmpire/Quests/QuestUtility.cs @@ -0,0 +1,70 @@ +using RimWorld; +using Verse; +using System.Collections.Generic; + +namespace WulaFallenEmpire.Quests +{ + public class GameComponent_WulaQuests : GameComponent + { + // key: 任务物品, value: 对应的回收穿梭机groupID + private Dictionary activeRecoveryQuests = new Dictionary(); + + public GameComponent_WulaQuests(Game game) + { + } + + public void RegisterRecoveryQuest(Thing item, int shuttleGroupID) + { + if (!activeRecoveryQuests.ContainsKey(item)) + { + activeRecoveryQuests.Add(item, shuttleGroupID); + } + } + + public void UnregisterRecoveryQuest(Thing item) + { + if (activeRecoveryQuests.ContainsKey(item)) + { + activeRecoveryQuests.Remove(item); + } + } + + public override void GameComponentTick() + { + base.GameComponentTick(); + + if (Find.TickManager.TicksGame % 60 != 0) return; + + var questsToCheck = new Dictionary(activeRecoveryQuests); + + foreach (var entry in questsToCheck) + { + var item = entry.Key; + var shuttleGroupID = entry.Value; + + if (item == null || item.Destroyed) + { + UnregisterRecoveryQuest(item); + continue; + } + + if (item.Map != null && item.Map.IsPlayerHome) + { + Find.SignalManager.SendSignal(new Signal("WulaFallenEmpire.Quest.RecoverItem.ItemRecoveredToHome")); + } + + if (item.ParentHolder is CompTransporter transporter && transporter.groupID == shuttleGroupID) + { + Find.SignalManager.SendSignal(new Signal("WulaFallenEmpire.Quest.RecoverItem.ItemLoadedOnShuttle")); + UnregisterRecoveryQuest(item); + } + } + } + + public override void ExposeData() + { + base.ExposeData(); + Scribe_Collections.Look(ref activeRecoveryQuests, "activeRecoveryQuests", LookMode.Reference, LookMode.Value); + } + } +} \ No newline at end of file diff --git a/Source/WulaFallenEmpire/WulaFallenEmpire.csproj b/Source/WulaFallenEmpire/WulaFallenEmpire.csproj index 33ab40c6..90c4d476 100644 --- a/Source/WulaFallenEmpire/WulaFallenEmpire.csproj +++ b/Source/WulaFallenEmpire/WulaFallenEmpire.csproj @@ -192,6 +192,8 @@ + + diff --git a/Wula_New_Quests_Design.md b/Wula_New_Quests_Design.md new file mode 100644 index 00000000..d07565a1 --- /dev/null +++ b/Wula_New_Quests_Design.md @@ -0,0 +1,120 @@ +# 乌拉族新任务设计文档 + +本文档旨在详细阐述为乌拉族Mod添加三个新任务的设计与实现方案。这三个任务分别为:**回收物品**、**安插信标**和**运送建材**。 + +## 1. 总体设计思路 + +我们将遵循RimWorld原版的任务(Quest)框架,为每个任务创建对应的`IncidentDef`(事件定义)作为触发器,以及`QuestScriptDef`(任务脚本定义)来描述任务的具体流程。 + +- **XML驱动**:尽可能利用原版的QuestNode来构建任务逻辑,减少C#代码的编写量。 +- **C#扩展**:对于原版QuestNode无法实现的功能(如检查穿梭机内容、特定地点交互),我们将编写自定义的C#类(QuestNode、WorldObjectComp或GameComponent)。 +- **模块化**:每个任务都将是独立的,有自己的`IncidentDef`和`QuestScriptDef`,便于管理和未来的扩展。 +- **本地化**:所有面向玩家的文本(任务名、描述、信件内容等)都将使用Keyed-Value形式,并提供中英双语支持。 + +## 2. 任务详解 + +### 2.1. 回收物品 (Recover Item) + +**任务描述**: 玩家接到任务,需要前往一个由佣兵或强盗看守的地图,取回一个特定的无价值物品(任务物品),并成功带回殖民地。一旦物品带回,乌拉族会派穿梭机前来回收,任务完成。 + +**实现方案**: +- **触发**: 创建一个新的`IncidentDef`,`defName: Wula_Incident_RecoverItem`。 +- **任务脚本**: 创建`QuestScriptDef`,`defName: Wula_Quest_RecoverItem`。该脚本将参照原版的`OpportunitySite_ItemStash`。 +- **流程图 (Mermaid)**: + ```mermaid + graph TD + A[任务触发: Wula_Incident_RecoverItem] --> B{生成任务地点和看守}; + B --> C[在任务地点生成任务物品]; + C --> D[玩家前往并击败看守]; + D --> E[玩家拾取任务物品并带回基地]; + E --> F{监听物品进入玩家基地地图}; + F --> G[生成乌拉族回收穿梭机]; + G --> H[玩家将物品交给穿梭机]; + H --> I[任务完成,给予奖励]; + ``` +- **关键QuestNode**: + - `QuestNode_GetSiteTile`: 生成任务地点。 + - `QuestNode_GetSitePartDefsByTagsAndFaction`: 定义地点的敌人(佣兵/强盗)。 + - `QuestNode_GenerateThing`: 在任务地点生成任务物品。 + - `QuestNode_SignalListen`: + - 监听`item.Map.IsPlayerHome`来检测物品是否被带回基地。 + - 监听`item.Transferable.Things`来检测物品是否被装入穿梭机。 + - `QuestNode_DropPods`: 用于生成乌拉族回收穿梭机。 + - `QuestNode_End`: 结束任务并给予奖励。 +- **新定义**: + - `ThingDef`: 一个新的任务物品,例如`Wula_QuestItem_AncientDataDevice`,它没有市场价值,不可交易,但可以被携带。 + +### 2.2. 安插信标 (Place Beacon) + +**任务描述**: 乌拉族空投一个可打包的信标建筑。玩家需要将信标带到另一个由机械族看守的地图,并在指定区域进行“安装”(放置)。安装成功后任务完成。 + +**实现方案**: +- **触发**: 创建`IncidentDef`,`defName: Wula_Incident_PlaceBeacon`。 +- **任务脚本**: 创建`QuestScriptDef`,`defName: Wula_Quest_PlaceBeacon`。 +- **流程图 (Mermaid)**: + ```mermaid + graph TD + A[任务触发: Wula_Incident_PlaceBeacon] --> B[在玩家基地空投信标物品]; + B --> C{生成任务地点和机械族看守}; + C --> D[玩家携带信标前往任务地点]; + D --> E[击败机械族]; + E --> F{在指定区域安装信标}; + F --> G[任务完成,给予奖励]; + ``` +- **关键QuestNode**: + - `QuestNode_DropPods`: 在玩家基地空投信标。 + - `QuestNode_GetSiteTile`: 生成任务地点。 + - `QuestNode_GetSitePartDefsByTagsAndFaction`: 定义地点的敌人(机械族)。 + - `QuestNode_SignalListen`: 监听一个自定义信号,如`wula.beaconPlaced`。 +- **C# 扩展**: + - `Building_QuestBeacon`: 一个继承自`Building`的C#类。当这个建筑在任务地图上成功建造完成时,它会触发`wula.beaconPlaced`信号。 +- **新定义**: + - `ThingDef`: 一个可打包、可安装的信标建筑,例如`Wula_QuestBuilding_Beacon`,并关联到`Building_QuestBeacon`类。 + +### 2.3. 运送建材 (Deliver Materials) + +**任务描述**: 乌拉族派遣一艘穿梭机降落在玩家基地,玩家需要在限定时间内将指定数量的材料(如钢铁、玻璃钢等)装入穿梭机。装满后穿梭机离开,任务完成。 + +**实现方案**: +- **触发**: 创建`IncidentDef`,`defName: Wula_Incident_DeliverMaterials`。 +- **任务脚本**: 创建`QuestScriptDef`,`defName: Wula_Quest_DeliverMaterials`。 +- **流程图 (Mermaid)**: + ```mermaid + graph TD + A[任务触发: Wula_Incident_DeliverMaterials] --> B[在玩家基地生成穿梭机和任务参数
    (所需材料/数量/时限)]; + B --> C{启动计时器和物品检查器}; + C --> D{玩家装载材料}; + D -- 未装满 --> E{检查是否超时}; + E -- 超时 --> F[任务失败,穿梭机离开]; + D -- 装满 --> G[任务成功,给予奖励]; + G --> H[穿梭机离开]; + ``` +- **关键QuestNode**: + - `QuestNode_Delay`: 用于设置任务时限。 + - `QuestNode_SignalListen`: 监听`wula.materialsDelivered`成功信号或`wula.deliveryFailed`失败信号。 +- **C# 扩展**: + - `QuestNode_WulaShuttleAndChecker`: 一个自定义的`QuestNode`。它的功能是: + 1. 在玩家基地生成一艘穿梭机。 + 2. 初始化任务参数(需要的物品、数量)。 + 3. 启动一个计时器。 + 4. 持续检查穿梭机内的物品数量。 + 5. 当数量满足或时间耗尽时,发送对应的成功/失败信号。 +- **新定义**: + - 无需新的`ThingDef`,将直接使用游戏内已有的材料。 + +## 3. 文件结构 + +- **XML**: + - `1.6/1.6/Defs/IncidentDefs/Wula_ScheduledIncidents.xml`: 添加3个新的`IncidentDef`。 + - `1.6/1.6/Defs/QuestScriptDefs/Wula_ScheduledEvents.xml`: 添加3个新的`QuestScriptDef`。 + - `1.6/1.6/Defs/ThingDefs_Misc/Wula_QuestItems.xml`: 创建一个新的XML文件,用于存放任务相关的物品定义。 +- **C#**: + - `Source/WulaFallenEmpire/Quests/`: 在源码中创建一个`Quests`目录。 + - `Source/WulaFallenEmpire/Quests/Building_QuestBeacon.cs`: “安插信标”任务的建筑逻辑。 + - `Source/WulaFallenEmpire/Quests/QuestNode_WulaShuttleAndChecker.cs`: “运送建材”任务的核心逻辑节点。 +- **语言 (Languages)**: + - `1.6/1.6/Languages/ChineseSimplified/Keyed/Wula_Quest_Keys.xml`: 中文文本。 + - `1.6/1.6/Languages/English/Keyed/Wula_Quest_Keys.xml`: 英文文本。 + +--- +这份文档概述了新任务的完整实现计划。请审阅。 \ No newline at end of file