暂存
This commit is contained in:
Binary file not shown.
@@ -22,4 +22,12 @@
|
||||
<allowOpportunisticPrefix>true</allowOpportunisticPrefix>
|
||||
</JobDef>
|
||||
|
||||
<JobDef>
|
||||
<defName>WULA_HaulToMaintenancePod</defName>
|
||||
<driverClass>WulaFallenEmpire.JobDriver_HaulToMaintenancePod</driverClass>
|
||||
<reportString>正在将TargetA抬到TargetB。</reportString>
|
||||
<allowOpportunisticPrefix>true</allowOpportunisticPrefix>
|
||||
<casualInterruptible>false</casualInterruptible>
|
||||
</JobDef>
|
||||
|
||||
</Defs>
|
||||
@@ -69,7 +69,8 @@
|
||||
<targetFuelLevelConfigurable>true</targetFuelLevelConfigurable>
|
||||
</li>
|
||||
<li Class="WulaFallenEmpire.CompProperties_MaintenancePod">
|
||||
<durationTicks>60000</durationTicks> <!-- 1 day -->
|
||||
<baseDurationTicks>30000</baseDurationTicks> <!-- 0.5 days base time -->
|
||||
<ticksPerSeverity>30000</ticksPerSeverity> <!-- 0.5 days per 1.0 severity -->
|
||||
<powerConsumptionRunning>250</powerConsumptionRunning>
|
||||
<powerConsumptionIdle>5</powerConsumptionIdle>
|
||||
<hediffToRemove>WULA_Maintenance_Neglect</hediffToRemove>
|
||||
|
||||
@@ -16,7 +16,8 @@ namespace WulaFallenEmpire
|
||||
public SoundDef enterSound;
|
||||
public SoundDef exitSound;
|
||||
public EffecterDef operatingEffecter;
|
||||
public int durationTicks = 60000; // Default to 1 day
|
||||
public int baseDurationTicks = 60000;
|
||||
public float ticksPerSeverity = 0f;
|
||||
public float powerConsumptionRunning = 250f;
|
||||
public float powerConsumptionIdle = 50f;
|
||||
public HediffDef hediffToRemove;
|
||||
@@ -57,6 +58,14 @@ namespace WulaFallenEmpire
|
||||
return Props.baseComponentCost + (int)(hediff.Severity * Props.componentCostPerSeverity);
|
||||
}
|
||||
|
||||
public int RequiredDuration(Pawn pawn)
|
||||
{
|
||||
if (pawn == null || Props.hediffToRemove == null) return Props.baseDurationTicks;
|
||||
Hediff hediff = pawn.health.hediffSet.GetFirstHediffOfDef(Props.hediffToRemove);
|
||||
if (hediff == null) return Props.baseDurationTicks;
|
||||
return Props.baseDurationTicks + (int)(hediff.Severity * Props.ticksPerSeverity);
|
||||
}
|
||||
|
||||
// ===================== Setup =====================
|
||||
public CompMaintenancePod()
|
||||
{
|
||||
@@ -130,9 +139,12 @@ namespace WulaFallenEmpire
|
||||
return;
|
||||
}
|
||||
|
||||
refuelableComp.ConsumeFuel(required);
|
||||
if (required > 0)
|
||||
{
|
||||
refuelableComp.ConsumeFuel(required);
|
||||
}
|
||||
state = MaintenancePodState.Running;
|
||||
ticksRemaining = Props.durationTicks;
|
||||
ticksRemaining = RequiredDuration(pawn);
|
||||
|
||||
// Move pawn inside
|
||||
pawn.DeSpawn();
|
||||
@@ -201,7 +213,13 @@ namespace WulaFallenEmpire
|
||||
|
||||
public override IEnumerable<Gizmo> CompGetGizmosExtra()
|
||||
{
|
||||
// Gizmo to order a pawn to enter
|
||||
// Base gizmos
|
||||
foreach (var gizmo in base.CompGetGizmosExtra())
|
||||
{
|
||||
yield return gizmo;
|
||||
}
|
||||
|
||||
// Gizmo to order a pawn to enter (Right-click menu style)
|
||||
if (state == MaintenancePodState.Idle && PowerOn)
|
||||
{
|
||||
var enterCommand = new Command_Action
|
||||
@@ -211,26 +229,7 @@ namespace WulaFallenEmpire
|
||||
icon = EnterIcon,
|
||||
action = () =>
|
||||
{
|
||||
List<FloatMenuOption> options = new List<FloatMenuOption>();
|
||||
foreach (Pawn p in parent.Map.mapPawns.FreeColonists)
|
||||
{
|
||||
if (Props.hediffToRemove != null && p.health.hediffSet.HasHediff(Props.hediffToRemove))
|
||||
{
|
||||
float required = RequiredComponents(p);
|
||||
if (refuelableComp.Fuel >= required)
|
||||
{
|
||||
options.Add(new FloatMenuOption(p.LabelShort, () =>
|
||||
{
|
||||
Job job = JobMaker.MakeJob(JobDefOf_WULA.WULA_EnterMaintenancePod, parent);
|
||||
p.jobs.TryTakeOrderedJob(job, JobTag.Misc);
|
||||
}));
|
||||
}
|
||||
else
|
||||
{
|
||||
options.Add(new FloatMenuOption(p.LabelShort + " (" + "WULA_MaintenancePod_NotEnoughComponents".Translate(required.ToString("F0")) + ")", null));
|
||||
}
|
||||
}
|
||||
}
|
||||
List<FloatMenuOption> options = GetPawnOptions();
|
||||
if (options.Any())
|
||||
{
|
||||
Find.WindowStack.Add(new FloatMenu(options));
|
||||
@@ -261,6 +260,43 @@ namespace WulaFallenEmpire
|
||||
yield return cancelCommand;
|
||||
}
|
||||
}
|
||||
|
||||
private List<FloatMenuOption> GetPawnOptions()
|
||||
{
|
||||
List<FloatMenuOption> options = new List<FloatMenuOption>();
|
||||
foreach (Pawn p in parent.Map.mapPawns.FreeColonists.Where(pawn => pawn.def == ThingDefOf_WULA.Wula))
|
||||
{
|
||||
if (p.health.hediffSet.HasHediff(Props.hediffToRemove))
|
||||
{
|
||||
if (!p.CanReach(parent, PathEndMode.InteractionCell, Danger.Deadly))
|
||||
{
|
||||
options.Add(new FloatMenuOption(p.LabelShortCap + " (" + "CannotReach".Translate() + ")", null));
|
||||
}
|
||||
else if (p.Downed)
|
||||
{
|
||||
// This is handled by the WorkGiver, but we can add a note here if we want.
|
||||
// options.Add(new FloatMenuOption(p.LabelShortCap + " (" + "Incapacitated".Translate() + ")", null));
|
||||
}
|
||||
else
|
||||
{
|
||||
float required = RequiredComponents(p);
|
||||
if (refuelableComp.Fuel >= required)
|
||||
{
|
||||
options.Add(new FloatMenuOption(p.LabelShortCap, () =>
|
||||
{
|
||||
Job job = JobMaker.MakeJob(JobDefOf_WULA.WULA_EnterMaintenancePod, parent);
|
||||
p.jobs.TryTakeOrderedJob(job, JobTag.Misc);
|
||||
}));
|
||||
}
|
||||
else
|
||||
{
|
||||
options.Add(new FloatMenuOption(p.LabelShortCap + " (" + "WULA_MaintenancePod_NotEnoughComponents".Translate(required.ToString("F0")) + ")", null));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return options;
|
||||
}
|
||||
}
|
||||
|
||||
public enum MaintenancePodState
|
||||
|
||||
@@ -8,6 +8,7 @@ namespace WulaFallenEmpire
|
||||
{
|
||||
public static JobDef WULA_LoadComponentsToMaintenancePod;
|
||||
public static JobDef WULA_EnterMaintenancePod;
|
||||
public static JobDef WULA_HaulToMaintenancePod;
|
||||
|
||||
static JobDefOf_WULA()
|
||||
{
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using RimWorld;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Verse;
|
||||
using Verse.AI;
|
||||
@@ -8,50 +7,46 @@ namespace WulaFallenEmpire
|
||||
{
|
||||
public class JobDriver_HaulToMaintenancePod : JobDriver
|
||||
{
|
||||
private const TargetIndex ComponentInd = TargetIndex.A;
|
||||
private const TargetIndex PodInd = TargetIndex.B;
|
||||
private const TargetIndex PatientIndex = TargetIndex.A;
|
||||
private const TargetIndex PodIndex = TargetIndex.B;
|
||||
|
||||
protected Thing Component => job.GetTarget(ComponentInd).Thing;
|
||||
protected Building Pod => (Building)job.GetTarget(PodInd).Thing;
|
||||
protected Pawn Patient => (Pawn)job.GetTarget(PatientIndex).Thing;
|
||||
protected Building_Bed Pod => (Building_Bed)job.GetTarget(PodIndex).Thing;
|
||||
|
||||
public override bool TryMakePreToilReservations(bool errorOnFailed)
|
||||
{
|
||||
return pawn.Reserve(Component, job, 1, -1, null, errorOnFailed) && pawn.Reserve(Pod, job, 1, -1, null, errorOnFailed);
|
||||
return pawn.Reserve(Patient, job, 1, -1, null, errorOnFailed) &&
|
||||
pawn.Reserve(Pod, job, 1, -1, null, errorOnFailed);
|
||||
}
|
||||
|
||||
protected override IEnumerable<Toil> MakeNewToils()
|
||||
{
|
||||
this.FailOnDespawnedNullOrForbidden(PodInd);
|
||||
this.FailOnBurningImmobile(PodInd);
|
||||
this.FailOnDespawnedNullOrForbidden(PodIndex);
|
||||
this.FailOnDespawnedNullOrForbidden(PatientIndex);
|
||||
this.FailOnAggroMentalState(PatientIndex);
|
||||
this.FailOn(() => !Patient.Downed);
|
||||
|
||||
yield return Toils_Goto.GotoThing(ComponentInd, PathEndMode.ClosestTouch)
|
||||
.FailOnSomeonePhysicallyInteracting(ComponentInd);
|
||||
var podComp = Pod.TryGetComp<CompMaintenancePod>();
|
||||
this.FailOn(() => podComp == null || podComp.State != MaintenancePodState.Idle || !podComp.PowerOn);
|
||||
|
||||
yield return Toils_Haul.StartCarryThing(ComponentInd, false, true, false)
|
||||
.FailOnDestroyedNullOrForbidden(ComponentInd);
|
||||
// Go to the patient
|
||||
yield return Toils_Goto.GotoThing(PatientIndex, PathEndMode.OnCell);
|
||||
|
||||
yield return Toils_Goto.GotoThing(PodInd, PathEndMode.Touch);
|
||||
// Pick up the patient
|
||||
yield return Toils_Haul.StartCarryThing(PatientIndex);
|
||||
|
||||
Toil findPlaceAndDrop = new Toil();
|
||||
findPlaceAndDrop.initAction = delegate
|
||||
// Carry the patient to the pod
|
||||
yield return Toils_Goto.GotoThing(PodIndex, PathEndMode.InteractionCell);
|
||||
|
||||
// Place the patient in the pod
|
||||
yield return new Toil
|
||||
{
|
||||
Pawn actor = findPlaceAndDrop.actor;
|
||||
Job curJob = actor.jobs.curJob;
|
||||
Thing carriedThing = curJob.GetTarget(ComponentInd).Thing;
|
||||
|
||||
CompMaintenancePod podComp = curJob.GetTarget(PodInd).Thing.TryGetComp<CompMaintenancePod>();
|
||||
|
||||
if (podComp != null)
|
||||
initAction = () =>
|
||||
{
|
||||
podComp.AddComponents(carriedThing);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Fallback if something goes wrong, just drop it near the pod
|
||||
actor.carryTracker.TryDropCarriedThing(Pod.Position, ThingPlaceMode.Near, out Thing _);
|
||||
}
|
||||
podComp.StartCycle(Patient);
|
||||
},
|
||||
defaultCompleteMode = ToilCompleteMode.Instant
|
||||
};
|
||||
yield return findPlaceAndDrop;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,6 +7,7 @@ namespace WulaFallenEmpire
|
||||
public static class ThingDefOf_WULA
|
||||
{
|
||||
public static ThingDef WULA_MaintenancePod;
|
||||
public static ThingDef Wula;
|
||||
|
||||
static ThingDefOf_WULA()
|
||||
{
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using RimWorld;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Verse;
|
||||
@@ -11,61 +10,52 @@ namespace WulaFallenEmpire
|
||||
{
|
||||
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 IEnumerable<Thing> PotentialWorkThingsGlobal(Pawn pawn)
|
||||
{
|
||||
return pawn.Map.listerBuildings.AllBuildingsColonistOfDef(ThingDefOf_WULA.WULA_MaintenancePod);
|
||||
}
|
||||
|
||||
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))
|
||||
if (!(t is Building pod) || !pawn.CanReserve(pod, 1, -1, null, forced))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
CompMaintenancePod comp = building.GetComp<CompMaintenancePod>();
|
||||
if (comp == null || comp.State != MaintenancePodState.Idle)
|
||||
var podComp = pod.GetComp<CompMaintenancePod>();
|
||||
if (podComp == null || podComp.State != MaintenancePodState.Idle || !podComp.PowerOn)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if it needs more components
|
||||
if (comp.storedComponents >= comp.Props.capacity)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (FindBestComponent(pawn, comp) == null)
|
||||
{
|
||||
JobFailReason.Is("WULA_NoComponentsToHaul".Translate());
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
Pawn patient = FindPatientFor(pawn, podComp);
|
||||
return patient != null && pawn.CanReserve(patient, 1, -1, null, forced);
|
||||
}
|
||||
|
||||
public override Job JobOnThing(Pawn pawn, Thing t, bool forced = false)
|
||||
{
|
||||
Building building = (Building)t;
|
||||
CompMaintenancePod comp = building.GetComp<CompMaintenancePod>();
|
||||
|
||||
Thing component = FindBestComponent(pawn, comp);
|
||||
if (component == null)
|
||||
var pod = (Building)t;
|
||||
var podComp = pod.GetComp<CompMaintenancePod>();
|
||||
Pawn patient = FindPatientFor(pawn, podComp);
|
||||
if (patient == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
Job job = JobMaker.MakeJob(JobDefOf_WULA.WULA_LoadComponentsToMaintenancePod, component, t);
|
||||
job.count = Math.Min(component.stackCount, (int)(comp.Props.capacity - comp.storedComponents));
|
||||
return job;
|
||||
return JobMaker.MakeJob(JobDefOf_WULA.WULA_HaulToMaintenancePod, patient, pod);
|
||||
}
|
||||
|
||||
private Thing FindBestComponent(Pawn pawn, CompMaintenancePod podComp)
|
||||
private Pawn FindPatientFor(Pawn rescuer, CompMaintenancePod podComp)
|
||||
{
|
||||
ThingFilter filter = podComp.GetStoreSettings().filter;
|
||||
|
||||
Predicate<Thing> 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);
|
||||
return rescuer.Map.mapPawns.AllPawnsSpawned
|
||||
.Where(p => p.def == ThingDefOf_WULA.Wula &&
|
||||
p.Faction == rescuer.Faction &&
|
||||
!p.IsForbidden(rescuer) &&
|
||||
p.Downed && // Key condition: pawn cannot walk
|
||||
p.health.hediffSet.HasHediff(podComp.Props.hediffToRemove) &&
|
||||
podComp.RequiredComponents(p) <= podComp.parent.GetComp<CompRefuelable>().Fuel &&
|
||||
rescuer.CanReserve(p))
|
||||
.OrderBy(p => p.Position.DistanceTo(rescuer.Position))
|
||||
.FirstOrDefault();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -100,6 +100,7 @@
|
||||
<Compile Include="IngestPatch.cs" />
|
||||
<Compile Include="JobDriver_FeedWulaPatient.cs" />
|
||||
<Compile Include="JobDriver_EnterMaintenancePod.cs" />
|
||||
<Compile Include="JobDriver_HaulToMaintenancePod.cs" />
|
||||
<Compile Include="JobDriver_IngestWulaEnergy.cs" />
|
||||
<Compile Include="JobGiver_WulaGetEnergy.cs" />
|
||||
<Compile Include="JobGiver_WulaPackEnergy.cs" />
|
||||
@@ -135,6 +136,7 @@
|
||||
<Compile Include="Verb\Verb_ShootBeamExplosive.cs" />
|
||||
<Compile Include="Verb\VerbPropertiesExplosiveBeam.cs" />
|
||||
<Compile Include="WorkGiver_FeedWulaPatient.cs" />
|
||||
<Compile Include="WorkGiver_HaulToMaintenancePod.cs" />
|
||||
<Compile Include="WorkGiver_Warden_DeliverEnergy.cs" />
|
||||
<Compile Include="WorkGiver_Warden_FeedWula.cs" />
|
||||
<Compile Include="WorkGiverDefExtension_FeedWula.cs" />
|
||||
|
||||
Reference in New Issue
Block a user