Files
ArachnaeSwarm/Source/Documents/HiveMind_Design.md
2025-09-01 19:34:25 +08:00

5.6 KiB
Raw Blame History

蜂巢意识Hive Mind系统设计文档 - v2

1. 需求概述

本设计旨在为 ArachnaeSwarm Mod 实现一个“蜂巢意识”系统。该系统包含两种角色:

  • 主节点 (Master):蜂巢的中心。
  • 子节点 (Drone):蜂巢的工蜂,可以有多个。

它们之间通过 Hediff(健康状态)进行链接,实现以下核心功能:

  1. 自动绑定:子节点在生成时,会自动在地图上寻找携带 ARA_HiveMindMaster Hediff 的Pawn作为主节点。如果找到多个则选择第一个进行绑定。如果找不到主节点子节点会立即死亡。
  2. 主从死亡联动:当主节点死亡时,所有与之链接的子节点也会立即死亡。
  3. 链接增益:主节点的力量会随着链接的子节点数量增加而增强。具体表现为主节点的 Hediff 严重性Severity会随着子节点数量的增加而提升为后续添加属性加成提供基础。

2. 技术方案

为了实现上述功能,我们将创建以下组件:

2.1. XML 定义 (使用 ARA_ 前缀)

我们将定义两个新的 HediffDef:

  • HediffDef: ARA_HiveMindMaster
    • hediffClass: ArachnaeSwarm.Hediff_HiveMindMaster
    • 描述: 应用于主节点,用于管理子节点链接并根据数量调整严重性。
  • HediffDef: ARA_HiveMindDrone
    • hediffClass: ArachnaeSwarm.Hediff_HiveMindDrone
    • 描述: 应用于子节点,继承自 HediffWithTarget,其 target 字段将指向主节点。

2.2. C# 类定义 (命名空间: ArachnaeSwarm)

我们将实现两个新的C#类:

  • Hediff_HiveMindMaster

    • 继承自 Hediff
    • 包含一个 List<Pawn> 类型的字段 drones,用于存储所有已链接的子节点。
    • 提供 RegisterDrone(Pawn drone)DeregisterDrone(Pawn drone) 方法,用于添加和移除子节点。
    • 在每次注册/反注册后,更新自身的 Severity 属性,其值等于 drones.Count
    • 重写 PostRemoved() 方法在主节点死亡或Hediff被移除时杀死所有已注册的子节点。
  • Hediff_HiveMindDrone

    • 继承自 HediffWithTarget
    • 重写 PostAdd(DamageInfo? dinfo) 方法。在此方法中:
      1. 在当前地图上扫描所有Pawn查找携带 ARA_HiveMindMaster Hediff 的单位。
      2. 如果找到至少一个,则选择第一个作为 target,并调用其 RegisterDrone 方法将自己注册进去。
      3. 如果找不到任何主节点,立即杀死自己 (pawn.Kill(null, null))。
    • 重写 PostRemoved() 方法,在自身被移除时,如果 target 仍然有效,则调用其 DeregisterDrone 方法将自己从中移除。
    • PostTick() 或类似方法中周期性检查 target(主节点)是否已死亡或 Hediff 已被移除。如果是,则立即杀死自己。

3. 开发步骤 (TODO List)

  • 步骤 1: 创建 XML 定义
    • ArachnaeSwarm/1.6/Defs/HediffDefs/ 目录下创建 ARA_Hediffs_HiveMind.xml 文件。
  • 步骤 2: 实现 C# 类 Hediff_HiveMindMaster
    • ArachnaeSwarm/Source/ArachnaeSwarm/ 目录下创建 Hediff_HiveMindMaster.cs 文件并编写代码。
  • 步骤 3: 实现 C# 类 Hediff_HiveMindDrone
    • ArachnaeSwarm/Source/ArachnaeSwarm/ 目录下创建 Hediff_HiveMindDrone.cs 文件并编写代码。
  • 步骤 4: 更新项目文件
    • 将新创建的 .cs 文件添加到 ArachnaeSwarm.csproj 项目文件中。
  • 步骤 5: 编译和测试
    • 运行 dotnet build 编译项目,修复所有编译错误。
    • 进入游戏进行功能测试。

4. 参考代码

HediffWithTarget.cs

using Verse;

namespace RimWorld
{
    public class HediffWithTarget : HediffWithComps
    {
        public Thing target;

        public override bool ShouldRemove
        {
            get
            {
                if (target != null && !(target is Pawn { Dead: not false }))
                {
                    return base.ShouldRemove;
                }
                return true;
            }
        }

        public override void ExposeData()
        {
            base.ExposeData();
            Scribe_References.Look(ref target, "target");
        }
    }
}

Hediff_PsychicBond.cs

using Verse;

namespace RimWorld
{
    public class Hediff_PsychicBond : HediffWithTarget
    {
        private const int HediffCheckInterval = 65;

        public override string LabelBase => base.LabelBase + " (" + target?.LabelShortCap + ")";

        public override bool ShouldRemove
        {
            get
            {
                if (!base.ShouldRemove)
                {
                    return pawn.Dead;
                }
                return true;
            }
        }

        public override void PostRemoved()
        {
            base.PostRemoved();
            Gene_PsychicBonding gene_PsychicBonding = base.pawn.genes?.GetFirstGeneOfType<Gene_PsychicBonding>();
            if (gene_PsychicBonding != null)
            {
                gene_PsychicBonding.RemoveBond();
            }
            else if (target != null && target is Pawn pawn)
            {
                pawn.genes?.GetFirstGeneOfType<Gene_PsychicBonding>()?.RemoveBond();
            }
        }

        public override void PostTickInterval(int delta)
        {
            base.PostTickInterval(delta);
            if (pawn.IsHashIntervalTick(65, delta))
            {
                Severity = (ThoughtWorker_PsychicBondProximity.NearPsychicBondedPerson(pawn, this) ? 0.5f : 1.5f);
            }
        }
    }
}