fix(Maintenance): 在 WorkGiver 中增加零部件消耗检查并修复注释乱码

This commit is contained in:
2025-12-14 12:50:59 +08:00
parent a608bd5586
commit 865bd922b2
3 changed files with 64 additions and 52 deletions

View File

@@ -16,24 +16,24 @@ namespace WulaFallenEmpire
public SoundDef exitSound;
public EffecterDef operatingEffecter;
// 时间相关
public int baseDurationTicks = 60000; // 基础维护时间1天
public float ticksPerNeedLevel = 120000f; // 每点需求降低需要的时间
// 时间相关
public int baseDurationTicks = 60000; // 基础维护时间1天
public float ticksPerNeedLevel = 120000f; // 每点需求降低需要的时间
// 电力消耗
// 电力消耗
public float powerConsumptionRunning = 250f;
public float powerConsumptionIdle = 50f;
// 组件消耗
// 组件消耗
public float componentCostPerNeedLevel = 2f;
public int baseComponentCost = 1;
// 维护效果
public float minNeedLevelToMaintain = 0.3f; // 低于此值才需要维护
public float needLevelAfterCycle = 1.0f; // 维护后的需求水平
public bool healInjuries = true; // 是否治疗损伤
public bool healMissingParts = true; // 是否修复缺失部位
public int maxInjuriesHealedPerCycle = 5; // 每次维护最多治疗的损伤数量
// 维护效果
public float minNeedLevelToMaintain = 0.3f; // 低于此值才需要维护
public float needLevelAfterCycle = 1.0f; // 维护后的需求水平
public bool healInjuries = true; // 是否治疗损伤
public bool healMissingParts = true; // 是否修复缺失部位
public int maxInjuriesHealedPerCycle = 5; // 每次维护最多治疗的损伤数量
public CompProperties_MaintenancePod()
{
compClass = typeof(CompMaintenancePod);
@@ -57,20 +57,18 @@ namespace WulaFallenEmpire
public MaintenancePodState State => state;
public Pawn Occupant => innerContainer.FirstOrDefault() as Pawn;
public bool PowerOn => powerComp != null && powerComp.PowerOn;
public float RequiredComponents
public float RequiredComponents => GetRequiredComponentsFor(Occupant);
public float GetRequiredComponentsFor(Pawn pawn)
{
get
{
var occupant = Occupant;
if (occupant == null) return Props.baseComponentCost;
if (pawn == null) return Props.baseComponentCost;
var maintenanceNeed = occupant.needs?.TryGetNeed<Need_Maintenance>();
if (maintenanceNeed == null) return Props.baseComponentCost;
var maintenanceNeed = pawn.needs?.TryGetNeed<Need_Maintenance>();
if (maintenanceNeed == null) return Props.baseComponentCost;
// 计算基于当前需求水平的组件需求
float needDeficit = 1.0f - maintenanceNeed.CurLevel;
return Props.baseComponentCost + (needDeficit * Props.componentCostPerNeedLevel);
}
// 计算基于当前需求水平的组件需求
float needDeficit = 1.0f - maintenanceNeed.CurLevel;
return Props.baseComponentCost + (needDeficit * Props.componentCostPerNeedLevel);
}
public int RequiredDuration
{
@@ -82,7 +80,7 @@ namespace WulaFallenEmpire
var maintenanceNeed = occupant.needs?.TryGetNeed<Need_Maintenance>();
if (maintenanceNeed == null) return Props.baseDurationTicks;
// 计算基于当前需求水平的维护时间
// 计算基于当前需求水平的维护时间
float needDeficit = 1.0f - maintenanceNeed.CurLevel;
return Props.baseDurationTicks + (int)(needDeficit * Props.ticksPerNeedLevel);
}
@@ -127,17 +125,17 @@ namespace WulaFallenEmpire
{
base.CompTick();
if (!parent.Spawned) return;
// 更新电力消耗
// 更新电力消耗
if (powerComp != null)
{
powerComp.PowerOutput = -(state == MaintenancePodState.Running ? Props.powerConsumptionRunning : Props.powerConsumptionIdle);
}
// 运行维护周期
// 运行维护周期
if (state == MaintenancePodState.Running && PowerOn)
{
ticksRemaining--;
// 更新效果器
// 更新效果器
if (Props.operatingEffecter != null)
{
if (operatingEffecter == null)
@@ -160,29 +158,29 @@ namespace WulaFallenEmpire
public void StartCycle(Pawn pawn)
{
if (pawn == null) return;
// 检查组件是否足够
// 检查组件是否足够
float requiredComponents = RequiredComponents;
if (refuelableComp.Fuel < requiredComponents)
{
Messages.Message("WULA_MaintenancePod_NotEnoughComponents".Translate(requiredComponents.ToString("F0")), MessageTypeDefOf.RejectInput);
return;
}
// 消耗组件
// 消耗组件
if (requiredComponents > 0)
{
refuelableComp.ConsumeFuel(requiredComponents);
}
// 将 pawn 放入容器
// 将 pawn 放入容器
if (pawn.Spawned)
{
pawn.DeSpawn(DestroyMode.Vanish);
}
innerContainer.TryAddOrTransfer(pawn);
// 开始维护周期
// 开始维护周期
state = MaintenancePodState.Running;
ticksRemaining = RequiredDuration;
// 播放进入音效
// 播放进入音效
if (Props.enterSound != null)
{
Props.enterSound.PlayOneShot(new TargetInfo(parent.Position, parent.Map));
@@ -197,10 +195,10 @@ namespace WulaFallenEmpire
state = MaintenancePodState.Idle;
return;
}
// 执行维护效果
// 执行维护效果
PerformMaintenanceEffects(occupant);
// 弹出 pawn
// 弹出 pawn
EjectPawn();
Messages.Message("WULA_MaintenanceCycleComplete".Translate(occupant.LabelShortCap), MessageTypeDefOf.PositiveEvent);
@@ -209,17 +207,17 @@ namespace WulaFallenEmpire
{
var maintenanceNeed = pawn.needs?.TryGetNeed<Need_Maintenance>();
// 1. 恢复维护需求
// 1. 恢复维护需求
if (maintenanceNeed != null)
{
maintenanceNeed.PerformMaintenance(Props.needLevelAfterCycle);
}
// 2. 治疗损伤(如果启用)
// 2. 治疗损伤(如果启用)
if (Props.healInjuries)
{
HealInjuries(pawn);
}
// 3. 修复缺失部位(如果启用)
// 3. 修复缺失部位(如果启用)
if (Props.healMissingParts)
{
HealMissingParts(pawn);
@@ -249,7 +247,7 @@ namespace WulaFallenEmpire
int partsHealed = 0;
foreach (var missingPart in missingParts)
{
if (partsHealed >= 1) // 每次最多修复一个缺失部位
if (partsHealed >= 1) // 每次最多修复一个缺失部位
break;
pawn.health.RemoveHediff(missingPart);
partsHealed++;
@@ -264,15 +262,15 @@ namespace WulaFallenEmpire
var occupant = Occupant;
if (occupant != null)
{
// 弹出到交互单元格
// 弹出到交互单元格
innerContainer.TryDropAll(parent.InteractionCell, parent.Map, ThingPlaceMode.Near);
// 播放退出音效
// 播放退出音效
if (Props.exitSound != null)
{
Props.exitSound.PlayOneShot(new TargetInfo(parent.Position, parent.Map));
}
// 如果被中断,应用负面效果
// 如果被中断,应用负面效果
if (interrupted)
{
occupant.needs?.mood?.thoughts?.memories?.TryGainMemory(ThoughtDefOf.SoakingWet);
@@ -281,7 +279,7 @@ namespace WulaFallenEmpire
innerContainer.Clear();
state = MaintenancePodState.Idle;
// 清理效果器
// 清理效果器
if (operatingEffecter != null)
{
operatingEffecter.Cleanup();
@@ -300,7 +298,7 @@ namespace WulaFallenEmpire
var maintenanceNeed = Occupant.needs?.TryGetNeed<Need_Maintenance>();
if (maintenanceNeed != null)
{
// 直接显示 CurLevel确保与 Need 显示一致
// 直接显示 CurLevel确保与 Need 显示一致
sb.AppendLine("WULA_MaintenanceLevel".Translate() + ": " + maintenanceNeed.CurLevel.ToStringPercent());
}
}
@@ -316,7 +314,7 @@ namespace WulaFallenEmpire
{
yield return gizmo;
}
// 进入维护舱的按钮
// 进入维护舱的按钮
if (state == MaintenancePodState.Idle && PowerOn)
{
yield return new Command_Action
@@ -327,7 +325,7 @@ namespace WulaFallenEmpire
action = () => ShowPawnSelectionMenu()
};
}
// 取消维护的按钮
// 取消维护的按钮
if (state == MaintenancePodState.Running)
{
yield return new Command_Action
@@ -362,19 +360,19 @@ namespace WulaFallenEmpire
foreach (var pawn in map.mapPawns.AllPawnsSpawned)
{
// 首先检查是否有维护需求
// 首先检查是否有维护需求
var maintenanceNeed = pawn.needs?.TryGetNeed<Need_Maintenance>();
if (maintenanceNeed == null)
{
// 这个Pawn没有维护需求跳过
// 这个Pawn没有维护需求跳过
continue;
}
// 检查是否真的需要维护
// 检查是否真的需要维护
if (maintenanceNeed.CurLevel > Props.minNeedLevelToMaintain && !DebugSettings.godMode)
continue;
// 创建选项
// 创建选项
var option = CreatePawnOption(pawn, maintenanceNeed);
if (option != null)
options.Add(option);
@@ -387,12 +385,12 @@ namespace WulaFallenEmpire
{
string label = $"{pawn.LabelShortCap} ({need.CurLevel.ToStringPercent()})";
float requiredComponents = RequiredComponents;
// 检查组件是否足够
// 检查组件是否足够
if (refuelableComp.Fuel < requiredComponents)
{
return new FloatMenuOption(label + " (" + "WULA_MaintenancePod_NotEnoughComponents".Translate(requiredComponents.ToString("F0")) + ")", null);
}
// 检查是否可以到达
// 检查是否可以到达
if (!pawn.CanReach(parent, PathEndMode.InteractionCell, Danger.Deadly))
{
return new FloatMenuOption(label + " (" + "CannotReach".Translate() + ")", null);
@@ -401,7 +399,7 @@ namespace WulaFallenEmpire
{
if (pawn.Downed || !pawn.IsFreeColonist)
{
// 需要搬运
// 需要搬运
var haulJob = JobMaker.MakeJob(JobDefOf_WULA.WULA_HaulToMaintenancePod, pawn, parent);
var hauler = FindBestHauler(pawn);
if (hauler != null)
@@ -415,7 +413,7 @@ namespace WulaFallenEmpire
}
else
{
// 自己进入
// 自己进入
var enterJob = JobMaker.MakeJob(JobDefOf_WULA.WULA_EnterMaintenancePod, parent);
pawn.jobs.TryTakeOrderedJob(enterJob);
}

View File

@@ -22,6 +22,20 @@ namespace WulaFallenEmpire
if (podComp == null || podComp.State != MaintenancePodState.Idle || !podComp.PowerOn)
return false;
// 检查是否有足够的燃料(零部件)
// 如果是强制工作(玩家右键),我们允许通过检查,让 JobDriver 去处理(可能会提示燃料不足)
// 这样玩家能知道为什么不能工作,而不是默默失败
if (!forced)
{
float requiredFuel = podComp.GetRequiredComponentsFor(pawn);
var refuelable = t.TryGetComp<CompRefuelable>();
if (refuelable != null && refuelable.Fuel < requiredFuel)
{
JobFailReason.Is("WULA_MaintenancePod_NotEnoughComponents".Translate(requiredFuel.ToString("F0")));
return false;
}
}
// 检查当前pawn是否有维护需求且需要维护
return PawnNeedsMaintenance(pawn);
}