Skip to content

P35.9#8

Merged
Sellafield merged 3 commits into
developfrom
p35.9
May 3, 2026
Merged

P35.9#8
Sellafield merged 3 commits into
developfrom
p35.9

Conversation

@Sellafield
Copy link
Copy Markdown
Contributor

No description provided.

Sellafield and others added 3 commits May 2, 2026 11:19
LogoutPlayer() ran inside a TransactionScope with no exception handling:
on any DB failure the method exited without calling Disconnect/OnStopped,
leaving _isInLogout=true with no recovery path and the character marked
online permanently in the database.

- Wrap LogoutPlayer() in try/catch/finally so Disconnect() and OnStopped()
  always execute; catch block ensures in-memory state (RemoveFromZone,
  SetSession) is cleaned up even when the transaction is rolled back.
- Remove LogoutRequest(false) from Disconnect() — it incorrectly created a
  new logout timer after logout had already completed (timer was cleared
  before Task.Run). OnDisconnected already starts the timer for raw
  TCP disconnections.
- Guard OnDisconnected against creating a logout timer when _isInLogout is
  already true to prevent a spurious second timer during session teardown.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
NPCs that carry a Remote Armor Repairer or Energy Transferer now switch
into a dedicated SupportAI state when any non-hostile NPC drops below
75% armor or energy. The most-needy ally (lowest %) is prioritized; the
support NPC paths into module range with combat-style A* pathing,
acquires a primary lock on the friend, and ticks support module
activators that bypass the visibility set (same-faction friends are not
visibility-tracked) by checking LOS directly through the zone.

While in SupportAI, the NPC ignores enemies — combat module activators
do not run and combat locks are dropped on Enter. AggressorAI's existing
ShouldFlee branch still wins, so support NPCs flee to safety when their
own armor or core gets low. AggressorAI re-acquires combat locks
naturally on resume via CombatAI.UpdateHostiles after SupportAI pops.

Friend discovery combines flock members with visible non-hostile
SmartCreatures, covering both same-faction allies (Niani+Niani) and
cross-faction allies (Niani+Cultist, both non-Syndicate per
Npc.IsHostile). NPCs without remote support modules short-circuit on
IsSupportCapable, so existing behavior is unchanged for them.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Three issues surfaced during in-zone testing:

1) Support modules fired on enemies during combat. CombatAI.Enter built
   a ModuleActivator for every equipped module — the standard Visit
   methods for RemoteArmorRepair/EnergyTransferer pick whatever is
   locked, which in combat is the enemy. Filter both module types out
   of CombatAI's activator list; SupportAI owns them.

2) NullReferenceException at the movement-start path and bot failing
   to follow its lock target. Two compounding bugs:
   - FindSupportPosition (worker thread) wrote `smartCreature.StopMoving()`
     and `movement = null` directly to instance fields. When a second
     worker started while the first's continuation had just populated
     `nextMovement`, the AI tick could read the swapped pending
     movement, then have it nulled by the worker before .Start ran.
   - The repath trigger used `movement == null` so the AI tick
     re-issued (and cancelled) the path search every frame until a
     path materialized, which it never did.
   Mirror CombatAI's trigger condition (target moved or periodic
   timer), gate it with a pathPending flag like FleeAI uses, drop the
   cross-thread mutations, add a defensive null check on the
   Interlocked.Exchange result, and wrap FindSupportPosition in a
   try/catch so worker exceptions don't fault the task.

3) Bot ran both repair and energy transfer regardless of need. Split
   activators into repair/transfer lists and only tick the kind whose
   corresponding stat on the current target is actually below the
   support threshold.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@Sellafield Sellafield merged commit be00785 into develop May 3, 2026
1 check passed
@Sellafield Sellafield deleted the p35.9 branch May 3, 2026 02:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants