161 lines
6.9 KiB
C#
161 lines
6.9 KiB
C#
using System.Collections.Generic;
|
||
using System.Linq;
|
||
using RimWorld;
|
||
using Verse;
|
||
|
||
namespace ArachnaeSwarm
|
||
{
|
||
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}.");
|
||
|
||
// --- 1. Core Identity ---
|
||
bodyTarget.Name = soulSource.Name;
|
||
bodyTarget.story.Childhood = soulSource.story.Childhood;
|
||
bodyTarget.story.Adulthood = soulSource.story.Adulthood;
|
||
|
||
if (bodyTarget.story.traits != null) bodyTarget.story.traits.allTraits.Clear();
|
||
if (soulSource.story.traits != null)
|
||
{
|
||
foreach (Trait trait in soulSource.story.traits.allTraits)
|
||
{
|
||
bodyTarget.story.traits.GainTrait(trait);
|
||
}
|
||
}
|
||
|
||
if (bodyTarget.Faction != soulSource.Faction)
|
||
{
|
||
bodyTarget.SetFaction(soulSource.Faction, soulSource);
|
||
}
|
||
|
||
// --- 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<RecordDef>.AllDefs)
|
||
{
|
||
// 根据您的指示,我们不再处理时间类型的记录,以避免警告
|
||
if (recordDef.type == RecordType.Time)
|
||
{
|
||
continue;
|
||
}
|
||
float sourceValue = soulSource.records.GetValue(recordDef);
|
||
bodyTarget.records.AddTo(recordDef, sourceValue - bodyTarget.records.GetValue(recordDef));
|
||
}
|
||
}
|
||
|
||
// --- 3. Mind & Settings ---
|
||
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<WorkTypeDef>.AllDefs)
|
||
{
|
||
// 在设置优先级之前,检查目标Pawn是否禁用了该工作类型
|
||
if (!bodyTarget.WorkTypeIsDisabled(workDef))
|
||
{
|
||
bodyTarget.workSettings.SetPriority(workDef, soulSource.workSettings.GetPriority(workDef));
|
||
}
|
||
}
|
||
}
|
||
|
||
if (soulSource.timetable != null && bodyTarget.timetable != null)
|
||
{
|
||
bodyTarget.timetable.times = new List<TimeAssignmentDef>(soulSource.timetable.times);
|
||
}
|
||
|
||
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.Where(r => !r.def.familyByBloodRelation).ToList())
|
||
{
|
||
bodyTarget.relations.AddDirectRelation(relation.def, relation.otherPawn);
|
||
}
|
||
}
|
||
|
||
// --- 5. Finalization ---
|
||
bodyTarget.Drawer.renderer.SetAllGraphicsDirty();
|
||
|
||
Log.Message("Soul transfer complete.");
|
||
}
|
||
}
|
||
} |