diff --git a/1.6/Assemblies/WulaFallenEmpire.dll b/1.6/Assemblies/WulaFallenEmpire.dll index 80439592..6ef0f347 100644 Binary files a/1.6/Assemblies/WulaFallenEmpire.dll and b/1.6/Assemblies/WulaFallenEmpire.dll differ diff --git a/1.6/Defs/JobDefs/WULA_Jobs.xml b/1.6/Defs/JobDefs/WULA_Jobs.xml index 34e51502..33914dfa 100644 --- a/1.6/Defs/JobDefs/WULA_Jobs.xml +++ b/1.6/Defs/JobDefs/WULA_Jobs.xml @@ -1,16 +1,11 @@ - - WULA_IngestWulaEnergy - WulaFallenEmpire.JobDriver_IngestWulaEnergy - 正在摄取能量。 - true - - - WULA_FeedWulaPatient - WulaFallenEmpire.JobDriver_FeedWulaPatient - 正在喂食能量核心。 - true - + + WULA_HaulToMaintenancePod + WulaFallenEmpire.JobDriver_HaulToMaintenancePod + hauling TargetA to TargetB. + true + + diff --git a/1.6/Defs/WorkGiverDefs/WULA_WorkGivers.xml b/1.6/Defs/WorkGiverDefs/WULA_WorkGivers.xml new file mode 100644 index 00000000..11950601 --- /dev/null +++ b/1.6/Defs/WorkGiverDefs/WULA_WorkGivers.xml @@ -0,0 +1,17 @@ + + + + + WULA_HaulToMaintenancePod + + WulaFallenEmpire.WorkGiver_HaulToMaintenancePod + Hauling + 20 + haul + hauling + +
  • Manipulation
  • +
    +
    + +
    \ No newline at end of file diff --git a/Source/WulaFallenEmpire/CompMaintenancePod.cs b/Source/WulaFallenEmpire/CompMaintenancePod.cs index ba82b2c9..4bc27bb9 100644 --- a/Source/WulaFallenEmpire/CompMaintenancePod.cs +++ b/Source/WulaFallenEmpire/CompMaintenancePod.cs @@ -32,12 +32,14 @@ namespace WulaFallenEmpire } [StaticConstructorOnStartup] - public class CompMaintenancePod : ThingComp, IThingHolder + public class CompMaintenancePod : ThingComp, IThingHolder, IStoreSettingsParent { // ===================== Fields ===================== private ThingOwner innerContainer; private CompPowerTrader powerComp; - private CompRefuelable refuelableComp; + private StorageSettings allowedComponentSettings; + public float storedComponents = 0f; + public int capacity = 50; // Let's define a capacity private int ticksRemaining; private MaintenancePodState state = MaintenancePodState.Idle; @@ -57,6 +59,8 @@ namespace WulaFallenEmpire return Props.baseComponentCost + (int)(hediff.Severity * Props.componentCostPerSeverity); } + public bool CanAcceptComponents(int count) => storedComponents + count <= capacity; + // ===================== Setup ===================== public CompMaintenancePod() { @@ -64,19 +68,31 @@ namespace WulaFallenEmpire } + public override void Initialize(CompProperties props) + { + base.Initialize(props); + allowedComponentSettings = new StorageSettings(this); + if (Props.componentDef != null) + { + allowedComponentSettings.filter = new ThingFilter(); + allowedComponentSettings.filter.SetAllow(Props.componentDef, true); + } + } + public override void PostSpawnSetup(bool respawningAfterLoad) { base.PostSpawnSetup(respawningAfterLoad); powerComp = parent.TryGetComp(); - refuelableComp = parent.TryGetComp(); } public override void PostExposeData() { base.PostExposeData(); Scribe_Values.Look(ref state, "state", MaintenancePodState.Idle); + Scribe_Values.Look(ref storedComponents, "storedComponents", 0f); Scribe_Values.Look(ref ticksRemaining, "ticksRemaining", 0); Scribe_Deep.Look(ref innerContainer, "innerContainer", this); + Scribe_Deep.Look(ref allowedComponentSettings, "allowedComponentSettings", this); } // ===================== IThingHolder Implementation ===================== @@ -90,6 +106,12 @@ namespace WulaFallenEmpire return innerContainer; } + // ===================== IStoreSettingsParent Implementation ===================== + public StorageSettings GetStoreSettings() => allowedComponentSettings; + public StorageSettings GetParentStoreSettings() => null; // No parent settings + public void Notify_SettingsChanged() { } + public bool StorageTabVisible => false; // We show it in the inspect string + // ===================== Core Logic ===================== public override void CompTick() { @@ -119,13 +141,13 @@ namespace WulaFallenEmpire public void StartCycle(Pawn pawn) { float required = RequiredComponents(pawn); - if (refuelableComp == null || refuelableComp.Fuel < required) + if (storedComponents < required) { Log.Error($"[WulaFallenEmpire] Tried to start maintenance cycle for {pawn.LabelShort} without enough components. This should have been checked earlier."); return; } - refuelableComp.ConsumeFuel(required); + storedComponents -= required; state = MaintenancePodState.Running; ticksRemaining = Props.durationTicks; @@ -174,6 +196,13 @@ namespace WulaFallenEmpire } + public void AddComponents(Thing components) + { + int count = components.stackCount; + storedComponents += count; + components.Destroy(); + } + // ===================== UI & Gizmos ===================== public override string CompInspectStringExtra() { @@ -186,10 +215,7 @@ namespace WulaFallenEmpire sb.AppendLine("TimeLeft".Translate() + ": " + ticksRemaining.ToStringTicksToPeriod()); } - if (refuelableComp != null) - { - sb.AppendLine("WULA_MaintenancePod_StoredComponents".Translate() + ": " + refuelableComp.Fuel.ToString("F0") + " / " + refuelableComp.Props.fuelCapacity.ToString("F0")); - } + sb.AppendLine("WULA_MaintenancePod_StoredComponents".Translate() + ": " + storedComponents.ToString("F0") + " / " + capacity.ToString("F0")); if (!PowerOn) { @@ -217,7 +243,7 @@ namespace WulaFallenEmpire if (p.health.hediffSet.HasHediff(Props.hediffToRemove)) { float required = RequiredComponents(p); - if (refuelableComp != null && refuelableComp.Fuel >= required) + if (storedComponents >= required) { options.Add(new FloatMenuOption(p.LabelShort, () => { diff --git a/Source/WulaFallenEmpire/JobDriver_HaulToMaintenancePod.cs b/Source/WulaFallenEmpire/JobDriver_HaulToMaintenancePod.cs new file mode 100644 index 00000000..8ea6cc1d --- /dev/null +++ b/Source/WulaFallenEmpire/JobDriver_HaulToMaintenancePod.cs @@ -0,0 +1,57 @@ +using RimWorld; +using System; +using System.Collections.Generic; +using Verse; +using Verse.AI; + +namespace WulaFallenEmpire +{ + public class JobDriver_HaulToMaintenancePod : JobDriver + { + private const TargetIndex ComponentInd = TargetIndex.A; + private const TargetIndex PodInd = TargetIndex.B; + + protected Thing Component => job.GetTarget(ComponentInd).Thing; + protected Building_Storage Pod => (Building_Storage)job.GetTarget(PodInd).Thing; + + public override bool TryMakePreToilReservations(bool errorOnFailed) + { + return pawn.Reserve(Component, job, 1, -1, null, errorOnFailed) && pawn.Reserve(Pod, job, 1, -1, null, errorOnFailed); + } + + protected override IEnumerable MakeNewToils() + { + this.FailOnDespawnedNullOrForbidden(PodInd); + this.FailOnBurningImmobile(PodInd); + + yield return Toils_Goto.GotoThing(ComponentInd, PathEndMode.ClosestTouch) + .FailOnSomeonePhysicallyInteracting(ComponentInd); + + yield return Toils_Haul.StartCarryThing(ComponentInd, false, true, false) + .FailOnDestroyedNullOrForbidden(ComponentInd); + + yield return Toils_Goto.GotoThing(PodInd, PathEndMode.Touch); + + Toil findPlaceAndDrop = new Toil(); + findPlaceAndDrop.initAction = delegate + { + Pawn actor = findPlaceAndDrop.actor; + Job curJob = actor.jobs.curJob; + Thing carriedThing = curJob.GetTarget(ComponentInd).Thing; + + CompMaintenancePod podComp = curJob.GetTarget(PodInd).Thing.TryGetComp(); + + if (podComp != null) + { + podComp.AddComponents(carriedThing); + } + else + { + // Fallback if something goes wrong, just drop it near the pod + actor.carryTracker.TryDropCarriedThing(Pod.Position, ThingPlaceMode.Near, out Thing _); + } + }; + yield return findPlaceAndDrop; + } + } +} \ No newline at end of file diff --git a/Source/WulaFallenEmpire/WorkGiver_HaulToMaintenancePod.cs b/Source/WulaFallenEmpire/WorkGiver_HaulToMaintenancePod.cs new file mode 100644 index 00000000..e1fb21de --- /dev/null +++ b/Source/WulaFallenEmpire/WorkGiver_HaulToMaintenancePod.cs @@ -0,0 +1,71 @@ +using RimWorld; +using System; +using System.Collections.Generic; +using System.Linq; +using Verse; +using Verse.AI; + +namespace WulaFallenEmpire +{ + public class WorkGiver_HaulToMaintenancePod : WorkGiver_Scanner + { + public override ThingRequest PotentialWorkThingRequest => ThingRequest.ForDef(ThingDefOf_WULA.WULA_MaintenancePod); + + public override PathEndMode PathEndMode => PathEndMode.Touch; + + public override Danger MaxPathDanger(Pawn pawn) => Danger.Deadly; + + public override bool HasJobOnThing(Pawn pawn, Thing t, bool forced = false) + { + if (!(t is Building building) || building.IsForbidden(pawn) || !pawn.CanReserve(building, 1, -1, null, forced)) + { + return false; + } + + CompMaintenancePod comp = building.GetComp(); + if (comp == null || comp.State != MaintenancePodState.Idle) + { + return false; + } + + // Check if it needs more components + if (comp.storedComponents >= comp.capacity) + { + return false; + } + + if (FindBestComponent(pawn, comp) == null) + { + JobFailReason.Is("WULA_NoComponentsToHaul".Translate()); + return false; + } + + return true; + } + + public override Job JobOnThing(Pawn pawn, Thing t, bool forced = false) + { + Building building = (Building)t; + CompMaintenancePod comp = building.GetComp(); + + Thing component = FindBestComponent(pawn, comp); + if (component == null) + { + return null; + } + + Job job = JobMaker.MakeJob(JobDefOf_WULA.WULA_HaulToMaintenancePod, component, t); + job.count = Math.Min(component.stackCount, (int)(comp.capacity - comp.storedComponents)); + return job; + } + + private Thing FindBestComponent(Pawn pawn, CompMaintenancePod podComp) + { + ThingFilter filter = podComp.GetStoreSettings().filter; + + Predicate validator = (Thing x) => !x.IsForbidden(pawn) && pawn.CanReserve(x) && filter.Allows(x); + + return GenClosest.ClosestThingReachable(pawn.Position, pawn.Map, filter.BestThingRequest, PathEndMode.ClosestTouch, TraverseParms.For(pawn), 9999f, validator); + } + } +} \ No newline at end of file