diff --git a/1.6/1.6/Assemblies/ArachnaeSwarm.dll b/1.6/1.6/Assemblies/ArachnaeSwarm.dll
index 8456ad8..334b1df 100644
Binary files a/1.6/1.6/Assemblies/ArachnaeSwarm.dll and b/1.6/1.6/Assemblies/ArachnaeSwarm.dll differ
diff --git a/1.6/1.6/Defs/JobDefs/ARA_Jobs_Nutrition.xml b/1.6/1.6/Defs/JobDefs/ARA_Jobs_Nutrition.xml
new file mode 100644
index 0000000..bef6bf4
--- /dev/null
+++ b/1.6/1.6/Defs/JobDefs/ARA_Jobs_Nutrition.xml
@@ -0,0 +1,11 @@
+
+
+
+
+ ARA_Refuel_Nutrition
+ ArachnaeSwarm.JobDriver_Refuel_Nutrition
+ 正在为 TargetA 补充营养。
+ true
+
+
+
\ No newline at end of file
diff --git a/1.6/1.6/Defs/WorkGiverDefs/ARA_WorkGivers.xml b/1.6/1.6/Defs/WorkGiverDefs/ARA_WorkGivers.xml
new file mode 100644
index 0000000..725e3a7
--- /dev/null
+++ b/1.6/1.6/Defs/WorkGiverDefs/ARA_WorkGivers.xml
@@ -0,0 +1,14 @@
+
+
+
+ ARA_Refuel_Nutrition
+
+ ArachnaeSwarm.WorkGiver_Refuel_Nutrition
+ Hauling
+ 60
+ 补充
+ 补充
+ true
+ false
+
+
\ No newline at end of file
diff --git a/Source/ArachnaeSwarm/ArachnaeSwarm.csproj b/Source/ArachnaeSwarm/ArachnaeSwarm.csproj
index 6b46fbc..7a9606b 100644
--- a/Source/ArachnaeSwarm/ArachnaeSwarm.csproj
+++ b/Source/ArachnaeSwarm/ArachnaeSwarm.csproj
@@ -146,6 +146,8 @@
+
+
diff --git a/Source/ArachnaeSwarm/Building_Comps/CompRefuelableNutrition.cs b/Source/ArachnaeSwarm/Building_Comps/CompRefuelableNutrition.cs
index 3d0283c..e9e153f 100644
--- a/Source/ArachnaeSwarm/Building_Comps/CompRefuelableNutrition.cs
+++ b/Source/ArachnaeSwarm/Building_Comps/CompRefuelableNutrition.cs
@@ -63,10 +63,7 @@ namespace ArachnaeSwarm
fuelNeeded = TargetFuelLevel - Fuel;
}
- if (totalNutritionGained > 0 && Props.fuelGizmoLabel != null)
- {
- Messages.Message("MessageRefueled".Translate(parent.LabelShort, totalNutritionGained.ToString("0.##"), Props.fuelGizmoLabel), parent, MessageTypeDefOf.PositiveEvent);
- }
+ // Let the job driver handle the message. This component should only handle logic.
}
public void ReceiveFuel(float amount)
diff --git a/Source/ArachnaeSwarm/Jobs/JobDriver_Refuel_Nutrition.cs b/Source/ArachnaeSwarm/Jobs/JobDriver_Refuel_Nutrition.cs
new file mode 100644
index 0000000..f048094
--- /dev/null
+++ b/Source/ArachnaeSwarm/Jobs/JobDriver_Refuel_Nutrition.cs
@@ -0,0 +1,88 @@
+using System.Collections.Generic;
+using RimWorld;
+using Verse;
+using Verse.AI;
+
+namespace ArachnaeSwarm
+{
+ public class JobDriver_Refuel_Nutrition : JobDriver
+ {
+ private const TargetIndex RefuelableInd = TargetIndex.A;
+ private const TargetIndex FuelInd = TargetIndex.B;
+ private const int RefuelingDuration = 240;
+
+ protected Thing Refuelable => job.GetTarget(RefuelableInd).Thing;
+
+ // --- KEY CHANGE HERE ---
+ // We specifically target CompRefuelableNutrition and its children.
+ protected CompRefuelableNutrition RefuelableComp => Refuelable.TryGetComp();
+
+ protected Thing Fuel => job.GetTarget(FuelInd).Thing;
+
+ public override bool TryMakePreToilReservations(bool errorOnFailed)
+ {
+ if (pawn.Reserve(Refuelable, job, 1, -1, null, errorOnFailed))
+ {
+ return pawn.Reserve(Fuel, job, 1, -1, null, errorOnFailed);
+ }
+ return false;
+ }
+
+ protected override IEnumerable MakeNewToils()
+ {
+ this.FailOnDespawnedNullOrForbidden(RefuelableInd);
+ AddEndCondition(() => !RefuelableComp.IsFull ? JobCondition.Ongoing : JobCondition.Succeeded);
+ AddFailCondition(() => !job.playerForced && !RefuelableComp.ShouldAutoRefuelNowIgnoringFuelPct);
+ AddFailCondition(() => !RefuelableComp.allowAutoRefuel && !job.playerForced);
+
+ yield return Toils_General.DoAtomic(delegate
+ {
+ job.count = RefuelableComp.GetFuelCountToFullyRefuel();
+ });
+
+ Toil reserveFuel = Toils_Reserve.Reserve(FuelInd);
+ yield return reserveFuel;
+ yield return Toils_Goto.GotoThing(FuelInd, PathEndMode.ClosestTouch)
+ .FailOnDespawnedNullOrForbidden(FuelInd)
+ .FailOnSomeonePhysicallyInteracting(FuelInd);
+ yield return Toils_Haul.StartCarryThing(FuelInd, putRemainderInQueue: false, subtractNumTakenFromJobCount: true)
+ .FailOnDestroyedNullOrForbidden(FuelInd);
+ yield return Toils_Haul.CheckForGetOpportunityDuplicate(reserveFuel, FuelInd, TargetIndex.None, takeFromValidStorage: true);
+ yield return Toils_Goto.GotoThing(RefuelableInd, PathEndMode.Touch);
+ yield return Toils_General.Wait(RefuelingDuration)
+ .FailOnDestroyedNullOrForbidden(FuelInd)
+ .FailOnDestroyedNullOrForbidden(RefuelableInd)
+ .FailOnCannotTouch(RefuelableInd, PathEndMode.Touch)
+ .WithProgressBarToilDelay(RefuelableInd);
+
+ // Use our custom Refuel toil for CompRefuelableNutrition
+ yield return FinalizeRefueling_Nutrition();
+ }
+
+ // Custom Finalize Toil that uses the specific Refuel method from CompRefuelableNutrition
+ public Toil FinalizeRefueling_Nutrition()
+ {
+ Toil toil = new Toil();
+ toil.initAction = delegate()
+ {
+ Pawn actor = toil.GetActor();
+ Job curJob = actor.jobs.curJob;
+ Thing refuelableThing = curJob.GetTarget(RefuelableInd).Thing;
+ CompRefuelableNutrition refuelableComp = refuelableThing.TryGetComp();
+
+ if (actor.carryTracker.CarriedThing == null)
+ {
+ Log.Error(actor + " is not carrying anything to refuel with.");
+ // The correct way to end the job from within a Toil's action.
+ actor.jobs.EndCurrentJob(JobCondition.Incompletable);
+ return;
+ }
+
+ // Call the specific Refuel method from our custom component
+ refuelableComp.Refuel(new List { actor.carryTracker.CarriedThing });
+ };
+ toil.defaultCompleteMode = ToilCompleteMode.Instant;
+ return toil;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Source/ArachnaeSwarm/WorkGivers/WorkGiver_Refuel_Nutrition.cs b/Source/ArachnaeSwarm/WorkGivers/WorkGiver_Refuel_Nutrition.cs
new file mode 100644
index 0000000..215efd5
--- /dev/null
+++ b/Source/ArachnaeSwarm/WorkGivers/WorkGiver_Refuel_Nutrition.cs
@@ -0,0 +1,70 @@
+using System.Collections.Generic;
+using System.Linq;
+using RimWorld;
+using Verse;
+using Verse.AI;
+
+namespace ArachnaeSwarm
+{
+ public class WorkGiver_Refuel_Nutrition : WorkGiver_Scanner
+ {
+ public override ThingRequest PotentialWorkThingRequest => ThingRequest.ForGroup(ThingRequestGroup.BuildingArtificial);
+
+ public override PathEndMode PathEndMode => PathEndMode.Touch;
+
+ public override IEnumerable PotentialWorkThingsGlobal(Pawn pawn)
+ {
+ // Find all buildings that have our special component.
+ return pawn.Map.listerBuildings.allBuildingsColonist.Where(b =>
+ b.GetComp() != null);
+ }
+
+ public override bool HasJobOnThing(Pawn pawn, Thing t, bool forced = false)
+ {
+ var building = t as Building;
+ if (building == null) return false;
+
+ // --- KEY CHANGE HERE ---
+ // Target the specific nutrition component
+ var refuelableComp = building.GetComp();
+ if (refuelableComp == null || refuelableComp.IsFull) return false;
+
+ if (!refuelableComp.ShouldAutoRefuelNow && !forced) return false;
+
+ if (building.IsForbidden(pawn) || !pawn.CanReserve(building, 1, -1, null, forced)) return false;
+
+ var fuel = FindBestFuel(pawn, refuelableComp);
+ if (fuel == null)
+ {
+ JobFailReason.Is("NoFuelToRefuel".Translate(refuelableComp.Props.fuelFilter.Summary));
+ return false;
+ }
+
+ return true;
+ }
+
+ public override Job JobOnThing(Pawn pawn, Thing t, bool forced = false)
+ {
+ var building = t as Building;
+ var refuelableComp = building.GetComp();
+ var fuel = FindBestFuel(pawn, refuelableComp);
+
+ // Return our custom Job
+ return new Job(DefDatabase.GetNamed("ARA_Refuel_Nutrition"), building, fuel);
+ }
+
+ private Thing FindBestFuel(Pawn pawn, CompRefuelable refuelable)
+ {
+ var fuelFilter = refuelable.Props.fuelFilter;
+ return GenClosest.ClosestThingReachable(
+ pawn.Position,
+ pawn.Map,
+ ThingRequest.ForGroup(ThingRequestGroup.HaulableEver),
+ PathEndMode.ClosestTouch,
+ TraverseParms.For(pawn),
+ 9999f,
+ thing => !thing.IsForbidden(pawn) && fuelFilter.Allows(thing) && pawn.CanReserve(thing)
+ );
+ }
+ }
+}
\ No newline at end of file