This commit is contained in:
2025-08-14 15:16:36 +08:00
parent 1fafac51bb
commit 0e0a952b0f
6 changed files with 80 additions and 65 deletions

View File

@@ -190,7 +190,6 @@
<maxEnergyLevelPercentage>0.9</maxEnergyLevelPercentage> <maxEnergyLevelPercentage>0.9</maxEnergyLevelPercentage>
<emergencyPriority>9.5</emergencyPriority> <emergencyPriority>9.5</emergencyPriority>
</li> </li>
<li Class="JobGiver_GetRest"/>
<li Class="JobGiver_SatisfyChemicalNeed"/> <li Class="JobGiver_SatisfyChemicalNeed"/>
<li Class="JobGiver_SatifyChemicalDependency" MayRequire="Ludeon.RimWorld.Biotech" /> <li Class="JobGiver_SatifyChemicalDependency" MayRequire="Ludeon.RimWorld.Biotech" />
<li Class="JobGiver_GetHemogen" MayRequire="Ludeon.RimWorld.Biotech" /> <li Class="JobGiver_GetHemogen" MayRequire="Ludeon.RimWorld.Biotech" />

View File

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8" ?>
<Defs>
<JobDef>
<defName>WULA_LayDownToCharge</defName>
<driverClass>WulaFallenEmpire.JobDriver_WulaLayDownToCharge</driverClass>
<reportString>正在充电。</reportString>
<casualInterruptible>false</casualInterruptible>
</JobDef>
</Defs>

View File

@@ -1,6 +1,6 @@
using RimWorld; using RimWorld;
using System.Collections.Generic;
using Verse; using Verse;
using System.Linq;
namespace WulaFallenEmpire namespace WulaFallenEmpire
{ {
@@ -17,60 +17,53 @@ namespace WulaFallenEmpire
public class CompChargingBed : ThingComp public class CompChargingBed : ThingComp
{ {
private Pawn lastOccupant; public CompProperties_ChargingBed Props => (CompProperties_ChargingBed)props;
private CompProperties_ChargingBed Props => (CompProperties_ChargingBed)props;
private List<Pawn> chargingPawns = new List<Pawn>();
public override void CompTick() public override void CompTick()
{ {
base.CompTick(); base.CompTick();
var bed = (Building_Bed)parent;
var occupants = new HashSet<Pawn>(bed.CurOccupants);
if (parent is Building_Bed bed) for (int i = chargingPawns.Count - 1; i >= 0; i--)
{ {
Pawn currentOccupant = bed.CurOccupants.FirstOrDefault(); var pawn = chargingPawns[i];
if (!occupants.Contains(pawn))
if (currentOccupant != lastOccupant)
{ {
Log.Message($"[CompChargingBed] Occupant changed. Old: {lastOccupant?.Name.ToStringShort ?? "null"}, New: {currentOccupant?.Name.ToStringShort ?? "null"} on {parent.Label}"); var hediff = pawn.health.hediffSet.GetFirstHediffOfDef(Props.hediffDef);
} if (hediff != null)
// Pawn starts resting
if (currentOccupant != null && lastOccupant == null)
{
if (IsWula(currentOccupant))
{ {
Log.Message($"[CompChargingBed] {currentOccupant.Name.ToStringShort} started resting. Applying hediff."); pawn.health.RemoveHediff(hediff);
ApplyChargingHediff(currentOccupant); }
chargingPawns.RemoveAt(i);
}
}
if (bed.AnyOccupants)
{
foreach (var pawn in bed.CurOccupants)
{
if (pawn.def.defName == Props.raceDefName)
{
if (!pawn.health.hediffSet.HasHediff(Props.hediffDef))
{
pawn.health.AddHediff(Props.hediffDef);
if (!chargingPawns.Contains(pawn))
{
chargingPawns.Add(pawn);
}
}
} }
} }
// Pawn stops resting
else if (currentOccupant == null && lastOccupant != null)
{
// Logic to remove hediff is now in the JobDriver, but we can log the event.
if (IsWula(lastOccupant))
{
Log.Message($"[CompChargingBed] {lastOccupant.Name.ToStringShort} stopped resting.");
}
}
lastOccupant = currentOccupant;
} }
} }
private bool IsWula(Pawn pawn) public override void PostExposeData()
{ {
return pawn.def.defName == Props.raceDefName || pawn.def.defName == (Props.raceDefName + "Real"); base.PostExposeData();
Scribe_Collections.Look(ref chargingPawns, "chargingPawns", LookMode.Reference);
} }
private void ApplyChargingHediff(Pawn pawn)
{
var powerComp = parent.GetComp<CompPowerTrader>();
Log.Message($"[CompChargingBed] Trying to apply hediff to {pawn.Name.ToStringShort}. PowerOn: {powerComp?.PowerOn}. HasHediff: {pawn.health.hediffSet.HasHediff(Props.hediffDef)}");
if (powerComp != null && powerComp.PowerOn && !pawn.health.hediffSet.HasHediff(Props.hediffDef))
{
Log.Message($"[CompChargingBed] Adding hediff to {pawn.Name.ToStringShort}.");
pawn.health.AddHediff(Props.hediffDef);
}
}
} }
} }

View File

@@ -5,40 +5,52 @@ using Verse.AI;
namespace WulaFallenEmpire namespace WulaFallenEmpire
{ {
public class JobDriver_WulaLayDownToCharge : JobDriver_LayDown public class JobDriver_WulaLayDownToCharge : JobDriver
{ {
public override bool TryMakePreToilReservations(bool errorOnFailed)
{
return pawn.Reserve(job.targetA, job, 1, -1, null, errorOnFailed);
}
protected override IEnumerable<Toil> MakeNewToils() protected override IEnumerable<Toil> MakeNewToils()
{ {
this.AddFinishAction(jobCondition => this.AddFinishAction(jobCondition =>
{ {
Log.Message($"[JobDriver_WulaLayDownToCharge] Job finishing for {pawn.Name.ToStringShort} with condition {jobCondition}. Removing hediff."); var bed = (Building_Bed)job.targetA.Thing;
var hediff = pawn.health.hediffSet.GetFirstHediffOfDef(HediffDef.Named("WULA_ChargingHediff")); var comp = bed.GetComp<CompChargingBed>();
if (comp == null) return;
var hediff = pawn.health.hediffSet.GetFirstHediffOfDef(comp.Props.hediffDef);
if (hediff != null) if (hediff != null)
{ {
pawn.health.RemoveHediff(hediff); pawn.health.RemoveHediff(hediff);
Log.Message($"[JobDriver_WulaLayDownToCharge] Hediff removed from {pawn.Name.ToStringShort}.");
}
else
{
Log.Message($"[JobDriver_WulaLayDownToCharge] No hediff found on {pawn.Name.ToStringShort} to remove.");
} }
}); });
foreach (Toil toil in base.MakeNewToils()) yield return Toils_Bed.GotoBed(TargetIndex.A);
{
yield return toil;
}
var bed = (Building_Bed)job.targetA.Thing; Toil layDownAndCharge = Toils_LayDown.LayDown(TargetIndex.A, true, false, false, false);
var powerComp = bed.GetComp<CompPowerTrader>(); layDownAndCharge.AddPreInitAction(delegate
var checkToil = new Toil
{ {
tickAction = delegate if (!pawn.health.hediffSet.HasHediff(HediffDef.Named("WULA_ChargingHediff")))
{ {
var bed = (Building_Bed)job.targetA.Thing;
var comp = bed.GetComp<CompChargingBed>();
if (comp != null && !pawn.health.hediffSet.HasHediff(comp.Props.hediffDef))
{
pawn.health.AddHediff(comp.Props.hediffDef);
}
}
});
layDownAndCharge.tickAction = delegate
{
if (pawn.IsHashIntervalTick(60))
{
var bed = (Building_Bed)job.targetA.Thing;
var powerComp = bed.GetComp<CompPowerTrader>();
if (powerComp != null && !powerComp.PowerOn) if (powerComp != null && !powerComp.PowerOn)
{ {
Log.Message($"[JobDriver_WulaLayDownToCharge] Power lost for {pawn.Name.ToStringShort}. Ending job.");
EndJobWith(JobCondition.Incompletable); EndJobWith(JobCondition.Incompletable);
return; return;
} }
@@ -46,13 +58,12 @@ namespace WulaFallenEmpire
Need_WulaEnergy energyNeed = pawn.needs.TryGetNeed<Need_WulaEnergy>(); Need_WulaEnergy energyNeed = pawn.needs.TryGetNeed<Need_WulaEnergy>();
if (energyNeed != null && energyNeed.CurLevelPercentage >= 0.99f) if (energyNeed != null && energyNeed.CurLevelPercentage >= 0.99f)
{ {
Log.Message($"[JobDriver_WulaLayDownToCharge] {pawn.Name.ToStringShort} is fully charged. Ending job.");
EndJobWith(JobCondition.Succeeded); EndJobWith(JobCondition.Succeeded);
} }
}, }
defaultCompleteMode = ToilCompleteMode.Never
}; };
yield return checkToil;
yield return layDownAndCharge;
} }
} }
} }

View File

@@ -103,7 +103,7 @@ namespace WulaFallenEmpire
Building_Bed bed = (Building_Bed)GenClosest.ClosestThingReachable( Building_Bed bed = (Building_Bed)GenClosest.ClosestThingReachable(
pawn.Position, pawn.Position,
pawn.Map, pawn.Map,
ThingRequest.ForDef(ThingDefOf_WULA.WULA_Charging_Station_Synth), ThingRequest.ForGroup(ThingRequestGroup.BuildingArtificial),
PathEndMode.InteractionCell, PathEndMode.InteractionCell,
TraverseParms.For(pawn), TraverseParms.For(pawn),
9999f, 9999f,
@@ -112,6 +112,9 @@ namespace WulaFallenEmpire
Building_Bed bed_internal = b as Building_Bed; Building_Bed bed_internal = b as Building_Bed;
if (bed_internal == null) return false; if (bed_internal == null) return false;
var chargingComp = bed_internal.GetComp<CompChargingBed>();
if (chargingComp == null) return false;
var powerComp = bed_internal.GetComp<CompPowerTrader>(); var powerComp = bed_internal.GetComp<CompPowerTrader>();
return !bed_internal.IsForbidden(pawn) && return !bed_internal.IsForbidden(pawn) &&
pawn.CanReserve(bed_internal) && pawn.CanReserve(bed_internal) &&