Repository navigation
Release V2.03
2026-09-07
-
"Ignore Distant XTargets When Pulling" now defaults ON (
triune.lua).ctrl.ignore_distant_xtargetsdefaults totrueso the shown toggle state matches the new pull-time behavior out of the box; existing saved loadouts with an explicit value keep their stored setting. -
Per-character loadout files (
triune.lua,triune_map.lua). When multiple MQ clients share one MQ install folder, every client wrote to the sametriune_loadout.lua— and since the ignore/pull lists, zone hazards, and zone-waypoint presets live at the top level of that file (under__ignore/__pullList/__zoneHazards/__zoneWaypoints/__zoneWaypointPresets), settings and lists were bleeding between different characters across clients. Triune now writestriune_loadout_<server>_<char>.lua(per-character file), andloadAllprefers that file, re-loading it when the character is first detected in the main loop (migrating from the legacy shared file on first save). The map syncs this character's file first (mq.configDir/triune_loadout_<server>_<char>.lua), then falls back to discovery/legacy names so pre-migration setups keep working; candidates now pair every directory with both the per-character name and the legacy name. On a transient parse failure the map now keeps the previous overlay state instead of blanking the triune overlays for a sync cycle (guards against reading mid-write). -
Search/Pull radius read live from the triune loadout; slider removed (
triune_map.lua,triune.lua). Triune's own control table only containscamp_radius(default 100, the "Camp/Pull Radius"),hunter_radius(default 1500, the "Search Radius" — the one true hunt/pull search range triune uses at lines 13878/19881/19996/20029), andhunter_combat_radius(default 250, the anchor roam radius) — there is nopull_radiusorcombat_radiusfield, so the old map "Search / Pull Radius" slider (seeded from those phantom fields, clamped to 25–600) was driving a circle radius that brave triune never used. The slider is gone; the search/pull/roam circle now renderstd.hunterRadiusstraight fromtriune_loadout.luaand the map defaults now match triune exactly (camp 100, search 1500). The map no longer invents its own radius. On triune's side, the three radius sliders (Camp Radius, Search Radius, Combat Radius, Pull Radius) previously assignedctrl.*without persisting — the circumference setting only hit the loadout file on some unrelated later save. Each slider now callsruntime.saveLoadout(true)on change (plusupdateMapRadiusVisualsfor the native-map visuals), so moving the slider in triune is immediately visible on the custom map at next sync. -
Triune camp / pull / anchor / waypoint map overlays restored & expanded (
triune_map.lua). The map already synced camp, pull/search, and patrol-waypoint overlays fromtriune_loadout.lua(saved bytriune.luainto the MQ config dir) — camp anchor pin + camp radius, waypoint nodes/arrival & scan radii with connecting patrol lines, the pull/search roam circle, and hazard hotspots. This change adds the missing Hunter/Puller combat anchor (hunter_combat_loc+hunter_combat_radius, the "Anchor / Roam Point"):syncTriuneLoadoutnow populatesstate.triuneData.hunterAnchor/hunterCombatRadius, the canvas draws a magenta anchor pin with its max-roam radius circle and label, and the pull/search roam circle now anchors at anchor > camp > player (previously camp > player). New persistent "Show Anchor / Roam Point" toggle in Settings & Layers, and the Triune status line reports anchor set/none plus the resolved loadout path. To make the overlays resilient across install layouts,triune_loadout.luadiscovery now mirrors the multi-path search triune itself uses fortriune_data.lua(mq.configDir, mq.luaDir, script-relativeTAC/config/config, cwd), and the manual "Sync Triune Data" button prints the exact searched locations and a hint to run/lua run triunewhen the file cannot be found. The triune overlays now draw from a dedicateddrawTriuneOverlayshelper invoked underpcall(with a throttled one-per-5s chat error report), so a single malformed overlay datum can never abort the rest of the canvas frame — previously the whole frame after the overlay section (circles and NPC markers) silently vanished whenever anything in that block errored, which read as "circles not maintained while the map updates." The pull/search roam circle disappeared every update becausesyncTriuneLoadoutre-seededctrl.customSearchRadiusfrom the loadout on every 2.5s re-sync (clobbering the slider), while the circle itself was anchored at the camp/anchor — so enlarging the radius via the slider would push the circle's edge into view and the next sync would shrink it back off-screen. The circle is now anchored at the player and always visible around the toon, the slider value is respected for the session (state.searchRadiusTouched) and never re-clobbered by periodic re-syncs, and it no longer issues per-framemq.TLO.Me.X/Y()fetches (it reuses the cached/interpolated player position passed intodrawTriuneOverlays). The manual sync also prints a load summary (loadout path, waypoint/camp/anchor/hazard counts). Note:TAC/config/triune_data.luaholds spell/AA data only; camp/pull/anchor/waypoints live intriune_loadout.luaunder the MQ config dir. Verification:luac -pclean, main chunk 116 locals (limit 200), all 2,092 unit tests pass,luacheck0 warnings / 0 errors. -
Smooth player marker & camera-follow update path (
triune_map.lua). Player X/Y/Z/Heading are now re-read from TLO every main-loop pass (~40ms / ~25Hz) instead of on a 100ms gate, so player motion is decoupled from the slower NPC scan cadence (500ms). The render callback additionally linearly interpolates the player position between cache writes (lastPlayer.prevX/Y/Z+interpAt, seeded on first write so the marker never lerps from the world origin), and the interpolated position feeds the player arrow, auto-follow camera center, nav-line origin, and smart-floor bounds — giving fluid map movement/pan even though NPC markers refresh every 500ms. Target ID still rides its 100ms gate. -
Smooth incremental spawn scanning (
triune_map.lua). The periodicscanZoneSpawns()rebuilt the full NPC list (up to 120NearestSpawnfetches plus up to 16LineOfSightraycasts) in one synchronous main-loop pass, blocking the ImGui draw callback and making the map visibly chop every scan cycle. The scanner is now an incremental state machine (state.scanChunk): the fetch is drained in slices of 12 spawns per frame and the throttled LoS budget in slices of 4 raycasts per frame, with an atomic finalize (filter/sort/group) that swapsfilteredNPCsonly when the cycle completes — so the map keeps rendering the previous valid frame throughout. Init and zone changes passforceCompletefor an immediate full pass since they are one-shot events. -
Fix: Map tool startup lag regression (
triune_map.lua). The previously-added color precompute ranImGui.GetColorU32once per map segment/label at parse time. A typical map file holds tens of thousands of segment records, so this added tens of thousands of Lua→C++ marshal calls to every zone/map load — delaying window display by 30+ seconds (the draw callback is what actually renders, so the window appeared "missing" until parse finished). Color caching is now computed lazily on a segment's first frame and cached, so parse/load runs zero ImGui calls and renders identically. -
Map & NPC Tracker Performance Hardening (
triune_map.lua).- Navmesh batch cost collapse (
processNavBatch, hover tooltip): The throttled background path verifier no longer computes a fullPathLengthfor every NPC in the zone every 6 seconds (two synchronous mq2nav queries per mob, ~100 navmesh calls/sec sustained). It now runsPathExistsonly; the expensive exact path length is resolved on demand for the hovered mob only (throttled to ~1 refresh/sec) and cached so tooltips stay accurate. Cache freshness raised from 6s to 15s (navState.cacheFreshMs). - Path verification limited to the visible/needed set (
scanZoneSpawns): Navmesh checks are now enqueued only for mobs that actually pass the current filters (and skipped entirely for remote ATLAS zones), instead of every scanned NPC up to the 120 cap. Mobs still awaiting their first path check are enqueued before the Pathable-Only gate so that filter can't starve itself.checkQueuecompacts its nil-hole floor. - Spawn scan TLO storm cut (
scanZoneSpawns, tracker tab): Removed the per-mobLineOfSight()raycast from every scan — LoS is now resolved lazily through a throttledlosCache(≤16 raycasts per scan, nearest-first, refreshed on hover) instead of a full raycast per NPC every 300ms. Default scan cadence raised from 300ms to 500ms with a new "Spawn Scan Interval (ms)" slider in Settings & Layers (250–3000ms). Removed six redundant on-keystroke/on-filterscanZoneSpawns()calls in the NPC Tracker filter bar (the periodic scan now recomputes filters). - Per-frame TLO churn removed from render callback (
DrawMapCanvas,DrawTriuneMapUI): Player X/Y/Z/Heading and target ID are refreshed once per ~100ms from the main loop intostate.lastPlayer/state.lastTargetId; the render callback reads the cache (with a one-time pcall fallback) instead of issuing ~10 cross-language marshals every frame.Navigation.Active()reads the scan-populatednavState.navActive. - Big-zone color precompute (
DrawMapCanvas): Segment and label base colors are computed lazily on first render and cached (seg.colBase,lb.colBase90), then reused every frame when the Z-filter alpha is 1.0, eliminating a per-segmentImGui.GetColorU32(float)conversion every frame on large map files (fallback preserved when alpha is non-opaque). Computed at draw time rather than parse time so map/zone loading performs zero ImGui marshal calls and tool startup stays instant even on atlas meshes with tens of thousands of segments. - Cleanups: Removed the unused
spawns.allPCsfield;getConStylereturns a hoisted fallback constant instead of allocating a new table per miss. - Verification:
luac -pclean, main chunk at 103 locals (limit 200), all 2,092 unit tests pass,luacheck0 warnings / 0 errors.
- Navmesh batch cost collapse (
-
Stuck Recovery & Auto-Avoid Stuck Hotspot Hardening (
triune.lua,tests/test_pure_logic.lua).- Hazard Aging & Forgetting (
runtime.decayZoneHazards,runtime.recordStuckHazard): Learned navigation hazards no longer accumulate forever. Each hotspot loses one hit everynav_hazard_decay_minutes(default 10) it goes without a fresh stuck event, deactivates once belownav_hazard_min_hits, and is removed entirely at zero hits. Added anav_hazard_max_hits(default 6) accumulation cap so a bad day can't permanently cripple a zone. Decay runs from the main loop once per minute (runtime.nextHazardDecayAt) and persists changes viasaveLoadout. New "Hazard Forget Time" slider in the Navigation settings UI. - Detour Anti-Oscillation (
runtime.moveToward,runtime.moveTowardLoc): Fixed the root cause of detour re-route loops. In-flight detours are no longer hard-killed on a 6s wall-clock expiry while navigation toward the waypoint is still active — they persist on progress and are only abandoned when waypoint navigation actually concludes without arrival (16s backstop).moveTowardnow stamps the waypoint loc key (instead ofnil) so the delegatedmoveTowardLocstate machine keeps the same detour alive, and a detour with no valid mesh route abandons cleanly to let normal routing proceed.calculateDetourWaypointnow penalizes near-side candidates whose onward segment immediately re-crosses a known hazard, preventing circumferential re-route churn. - Dead State Cleanup (
runtime.checkCombatStall): Removed the never-assignedcombatStallSinceandlastCombatStallRecoveryAtfields and their six= nilwrites fromstuckState/checkCombatStall. - Roam Target Hazard Gate Simplification (
findRoamTarget): Collapsed the shadowedinHaz/isMelee/pathOkchain into a singlepathOk = not (inHaz and isMeleeStyle)guard. - Unit Test Coverage (
Suite 30b): Added deterministic (fake wall-clock) tests for hazard hit capping, timed decay, deactivation below the active threshold, and complete removal at zero hits.
- Hazard Aging & Forgetting (
-
Removal of
/alt buyDispatch & Cap-Protection MQ2AAspend Delegation Fix (triune.lua,tests/test_pure_logic.lua).- All
/alt buycalls removed (runtime.startAATrainWorkflow,runtime.processAATrainWorkflow): Deleted the fast-path dispatch instartAATrainWorkflow, theselect_itemlistbox fallback, and theclick_trainbelt-and-suspenders call./alt buydoes not function on the project's custom server, so it was issuing dead commands and misleading "Issued /alt buy" logs while the real purchase still depended on the window workflow. The notify-based AA Window sequence is now the sole native purchase path; if an ability can't be located in any window list, a warning is logged and the attempt recorded instead of issuing a no-op command. - Cap-threshold delegation no longer skips MQ2AAspend (
runtime.checkAutoSpendAA): The cap-protection branch's fallback condition(now - lastAACapDelegatedAt) >= 3.0was always true on first entry (lastAACapDelegatedAtunset), so it immediately resorted to the native trainer and never issued/aaspend. Addedruntime.lastAACapDelegatedTargettracking (mirroring the prioritized-AAlastAASpendDelegatedTargetpattern) so the first call delegates to MQ2AAspend and the fallback only fires if points are unchanged after 3 seconds. The new state is cleared in thefinishstep alongside the existing delegation cleanup. - Static analysis cleanup (
tests/test_pure_logic.lua): Replaced three non-narrowingassert_true(x ~= nil, ...)guards with Lua's nativeassert(x ~= nil, ...)so the Lua language server no longer reportsneed-check-nilon the subsequent dereferences, and nil failures now abort with the suite label instead of hard-crashing on the following method call.
- All
-
Special Tab Alternate Advancement & Fireworks Auto-Training Fast Path (
triune.lua,tests/test_pure_logic.lua).- Fast-Path
/alt buyCommand Dispatch (runtime.startAATrainWorkflow): When initiating an AA training workflow for any ability with a known ID (such as Alternately Advanced Fireworks with ID 17788), Triune now dispatches/alt buy <id>immediately on the fast path. The window workflow continues in parallel for visual client confirmation and secondary fallback. - Unrestricted
/alt buyFallbacks (runtime.processAATrainWorkflow): Removed the obsoletenot runtime.isSpecialTabAAguards from both theselect_itemlistbox fallback and theclick_trainbutton fallback. Since modern MacroQuest/alt buy <id>works reliably across all AA tabs including Special, Special tab abilities now enjoy full/alt buyfallback redundancy if listbox indexing is delayed. - Static Analysis Cleanup (
triune.lua): Removed unusedcanTrainandminLevellocal assignments inruntime.checkAutoSpendAA, achieving 0 warnings and 0 errors across all 182 files inluacheck TAC/.
- Fast-Path
-
Between-Pulling Alternate Advancement Purchasing (
triune.lua,tests/test_pure_logic.lua).- Between-Pull Auto-Spend Evaluation (
runtime.pullerTick,combatTick): Added hooks inpullerTick(Camp mode,IDLEstate) andcombatTick(Hunt mode,not haveNPC) that check whether any prioritized AA or cap-protection ability is affordable before selecting the next roam target. - Affordability-Guarded Clean Movement Cessation (
runtime.checkAutoSpendAA(allowStop)): Auto-spend strictly checks if an AA can actually be purchased prior to altering movement. If an ability is affordable, Triune smoothly halts movement (stopMoving(),/nav stop,/stick off), initiates the window workflow, and pauses pulling. If no AA can be purchased, pulling proceeds immediately without any pause or stutter. - Pulling Movement Hold During Active Training (
runtime.pendingAATrain): Added guards inpullerTick()andcombatTick()(for both Camp, Hunt, and Assist modes) that hold character position whileruntime.pendingAATrainis active (~0.6s), ensuring client UI interactions complete without movement interruption before immediately resuming pulls. - Motion Grace Period (
runtime.processAATrainWorkflow): Added anallowStopgrace period (0.35s) to the workflow's motion check, ensuring decelerating characters after pulling do not falsely abort the opening sequence. - Unit Test Coverage (
Suite 73): Added comprehensive unit tests intests/test_pure_logic.luacovering between-pull evaluation, motion cessation, in-combat rejection, unaffordable skip logic, and source code assertions.
- Between-Pull Auto-Spend Evaluation (
-
Alternate Advancement Training Restoration & Anti-Stutter Elimination (
triune.lua,tests/test_pure_logic.lua).- Removed
checkAutoSpendAAfrom Active Combat (combatTick): Eliminated auto-spend execution from the combat tick loop. AA spending now runs exclusively during out-of-combat downtime when stationary, completely stopping in-combat window popups and combat stutter. - Restored Proven AA Window Training Flow (
startAATrainWorkflow,processAATrainWorkflow): Restored the clean, direct 5-step AA window sequence (open->wait_open->prepare_tab->select_item->click_train->finish). Removed artificial 5-minute skip timers, speculative verification deadlines, and premature/alt buycalls that interfered with training Fireworks and custom abilities. - Reliable
wait_openStep Advancement: Ensured that the train sequence advances directly toprepare_tabupon window open detection or after attempt retries, preventing premature aborts and guaranteed window clicks across custom UI layouts. - Guarded Inventory Fallback: Strictly verified inventory window state prior to sending fallback button notifications, eliminating red MacroQuest errors (
Window 'InventoryWnd' not available). - Anti-Pause Movement, Navigation & Casting Protection (
checkAutoSpendAA,processAATrainWorkflow): Enforced strict motion gates (not mq.TLO.Me.Moving(),not runtime.isMoveActive(),not mq.TLO.Navigation.Active(), andnot isCasting()) both incheckAutoSpendAAand at the main loop call site. Mid-workflow movement or combat immediately aborts and closes the window cleanly without disrupting character motion. - Endless Retrain Loop Prevention (
runtime.lastAATrainAttempt): Replaced hard lockouts with a lightweight 30-second attempt cooldown that resets automatically whenever unspent AA points change, preventing repeated 2-second window open/close loops on abilities that cannot be trained. - Unit Test Coverage (
Suite 69,Suite 72): Validated that all 2,073 unit tests pass with zero failures and main chunk locals remain at 182 (limit 200).
- Removed
-
Lifetap Spell Healing Logic Isolation & Necromancer Touch of Death Fix (
triune.lua,triune_data.lua,triune_spellbook.lua,tests/test_pure_logic.lua).- Early Detrimental Guard in
runtime.isHealAction: Added an explicitif runtime.isDetrimentalAction(name, targetToken, entry) then return false endguard at the top ofisHealAction, guaranteeing that offensive lifetap and damage abilities are never mistakenly evaluated by the reactive healing priority engine, gem healing prepends, or healing condition filters. - Condition
my HP <=Guard Against Hostile Targets (runtime.conditionMet): Updated themy HP <=threshold evaluator so that enemy mob HP is never evaluated when casting detrimental/offensive spells (E: Current Target,isDetrimentalAction,isHostileTarget). When a lifetap is configured withmy HP <=(e.g. cast defensively when the player drops below 60%), the condition now strictly evaluates the player's own health rather than firing prematurely on low enemy mob HP. - Beneficial Gate in
mapTLOCategoryToKind(triune.lua,triune_spellbook.lua): Added a strictbenerequirement to category/subcategory heal string matching (bene and (catStr:find('heal') ...)), ensuring detrimental spells with descriptive heal or restore substrings are never classified as friendly heals. - Heuristic Lifetap Coverage in
isDetrimentalSpell: Addedlifedraw,lifespike, andsiphon lifeto the offline fallback detrimental name patterns alongsidelifetap. - Database Fix for Necromancer Touch of Death (
triune_data.lua): Corrected level 64 Necromancer lifetap Touch of Death from{"Touch of Death",64,1,"heal"}to{"Touch of Death",64,0,"dd"}in the era spell database. - Unit Test Coverage (
tests/test_pure_logic.lua): Added test assertions verifying lifetap rejection fromisHealAction,Touch of Deathdirect damage classification intriune_data.lua, andmy HP <=player-only evaluation on enemy targets.
- Early Detrimental Guard in
-
Custom Server AA Compatibility & Removal of Speculative Static Pre-Checks (
triune.lua,tests/test_pure_logic.lua).- Eliminated Speculative Pre-Checks (
runtime.checkAutoSpendAA): Removed the staticga.CanTrain()andMinLevelpre-check that previously caused custom/special server abilities (such as Bestial Frenzy) to be falsely marked withUnmet Reqand placed on a 5-minute skip. On custom servers that alter level requirements, prerequisite trees, or class access, eligibility is now determined strictly through live client interactions and server purchase verification rather than static client database tables. - Unconditional User Priority Authorization (
runtime.isAAAllowedForPlayer): Added explicit bypasses inisAAAllowedForPlayerso that any ability checked by the user inctrl.auto_aa_prioritiesor discovered with an in-game ID is unconditionally permitted, guaranteeing that custom server abilities are never rejected or pruned from the loadout.
- Eliminated Speculative Pre-Checks (
-
Alternate Advancement In-Game Description Tooltips & Text Wrapping (
triune.lua,tests/test_pure_logic.lua).- AA Description Extraction & Caching (
runtime.getAADescription,runtime.recordScannedAA): Integrated in-game ability descriptions from MacroQuest'smq.TLO.Me.AltAbility(name).Description()andmq.TLO.AltAbility(name).Description()(with spell fallback for activated AAs). Descriptions are cached both in memory on the ability entry and persisted inruntime.cachedAADataacross sessions. - Clean Word-Boundary Text Wrapping (
runtime.wrapText): Implemented a formatting helper that formats long descriptions across multiple lines at word boundaries (~55 characters) while preserving existing paragraphs, preventing tooltips from spanning excessively wide across the screen. - Hover Tooltips in Auto AA Table (
runtime.showAATooltip,UI.drawAutoAATab): Hovering over an ability name or rank in the Auto AA browser displays a comprehensive tooltip showing the ability name, current rank, maximum rank, next rank cost, points spent, followed by the full wrapped description. Implemented using percent-safe string formatting (ImGui.SetTooltip('%s', ...)). - Automated Regression Suite (
Suite 71): Added unit tests intests/test_pure_logic.luacovering text wrapping, lazy description extraction and caching, percent format string safety, and UI source code inspection.
- AA Description Extraction & Caching (
-
Player-Specific AA Filtering & Cross-Class Ability Rejection (
triune.lua,tests/test_pure_logic.lua).- Class & Archetype Ability Maps (
runtime.CLASS_ARCHETYPES,runtime.ARCHETYPE_CLASSES,runtime.ARCHETYPE_RESTRICTIONS,runtime.CLASS_SPECIFIC_ABILITIES,runtime.buildAAClassRestrictions): Mapped all 16 EverQuest classes and archetypes to their class-specific and archetype-specific Alternate Advancement abilities. - Player Ability Validator (
runtime.isAAAllowedForPlayer): Implemented strict validation ensuring that characters only see and auto-train AAs belonging to their own classes (myClasses), their archetype (Melee, Priest, Caster, Pet), universal General AAs, or Special tab abilities. Rejects cross-class abilities (e.g. Warriors seeingHeadshot,Mana Burn,Harm Touch,Divine Arbitration, or Clerics seeingTaunt,Area Taunt,Ambidexterity). - Permissive Ownership & In-Game UI Bypasses: Grants immediate access if the character has already trained rank > 0 or if the ability was scanned directly from the character's live in-game
AAWindowlistbox. - Cross-Class AA Cache Pruning (
runtime.scanPlayerAAs): Updated Step 1.5 in the AA scanner to automatically prune any stale or cross-class abilities fromruntime.cachedAAData, immediately cleaning up characters whose caches were populated by earlier scans. - Automated Regression Suite (
Suite 70): Added comprehensive unit tests intests/test_pure_logic.luavalidating player-specific AA filtering, cross-class rejection for Warrior and Cleric profiles, ownership bypasses, and cache pruning.
- Class & Archetype Ability Maps (
-
Alternate Advancement Purchase Verification & Unpurchasable Ability Anti-Stall (
triune.lua,tests/test_pure_logic.lua).- Purchase Outcome Verification (
runtime.processAATrainWorkflow): Added initial point and rank tracking (task.initialPoints,task.initialRank) when initiating an AA training workflow. After clicking the Train button (or issuing fallback/alt buy), the workflow transitions to a newverifystep that checks whether unspent AA points decreased (currentPts < initialPts) or ability rank increased (currentRank > initialRank). - Unpurchasable Ability Skip & Cooldown (
runtime.aaSkipUntil): If an AA purchase cannot be completed (e.g.AAW_TrainButtondisabled in UI, level requirement not met, missing prerequisites, or server rejected purchase), Triune records the failure and temporarily skips that ability for 5 minutes (runtime.aaSkipUntil[name] = now + 300). This ensures Auto AA never stalls or loops indefinitely on an unpurchasable ability and seamlessly advances to the next prioritized candidate. - UI Train Button Disabled State Detection: In
click_train, Triune now checksbtn.Enabled()on the client'sAAW_TrainButton. If EverQuest has disabled the train button, Triune avoids unnecessary clicks, notes the unmet requirement, and flags the ability for skip cooldown. - Level-Up & Manual Spend Skip Reset (
runtime.checkAutoSpendAA,runtime.manualSpendAA): Whenever the character levels up (mq.TLO.Me.Level()change), all temporary AA skips are automatically cleared so newly unlocked abilities can be purchased immediately. In addition, manualTrain##btnorSpend Nowbutton clicks immediately clear skips for the selected ability. - UI Unmet Requirements Status Indicator (
UI.drawAutoAATab): In the Auto AA table, abilities currently under temporary skip cooldown display a yellowUnmet Reqstatus with a descriptive hover tooltip explaining that the ability is being skipped due to level/prerequisite requirements. - Automated Regression Suite (
Suite 69): Added comprehensive unit tests intests/test_pure_logic.luavalidating purchase verification, skip timeout placement, advancement to subsequent priority candidates, level-up reset handling, manual spend overrides, and static pre-checks.
- Purchase Outcome Verification (
-
Alternate Advancement Auto-Spend MQ2AAspend Fallback & UI Delegation Toggle (
triune.lua,tests/test_pure_logic.lua).- Automated Native Window Training Fallback (
runtime.checkAutoSpendAA): Resolved an issue where auto-spending stalled when delegating toMQ2AAspendon progression/emulated servers where/alt buyoreqlib::AltAdvManager::CanTrainAbilitychecks fail. If Triune delegates an AA purchase toMQ2AAspendand the ability remains unpurchased with unspent points unchanged after >= 2.5s, Triune automatically falls back to its built-in native window trainer (runtime.startAATrainWorkflow) to train the prioritized ability using in-game window UI clicks. - Cap Dump Protection Fallback (
runtime.checkAutoSpendAA): Extended the fallback mechanism to cap dump protection (e.g. Fireworks or designated cap dumps) ifMQ2AAspendfails to spend points when at or above the threshold. - Direct Spend Now Prioritized Fallback (
runtime.manualSpendAA): UpdatedSpend Nowbutton handling so that clickingSpend Nowwith prioritized abilities immediately purchases the top affordable prioritized ability (or falls back to native training ifMQ2AAspendpreviously stalled). - Interactive UI Delegation Toggle (
UI.drawAutoAATab): Converted the staticMQ2AAspendindicator into an interactive checkbox (MQ2AAspend##aaDelegateMaster) in the AA Progression header toolbar. Users can now directly toggle between delegating toMQ2AAspendor using Triune's native window trainer without needing slash commands. - Automated Regression Suite (
Suite 64): Enhanced unit tests intests/test_pure_logic.luacovering stalledMQ2AAspenddelegation detection, native fallback triggers, direct native spending with delegation disabled, and UI toggle token verification.
- Automated Native Window Training Fallback (
-
Native Alternate Advancement Window Trainer & Window Control Overhaul (
triune.lua,tests/test_pure_logic.lua).- Window Object Call & Boolean Bugfix (
runtime.getAAWindow,runtime.openAAWindow,runtime.closeAAWindow): Resolved a critical issue where Triune loggedInitiating AA Window train sequence...but never actually opened the in-game Alternate Advancement window. In MacroQuest Lua, calling a Window TLO as a function (w()) invokesToString(), which returns booleanfalsewhen the window is closed. Previously, statements likeif w and w() and w.DoOpen then w.DoOpen() endevaluated tofalsewhenever the window was closed, preventingDoOpen()andDoClose()from ever firing. Created clean dedicated window helpers (runtime.getAAWindow,runtime.getAAWindowName,runtime.isAAWindowOpen,runtime.openAAWindow, andruntime.closeAAWindow) that query.Open()and invoke.DoOpen()without testingw(). - Native EQ Command Keypress (
TOGGLE_ALTADVWIN): Replaced non-functional/keypress Vwith EverQuest's native internal command/keypress TOGGLE_ALTADVWINand standard key combos (/keypress v alt,/keypress a alt), as well as/notify InventoryWindow IW_AltAdvBtn leftmouseup(andInventoryWnd), ensuring the AA window opens reliably across client configurations, UI skins, and keybind layouts. - Window Name Resolution (
AAWindow&AAWnd): Supported bothAAWindowand custom UI aliasAAWndacross all notifications, list queries, and window operations. - Recursive Child Window Iteration Bugfix (
runtime.findChildRecursive): Resolved an issue wherefindChildRecursiveprematurely terminated child traversal when encountering an inactive or closed tab page (while curr and curr()). Changed loop check towhile curr and safety < 120, allowing seamless navigation across inactive tab pages and deeper UI hierarchies to find listboxes and buttons. - Safe Workflow Abort on Failed Open (
runtime.processAATrainWorkflow): Replaced premature step advancement with a clean retry threshold (up to 4 attempts) that outputs a clear warning and terminates safely if the client window fails to open, rather than executing phantom list clicks or issuing rejected/alt buy 0commands. - Eliminated Toggle Collisions & Red
InventoryWndNotifications (runtime.openAAWindow): Fixed an issue where all opening methods were fired simultaneously in a single function call. While non-toggling/windowstate AAWindow opensuccessfully opened the window, immediate subsequent keypresses (TOGGLE_ALTADVWIN,v alt,a alt) acted as toggles that immediately shut the window back down, while blind/notify InventoryWnd IW_AltAdvBtncommands triggered red MacroQuest errors (Window 'InventoryWnd' not available). RefactoredopenAAWindow(attempt)to staged attempts: Attempt 1 executes non-toggling/windowstate %s openandDoOpen(), subsequent retry attempts issue fallback toggle keypresses only if needed, and inventory button notifications are strictly guarded to only fire when the player's inventory window is actually open. - Direct Open State Detection (
runtime.isAAWindowOpen): UpdatedisAAWindowOpen()to checkmq.TLO.Window('AAWindow').Open()and'AAWnd'directly, eliminating false-negative window state evaluations.
- Window Object Call & Boolean Bugfix (
-
Comprehensive Auto AA Discovery & Unpurchased Ability Retention (
triune.lua,tests/test_pure_logic.lua).- Removed
isAAWindowOpen()Scan Gate: Discovered thatscanPlayerAAs()previously wrapped listbox reading (AAW_GeneralList,AAW_ArchList,AAW_ClassList,AAW_SpecialList) insideif runtime.isAAWindowOpen() then. Because players normally play with the in-game AA window closed, Step 1 was skipped 100% of the time during routine gameplay. Removed this gate and thechild()boolean check, reading listbox children loaded in EQ memory directly. - Removed Non-UI
id <= 0Rejection inrecordScannedAA: On EverQuest emulated/progression servers,mq.TLO.Me.AltAbility(name)returnsnilfor unpurchased (Rank 0) abilities, and unowned passive abilities return ID 0. Previously,if not isFromUI and id <= 0 then return enddropped all unpurchased AAs scanned from catalogs or config when the window was closed. Removed this check while continuing to strictly reject character skills (Mend,Flying Kick,Backstab) viamq.TLO.Skill(name). - Reinstated Norrath AA Catalog (
NORRATH_AAS): Added a curated reference catalog of General, Archetype, and Class AAs (includingCombat Agility,Combat Stability,Physical Enhancement,Fury of Magic,Twinproc,Extended Ingenuity,Fearless,Bloodlust,Gelid Rending,Run Speed, etc.) to ensure that all core progression abilities are immediately listed and prioritizeable even prior to first purchase or before the client UI listboxes populate. - Step 1.5 Cache Pruning Bugfix: Updated cached AA verification so that abilities with
id == 0andmaxRank == 0are not purged fromruntime.cachedAADataunless they are detected as true character skills.
- Removed
-
Out-of-Combat AA Spending Enforcement & Deep UI Hierarchy Traversal Fix (
triune.lua,tests/test_pure_logic.lua).- Strict Out-of-Combat Spending Gate (
runtime.checkAutoSpendAA): Enforced a strict out-of-combat gate across all automatic Alternate Advancement spending (mq.TLO.Me.Combat(),mq.TLO.Me.CombatState() == 'COMBAT',AutoFire(),anyXtarAlive(),XTHaterCount() > 0). Triune will now never trigger AA window workflows or point purchases during combat encounters, completely eliminating pauses, stalls, and player interruptions while fighting. - Mid-Train Combat Abort Handler (
runtime.processAATrainWorkflow): Added an immediate aggro and combat check insideprocessAATrainWorkflow. If combat initiates while an AA train sequence is active, Triune immediately closes the AA window and aborts the workflow cleanly to prioritize combat. - Deep UI Hierarchy Traversal Bugfix (
runtime.findChildRecursive): Resolved an issue wherefindChildRecursivefailed to search nested tab pages and subwindows. Previously, recursion was gated behindcurr.Children and (curr.Children() == true). Because MacroQuest TLO booleans return DataType objects or string"TRUE","TRUE" == trueevaluated tofalsein Lua, preventing the traversal from descending down into child tab boxes, subwindows, and pages (AAWindow -> AAW_Subwindows -> AAW_GeneralPage -> AAW_GeneralList). Refactored to inspectcurr.FirstChilddirectly, enabling full recursive discovery of all listboxes and buttons. - Enhanced AA Row Selection & Train Button Execution (
runtime.findAAInWindowLists,runtime.processAATrainWorkflow): Added direct text matching viachild.List('=' .. name)before falling back to row iteration, with safe extraction across string, userdata, and function types. Pre-selected initial tab pages using known AA categories (General,Archetype,Class,Special), added a 0.2s tab activation delay upon switching tabs, and updated button clicks to fire bothLeftMouseDownandLeftMouseUpevents and notifications so the client engine registers the purchase. - Automated Regression Suite (
Suite 68): Added unit tests covering in-combat AA spending prevention, 3-level deep nested UI tree navigation, and code token verification.
- Strict Out-of-Combat Spending Gate (
📦 Installation & Updating Instructions
🆕 New Installation
- Go here and grab the latest macroquest release https://github.com/macroquest/macroquest/releases and extract under your user folder.
- Download TriuneAutocombat-full.zip below and extract contents of TAC into the root of your macroquest folder.
- If running windows add an exception to your MQ folder before running.
- Start
MacroQuest.exebefore launching EverQuest.
- **Existing install
- Download
TriuneAutocombat-Update.zipfrom the Assets below. - Extract the TAC folder to the root of your macroquest folder.
- Note: Your personal settings and saved loadouts in
triune_loadout.luaare preserved and will never be overwritten.
- Download