Skip to content

Zul'Farrak boss steps: Zel'jeb, Farraki Arena, Gahz'rilla tactics, Bly (with the dead-NPC and arena-reset hold flags) - #391

Closed
pjerra wants to merge 20 commits into
devfrom
feat/ta243-zf-bosses
Closed

pjerra wants to merge 20 commits into
devfrom
feat/ta243-zf-bosses

Conversation

@pjerra

@pjerra pjerra commented Nov 2, 2026 •

Copy link
Copy Markdown
Owner

Parts A and B of #243 (Zul'Farrak boss steps). The TortoiseBots rows (part C) are in Sagiroth/TortoiseBots fix/units-hold-reset, migration 20261102190000, which goes with #1455.

Plan changes

  • The Zel'jeb wing and the Farraki Arena legs: a units hold plus gossip 62498.
  • The Gahz'rilla leg: two approach stands, and her interruptible casts as boss tactics.
  • Sergeant Bly's units hold in the run leader's rows.

New hold fields

  • reset_to_gossip (flag 16384): the arena hold goes back to its gossip after the script resets it.
  • skip_if_dead_of_gossip (flag 32768): Bly's hold ends when no crew unit is hostile. The core keeps the crew friendly for good if Bly dies first.

plan-export

  • A gossip may set dead_is_done.
  • A cut hop keeps off the plan's leave spawns, measured along its segments.

Compatibility: a turtle-agent binary built before this refuses the new fields, and the rows and the module ship together.

Deploy warning: do not deploy ZF exports with the farraki_arena (flag 16384) or bly (flag 32768) legs to a server without TortoiseBots PR #1477 (fix/units-hold-reset): the reset and the dead-NPC end need the module fix, and without it the holds hang (the module ignores the unknown flag bits and waits out the timeout).

Tests: plan validation for both flags, export row flags, the leave-spawn segment check, and plan-check on zulfarrak.

Reviews: Codex (3 rounds) and an Opus cold review of the TortoiseBots side.

pjerra and others added 20 commits October 21, 2026 22:19
…by its units, agent_only unit waits; Zul'Farrak exports without a cut

A boss's hold may leave instance_data out: plan-export writes the run leader's hold done by its units (entry 0, param 0, flags 0, the boss entry first, so a boss a script turns hostile later counts while still friendly). wait_for.agent_only names why a unit wait needs no row: plan-export leaves it out with a warning quoting the reason instead of cutting the plan. Validate takes the units hold as the loader does. A boss.first under a hold is warned as no kill order.

zulfarrak.json: the bly leg's three unit waits are agent_only, Bly's gossip is option 0, the boss has a units hold on the leg's spot (1884 1212 9, r25, 300 s); Murta, Oro and Raven join kill_first; the gahzrilla leg's Gahz'rilla wait is agent_only (the leg stays optional: its gong needs a row kind the module does not have). The whole plan now exports without --skip-legs bly.
…l writes an optional leg; Zul'Farrak's End Door wait is for active_alt

A via_item use_object (the item used ON the object) exports as TortoiseBots' use_on row: entry = the object, x,y,z = its near point, item = requires_item, after the move to its stand; Validate applies the loader's use_on rule. Options.WithOptional (--with-optional) writes a named optional leg into the rows with a warning that its item is the operator's to give to the lead bot before .bot run start (a GM .additem); a name that is no optional leg is refused. zulfarrak.json: the weegli_door wait for the End Door is for active_alt (state 2): Weegli's blast opens it with the alternative state (zulfarrak.cpp:423), and the module run r8 paused twice at a state-1 wait on an open door.
…Gahz'rilla dies at once, an invisible corpse at the pit); README: the gahzrilla export is TortoiseBots' opt-in file
…n Zul'Farrak's Bly gossip

Bly's crew is killed by the pyramid event's troll waves in some runs; the run leader then paused at the gossip and held 300 s on a dead hold. The flag lets the module count a dead NPC as done.
…s the east pool ring from within 50 yd (no navmesh hops of its own)
Sergeant Bly's gossip row counts a dead NPC as done, but the units hold after it needed a unit seen hostile: a Bly killed by the pyramid waves leaves the crew friendly for good (zulfarrak.cpp npc_sergeant_blyAI turns them only from his own postGossipStep 3), so nobody turns hostile and the hold waited 300 s.

hold.skip_if_dead_of_gossip on a boss's units hold: plan-export writes flag 16384 (kPlanFlagDeadGossipOk) and the plan check wants the boss's gossip step with dead_is_done. The run leader ends such a hold when no unit of it is hostile; at once when all lie dead.
…nFlagResetToGossip

The dead-gossip hold flag moves from 16384 to 32768 (plan-export constant,
plan check, README, zulfarrak.json note, tests). kPlanFlagDeadGossipOk = 32768
on the TortoiseBots side is not written yet.
… the script resets it

hold.reset_to_gossip (a boss's units hold only, never with skip_if_dead_of_gossip;
the leg's last event-start step must be the boss's gossip) exports as flag 16384,
kPlanFlagResetToGossip on the TortoiseBots side (#1455). skip_if_dead_of_gossip
stays 32768. Validation, plan-parse tests, the arena row pin and the export row
test cover both flags; README and the arena note say which row takes which.
The cut hop is the exporter's own walk. A hop whose cut points would come within
LeaveClearYd (15 yd) of a leg's leave spawn is left uncut, with a warning, so the
run leader hops it itself as it did before --approach-hops: Zul'Farrak's island
Shadowhunter 81610 otherwise stood 9 yd from the cut path to the velratha leg's
pull group 4. README says so.
LegNumber and PlanLeg treated optional and skip_export legs as absent even
when --with-optional or --with-legs exported them, so firstLeaveConflict
checked a cut hop against the wrong plan leg's leave list.

The export now builds one LegMap (plan leg index -> row leg number) from the
legs it writes, by name, with ExportedLegs, and passes it to LegNumber,
PlanLeg and firstLeaveConflict. Rows.LegMap matches a rows set's legs to the
plan by name for the callers that hold rows. The default export is unchanged.
The Bly gossip option lets the export reach Bly and Ukorz, so the count covers
more of the run. Two Sandfury Guardian passes on Ukorz's leg (19.5/21.6 yd,
later rows' own packs) and Ukorz's own 0.1 yd final approach (no row: his boss
row names only Ruuzlu in first, and the loader refuses 7267 there); the
Courtyard via removed two. Fixes the comment that claimed the old baseline saw
the whole run.
@pjerra

pjerra commented Nov 2, 2026

Copy link
Copy Markdown
Owner Author

Combined into #401

@pjerra pjerra closed this Nov 2, 2026
pjerra added a commit that referenced this pull request Nov 2, 2026
Combined 3: hire floors + spot check (#385), Zul'Farrak boss steps (#391), walk-super without eval, boss rows own their boss, pull_size lint (#398)
@pjerra
pjerra deleted the feat/ta243-zf-bosses branch November 5, 2026 21:50
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.

1 participant