1
This commit is contained in:
@@ -23,6 +23,9 @@ namespace WulaFallenEmpire
|
||||
public int StoredCount => storedMechanoidCount;
|
||||
public int MaxStorage => Props.maxStorageCapacity;
|
||||
public bool IsCooldownActive => Find.TickManager.TicksGame - spawnTick < 24 * 2500; // 24小时冷却
|
||||
|
||||
// 新增:检查是否属于玩家派系
|
||||
public bool IsPlayerFaction => this.Faction == Faction.OfPlayer;
|
||||
|
||||
// 生成初始单位(改为计数)
|
||||
private void SpawnInitialUnits()
|
||||
@@ -192,6 +195,10 @@ namespace WulaFallenEmpire
|
||||
foreach (Gizmo g in base.GetGizmos())
|
||||
yield return g;
|
||||
|
||||
// 新增:只有玩家派系才能看到和使用这些按钮
|
||||
if (!IsPlayerFaction)
|
||||
yield break;
|
||||
|
||||
// 回收附近机械族按钮
|
||||
Command_Action recycleCommand = new Command_Action
|
||||
{
|
||||
|
||||
@@ -24,10 +24,24 @@ namespace WulaFallenEmpire
|
||||
return _worldComponent;
|
||||
}
|
||||
}
|
||||
|
||||
private GlobalStorageWorldComponent _globalStorage;
|
||||
private GlobalStorageWorldComponent GlobalStorage
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_globalStorage == null)
|
||||
{
|
||||
_globalStorage = Find.World.GetComponent<GlobalStorageWorldComponent>();
|
||||
}
|
||||
return _globalStorage;
|
||||
}
|
||||
}
|
||||
|
||||
private bool used = false;
|
||||
private int callTick = -1;
|
||||
private bool calling = false;
|
||||
private bool usedGlobalStorage = false; // 新增:标记是否使用了全局储存器
|
||||
|
||||
public bool CanCall => !used && !calling;
|
||||
|
||||
@@ -119,6 +133,7 @@ namespace WulaFallenEmpire
|
||||
Scribe_Values.Look(ref used, "used", false);
|
||||
Scribe_Values.Look(ref callTick, "callTick", -1);
|
||||
Scribe_Values.Look(ref calling, "calling", false);
|
||||
Scribe_Values.Look(ref usedGlobalStorage, "usedGlobalStorage", false);
|
||||
}
|
||||
|
||||
public override void CompTick()
|
||||
@@ -166,7 +181,11 @@ namespace WulaFallenEmpire
|
||||
}
|
||||
else
|
||||
{
|
||||
Messages.Message("WULA_SkyfallerIncoming".Translate(delay.ToStringTicksToPeriod()), parent, MessageTypeDefOf.ThreatBig);
|
||||
// 修改:根据资源来源显示不同的消息
|
||||
string messageKey = usedGlobalStorage ?
|
||||
"WULA_SkyfallerIncomingFromGlobal" :
|
||||
"WULA_SkyfallerIncoming";
|
||||
Messages.Message(messageKey.Translate(delay.ToStringTicksToPeriod()), parent, MessageTypeDefOf.ThreatBig);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -175,6 +194,7 @@ namespace WulaFallenEmpire
|
||||
calling = false;
|
||||
used = false;
|
||||
callTick = -1;
|
||||
usedGlobalStorage = false;
|
||||
}
|
||||
|
||||
protected virtual void ExecuteSkyfallerCall()
|
||||
@@ -187,14 +207,17 @@ namespace WulaFallenEmpire
|
||||
return;
|
||||
}
|
||||
|
||||
if (!HasEnoughMaterials())
|
||||
// 修改:使用新的资源检查方法
|
||||
var resourceCheck = CheckAndConsumeMaterials();
|
||||
if (!resourceCheck.HasEnoughMaterials)
|
||||
{
|
||||
Log.Message($"[SkyfallerCaller] Aborting skyfaller call due to insufficient materials.");
|
||||
ResetCall();
|
||||
return;
|
||||
}
|
||||
|
||||
ConsumeMaterials();
|
||||
// 记录是否使用了全局储存器
|
||||
usedGlobalStorage = resourceCheck.UsedGlobalStorage;
|
||||
|
||||
// 检查屋顶并处理
|
||||
HandleRoofDestruction();
|
||||
@@ -251,18 +274,106 @@ namespace WulaFallenEmpire
|
||||
}
|
||||
}
|
||||
|
||||
protected bool HasEnoughMaterials()
|
||||
// 新增:资源检查结果结构
|
||||
protected struct ResourceCheckResult
|
||||
{
|
||||
if (DebugSettings.godMode) return true;
|
||||
public bool HasEnoughMaterials;
|
||||
public bool UsedGlobalStorage;
|
||||
public Dictionary<ThingDef, int> BeaconMaterials;
|
||||
public Dictionary<ThingDef, int> GlobalMaterials;
|
||||
}
|
||||
|
||||
// 修改:新的资源检查方法,优先检查信标附近,然后检查全局储存器
|
||||
protected ResourceCheckResult CheckAndConsumeMaterials()
|
||||
{
|
||||
var result = new ResourceCheckResult
|
||||
{
|
||||
HasEnoughMaterials = false,
|
||||
UsedGlobalStorage = false,
|
||||
BeaconMaterials = new Dictionary<ThingDef, int>(),
|
||||
GlobalMaterials = new Dictionary<ThingDef, int>()
|
||||
};
|
||||
|
||||
if (DebugSettings.godMode)
|
||||
{
|
||||
result.HasEnoughMaterials = true;
|
||||
return result;
|
||||
}
|
||||
|
||||
var costList = CostList;
|
||||
if (costList.NullOrEmpty())
|
||||
{
|
||||
return true;
|
||||
result.HasEnoughMaterials = true;
|
||||
return result;
|
||||
}
|
||||
|
||||
var availableThings = new List<Thing>();
|
||||
if (parent.Map == null) return false;
|
||||
if (parent.Map == null)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
// 第一步:收集信标附近的可用物资
|
||||
var beaconMaterials = CollectBeaconMaterials();
|
||||
result.BeaconMaterials = beaconMaterials;
|
||||
|
||||
// 第二步:检查信标附近物资是否足够
|
||||
bool beaconHasEnough = true;
|
||||
foreach (var cost in costList)
|
||||
{
|
||||
int availableInBeacon = beaconMaterials.ContainsKey(cost.thingDef) ? beaconMaterials[cost.thingDef] : 0;
|
||||
if (availableInBeacon < cost.count)
|
||||
{
|
||||
beaconHasEnough = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 第三步:如果信标附近物资足够,只消耗信标附近的
|
||||
if (beaconHasEnough)
|
||||
{
|
||||
ConsumeBeaconMaterials(beaconMaterials, costList);
|
||||
result.HasEnoughMaterials = true;
|
||||
result.UsedGlobalStorage = false;
|
||||
return result;
|
||||
}
|
||||
|
||||
// 第四步:如果信标附近物资不足,检查全局储存器
|
||||
var globalMaterials = CheckGlobalStorageMaterials();
|
||||
result.GlobalMaterials = globalMaterials;
|
||||
|
||||
bool globalHasEnough = true;
|
||||
foreach (var cost in costList)
|
||||
{
|
||||
int availableInBeacon = beaconMaterials.ContainsKey(cost.thingDef) ? beaconMaterials[cost.thingDef] : 0;
|
||||
int availableInGlobal = globalMaterials.ContainsKey(cost.thingDef) ? globalMaterials[cost.thingDef] : 0;
|
||||
|
||||
if (availableInBeacon + availableInGlobal < cost.count)
|
||||
{
|
||||
globalHasEnough = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (globalHasEnough)
|
||||
{
|
||||
// 先消耗信标附近的,不足部分从全局储存器扣除
|
||||
ConsumeMixedMaterials(beaconMaterials, globalMaterials, costList);
|
||||
result.HasEnoughMaterials = true;
|
||||
result.UsedGlobalStorage = true;
|
||||
return result;
|
||||
}
|
||||
|
||||
// 两种来源加起来都不够
|
||||
result.HasEnoughMaterials = false;
|
||||
return result;
|
||||
}
|
||||
|
||||
// 新增:收集信标附近的物资
|
||||
private Dictionary<ThingDef, int> CollectBeaconMaterials()
|
||||
{
|
||||
var materials = new Dictionary<ThingDef, int>();
|
||||
|
||||
if (parent.Map == null) return materials;
|
||||
|
||||
foreach (Building_OrbitalTradeBeacon beacon in Building_OrbitalTradeBeacon.AllPowered(parent.Map))
|
||||
{
|
||||
@@ -274,46 +385,49 @@ namespace WulaFallenEmpire
|
||||
Thing thing = thingList[i];
|
||||
if (thing.def.EverHaulable)
|
||||
{
|
||||
availableThings.Add(thing);
|
||||
if (materials.ContainsKey(thing.def))
|
||||
{
|
||||
materials[thing.def] += thing.stackCount;
|
||||
}
|
||||
else
|
||||
{
|
||||
materials[thing.def] = thing.stackCount;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
availableThings = availableThings.Distinct().ToList();
|
||||
|
||||
return materials;
|
||||
}
|
||||
|
||||
// 新增:检查全局储存器中的物资
|
||||
private Dictionary<ThingDef, int> CheckGlobalStorageMaterials()
|
||||
{
|
||||
var materials = new Dictionary<ThingDef, int>();
|
||||
|
||||
if (GlobalStorage == null) return materials;
|
||||
|
||||
var costList = CostList;
|
||||
if (costList.NullOrEmpty()) return materials;
|
||||
|
||||
foreach (var cost in costList)
|
||||
{
|
||||
int count = 0;
|
||||
foreach (var thing in availableThings)
|
||||
int globalCount = GlobalStorage.GetInputStorageCount(cost.thingDef);
|
||||
if (globalCount > 0)
|
||||
{
|
||||
if (thing.def == cost.thingDef)
|
||||
{
|
||||
count += thing.stackCount;
|
||||
}
|
||||
}
|
||||
if (count < cost.count)
|
||||
{
|
||||
return false;
|
||||
materials[cost.thingDef] = globalCount;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
return materials;
|
||||
}
|
||||
|
||||
protected void ConsumeMaterials()
|
||||
// 新增:只消耗信标附近的物资
|
||||
private void ConsumeBeaconMaterials(Dictionary<ThingDef, int> beaconMaterials, List<ThingDefCountClass> costList)
|
||||
{
|
||||
if (DebugSettings.godMode) return;
|
||||
|
||||
var costList = CostList;
|
||||
if (costList.NullOrEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var tradeableThings = new List<Thing>();
|
||||
if (parent.Map == null) return;
|
||||
|
||||
|
||||
foreach (Building_OrbitalTradeBeacon beacon in Building_OrbitalTradeBeacon.AllPowered(parent.Map))
|
||||
{
|
||||
foreach (IntVec3 cell in beacon.TradeableCells)
|
||||
@@ -329,13 +443,11 @@ namespace WulaFallenEmpire
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tradeableThings = tradeableThings.Distinct().ToList();
|
||||
|
||||
foreach (var cost in costList)
|
||||
{
|
||||
int remaining = cost.count;
|
||||
for (int i = tradeableThings.Count - 1; i >= 0; i--)
|
||||
for (int i = tradeableThings.Count - 1; i >= 0 && remaining > 0; i--)
|
||||
{
|
||||
var thing = tradeableThings[i];
|
||||
if (thing.def == cost.thingDef)
|
||||
@@ -349,16 +461,123 @@ namespace WulaFallenEmpire
|
||||
{
|
||||
remaining -= thing.stackCount;
|
||||
thing.Destroy();
|
||||
}
|
||||
if (remaining <= 0)
|
||||
{
|
||||
break;
|
||||
tradeableThings.RemoveAt(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 新增:混合消耗信标和全局储存器的物资
|
||||
private void ConsumeMixedMaterials(Dictionary<ThingDef, int> beaconMaterials, Dictionary<ThingDef, int> globalMaterials, List<ThingDefCountClass> costList)
|
||||
{
|
||||
// 先消耗信标附近的物资
|
||||
var tradeableThings = new List<Thing>();
|
||||
|
||||
foreach (Building_OrbitalTradeBeacon beacon in Building_OrbitalTradeBeacon.AllPowered(parent.Map))
|
||||
{
|
||||
foreach (IntVec3 cell in beacon.TradeableCells)
|
||||
{
|
||||
List<Thing> thingList = parent.Map.thingGrid.ThingsListAt(cell);
|
||||
for (int i = 0; i < thingList.Count; i++)
|
||||
{
|
||||
Thing thing = thingList[i];
|
||||
if (thing.def.EverHaulable)
|
||||
{
|
||||
tradeableThings.Add(thing);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 对每种所需材料进行处理
|
||||
foreach (var cost in costList)
|
||||
{
|
||||
int remaining = cost.count;
|
||||
|
||||
// 第一步:消耗信标附近的物资
|
||||
for (int i = tradeableThings.Count - 1; i >= 0 && remaining > 0; i--)
|
||||
{
|
||||
var thing = tradeableThings[i];
|
||||
if (thing.def == cost.thingDef)
|
||||
{
|
||||
if (thing.stackCount > remaining)
|
||||
{
|
||||
thing.SplitOff(remaining);
|
||||
remaining = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
remaining -= thing.stackCount;
|
||||
thing.Destroy();
|
||||
tradeableThings.RemoveAt(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 第二步:如果还有剩余,从全局储存器扣除
|
||||
if (remaining > 0 && GlobalStorage != null)
|
||||
{
|
||||
GlobalStorage.RemoveFromInputStorage(cost.thingDef, remaining);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 保留原有的 HasEnoughMaterials 方法用于 Gizmo 显示
|
||||
protected bool HasEnoughMaterials()
|
||||
{
|
||||
if (DebugSettings.godMode) return true;
|
||||
|
||||
var costList = CostList;
|
||||
if (costList.NullOrEmpty())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// 第一步:检查信标附近物资
|
||||
var beaconMaterials = CollectBeaconMaterials();
|
||||
bool beaconHasEnough = true;
|
||||
|
||||
foreach (var cost in costList)
|
||||
{
|
||||
int availableInBeacon = beaconMaterials.ContainsKey(cost.thingDef) ? beaconMaterials[cost.thingDef] : 0;
|
||||
if (availableInBeacon < cost.count)
|
||||
{
|
||||
beaconHasEnough = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (beaconHasEnough) return true;
|
||||
|
||||
// 第二步:检查全局储存器(如果信标附近不够)
|
||||
if (GlobalStorage == null) return false;
|
||||
|
||||
foreach (var cost in costList)
|
||||
{
|
||||
int availableInBeacon = beaconMaterials.ContainsKey(cost.thingDef) ? beaconMaterials[cost.thingDef] : 0;
|
||||
int availableInGlobal = GlobalStorage.GetInputStorageCount(cost.thingDef);
|
||||
|
||||
if (availableInBeacon + availableInGlobal < cost.count)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// 原有的 ConsumeMaterials 方法现在只用于 God Mode 情况
|
||||
protected void ConsumeMaterials()
|
||||
{
|
||||
if (DebugSettings.godMode) return;
|
||||
|
||||
// 在非 God Mode 下,这个方法不应该被调用
|
||||
// 实际的消耗在 CheckAndConsumeMaterials 中处理
|
||||
Log.Warning("[SkyfallerCaller] ConsumeMaterials called in non-God mode, this shouldn't happen");
|
||||
}
|
||||
|
||||
// 其余方法保持不变...
|
||||
private string GetCostString()
|
||||
{
|
||||
var costList = CostList;
|
||||
@@ -379,6 +598,7 @@ namespace WulaFallenEmpire
|
||||
calling = false;
|
||||
used = false;
|
||||
callTick = -1;
|
||||
usedGlobalStorage = false;
|
||||
Messages.Message("WULA_SkyfallerCallCancelled".Translate(), parent, MessageTypeDefOf.NeutralEvent);
|
||||
}
|
||||
|
||||
@@ -451,6 +671,9 @@ namespace WulaFallenEmpire
|
||||
sb.Append(costString);
|
||||
}
|
||||
|
||||
// 新增:显示资源来源信息
|
||||
sb.AppendLine().AppendLine().Append("WULA_ResourcePriorityInfo".Translate());
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
@@ -501,7 +724,10 @@ namespace WulaFallenEmpire
|
||||
int ticksLeft = callTick - Find.TickManager.TicksGame;
|
||||
if (ticksLeft > 0)
|
||||
{
|
||||
sb.Append("WULA_SkyfallerArrivingIn".Translate(ticksLeft.ToStringTicksToPeriod()));
|
||||
string messageKey = usedGlobalStorage ?
|
||||
"WULA_SkyfallerArrivingInFromGlobal" :
|
||||
"WULA_SkyfallerArrivingIn";
|
||||
sb.Append(messageKey.Translate(ticksLeft.ToStringTicksToPeriod()));
|
||||
}
|
||||
}
|
||||
else if (!used)
|
||||
|
||||
@@ -83,22 +83,34 @@ namespace WulaFallenEmpire
|
||||
}
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
public void TransformToPawn()
|
||||
{
|
||||
if (Recycler == null || !parent.Spawned)
|
||||
return;
|
||||
|
||||
Map map = parent.Map;
|
||||
IntVec3 position = parent.Position;
|
||||
Faction faction = parent.Faction;
|
||||
|
||||
// 记录建筑定义用于后续更新
|
||||
ThingDef buildingDef = parent.def;
|
||||
// 消耗存储的机械族
|
||||
if (!Recycler.ConsumeMechanoids(Props.requiredCapacity))
|
||||
{
|
||||
Messages.Message("WULA_NotEnoughMechs".Translate(), MessageTypeDefOf.RejectInput);
|
||||
return;
|
||||
}
|
||||
|
||||
// 生成目标Pawn
|
||||
PawnGenerationRequest request = new PawnGenerationRequest(
|
||||
Props.targetPawnKind,
|
||||
@@ -111,9 +123,8 @@ namespace WulaFallenEmpire
|
||||
canGeneratePawnRelations: false,
|
||||
mustBeCapableOfViolence: true
|
||||
);
|
||||
|
||||
Pawn newPawn = PawnGenerator.GeneratePawn(request);
|
||||
|
||||
|
||||
// 关键修改:传递当前的机械族数量(6个)
|
||||
var transformComp = newPawn.GetComp<CompTransformIntoBuilding>();
|
||||
if (transformComp != null)
|
||||
@@ -136,37 +147,24 @@ namespace WulaFallenEmpire
|
||||
// 传递建筑定义和机械族数量
|
||||
transformComp.SetRestoreData(parent.def, Props.requiredCapacity);
|
||||
}
|
||||
|
||||
// 移除建筑
|
||||
parent.DeSpawn(DestroyMode.Vanish);
|
||||
|
||||
|
||||
// 生成Pawn
|
||||
GenSpawn.Spawn(newPawn, position, map, WipeMode.Vanish);
|
||||
|
||||
|
||||
// 选中新生成的Pawn
|
||||
if (Find.Selector.IsSelected(parent))
|
||||
{
|
||||
Find.Selector.Select(newPawn);
|
||||
}
|
||||
|
||||
Messages.Message("WULA_BuildingTransformedToPawn".Translate(parent.Label, newPawn.LabelCap, Props.requiredCapacity),
|
||||
Messages.Message("WULA_BuildingTransformedToPawn".Translate(parent.Label, newPawn.LabelCap, Props.requiredCapacity),
|
||||
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));
|
||||
Log.Message($"[TransformSystem] Building -> Pawn transformation completed at {position}. Path grid updated.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -77,7 +77,6 @@ namespace WulaFallenEmpire
|
||||
|
||||
// 显示恢复的机械族数量
|
||||
sb.AppendLine();
|
||||
sb.Append("WULA_RestoreMechCount".Translate(restoreMechCount));
|
||||
|
||||
// 显示目标建筑的最大存储容量
|
||||
var recyclerProps = restoreBuildingDef.GetCompProperties<CompProperties_MechanoidRecycler>();
|
||||
@@ -195,88 +194,6 @@ namespace WulaFallenEmpire
|
||||
return false;
|
||||
}
|
||||
|
||||
public void TransformToBuilding()
|
||||
{
|
||||
if (Pawn == null || !Pawn.Spawned)
|
||||
return;
|
||||
|
||||
Map map = Pawn.Map;
|
||||
IntVec3 desiredPosition = Pawn.Position;
|
||||
Faction faction = Pawn.Faction;
|
||||
|
||||
// 确定要生成的建筑类型
|
||||
ThingDef buildingDef = restoreBuildingDef ?? Props.targetBuildingDef;
|
||||
if (buildingDef == null)
|
||||
{
|
||||
Messages.Message("WULA_CannotDetermineBuildingType".Translate(), MessageTypeDefOf.RejectInput);
|
||||
return;
|
||||
}
|
||||
|
||||
// 最终校验(排除被转换的Pawn本身)
|
||||
string failReason;
|
||||
if (!TransformValidationUtility.CanPlaceBuildingAt(buildingDef, desiredPosition, map, faction, Pawn, out failReason))
|
||||
{
|
||||
// 尝试寻找附近的位置
|
||||
IntVec3 alternativePosition;
|
||||
if (TryFindNearbyValidPosition(out alternativePosition, out failReason))
|
||||
{
|
||||
desiredPosition = alternativePosition;
|
||||
Messages.Message("WULA_DeployingAtNearbyPosition".Translate(desiredPosition), MessageTypeDefOf.NeutralEvent);
|
||||
}
|
||||
else
|
||||
{
|
||||
Messages.Message("WULA_CannotDeployBuilding".Translate(failReason), MessageTypeDefOf.RejectInput);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// 移除Pawn
|
||||
Pawn.DeSpawn(DestroyMode.Vanish);
|
||||
|
||||
// 生成建筑
|
||||
Building newBuilding = (Building)GenSpawn.Spawn(buildingDef, desiredPosition, map, WipeMode.Vanish);
|
||||
newBuilding.SetFaction(faction);
|
||||
|
||||
// 关键修改:恢复机械族数量
|
||||
var recycler = newBuilding as Building_MechanoidRecycler;
|
||||
if (recycler != null)
|
||||
{
|
||||
recycler.SetMechanoidCount(restoreMechCount);
|
||||
}
|
||||
|
||||
// 添加建筑转换组件
|
||||
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("WULA_PawnDeployedAsBuilding".Translate(Pawn.LabelCap, newBuilding.Label, restoreMechCount),
|
||||
MessageTypeDefOf.PositiveEvent);
|
||||
|
||||
// 播放转换效果
|
||||
PlayTransformEffects(desiredPosition, map);
|
||||
|
||||
// 清除缓存
|
||||
lastValidationResult = null;
|
||||
lastValidationReason = null;
|
||||
}
|
||||
|
||||
private void PlayTransformEffects(IntVec3 position, Map map)
|
||||
{
|
||||
// 播放转换视觉效果
|
||||
@@ -298,5 +215,80 @@ namespace WulaFallenEmpire
|
||||
lastValidationResult = null;
|
||||
}
|
||||
}
|
||||
|
||||
public void TransformToBuilding()
|
||||
{
|
||||
if (Pawn == null || !Pawn.Spawned)
|
||||
return;
|
||||
Map map = Pawn.Map;
|
||||
IntVec3 desiredPosition = Pawn.Position;
|
||||
Faction faction = Pawn.Faction;
|
||||
// 确定要生成的建筑类型
|
||||
ThingDef buildingDef = restoreBuildingDef ?? Props.targetBuildingDef;
|
||||
if (buildingDef == null)
|
||||
{
|
||||
Messages.Message("WULA_CannotDetermineBuildingType".Translate(), MessageTypeDefOf.RejectInput);
|
||||
return;
|
||||
}
|
||||
// 最终校验(排除被转换的Pawn本身)
|
||||
string failReason;
|
||||
if (!TransformValidationUtility.CanPlaceBuildingAt(buildingDef, desiredPosition, map, faction, Pawn, out failReason))
|
||||
{
|
||||
// 尝试寻找附近的位置
|
||||
IntVec3 alternativePosition;
|
||||
if (TryFindNearbyValidPosition(out alternativePosition, out failReason))
|
||||
{
|
||||
desiredPosition = alternativePosition;
|
||||
Messages.Message("WULA_DeployingAtNearbyPosition".Translate(desiredPosition), MessageTypeDefOf.NeutralEvent);
|
||||
}
|
||||
else
|
||||
{
|
||||
Messages.Message("WULA_CannotDeployBuilding".Translate(failReason), MessageTypeDefOf.RejectInput);
|
||||
return;
|
||||
}
|
||||
}
|
||||
// 移除Pawn
|
||||
Pawn.DeSpawn(DestroyMode.Vanish);
|
||||
// 生成建筑
|
||||
Building newBuilding = (Building)GenSpawn.Spawn(buildingDef, desiredPosition, map, WipeMode.Vanish);
|
||||
newBuilding.SetFaction(faction);
|
||||
// 关键修改:恢复机械族数量
|
||||
var recycler = newBuilding as Building_MechanoidRecycler;
|
||||
if (recycler != null)
|
||||
{
|
||||
recycler.SetMechanoidCount(restoreMechCount);
|
||||
}
|
||||
// 添加建筑转换组件
|
||||
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("WULA_PawnDeployedAsBuilding".Translate(Pawn.LabelCap, newBuilding.Label, restoreMechCount),
|
||||
MessageTypeDefOf.PositiveEvent);
|
||||
|
||||
// 播放转换效果
|
||||
PlayTransformEffects(desiredPosition, map);
|
||||
|
||||
// 清除缓存
|
||||
lastValidationResult = null;
|
||||
lastValidationReason = null;
|
||||
|
||||
Log.Message($"[TransformSystem] Pawn -> Building transformation completed at {desiredPosition}. Path grid updated.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user