This commit is contained in:
2025-11-27 12:02:32 +08:00
parent dbc823108f
commit 73fb69b96e
21 changed files with 950 additions and 428 deletions

View File

@@ -9,73 +9,29 @@ namespace WulaFallenEmpire
{
public class Building_MechanoidRecycler : Building
{
// 翻译键定义
public static class TranslationKeys
{
// 消息文本
public const string NoRecyclableMechanoidsNearby = "WULA_NoRecyclableMechanoidsNearby";
public const string RecyclerStorageFull = "WULA_RecyclerStorageFull";
public const string CalledMechanoidsForRecycling = "WULA_CalledMechanoidsForRecycling";
public const string MechanoidRecycled = "WULA_MechanoidRecycled";
public const string NoMechanoidsAvailableForConversion = "WULA_NoMechanoidsAvailableForConversion";
public const string NotEnoughStoredMechanoids = "WULA_NotEnoughStoredMechanoids";
public const string ConvertingMechanoids = "WULA_ConvertingMechanoids";
// Gizmo 文本
public const string RecycleNearbyMechanoids = "WULA_RecycleNearbyMechanoids";
public const string RecycleNearbyMechanoidsDesc = "WULA_RecycleNearbyMechanoidsDesc";
public const string RecycleNearbyMechanoidsDisabled = "WULA_RecycleNearbyMechanoidsDisabled";
public const string ConvertMechanoids = "WULA_ConvertMechanoids";
public const string ConvertMechanoidsDesc = "WULA_ConvertMechanoidsDesc";
public const string ConvertMechanoidsDisabled = "WULA_ConvertMechanoidsDisabled";
// 检查字符串
public const string StoredInfo = "WULA_StoredInfo";
}
public CompProperties_MechanoidRecycler Props => def.GetCompProperties<CompProperties_MechanoidRecycler>();
// 存储的机械族列表
public List<Pawn> storedMechanoids = new List<Pawn>();
// 改为存储计数而不是Pawn实例
private int storedMechanoidCount = 0;
private int spawnTick; // 建筑生成的时间点
// 生成队列
// 生成队列存储Pawn生成请求
private Queue<PawnGenerationRequest> spawnQueue = new Queue<PawnGenerationRequest>();
// 是否已经生成初始单位
private bool initialUnitsSpawned = false;
public int StoredCount => storedMechanoids.Count;
public int StoredCount => storedMechanoidCount;
public int MaxStorage => Props.maxStorageCapacity;
public bool IsCooldownActive => Find.TickManager.TicksGame - spawnTick < 24 * 2500; // 24小时冷却
// 生成初始单位
// 生成初始单位(改为计数)
private void SpawnInitialUnits()
{
if (initialUnitsSpawned || Props.initialUnits == null || Props.initialUnits.Count == 0)
if (initialUnitsSpawned || Props.initialUnits == null)
return;
foreach (var initialUnit in Props.initialUnits)
{
if (storedMechanoids.Count >= MaxStorage)
break;
// 生成初始机械族
PawnGenerationRequest request = new PawnGenerationRequest(
initialUnit.pawnKindDef,
Faction, // 使用当前建筑的派系
PawnGenerationContext.NonPlayer,
-1,
forceGenerateNewPawn: true,
allowDead: false,
allowDowned: false,
canGeneratePawnRelations: false,
mustBeCapableOfViolence: true
);
Pawn initialMech = PawnGenerator.GeneratePawn(request);
storedMechanoids.Add(initialMech);
Log.Message($"Mechanoid Recycler spawned initial unit: {initialMech.LabelCap} for faction: {Faction.Name}");
storedMechanoidCount += initialUnit.count;
}
initialUnitsSpawned = true;
@@ -84,118 +40,48 @@ namespace WulaFallenEmpire
public override void SpawnSetup(Map map, bool respawningAfterLoad)
{
base.SpawnSetup(map, respawningAfterLoad);
spawnTick = Find.TickManager.TicksGame;
// 如果不是从存档加载,生成初始单位
if (!respawningAfterLoad)
{
SpawnInitialUnits();
}
}
// 回收附近机械族
public void RecycleNearbyMechanoids()
// 回收机械族(改为增加计数)
public void AcceptMechanoid(Pawn mech)
{
if (!CanRecycleNow())
return;
List<Pawn> nearbyMechs = FindNearbyRecyclableMechanoids();
if (nearbyMechs.Count == 0)
if (storedMechanoidCount >= Props.maxStorageCapacity)
{
Messages.Message(TranslationKeys.NoRecyclableMechanoidsNearby.Translate(), MessageTypeDefOf.RejectInput);
Messages.Message("回收器已满", MessageTypeDefOf.RejectInput);
return;
}
int assignedCount = 0;
foreach (Pawn mech in nearbyMechs)
{
if (StartRecycleJob(mech))
{
assignedCount++;
}
}
storedMechanoidCount++;
mech.Destroy(); // 直接销毁,不存储实例
Messages.Message(TranslationKeys.CalledMechanoidsForRecycling.Translate(assignedCount), MessageTypeDefOf.PositiveEvent);
Messages.Message($"机械族 {mech.LabelCap} 已回收 (当前: {storedMechanoidCount}/{Props.maxStorageCapacity})",
MessageTypeDefOf.PositiveEvent);
// 通知转换组件存储更新
var transformComp = this.TryGetComp<CompTransformAtFullCapacity>();
transformComp?.NotifyStorageUpdated();
}
private bool CanRecycleNow()
// 消耗机械族计数
public bool ConsumeMechanoids(int count)
{
if (storedMechanoids.Count >= Props.maxStorageCapacity)
{
if (storedMechanoidCount < count)
return false;
}
storedMechanoidCount -= count;
return true;
}
private List<Pawn> FindNearbyRecyclableMechanoids()
// 设置机械族计数(用于转换恢复)
public void SetMechanoidCount(int count)
{
List<Pawn> result = new List<Pawn>();
CellRect searchRect = CellRect.CenteredOn(Position, Props.recycleRange);
foreach (Pawn pawn in Map.mapPawns.AllPawnsSpawned)
{
if (searchRect.Contains(pawn.Position) &&
IsRecyclableMechanoid(pawn) &&
!storedMechanoids.Contains(pawn) &&
!IsAlreadyGoingToRecycler(pawn) && // 检查是否已经在前往回收器
pawn.CanReach(this, PathEndMode.InteractionCell, Danger.Some))
{
result.Add(pawn);
}
}
return result;
}
private bool IsRecyclableMechanoid(Pawn pawn)
{
return pawn.RaceProps.IsMechanoid &&
Props.recyclableRaces.Contains(pawn.def) &&
!pawn.Downed &&
pawn.Faction == Faction; // 使用当前建筑的派系
}
// 检查机械族是否已经在前往此回收器
private bool IsAlreadyGoingToRecycler(Pawn mech)
{
// 检查当前工作是否是前往此回收器
Job curJob = mech.CurJob;
if (curJob != null && curJob.def == Props.recycleJobDef && curJob.targetA.Thing == this)
return true;
return false;
}
private bool StartRecycleJob(Pawn mech)
{
// 防止重复分配
if (IsAlreadyGoingToRecycler(mech))
return false;
Job job = JobMaker.MakeJob(Props.recycleJobDef, this);
if (mech.jobs.TryTakeOrderedJob(job))
{
return true;
}
return false;
}
// 机械族进入建筑
public void AcceptMechanoid(Pawn mech)
{
if (storedMechanoids.Contains(mech))
return;
if (storedMechanoids.Count >= Props.maxStorageCapacity)
{
Messages.Message(TranslationKeys.RecyclerStorageFull.Translate(), MessageTypeDefOf.RejectInput);
return;
}
storedMechanoids.Add(mech);
mech.DeSpawn();
Messages.Message(TranslationKeys.MechanoidRecycled.Translate(mech.LabelCap), MessageTypeDefOf.PositiveEvent);
storedMechanoidCount = Mathf.Clamp(count, 0, Props.maxStorageCapacity);
}
protected override void Tick()
@@ -212,9 +98,9 @@ namespace WulaFallenEmpire
// 打开生成界面
public void OpenSpawnInterface()
{
if (storedMechanoids.Count == 0)
if (storedMechanoidCount == 0)
{
Messages.Message(TranslationKeys.NoMechanoidsAvailableForConversion.Translate(), MessageTypeDefOf.RejectInput);
Messages.Message("没有可用的机械族进行转换", MessageTypeDefOf.RejectInput);
return;
}
@@ -223,7 +109,7 @@ namespace WulaFallenEmpire
foreach (PawnKindDef kindDef in Props.spawnablePawnKinds)
{
kindOptions.Add(new FloatMenuOption(
kindDef.LabelCap,
$"{kindDef.LabelCap}",
() => TrySpawnMechanoids(kindDef, 1)
));
}
@@ -233,27 +119,17 @@ namespace WulaFallenEmpire
private void TrySpawnMechanoids(PawnKindDef kindDef, int count)
{
if (storedMechanoids.Count < count)
if (!ConsumeMechanoids(count))
{
Messages.Message(TranslationKeys.NotEnoughStoredMechanoids.Translate(), MessageTypeDefOf.RejectInput);
Messages.Message("机械族数量不足", MessageTypeDefOf.RejectInput);
return;
}
// 消耗存储的机械族并生成
for (int i = 0; i < count; i++)
{
if (storedMechanoids.Count > 0)
{
Pawn consumedMech = storedMechanoids[0];
storedMechanoids.RemoveAt(0);
if (consumedMech.Spawned)
consumedMech.Destroy();
}
PawnGenerationRequest request = new PawnGenerationRequest(
kindDef,
Faction, // 使用当前建筑的派系
Faction,
PawnGenerationContext.NonPlayer,
-1,
forceGenerateNewPawn: true,
@@ -267,7 +143,7 @@ namespace WulaFallenEmpire
}
TrySpawnFromQueue();
Messages.Message(TranslationKeys.ConvertingMechanoids.Translate(count, kindDef.LabelCap), MessageTypeDefOf.PositiveEvent);
Messages.Message($"正在转换 {count} 个机械族为 {kindDef.LabelCap}", MessageTypeDefOf.PositiveEvent);
}
private void TrySpawnFromQueue()
@@ -318,15 +194,15 @@ namespace WulaFallenEmpire
// 回收附近机械族按钮
Command_Action recycleCommand = new Command_Action
{
defaultLabel = TranslationKeys.RecycleNearbyMechanoids.Translate(),
defaultDesc = TranslationKeys.RecycleNearbyMechanoidsDesc.Translate(Props.recycleRange),
defaultLabel = "回收附近机械族",
defaultDesc = $"命令附近 {Props.recycleRange} 格内的机械族前来回收",
icon = ContentFinder<Texture2D>.Get("Wula/UI/Commands/WULA_RecycleNearbyMechanoids"),
action = RecycleNearbyMechanoids
};
if (!CanRecycleNow())
if (storedMechanoidCount >= Props.maxStorageCapacity)
{
recycleCommand.Disable(TranslationKeys.RecycleNearbyMechanoidsDisabled.Translate());
recycleCommand.Disable("储存器已满");
}
yield return recycleCommand;
@@ -334,19 +210,97 @@ namespace WulaFallenEmpire
// 生成机械族按钮
Command_Action spawnCommand = new Command_Action
{
defaultLabel = TranslationKeys.ConvertMechanoids.Translate(),
defaultDesc = TranslationKeys.ConvertMechanoidsDesc.Translate(storedMechanoids.Count, Props.maxStorageCapacity),
defaultLabel = "转换机械族",
defaultDesc = $"将储存的机械族转换为其他单位 (当前: {storedMechanoidCount}/{Props.maxStorageCapacity})",
icon = ContentFinder<Texture2D>.Get("Wula/UI/Commands/WULA_ConvertMechanoids"),
action = OpenSpawnInterface
};
if (storedMechanoids.Count == 0)
if (storedMechanoidCount == 0)
{
spawnCommand.Disable(TranslationKeys.ConvertMechanoidsDisabled.Translate());
spawnCommand.Disable("没有可用的机械族");
}
yield return spawnCommand;
}
// 回收附近机械族
public void RecycleNearbyMechanoids()
{
if (storedMechanoidCount >= Props.maxStorageCapacity)
{
Messages.Message("储存器已满", MessageTypeDefOf.RejectInput);
return;
}
List<Pawn> nearbyMechs = FindNearbyRecyclableMechanoids();
if (nearbyMechs.Count == 0)
{
Messages.Message("附近没有可回收的机械族", MessageTypeDefOf.RejectInput);
return;
}
int assignedCount = 0;
foreach (Pawn mech in nearbyMechs)
{
if (StartRecycleJob(mech))
{
assignedCount++;
}
}
Messages.Message($"已命令 {assignedCount} 个机械族前来回收", MessageTypeDefOf.PositiveEvent);
}
private List<Pawn> FindNearbyRecyclableMechanoids()
{
List<Pawn> result = new List<Pawn>();
CellRect searchRect = CellRect.CenteredOn(Position, Props.recycleRange);
foreach (Pawn pawn in Map.mapPawns.AllPawnsSpawned)
{
if (searchRect.Contains(pawn.Position) &&
IsRecyclableMechanoid(pawn) &&
!IsAlreadyGoingToRecycler(pawn) &&
pawn.CanReach(this, PathEndMode.InteractionCell, Danger.Some))
{
result.Add(pawn);
}
}
return result;
}
private bool IsRecyclableMechanoid(Pawn pawn)
{
return pawn.RaceProps.IsMechanoid &&
Props.recyclableRaces.Contains(pawn.def) &&
!pawn.Downed &&
pawn.Faction == Faction;
}
private bool IsAlreadyGoingToRecycler(Pawn mech)
{
Job curJob = mech.CurJob;
if (curJob != null && curJob.def == Props.recycleJobDef && curJob.targetA.Thing == this)
return true;
return false;
}
private bool StartRecycleJob(Pawn mech)
{
if (IsAlreadyGoingToRecycler(mech))
return false;
Job job = JobMaker.MakeJob(Props.recycleJobDef, this);
if (mech.jobs.TryTakeOrderedJob(job))
{
return true;
}
return false;
}
public override string GetInspectString()
{
@@ -358,27 +312,39 @@ namespace WulaFallenEmpire
stringBuilder.Append(baseString);
}
string storedInfo = TranslationKeys.StoredInfo.Translate(storedMechanoids.Count, Props.maxStorageCapacity);
string storedInfo = $"储存机械族: {storedMechanoidCount}/{Props.maxStorageCapacity}";
if (stringBuilder.Length > 0)
stringBuilder.AppendLine();
stringBuilder.Append(storedInfo);
// 显示冷却状态
if (IsCooldownActive)
{
stringBuilder.AppendLine();
stringBuilder.Append($"转换冷却: {GetRemainingCooldownHours():F1} 小时");
}
return stringBuilder.ToString();
}
public float GetRemainingCooldownHours()
{
int remainingTicks = (24 * 2500) - (Find.TickManager.TicksGame - spawnTick);
return Mathf.Max(0, remainingTicks / 2500f);
}
public override void ExposeData()
{
base.ExposeData();
Scribe_Collections.Look(ref storedMechanoids, "storedMechanoids", LookMode.Reference);
Scribe_Collections.Look(ref spawnQueue, "spawnQueue", LookMode.Deep);
Scribe_Values.Look(ref storedMechanoidCount, "storedMechanoidCount", 0);
Scribe_Values.Look(ref spawnTick, "spawnTick", 0);
Scribe_Values.Look(ref initialUnitsSpawned, "initialUnitsSpawned", false);
Scribe_Collections.Look(ref spawnQueue, "spawnQueue", LookMode.Deep);
if (Scribe.mode == LoadSaveMode.PostLoadInit)
{
storedMechanoids?.RemoveAll(pawn => pawn == null);
if (spawnQueue == null)
spawnQueue = new Queue<PawnGenerationRequest>();
}

View File

@@ -1,42 +1,35 @@
// CompProperties_MechanoidRecycler.cs (简化)
using System.Collections.Generic;
using RimWorld;
using Verse;
namespace WulaFallenEmpire
{
// 初始单位配置类
public class InitialUnitConfig
{
public PawnKindDef pawnKindDef;
public int count = 1;
}
public class CompProperties_MechanoidRecycler : CompProperties
{
// 回收相关
public List<ThingDef> recyclableRaces = new List<ThingDef>();
public int recycleRange = 15;
public JobDef recycleJobDef;
public int maxStorageCapacity = 5;
// 生成相关
public List<PawnKindDef> spawnablePawnKinds = new List<PawnKindDef>();
// 初始单位配置
public List<InitialUnitConfig> initialUnits = new List<InitialUnitConfig>();
// 归属权配置
public Faction ownershipFaction = null; // 如果为null则默认使用玩家派系
public CompProperties_MechanoidRecycler()
{
compClass = typeof(CompMechanoidRecycler);
}
}
// 空的组件类,用于属性存储
public class CompMechanoidRecycler : ThingComp
{
// 组件逻辑主要在建筑类中实现
// 组件,用于属性存储
}
}

View File

@@ -0,0 +1,21 @@
// CompProperties_TransformAtFullCapacity.cs
using RimWorld;
using Verse;
namespace WulaFallenEmpire
{
public class CompProperties_TransformAtFullCapacity : CompProperties
{
public PawnKindDef targetPawnKind;
public int requiredCapacity = 5;
public string gizmoLabel = "转换为机械单位";
public string gizmoDesc = "将储存的机械族转换为一个强大的机械单位。";
public string gizmoIconPath;
public CompProperties_TransformAtFullCapacity()
{
compClass = typeof(CompTransformAtFullCapacity);
}
}
}

View File

@@ -0,0 +1,21 @@
// CompProperties_TransformIntoBuilding.cs
using RimWorld;
using Verse;
namespace WulaFallenEmpire
{
public class CompProperties_TransformIntoBuilding : CompProperties
{
public ThingDef targetBuildingDef;
public string gizmoLabel = "部署为建筑";
public string gizmoDesc = "转换为功能建筑形态。";
public string gizmoIconPath;
public CompProperties_TransformIntoBuilding()
{
compClass = typeof(CompTransformIntoBuilding);
}
}
}

View File

@@ -0,0 +1,172 @@
using RimWorld;
using System.Collections.Generic;
using UnityEngine;
using Verse;
namespace WulaFallenEmpire
{
public class CompTransformAtFullCapacity : ThingComp
{
private CompProperties_TransformAtFullCapacity Props => (CompProperties_TransformAtFullCapacity)props;
// 存储转换前的计数,用于恢复
private int storedCountAtTransform = 0;
public Building_MechanoidRecycler Recycler => parent as Building_MechanoidRecycler;
public bool IsCooldownActive => Recycler?.IsCooldownActive ?? false;
public bool IsAtFullCapacity => Recycler?.StoredCount >= Props.requiredCapacity;
public override void Initialize(CompProperties props)
{
base.Initialize(props);
}
public override void PostExposeData()
{
base.PostExposeData();
Scribe_Values.Look(ref storedCountAtTransform, "storedCountAtTransform", 0);
}
public override IEnumerable<Gizmo> CompGetGizmosExtra()
{
if (parent.Faction == Faction.OfPlayer && Recycler != null)
{
Command_Action command = new Command_Action
{
defaultLabel = Props.gizmoLabel,
defaultDesc = GetGizmoDescription(),
icon = GetGizmoIcon(),
action = TransformToPawn
};
// 禁用条件
if (IsCooldownActive)
{
command.Disable($"建筑刚部署,需要等待 {Recycler.GetRemainingCooldownHours():F1} 小时后才能转换");
}
else if (!IsAtFullCapacity)
{
command.Disable($"需要储存 {Props.requiredCapacity} 个机械族,当前: {Recycler.StoredCount}/{Props.requiredCapacity}");
}
yield return command;
}
}
private string GetGizmoDescription()
{
string desc = Props.gizmoDesc;
if (IsCooldownActive)
{
desc += $"\n\n冷却时间剩余: {Recycler.GetRemainingCooldownHours():F1} 小时";
}
desc += $"\n目标单位: {Props.targetPawnKind.LabelCap}";
return desc;
}
private Texture2D GetGizmoIcon()
{
if (!Props.gizmoIconPath.NullOrEmpty())
{
return ContentFinder<Texture2D>.Get(Props.gizmoIconPath);
}
return TexCommand.ReleaseAnimals;
}
public void NotifyStorageUpdated()
{
// 当存储更新时,可以触发视觉效果
if (IsAtFullCapacity && !IsCooldownActive)
{
// 播放满容量提示效果
//MoteMaker.ThrowLightningGlow(parent.DrawPos, parent.Map, 2f);
}
}
public void TransformToPawn()
{
if (Recycler == null || !parent.Spawned)
return;
Map map = parent.Map;
IntVec3 position = parent.Position;
Faction faction = parent.Faction;
// 存储当前的机械族计数(用于恢复)
storedCountAtTransform = Recycler.StoredCount;
// 消耗存储的机械族
if (!Recycler.ConsumeMechanoids(Props.requiredCapacity))
{
Messages.Message("机械族数量不足", MessageTypeDefOf.RejectInput);
return;
}
// 生成目标Pawn
PawnGenerationRequest request = new PawnGenerationRequest(
Props.targetPawnKind,
faction,
PawnGenerationContext.NonPlayer,
-1,
forceGenerateNewPawn: true,
allowDead: false,
allowDowned: false,
canGeneratePawnRelations: false,
mustBeCapableOfViolence: true
);
Pawn newPawn = PawnGenerator.GeneratePawn(request);
// 添加转换组件并设置恢复数据
var transformComp = newPawn.GetComp<CompTransformIntoBuilding>();
if (transformComp != null)
{
transformComp.SetRestoreData(parent.def, storedCountAtTransform);
}
else
{
// 动态添加组件
var compProps = new CompProperties_TransformIntoBuilding
{
targetBuildingDef = parent.def
};
transformComp = new CompTransformIntoBuilding();
transformComp.parent = newPawn;
transformComp.props = compProps;
newPawn.AllComps.Add(transformComp);
transformComp.Initialize(compProps);
transformComp.SetRestoreData(parent.def, storedCountAtTransform);
}
// 移除建筑
parent.DeSpawn(DestroyMode.Vanish);
// 生成Pawn
GenSpawn.Spawn(newPawn, position, map, WipeMode.Vanish);
// 选中新生成的Pawn
if (Find.Selector.IsSelected(parent))
{
Find.Selector.Select(newPawn);
}
Messages.Message($"{parent.Label} 已转换为 {newPawn.LabelCap}", MessageTypeDefOf.PositiveEvent);
// 播放转换效果
PlayTransformEffects(position, map);
}
private void PlayTransformEffects(IntVec3 position, Map map)
{
//// 播放转换视觉效果
//for (int i = 0; i < 3; i++)
//{
// MoteMaker.ThrowSmoke(position.ToVector3Shifted() + new Vector3(0, 0, 0.5f), map, 1.5f);
// MoteMaker.ThrowLightningGlow(position.ToVector3Shifted(), map, 2f);
//}
//// 播放音效
//SoundDefOf.PsychicPulseGlobal.PlayOneShot(new TargetInfo(position, map));
}
}
}

View File

@@ -0,0 +1,170 @@
using RimWorld;
using System.Collections.Generic;
using UnityEngine;
using Verse;
namespace WulaFallenEmpire
{
public class CompTransformIntoBuilding : ThingComp
{
private CompProperties_TransformIntoBuilding Props => (CompProperties_TransformIntoBuilding)props;
private Pawn Pawn => (Pawn)parent;
// 恢复数据
private ThingDef restoreBuildingDef;
private int restoreMechanoidCount;
public override void Initialize(CompProperties props)
{
base.Initialize(props);
}
public override void PostExposeData()
{
base.PostExposeData();
Scribe_Defs.Look(ref restoreBuildingDef, "restoreBuildingDef");
Scribe_Values.Look(ref restoreMechanoidCount, "restoreMechanoidCount", 0);
}
// 设置恢复数据
public void SetRestoreData(ThingDef buildingDef, int mechanoidCount)
{
restoreBuildingDef = buildingDef;
restoreMechanoidCount = mechanoidCount;
}
public override IEnumerable<Gizmo> CompGetGizmosExtra()
{
if (parent.Faction == Faction.OfPlayer && Pawn != null)
{
Command_Action command = new Command_Action
{
defaultLabel = Props.gizmoLabel,
defaultDesc = GetGizmoDescription(),
icon = GetGizmoIcon(),
action = TransformToBuilding
};
// 检查是否可以转换
if (!CanTransformNow())
{
command.Disable("无法在当前位置转换");
}
yield return command;
}
}
private string GetGizmoDescription()
{
string desc = Props.gizmoDesc;
if (restoreBuildingDef != null)
{
desc += $"\n\n将恢复为: {restoreBuildingDef.LabelCap}";
}
return desc;
}
private Texture2D GetGizmoIcon()
{
if (!Props.gizmoIconPath.NullOrEmpty())
{
return ContentFinder<Texture2D>.Get(Props.gizmoIconPath);
}
return TexCommand.Install;
}
private bool CanTransformNow()
{
if (parent == null || !parent.Spawned)
return false;
// 检查空间是否足够
ThingDef buildingDef = restoreBuildingDef ?? Props.targetBuildingDef;
if (buildingDef == null)
return false;
foreach (IntVec3 cell in GenAdj.CellsOccupiedBy(Pawn.Position, Rot4.North, buildingDef.Size))
{
if (!cell.InBounds(Pawn.Map) || !cell.Walkable(Pawn.Map) || cell.GetEdifice(Pawn.Map) != null)
{
return false;
}
}
return true;
}
public void TransformToBuilding()
{
if (Pawn == null || !Pawn.Spawned)
return;
Map map = Pawn.Map;
IntVec3 position = Pawn.Position;
Faction faction = Pawn.Faction;
// 确定要生成的建筑类型
ThingDef buildingDef = restoreBuildingDef ?? Props.targetBuildingDef;
if (buildingDef == null)
{
Messages.Message("无法确定目标建筑类型", MessageTypeDefOf.RejectInput);
return;
}
// 移除Pawn
Pawn.DeSpawn(DestroyMode.Vanish);
// 生成建筑
Building newBuilding = (Building)GenSpawn.Spawn(buildingDef, position, map, WipeMode.Vanish);
newBuilding.SetFaction(faction);
// 恢复机械族计数
var recycler = newBuilding as Building_MechanoidRecycler;
if (recycler != null && restoreMechanoidCount > 0)
{
recycler.SetMechanoidCount(restoreMechanoidCount);
}
// 添加建筑转换组件
var transformComp = newBuilding.TryGetComp<CompTransformAtFullCapacity>();
if (transformComp == null)
{
// 动态添加组件
var compProps = new CompProperties_TransformAtFullCapacity
{
targetPawnKind = Pawn.kindDef
};
transformComp = new CompTransformAtFullCapacity();
transformComp.parent = newBuilding;
transformComp.props = compProps;
newBuilding.AllComps.Add(transformComp);
transformComp.Initialize(compProps);
}
// 选中新生成的建筑
if (Find.Selector.IsSelected(Pawn))
{
Find.Selector.Select(newBuilding);
}
Messages.Message($"{Pawn.LabelCap} 已部署为 {newBuilding.Label}", MessageTypeDefOf.PositiveEvent);
// 播放转换效果
PlayTransformEffects(position, map);
}
private void PlayTransformEffects(IntVec3 position, Map map)
{
//// 播放转换视觉效果
//for (int i = 0; i < 3; i++)
//{
// MoteMaker.ThrowSmoke(position.ToVector3Shifted() + new Vector3(0, 0, 0.5f), map, 1.5f);
// MoteMaker.ThrowMicroSparks(position.ToVector3Shifted(), map);
//}
//// 播放音效
//SoundDefOf.MechClusterDefeated.PlayOneShot(new TargetInfo(position, map));
}
}
}