1
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user