各种更新
This commit is contained in:
@@ -11,6 +11,12 @@ namespace WulaFallenEmpire
|
||||
public int aircraftCount = 1; // 起飞后提供的战机数量
|
||||
public ThingDef skyfallerLeaving; // 起飞时的天空坠落者效果
|
||||
|
||||
// 新增:自动发射配置
|
||||
public bool autoLaunchEnabled = false; // 是否启用自动发射
|
||||
public int autoLaunchDelayTicks = 600; // 自动发射延迟(ticks,默认10秒)
|
||||
public bool autoLaunchOnConstruction = true; // 建造完成后自动发射
|
||||
public bool autoLaunchOnPowerOn = false; // 通电时自动发射
|
||||
|
||||
public CompProperties_AircraftHangar()
|
||||
{
|
||||
compClass = typeof(CompAircraftHangar);
|
||||
@@ -21,6 +27,86 @@ namespace WulaFallenEmpire
|
||||
{
|
||||
public CompProperties_AircraftHangar Props => (CompProperties_AircraftHangar)props;
|
||||
|
||||
// 新增:自动发射状态
|
||||
private bool autoLaunchScheduled = false;
|
||||
private int autoLaunchTick = -1;
|
||||
private bool hasLaunched = false;
|
||||
|
||||
public override void PostSpawnSetup(bool respawningAfterLoad)
|
||||
{
|
||||
base.PostSpawnSetup(respawningAfterLoad);
|
||||
|
||||
if (!respawningAfterLoad && Props.autoLaunchEnabled && Props.autoLaunchOnConstruction)
|
||||
{
|
||||
ScheduleAutoLaunch();
|
||||
}
|
||||
}
|
||||
|
||||
public override void PostExposeData()
|
||||
{
|
||||
base.PostExposeData();
|
||||
Scribe_Values.Look(ref autoLaunchScheduled, "autoLaunchScheduled", false);
|
||||
Scribe_Values.Look(ref autoLaunchTick, "autoLaunchTick", -1);
|
||||
Scribe_Values.Look(ref hasLaunched, "hasLaunched", false);
|
||||
}
|
||||
|
||||
public override void CompTick()
|
||||
{
|
||||
base.CompTick();
|
||||
|
||||
// 处理自动发射
|
||||
if (Props.autoLaunchEnabled && !hasLaunched)
|
||||
{
|
||||
HandleAutoLaunch();
|
||||
}
|
||||
}
|
||||
|
||||
// 新增:自动发射处理
|
||||
private void HandleAutoLaunch()
|
||||
{
|
||||
// 检查预定发射
|
||||
if (autoLaunchScheduled && Find.TickManager.TicksGame >= autoLaunchTick)
|
||||
{
|
||||
LaunchAircraft();
|
||||
return;
|
||||
}
|
||||
|
||||
// 检查通电自动发射
|
||||
if (Props.autoLaunchOnPowerOn && IsPoweredOn() && !autoLaunchScheduled)
|
||||
{
|
||||
ScheduleAutoLaunch();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// 新增:检查电力状态
|
||||
private bool IsPoweredOn()
|
||||
{
|
||||
var powerComp = parent.GetComp<CompPowerTrader>();
|
||||
return powerComp != null && powerComp.PowerOn;
|
||||
}
|
||||
|
||||
// 新增:预定自动发射
|
||||
private void ScheduleAutoLaunch()
|
||||
{
|
||||
if (hasLaunched || autoLaunchScheduled)
|
||||
return;
|
||||
|
||||
autoLaunchScheduled = true;
|
||||
autoLaunchTick = Find.TickManager.TicksGame + Props.autoLaunchDelayTicks;
|
||||
|
||||
Messages.Message("AircraftAutoLaunchScheduled".Translate(Props.aircraftDef.LabelCap, (Props.autoLaunchDelayTicks / 60f).ToString("F1")), parent, MessageTypeDefOf.NeutralEvent);
|
||||
}
|
||||
|
||||
// 新增:强制立即发射(用于调试或其他系统调用)
|
||||
public void ForceLaunch()
|
||||
{
|
||||
if (!hasLaunched)
|
||||
{
|
||||
LaunchAircraft();
|
||||
}
|
||||
}
|
||||
|
||||
public override IEnumerable<Gizmo> CompGetGizmosExtra()
|
||||
{
|
||||
foreach (Gizmo gizmo in base.CompGetGizmosExtra())
|
||||
@@ -28,7 +114,11 @@ namespace WulaFallenEmpire
|
||||
yield return gizmo;
|
||||
}
|
||||
|
||||
// 起飞命令
|
||||
// 如果已经发射,不显示任何按钮
|
||||
if (hasLaunched)
|
||||
yield break;
|
||||
|
||||
// 手动发射命令
|
||||
Command_Action launchCommand = new Command_Action
|
||||
{
|
||||
defaultLabel = "LaunchAircraft".Translate(),
|
||||
@@ -46,8 +136,28 @@ namespace WulaFallenEmpire
|
||||
yield return launchCommand;
|
||||
}
|
||||
|
||||
// 新增:切换自动发射状态
|
||||
private void ToggleAutoLaunch()
|
||||
{
|
||||
if (autoLaunchScheduled)
|
||||
{
|
||||
// 取消预定发射
|
||||
autoLaunchScheduled = false;
|
||||
autoLaunchTick = -1;
|
||||
Messages.Message("AutoLaunchCancelled".Translate(), parent, MessageTypeDefOf.NeutralEvent);
|
||||
}
|
||||
else
|
||||
{
|
||||
// 预定发射
|
||||
ScheduleAutoLaunch();
|
||||
}
|
||||
}
|
||||
|
||||
private void LaunchAircraft()
|
||||
{
|
||||
if (hasLaunched)
|
||||
return;
|
||||
|
||||
// 获取全局战机管理器
|
||||
WorldComponent_AircraftManager aircraftManager = Find.World.GetComponent<WorldComponent_AircraftManager>();
|
||||
|
||||
@@ -61,7 +171,7 @@ namespace WulaFallenEmpire
|
||||
aircraftManager.AddAircraft(Props.aircraftDef, Props.aircraftCount, parent.Faction);
|
||||
|
||||
// 显示消息
|
||||
Messages.Message("AircraftLaunched".Translate(Props.aircraftCount, Props.aircraftDef.LabelCap), MessageTypeDefOf.PositiveEvent);
|
||||
Messages.Message("AircraftLaunched".Translate(Props.aircraftCount, Props.aircraftDef.LabelCap), parent, MessageTypeDefOf.PositiveEvent);
|
||||
|
||||
// 创建起飞效果(仅视觉效果)
|
||||
if (Props.skyfallerLeaving != null)
|
||||
@@ -73,6 +183,9 @@ namespace WulaFallenEmpire
|
||||
// 如果没有定义 Skyfaller,直接销毁建筑
|
||||
parent.Destroy();
|
||||
}
|
||||
|
||||
hasLaunched = true;
|
||||
autoLaunchScheduled = false;
|
||||
}
|
||||
|
||||
private void CreateTakeoffEffect()
|
||||
@@ -112,10 +225,30 @@ namespace WulaFallenEmpire
|
||||
}
|
||||
}
|
||||
|
||||
public override void PostExposeData()
|
||||
// 新增:检查是否已经发射
|
||||
public bool HasLaunched => hasLaunched;
|
||||
|
||||
// 新增:获取自动发射状态信息(用于检查字符串)
|
||||
public override string CompInspectStringExtra()
|
||||
{
|
||||
base.PostExposeData();
|
||||
// 不需要保存状态,因为建筑起飞后就销毁了
|
||||
if (hasLaunched)
|
||||
return "AircraftStatusLaunched".Translate();
|
||||
|
||||
if (Props.autoLaunchEnabled)
|
||||
{
|
||||
if (autoLaunchScheduled)
|
||||
{
|
||||
int ticksRemaining = autoLaunchTick - Find.TickManager.TicksGame;
|
||||
float secondsRemaining = ticksRemaining / 60f;
|
||||
return "AutoLaunchScheduled".Translate(secondsRemaining.ToString("F1"));
|
||||
}
|
||||
else
|
||||
{
|
||||
return "AutoLaunchReady".Translate();
|
||||
}
|
||||
}
|
||||
|
||||
return base.CompInspectStringExtra();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,243 +0,0 @@
|
||||
using RimWorld;
|
||||
using Verse;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace WulaFallenEmpire
|
||||
{
|
||||
public class CompProperties_AutoLaunchHangar : CompProperties
|
||||
{
|
||||
public ThingDef aircraftDef; // 对应的战机定义
|
||||
public int aircraftCount = 1; // 起飞后提供的战机数量
|
||||
public ThingDef skyfallerLeaving; // 起飞时的天空坠落者效果
|
||||
public int launchDelayTicks = 60; // 延迟启动的ticks(默认1秒)
|
||||
public bool requirePower = true; // 是否需要电力才能启动
|
||||
|
||||
public CompProperties_AutoLaunchHangar()
|
||||
{
|
||||
compClass = typeof(CompAutoLaunchHangar);
|
||||
}
|
||||
}
|
||||
|
||||
public class CompAutoLaunchHangar : ThingComp
|
||||
{
|
||||
public CompProperties_AutoLaunchHangar Props => (CompProperties_AutoLaunchHangar)props;
|
||||
private bool hasLaunched = false;
|
||||
private int spawnTick = -1;
|
||||
|
||||
private CompPowerTrader powerComp;
|
||||
private CompRefuelable refuelableComp;
|
||||
|
||||
public override void PostSpawnSetup(bool respawningAfterLoad)
|
||||
{
|
||||
base.PostSpawnSetup(respawningAfterLoad);
|
||||
|
||||
if (!respawningAfterLoad)
|
||||
{
|
||||
// 记录生成时间
|
||||
spawnTick = Find.TickManager.TicksAbs;
|
||||
hasLaunched = false;
|
||||
|
||||
// 缓存其他组件
|
||||
powerComp = parent.GetComp<CompPowerTrader>();
|
||||
refuelableComp = parent.GetComp<CompRefuelable>();
|
||||
|
||||
Log.Message($"AutoLaunchHangar spawned at tick {spawnTick}, will launch in {Props.launchDelayTicks} ticks");
|
||||
}
|
||||
}
|
||||
|
||||
public override void PostExposeData()
|
||||
{
|
||||
base.PostExposeData();
|
||||
Scribe_Values.Look(ref hasLaunched, "hasLaunched", false);
|
||||
Scribe_Values.Look(ref spawnTick, "spawnTick", -1);
|
||||
}
|
||||
|
||||
public override void CompTick()
|
||||
{
|
||||
base.CompTick();
|
||||
|
||||
if (hasLaunched || spawnTick == -1)
|
||||
return;
|
||||
|
||||
int currentTick = Find.TickManager.TicksAbs;
|
||||
if (currentTick - spawnTick >= Props.launchDelayTicks)
|
||||
{
|
||||
if (CanAutoLaunch())
|
||||
{
|
||||
AutoLaunchAircraft();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private bool CanAutoLaunch()
|
||||
{
|
||||
// 检查建筑是否完好
|
||||
if (parent.HitPoints <= 0)
|
||||
{
|
||||
Log.Message("AutoLaunch: Hangar is damaged, cannot launch");
|
||||
return false;
|
||||
}
|
||||
|
||||
// 检查电力需求
|
||||
if (Props.requirePower && powerComp != null && !powerComp.PowerOn)
|
||||
{
|
||||
Log.Message("AutoLaunch: No power, cannot launch");
|
||||
return false;
|
||||
}
|
||||
|
||||
// 检查燃料需求
|
||||
if (refuelableComp != null && !refuelableComp.HasFuel)
|
||||
{
|
||||
Log.Message("AutoLaunch: No fuel, cannot launch");
|
||||
return false;
|
||||
}
|
||||
|
||||
// 检查地图是否有效
|
||||
if (parent.Map == null)
|
||||
{
|
||||
Log.Message("AutoLaunch: Map is null, cannot launch");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void AutoLaunchAircraft()
|
||||
{
|
||||
Log.Message($"AutoLaunch: Starting aircraft launch sequence for {parent.Label}");
|
||||
|
||||
// 获取全局战机管理器
|
||||
WorldComponent_AircraftManager aircraftManager = Find.World.GetComponent<WorldComponent_AircraftManager>();
|
||||
|
||||
if (aircraftManager == null)
|
||||
{
|
||||
Log.Error("AutoLaunch: AircraftManager not found");
|
||||
hasLaunched = true;
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
// 立即向全局管理器注册战机
|
||||
aircraftManager.AddAircraft(Props.aircraftDef, Props.aircraftCount, parent.Faction);
|
||||
|
||||
// 显示消息
|
||||
Messages.Message("AircraftAutoLaunched".Translate(Props.aircraftCount, Props.aircraftDef.LabelCap),
|
||||
parent, MessageTypeDefOf.PositiveEvent);
|
||||
|
||||
Log.Message($"AutoLaunch: Successfully added {Props.aircraftCount} {Props.aircraftDef.LabelCap} to global manager");
|
||||
|
||||
// 创建起飞效果
|
||||
if (Props.skyfallerLeaving != null)
|
||||
{
|
||||
CreateAutoTakeoffEffect();
|
||||
}
|
||||
else
|
||||
{
|
||||
// 如果没有定义 Skyfaller,直接销毁建筑
|
||||
parent.Destroy();
|
||||
}
|
||||
|
||||
hasLaunched = true;
|
||||
}
|
||||
catch (System.Exception ex)
|
||||
{
|
||||
Log.Error($"AutoLaunch error: {ex}");
|
||||
hasLaunched = true; // 标记为已启动,避免重复尝试
|
||||
}
|
||||
}
|
||||
|
||||
private void CreateAutoTakeoffEffect()
|
||||
{
|
||||
try
|
||||
{
|
||||
// 创建起飞效果
|
||||
Thing chemfuel = ThingMaker.MakeThing(ThingDefOf.Chemfuel);
|
||||
chemfuel.stackCount = 1;
|
||||
|
||||
Skyfaller skyfaller = SkyfallerMaker.MakeSkyfaller(Props.skyfallerLeaving, chemfuel);
|
||||
|
||||
IntVec3 takeoffPos = parent.Position;
|
||||
|
||||
if (parent.Map == null)
|
||||
{
|
||||
Log.Error("AutoLaunch: Map is null during takeoff effect creation");
|
||||
parent.Destroy();
|
||||
return;
|
||||
}
|
||||
|
||||
// 生成 Skyfaller
|
||||
GenSpawn.Spawn(skyfaller, takeoffPos, parent.Map);
|
||||
|
||||
Log.Message($"AutoLaunch: Takeoff effect created at {takeoffPos}");
|
||||
|
||||
// 销毁原建筑
|
||||
parent.Destroy(DestroyMode.Vanish);
|
||||
}
|
||||
catch (System.Exception ex)
|
||||
{
|
||||
Log.Error($"AutoLaunch takeoff effect error: {ex}");
|
||||
// 如果Skyfaller创建失败,直接销毁建筑
|
||||
parent.Destroy(DestroyMode.Vanish);
|
||||
}
|
||||
}
|
||||
|
||||
// 可选:提供手动触发的Gizmo(如果自动触发失败)
|
||||
public override IEnumerable<Gizmo> CompGetGizmosExtra()
|
||||
{
|
||||
if (!hasLaunched)
|
||||
{
|
||||
Command_Action manualLaunch = new Command_Action
|
||||
{
|
||||
defaultLabel = "ManualLaunchAircraft".Translate(),
|
||||
defaultDesc = "ManualLaunchAircraftDesc".Translate(),
|
||||
icon = TexCommand.Attack,
|
||||
action = () =>
|
||||
{
|
||||
if (CanAutoLaunch())
|
||||
{
|
||||
AutoLaunchAircraft();
|
||||
}
|
||||
else
|
||||
{
|
||||
Messages.Message("CannotManualLaunch".Translate(), MessageTypeDefOf.RejectInput);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// 禁用条件检查
|
||||
if (parent.HitPoints <= 0)
|
||||
{
|
||||
manualLaunch.Disable("HangarDamaged".Translate());
|
||||
}
|
||||
else if (Props.requirePower && powerComp != null && !powerComp.PowerOn)
|
||||
{
|
||||
manualLaunch.Disable("NoPower".Translate());
|
||||
}
|
||||
else if (refuelableComp != null && !refuelableComp.HasFuel)
|
||||
{
|
||||
manualLaunch.Disable("NoFuel".Translate());
|
||||
}
|
||||
|
||||
yield return manualLaunch;
|
||||
}
|
||||
}
|
||||
|
||||
public override string CompInspectStringExtra()
|
||||
{
|
||||
if (!hasLaunched)
|
||||
{
|
||||
int remainingTicks = Props.launchDelayTicks - (Find.TickManager.TicksAbs - spawnTick);
|
||||
if (remainingTicks > 0)
|
||||
{
|
||||
return "AutoLaunchIn".Translate(remainingTicks.ToStringTicksToPeriod());
|
||||
}
|
||||
else
|
||||
{
|
||||
return "AutoLaunchReady".Translate();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using Verse;
|
||||
using Verse.Sound;
|
||||
using System.Text;
|
||||
|
||||
namespace WulaFallenEmpire
|
||||
{
|
||||
@@ -58,19 +59,105 @@ namespace WulaFallenEmpire
|
||||
return;
|
||||
}
|
||||
|
||||
// 1. 将物品转移到全局存储
|
||||
// 统计发送的物品
|
||||
int inputItemsCount = 0;
|
||||
int outputItemsCount = 0;
|
||||
StringBuilder inputItemsList = new StringBuilder();
|
||||
StringBuilder outputItemsList = new StringBuilder();
|
||||
|
||||
// 1. 将物品分类转移到相应的存储
|
||||
foreach (Thing item in transporter.innerContainer)
|
||||
{
|
||||
globalStorage.AddToInputStorage(item.def, item.stackCount);
|
||||
if (ShouldGoToOutputStorage(item))
|
||||
{
|
||||
// 发送到输出存储器
|
||||
globalStorage.AddToOutputStorage(item.def, item.stackCount);
|
||||
outputItemsCount += item.stackCount;
|
||||
if (outputItemsList.Length > 0) outputItemsList.Append(", ");
|
||||
outputItemsList.Append($"{item.LabelCap} x{item.stackCount}");
|
||||
}
|
||||
else
|
||||
{
|
||||
// 发送到输入存储器
|
||||
globalStorage.AddToInputStorage(item.def, item.stackCount);
|
||||
inputItemsCount += item.stackCount;
|
||||
if (inputItemsList.Length > 0) inputItemsList.Append(", ");
|
||||
inputItemsList.Append($"{item.LabelCap} x{item.stackCount}");
|
||||
}
|
||||
}
|
||||
Messages.Message("WULA_ItemsSentToGlobalStorage".Translate(transporter.innerContainer.ContentsString), this.parent, MessageTypeDefOf.PositiveEvent);
|
||||
|
||||
// 2. 清空容器,防止物品掉落
|
||||
// 2. 显示发送结果消息
|
||||
string message = BuildTransferMessage(inputItemsCount, outputItemsCount, inputItemsList.ToString(), outputItemsList.ToString());
|
||||
Messages.Message(message, this.parent, MessageTypeDefOf.PositiveEvent);
|
||||
|
||||
// 3. 清空容器,防止物品掉落
|
||||
transporter.innerContainer.ClearAndDestroyContents();
|
||||
|
||||
// 3. 调用基类的发射方法,让它处理动画和销毁
|
||||
// 我们给一个无效的目标和空的到达动作,让它飞出地图后就消失
|
||||
// 4. 调用基类的发射方法,让它处理动画和销毁
|
||||
base.TryLaunch(this.parent.Map.Tile, null);
|
||||
}
|
||||
|
||||
// 判断物品是否应该发送到输出存储器
|
||||
private bool ShouldGoToOutputStorage(Thing item)
|
||||
{
|
||||
// 武器
|
||||
if (item.def.IsWeapon)
|
||||
return true;
|
||||
|
||||
// 装备
|
||||
if (item.def.IsApparel)
|
||||
return true;
|
||||
|
||||
// 活着的Pawn
|
||||
//if (item is Pawn pawn && !pawn.Dead)
|
||||
// return true;
|
||||
|
||||
// Pawn的尸体
|
||||
if (item.def.IsCorpse)
|
||||
return true;
|
||||
|
||||
// 其他物品发送到输入存储器
|
||||
return false;
|
||||
}
|
||||
|
||||
// 构建转移消息
|
||||
private string BuildTransferMessage(int inputCount, int outputCount, string inputList, string outputList)
|
||||
{
|
||||
StringBuilder message = new StringBuilder();
|
||||
|
||||
if (inputCount > 0 && outputCount > 0)
|
||||
{
|
||||
// 既有输入又有输出物品
|
||||
message.Append("WULA_ItemsSentToBothStorages".Translate(inputCount, outputCount));
|
||||
if (!string.IsNullOrEmpty(inputList))
|
||||
{
|
||||
message.Append("\n").Append("WULA_InputStorageItems".Translate(inputList));
|
||||
}
|
||||
if (!string.IsNullOrEmpty(outputList))
|
||||
{
|
||||
message.Append("\n").Append("WULA_OutputStorageItems".Translate(outputList));
|
||||
}
|
||||
}
|
||||
else if (inputCount > 0)
|
||||
{
|
||||
// 只有输入物品
|
||||
message.Append("WULA_ItemsSentToInputStorage".Translate(inputCount));
|
||||
if (!string.IsNullOrEmpty(inputList))
|
||||
{
|
||||
message.Append(": ").Append(inputList);
|
||||
}
|
||||
}
|
||||
else if (outputCount > 0)
|
||||
{
|
||||
// 只有输出物品
|
||||
message.Append("WULA_ItemsSentToOutputStorage".Translate(outputCount));
|
||||
if (!string.IsNullOrEmpty(outputList))
|
||||
{
|
||||
message.Append(": ").Append(outputList);
|
||||
}
|
||||
}
|
||||
|
||||
return message.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,19 +36,19 @@ namespace WulaFallenEmpire
|
||||
Text.Font = GameFont.Small;
|
||||
|
||||
// 存储查看按钮 - 放在标题旁边
|
||||
Rect storageButtonRect = new Rect(mainRect.xMax - 120f, mainRect.y, 120f, 25f);
|
||||
Rect storageButtonRect = new Rect(mainRect.xMax - 160f, mainRect.y, 120f, 25f);
|
||||
DoStorageButton(storageButtonRect);
|
||||
|
||||
// 开发模式按钮区域
|
||||
if (Prefs.DevMode)
|
||||
// 上帝模式按钮区域
|
||||
if (DebugSettings.godMode)
|
||||
{
|
||||
Rect devButtonRect = new Rect(mainRect.x, mainRect.y + 35f, mainRect.width, 25f);
|
||||
DoDevButtons(devButtonRect);
|
||||
Rect godModeButtonRect = new Rect(mainRect.x, mainRect.y + 35f, mainRect.width, 25f);
|
||||
DoGodModeButtons(godModeButtonRect);
|
||||
}
|
||||
|
||||
// 订单列表区域 - 调整位置
|
||||
float ordersRectY = Prefs.DevMode ? mainRect.y + 65f : mainRect.y + 35f;
|
||||
Rect ordersRect = new Rect(mainRect.x, ordersRectY, mainRect.width, mainRect.height - (Prefs.DevMode ? 110f : 80f));
|
||||
float ordersRectY = DebugSettings.godMode ? mainRect.y + 65f : mainRect.y + 35f;
|
||||
Rect ordersRect = new Rect(mainRect.x, ordersRectY, mainRect.width, mainRect.height - (DebugSettings.godMode ? 110f : 80f));
|
||||
mouseoverOrder = DoOrdersListing(ordersRect);
|
||||
|
||||
// 添加订单按钮
|
||||
@@ -148,17 +148,18 @@ namespace WulaFallenEmpire
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
private void DoDevButtons(Rect rect)
|
||||
// 修改:将开发者模式按钮改为上帝模式按钮
|
||||
private void DoGodModeButtons(Rect rect)
|
||||
{
|
||||
Rect button1Rect = new Rect(rect.x, rect.y, rect.width / 2 - 5f, rect.height);
|
||||
Rect button2Rect = new Rect(rect.x + rect.width / 2 + 5f, rect.y, rect.width / 2 - 5f, rect.height);
|
||||
|
||||
if (Widgets.ButtonText(button1Rect, "DEV: Add Resources"))
|
||||
if (Widgets.ButtonText(button1Rect, "GOD: Add Resources"))
|
||||
{
|
||||
AddTestResources();
|
||||
}
|
||||
|
||||
if (Widgets.ButtonText(button2Rect, "DEV: Spawn Products"))
|
||||
if (Widgets.ButtonText(button2Rect, "GOD: Spawn Products"))
|
||||
{
|
||||
SpawnOutputProducts();
|
||||
}
|
||||
@@ -178,7 +179,7 @@ namespace WulaFallenEmpire
|
||||
globalStorage.AddToInputStorage(componentDef, 100);
|
||||
|
||||
Messages.Message("Added 200 Steel and 100 Components to global storage", MessageTypeDefOf.PositiveEvent);
|
||||
Log.Message("[DEBUG] Added test resources");
|
||||
Log.Message("[GOD MODE] Added test resources");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -223,7 +224,7 @@ namespace WulaFallenEmpire
|
||||
}
|
||||
|
||||
Messages.Message($"Spawned {totalSpawned} items at worktable location", MessageTypeDefOf.PositiveEvent);
|
||||
Log.Message($"[DEBUG] Spawned {totalSpawned} output products");
|
||||
Log.Message($"[GOD MODE] Spawned {totalSpawned} output products");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -318,8 +319,31 @@ namespace WulaFallenEmpire
|
||||
|
||||
// 控制按钮
|
||||
float buttonY = rect.y + padding;
|
||||
Rect pauseButtonRect = new Rect(rect.xMax - 90f, buttonY, 40f, 25f);
|
||||
float buttonWidth = 40f;
|
||||
float buttonSpacing = 5f;
|
||||
|
||||
// 计算按钮位置(从右向左排列)
|
||||
float currentX = rect.xMax;
|
||||
|
||||
// 删除按钮(最右边)
|
||||
Rect deleteButtonRect = new Rect(currentX - buttonWidth, buttonY, buttonWidth, 25f);
|
||||
currentX -= (buttonWidth + buttonSpacing);
|
||||
|
||||
// 暂停/恢复按钮
|
||||
Rect pauseButtonRect = new Rect(currentX - buttonWidth, buttonY, buttonWidth, 25f);
|
||||
currentX -= (buttonWidth + buttonSpacing);
|
||||
|
||||
// 上帝模式:立刻完成按钮(在暂停按钮左边)
|
||||
Rect completeButtonRect = new Rect(currentX - buttonWidth, buttonY, buttonWidth, 25f);
|
||||
|
||||
// 绘制删除按钮
|
||||
if (Widgets.ButtonText(deleteButtonRect, "WULA_Delete".Translate()))
|
||||
{
|
||||
SelTable.globalOrderStack.Delete(order);
|
||||
SoundDefOf.Click.PlayOneShotOnCamera();
|
||||
}
|
||||
|
||||
// 绘制暂停/恢复按钮
|
||||
string pauseButtonText = order.paused ? "WULA_Resume".Translate() : "WULA_Pause".Translate();
|
||||
if (Widgets.ButtonText(pauseButtonRect, pauseButtonText))
|
||||
{
|
||||
@@ -327,15 +351,23 @@ namespace WulaFallenEmpire
|
||||
|
||||
// 暂停/恢复时更新状态
|
||||
order.UpdateState();
|
||||
|
||||
SoundDefOf.Click.PlayOneShotOnCamera();
|
||||
}
|
||||
|
||||
Rect deleteButtonRect = new Rect(rect.xMax - 45f, buttonY, 40f, 25f);
|
||||
if (Widgets.ButtonText(deleteButtonRect, "WULA_Delete".Translate()))
|
||||
// 绘制上帝模式按钮(仅上帝模式下可见)
|
||||
if (DebugSettings.godMode && order.state != GlobalProductionOrder.ProductionState.Completed)
|
||||
{
|
||||
SelTable.globalOrderStack.Delete(order);
|
||||
SoundDefOf.Click.PlayOneShotOnCamera();
|
||||
if (Widgets.ButtonText(completeButtonRect, "GOD: Complete"))
|
||||
{
|
||||
CompleteOrderImmediately(order);
|
||||
SoundDefOf.Click.PlayOneShotOnCamera();
|
||||
}
|
||||
|
||||
// 为上帝模式按钮添加Tooltip
|
||||
if (Mouse.IsOver(completeButtonRect))
|
||||
{
|
||||
TooltipHandler.TipRegion(completeButtonRect, "Instantly complete this order (God Mode Only)");
|
||||
}
|
||||
}
|
||||
|
||||
// 资源检查提示 - 只在等待资源且不暂停时显示红色边框
|
||||
@@ -358,6 +390,79 @@ namespace WulaFallenEmpire
|
||||
return Mouse.IsOver(rect);
|
||||
}
|
||||
|
||||
// 新增:立刻完成订单的方法
|
||||
private void CompleteOrderImmediately(GlobalProductionOrder order)
|
||||
{
|
||||
if (order.state == GlobalProductionOrder.ProductionState.Completed)
|
||||
return;
|
||||
|
||||
var globalStorage = Find.World.GetComponent<GlobalStorageWorldComponent>();
|
||||
if (globalStorage == null)
|
||||
return;
|
||||
|
||||
// 检查是否有足够资源
|
||||
bool hasEnoughResources = order.HasEnoughResources();
|
||||
|
||||
if (!hasEnoughResources)
|
||||
{
|
||||
// 上帝模式下,如果没有足够资源,显示确认对话框
|
||||
Find.WindowStack.Add(new Dialog_MessageBox(
|
||||
"This order doesn't have enough resources. Complete anyway? (God Mode)",
|
||||
"Yes, Complete Anyway",
|
||||
() => ForceCompleteOrder(order),
|
||||
"Cancel",
|
||||
null,
|
||||
"Complete Without Resources",
|
||||
false,
|
||||
null,
|
||||
null
|
||||
));
|
||||
}
|
||||
else
|
||||
{
|
||||
// 有足够资源,正常完成
|
||||
ForceCompleteOrder(order);
|
||||
}
|
||||
}
|
||||
|
||||
// 强制完成订单(上帝模式)
|
||||
private void ForceCompleteOrder(GlobalProductionOrder order)
|
||||
{
|
||||
var globalStorage = Find.World.GetComponent<GlobalStorageWorldComponent>();
|
||||
if (globalStorage == null)
|
||||
return;
|
||||
|
||||
// 计算需要完成的数量
|
||||
int remainingCount = order.targetCount - order.currentCount;
|
||||
|
||||
if (remainingCount <= 0)
|
||||
return;
|
||||
|
||||
// 尝试消耗资源(如果可能)
|
||||
bool resourcesConsumed = order.ConsumeResources();
|
||||
|
||||
if (!resourcesConsumed)
|
||||
{
|
||||
Log.Message($"[GOD MODE] Could not consume resources for {order.recipe.defName}, completing without resource consumption");
|
||||
}
|
||||
|
||||
// 添加产品到输出存储
|
||||
foreach (var product in order.recipe.products)
|
||||
{
|
||||
int totalCount = product.count * remainingCount;
|
||||
globalStorage.AddToOutputStorage(product.thingDef, totalCount);
|
||||
}
|
||||
|
||||
// 更新订单状态
|
||||
order.currentCount = order.targetCount;
|
||||
order.state = GlobalProductionOrder.ProductionState.Completed;
|
||||
order.progress = 0f;
|
||||
|
||||
// 显示完成消息
|
||||
Messages.Message($"GOD MODE: Completed order for {order.recipe.LabelCap} ({remainingCount} units)", MessageTypeDefOf.PositiveEvent);
|
||||
Log.Message($"[GOD MODE] Force completed order: {order.recipe.defName}, produced {remainingCount} units");
|
||||
}
|
||||
|
||||
private List<FloatMenuOption> GenerateRecipeOptions()
|
||||
{
|
||||
var options = new List<FloatMenuOption>();
|
||||
|
||||
@@ -12,6 +12,10 @@ namespace WulaFallenEmpire
|
||||
|
||||
// 上次维护的天数
|
||||
private float daysSinceLastMaintenance = 0f;
|
||||
|
||||
// 新增:记录当前应用的 Hediff 状态
|
||||
private MaintenanceStatus currentAppliedStatus = MaintenanceStatus.Operational;
|
||||
private Hediff currentAppliedHediff = null;
|
||||
|
||||
// 当前维护状态
|
||||
public MaintenanceStatus Status
|
||||
@@ -35,6 +39,8 @@ namespace WulaFallenEmpire
|
||||
{
|
||||
CurLevel = 1.0f;
|
||||
daysSinceLastMaintenance = 0f;
|
||||
currentAppliedStatus = MaintenanceStatus.Operational;
|
||||
currentAppliedHediff = null;
|
||||
}
|
||||
|
||||
public override void NeedInterval()
|
||||
@@ -82,46 +88,72 @@ namespace WulaFallenEmpire
|
||||
if (Extension == null)
|
||||
return;
|
||||
|
||||
// 检查是否需要应用故障效果
|
||||
var currentStatus = Status;
|
||||
var newStatus = Status;
|
||||
|
||||
// 移除旧的维护相关 Hediff
|
||||
RemoveMaintenanceHediffs();
|
||||
|
||||
// 根据状态添加相应的 Hediff
|
||||
switch (currentStatus)
|
||||
// 只有当状态发生变化时才更新 Hediff
|
||||
if (newStatus != currentAppliedStatus)
|
||||
{
|
||||
case MaintenanceStatus.MinorBreakdown:
|
||||
if (Extension.minorBreakdownHediff != null)
|
||||
pawn.health.AddHediff(Extension.minorBreakdownHediff);
|
||||
break;
|
||||
|
||||
case MaintenanceStatus.MajorBreakdown:
|
||||
if (Extension.majorBreakdownHediff != null)
|
||||
pawn.health.AddHediff(Extension.majorBreakdownHediff);
|
||||
break;
|
||||
|
||||
case MaintenanceStatus.CriticalFailure:
|
||||
if (Extension.criticalFailureHediff != null)
|
||||
pawn.health.AddHediff(Extension.criticalFailureHediff);
|
||||
break;
|
||||
UpdateHediffForStatus(newStatus);
|
||||
currentAppliedStatus = newStatus;
|
||||
}
|
||||
|
||||
// 额外检查:确保当前 Hediff 仍然存在(可能被其他系统移除)
|
||||
if (currentAppliedHediff != null && !pawn.health.hediffSet.hediffs.Contains(currentAppliedHediff))
|
||||
{
|
||||
// Hediff 被意外移除,重新应用
|
||||
UpdateHediffForStatus(currentAppliedStatus);
|
||||
}
|
||||
}
|
||||
|
||||
private void RemoveMaintenanceHediffs()
|
||||
// 新增:智能更新 Hediff
|
||||
private void UpdateHediffForStatus(MaintenanceStatus status)
|
||||
{
|
||||
// 首先移除当前应用的 Hediff
|
||||
if (currentAppliedHediff != null)
|
||||
{
|
||||
pawn.health.RemoveHediff(currentAppliedHediff);
|
||||
currentAppliedHediff = null;
|
||||
}
|
||||
|
||||
// 根据新状态添加相应的 Hediff
|
||||
HediffDef hediffDefToAdd = GetHediffDefForStatus(status);
|
||||
|
||||
if (hediffDefToAdd != null)
|
||||
{
|
||||
currentAppliedHediff = pawn.health.AddHediff(hediffDefToAdd);
|
||||
|
||||
// 调试日志
|
||||
if (Prefs.DevMode)
|
||||
{
|
||||
Log.Message($"Maintenance: Applied {hediffDefToAdd.defName} for status {status} to {pawn.Label}");
|
||||
}
|
||||
}
|
||||
else if (status == MaintenanceStatus.Operational)
|
||||
{
|
||||
// 操作状态,不需要 Hediff
|
||||
if (Prefs.DevMode)
|
||||
{
|
||||
Log.Message($"Maintenance: {pawn.Label} is operational, no hediff needed");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 新增:获取对应状态的 HediffDef
|
||||
private HediffDef GetHediffDefForStatus(MaintenanceStatus status)
|
||||
{
|
||||
if (Extension == null)
|
||||
return;
|
||||
return null;
|
||||
|
||||
// 移除所有维护相关的 Hediff
|
||||
var hediffsToRemove = pawn.health.hediffSet.hediffs.FindAll(h =>
|
||||
h.def == Extension.minorBreakdownHediff ||
|
||||
h.def == Extension.majorBreakdownHediff ||
|
||||
h.def == Extension.criticalFailureHediff);
|
||||
|
||||
foreach (var hediff in hediffsToRemove)
|
||||
switch (status)
|
||||
{
|
||||
pawn.health.RemoveHediff(hediff);
|
||||
case MaintenanceStatus.MinorBreakdown:
|
||||
return Extension.minorBreakdownHediff;
|
||||
case MaintenanceStatus.MajorBreakdown:
|
||||
return Extension.majorBreakdownHediff;
|
||||
case MaintenanceStatus.CriticalFailure:
|
||||
return Extension.criticalFailureHediff;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -132,8 +164,10 @@ namespace WulaFallenEmpire
|
||||
CurLevel = ClampNeedLevel(CurLevel);
|
||||
daysSinceLastMaintenance = 0f;
|
||||
|
||||
// 移除所有维护相关的负面效果
|
||||
RemoveMaintenanceHediffs();
|
||||
// 更新状态(会自动移除旧的 Hediff 并应用新的)
|
||||
var newStatus = Status;
|
||||
UpdateHediffForStatus(newStatus);
|
||||
currentAppliedStatus = newStatus;
|
||||
|
||||
// 触发维护完成的效果
|
||||
OnMaintenancePerformed(maintenanceAmount);
|
||||
@@ -148,8 +182,13 @@ namespace WulaFallenEmpire
|
||||
float reduction = damageAmount * Extension.damageToMaintenanceFactor;
|
||||
CurLevel = Math.Max(0f, CurLevel - reduction);
|
||||
|
||||
// 立即检查状态变化
|
||||
CheckStatusChanges();
|
||||
// 检查状态变化
|
||||
var newStatus = Status;
|
||||
if (newStatus != currentAppliedStatus)
|
||||
{
|
||||
UpdateHediffForStatus(newStatus);
|
||||
currentAppliedStatus = newStatus;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnMaintenancePerformed(float amount)
|
||||
@@ -180,6 +219,24 @@ namespace WulaFallenEmpire
|
||||
{
|
||||
base.ExposeData();
|
||||
Scribe_Values.Look(ref daysSinceLastMaintenance, "daysSinceLastMaintenance", 0f);
|
||||
Scribe_Values.Look(ref currentAppliedStatus, "currentAppliedStatus", MaintenanceStatus.Operational);
|
||||
Scribe_References.Look(ref currentAppliedHediff, "currentAppliedHediff");
|
||||
|
||||
// 修复:加载后验证状态一致性
|
||||
if (Scribe.mode == LoadSaveMode.PostLoadInit)
|
||||
{
|
||||
// 确保当前状态与实际 Hediff 一致
|
||||
if (currentAppliedHediff != null && !pawn.health.hediffSet.hediffs.Contains(currentAppliedHediff))
|
||||
{
|
||||
// Hediff 丢失,重新应用
|
||||
UpdateHediffForStatus(currentAppliedStatus);
|
||||
}
|
||||
else if (currentAppliedHediff == null && currentAppliedStatus != MaintenanceStatus.Operational)
|
||||
{
|
||||
// 应该有 Hediff 但没有,重新应用
|
||||
UpdateHediffForStatus(currentAppliedStatus);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -95,7 +95,6 @@
|
||||
<Compile Include="Flyover\WULA_AircraftHangar\CompAbilityEffect_AircraftStrike.cs" />
|
||||
<Compile Include="Flyover\WULA_AircraftHangar\CompAircraftHangar.cs" />
|
||||
<Compile Include="Flyover\WULA_AircraftHangar\WorldComponent_AircraftManager.cs" />
|
||||
<Compile Include="Flyover\WULA_AutoLaunchHangar\CompProperties_AutoLaunchHangar.cs" />
|
||||
<Compile Include="Flyover\WULA_FlyOverDropPod\CompProperties_FlyOverDropPod.cs" />
|
||||
<Compile Include="Flyover\WULA_FlyOverEscort\CompFlyOverEscort.cs" />
|
||||
<Compile Include="Flyover\WULA_FlyOverEscort\CompProperties_FlyOverEscort.cs" />
|
||||
|
||||
Reference in New Issue
Block a user