diff --git a/1.6/Assemblies/WulaFallenEmpire.dll b/1.6/Assemblies/WulaFallenEmpire.dll
index 870094b2..85be7978 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_JobDefs.xml b/1.6/Defs/JobDefs/WULA_JobDefs.xml
index 6d567805..68ba56d1 100644
--- a/1.6/Defs/JobDefs/WULA_JobDefs.xml
+++ b/1.6/Defs/JobDefs/WULA_JobDefs.xml
@@ -22,4 +22,12 @@
true
+
+ WULA_HaulToMaintenancePod
+ WulaFallenEmpire.JobDriver_HaulToMaintenancePod
+ 正在将TargetA抬到TargetB。
+ true
+ false
+
+
\ No newline at end of file
diff --git a/1.6/Defs/ThingDefs_Buildings/WULA_Buildings_Maintenance.xml b/1.6/Defs/ThingDefs_Buildings/WULA_Buildings_Maintenance.xml
index 78967690..46977ccf 100644
--- a/1.6/Defs/ThingDefs_Buildings/WULA_Buildings_Maintenance.xml
+++ b/1.6/Defs/ThingDefs_Buildings/WULA_Buildings_Maintenance.xml
@@ -69,7 +69,8 @@
true
- 60000
+ 30000
+ 30000
250
5
WULA_Maintenance_Neglect
diff --git a/Source/WulaFallenEmpire/CompMaintenancePod.cs b/Source/WulaFallenEmpire/CompMaintenancePod.cs
index 9dcefd2b..43217cee 100644
--- a/Source/WulaFallenEmpire/CompMaintenancePod.cs
+++ b/Source/WulaFallenEmpire/CompMaintenancePod.cs
@@ -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 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 options = new List();
- 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 options = GetPawnOptions();
if (options.Any())
{
Find.WindowStack.Add(new FloatMenu(options));
@@ -261,6 +260,43 @@ namespace WulaFallenEmpire
yield return cancelCommand;
}
}
+
+ private List GetPawnOptions()
+ {
+ List options = new List();
+ 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
diff --git a/Source/WulaFallenEmpire/JobDefOf_WULA.cs b/Source/WulaFallenEmpire/JobDefOf_WULA.cs
index ed0e0d28..253d8ae7 100644
--- a/Source/WulaFallenEmpire/JobDefOf_WULA.cs
+++ b/Source/WulaFallenEmpire/JobDefOf_WULA.cs
@@ -8,6 +8,7 @@ namespace WulaFallenEmpire
{
public static JobDef WULA_LoadComponentsToMaintenancePod;
public static JobDef WULA_EnterMaintenancePod;
+ public static JobDef WULA_HaulToMaintenancePod;
static JobDefOf_WULA()
{
diff --git a/Source/WulaFallenEmpire/JobDriver_HaulToMaintenancePod.cs b/Source/WulaFallenEmpire/JobDriver_HaulToMaintenancePod.cs
index 29224a9f..6046a391 100644
--- a/Source/WulaFallenEmpire/JobDriver_HaulToMaintenancePod.cs
+++ b/Source/WulaFallenEmpire/JobDriver_HaulToMaintenancePod.cs
@@ -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 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();
+ 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();
-
- 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;
}
}
}
\ No newline at end of file
diff --git a/Source/WulaFallenEmpire/ThingDefOf_WULA.cs b/Source/WulaFallenEmpire/ThingDefOf_WULA.cs
index 4f61ed19..60f5e417 100644
--- a/Source/WulaFallenEmpire/ThingDefOf_WULA.cs
+++ b/Source/WulaFallenEmpire/ThingDefOf_WULA.cs
@@ -7,6 +7,7 @@ namespace WulaFallenEmpire
public static class ThingDefOf_WULA
{
public static ThingDef WULA_MaintenancePod;
+ public static ThingDef Wula;
static ThingDefOf_WULA()
{
diff --git a/Source/WulaFallenEmpire/WorkGiver_HaulToMaintenancePod.cs b/Source/WulaFallenEmpire/WorkGiver_HaulToMaintenancePod.cs
index 24b37049..95d56697 100644
--- a/Source/WulaFallenEmpire/WorkGiver_HaulToMaintenancePod.cs
+++ b/Source/WulaFallenEmpire/WorkGiver_HaulToMaintenancePod.cs
@@ -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 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();
- if (comp == null || comp.State != MaintenancePodState.Idle)
+ var podComp = pod.GetComp();
+ 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();
-
- Thing component = FindBestComponent(pawn, comp);
- if (component == null)
+ var pod = (Building)t;
+ var podComp = pod.GetComp();
+ 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 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().Fuel &&
+ rescuer.CanReserve(p))
+ .OrderBy(p => p.Position.DistanceTo(rescuer.Position))
+ .FirstOrDefault();
}
}
}
\ No newline at end of file
diff --git a/Source/WulaFallenEmpire/WulaFallenEmpire.csproj b/Source/WulaFallenEmpire/WulaFallenEmpire.csproj
index c40b15bc..6fc2e370 100644
--- a/Source/WulaFallenEmpire/WulaFallenEmpire.csproj
+++ b/Source/WulaFallenEmpire/WulaFallenEmpire.csproj
@@ -100,6 +100,7 @@
+
@@ -135,6 +136,7 @@
+