燃料装填
This commit is contained in:
@@ -146,6 +146,8 @@
|
||||
<Compile Include="Building_Comps\WULA_MutiFuelSpawner\Patch_CompRefuelableWithKey.cs" />
|
||||
<Compile Include="Building_Comps\CompNutritionToFuelConverter.cs" />
|
||||
<Compile Include="Building_Comps\CompAutoEjector.cs" />
|
||||
<Compile Include="Jobs\JobDriver_Refuel_Nutrition.cs" />
|
||||
<Compile Include="WorkGivers\WorkGiver_Refuel_Nutrition.cs" />
|
||||
<Compile Include="Hediffs\ARA_ConfigurableMutant\Hediff_ConfigurableMutant.cs" />
|
||||
<Compile Include="Hediffs\ARA_ConfigurableMutant\Hediff_NecroticVirus_Configurable.cs" />
|
||||
<Compile Include="Hediffs\ARA_ConfigurableMutant\HediffComp_NecroticTransformation.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)
|
||||
|
||||
88
Source/ArachnaeSwarm/Jobs/JobDriver_Refuel_Nutrition.cs
Normal file
88
Source/ArachnaeSwarm/Jobs/JobDriver_Refuel_Nutrition.cs
Normal file
@@ -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<CompRefuelableNutrition>();
|
||||
|
||||
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<Toil> 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<CompRefuelableNutrition>();
|
||||
|
||||
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<Thing> { actor.carryTracker.CarriedThing });
|
||||
};
|
||||
toil.defaultCompleteMode = ToilCompleteMode.Instant;
|
||||
return toil;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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<Thing> PotentialWorkThingsGlobal(Pawn pawn)
|
||||
{
|
||||
// Find all buildings that have our special component.
|
||||
return pawn.Map.listerBuildings.allBuildingsColonist.Where(b =>
|
||||
b.GetComp<CompRefuelableNutrition>() != 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<CompRefuelableNutrition>();
|
||||
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<CompRefuelableNutrition>();
|
||||
var fuel = FindBestFuel(pawn, refuelableComp);
|
||||
|
||||
// Return our custom Job
|
||||
return new Job(DefDatabase<JobDef>.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)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user