Skip to content

Fix TendSelf/TendPatient reservation conflict in CompTend - #4653

Open
WhiteGiverMa wants to merge 2 commits into
CombatExtended-Continued:Developmentfrom
WhiteGiverMa:fix/tend-self-reservation-conflict
Open

Fix TendSelf/TendPatient reservation conflict in CompTend#4653
WhiteGiverMa wants to merge 2 commits into
CombatExtended-Continued:Developmentfrom
WhiteGiverMa:fix/tend-self-reservation-conflict

Conversation

@WhiteGiverMa

@WhiteGiverMa WhiteGiverMa commented Jul 5, 2026

Copy link
Copy Markdown

Additions

  • None (pure bugfix)

Changes

  • CompTend.TryGiveTacticalJob() now checks ReservationManager.ReservationsReadOnly before creating a TendSelf job. If another pawn has already reserved the target (e.g., a doctor performing TendPatient), the assignment is skipped and the cooldown counter (lastTendJobCheckedAt) is updated.

References

  • Closes #[ISSUE_NUMBER] (if an issue exists, otherwise: N/A)

Reasoning

  • In combat, when a non-player pawn (prisoner, ally, animal) is bleeding, CE's CompTend simultaneously assigns a TendSelf job while a doctor pawn may already be tending them via TendPatient. Both jobs call pawn.Reserve(Deliveree, ...) through JobDriver_TendPatient.TryMakePreToilReservations with maxPawns: 1 on the same target, causing LogCouldNotReserveError red error spam in the console.
  • The fix prevents this by checking the reservation manager before creating the job — if the target pawn is already reserved by someone else, TendSelf is deferred. This is a minimal, targeted change that preserves all existing CompTend logic (cooldown, enemy proximity check, capability checks, etc.).
  • The reservation check iterates ReservationsReadOnly directly rather than using IsReservedByAnyoneOf(target, faction) to cover cross-faction scenarios (e.g., a player-faction doctor tending a prisoner from a different faction).

Alternatives

  • Check reservation in TryGiveTacticalJobs prefix instead (the caller):
    • Would catch reservation conflicts for ALL tactical comps, not just CompTend.
    • But each comp has different reservation patterns — a generic check in the caller cannot know what targets each job type needs to reserve.
    • Placing the check inside CompTend keeps the fix scoped to the actual problem.
  • Use IsReservedByAnyoneOf(target, pawn.Faction):
    • Simpler API, but filters by faction — would miss cross-faction reservation conflicts (doctor from faction A tending prisoner from faction B).
    • ReservationsReadOnly with explicit iteration covers all cases.

Testing

  • Compiles without warnings
  • Game runs without errors
  • Playtested a colony 60+ days

Note: fix verified through a local Harmony prefix patch (same logic, built and deployed). In-game testing pending.

When CompTend assigns a TendSelf job to a pawn, it never checks
whether another pawn has already reserved that pawn for TendPatient.
Both jobs call pawn.Reserve(Deliveree, ...) with maxPawns=1 on the
same target, causing the second Reserve() to fail and spam
LogCouldNotReserveError red errors in combat.

Reproduction: capture a prisoner, injure them, send a doctor to
tend them. The prisoner (non-player faction, thus eligible for
CompTend) will simultaneously try to TendSelf, triggering the
reservation conflict.

Fix: before creating the TendSelf job, iterate ReservationManager.
ReservationsReadOnly to check if any other pawn has already
reserved the target.
@WhiteGiverMa
WhiteGiverMa requested review from a team as code owners July 5, 2026 10:40
@github-actions

github-actions Bot commented Jul 5, 2026

Copy link
Copy Markdown

You can download the rebuilt assembly for this PR here: https://combatextended.lp-programming.com/CombatExtended-28738024820.zip

@github-actions github-actions Bot added the Download in Comments This PR has a zipfile download available. label Jul 5, 2026
@mszabo-wikia

Copy link
Copy Markdown
Contributor

Thanks! Can you provide some reproduction steps and a corresponding Player.log?

@github-actions

Copy link
Copy Markdown

You can download the rebuilt assembly for this PR here: https://combatextended.lp-programming.com/CombatExtended-29979168696.zip

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Download in Comments This PR has a zipfile download available.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants