This commit is contained in:
2025-08-09 00:44:31 +08:00
parent fa442bd7fd
commit 8d4fa0f7b8
11 changed files with 36 additions and 282 deletions

Binary file not shown.

View File

@@ -1,17 +0,0 @@
<?xml version="1.0" encoding="utf-8" ?>
<Defs>
<JobDef>
<defName>WULA_LoadComponentsToMaintenancePod</defName>
<driverClass>WulaFallenEmpire.JobDriver_LoadComponents</driverClass>
<reportString>正在为维护舱装填零部件。</reportString>
<haulMode>ToCellNonStorage</haulMode>
</JobDef>
<JobDef>
<defName>WULA_EnterMaintenancePod</defName>
<driverClass>WulaFallenEmpire.JobDriver_EnterMaintenancePod</driverClass>
<reportString>正在进入维护舱。</reportString>
</JobDef>
</Defs>

View File

@@ -42,13 +42,6 @@
<building> <building>
<destroySound>BuildingDestroyed_Metal_Big</destroySound> <destroySound>BuildingDestroyed_Metal_Big</destroySound>
<uninstallWork>1800</uninstallWork> <uninstallWork>1800</uninstallWork>
<defaultStorageSettings>
<filter>
<thingDefs>
<li>ComponentIndustrial</li>
</thingDefs>
</filter>
</defaultStorageSettings>
</building> </building>
<designationCategory>Misc</designationCategory> <designationCategory>Misc</designationCategory>
<minifiedDef>MinifiedThing</minifiedDef> <minifiedDef>MinifiedThing</minifiedDef>
@@ -79,9 +72,6 @@
<placeWorkers> <placeWorkers>
<li>PlaceWorker_PreventInteractionSpotOverlap</li> <li>PlaceWorker_PreventInteractionSpotOverlap</li>
</placeWorkers> </placeWorkers>
<inspectorTabs>
<li>ITab_Storage</li>
</inspectorTabs>
</ThingDef> </ThingDef>
</Defs> </Defs>

View File

@@ -1,27 +0,0 @@
<?xml version="1.0" encoding="utf-8" ?>
<Defs>
<WorkGiverDef>
<defName>WULA_LoadComponentsToMaintenancePod</defName>
<label>装填维护舱</label>
<giverClass>WulaFallenEmpire.WorkGiver_LoadComponents</giverClass>
<workType>Hauling</workType>
<verb>装填</verb>
<gerund>装填于</gerund>
<priorityInType>110</priorityInType> <!-- High priority for hauling -->
<requiredCapacities>
<li>Manipulation</li>
</requiredCapacities>
</WorkGiverDef>
<WorkGiverDef>
<defName>WULA_EnterMaintenancePod</defName>
<label>进行机体维护</label>
<giverClass>WulaFallenEmpire.WorkGiver_EnterMaintenancePod</giverClass>
<workType>Patient</workType>
<verb>进行维护</verb>
<gerund>进行维护于</gerund>
<priorityInType>100</priorityInType> <!-- High priority for self-care -->
</WorkGiverDef>
</Defs>

View File

@@ -6,6 +6,7 @@ using System.Text;
using UnityEngine; using UnityEngine;
using Verse; using Verse;
using Verse.AI; using Verse.AI;
using Verse.Sound;
namespace WulaFallenEmpire namespace WulaFallenEmpire
{ {
@@ -31,14 +32,12 @@ namespace WulaFallenEmpire
} }
[StaticConstructorOnStartup] [StaticConstructorOnStartup]
public class CompMaintenancePod : ThingComp, IThingHolder, IStoreSettingsParent public class CompMaintenancePod : ThingComp, IThingHolder
{ {
// ===================== Fields ===================== // ===================== Fields =====================
private ThingOwner innerContainer; private ThingOwner innerContainer;
private CompPowerTrader powerComp; private CompPowerTrader powerComp;
private StorageSettings allowedComponentSettings; private CompRefuelable refuelableComp;
public float storedComponents = 0f;
private int ticksRemaining; private int ticksRemaining;
private MaintenancePodState state = MaintenancePodState.Idle; private MaintenancePodState state = MaintenancePodState.Idle;
@@ -64,36 +63,20 @@ namespace WulaFallenEmpire
innerContainer = new ThingOwner<Thing>(this, false, LookMode.Deep); innerContainer = new ThingOwner<Thing>(this, false, LookMode.Deep);
} }
public override void Initialize(CompProperties props)
{
base.Initialize(props);
// Setup allowed thing filter for components
allowedComponentSettings = new StorageSettings(this);
if (parent.def.building.defaultStorageSettings != null)
{
allowedComponentSettings.CopyFrom(parent.def.building.defaultStorageSettings);
}
else if (Props.componentDef != null)
{
allowedComponentSettings.filter = new ThingFilter();
allowedComponentSettings.filter.SetAllow(Props.componentDef, true);
}
}
public override void PostSpawnSetup(bool respawningAfterLoad) public override void PostSpawnSetup(bool respawningAfterLoad)
{ {
base.PostSpawnSetup(respawningAfterLoad); base.PostSpawnSetup(respawningAfterLoad);
powerComp = parent.TryGetComp<CompPowerTrader>(); powerComp = parent.TryGetComp<CompPowerTrader>();
refuelableComp = parent.TryGetComp<CompRefuelable>();
} }
public override void PostExposeData() public override void PostExposeData()
{ {
base.PostExposeData(); base.PostExposeData();
Scribe_Values.Look(ref state, "state", MaintenancePodState.Idle); Scribe_Values.Look(ref state, "state", MaintenancePodState.Idle);
Scribe_Values.Look(ref storedComponents, "storedComponents", 0f);
Scribe_Values.Look(ref ticksRemaining, "ticksRemaining", 0); Scribe_Values.Look(ref ticksRemaining, "ticksRemaining", 0);
Scribe_Deep.Look(ref innerContainer, "innerContainer", this); Scribe_Deep.Look(ref innerContainer, "innerContainer", this);
Scribe_Deep.Look(ref allowedComponentSettings, "allowedComponentSettings", this);
} }
// ===================== IThingHolder Implementation ===================== // ===================== IThingHolder Implementation =====================
@@ -107,13 +90,6 @@ namespace WulaFallenEmpire
return innerContainer; return innerContainer;
} }
// ===================== IStoreSettingsParent Implementation =====================
public StorageSettings GetStoreSettings() => allowedComponentSettings;
public StorageSettings GetParentStoreSettings() => parent.def.building.fixedStorageSettings;
public void Notify_SettingsChanged() { }
public bool StorageTabVisible => true;
// ===================== Core Logic ===================== // ===================== Core Logic =====================
public override void CompTick() public override void CompTick()
{ {
@@ -143,13 +119,13 @@ namespace WulaFallenEmpire
public void StartCycle(Pawn pawn) public void StartCycle(Pawn pawn)
{ {
float required = RequiredComponents(pawn); float required = RequiredComponents(pawn);
if (storedComponents < required) if (refuelableComp == null || refuelableComp.Fuel < required)
{ {
Log.Error($"[WulaFallenEmpire] Tried to start maintenance cycle for {pawn.LabelShort} without enough components. This should have been checked earlier."); Log.Error($"[WulaFallenEmpire] Tried to start maintenance cycle for {pawn.LabelShort} without enough components. This should have been checked earlier.");
return; return;
} }
storedComponents -= required; refuelableComp.ConsumeFuel(required);
state = MaintenancePodState.Running; state = MaintenancePodState.Running;
ticksRemaining = Props.durationTicks; ticksRemaining = Props.durationTicks;
@@ -174,7 +150,7 @@ namespace WulaFallenEmpire
Hediff hediff = occupant.health.hediffSet.GetFirstHediffOfDef(Props.hediffToRemove); Hediff hediff = occupant.health.hediffSet.GetFirstHediffOfDef(Props.hediffToRemove);
if (hediff != null) if (hediff != null)
{ {
occupant.health.RemoveHediff(hediff); hediff.Severity = 0.01f;
Messages.Message("WULA_MaintenanceComplete".Translate(occupant.Named("PAWN")), occupant, MessageTypeDefOf.PositiveEvent); Messages.Message("WULA_MaintenanceComplete".Translate(occupant.Named("PAWN")), occupant, MessageTypeDefOf.PositiveEvent);
} }
} }
@@ -190,19 +166,13 @@ namespace WulaFallenEmpire
GenPlace.TryPlaceThing(occupant, parent.InteractionCell, parent.Map, ThingPlaceMode.Near); GenPlace.TryPlaceThing(occupant, parent.InteractionCell, parent.Map, ThingPlaceMode.Near);
if (Props.exitSound != null) if (Props.exitSound != null)
{ {
Props.exitSound.PlayOneShot(new TargetInfo(parent.Position, parent.Map)); SoundStarter.PlayOneShot(Props.exitSound, new TargetInfo(parent.Position, parent.Map));
} }
} }
innerContainer.Clear(); innerContainer.Clear();
state = MaintenancePodState.Idle; state = MaintenancePodState.Idle;
} }
public void AddComponents(Thing components)
{
int count = components.stackCount;
storedComponents += count;
components.Destroy();
}
// ===================== UI & Gizmos ===================== // ===================== UI & Gizmos =====================
public override string CompInspectStringExtra() public override string CompInspectStringExtra()
@@ -216,7 +186,10 @@ namespace WulaFallenEmpire
sb.AppendLine("TimeLeft".Translate() + ": " + ticksRemaining.ToStringTicksToPeriod()); sb.AppendLine("TimeLeft".Translate() + ": " + ticksRemaining.ToStringTicksToPeriod());
} }
sb.AppendLine("WULA_MaintenancePod_StoredComponents".Translate() + ": " + storedComponents.ToString("F0")); if (refuelableComp != null)
{
sb.AppendLine("WULA_MaintenancePod_StoredComponents".Translate() + ": " + refuelableComp.Fuel.ToString("F0") + " / " + refuelableComp.Props.fuelCapacity.ToString("F0"));
}
if (!PowerOn) if (!PowerOn)
{ {
@@ -244,12 +217,12 @@ namespace WulaFallenEmpire
if (p.health.hediffSet.HasHediff(Props.hediffToRemove)) if (p.health.hediffSet.HasHediff(Props.hediffToRemove))
{ {
float required = RequiredComponents(p); float required = RequiredComponents(p);
if (storedComponents >= required) if (refuelableComp != null && refuelableComp.Fuel >= required)
{ {
options.Add(new FloatMenuOption(p.LabelShort, () => options.Add(new FloatMenuOption(p.LabelShort, () =>
{ {
// TODO: Create and assign job Job job = JobMaker.MakeJob(JobDefOf_WULA.WULA_EnterMaintenancePod, parent);
Messages.Message("This needs a JobDriver.", MessageTypeDefOf.RejectInput); p.jobs.TryTakeOrderedJob(job, JobTag.Misc);
})); }));
} }
else else

View File

@@ -0,0 +1,17 @@
using RimWorld;
using Verse;
namespace WulaFallenEmpire
{
[DefOf]
public static class JobDefOf_WULA
{
public static JobDef WULA_LoadComponentsToMaintenancePod;
public static JobDef WULA_EnterMaintenancePod;
static JobDefOf_WULA()
{
DefOfHelper.EnsureInitializedInCtor(typeof(JobDefOf_WULA));
}
}
}

View File

@@ -1,53 +0,0 @@
using RimWorld;
using System;
using System.Collections.Generic;
using Verse;
using Verse.AI;
namespace WulaFallenEmpire
{
public class JobDriver_LoadComponents : JobDriver
{
private const TargetIndex PodIndex = TargetIndex.A;
private const TargetIndex ComponentIndex = TargetIndex.B;
protected Thing Pod => job.GetTarget(PodIndex).Thing;
protected Thing Component => job.GetTarget(ComponentIndex).Thing;
public override bool TryMakePreToilReservations(bool errorOnFailed)
{
if (pawn.Reserve(Pod, job, 1, -1, null, errorOnFailed))
{
return pawn.Reserve(Component, job, 1, -1, null, errorOnFailed);
}
return false;
}
protected override IEnumerable<Toil> MakeNewToils()
{
this.FailOnDespawnedNullOrForbidden(PodIndex);
this.FailOnBurningImmobile(PodIndex);
var podComp = Pod.TryGetComp<CompMaintenancePod>();
this.FailOn(() => podComp == null || podComp.State != MaintenancePodState.Idle);
// Go and get the components
yield return Toils_Goto.GotoThing(ComponentIndex, PathEndMode.OnCell).FailOnSomeonePhysicallyInteracting(ComponentIndex);
yield return Toils_Haul.StartCarryThing(ComponentIndex);
// Carry them to the pod
yield return Toils_Goto.GotoThing(PodIndex, PathEndMode.InteractionCell);
// Load the components
yield return Toils_General.WaitWith(60, TargetIndex.A, true, true, false, PodIndex);
yield return new Toil
{
initAction = () =>
{
podComp.AddComponents(this.GetActor().carryTracker.CarriedThing);
},
defaultCompleteMode = ToilCompleteMode.Instant
};
}
}
}

View File

@@ -4,10 +4,6 @@ using Verse.AI;
namespace WulaFallenEmpire namespace WulaFallenEmpire
{ {
public class JobDriver_EnterMaintenancePod : JobDriver_EnterBiosculpterPod
{
}
public class WorkGiver_DoMaintenance : WorkGiver_Scanner public class WorkGiver_DoMaintenance : WorkGiver_Scanner
{ {
public override ThingRequest PotentialWorkThingRequest => ThingRequest.ForDef(ThingDef.Named("WULA_MaintenancePod")); public override ThingRequest PotentialWorkThingRequest => ThingRequest.ForDef(ThingDef.Named("WULA_MaintenancePod"));

View File

@@ -1,62 +0,0 @@
using RimWorld;
using System;
using System.Collections.Generic;
using System.Linq;
using Verse;
using Verse.AI;
namespace WulaFallenEmpire
{
public class WorkGiver_EnterMaintenancePod : WorkGiver_Scanner
{
public override ThingRequest PotentialWorkThingRequest => ThingRequest.ForDef(ThingDef.Named("WULA_MaintenancePod"));
public override PathEndMode PathEndMode => PathEndMode.InteractionCell;
// This method now checks the severity of the hediff.
public override bool ShouldSkip(Pawn pawn, bool forced = false)
{
var podDef = ThingDef.Named("WULA_MaintenancePod");
var podProps = podDef.GetCompProperties<CompProperties_MaintenancePod>();
if (podProps?.hediffToRemove == null) return true;
Hediff hediff = pawn.health.hediffSet.GetFirstHediffOfDef(podProps.hediffToRemove);
// Skip if no hediff or if severity is below the configured threshold.
if (hediff == null || hediff.Severity < podProps.minSeverityToMaintain)
{
return true;
}
return false;
}
public override bool HasJobOnThing(Pawn pawn, Thing t, bool forced = false)
{
if (!(t is Building building) || !building.Spawned || building.IsForbidden(pawn) || !pawn.CanReserve(building, 1, -1, null, forced))
{
return false;
}
var podComp = building.GetComp<CompMaintenancePod>();
if (podComp == null || podComp.State != MaintenancePodState.Idle || !podComp.PowerOn)
{
return false;
}
float requiredComponents = podComp.RequiredComponents(pawn);
if (podComp.storedComponents < requiredComponents)
{
JobFailReason.Is("WULA_MaintenancePod_NotEnoughComponents".Translate(requiredComponents.ToString("F0")));
return false;
}
return true;
}
public override Job JobOnThing(Pawn pawn, Thing t, bool forced = false)
{
return JobMaker.MakeJob(JobDefOf.WULA_EnterMaintenancePod, t);
}
}
}

View File

@@ -1,66 +0,0 @@
using RimWorld;
using System;
using System.Collections.Generic;
using System.Linq;
using Verse;
using Verse.AI;
namespace WulaFallenEmpire
{
public class WorkGiver_LoadComponents : WorkGiver_Scanner
{
public override ThingRequest PotentialWorkThingRequest => ThingRequest.ForDef(ThingDef.Named("WULA_MaintenancePod"));
public override PathEndMode PathEndMode => PathEndMode.Touch;
public override bool HasJobOnThing(Pawn pawn, Thing t, bool forced = false)
{
if (!(t is Building building) || !building.Spawned || building.IsForbidden(pawn) || !pawn.CanReserve(building, 1, -1, null, forced))
{
return false;
}
var podComp = building.GetComp<CompMaintenancePod>();
if (podComp == null || podComp.State != MaintenancePodState.Idle)
{
return false;
}
// We define a "needed" threshold. Let's say we want to keep at least 10 components stocked.
// This prevents pawns from hauling one component at a time.
const int desiredStockpile = 10;
if (podComp.storedComponents >= desiredStockpile)
{
return false;
}
if (FindBestComponent(pawn, podComp) == null)
{
JobFailReason.Is("WULA_NoComponentsToLoad".Translate());
return false;
}
return true;
}
public override Job JobOnThing(Pawn pawn, Thing t, bool forced = false)
{
var podComp = t.GetComp<CompMaintenancePod>();
Thing component = FindBestComponent(pawn, podComp);
if (component == null)
{
return null;
}
return JobMaker.MakeJob(JobDefOf.WULA_LoadComponentsToMaintenancePod, t, component);
}
private Thing FindBestComponent(Pawn pawn, CompMaintenancePod pod)
{
ThingDef componentDef = pod.Props.componentDef;
if (componentDef == null) return null;
Predicate<Thing> validator = (Thing x) => !x.IsForbidden(pawn) && pawn.CanReserve(x);
return GenClosest.ClosestThingReachable(pawn.Position, pawn.Map, ThingRequest.ForDef(componentDef), PathEndMode.ClosestTouch, TraverseParms.For(pawn), 9999f, validator);
}
}
}

View File

@@ -72,6 +72,7 @@
<Compile Include="CompApparelInterceptor.cs" /> <Compile Include="CompApparelInterceptor.cs" />
<Compile Include="CompCustomUniqueWeapon.cs" /> <Compile Include="CompCustomUniqueWeapon.cs" />
<Compile Include="CompProperties_CustomUniqueWeapon.cs" /> <Compile Include="CompProperties_CustomUniqueWeapon.cs" />
<Compile Include="CompMaintenancePod.cs" />
<Compile Include="CompWulaRitualSpot.cs" /> <Compile Include="CompWulaRitualSpot.cs" />
<Compile Include="CompPsychicScaling.cs" /> <Compile Include="CompPsychicScaling.cs" />
<Compile Include="CompUseEffect_FixAllHealthConditions.cs" /> <Compile Include="CompUseEffect_FixAllHealthConditions.cs" />
@@ -98,9 +99,11 @@
<Compile Include="HediffComp_WulaCharging.cs" /> <Compile Include="HediffComp_WulaCharging.cs" />
<Compile Include="IngestPatch.cs" /> <Compile Include="IngestPatch.cs" />
<Compile Include="JobDriver_FeedWulaPatient.cs" /> <Compile Include="JobDriver_FeedWulaPatient.cs" />
<Compile Include="JobDriver_EnterMaintenancePod.cs" />
<Compile Include="JobDriver_IngestWulaEnergy.cs" /> <Compile Include="JobDriver_IngestWulaEnergy.cs" />
<Compile Include="JobGiver_WulaGetEnergy.cs" /> <Compile Include="JobGiver_WulaGetEnergy.cs" />
<Compile Include="JobGiver_WulaPackEnergy.cs" /> <Compile Include="JobGiver_WulaPackEnergy.cs" />
<Compile Include="Job_Maintenance.cs" />
<Compile Include="JobGiverDefExtension_WulaPackEnergy.cs" /> <Compile Include="JobGiverDefExtension_WulaPackEnergy.cs" />
<Compile Include="LightningBombardment.cs" /> <Compile Include="LightningBombardment.cs" />
<Compile Include="MechanitorPatch.cs" /> <Compile Include="MechanitorPatch.cs" />
@@ -140,7 +143,7 @@
<Compile Include="WulaStatDefOf.cs" /> <Compile Include="WulaStatDefOf.cs" />
<Compile Include="Building_MaintenancePod.cs" /> <Compile Include="Building_MaintenancePod.cs" />
<Compile Include="HediffComp_MaintenanceNeed.cs" /> <Compile Include="HediffComp_MaintenanceNeed.cs" />
<Compile Include="Job_Maintenance.cs" /> <Compile Include="JobDefOf_WULA.cs" />
</ItemGroup> </ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- 自定义清理任务删除obj文件夹中的临时文件 --> <!-- 自定义清理任务删除obj文件夹中的临时文件 -->