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 @@ +