燃料装填
This commit is contained in:
Binary file not shown.
11
1.6/1.6/Defs/JobDefs/ARA_Jobs_Nutrition.xml
Normal file
11
1.6/1.6/Defs/JobDefs/ARA_Jobs_Nutrition.xml
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8" ?>
|
||||||
|
<Defs>
|
||||||
|
|
||||||
|
<JobDef>
|
||||||
|
<defName>ARA_Refuel_Nutrition</defName>
|
||||||
|
<driverClass>ArachnaeSwarm.JobDriver_Refuel_Nutrition</driverClass>
|
||||||
|
<reportString>正在为 TargetA 补充营养。</reportString>
|
||||||
|
<allowOpportunisticPrefix>true</allowOpportunisticPrefix>
|
||||||
|
</JobDef>
|
||||||
|
|
||||||
|
</Defs>
|
||||||
14
1.6/1.6/Defs/WorkGiverDefs/ARA_WorkGivers.xml
Normal file
14
1.6/1.6/Defs/WorkGiverDefs/ARA_WorkGivers.xml
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8" ?>
|
||||||
|
<Defs>
|
||||||
|
<WorkGiverDef>
|
||||||
|
<defName>ARA_Refuel_Nutrition</defName>
|
||||||
|
<label>补充营养</label>
|
||||||
|
<giverClass>ArachnaeSwarm.WorkGiver_Refuel_Nutrition</giverClass>
|
||||||
|
<workType>Hauling</workType>
|
||||||
|
<priorityInType>60</priorityInType>
|
||||||
|
<verb>补充</verb>
|
||||||
|
<gerund>补充</gerund>
|
||||||
|
<scanThings>true</scanThings>
|
||||||
|
<scanCells>false</scanCells>
|
||||||
|
</WorkGiverDef>
|
||||||
|
</Defs>
|
||||||
@@ -146,6 +146,8 @@
|
|||||||
<Compile Include="Building_Comps\WULA_MutiFuelSpawner\Patch_CompRefuelableWithKey.cs" />
|
<Compile Include="Building_Comps\WULA_MutiFuelSpawner\Patch_CompRefuelableWithKey.cs" />
|
||||||
<Compile Include="Building_Comps\CompNutritionToFuelConverter.cs" />
|
<Compile Include="Building_Comps\CompNutritionToFuelConverter.cs" />
|
||||||
<Compile Include="Building_Comps\CompAutoEjector.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_ConfigurableMutant.cs" />
|
||||||
<Compile Include="Hediffs\ARA_ConfigurableMutant\Hediff_NecroticVirus_Configurable.cs" />
|
<Compile Include="Hediffs\ARA_ConfigurableMutant\Hediff_NecroticVirus_Configurable.cs" />
|
||||||
<Compile Include="Hediffs\ARA_ConfigurableMutant\HediffComp_NecroticTransformation.cs" />
|
<Compile Include="Hediffs\ARA_ConfigurableMutant\HediffComp_NecroticTransformation.cs" />
|
||||||
|
|||||||
@@ -63,10 +63,7 @@ namespace ArachnaeSwarm
|
|||||||
fuelNeeded = TargetFuelLevel - Fuel;
|
fuelNeeded = TargetFuelLevel - Fuel;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (totalNutritionGained > 0 && Props.fuelGizmoLabel != null)
|
// Let the job driver handle the message. This component should only handle logic.
|
||||||
{
|
|
||||||
Messages.Message("MessageRefueled".Translate(parent.LabelShort, totalNutritionGained.ToString("0.##"), Props.fuelGizmoLabel), parent, MessageTypeDefOf.PositiveEvent);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ReceiveFuel(float amount)
|
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