From 760ddee0cc824a8a72363f3d97732bd7e1256ead Mon Sep 17 00:00:00 2001 From: "ProjectKoi-Kalo\\Kalo" Date: Thu, 4 Sep 2025 20:40:32 +0800 Subject: [PATCH 1/7] =?UTF-8?q?=E6=9A=82=E5=AD=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 1.6/1.6/Assemblies/ArachnaeSwarm.dll | Bin 62976 -> 68608 bytes .../HediffDefs/ARA_Hediffs_Possession.xml | 19 + 1.6/1.6/Defs/Misc/ARA_Possession_Defs.xml | 166 ++++ Source/ArachnaeSwarm/ArachnaeSwarm.csproj | 6 + .../Possession/CompAbilityEffect_Possess.cs | 33 + .../CompProperties_AbilityPossess.cs | 12 + .../Possession/Hediff_Possession.cs | 90 ++ .../Possession/PawnDataUtility.cs | 106 +++ Source/Documents/Human.xml | 787 ++++++++++++++++++ .../Documents/PawnStorageInHediff_Analysis.md | 188 +++++ .../Possession_Implementation_Guide.md | 569 +++++++++++++ 11 files changed, 1976 insertions(+) create mode 100644 1.6/1.6/Defs/HediffDefs/ARA_Hediffs_Possession.xml create mode 100644 1.6/1.6/Defs/Misc/ARA_Possession_Defs.xml create mode 100644 Source/ArachnaeSwarm/Possession/CompAbilityEffect_Possess.cs create mode 100644 Source/ArachnaeSwarm/Possession/CompProperties_AbilityPossess.cs create mode 100644 Source/ArachnaeSwarm/Possession/Hediff_Possession.cs create mode 100644 Source/ArachnaeSwarm/Possession/PawnDataUtility.cs create mode 100644 Source/Documents/Human.xml create mode 100644 Source/Documents/PawnStorageInHediff_Analysis.md create mode 100644 Source/Documents/Possession_Implementation_Guide.md diff --git a/1.6/1.6/Assemblies/ArachnaeSwarm.dll b/1.6/1.6/Assemblies/ArachnaeSwarm.dll index 84e0e9cb4a40df643f471930bea70fa2b2f515d4..5157529b235c0f00a15906fb4eaa74818da7ae79 100644 GIT binary patch delta 24273 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

%l6co0_`%1zVpuK_y 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 E03`Pw + + + + ARA_Possession + + 这个生物的身体正被另一个实体所控制。 + ArachnaeSwarm.Possession.Hediff_Possession + false + false + 1.0 + +

  • + +
  • + + + + \ No newline at end of file diff --git a/1.6/1.6/Defs/Misc/ARA_Possession_Defs.xml b/1.6/1.6/Defs/Misc/ARA_Possession_Defs.xml new file mode 100644 index 0000000..40efc0a --- /dev/null +++ b/1.6/1.6/Defs/Misc/ARA_Possession_Defs.xml @@ -0,0 +1,166 @@ + + + + + + + ARA_Ability_Possess + + 将你的意识注入另一个生物的身体,完全占据它。 + UI/Abilities/Possess + 600 + + Verb_CastAbility + 1.5 + 5.9 + + true + false + false + false + + + +
  • + + + + + ARA_Facehugger + Humanlike_PostMentalState + 100 + + + + +
  • + Possess + +
  • + + + + + + + + ARA_Facehugger + + ARA_FacehuggerRace + 25 + +
  • + + Things/Pawn/Animal/ARA_Facehugger + 0.8 + + + Things/Pawn/Animal/Dessicated/CritterDessicated + 0.8 + +
  • +
    + ARA_Facehugger + +
  • ARA_Ability_Possess
  • +
    +
    + + + + + ARA_FacehuggerRace + + 一种小型的、脆弱的寄生生物,其唯一的生存目的就是寻找并占据一个更强大的宿主。它通过将自己的意识注入目标来完成这一过程。 + + 4.0 + 50 + -10 + 50 + + +
  • + + +
  • Scratch
  • + + 2 + 1.5 + +
    + + Animal + ARA_FacehuggerBody + 0.2 + 0.3 + 0.1 + +
  • + AnimalAdult + 0 +
  • +
    +
    +
    + + + ARA_FacehuggerBody + + + Body + 20 + 20 + +
  • + Head + 0.3 + +
  • + Skull + 0.2 + Inside + +
  • + Brain + 0.1 + Inside +
  • +
    + +
  • + Eye + left eye + 0.07 +
  • +
  • + Eye + right eye + 0.07 +
  • + + +
  • + Leg + front left leg + 0.1 +
  • +
  • + Leg + front right leg + 0.1 +
  • +
  • + Leg + rear left leg + 0.1 +
  • +
  • + Leg + rear right leg + 0.1 +
  • + +
    +
    + +
    \ No newline at end of file diff --git a/Source/ArachnaeSwarm/ArachnaeSwarm.csproj b/Source/ArachnaeSwarm/ArachnaeSwarm.csproj index fa02310..39029b2 100644 --- a/Source/ArachnaeSwarm/ArachnaeSwarm.csproj +++ b/Source/ArachnaeSwarm/ArachnaeSwarm.csproj @@ -112,6 +112,12 @@ + + + + + + diff --git a/Source/ArachnaeSwarm/Possession/CompAbilityEffect_Possess.cs b/Source/ArachnaeSwarm/Possession/CompAbilityEffect_Possess.cs new file mode 100644 index 0000000..f0e2b8b --- /dev/null +++ b/Source/ArachnaeSwarm/Possession/CompAbilityEffect_Possess.cs @@ -0,0 +1,33 @@ +using RimWorld; +using Verse; + +namespace ArachnaeSwarm.Possession +{ + public class CompAbilityEffect_Possess : CompAbilityEffect + { + public override void Apply(LocalTargetInfo target, LocalTargetInfo dest) + { + base.Apply(target, dest); + + Pawn caster = this.parent.pawn; + Pawn targetPawn = target.Pawn; + + if (targetPawn == null) + { + return; + } + + // Optional: Add checks here. E.g., cannot possess mechanical, already possessed, etc. + // if (targetPawn.RaceProps.IsMechanoid) + // { + // Messages.Message("Cannot possess a mechanoid.", MessageTypeDefOf.RejectInput); + // return; + // } + + Hediff_Possession hediff = (Hediff_Possession)HediffMaker.MakeHediff(HediffDef.Named("ARA_Possession"), targetPawn); + hediff.SetCaster(caster); + + targetPawn.health.AddHediff(hediff); + } + } +} \ No newline at end of file diff --git a/Source/ArachnaeSwarm/Possession/CompProperties_AbilityPossess.cs b/Source/ArachnaeSwarm/Possession/CompProperties_AbilityPossess.cs new file mode 100644 index 0000000..7cea6a7 --- /dev/null +++ b/Source/ArachnaeSwarm/Possession/CompProperties_AbilityPossess.cs @@ -0,0 +1,12 @@ +using RimWorld; + +namespace ArachnaeSwarm.Possession +{ + public class CompProperties_AbilityPossess : CompProperties_AbilityEffect + { + public CompProperties_AbilityPossess() + { + this.compClass = typeof(CompAbilityEffect_Possess); + } + } +} \ No newline at end of file diff --git a/Source/ArachnaeSwarm/Possession/Hediff_Possession.cs b/Source/ArachnaeSwarm/Possession/Hediff_Possession.cs new file mode 100644 index 0000000..7054207 --- /dev/null +++ b/Source/ArachnaeSwarm/Possession/Hediff_Possession.cs @@ -0,0 +1,90 @@ +using System.Collections.Generic; +using RimWorld; +using Verse; + +namespace ArachnaeSwarm.Possession +{ + public class Hediff_Possession : HediffWithComps, IThingHolder + { + private ThingOwner innerContainer; + private Pawn originalCaster; + + public Hediff_Possession() + { + this.innerContainer = new ThingOwner(this, false, LookMode.Deep); + } + + public Pawn StoredCasterPawn => innerContainer.Count > 0 ? innerContainer[0] as Pawn : null; + + public IThingHolder ParentHolder => this.pawn; + + public void GetChildHolders(List outChildren) + { + ThingOwnerUtility.AppendThingHoldersFromThings(outChildren, this.GetDirectlyHeldThings()); + } + + public ThingOwner GetDirectlyHeldThings() + { + return innerContainer; + } + + public override void PostAdd(DamageInfo? dinfo) + { + base.PostAdd(dinfo); + + if (this.originalCaster == null) + { + Log.Error("Hediff_Possession was added without an original caster."); + return; + } + + this.innerContainer.TryAdd(this.originalCaster); + PawnDataUtility.TransferSoul(this.originalCaster, this.pawn); + + if (!this.originalCaster.Destroyed) + { + this.originalCaster.Destroy(DestroyMode.Vanish); + } + + Log.Message($"{this.pawn.LabelShort} has been possessed by {StoredCasterPawn.LabelShort}!"); + } + + public override void Notify_PawnDied(DamageInfo? dinfo, Hediff culprit = null) + { + base.Notify_PawnDied(dinfo, culprit); + + Pawn deadBody = this.pawn; + Pawn storedCaster = this.StoredCasterPawn; + + if (storedCaster == null) + { + Log.Error("Possessed pawn died, but no caster soul was found inside."); + return; + } + + Log.Message($"Host {deadBody.LabelShort} died. Transferring experience back to {storedCaster.LabelShort} and ejecting."); + PawnDataUtility.TransferSoul(deadBody, storedCaster); + this.EjectContents(); + } + + public void SetCaster(Pawn caster) + { + this.originalCaster = caster; + } + + public void EjectContents() + { + if (StoredCasterPawn != null) + { + this.innerContainer.TryDropAll(this.pawn.Position, this.pawn.Map, ThingPlaceMode.Near); + } + } + + public override void ExposeData() + { + base.ExposeData(); + Scribe_Deep.Look(ref innerContainer, "innerContainer", this); + Scribe_References.Look(ref originalCaster, "originalCaster"); + } + } +} \ No newline at end of file diff --git a/Source/ArachnaeSwarm/Possession/PawnDataUtility.cs b/Source/ArachnaeSwarm/Possession/PawnDataUtility.cs new file mode 100644 index 0000000..6b78f42 --- /dev/null +++ b/Source/ArachnaeSwarm/Possession/PawnDataUtility.cs @@ -0,0 +1,106 @@ +using System.Collections.Generic; +using RimWorld; +using Verse; + +namespace ArachnaeSwarm.Possession +{ + public static class PawnDataUtility + { + public static void TransferSoul(Pawn soulSource, Pawn bodyTarget) + { + if (soulSource == null || bodyTarget == null) + { + Log.Error("Cannot transfer soul: source or target is null."); + return; + } + + Log.Message($"Beginning soul transfer from {soulSource.LabelShort} to {bodyTarget.LabelShort}."); + + // Name + bodyTarget.Name = soulSource.Name; + + // Story (Backstory and Traits) + bodyTarget.story.Childhood = soulSource.story.Childhood; + bodyTarget.story.Adulthood = soulSource.story.Adulthood; + bodyTarget.story.traits.allTraits.Clear(); + foreach (Trait trait in soulSource.story.traits.allTraits) + { + bodyTarget.story.traits.GainTrait(trait); + } + + // Skills + bodyTarget.skills.skills.Clear(); + foreach (SkillRecord skill in soulSource.skills.skills) + { + SkillRecord newSkill = new SkillRecord(bodyTarget, skill.def) + { + levelInt = skill.levelInt, + xpSinceLastLevel = skill.xpSinceLastLevel, + passion = skill.passion + }; + bodyTarget.skills.skills.Add(newSkill); + } + + // Faction + if (bodyTarget.Faction != soulSource.Faction) + { + bodyTarget.SetFaction(soulSource.Faction, soulSource); + } + + // Thoughts and Memories + if (bodyTarget.needs.mood?.thoughts?.memories != null) + { + bodyTarget.needs.mood.thoughts.memories.Memories.Clear(); + } + if (soulSource.needs.mood?.thoughts?.memories != null) + { + foreach (Thought_Memory memory in soulSource.needs.mood.thoughts.memories.Memories) + { + bodyTarget.needs.mood.thoughts.memories.TryGainMemory(memory); + } + } + + // Work Settings + if (soulSource.workSettings != null && bodyTarget.workSettings != null) + { + bodyTarget.workSettings.EnableAndInitialize(); + foreach (WorkTypeDef workDef in DefDatabase.AllDefs) + { + bodyTarget.workSettings.SetPriority(workDef, soulSource.workSettings.GetPriority(workDef)); + } + } + + // Timetable + if (soulSource.timetable != null && bodyTarget.timetable != null) + { + bodyTarget.timetable.times = new List(soulSource.timetable.times); + } + + // Social Relations + if (soulSource.relations != null && bodyTarget.relations != null) + { + bodyTarget.relations.ClearAllRelations(); + foreach (DirectPawnRelation relation in soulSource.relations.DirectRelations) + { + bodyTarget.relations.AddDirectRelation(relation.def, relation.otherPawn); + } + } + + // Guest status + if (soulSource.guest != null && bodyTarget.guest != null) + { + bodyTarget.guest.SetGuestStatus(soulSource.guest.HostFaction, soulSource.guest.GuestStatus); + if (soulSource.guest.IsPrisoner) + { + bodyTarget.guest.SetExclusiveInteraction(soulSource.guest.ExclusiveInteractionMode); + } + bodyTarget.guest.joinStatus = soulSource.guest.joinStatus; + } + + // Refresh the UI and game state to reflect the changes. + bodyTarget.Drawer.renderer.SetAllGraphicsDirty(); + + Log.Message("Soul transfer complete."); + } + } +} \ No newline at end of file diff --git a/Source/Documents/Human.xml b/Source/Documents/Human.xml new file mode 100644 index 0000000..2879174 --- /dev/null +++ b/Source/Documents/Human.xml @@ -0,0 +1,787 @@ + + Human + 2 + Human846 + 0 + (146, 0, 131) + 1 + Faction_18 + + 0 + -1 + True + null + -9999999 + + + + + +
  • base
  • +
  • hair
  • +
  • skin
  • +
  • skinBase
  • +
  • tattoo
  • +
  • favorite
  • +
  • ideo
  • +
  • mech
  • +
    + +
  • + RGBA(1.000, 1.000, 1.000, 1.000) + RGBA(1.000, 1.000, 1.000, 1.000) +
  • +
  • + RGBA(0.343, 0.310, 0.288, 1.000) +
  • +
  • + RGBA(1.000, 0.937, 0.788, 1.000) +
  • +
  • + RGBA(1.000, 0.937, 0.788, 1.000) +
  • +
  • + RGBA(1.000, 0.937, 0.788, 0.800) +
  • +
  • + RGBA(0.890, 0.451, 1.000, 1.000) + RGBA(0.890, 0.451, 1.000, 1.000) +
  • +
  • + RGBA(0.600, 0.500, 0.900, 1.000) + RGBA(0.549, 0.458, 0.824, 1.000) +
  • +
  • + RGBA(0.000, 0.737, 0.847, 1.000) +
  • +
    +
    + + + + + 0 + 0 + 0 + 0 +
    + Colonist + Female + + Yue + Moon + Ren + + null + + null + null + null + null + null + (0, 0, 0) + + + + + Idle + 6673 + -99999 + -99999 + True + -99999 + + + + + + + + + + + (-1000, -1000, -1000) + + -99999 + + + + + + + + + + + 0 + 16777 + + + + null + null + null + null + null + GotoWander + 221 + (156, 0, 116) + + + + 1576 + True + + Walk + Humanlike + -1 + null + null + -1 + -1672709817 + + + 0 + -203 + 1576 + null + + + + + -1 + + + + True + + + + + + + + + + True + + + + + + + +
  • + Thing_Human846_0_Smash + (0, 0, 0) + (0, 0, 0) + -999999 + True +
  • +
  • + Thing_Human846_1_Smash + (0, 0, 0) + (0, 0, 0) + -999999 + True +
  • +
  • + Thing_Human846_2_Bite + (0, 0, 0) + (0, 0, 0) + -999999 + True +
  • +
  • + Thing_Human846_3_Smash + (0, 0, 0) + (0, 0, 0) + -999999 + True +
  • +
    +
    + + + + + + + null + + + + + (147, 0, 130) + 48 + 50 + OnCell + 4 + 1777 + 1779 + (156, 0, 116) + + + + 1 + + + + + + +
  • + Apparel_Pants + Apparel_Pants847 + 130 + 1 + Synthread + + -1 + Normal + null + True + +
  • +
  • + Apparel_Parka + Apparel_Parka848 + 235 + 1 + Synthread + + -1 + Normal + null + True + +
  • +
    +
    + + 111 +
    + + Fat + Elisabeth + RGBA(0.343, 0.310, 0.288, 1.000) + + +
  • + SpeedOffset + null + -1 + null +
  • +
  • + Jealous + null + null +
  • +
    +
    + Ren + LightPurple + Female_AveragePointy + WarRefugee51 + MedievalMinstrel95 +
    + + + + + null + + + + + + 139350193 + -297730916 + 1 + 9223372036854775807 + 141208416 + + + + + + + + + + + + + + + +
  • 0
  • +
  • 0
  • +
  • 0
  • +
  • 0
  • +
  • 0
  • +
  • 0
  • +
  • 0
  • +
  • 0
  • +
  • 0
  • +
  • 0
  • +
  • 0
  • +
  • 0
  • +
  • 0
  • +
  • 0
  • +
  • 0
  • +
  • 0
  • +
  • 0
  • +
  • 0
  • +
  • 0
  • +
  • 0
  • +
  • 0
  • +
  • 0
  • +
  • 0
  • +
  • 0
  • +
  • 0
  • +
  • 0
  • +
  • 0
  • +
  • 0
  • +
  • 0
  • +
  • 0
  • +
  • 0
  • +
  • 0
  • +
  • 0
  • +
  • 0
  • +
  • 0
  • +
  • 0
  • +
  • 0
  • +
  • 0
  • +
  • 0
  • +
  • 0
  • +
  • 0
  • +
  • 0
  • +
  • 0
  • +
  • 1840
  • +
  • 0
  • +
  • 0
  • +
  • 0
  • +
  • 0
  • +
  • 0
  • +
  • 0
  • +
  • 0
  • +
  • 0
  • +
  • 0
  • +
  • 0
  • +
  • 0
  • +
  • 0
  • +
  • 0
  • +
  • 0
  • +
  • 0
  • +
  • 0
  • +
  • 0
  • +
  • 0
  • +
  • 0
  • +
  • 0
  • +
  • 0
  • +
  • 0
  • +
  • 0
  • +
  • 0
  • +
  • 0
  • +
  • 0
  • +
    +
    + null +
    + + + + + + + + + Filth_Sand + +
  • + Filth_Sand + Filth_Sand14506 + + -1 +
  • +
    +
    + + null + + + + +
  • + Mood + 0.586400032 + + + +
  • + CrashedTogether + null + Thing_Human849 + 1800 + 25 +
  • +
  • + CrashedTogether + null + Thing_Human852 + 1800 + 25 +
  • +
  • + NewColonyOptimism + null + null + 1800 +
  • +
  • + Chitchat + null + Thing_Human852 + 0.773389459 + 1650 + 0.510437071 +
  • + + + + + 1711 + 1711 + + +
  • + Food + 0.751999915 + 1711 +
  • +
  • + Rest + 0.879273593 +
  • +
  • + Joy + 0.513921499 + + +
  • 0
  • +
  • 0
  • +
  • 0
  • +
  • 0
  • +
  • 0
  • +
  • 0
  • +
  • 0
  • +
  • 0
  • +
  • 0
  • +
  • 0
  • + + + + +
  • False
  • +
  • False
  • +
  • False
  • +
  • False
  • +
  • False
  • +
  • False
  • +
  • False
  • +
  • False
  • +
  • False
  • +
  • False
  • +
    +
    + +
  • + Beauty + 0.442400098 +
  • +
  • + Comfort + 0.47119987 +
  • +
  • + Outdoors + 1 +
  • +
  • + DrugDesire + 0.5 +
  • +
  • + RoomSize + 1 +
  • +
    +
    + + null + null + JoinAsColonist + MaintainOnly + NoInteraction + (-1000, -1000, -1000) + -1 + null + False + + + + + + + + + + + + + + + + + + + + + + + + +
  • + ExSpouse + Thing_Human849 +
  • +
  • + Parent + Thing_Human853 +
  • +
  • + Parent + Thing_Human857 +
  • +
    + + null + + + + + -1 +
    + + True + + + + null + null + null + null + null + + + Chitchat + 121 + Chitchat + + + +
  • + Shooting + 3 +
  • +
  • + Melee + 5 +
  • +
  • + Construction + 2 +
  • +
  • + Mining + 2 +
  • +
  • + Cooking + 7 +
  • +
  • + Plants + 1 +
  • +
  • + Animals + 3 + Minor +
  • +
  • + Crafting + 3 +
  • +
  • + Artistic + 5 + Minor +
  • +
  • + Medicine + 2 + Minor +
  • +
  • + Social + 7 + Major +
  • +
  • + Intellectual +
  • +
    + -1 +
    + + + + + Ideo_10 + + 0.605378687 + + + + + +
  • 3
  • +
  • 3
  • +
  • 0
  • +
  • 3
  • +
  • 3
  • +
  • 3
  • +
  • 0
  • +
  • 0
  • +
  • 0
  • +
  • 0
  • +
  • 0
  • +
  • 0
  • +
  • 0
  • +
  • 0
  • +
  • 0
  • +
  • 0
  • +
  • 0
  • +
  • 0
  • +
  • 3
  • +
  • 0
  • +
  • 3
  • +
  • 0
  • +
  • 0
  • +
    +
    +
    + + + ApparelPolicy_任意_1 + + + + + + DrugPolicy_社交成瘾品_1 + + + + null + + + + +
  • Sleep
  • +
  • Sleep
  • +
  • Sleep
  • +
  • Sleep
  • +
  • Sleep
  • +
  • Sleep
  • +
  • Anything
  • +
  • Anything
  • +
  • Anything
  • +
  • Anything
  • +
  • Anything
  • +
  • Anything
  • +
  • Anything
  • +
  • Anything
  • +
  • Anything
  • +
  • Anything
  • +
  • Anything
  • +
  • Anything
  • +
  • Anything
  • +
  • Anything
  • +
  • Anything
  • +
  • Anything
  • +
  • Sleep
  • +
  • Sleep
  • +
    +
    + + Best + + + + + null + 1 + + + + + + + + + + + + + + + + + + + + + + + +
  • + Skin_Melanin3 + Thing_Human846 + null + 132 +
  • +
  • + Hair_MidBlack + Thing_Human846 + null + 133 +
  • +
    + Baseliner +
    + + + null + + + + +
    \ No newline at end of file diff --git a/Source/Documents/PawnStorageInHediff_Analysis.md b/Source/Documents/PawnStorageInHediff_Analysis.md new file mode 100644 index 0000000..62cdef5 --- /dev/null +++ b/Source/Documents/PawnStorageInHediff_Analysis.md @@ -0,0 +1,188 @@ +# RimWorld Modding: 利用Hediff存储Pawn的深度解析 + +在RimWorld的Mod开发中,有时需要将一个`Pawn`(人物、动物等)从游戏世界中临时移除,并将其数据完整保存起来,之后再释放回游戏中。一个非常精妙且强大的实现方式就是让`Hediff`(健康效果)扮演一个“容器”的角色。 + +本文档将以`HediffAbility_PaintedSkin`为例,深入剖析其实现`Pawn`存储的核心机制。 + +## 核心概念 + +该功能主要依赖于RimWorld框架中的两个核心组件: + +1. **`IThingHolder`接口**: 一个对象(如建筑、Hediff、Pawn的装备栏等)如果实现了这个接口,就等于向游戏声明:“我是一个可以容纳其他物品(`Thing`)的容器”。 +2. **`ThingOwner`类**: 这是实现存储功能的“袋子”。它是一个专门用于管理一组`Thing`对象的集合,并负责处理这些物品的保存、加载和所有权关系。 + +## 案例分析: `HediffAbility_PaintedSkin` + +以下是`HediffAbility_PaintedSkin`的完整源代码,它完美地展示了如何利用`Hediff`来存储一个`Pawn`。 + +```csharp +using System; +using System.Collections.Generic; +using RimWorld; +using Verse; +using Verse.AI; +using Verse.Sound; + +namespace RigorMortis +{ + public class HediffAbility_PaintedSkin : HediffWithComps, IHediffAbility, IThingHolder + { + // 1. 核心存储容器 + protected ThingOwner innerContainer; + + private CompYinAndMalevolent compYin; + public Pawn victim; + + // 构造函数:初始化容器 + public HediffAbility_PaintedSkin() + { + // 'this'表示容器的所有者是当前Hediff实例 + // 'LookMode.Deep'是关键,确保能完整保存Pawn的所有数据 + this.innerContainer = new ThingOwner(this, false, LookMode.Deep, true); + } + + // --- IThingHolder 接口实现 --- + + public IThingHolder ParentHolder + { + get + { + // 对于Hediff来说,它的父容器就是持有它的Pawn + return this.pawn; + } + } + + public void GetChildHolders(List outChildren) + { + ThingOwnerUtility.AppendThingHoldersFromThings(outChildren, this.GetDirectlyHeldThings()); + } + + + + public ThingOwner GetDirectlyHeldThings() + { + return this.innerContainer; + } + + // --- 容器内容访问 --- + + public Thing ContainedThing + { + get + { + return this.innerContainer.Count > 0 ? this.innerContainer[0] : null; + } + } + + public Pawn Zombie + { + get + { + // 提供一个便捷的属性来访问被存储的Pawn + return this.ContainedThing as Pawn; + } + } + + public bool HasAnyContents + { + get + { + return this.innerContainer.Count > 0; + } + } + + // --- 存入/取出逻辑 --- + + public virtual bool Accepts(Thing thing) + { + return this.innerContainer.CanAcceptAnyOf(thing, true); + } + + public virtual bool TryAcceptThing(Thing thing, bool allowSpecialEffects = true) + { + if (!this.Accepts(thing)) + { + return false; + } + bool flag; + if (thing.holdingOwner != null) + { + // 将Pawn从当前持有者(通常是地图)转移到我们的容器中 + thing.holdingOwner.TryTransferToContainer(thing, this.innerContainer, thing.stackCount, true); + flag = true; + } + else + { + // 如果Pawn没有持有者(例如是新生成的),直接添加 + flag = this.innerContainer.TryAdd(thing, true); + } + return flag; + } + + public virtual void EjectContents() + { + // 决定在何处释放Pawn + Map map = this.pawn.MapHeld ?? Find.AnyPlayerHomeMap; + IntVec3 cell = (this.pawn.Spawned || (this.pawn.Corpse != null && this.pawn.Corpse.Spawned)) ? this.pawn.PositionHeld : ((this.pawn.CarriedBy != null) ? this.pawn.CarriedBy.PositionHeld : map.Center); + + // 将容器内的所有东西(即被存储的Pawn)扔到地图上 + this.innerContainer.TryDropAll(cell, map, ThingPlaceMode.Direct, null, null, true); + } + + // --- 存档/读档 --- + + public override void ExposeData() + { + base.ExposeData(); + Scribe_References.Look(ref this.victim, "victim", false); + + // 2. 深度保存容器内容 + // 'Scribe_Deep.Look' 会序列化容器内的Pawn的所有数据 + Scribe_Deep.Look(ref this.innerContainer, "innerContainer", new object[] + { + this + }); + + // 兼容性处理:确保旧存档在加载后也能正确初始化容器 + if (Scribe.mode == LoadSaveMode.PostLoadInit) + { + if (this.innerContainer == null) + { + this.innerContainer = new ThingOwner(this, false, LookMode.Deep, true); + } + } + } + + // --- 其他逻辑 --- + // (为了简洁,此处省略了PostTick, End, AbsolutelyKill等与存储机制非直接相关的代码) + // ... + } +} +``` + +## 机制剖析 + +### 1. 声明容器身份 (`IThingHolder`) + +通过在类声明中加入 `IThingHolder`,`HediffAbility_PaintedSkin` 就获得了“容器”的资格。这要求它必须实现接口定义的属性和方法,如 `ParentHolder` 和 `GetDirectlyHeldThings()`。`GetDirectlyHeldThings()` 方法必须返回真正的存储实例,也就是我们的 `innerContainer`。 + +### 2. 初始化存储核心 (`ThingOwner`) + +在构造函数中,我们创建了一个 `ThingOwner` 实例。这里的关键在于 `LookMode.Deep` 参数。 + +* `LookMode.Value`: 只保存简单值类型(如int, float, string)。 +* `LookMode.Reference`: 只保存一个对物体的引用ID。加载时,游戏会尝试在世界中找到这个ID对应的物体。如果物体已被销毁,引用会丢失。**这不适用于存储Pawn**,因为Pawn在被存入容器时已经从世界中移除了。 +* **`LookMode.Deep`**: 这才是我们的选择。它告诉序列化系统:“请将这个物体(`Pawn`)的所有数据——健康、技能、装备、Hediff、人际关系、思想等等——完完整整地打包保存起来。” 当游戏加载时,它会用这些数据重建一个一模一样的`Pawn`实例。 + +### 3. 序列化 (`ExposeData`) + +`ExposeData` 方法是RimWorld存档机制的核心。 + +* `Scribe_Deep.Look(ref this.innerContainer, ...)`: 这行代码是魔法发生的地方。当游戏保存时,`Scribe_Deep` 会深入到 `innerContainer` 内部,并因为我们之前设置了 `LookMode.Deep`,它会对容器里的每一个 `Pawn` 进行递归式的深度保存。 +* 当游戏加载时,`Scribe_Deep` 会读取存档中的数据,重建 `innerContainer`,并利用深度保存的数据重建一个与存入时状态完全一致的 `Pawn`。 + +## 总结 + +通过实现 `IThingHolder` 接口并利用一个配置为 `LookMode.Deep` 的 `ThingOwner` 容器,我们可以将一个 `Hediff` 转变为一个功能强大的、能够随宿主移动的“Pawn胶囊”。这个“胶囊”可以安全地携带一个`Pawn`穿越存档的海洋,确保其数据的完整性和一致性。 + +这项技术是实现诸如吞噬、俘获、传送、特殊休眠仓等高级Mod功能的基石。 \ No newline at end of file diff --git a/Source/Documents/Possession_Implementation_Guide.md b/Source/Documents/Possession_Implementation_Guide.md new file mode 100644 index 0000000..d10dcdc --- /dev/null +++ b/Source/Documents/Possession_Implementation_Guide.md @@ -0,0 +1,569 @@ +# “抱脸虫夺舍”技能实现说明书 (V3 - 最终版) + +## 1. 功能概述 + +本功能实现了一个名为“阿拉克涅寄生”的特殊技能,允许一个特定的“阿拉克涅原虫”(抱脸虫)Pawn将自己的意识(灵魂)注入另一个生物的身体,从而完全占据并控制它。 + +**核心玩法循环:** +1. **夺舍**: 抱脸虫使用技能后,其物理实体消失,其“灵魂”(名字、背景、技能、特性等)将完全覆盖目标的身体。 +2. **成长**: 玩家将控制这个新的身体进行游戏,所有获得的经验、技能和记忆都将积累在这个身体上。 +3. **重生**: 当被夺舍的身体死亡时,抱脸虫的灵魂会带着所有新的成长,从尸体中“重生”,变回一个独立的、更强大的阿拉克涅原虫Pawn,准备寻找下一个宿主。 + +这是一个高风险、高回报的玩法,允许玩家以一种独特的方式延续一个核心角色的“生命”和成长。 + +## 2. 实现流程 + +```mermaid +graph TD + A[抱脸虫] -- 使用“阿拉克涅寄生”技能 --> B(目标Pawn); + B -- 添加 Hediff_Possession --> C{执行灵魂覆盖}; + C -- 1. 存储抱脸虫Pawn的完整数据 --> D[Hediff容器]; + C -- 2. 将抱脸虫的“灵魂”数据覆盖到目标身上 --> E[被夺舍的身体]; + D -- 3. 抱脸虫物理实体消失 --> F([Vanish]); + E -- 玩家控制,积累经验和记忆 --> E; + E -- 受到致命伤害 --> G{身体死亡}; + G -- 触发Hediff.Notify_PawnDied --> H{反向同步成长}; + D -- 获取存储的抱脸虫数据 --> H; + E -- 获取身体上的成长数据 --> H; + H -- 将成长更新到抱脸虫数据上 --> I[更新后的抱脸虫]; + I -- 从Hediff中释放 --> J(更强大的抱脸虫重生); + J -- 等待下一次夺舍 --> A; +``` + +--- + +## 3. 代码详解 + +### 3.1 `CompAbilityEffect_Possess.cs` - 技能效果的起点 + +这是技能被使用时第一个被调用的C#文件。它的职责是创建`Hediff_Possession`并将其附加到目标身上,从而启动整个夺舍流程。 + +```csharp +// 路径: Source/ArachnaeSwarm/Possession/CompAbilityEffect_Possess.cs +using RimWorld; +using Verse; + +namespace ArachnaeSwarm.Possession +{ + // 继承自CompAbilityEffect,这是所有技能效果组件的基类 + public class CompAbilityEffect_Possess : CompAbilityEffect + { + // 当技能成功施放时,游戏会调用这个Apply方法 + public override void Apply(LocalTargetInfo target, LocalTargetInfo dest) + { + base.Apply(target, dest); // 调用基类方法,确保标准流程执行 + + // 获取施法者 (我们的抱脸虫) + Pawn caster = this.parent.pawn; + // 获取目标Pawn + Pawn targetPawn = target.Pawn; + + // 安全检查:如果目标不是一个Pawn,则直接返回 + if (targetPawn == null) + { + return; + } + + // TODO: 在此可以添加更多的限制条件,例如: + // 1. 不能夺舍机械体 + // if (targetPawn.RaceProps.IsMechanoid) { ... } + // 2. 不能夺舍已经被夺舍的目标 + // if (targetPawn.health.hediffSet.HasHediff(HediffDef.Named("ARA_Possession"))) { ... } + + // 步骤1: 创建Hediff实例 + // HediffMaker.MakeHediff会根据XML定义创建一个新的Hediff对象 + Hediff_Possession hediff = (Hediff_Possession)HediffMaker.MakeHediff(HediffDef.Named("ARA_Possession"), targetPawn); + + // 步骤2: 注入施法者灵魂 + // 在Hediff被正式添加到目标身上之前,将施法者的引用传递进去。 + // 这是关键一步,确保Hediff在执行PostAdd逻辑时能知道谁是施法者。 + hediff.SetCaster(caster); + + // 步骤3: 将Hediff添加到目标身上 + // 这会触发Hediff_Possession类中的PostAdd方法,从而启动真正的夺舍逻辑。 + targetPawn.health.AddHediff(hediff); + } + } +} +``` + +### 3.2 `Hediff_Possession.cs` - 夺舍与重生的核心 + +这个Hediff是整个功能的核心。它作为“灵魂容器”,负责存储抱脸虫的本体,并在恰当的时机执行“夺舍”和“重生”的逻辑。 + +```csharp +// 路径: Source/ArachnaeSwarm/Possession/Hediff_Possession.cs +using System.Collections.Generic; +using RimWorld; +using Verse; + +namespace ArachnaeSwarm.Possession +{ + // 继承HediffWithComps以支持组件,并实现IThingHolder接口来表明自己是容器 + public class Hediff_Possession : HediffWithComps, IThingHolder + { + // --- 核心字段 --- + private ThingOwner innerContainer; // 实际存储灵魂(抱脸虫Pawn)的容器 + private Pawn originalCaster; // 临时保存对原始施法者的引用 + + // --- 构造与属性 --- + public Hediff_Possession() + { + // 初始化容器。LookMode.Deep是关键,它能确保Pawn的所有数据都被完整保存。 + this.innerContainer = new ThingOwner(this, false, LookMode.Deep); + } + + // 提供一个方便的只读属性来获取容器中存储的Pawn + public Pawn StoredCasterPawn => innerContainer.Count > 0 ? innerContainer[0] as Pawn : null; + + // --- IThingHolder 接口实现 --- + public IThingHolder ParentHolder => this.pawn; // 容器的父级就是持有该Hediff的Pawn + + public void GetChildHolders(List outChildren) + { + ThingOwnerUtility.AppendThingHoldersFromThings(outChildren, this.GetDirectlyHeldThings()); + } + + public ThingOwner GetDirectlyHeldThings() + { + return innerContainer; + } + + // --- 核心逻辑 --- + + // 当Hediff被成功添加到目标身上后,此方法被自动调用 + public override void PostAdd(DamageInfo? dinfo) + { + base.PostAdd(dinfo); + + if (this.originalCaster == null) + { + Log.Error("Hediff_Possession was added without an original caster."); + return; + } + + // 1. 存储灵魂:将施法者的Pawn对象完整地存入容器 + this.innerContainer.TryAdd(this.originalCaster); + + // 2. 灵魂覆盖:调用工具类,执行数据迁移 + PawnDataUtility.TransferSoul(this.originalCaster, this.pawn); + + // 3. 销毁施法者的物理实体,因为它现在“活”在目标的身体里了 + if (!this.originalCaster.Destroyed) + { + this.originalCaster.Destroy(DestroyMode.Vanish); + } + + Log.Message($"{this.pawn.LabelShort} has been possessed by {StoredCasterPawn.LabelShort}!"); + } + + // 当持有此Hediff的Pawn(即宿主)死亡时,此方法被自动调用 + public override void Notify_PawnDied(DamageInfo? dinfo, Hediff culprit = null) + { + base.Notify_PawnDied(dinfo, culprit); + + Pawn deadBody = this.pawn; + Pawn storedCaster = this.StoredCasterPawn; + + if (storedCaster == null) + { + Log.Error("Possessed pawn died, but no caster soul was found inside."); + return; + } + + Log.Message($"Host {deadBody.LabelShort} died. Transferring experience back to {storedCaster.LabelShort} and ejecting."); + + // 1. 灵魂更新:反向调用工具类,将宿主身体上的成长同步回抱脸虫的灵魂 + PawnDataUtility.TransferSoul(deadBody, storedCaster); + + // 2. 重生:将更新后的抱脸虫灵魂从容器中释放到地图上 + this.EjectContents(); + } + + // --- 公共方法 --- + + // 由CompAbilityEffect调用,用于在添加Hediff前设置施法者 + public void SetCaster(Pawn caster) + { + this.originalCaster = caster; + } + + // 将容器内的东西(抱脸虫)扔到地图上 + public void EjectContents() + { + if (StoredCasterPawn != null) + { + this.innerContainer.TryDropAll(this.pawn.Position, this.pawn.Map, ThingPlaceMode.Near); + } + } + + // --- 存档/读档 --- + public override void ExposeData() + { + base.ExposeData(); + // Scribe_Deep是关键,确保容器内的Pawn被深度保存 + Scribe_Deep.Look(ref innerContainer, "innerContainer", this); + // 保存对原始施法者的引用(虽然它很快会被销毁,但以防万一) + Scribe_References.Look(ref originalCaster, "originalCaster"); + } + } +} +``` + +### 3.3 `PawnDataUtility.cs` - “灵魂”数据迁移的执行者 + +这是一个静态工具类,集中处理所有与Pawn数据复制相关的复杂逻辑,使得其他部分的代码更整洁。 + +```csharp +// 路径: Source/ArachnaeSwarm/Possession/PawnDataUtility.cs +using System.Collections.Generic; +using RimWorld; +using Verse; + +namespace ArachnaeSwarm.Possession +{ + public static class PawnDataUtility + { + // 核心方法:将soulSource的“灵魂”数据转移到bodyTarget上 + public static void TransferSoul(Pawn soulSource, Pawn bodyTarget) + { + if (soulSource == null || bodyTarget == null) + { + Log.Error("Cannot transfer soul: source or target is null."); + return; + } + + Log.Message($"Beginning soul transfer from {soulSource.LabelShort} to {bodyTarget.LabelShort}."); + + // --- 1. 核心身份数据 --- + + // 姓名 + bodyTarget.Name = soulSource.Name; + + // 故事 (背景和特性) + bodyTarget.story.Childhood = soulSource.story.Childhood; + bodyTarget.story.Adulthood = soulSource.story.Adulthood; + // 先清空目标的所有特性,再逐一添加源的特性 + bodyTarget.story.traits.allTraits.Clear(); + foreach (Trait trait in soulSource.story.traits.allTraits) + { + bodyTarget.story.traits.GainTrait(trait); + } + + // 技能 + // 同样地,清空后逐一添加 + bodyTarget.skills.skills.Clear(); + foreach (SkillRecord skill in soulSource.skills.skills) + { + SkillRecord newSkill = new SkillRecord(bodyTarget, skill.def) + { + levelInt = skill.levelInt, + xpSinceLastLevel = skill.xpSinceLastLevel, + passion = skill.passion + }; + bodyTarget.skills.skills.Add(newSkill); + } + + // 阵营 + if (bodyTarget.Faction != soulSource.Faction) + { + bodyTarget.SetFaction(soulSource.Faction, soulSource); + } + + // --- 2. 思想、社交和设定 --- + + // 思想和记忆 + // 清空目标的记忆,然后复制源的记忆 + if (bodyTarget.needs.mood?.thoughts?.memories != null) + { + bodyTarget.needs.mood.thoughts.memories.Memories.Clear(); + } + if (soulSource.needs.mood?.thoughts?.memories != null) + { + foreach (Thought_Memory memory in soulSource.needs.mood.thoughts.memories.Memories) + { + bodyTarget.needs.mood.thoughts.memories.TryGainMemory(memory); + } + } + + // 工作设置 + if (soulSource.workSettings != null && bodyTarget.workSettings != null) + { + bodyTarget.workSettings.EnableAndInitialize(); + foreach (WorkTypeDef workDef in DefDatabase.AllDefs) + { + bodyTarget.workSettings.SetPriority(workDef, soulSource.workSettings.GetPriority(workDef)); + } + } + + // 时间表 + if (soulSource.timetable != null && bodyTarget.timetable != null) + { + bodyTarget.timetable.times = new List(soulSource.timetable.times); + } + + // 社交关系 (简化处理) + // 警告: 直接复制关系可能很危险,这里采用清空再添加直接关系的方式 + if (soulSource.relations != null && bodyTarget.relations != null) + { + bodyTarget.relations.ClearAllRelations(); + foreach (DirectPawnRelation relation in soulSource.relations.DirectRelations) + { + bodyTarget.relations.AddDirectRelation(relation.def, relation.otherPawn); + } + } + + // 访客/囚犯状态 + if (soulSource.guest != null && bodyTarget.guest != null) + { + // 使用游戏提供的标准方法来设置,而不是直接赋值 + bodyTarget.guest.SetGuestStatus(soulSource.guest.HostFaction, soulSource.guest.GuestStatus); + if (soulSource.guest.IsPrisoner) + { + bodyTarget.guest.SetExclusiveInteraction(soulSource.guest.ExclusiveInteractionMode); + } + bodyTarget.guest.joinStatus = soulSource.guest.joinStatus; + } + + // --- 3. 收尾工作 --- + + // 强制刷新Pawn的渲染缓存,确保外观(如名字)能立刻更新 + bodyTarget.Drawer.renderer.SetAllGraphicsDirty(); + + Log.Message("Soul transfer complete."); + } + } +} +``` + +### 3.4 `CompProperties_AbilityPossess.cs` - 技能属性类 + +这是一个简单的属性类,用于将我们的技能效果组件(`CompAbilityEffect_Possess`)连接到XML定义上。 + +```csharp +// 路径: Source/ArachnaeSwarm/Possession/CompProperties_AbilityPossess.cs +using RimWorld; + +namespace ArachnaeSwarm.Possession +{ + // CompProperties类用于在XML中配置Comp组件的参数 + public class CompProperties_AbilityPossess : CompProperties_AbilityEffect + { + public CompProperties_AbilityPossess() + { + // 将这个属性类与我们的技能效果实现类关联起来 + this.compClass = typeof(CompAbilityEffect_Possess); + } + } +} +``` + +--- + +## 4. XML 定义详解 + +### 4.1 `ARA_Hediffs_Possession.xml` - 定义Hediff + +```xml + + + + + + + ARA_Possession + + + + 这个生物的身体正被另一个实体所控制。 + + ArachnaeSwarm.Possession.Hediff_Possession + + false + false + 1.0 + +
  • + +
  • +
    +
    + +
    +``` + +### 4.2 `ARA_Possession_Defs.xml` - 定义技能、种族和身体 + +这个文件定义了技能本身,以及我们的“阿拉克涅原虫”作为一个完整的生物所需的一切。 + +```xml + + + + + + + ARA_Ability_Possess + + 将你的意识注入另一个生物的身体,完全占据它。 + UI/Abilities/Possess + 600 + + Verb_CastAbility + 1.5 + 5.9 + + true + false + false + false + + + + +
  • + + + + + + ARA_Facehugger + Humanlike_PostMentalState + 100 + + + + + + + + + + ARA_Facehugger + + + ARA_FacehuggerRace + 25 + +
  • + + Things/Pawn/Animal/ARA_Facehugger + 0.8 + + + Things/Pawn/Animal/Dessicated/CritterDessicated + 0.8 + +
  • + + ARA_Facehugger + + +
  • ARA_Ability_Possess
  • +
    + + + + + ARA_FacehuggerRace + + 一种小型的、脆弱的寄生生物,其唯一的生存目的就是寻找并占据一个更强大的宿主。它通过将自己的意识注入目标来完成这一过程。 + + 4.0 + 50 + -10 + 50 + + +
  • + + +
  • Scratch
  • + + 2 + 1.5 + +
    + + Animal + + ARA_FacehuggerBody + 0.2 + 0.3 + 0.1 + +
  • + AnimalAdult + 0 +
  • +
    +
    +
    + + + + ARA_FacehuggerBody + + + Body + 20 + 20 + +
  • + Head + 0.3 + +
  • + Skull + 0.2 + Inside + +
  • + Brain + 0.1 + Inside +
  • +
    + +
  • + Eye + left eye + 0.07 +
  • +
  • + Eye + right eye + 0.07 +
  • + + +
  • + Leg + front left leg + 0.1 +
  • +
  • + Leg + front right leg + 0.1 +
  • +
  • + Leg + rear left leg + 0.1 +
  • +
  • + Leg + rear right leg + 0.1 +
  • + +
    +
    + +
    +``` + +--- + +这份详尽的文档现在包含了我们所有的最终代码和XML,并附有详细的注释,解释了每一步的作用和它们之间的关联。 \ No newline at end of file From 0982682cc96993ffdfc7edad3202b8030ecc6abb Mon Sep 17 00:00:00 2001 From: "ProjectKoi-Kalo\\Kalo" Date: Thu, 4 Sep 2025 21:01:54 +0800 Subject: [PATCH 2/7] =?UTF-8?q?=E6=9A=82=E5=AD=982?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 1.6/1.6/Assemblies/ArachnaeSwarm.dll | Bin 68608 -> 70656 bytes .../Defs/AbilityDefs/ARA_Possession_Defs.xml | 27 +++ .../Defs/BackstoryDefs/ARA_BackstoryDef.xml | 16 ++ .../HediffDefs/ARA_Hediffs_Possession.xml | 2 +- 1.6/1.6/Defs/Misc/ARA_Possession_Defs.xml | 166 ------------------ .../ARA_Race_HuggingFaceSwarm.xml | 115 ++++++++++++ .../Possession/CompAbilityEffect_Possess.cs | 2 +- .../CompProperties_AbilityPossess.cs | 2 +- .../Possession/Hediff_Possession.cs | 2 +- .../Possession/PawnDataUtility.cs | 129 +++++++++----- .../Possession_Implementation_Guide.md | 49 ++++++ 11 files changed, 300 insertions(+), 210 deletions(-) create mode 100644 1.6/1.6/Defs/AbilityDefs/ARA_Possession_Defs.xml delete mode 100644 1.6/1.6/Defs/Misc/ARA_Possession_Defs.xml create mode 100644 1.6/1.6/Defs/ThingDef_Races/ARA_Race_HuggingFaceSwarm.xml diff --git a/1.6/1.6/Assemblies/ArachnaeSwarm.dll b/1.6/1.6/Assemblies/ArachnaeSwarm.dll index 5157529b235c0f00a15906fb4eaa74818da7ae79..3f48b6b6ae03ebd462c58731654ce6402cc0bef1 100644 GIT binary patch delta 19019 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 delta 17182 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 + + + + + ARA_Ability_Possess + + 将你的意识注入另一个生物的身体,完全占据它。 + UI/Abilities/Possess + 600 + + Verb_CastAbility + 1.5 + 5.9 + + true + false + false + false + + + +
  • + + + + \ No newline at end of file diff --git a/1.6/1.6/Defs/BackstoryDefs/ARA_BackstoryDef.xml b/1.6/1.6/Defs/BackstoryDefs/ARA_BackstoryDef.xml index ad5604f..596747c 100644 --- a/1.6/1.6/Defs/BackstoryDefs/ARA_BackstoryDef.xml +++ b/1.6/1.6/Defs/BackstoryDefs/ARA_BackstoryDef.xml @@ -97,4 +97,20 @@
  • ArachnaeNode_spawnCategories_WeaponSmith
  • + + + Arachnae_Node_BS_Adult_Facehugger + 阿拉克涅原虫种 + 原虫种 + [PAWN_nameDef]是一只阿拉克涅原虫种督虫。[PAWN_nameDef]通过独特的神经链接管伸入受害者身体来接管受害者的身体。不同于普通阿拉克涅虫族,阿拉克涅原虫种拥有自我意识,不需要女皇种的监管。 + Adulthood + Cooking + + + + + +
  • ArachnaeNode_spawnCategories_Facehugger
  • +
    +
    \ No newline at end of file diff --git a/1.6/1.6/Defs/HediffDefs/ARA_Hediffs_Possession.xml b/1.6/1.6/Defs/HediffDefs/ARA_Hediffs_Possession.xml index 095afb3..6dfe6f3 100644 --- a/1.6/1.6/Defs/HediffDefs/ARA_Hediffs_Possession.xml +++ b/1.6/1.6/Defs/HediffDefs/ARA_Hediffs_Possession.xml @@ -5,7 +5,7 @@ ARA_Possession 这个生物的身体正被另一个实体所控制。 - ArachnaeSwarm.Possession.Hediff_Possession + ArachnaeSwarm.Hediff_Possession false false 1.0 diff --git a/1.6/1.6/Defs/Misc/ARA_Possession_Defs.xml b/1.6/1.6/Defs/Misc/ARA_Possession_Defs.xml deleted file mode 100644 index 40efc0a..0000000 --- a/1.6/1.6/Defs/Misc/ARA_Possession_Defs.xml +++ /dev/null @@ -1,166 +0,0 @@ - - - - - - - ARA_Ability_Possess - - 将你的意识注入另一个生物的身体,完全占据它。 - UI/Abilities/Possess - 600 - - Verb_CastAbility - 1.5 - 5.9 - - true - false - false - false - - - -
  • - - - - - ARA_Facehugger - Humanlike_PostMentalState - 100 - - - - -
  • - Possess - -
  • - - - - - - - - ARA_Facehugger - - ARA_FacehuggerRace - 25 - -
  • - - Things/Pawn/Animal/ARA_Facehugger - 0.8 - - - Things/Pawn/Animal/Dessicated/CritterDessicated - 0.8 - -
  • -
    - ARA_Facehugger - -
  • ARA_Ability_Possess
  • -
    -
    - - - - - ARA_FacehuggerRace - - 一种小型的、脆弱的寄生生物,其唯一的生存目的就是寻找并占据一个更强大的宿主。它通过将自己的意识注入目标来完成这一过程。 - - 4.0 - 50 - -10 - 50 - - -
  • - - -
  • Scratch
  • - - 2 - 1.5 - -
    - - Animal - ARA_FacehuggerBody - 0.2 - 0.3 - 0.1 - -
  • - AnimalAdult - 0 -
  • -
    -
    -
    - - - ARA_FacehuggerBody - - - Body - 20 - 20 - -
  • - Head - 0.3 - -
  • - Skull - 0.2 - Inside - -
  • - Brain - 0.1 - Inside -
  • -
    - -
  • - Eye - left eye - 0.07 -
  • -
  • - Eye - right eye - 0.07 -
  • - - -
  • - Leg - front left leg - 0.1 -
  • -
  • - Leg - front right leg - 0.1 -
  • -
  • - Leg - rear left leg - 0.1 -
  • -
  • - Leg - rear right leg - 0.1 -
  • - -
    -
    - -
    \ No newline at end of file diff --git a/1.6/1.6/Defs/ThingDef_Races/ARA_Race_HuggingFaceSwarm.xml b/1.6/1.6/Defs/ThingDef_Races/ARA_Race_HuggingFaceSwarm.xml new file mode 100644 index 0000000..220a030 --- /dev/null +++ b/1.6/1.6/Defs/ThingDef_Races/ARA_Race_HuggingFaceSwarm.xml @@ -0,0 +1,115 @@ + + + + + + ArachnaeNode_Race_Facehugger + + ArachnaeNode_Race_Facehugger + PlayerColony + 0 + +
  • + +
  • ArachnaeNode_spawnCategoriesA
  • +
  • ArachnaeNode_spawnCategories_Facehugger
  • + + +
    + +
  • ARA_Facehugger
  • +
    + + + 0 +
    + + + + ArachnaeNode_Race_Facehugger + + 阿拉克涅原虫,通过独特的神经链接管伸入受害者身体来接管受害者的身体。不同于普通阿拉克涅虫族,阿拉克涅原虫种拥有自我意识,不需要女皇种的监管。 + + + + + + +
  • + ArachnaeSwarm/Things/ARA_HiveNode/Addons/ArachnaeNode_Race_Myrmecocystus_Addons_Stomach + false + +
  • +
    +
    +
    + + + + + +
  • ARA_InsectJelly
  • +
    + false +
    +
    + +
  • + ARA_InsectJelly + 3 + 4 +
  • +
    + + + + + 2 + + + + 5 + 1 + + 100 + 70 + 10 + + 0.5 + + + + + + + + + 0.18 + 0.27 + 0.2 + + + + OmnivoreHuman,CarnivoreAnimal,OvivoreAnimal,VegetarianRoughAnimal + + ArachnaeMyrmecocystus_Body + + 2.5 + + 3 + + 1.5 + +
  • + ArachnaeNode_Myrmecocystus_Adult + 0 +
  • +
    +
    +
    + +
    \ No newline at end of file diff --git a/Source/ArachnaeSwarm/Possession/CompAbilityEffect_Possess.cs b/Source/ArachnaeSwarm/Possession/CompAbilityEffect_Possess.cs index f0e2b8b..f9f7f4e 100644 --- a/Source/ArachnaeSwarm/Possession/CompAbilityEffect_Possess.cs +++ b/Source/ArachnaeSwarm/Possession/CompAbilityEffect_Possess.cs @@ -1,7 +1,7 @@ using RimWorld; using Verse; -namespace ArachnaeSwarm.Possession +namespace ArachnaeSwarm { public class CompAbilityEffect_Possess : CompAbilityEffect { diff --git a/Source/ArachnaeSwarm/Possession/CompProperties_AbilityPossess.cs b/Source/ArachnaeSwarm/Possession/CompProperties_AbilityPossess.cs index 7cea6a7..b4402d0 100644 --- a/Source/ArachnaeSwarm/Possession/CompProperties_AbilityPossess.cs +++ b/Source/ArachnaeSwarm/Possession/CompProperties_AbilityPossess.cs @@ -1,6 +1,6 @@ using RimWorld; -namespace ArachnaeSwarm.Possession +namespace ArachnaeSwarm { public class CompProperties_AbilityPossess : CompProperties_AbilityEffect { diff --git a/Source/ArachnaeSwarm/Possession/Hediff_Possession.cs b/Source/ArachnaeSwarm/Possession/Hediff_Possession.cs index 7054207..34c6e0f 100644 --- a/Source/ArachnaeSwarm/Possession/Hediff_Possession.cs +++ b/Source/ArachnaeSwarm/Possession/Hediff_Possession.cs @@ -2,7 +2,7 @@ using System.Collections.Generic; using RimWorld; using Verse; -namespace ArachnaeSwarm.Possession +namespace ArachnaeSwarm { public class Hediff_Possession : HediffWithComps, IThingHolder { diff --git a/Source/ArachnaeSwarm/Possession/PawnDataUtility.cs b/Source/ArachnaeSwarm/Possession/PawnDataUtility.cs index 6b78f42..39f2318 100644 --- a/Source/ArachnaeSwarm/Possession/PawnDataUtility.cs +++ b/Source/ArachnaeSwarm/Possession/PawnDataUtility.cs @@ -1,8 +1,9 @@ using System.Collections.Generic; +using System.Linq; using RimWorld; using Verse; -namespace ArachnaeSwarm.Possession +namespace ArachnaeSwarm { public static class PawnDataUtility { @@ -16,43 +17,59 @@ namespace ArachnaeSwarm.Possession Log.Message($"Beginning soul transfer from {soulSource.LabelShort} to {bodyTarget.LabelShort}."); - // Name + // --- 1. Core Identity --- bodyTarget.Name = soulSource.Name; - - // Story (Backstory and Traits) bodyTarget.story.Childhood = soulSource.story.Childhood; bodyTarget.story.Adulthood = soulSource.story.Adulthood; - bodyTarget.story.traits.allTraits.Clear(); - foreach (Trait trait in soulSource.story.traits.allTraits) + + if (bodyTarget.story.traits != null) bodyTarget.story.traits.allTraits.Clear(); + if (soulSource.story.traits != null) { - bodyTarget.story.traits.GainTrait(trait); + foreach (Trait trait in soulSource.story.traits.allTraits) + { + bodyTarget.story.traits.GainTrait(trait); + } } - // Skills - bodyTarget.skills.skills.Clear(); - foreach (SkillRecord skill in soulSource.skills.skills) - { - SkillRecord newSkill = new SkillRecord(bodyTarget, skill.def) - { - levelInt = skill.levelInt, - xpSinceLastLevel = skill.xpSinceLastLevel, - passion = skill.passion - }; - bodyTarget.skills.skills.Add(newSkill); - } - - // Faction if (bodyTarget.Faction != soulSource.Faction) { bodyTarget.SetFaction(soulSource.Faction, soulSource); } - // Thoughts and Memories - if (bodyTarget.needs.mood?.thoughts?.memories != null) + // --- 2. Growth & Experience --- + if (bodyTarget.skills != null) bodyTarget.skills.skills.Clear(); + if (soulSource.skills != null) + { + foreach (SkillRecord skill in soulSource.skills.skills) + { + SkillRecord newSkill = new SkillRecord(bodyTarget, skill.def) + { + levelInt = skill.levelInt, + xpSinceLastLevel = skill.xpSinceLastLevel, + passion = skill.passion + }; + bodyTarget.skills.skills.Add(newSkill); + } + } + + if (bodyTarget.records != null && soulSource.records != null) + { + foreach (RecordDef recordDef in DefDatabase.AllDefs) + { + // Correct way: Get value from source and add the difference to target. + // This effectively sets the value. + float sourceValue = soulSource.records.GetValue(recordDef); + float targetValue = bodyTarget.records.GetValue(recordDef); + bodyTarget.records.AddTo(recordDef, sourceValue - targetValue); + } + } + + // --- 3. Mind & Settings --- + if (bodyTarget.needs?.mood?.thoughts?.memories != null) { bodyTarget.needs.mood.thoughts.memories.Memories.Clear(); } - if (soulSource.needs.mood?.thoughts?.memories != null) + if (soulSource.needs?.mood?.thoughts?.memories != null) { foreach (Thought_Memory memory in soulSource.needs.mood.thoughts.memories.Memories) { @@ -60,7 +77,6 @@ namespace ArachnaeSwarm.Possession } } - // Work Settings if (soulSource.workSettings != null && bodyTarget.workSettings != null) { bodyTarget.workSettings.EnableAndInitialize(); @@ -70,34 +86,67 @@ namespace ArachnaeSwarm.Possession } } - // Timetable if (soulSource.timetable != null && bodyTarget.timetable != null) { bodyTarget.timetable.times = new List(soulSource.timetable.times); } - // Social Relations + if (soulSource.playerSettings != null && bodyTarget.playerSettings != null) + { + bodyTarget.playerSettings.hostilityResponse = soulSource.playerSettings.hostilityResponse; + bodyTarget.playerSettings.medCare = soulSource.playerSettings.medCare; + bodyTarget.playerSettings.selfTend = soulSource.playerSettings.selfTend; + } + + if (soulSource.outfits != null && bodyTarget.outfits != null) bodyTarget.outfits.CurrentApparelPolicy = soulSource.outfits.CurrentApparelPolicy; + if (soulSource.drugs != null && bodyTarget.drugs != null) bodyTarget.drugs.CurrentPolicy = soulSource.drugs.CurrentPolicy; + if (soulSource.foodRestriction != null && bodyTarget.foodRestriction != null) bodyTarget.foodRestriction.CurrentFoodPolicy = soulSource.foodRestriction.CurrentFoodPolicy; + // Ownership is claimed on the Building, not the pawn. We can't directly transfer this. + // if (soulSource.ownership != null && bodyTarget.ownership != null) + // { + // // This requires finding the bed and calling bed.SetOwner(pawn) + // } + + + // --- 4. DLC & Social --- + if (ModsConfig.IdeologyActive && soulSource.ideo != null && bodyTarget.ideo != null) + { + bodyTarget.ideo.SetIdeo(soulSource.ideo.Ideo); + // Can't set certainty directly, but setting the ideo resets it. + } + + if (ModsConfig.RoyaltyActive && soulSource.royalty != null && bodyTarget.royalty != null) + { + // Clear existing royalty status from the target body + bodyTarget.royalty.AllTitlesForReading.Clear(); + + // Transfer titles + foreach(var title in soulSource.royalty.AllTitlesForReading) + { + bodyTarget.royalty.SetTitle(title.faction, title.def, true, false, false); + } + // Transfer permits + if(soulSource.royalty.AllFactionPermits != null) + { + foreach (var permit in soulSource.royalty.AllFactionPermits) + { + bodyTarget.royalty.AddPermit(permit.Permit, permit.Faction); + } + } + // Abilities are handled by the titles and should update automatically. + bodyTarget.royalty.UpdateAvailableAbilities(); + } + if (soulSource.relations != null && bodyTarget.relations != null) { bodyTarget.relations.ClearAllRelations(); - foreach (DirectPawnRelation relation in soulSource.relations.DirectRelations) + foreach (DirectPawnRelation relation in soulSource.relations.DirectRelations.Where(r => !r.def.familyByBloodRelation).ToList()) { bodyTarget.relations.AddDirectRelation(relation.def, relation.otherPawn); } } - // Guest status - if (soulSource.guest != null && bodyTarget.guest != null) - { - bodyTarget.guest.SetGuestStatus(soulSource.guest.HostFaction, soulSource.guest.GuestStatus); - if (soulSource.guest.IsPrisoner) - { - bodyTarget.guest.SetExclusiveInteraction(soulSource.guest.ExclusiveInteractionMode); - } - bodyTarget.guest.joinStatus = soulSource.guest.joinStatus; - } - - // Refresh the UI and game state to reflect the changes. + // --- 5. Finalization --- bodyTarget.Drawer.renderer.SetAllGraphicsDirty(); Log.Message("Soul transfer complete."); diff --git a/Source/Documents/Possession_Implementation_Guide.md b/Source/Documents/Possession_Implementation_Guide.md index d10dcdc..e69425b 100644 --- a/Source/Documents/Possession_Implementation_Guide.md +++ b/Source/Documents/Possession_Implementation_Guide.md @@ -37,6 +37,55 @@ graph TD ### 3.1 `CompAbilityEffect_Possess.cs` - 技能效果的起点 这是技能被使用时第一个被调用的C#文件。它的职责是创建`Hediff_Possession`并将其附加到目标身上,从而启动整个夺舍流程。 +## 3. 最终数据迁移规范 (Final Data Transfer Specification) + +通过对真实存档文件 (`Human.xml`) 的深度分析,我们最终确定了“灵魂”与“肉体”的数据边界。`PawnDataUtility.TransferSoul` 方法将严格遵循以下规范进行数据迁移: + +### 3.1 必须复制的“灵魂”数据 + +这些数据定义了Pawn的身份、经历、思想和核心能力,将**完全从抱脸虫(源)复制到宿主(目标)**。 + +- **核心身份 (`Name`, `Story`, `Faction`)**: + - `Name`: 姓名与昵称。 + - `Story`: 童年和成年背景 (`Childhood`, `Adulthood`)。 + - `Traits`: 所有特性。 + - `Faction`: 所属阵营。 +- **成长与经历 (`Skills`, `Records`)**: + - `Skills`: 所有技能的等级、经验和热情。 + - `Records`: 全部生平记录 (如击杀数、建造数等)。 +- **思想与设定 (`Needs`, `WorkSettings`, etc.)**: + - `Needs`: 主要是指`thoughts.memories` (思想和记忆)。 + - `WorkSettings`: 工作优先级。 + - `Timetable`: 时间表。 + - `PlayerSettings`: 玩家设定 (如医疗策略)。 + - `Ownership`: 对床、王座等的所有权。 + - `Outfits` & `Drugs`: 穿着和药物策略。 + - `FoodRestriction`: 食物策略。 +- **DLC核心数据 (`Ideo`, `Royalty`)**: + - `Ideo`: 完整的信仰体系。 + - `Royalty`: 完整的贵族系统,包括头衔、恩惠、许可、灵能和相关技能 (`abilities`)。 +- **社交 (`Relations`)**: + - 将采用**简化处理**:清空目标的旧关系,然后只复制源的**非亲属**直接关系 (如朋友、对手、爱人)。这可以避免破坏家族树。 + +### 3.2 必须保留的“肉体”数据 + +这些数据属于物理身体的范畴,在夺舍过程中将**完全保留宿主原有的数据**,不进行任何复制。 + +- **健康与生理 (`Health`, `Age`)**: + - `Health`: 所有伤口、疤痕、疾病和植入物。 + - `Age`: 生物年龄和时间年龄。 +- **外观与基因 (`Style`, `Genes`, `BodyType`)**: + - `Style`: 发型、胡须、纹身。 + - `Genes`: 所有内生和异种基因。 + - `BodyType`, `HeadType`, `HairColor`: 身体类型、头型和发色。 +- **装备与物品 (`Apparel`, `Equipment`, `Inventory`)**: + - `Apparel`: 身上穿着的衣物。 + - `Equipment`: 手中持有的装备。 + - `Inventory`: 物品栏中的物品。 +- **物理状态 (`Position`, `Stances`, `Pather`)**: + - Pawn在世界中的位置、姿态和寻路信息。 + +--- ```csharp // 路径: Source/ArachnaeSwarm/Possession/CompAbilityEffect_Possess.cs From 3df5314d4e09a40cbb9257786181972e1b0d3bb4 Mon Sep 17 00:00:00 2001 From: "ProjectKoi-Kalo\\Kalo" Date: Thu, 4 Sep 2025 21:12:22 +0800 Subject: [PATCH 3/7] =?UTF-8?q?=E6=9A=82=E5=AD=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 1.6/1.6/Assemblies/ArachnaeSwarm.dll | Bin 70656 -> 70656 bytes .../Defs/AbilityDefs/ARA_Possession_Defs.xml | 4 ++-- .../Defs/ThingDef_Races/ARA_RaceNodeSwarm.xml | 2 +- .../ARA_Race_HuggingFaceSwarm.xml | 2 +- .../Possession/Hediff_Possession.cs | 6 ++++-- 5 files changed, 8 insertions(+), 6 deletions(-) diff --git a/1.6/1.6/Assemblies/ArachnaeSwarm.dll b/1.6/1.6/Assemblies/ArachnaeSwarm.dll index 3f48b6b6ae03ebd462c58731654ce6402cc0bef1..58a9ee56b1c3a225f453243a3453bfdec2f16cc1 100644 GIT binary patch delta 1590 zcmY+EUu+ar6o-FzcDq=LK$UbV-IqppS%_#$DkKIWgtS&?rY&|W!_JH^CPENHz?4=R zm@V5Dh?sP<@lPs(ff$PV0NEzhKw^oB_QCY6p-~gF>Jup`M2JRf;GTOA?6S#j^5wg8 zf9KqLX0zkb?09taMD)tZv7hs&;-W2oai_Rb5MoW$+**Nnq0xA@uuH5Fc41J2wW)Oi z^l6u0169~ptTisYB2E{+wbnh^XAB$wqQ<~M`D^Z<7Fb%iWxZ8&?Wq?+e=j}v1J1+} zOSYq=Xapyp=`>m~&$McN3~hM+ZM`y6MYKoJM@Tjdn{AkvThlH#HzLxG%)3M*_0!21 zUd5Y_(2<8Er28aPSQ6J)#9(2L>HC&ONvU4iW)Ra6a;=I=)h{(K3JZ=VG5j34G&^fU zlO&(rJBbfW3tutilG~*#D$=D{xY`?*E447KWDZXov}x0!2Tn+`73o54oMNIvZDjk) zh1&R3QK|Y`^M|I5^O{tlHojy>h1!_t2j!Q<-Ncw&8hMYlDG937MvWq>R7gs)qjPeQ zVxo8lzi6rso6nmL{$NKZ>}EwG)`5u%*NG{1x5bp%iDd)jgf7$*g*+x*XjC$XG5lzDVJ*`F z&eiR}CZ-xmuc1|uF0C6K4_xG2T{qsSaB1vjx5bz-)99;kJ;*8wbNENf9*pwRm6Be^ z=MR?(?8H??`tDsUGST6?cDRuEaFQvP8 zQBb6>!o^udx?dOLigGw(%*y93F%5}Xa~Hm;See1KN9ZSBNyD8%%TX$Oq&}qa%AiZ3 z?$E<16LshzJy`D0!+u42x;^x1QXP6Y%8okpaDp8Tw}uC8Si0{B~7=F z&BrLPBq-iTHdl`K@tLAhb{%W=HWpCfIFD{w`Pk%|!7&?kS=Z4TZ$j zLpqS+1H_pqKER)v)XNoMo*lhh0sdk~fdLlT(aRNJ>#*LF0t39PNMC4xZbj-sqf+|C z{PF*Guk1ZMv+7tf)p?~M+%eRj>?xjJNXH+K^FKT7w(;ZtYea)cO+K|u+!m9|my3TR QM*EACwNHozk#AaZADTjJbN~PV delta 1590 zcmY+EZD>N|}N?&pD4K1{(PF_uTV; zo^#Gk_pqmX*z?^X&*a8M&jts|#OlG3X7MB?L}mV+DuJ?8g|Rf%A}U3Fsz1|H zsh58S^07T#Y@FL5j;F4K7th^obnXT`M(5Y^JM}WW%>dGI>&C~fy@MXQh11?ZK^^WX z>c?S!)L4rtrUf5*u?|ai>dMx9qBcdx5iIR9*I`PoORGFyfxLQbZ71sYjR(DGz~}GL z-ghLV``%TU5qIZ%5yl;+-eVGAHiKs zg>LoFW(4=y(auEhFFOj1;0e2nfe~4`Y#%5;BPcL}RT6bl zBP}0n$#IQnV>clJ-bRe(xG1i&dn#_2QOxShCd9CS$mMGiL%EVkoWvhy3<0KT43%ue zGN##*HlbFLZf!Ff-nzV@lFew%aZUJw-Dk#avkC1vZVS2;xk=1Oxdj7US|n*JPQ5D? zXvSqldh>0}Fwy4Q@a(6V^d+@Xp-5j+8&#Ur+1m)Qqoc5~Qj;s_mfASTrF0ZFjw;ee zVdF%obeAscgly_h_6e>2kLsbb#9K_qpRiA<uv3w~-45C{sRfX8Sh|*CH)G-vGQ9A z%m|8)qbr$>kK+eLnZnsMlV%)0X;SfV46~#7I7Zpk1|Q1G=S&nI$16p&qppxx(yIe0 zJ^>#S#V7DUlX|%lm|{mSR|3=QC@_H;cJy*3u&Ph5Nr4H}Dbfd;Kva=BP>+;$`q;r& zUlz@3__OFuXnS<@t49xam`-#0>~vGvTp$0e(`q#*#2is7{A1;F#8WXC@{G-!C;rPb P)_gKn{DGL3|0(z%x@BtJ diff --git a/1.6/1.6/Defs/AbilityDefs/ARA_Possession_Defs.xml b/1.6/1.6/Defs/AbilityDefs/ARA_Possession_Defs.xml index 993203b..90e4371 100644 --- a/1.6/1.6/Defs/AbilityDefs/ARA_Possession_Defs.xml +++ b/1.6/1.6/Defs/AbilityDefs/ARA_Possession_Defs.xml @@ -6,8 +6,8 @@ ARA_Ability_Possess 将你的意识注入另一个生物的身体,完全占据它。 - UI/Abilities/Possess - 600 + UI/Commands/EggSpew + 600 Verb_CastAbility 1.5 diff --git a/1.6/1.6/Defs/ThingDef_Races/ARA_RaceNodeSwarm.xml b/1.6/1.6/Defs/ThingDef_Races/ARA_RaceNodeSwarm.xml index f22c796..94bfddf 100644 --- a/1.6/1.6/Defs/ThingDef_Races/ARA_RaceNodeSwarm.xml +++ b/1.6/1.6/Defs/ThingDef_Races/ARA_RaceNodeSwarm.xml @@ -522,7 +522,7 @@ - +
  • diff --git a/1.6/1.6/Defs/ThingDef_Races/ARA_Race_HuggingFaceSwarm.xml b/1.6/1.6/Defs/ThingDef_Races/ARA_Race_HuggingFaceSwarm.xml index 220a030..f6ca2c5 100644 --- a/1.6/1.6/Defs/ThingDef_Races/ARA_Race_HuggingFaceSwarm.xml +++ b/1.6/1.6/Defs/ThingDef_Races/ARA_Race_HuggingFaceSwarm.xml @@ -17,7 +17,7 @@
  • -
  • ARA_Facehugger
  • +
  • ARA_Ability_Possess
  • diff --git a/Source/ArachnaeSwarm/Possession/Hediff_Possession.cs b/Source/ArachnaeSwarm/Possession/Hediff_Possession.cs index 34c6e0f..8f8c5b9 100644 --- a/Source/ArachnaeSwarm/Possession/Hediff_Possession.cs +++ b/Source/ArachnaeSwarm/Possession/Hediff_Possession.cs @@ -38,7 +38,9 @@ namespace ArachnaeSwarm return; } - this.innerContainer.TryAdd(this.originalCaster); + // 正确的做法:从原始施法者身上“分裂”出一个副本存入容器 + // 这确保了容器里的是一个独立的对象,而不是一个会被销毁的引用 + this.innerContainer.TryAdd(this.originalCaster.SplitOff(1), true); PawnDataUtility.TransferSoul(this.originalCaster, this.pawn); if (!this.originalCaster.Destroyed) @@ -84,7 +86,7 @@ namespace ArachnaeSwarm { base.ExposeData(); Scribe_Deep.Look(ref innerContainer, "innerContainer", this); - Scribe_References.Look(ref originalCaster, "originalCaster"); + Scribe_References.Look(ref originalCaster, "originalCaster", false); } } } \ No newline at end of file From 00d43cfba388a87e4df8b455c129edaa9b0c8f2e Mon Sep 17 00:00:00 2001 From: "ProjectKoi-Kalo\\Kalo" Date: Thu, 4 Sep 2025 22:21:01 +0800 Subject: [PATCH 4/7] =?UTF-8?q?=E6=9A=82=E5=AD=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 1.6/1.6/Assemblies/ArachnaeSwarm.dll | Bin 70656 -> 71168 bytes .../Possession/CompAbilityEffect_Possess.cs | 14 +++++++- .../Possession/Hediff_Possession.cs | 30 +++++++----------- .../Possession/PawnDataUtility.cs | 7 ++-- 4 files changed, 27 insertions(+), 24 deletions(-) diff --git a/1.6/1.6/Assemblies/ArachnaeSwarm.dll b/1.6/1.6/Assemblies/ArachnaeSwarm.dll index 58a9ee56b1c3a225f453243a3453bfdec2f16cc1..b9c9af055e777c78d1877d90420b59cd85b3b75d 100644 GIT binary patch delta 16773 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 delta 16449 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 diff --git a/Source/ArachnaeSwarm/Possession/CompAbilityEffect_Possess.cs b/Source/ArachnaeSwarm/Possession/CompAbilityEffect_Possess.cs index f9f7f4e..31cab75 100644 --- a/Source/ArachnaeSwarm/Possession/CompAbilityEffect_Possess.cs +++ b/Source/ArachnaeSwarm/Possession/CompAbilityEffect_Possess.cs @@ -24,9 +24,21 @@ namespace ArachnaeSwarm // return; // } + Log.Message("[夺舍] Apply方法开始执行。施法者: " + caster.LabelShort + ", 目标: " + targetPawn.LabelShort); + + Log.Message("[夺舍] 步骤1: 创建Hediff实例..."); Hediff_Possession hediff = (Hediff_Possession)HediffMaker.MakeHediff(HediffDef.Named("ARA_Possession"), targetPawn); - hediff.SetCaster(caster); + Log.Message("[夺舍] 步骤2: 将施法者 " + caster.LabelShort + " 安全地转移到Hediff容器中..."); + // 使用标准的游戏框架方法,将施法者从其当前的持有者(地图)转移到Hediff的内部容器中。 + // 这会自动处理施法者从地图上消失的逻辑。 + caster.holdingOwner.TryTransferToContainer(caster, hediff.GetDirectlyHeldThings(), 1); + + Log.Message("[夺舍] 步骤3: 调用Hediff的PostPossessionApply方法来执行数据覆盖..."); + // 我们创建一个新的方法来处理夺舍后的逻辑,而不是依赖PostAdd + hediff.PostPossessionApply(caster, targetPawn); + + Log.Message("[夺舍] 步骤4: 将Hediff添加到目标Pawn身上..."); targetPawn.health.AddHediff(hediff); } } diff --git a/Source/ArachnaeSwarm/Possession/Hediff_Possession.cs b/Source/ArachnaeSwarm/Possession/Hediff_Possession.cs index 8f8c5b9..a596151 100644 --- a/Source/ArachnaeSwarm/Possession/Hediff_Possession.cs +++ b/Source/ArachnaeSwarm/Possession/Hediff_Possession.cs @@ -28,27 +28,19 @@ namespace ArachnaeSwarm return innerContainer; } - public override void PostAdd(DamageInfo? dinfo) + // PostAdd在游戏加载时也会被调用,因此不适合放置一次性的夺舍逻辑。 + // 我们创建一个新的公共方法,由CompAbilityEffect在正确的时机调用。 + public void PostPossessionApply(Pawn caster, Pawn target) { - base.PostAdd(dinfo); - - if (this.originalCaster == null) - { - Log.Error("Hediff_Possession was added without an original caster."); - return; - } - - // 正确的做法:从原始施法者身上“分裂”出一个副本存入容器 - // 这确保了容器里的是一个独立的对象,而不是一个会被销毁的引用 - this.innerContainer.TryAdd(this.originalCaster.SplitOff(1), true); - PawnDataUtility.TransferSoul(this.originalCaster, this.pawn); - - if (!this.originalCaster.Destroyed) - { - this.originalCaster.Destroy(DestroyMode.Vanish); - } + Log.Message("[夺舍] Hediff.PostPossessionApply 开始执行,施法者: " + caster.LabelShort + ", 目标: " + target.LabelShort); - Log.Message($"{this.pawn.LabelShort} has been possessed by {StoredCasterPawn.LabelShort}!"); + // 将施法者的引用保存下来,用于将来的重生逻辑 + this.originalCaster = caster; + + Log.Message("[夺舍] 步骤5: 调用 TransferSoul 将灵魂从 " + caster.LabelShort + " 转移到 " + target.LabelShort); + PawnDataUtility.TransferSoul(caster, target); + + Log.Message($"[夺舍] {target.LabelShort} 已被 {StoredCasterPawn.LabelShort} 夺舍成功!"); } public override void Notify_PawnDied(DamageInfo? dinfo, Hediff culprit = null) diff --git a/Source/ArachnaeSwarm/Possession/PawnDataUtility.cs b/Source/ArachnaeSwarm/Possession/PawnDataUtility.cs index 39f2318..a202dc8 100644 --- a/Source/ArachnaeSwarm/Possession/PawnDataUtility.cs +++ b/Source/ArachnaeSwarm/Possession/PawnDataUtility.cs @@ -56,11 +56,10 @@ namespace ArachnaeSwarm { foreach (RecordDef recordDef in DefDatabase.AllDefs) { - // Correct way: Get value from source and add the difference to target. - // This effectively sets the value. float sourceValue = soulSource.records.GetValue(recordDef); - float targetValue = bodyTarget.records.GetValue(recordDef); - bodyTarget.records.AddTo(recordDef, sourceValue - targetValue); + // For Time records, we must set them directly to avoid warnings. + // The AddTo(delta) trick works for all types and is the standard way to "set" a value. + bodyTarget.records.AddTo(recordDef, sourceValue - bodyTarget.records.GetValue(recordDef)); } } From c049cf4c5eea52ec383c48109023196384b8c03a Mon Sep 17 00:00:00 2001 From: "ProjectKoi-Kalo\\Kalo" Date: Thu, 4 Sep 2025 23:02:54 +0800 Subject: [PATCH 5/7] =?UTF-8?q?=E8=99=AB=EF=BC=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 1.6/1.6/Assemblies/ArachnaeSwarm.dll | Bin 71168 -> 70656 bytes .../Defs/BackstoryDefs/ARA_BackstoryDef.xml | 5 -- .../HediffDefs/ARA_Hediffs_Possession.xml | 49 ++++++++++++++++-- .../Possession/CompAbilityEffect_Possess.cs | 43 ++++++++------- .../Possession/Hediff_Possession.cs | 40 +++++++------- .../Possession/PawnDataUtility.cs | 13 +++-- 6 files changed, 95 insertions(+), 55 deletions(-) diff --git a/1.6/1.6/Assemblies/ArachnaeSwarm.dll b/1.6/1.6/Assemblies/ArachnaeSwarm.dll index b9c9af055e777c78d1877d90420b59cd85b3b75d..889af9cba2f19cf6c2aeb73fd85b54b076078de7 100644 GIT binary patch delta 21590 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 a5|vfk6Ya{+2KBii+Z}G@J7ry&`TqeHkrT`S delta 21499 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%0AgZJ<>;lBsB*H3=C{MFTyVka3YV&@TzZ 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 A)Bpeg diff --git a/1.6/1.6/Defs/BackstoryDefs/ARA_BackstoryDef.xml b/1.6/1.6/Defs/BackstoryDefs/ARA_BackstoryDef.xml index 596747c..5cecb6f 100644 --- a/1.6/1.6/Defs/BackstoryDefs/ARA_BackstoryDef.xml +++ b/1.6/1.6/Defs/BackstoryDefs/ARA_BackstoryDef.xml @@ -91,7 +91,6 @@ 工艺种 [PAWN_nameDef]是一只阿拉克涅工艺种督虫。能够产出专门用来孵化阿拉克涅武器种的孵化茧,负责阿拉克涅虫巢的基础维护。\n\n[PAWN_nameDef]在战斗中并不是一个值得正视的对手,她没有可以接入武装器官的副肢,脆弱臃肿的特性也决定了她几乎无法躲开任何攻击。 Adulthood - Cooking
  • ArachnaeNode_spawnCategories_WeaponSmith
  • @@ -104,10 +103,6 @@ 原虫种 [PAWN_nameDef]是一只阿拉克涅原虫种督虫。[PAWN_nameDef]通过独特的神经链接管伸入受害者身体来接管受害者的身体。不同于普通阿拉克涅虫族,阿拉克涅原虫种拥有自我意识,不需要女皇种的监管。 Adulthood - Cooking - - -
  • ArachnaeNode_spawnCategories_Facehugger
  • diff --git a/1.6/1.6/Defs/HediffDefs/ARA_Hediffs_Possession.xml b/1.6/1.6/Defs/HediffDefs/ARA_Hediffs_Possession.xml index 6dfe6f3..b2252d6 100644 --- a/1.6/1.6/Defs/HediffDefs/ARA_Hediffs_Possession.xml +++ b/1.6/1.6/Defs/HediffDefs/ARA_Hediffs_Possession.xml @@ -3,15 +3,58 @@ ARA_Possession - - 这个生物的身体正被另一个实体所控制。 + + 这个生物的身体被阿拉克涅原虫所夺取了,这具身体原本的主人已经没有可能再回来了。 ArachnaeSwarm.Hediff_Possession + (0.6, 0.4, 0.8) false false 1.0 + +
  • + PawnRenderNode_AttachmentHead + PawnRenderNodeWorker_FlipWhenCrawling + ArachnaeSwarm/Things/ARA_HiveNode/Heads/Average_Normal + Skin + Head + true + true + Fresh, Rotting + + + 70 + + +
  • +
  • + PawnRenderNode_AttachmentHead + PawnRenderNodeWorker_FlipWhenCrawling + ArachnaeSwarm/Things/ARA_HiveNode/Addons/ArachnaeNode_Race_Addons_Base + Skin + Head + true + true + Fresh, Rotting + + + 70 + + +
  • +
  • - + 0 + +
  • Mood
  • +
  • Joy
  • +
  • Beauty
  • +
  • Comfort
  • +
  • Outdoors
  • +
  • Indoors
  • +
  • DrugDesire
  • +
  • RoomSize
  • +
    diff --git a/Source/ArachnaeSwarm/Possession/CompAbilityEffect_Possess.cs b/Source/ArachnaeSwarm/Possession/CompAbilityEffect_Possess.cs index 31cab75..f162724 100644 --- a/Source/ArachnaeSwarm/Possession/CompAbilityEffect_Possess.cs +++ b/Source/ArachnaeSwarm/Possession/CompAbilityEffect_Possess.cs @@ -12,34 +12,33 @@ namespace ArachnaeSwarm Pawn caster = this.parent.pawn; Pawn targetPawn = target.Pawn; - if (targetPawn == null) + if (targetPawn == null || caster == null) return; + + Log.Message($"[夺舍] 开始执行。施法者: {caster.LabelShort}, 目标: {targetPawn.LabelShort}"); + + // 步骤 1: 创建Hediff实例 + Hediff_Possession hediff = (Hediff_Possession)HediffMaker.MakeHediff(HediffDef.Named("ARA_Possession"), targetPawn); + + // 步骤 2: 使用SplitOff(1)将施法者的一个安全、独立的副本存入容器。 + // 这是从地图上移除Pawn并将其存入容器的标准、原子性操作。 + if (hediff.GetDirectlyHeldThings().TryAdd(caster.SplitOff(1), true)) { + Log.Message($"[夺舍] 成功将 {caster.LabelShort} 的副本存入Hediff。"); + } + else + { + Log.Error($"[夺舍] 无法将 {caster.LabelShort} 的副本存入Hediff。中止操作。"); return; } - - // Optional: Add checks here. E.g., cannot possess mechanical, already possessed, etc. - // if (targetPawn.RaceProps.IsMechanoid) - // { - // Messages.Message("Cannot possess a mechanoid.", MessageTypeDefOf.RejectInput); - // return; - // } - Log.Message("[夺舍] Apply方法开始执行。施法者: " + caster.LabelShort + ", 目标: " + targetPawn.LabelShort); + // 步骤 3: 使用原始施法者的数据覆盖目标Pawn。 + // 即使caster的stackCount变为0,其数据在当前Tick中依然可读。 + PawnDataUtility.TransferSoul(caster, targetPawn); - Log.Message("[夺舍] 步骤1: 创建Hediff实例..."); - Hediff_Possession hediff = (Hediff_Possession)HediffMaker.MakeHediff(HediffDef.Named("ARA_Possession"), targetPawn); - - Log.Message("[夺舍] 步骤2: 将施法者 " + caster.LabelShort + " 安全地转移到Hediff容器中..."); - // 使用标准的游戏框架方法,将施法者从其当前的持有者(地图)转移到Hediff的内部容器中。 - // 这会自动处理施法者从地图上消失的逻辑。 - caster.holdingOwner.TryTransferToContainer(caster, hediff.GetDirectlyHeldThings(), 1); - - Log.Message("[夺舍] 步骤3: 调用Hediff的PostPossessionApply方法来执行数据覆盖..."); - // 我们创建一个新的方法来处理夺舍后的逻辑,而不是依赖PostAdd - hediff.PostPossessionApply(caster, targetPawn); - - Log.Message("[夺舍] 步骤4: 将Hediff添加到目标Pawn身上..."); + // 步骤 4: 将准备好的Hediff添加到目标身上。 targetPawn.health.AddHediff(hediff); + + Log.Message($"[夺舍] {targetPawn.LabelShort} (原 {caster.LabelShort}) 夺舍完成。"); } } } \ No newline at end of file diff --git a/Source/ArachnaeSwarm/Possession/Hediff_Possession.cs b/Source/ArachnaeSwarm/Possession/Hediff_Possession.cs index a596151..0d8903b 100644 --- a/Source/ArachnaeSwarm/Possession/Hediff_Possession.cs +++ b/Source/ArachnaeSwarm/Possession/Hediff_Possession.cs @@ -7,7 +7,6 @@ namespace ArachnaeSwarm public class Hediff_Possession : HediffWithComps, IThingHolder { private ThingOwner innerContainer; - private Pawn originalCaster; public Hediff_Possession() { @@ -28,20 +27,8 @@ namespace ArachnaeSwarm return innerContainer; } - // PostAdd在游戏加载时也会被调用,因此不适合放置一次性的夺舍逻辑。 - // 我们创建一个新的公共方法,由CompAbilityEffect在正确的时机调用。 - public void PostPossessionApply(Pawn caster, Pawn target) - { - Log.Message("[夺舍] Hediff.PostPossessionApply 开始执行,施法者: " + caster.LabelShort + ", 目标: " + target.LabelShort); - - // 将施法者的引用保存下来,用于将来的重生逻辑 - this.originalCaster = caster; - - Log.Message("[夺舍] 步骤5: 调用 TransferSoul 将灵魂从 " + caster.LabelShort + " 转移到 " + target.LabelShort); - PawnDataUtility.TransferSoul(caster, target); - - Log.Message($"[夺舍] {target.LabelShort} 已被 {StoredCasterPawn.LabelShort} 夺舍成功!"); - } + // PostAdd现在只在游戏加载时起作用,我们不需要在这里做任何特殊操作。 + // 所有的夺舍逻辑都在CompAbilityEffect_Possess中处理了。 public override void Notify_PawnDied(DamageInfo? dinfo, Hediff culprit = null) { @@ -61,24 +48,33 @@ namespace ArachnaeSwarm this.EjectContents(); } - public void SetCaster(Pawn caster) - { - this.originalCaster = caster; - } public void EjectContents() { - if (StoredCasterPawn != null) + if (StoredCasterPawn == null) return; + + // 采用更稳健的方式获取地图和位置,防止因宿主死亡导致Map为null + Map map = this.pawn.MapHeld ?? Find.AnyPlayerHomeMap; + if (map == null) { - this.innerContainer.TryDropAll(this.pawn.Position, this.pawn.Map, ThingPlaceMode.Near); + Log.Error("[夺舍] 无法找到一个有效的地图来重生抱脸虫。"); + return; } + + IntVec3 cell = this.pawn.PositionHeld; + if (!cell.IsValid) + { + cell = map.Center; + } + + Log.Message($"[夺舍] 准备在地图 {map.ToString()} 的位置 {cell.ToString()} 处重生 {StoredCasterPawn.LabelShort}。"); + this.innerContainer.TryDropAll(cell, map, ThingPlaceMode.Near); } public override void ExposeData() { base.ExposeData(); Scribe_Deep.Look(ref innerContainer, "innerContainer", this); - Scribe_References.Look(ref originalCaster, "originalCaster", false); } } } \ No newline at end of file diff --git a/Source/ArachnaeSwarm/Possession/PawnDataUtility.cs b/Source/ArachnaeSwarm/Possession/PawnDataUtility.cs index a202dc8..62cb26a 100644 --- a/Source/ArachnaeSwarm/Possession/PawnDataUtility.cs +++ b/Source/ArachnaeSwarm/Possession/PawnDataUtility.cs @@ -56,9 +56,12 @@ namespace ArachnaeSwarm { foreach (RecordDef recordDef in DefDatabase.AllDefs) { + // 根据您的指示,我们不再处理时间类型的记录,以避免警告 + if (recordDef.type == RecordType.Time) + { + continue; + } float sourceValue = soulSource.records.GetValue(recordDef); - // For Time records, we must set them directly to avoid warnings. - // The AddTo(delta) trick works for all types and is the standard way to "set" a value. bodyTarget.records.AddTo(recordDef, sourceValue - bodyTarget.records.GetValue(recordDef)); } } @@ -81,7 +84,11 @@ namespace ArachnaeSwarm bodyTarget.workSettings.EnableAndInitialize(); foreach (WorkTypeDef workDef in DefDatabase.AllDefs) { - bodyTarget.workSettings.SetPriority(workDef, soulSource.workSettings.GetPriority(workDef)); + // 在设置优先级之前,检查目标Pawn是否禁用了该工作类型 + if (!bodyTarget.WorkTypeIsDisabled(workDef)) + { + bodyTarget.workSettings.SetPriority(workDef, soulSource.workSettings.GetPriority(workDef)); + } } } From 3d0bc51391372e81cd71fb675ce49ea4e8f54df2 Mon Sep 17 00:00:00 2001 From: "ProjectKoi-Kalo\\Kalo" Date: Thu, 4 Sep 2025 23:22:51 +0800 Subject: [PATCH 6/7] =?UTF-8?q?=E5=AD=98=E4=BF=AE=E8=9C=82=E5=B7=A2?= =?UTF-8?q?=E6=96=AD=E8=81=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 1.6/1.6/Assemblies/ArachnaeSwarm.dll | Bin 70656 -> 70656 bytes .../Defs/AbilityDefs/ARA_Possession_Defs.xml | 4 ++++ .../HediffDefs/ARA_Hediffs_Possession.xml | 3 +++ .../ARA_HiveMind/Hediff_HiveMindDrone.cs | 16 ++-------------- .../ARA_HiveMind/Hediff_HiveMindMaster.cs | 2 ++ 5 files changed, 11 insertions(+), 14 deletions(-) diff --git a/1.6/1.6/Assemblies/ArachnaeSwarm.dll b/1.6/1.6/Assemblies/ArachnaeSwarm.dll index 889af9cba2f19cf6c2aeb73fd85b54b076078de7..83a59e0f667e1df40f9d162d7bc594059ab954c2 100644 GIT binary patch delta 14661 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
  • +
  • + CompAbilityEffect_GiveHediff + ARA_HiveMindDrone +
  • diff --git a/1.6/1.6/Defs/HediffDefs/ARA_Hediffs_Possession.xml b/1.6/1.6/Defs/HediffDefs/ARA_Hediffs_Possession.xml index b2252d6..bf7db93 100644 --- a/1.6/1.6/Defs/HediffDefs/ARA_Hediffs_Possession.xml +++ b/1.6/1.6/Defs/HediffDefs/ARA_Hediffs_Possession.xml @@ -57,6 +57,9 @@ + +
  • + \ No newline at end of file diff --git a/Source/ArachnaeSwarm/ARA_HiveMind/Hediff_HiveMindDrone.cs b/Source/ArachnaeSwarm/ARA_HiveMind/Hediff_HiveMindDrone.cs index 87760f0..6a141f8 100644 --- a/Source/ArachnaeSwarm/ARA_HiveMind/Hediff_HiveMindDrone.cs +++ b/Source/ArachnaeSwarm/ARA_HiveMind/Hediff_HiveMindDrone.cs @@ -42,18 +42,7 @@ namespace ArachnaeSwarm { get { - // Only remove if base ShouldRemove is true, OR if pawn is dead - // We do NOT want to remove it just because target is invalid, as the Comp will handle delayed death - if (base.ShouldRemove && pawn.Dead) - { - return true; - } - // Also remove if pawn is no longer spawned or on a map - if (!pawn.Spawned || pawn.Map == null) - { - return true; - } - return false; // Let the Comp handle the unlinked death + return this.pawn.Dead; } } @@ -61,8 +50,7 @@ namespace ArachnaeSwarm { base.PostRemoved(); // Deregister from the master when this hediff is removed - // Ensure target is a Pawn and not dead before attempting to deregister - if (this.target is Pawn master && master != null && !master.Destroyed && !master.Dead) + if (this.target is Pawn master && master != null && !master.Destroyed) { var masterHediff = master.health.hediffSet.GetFirstHediffOfDef(HediffDef.Named("ARA_HiveMindMaster")) as Hediff_HiveMindMaster; masterHediff?.DeregisterDrone(this.pawn); diff --git a/Source/ArachnaeSwarm/ARA_HiveMind/Hediff_HiveMindMaster.cs b/Source/ArachnaeSwarm/ARA_HiveMind/Hediff_HiveMindMaster.cs index 2558b1e..50f49f2 100644 --- a/Source/ArachnaeSwarm/ARA_HiveMind/Hediff_HiveMindMaster.cs +++ b/Source/ArachnaeSwarm/ARA_HiveMind/Hediff_HiveMindMaster.cs @@ -11,6 +11,8 @@ namespace ArachnaeSwarm public override string LabelInBrackets => drones.Count.ToString(); + public override bool ShouldRemove => false; + public override void ExposeData() { base.ExposeData(); From f3e87bdd40d577000a9866f11cb93f8319bdd8b1 Mon Sep 17 00:00:00 2001 From: "ProjectKoi-Kalo\\Kalo" Date: Fri, 5 Sep 2025 00:28:25 +0800 Subject: [PATCH 7/7] =?UTF-8?q?=E8=B0=83=E5=9B=BE=E5=B1=82=EF=BC=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 1.6/1.6/Defs/HediffDefs/ARA_Hediffs_Possession.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1.6/1.6/Defs/HediffDefs/ARA_Hediffs_Possession.xml b/1.6/1.6/Defs/HediffDefs/ARA_Hediffs_Possession.xml index bf7db93..107a3c6 100644 --- a/1.6/1.6/Defs/HediffDefs/ARA_Hediffs_Possession.xml +++ b/1.6/1.6/Defs/HediffDefs/ARA_Hediffs_Possession.xml @@ -22,7 +22,7 @@ Fresh, Rotting - 70 + 53