### Lua Function Documentation Example Source: https://github.com/wealdly/justac/blob/main/Documentation/STYLE_GUIDE_JUSTAC.md Shows how to document a public Lua function, including its purpose, parameters with types and descriptions, and return values. ```lua -- SHOULD: Document public API -- Gets the current spell queue with filters applied -- @param ignoreBlacklist bool - Skip blacklist filtering -- @return table - Array of spell IDs function SpellQueue.GetCurrentSpellQueue(ignoreBlacklist) ``` -------------------------------- ### Filter Assistant Button Actions (Lua) Source: https://github.com/wealdly/justac/blob/main/Documentation/STYLE_GUIDE_JUSTAC.md Explains how to correctly process assistant buttons by first filtering them out before attempting to get action information. Shows a 'BAD' example of directly getting hotkeys and a 'GOOD' example that checks for and skips assistant combat actions. ```lua -- BAD: Tries to get hotkey for dynamic button ❌ local actionType, id = GetActionInfo(slot) if actionType == "spell" then return GetHotkeyForSpell(id) end -- GOOD: Filter assistant button first ✓ local actionType, id = GetActionInfo(slot) if actionType == "spell" and type(id) == "string" and id == "assistedcombat" then return nil -- Skip end if C_ActionBar.IsAssistedCombatAction(slot) then return nil -- Double-check end ``` -------------------------------- ### Lua Cache Key Composition Example Source: https://github.com/wealdly/justac/blob/main/Documentation/STYLE_GUIDE_JUSTAC.md Demonstrates best practices for composing cache keys in Lua by including all state dependencies. It highlights a common pitfall of missing dependencies, which can lead to incorrect cache hits. ```lua -- SHOULD: Include all state dependencies local cacheKey = slot .. "_" .. spellID .. "_" .. currentForm .. "_" .. currentSpec -- BAD: Missing state dependency ❌ local cacheKey = slot .. "_" .. spellID -- Breaks on form/spec change ``` -------------------------------- ### Lua Comment Examples Source: https://github.com/wealdly/justac/blob/main/Documentation/STYLE_GUIDE_JUSTAC.md Illustrates good and bad practices for commenting Lua code, including explaining the 'why', documenting workarounds, clarifying complex state tracking, and avoiding comments for obvious code. ```lua -- GOOD: Explains WHY -- Cache to avoid repeated API calls during combat local playerName = UnitName("player") -- GOOD: Documents workaround -- GetShapeshiftFormID() returns nil in caster form, treat as 0 local formID = GetShapeshiftFormID() or 0 -- GOOD: Complex state tracking -- Hash includes page, bonusOffset, form, and special bar flags -- This invalidates when ANY of these change local hash = page + (bonusOffset * 100) + (formID * 10000) -- BAD: Obvious ❌ local playerName = UnitName("player") -- Get player name ``` -------------------------------- ### Avoid Function Creation in Loops (Lua) Source: https://github.com/wealdly/justac/blob/main/Documentation/STYLE_GUIDE_JUSTAC.md Illustrates the performance pitfall of creating function closures within loops. Shows a 'BAD' example creating 100 closures and a 'GOOD' example by defining the function outside the loop. ```lua -- BAD ❌ for i = 1, 100 do C_Timer.After(i, function() print(i) end) -- Creates 100 closures end -- GOOD local function printNumber(n) print(n) end for i = 1, 100 do C_Timer.After(i, function() printNumber(i) end) end ``` -------------------------------- ### Avoid Deep Nesting with Early Returns (Lua) Source: https://github.com/wealdly/justac/blob/main/Documentation/STYLE_GUIDE_JUSTAC.md Demonstrates how to refactor deeply nested conditional logic in Lua using early return statements. Provides a 'BAD' example with four levels of nesting and a 'GOOD' example that simplifies the logic. ```lua -- BAD: 4+ levels of nesting ❌ function process(data) if data then if data.spellID then if data.spellID > 0 then if IsSpellKnown(data.spellID) then return true end end end end return false end -- GOOD: Early returns ✓ function process(data) if not data then return false end if not data.spellID then return false end if data.spellID <= 0 then return false end if not IsSpellKnown(data.spellID) then return false end return true end ``` -------------------------------- ### Lua: Module Registration with LibStub Source: https://github.com/wealdly/justac/blob/main/Documentation/STYLE_GUIDE_JUSTAC.md Demonstrates the correct way to register a Lua module using LibStub, ensuring proper library initialization and preventing errors if the library is not found. ```lua -- Module registration ❌ local MyModule = {} ✓ local MyModule = LibStub:NewLibrary("JustAC-MyModule", 1) if not MyModule then return end ``` -------------------------------- ### Verification Commands in Lua Source: https://github.com/wealdly/justac/blob/main/Documentation/STYLE_GUIDE_JUSTAC.md Lists example debug commands that can be added to an addon for diagnosing complex systems. These commands allow users or developers to inspect various aspects of the addon's functionality, such as API diagnostics, module health, and spell data. ```lua -- SHOULD: Add debug commands for complex systems -- /jac test -- Full API diagnostics -- /jac modules -- Module health check -- /jac formcheck -- Form detection debug -- /jac raw -- Show raw spell queue -- /jac find -- Locate spell on bars ``` -------------------------------- ### Lua: Safe API Calls with pcall Source: https://github.com/wealdly/justac/blob/main/Documentation/STYLE_GUIDE_JUSTAC.md Demonstrates how to use the `pcall` function in Lua to safely execute API calls that might fail, returning success status and the result. ```lua -- API safety ❌ local spell = C_AssistedCombat.GetNextCastSpell(true) ✓ local success, spell = pcall(C_AssistedCombat.GetNextCastSpell, true) if not success or not spell then return nil end ``` -------------------------------- ### AssistedCombatManager Public API Examples Source: https://github.com/wealdly/justac/blob/main/Documentation/ASSISTED_COMBAT_API_DEEP_DIVE.md Provides examples of how to use the public API of Blizzard's `AssistedCombatManager` from within JustAC, showcasing functions for checking spell status, retrieving descriptions, and managing highlights. ```lua -- Check if action spell exists AssistedCombatManager:HasActionSpell() -- → bool -- Get current action spell ID (same as C_AssistedCombat.GetActionSpell()) AssistedCombatManager:GetActionSpellID() -- → spellID or nil -- Get spell description string (loaded async on action spell change) AssistedCombatManager:GetActionSpellDescription() -- → string or nil -- Fast set-lookup: is spellID part of the rotation? AssistedCombatManager:IsRotationSpell(spellID) -- → bool (O(1), backed by hash) -- Is the assistedCombatHighlight CVar enabled? AssistedCombatManager:IsAssistedHighlightActive() -- → bool -- Current update rate in seconds (from assistedCombatIconUpdateRate CVar) AssistedCombatManager:GetUpdateRate() -- → number (0-1) -- Is this button currently highlighted as recommended? AssistedCombatManager:IsRecommendedAssistedHighlightButton(actionButton) -- → bool -- Spellbook integration AssistedCombatManager:ShouldHighlightSpellbookSpell(spellID) -- → bool AssistedCombatManager:IsHighlightableSpellbookSpell(spellID) -- → bool ``` -------------------------------- ### Lua: Handling Missing Module Dependencies with LibStub Source: https://github.com/wealdly/justac/blob/main/Documentation/STYLE_GUIDE_JUSTAC.md Shows how to safely retrieve module dependencies using LibStub, allowing for nil returns if a dependency is missing, rather than causing an error. ```lua -- Module dependencies ❌ local Other = LibStub("JustAC-Other") -- Errors if missing ✓ local Other = LibStub("JustAC-Other", true) -- Returns nil if missing ``` -------------------------------- ### Lua Function Naming Conventions Source: https://github.com/wealdly/justac/blob/main/Documentation/STYLE_GUIDE_JUSTAC.md Explains the naming conventions for Lua functions, advocating for lowercase starts for private functions, PascalCase for public module API functions, and descriptive verb-based names. ```lua -- SHOULD: Lowercase start for private functions local function updateFormCache() local function validateSpell(spellID) local function getQueueThrottleInterval() -- SHOULD: Module public API - PascalCase function SpellQueue.GetCurrentSpellQueue() function ActionBarScanner.GetSpellHotkey(spellID) function BlizzardAPI.GetNextCastSpell() -- SHOULD: Verb-based descriptive names ✓ getCachedSpellInfo() ✓ invalidateCache() ✓ isSpellBlacklisted() ✓ updateCachedState() ❌ spell() ❌ cache() ❌ blacklist() ❌ state() ``` -------------------------------- ### Module Registration Pattern (Lua) Source: https://github.com/wealdly/justac/blob/main/Documentation/STYLE_GUIDE_JUSTAC.md Demonstrates the mandatory LibStub module registration pattern for creating new libraries in Lua. It ensures proper module initialization and versioning. ```lua -- MUST: Use at top of every module file local ModuleName = LibStub:NewLibrary("JustAC-ModuleName", VERSION_NUMBER) if not ModuleName then return end -- Example from SpellQueue.lua local SpellQueue = LibStub:NewLibrary("JustAC-SpellQueue", 34) if not SpellQueue then return end ``` -------------------------------- ### Get Addon Reference Safely (Lua) Source: https://github.com/wealdly/justac/blob/main/Documentation/STYLE_GUIDE_JUSTAC.md Safely retrieves an addon reference using LibStub. Includes a helper function to get the addon's profile database. Returns nil if the addon or its database is not found. ```lua -- SHOULD: Get addon reference safely local function getAddonReference() local addon = LibStub("AceAddon-3.0"):GetAddon("JustAssistedCombat", true) if not addon then return nil end return addon end local function getProfile() local addon = getAddonReference() if not addon or not addon.db then return nil end return addon.db.profile end ``` -------------------------------- ### Cache Expensive Operations (Lua) Source: https://github.com/wealdly/justac/blob/main/Documentation/STYLE_GUIDE_JUSTAC.md Demonstrates caching expensive WoW API calls like GetMacroInfo, GetBindingKey, and GetShapeshiftFormInfo to improve performance. Provides a 'GOOD' example of a cached binding function and a 'BAD' example of calling GetBindingKey directly in a loop. ```lua -- MUST: Cache GetMacroInfo, GetBindingKey, GetShapeshiftFormInfo -- These are expensive and called frequently -- GOOD local bindingCache = {} function getCachedBinding(key) if not bindingCache[key] then bindingCache[key] = GetBindingKey(key) or "" end return bindingCache[key] end -- BAD ❌ function getBinding(key) return GetBindingKey(key) -- Called every frame! end ``` -------------------------------- ### Lua Comment Style Guide Source: https://github.com/wealdly/justac/blob/main/Documentation/STYLE_GUIDE_JUSTAC.md Demonstrates the correct style for Lua comments, emphasizing the mandatory space after the '--' characters. Incorrectly formatted comments are highlighted. ```lua -- MUST: Space after -- -- Good comment --Bad comment (no space) ``` -------------------------------- ### Lua: Safe Nil Checking for API Calls Source: https://github.com/wealdly/justac/blob/main/Documentation/STYLE_GUIDE_JUSTAC.md Illustrates a robust method for checking nil values before calling Blizzard API functions, preventing runtime errors. ```lua -- Nil checking ❌ if BlizzardAPI.GetSpell() then ✓ if BlizzardAPI and BlizzardAPI.GetSpell and BlizzardAPI.GetSpell() then ``` -------------------------------- ### Lua: Implementing Caching for API Data Source: https://github.com/wealdly/justac/blob/main/Documentation/STYLE_GUIDE_JUSTAC.md Shows a basic caching mechanism in Lua to avoid repeatedly fetching data from an API within a frame, improving performance. ```lua -- Caching ❌ function update() local spells = C_AssistedCombat.GetRotationSpells() -- Every frame! ✓ local cachedSpells = {} local spellsValid = false function update() if not spellsValid then cachedSpells = C_AssistedCombat.GetRotationSpells() spellsValid = true end ``` -------------------------------- ### Module Dependency Check (Lua) Source: https://github.com/wealdly/justac/blob/main/Documentation/STYLE_GUIDE_JUSTAC.md Illustrates the mandatory pattern for checking module availability using LibStub with the 'true' parameter for safe retrieval. It includes validation to ensure modules and their functions exist before use. ```lua -- MUST: Always check for nil with true parameter local BlizzardAPI = LibStub("JustAC-BlizzardAPI", true) local FormCache = LibStub("JustAC-FormCache", true) -- MUST: Validate before use if not BlizzardAPI then return end if not FormCache or not FormCache.GetActiveForm then return end -- GOOD: Full safety pattern local function getActiveForm() local FormCache = LibStub("JustAC-FormCache", true) if not FormCache or not FormCache.GetActiveForm then return 0 end return FormCache.GetActiveForm() end ``` -------------------------------- ### Lua: Simplifying Nested Conditionals Source: https://github.com/wealdly/justac/blob/main/Documentation/STYLE_GUIDE_JUSTAC.md Presents a pattern for refactoring deeply nested if statements into a series of early return checks, improving readability. ```lua -- Nesting ❌ if a then if b then if c then ✓ if not a then return end if not b then return end if not c then return end ``` -------------------------------- ### Assisted Combat Highlight System Control (Lua Example) Source: https://github.com/wealdly/justac/blob/main/Documentation/ASSISTED_COMBAT_API_DEEP_DIVE.md Shows how the AssistedCombatManager controls the visual highlighting feature based on CVar settings. It manages the `useAssistedHighlight` flag and the `updateRate` for icon updates. ```lua useAssistedHighlight = false -- From assistedCombatHighlight CVar updateRate = 0 -- From assistedCombatIconUpdateRate CVar (0-1) ``` -------------------------------- ### Lua: Identifying 'Assisted Combat' Action Buttons Source: https://github.com/wealdly/justac/blob/main/Documentation/STYLE_GUIDE_JUSTAC.md Provides a Lua snippet to correctly identify action buttons associated with 'assisted combat', distinguishing them from spell actions. ```lua -- Assistant button ❌ local type, id = GetActionInfo(slot) -- id might be "assistedcombat" string! ✓ local type, id = GetActionInfo(slot) if type == "spell" and type(id) == "string" and id == "assistedcombat" then return nil end ``` -------------------------------- ### Lua Comment Purpose Guidelines Source: https://github.com/wealdly/justac/blob/main/Documentation/STYLE_GUIDE_JUSTAC.md Provides guidelines on what should and should not be commented in Lua code. Focuses on commenting the 'why' and complex logic, while avoiding obvious statements or syntax explanations. ```lua SHOULD: Comment WHY, not WHAT SHOULD: Comment complex logic MUST: Comment WoW API workarounds MUST NOT: Comment obvious code MUST NOT: Comment Lua syntax ``` -------------------------------- ### Standard Lua Module Structure Source: https://github.com/wealdly/justac/blob/main/Documentation/STYLE_GUIDE_JUSTAC.md Presents the conventional structure for a Lua module file, including LibStub registration, dependency loading, local variable/cache declaration, private helper functions, and public API functions. ```lua -- Standard module file structure: -- 1. LibStub registration local ModuleName = LibStub:NewLibrary("JustAC-ModuleName", VERSION) if not ModuleName then return end -- 2. Module dependencies local BlizzardAPI = LibStub("JustAC-BlizzardAPI", true) -- 3. File-local variables and caches local cache = {} local lastUpdate = 0 -- 4. Private helper functions local function privateHelper() end -- 5. Public API functions function ModuleName.PublicFunction() end -- 6. Optional: return module return ModuleName ``` -------------------------------- ### Conditional Constants Based on WoW Version Source: https://github.com/wealdly/justac/blob/main/Documentation/VERSION_CONDITIONALS.md Illustrates how to define constants that change their values between WoW versions. This example sets the SPELL_FLAGS.HARMFUL and SPELL_FLAGS.HELPFUL constants based on whether the client is running Midnight or later. ```lua local SPELL_FLAGS = {} if BlizzardAPI.IsMidnightOrLater() then SPELL_FLAGS.HARMFUL = 0x00008000 -- 12.0 value SPELL_FLAGS.HELPFUL = 0x00004000 else SPELL_FLAGS.HARMFUL = 0x00010000 -- Pre-12.0 value SPELL_FLAGS.HELPFUL = 0x00008000 end ``` -------------------------------- ### JustAC Main Module: Addon Initialization and Configuration Source: https://context7.com/wealdly/justac/llms.txt This snippet demonstrates how to initialize the JustAC addon using Ace3, access profile settings like max icons and debug mode, and manage spell blacklisting and hotkey overrides. It also shows how to force queue updates and invalidate various caches. ```lua -- Initialize the addon (called automatically by Ace3) local JustAC = LibStub("AceAddon-3.0"):GetAddon("JustAssistedCombat") -- Access addon profile settings local profile = JustAC:GetProfile() print("Max icons:", profile.maxIcons) -- Number of spell icons to display print("Icon size:", profile.iconSize) -- Icon size in pixels print("Debug mode:", profile.debugMode) -- Whether debug output is enabled -- Check if a spell is blacklisted (won't appear in queue) local isBlacklisted = JustAC:IsSpellBlacklisted(12345) -- Toggle blacklist status for a spell (Shift+Right-click on icon) JustAC:ToggleSpellBlacklist(12345) -- Set a custom hotkey override for a spell JustAC:SetHotkeyOverride(12345, "F1") -- Display "F1" instead of detected keybind -- Get custom hotkey override local override = JustAC:GetHotkeyOverride(12345) -- Force immediate queue update (bypasses throttling) JustAC:ForceUpdate() -- Update spell queue only JustAC:ForceUpdateAll() -- Update spell queue + defensives -- Invalidate caches (call after keybind or spell changes) JustAC:InvalidateCaches({spells = true}) -- Clear spell info cache JustAC:InvalidateCaches({macros = true}) -- Clear macro parsing cache JustAC:InvalidateCaches({hotkeys = true}) -- Clear keybind lookup cache JustAC:InvalidateCaches({forms = true}) -- Clear form/shapeshift cache JustAC:InvalidateCaches({auras = true}) -- Clear aura/buff cache JustAC:InvalidateCaches({all = true}) -- Clear everything ``` -------------------------------- ### Avoid Calling GetRotationSpells Every Frame (Lua) Source: https://github.com/wealdly/justac/blob/main/Documentation/STYLE_GUIDE_JUSTAC.md Addresses the anti-pattern of calling `C_AssistedCombat.GetRotationSpells()` frequently. Provides a 'GOOD' example of caching the rotation spells and invalidating the cache only when necessary (e.g., on `SPELLS_CHANGED`). ```lua -- BAD: Called 30 times per second in combat! ❌ function OnUpdate() local spells = C_AssistedCombat.GetRotationSpells() DisplaySpells(spells) end -- GOOD: Cache and invalidate on SPELLS_CHANGED ✓ local cachedRotation = {} local rotationValid = false function OnSpellsChanged() rotationValid = false end function GetRotation() if not rotationValid then cachedRotation = C_AssistedCombat.GetRotationSpells() rotationValid = true end return cachedRotation end ``` -------------------------------- ### Testing WoW Version Compatibility Commands Source: https://github.com/wealdly/justac/blob/main/Documentation/VERSION_CONDITIONALS.md Provides example console commands for testing version detection and module loading within the WoW client. These commands help verify that the JustAC-BlizzardAPI is correctly identifying the client version and that modules are loading as expected. ```lua -- Test in 11.2.7 (current retail): /jac test /jac modules -- Test in 12.0 (beta): /jac test /jac modules -- Verify version detection: /dump BlizzardAPI.GetInterfaceVersion() -- Should show 110207 or 120000 /dump BlizzardAPI.IsMidnightOrLater() -- Should show false or true ``` -------------------------------- ### WoW Macro Example and Parsing Questions (Lua) Source: https://github.com/wealdly/justac/blob/main/Documentation/MACRO_PARSING_DEEP_DIVE.md Illustrates a typical World of Warcraft macro and poses the key questions that the MacroParser module must answer to correctly interpret and apply the macro's logic under various in-game conditions. ```lua -- Macro example: #showtooltip /cast [mod:shift,form:1] Maul; [form:1] Swipe; Wrath -- Questions MacroParser must answer: -- 1. Does this macro cast Maul? (depends on form AND modifier state) -- 2. What hotkey should display for Maul? (base key or "Shift+key") -- 3. Should this macro "win" if Maul appears in other macros too? ``` -------------------------------- ### SUF Interruptible Overlay Setup (Lua) Source: https://github.com/wealdly/justac/blob/main/Documentation/CASTBAR_SECRET_VALUE_RESEARCH.md This Lua code snippet from SUF demonstrates setting up an overlay StatusBar to indicate uninterruptible casts. It uses UnitCastingDuration to get the duration object and then configures the overlay's timer. SetAlphaFromBoolean is used to control the visibility of this overlay based on the 'notInterruptible' state. ```lua -- During cast start, after setting up main bar: if hasSecretTimes then local durationObj = UnitCastingDuration(unit) overlay:SetTimerDuration(durationObj, Enum.StatusBarInterpolation.Immediate, Enum.StatusBarTimerDirection.ElapsedTime) end -- Control visibility via SetAlphaFromBoolean overlay:SetAlphaFromBoolean(notInterruptible, 1, 0) ``` -------------------------------- ### Instance / Context APIs Source: https://github.com/wealdly/justac/blob/main/Documentation/12.0_COMPATIBILITY.md APIs for determining the current game instance or context, such as PvP, arena, party, or raid. These also include utility functions like getting the current time and checking for low health or channeling states. ```APIDOC ## Instance / Context APIs ### Description APIs for determining the current game instance or context, such as PvP, arena, party, or raid. These also include utility functions like getting the current time and checking for low health or channeling states. ### Methods - `IsInInstance()` - `C_PvP.IsPVPMap()` - `GetTime()` - `C_DamageMeter.GetSessionDurationSeconds(type)` - `LowHealthFrame:IsShown()` - `LowHealthFrame:GetAlpha()` - `PlayerChannelBarFrame:IsShown()` ### Returns - `IsInInstance()`: `boolean`, `instanceType` (`"pvp"`, `"arena"`, `"party"`, `"raid"`, `"none"`) - `C_PvP.IsPVPMap()`: `boolean` (PvP context detection.) - `GetTime()`: `number` (Always available.) - `C_DamageMeter.GetSessionDurationSeconds(type)`: `number?` (Real combat timer. Returns elapsed seconds.) - `LowHealthFrame:IsShown()`: `boolean` (Visual frame — NeverSecret. ~35% health threshold.) - `LowHealthFrame:GetAlpha()`: `number` (Higher alpha (~0.8) at ~20% critical.) - `PlayerChannelBarFrame:IsShown()`: `boolean` (Visual frame — player channeling detection.) ``` -------------------------------- ### Gradual Migration with Version-Aware Fixes Source: https://github.com/wealdly/justac/blob/main/Documentation/VERSION_CONDITIONALS.md Demonstrates a gradual migration strategy for fixing issues that arise in newer WoW versions. This example shows how to replace a deprecated string manipulation function (string.split) with a version-compatible alternative (string.gmatch) for WoW 12.0. ```lua local function ParseMacro(macroText) -- BEFORE: This crashes in 12.0 -- local tokens = string.split(macroText, ";") -- AFTER: Version-aware fix if BlizzardAPI.IsMidnightOrLater() then -- 12.0: string.split removed, use gmatch local tokens = {} for token in string.gmatch(macroText, "[^;]+") do table.insert(tokens, token) end return tokens else -- Pre-12.0: Original code works fine return {string.split(macroText, ";")} end end ``` -------------------------------- ### Example Complex Macro Structure Source: https://github.com/wealdly/justac/blob/main/Documentation/MACRO_PARSING_DEEP_DIVE.md This Lua code snippet demonstrates a common, complex macro structure observed in Feral/Resto Druid gameplay. It utilizes multiple conditions such as spec, form, modifiers, and spell knowledge to select the appropriate spell. The example highlights the challenges in parsing such macros due to the number of conditions and spell options per line, impacting the complexity score calculation. ```lua #showtooltip /use [spec:1,noform:4]Moonkin Form /use [mod,known:108238]Renewal /use [mod,known:192081]Ironfur /use [form:1]Mangle;[form:2]Shred;Starsurge ``` -------------------------------- ### Get Current Time (Lua) Source: https://github.com/wealdly/justac/blob/main/Documentation/12.0_COMPATIBILITY.md Retrieves the current game time. This function is always available and returns a number. ```lua GetTime() ``` -------------------------------- ### Lua Module Naming Convention Source: https://github.com/wealdly/justac/blob/main/Documentation/STYLE_GUIDE_JUSTAC.md Specifies the naming convention for Lua modules registered with LibStub, requiring a 'JustAC-' prefix followed by a PascalCase name. ```lua -- MUST: PascalCase with "JustAC-" prefix for LibStub "JustAC-SpellDB" "JustAC-BlizzardAPI" "JustAC-FormCache" "JustAC-MacroParser" "JustAC-ActionBarScanner" "JustAC-RedundancyFilter" "JustAC-SpellQueue" "JustAC-UIHealthBar" "JustAC-UIAnimations" "JustAC-UIFrameFactory" "JustAC-UIRenderer" "JustAC-UINameplateOverlay" "JustAC-DefensiveEngine" "JustAC-DebugCommands" "JustAC-Options" ``` -------------------------------- ### Proc Glow Detection with 12.0 Migration (UIManager.lua) Source: https://github.com/wealdly/justac/blob/main/Documentation/12.0_COMPATIBILITY.md Handles the detection of spell overlays and glows, with a specific migration path for WoW version 12.0. It addresses the use of secret values returned by API calls and provides a fallback for older versions or unchanged APIs. ```lua local hasProc = C_SpellActivationOverlay.IsSpellOverlayed and C_SpellActivationOverlay.IsSpellOverlayed(spellID) ``` ```lua -- If returns secret, use SetAlphaFromBoolean local hasProc = C_SpellActivationOverlay.IsSpellOverlayed(spellID) if issecretvalue and issecretvalue(hasProc) then -- Use secret-safe method glowFrame:SetAlphaFromBoolean(hasProc, 1.0, 0.0) else -- Normal path (out of combat or API unchanged) if hasProc then StartProcGlow() else StopProcGlow() end end ``` -------------------------------- ### DefensiveEngine Module Source: https://context7.com/wealdly/justac/llms.txt The DefensiveEngine module manages the defensive spell system including health-based queue building, proc detection, and potion auto-insertion. ```APIDOC ## DefensiveEngine Module ### Description The DefensiveEngine module manages the defensive spell system including health-based queue building, proc detection, and potion auto-insertion. ### Functions #### `DefensiveEngine.InitializeDefensiveSpells(addon)` **Description:** Initializes the defensive spells for the current player class. Call this on addon load. **Parameters:** - `addon` (table) - The AceAddon instance for JustAssistedCombat. ### `DefensiveEngine.GetClassSpellList(addon, listType)` **Description:** Retrieves a list of spells specific to the player's class for a given type. **Parameters:** - `addon` (table) - The AceAddon instance for JustAssistedCombat. - `listType` (string) - The type of spell list to retrieve (e.g., "defensiveSpells", "petHealSpells", "petRezSpells"). **Returns:** - `spells` (table) - A table containing the requested spell list. ### `DefensiveEngine.RestoreDefensiveDefaults(addon, listType)` **Description:** Restores the default settings for a specified spell list type. **Parameters:** - `addon` (table) - The AceAddon instance for JustAssistedCombat. - `listType` (string) - The type of spell list to restore defaults for ("defensive", "petheal", "petrez"). ### `DefensiveEngine.GetDefensiveSpellQueue(addon, isLow, inCombat, exclusions)` **Description:** Gets the defensive spell queue, applying health-based filtering. **Parameters:** - `addon` (table) - The AceAddon instance for JustAssistedCombat. - `isLow` (boolean) - True if the player's health is low. - `inCombat` (boolean) - True if the player is in combat. - `exclusions` (table) - A list of spells already present in the DPS queue. **Returns:** - `queue` (table) - A table of defensive spell entries, each containing `spellID`, `isItem`, `isProcced`, and `unusable`. ### `DefensiveEngine.GetUsableDefensiveSpells(addon, defensives, maxCount, alreadyAdded)` **Description:** Gets usable defensive spells, prioritizing procs. **Parameters:** - `addon` (table) - The AceAddon instance for JustAssistedCombat. - `defensives` (table) - A list of defensive spells to consider. - `maxCount` (number) - The maximum number of spells to return. - `alreadyAdded` (table) - A list of spells that have already been added. **Returns:** - `spells` (table) - A table of usable defensive spell entries. ### `DefensiveEngine.FindHealingPotionOnActionBar(addon)` **Description:** Finds a healing potion on the action bar. This function is used for auto-inserting potions when health is low. **Parameters:** - `addon` (table) - The AceAddon instance for JustAssistedCombat. **Returns:** - `itemID` (number | nil) - The item ID of the healing potion, or nil if not found. - `slot` (number | nil) - The action bar slot of the healing potion, or nil if not found. ### `DefensiveEngine.InvalidatePotionCache()` **Description:** Invalidates the potion cache. Call this when action bar or bag contents change. ### `DefensiveEngine.OnHealthChanged(addon, event, unit)` **Description:** Handles health change events. This is the main entry point for health-related updates. **Parameters:** - `addon` (table) - The AceAddon instance for JustAssistedCombat. - `event` (string | nil) - The event name (e.g., "UNIT_HEALTH"), or nil to bypass throttling. - `unit` (string) - The unit whose health changed (e.g., "player", "pet"). ### `DefensiveEngine.UpdateDefensiveCooldowns(addon)` **Description:** Updates the cooldown displays on visible defensive spell icons. **Parameters:** - `addon` (table) - The AceAddon instance for JustAssistedCombat. ### `DefensiveEngine.RegisterDefensivesForTracking(addon)` **Description:** Registers defensive spells for cooldown tracking in version 12.0 and later. **Parameters:** - `addon` (table) - The AceAddon instance for JustAssistedCombat. ``` -------------------------------- ### API Availability Check and Version-Specific Logic Source: https://github.com/wealdly/justac/blob/main/Documentation/VERSION_CONDITIONALS.md Shows a pattern for handling APIs that might not exist in older WoW versions, combined with version-specific logic. This example for GetCooldown checks for C_Spell.GetSpellCooldown and then applies 12.0 specific handling for secrets. ```lua local function GetCooldown(spellID) if C_Spell and C_Spell.GetSpellCooldown then -- Modern API (11.0+) if BlizzardAPI.IsMidnightOrLater() then -- 12.0: Handle secrets in cooldown data local info = C_Spell.GetSpellCooldown(spellID) if info and not issecretvalue(info.startTime) then return info.startTime, info.duration end return nil, nil -- Secret value detected else -- 11.x: No secrets yet local info = C_Spell.GetSpellCooldown(spellID) return info.startTime, info.duration end else -- Fallback for ancient clients return GetSpellCooldown(spellID) end end ``` -------------------------------- ### Use table.concat for Large Strings (Lua) Source: https://github.com/wealdly/justac/blob/main/Documentation/STYLE_GUIDE_JUSTAC.md Recommends using `table.concat` for building large strings efficiently in Lua, contrasting it with the performance cost of repeated string concatenation in a loop. ```lua -- BAD: Repeated concatenation ❌ local result = "" for i = 1, 1000 do result = result .. tostring(i) .. ", " end -- GOOD: table.concat ✓ local parts = {} for i = 1, 1000 do parts[i] = tostring(i) end local result = table.concat(parts, ", ") ``` -------------------------------- ### JustAC Configuration Structure (Lua) Source: https://context7.com/wealdly/justac/llms.txt Defines the default configuration structure for the JustAC addon using AceDB-3.0. It includes settings for profile, character, and global scopes, covering display, visibility, features, input, and defensive systems. ```lua -- Profile settings (shared across characters using same profile) local defaults = { profile = { -- Display settings maxIcons = 4, -- Number of spell icons (1-10) iconSize = 42, -- Icon size in pixels iconSpacing = 1, -- Gap between icons firstIconScale = 1.0, -- Scale for primary spell icon queueIconDesaturation = 0, -- Desaturate queue icons (0-1) frameOpacity = 1.0, -- Overall frame transparency queueOrientation = "LEFT", -- Queue growth: LEFT, RIGHT, UP, DOWN -- Visibility settings displayMode = "queue", -- "disabled", "queue", "overlay", "both" hideQueueOutOfCombat = false, -- Hide when not in combat hideQueueWhenMounted = false, -- Hide while mounted requireHostileTarget = false, -- Only show with hostile target -- Feature settings interruptMode = "ccPrefer", -- "disabled", "kickOnly", "ccPrefer" glowMode = "all", -- "all", "primaryOnly", "procOnly", "none" showFlash = true, -- Flash on keybind press showSpellbookProcs = true, -- Show procced spells from spellbook tooltipMode = "always", -- "never", "outOfCombat", "always" -- Input settings gamepadIconStyle = "xbox", -- "generic", "xbox", "playstation" inputPreference = "auto", -- "auto", "keyboard", "gamepad" -- Defensive settings defensives = { enabled = true, displayMode = "always", -- "healthBased", "combatOnly", "always" maxIcons = 4, selfHealThreshold = 80, -- Show below this health % showProcs = true, -- Show procced defensives at any health autoInsertPotions = true, -- Auto-add health potions when low }, -- Gap-closer settings gapClosers = { enabled = true, classSpells = {}, -- Per-spec spell lists }, -- Hotkey overrides (profile-level, included in copies) hotkeyOverrides = {}, -- [spellID] = "custom text" }, -- Character-specific settings char = { blacklistedSpells = {}, -- [spellID] = true specProfilesEnabled = true, -- Auto-switch profiles by spec specProfiles = {}, -- [specIndex] = "profileName" }, } ``` -------------------------------- ### Lua Indentation Standard Source: https://github.com/wealdly/justac/blob/main/Documentation/STYLE_GUIDE_JUSTAC.md Enforces a strict 4-space indentation per level for Lua code, prohibiting the use of tabs. This ensures consistent code readability across the project. ```lua -- MUST: 4 spaces per level, no tabs function myFunction() if condition then doSomething() end end ``` -------------------------------- ### WoW Macro Spell and Item Casting Source: https://github.com/wealdly/justac/blob/main/Documentation/MACRO_PARSING_DEEP_DIVE.md Illustrates the syntax for casting spells, using items, and managing sequential spell casts with reset timers in WoW macros. ```lua -- Spell syntax: /cast SpellName -- Direct cast /cast [cond] Spell1; Spell2; Spell3 -- Conditional cascade /castsequence reset=N Spell1, Spell2 -- Sequential /use ItemName -- Items or spells /use SlotNumber -- Equipment slots (0-19) ``` -------------------------------- ### Get Unit Health (Lua) Source: https://github.com/wealdly/justac/blob/main/Documentation/12.0_COMPATIBILITY.md This function retrieves the health status of a unit. It's confirmed to be safe and reliable, even when dealing with secret values in other health-related APIs. ```lua UnitHealth("player") ``` -------------------------------- ### Standard Event Registration in Lua (AceEvent) Source: https://github.com/wealdly/justac/blob/main/Documentation/STYLE_GUIDE_JUSTAC.md Shows the standard method for registering events using the AceEvent library, commonly found in WoW addons. It includes registering callbacks for specific game events like player specialization changes and shapeshift form updates. ```lua -- Core addon uses AceEvent self:RegisterEvent("PLAYER_SPECIALIZATION_CHANGED", "OnSpecChanged") self:RegisterEvent("UPDATE_SHAPESHIFT_FORM", function() if MacroParser and MacroParser.InvalidateMacroCache then MacroParser:InvalidateMacroCache() end self:ForceUpdate() end) ``` -------------------------------- ### Get Low Health Frame Alpha (Lua) Source: https://github.com/wealdly/justac/blob/main/Documentation/12.0_COMPATIBILITY.md Retrieves the alpha (transparency) value of the low health warning frame. The alpha is higher at critical health thresholds. ```lua LowHealthFrame:GetAlpha() ``` -------------------------------- ### Assisted Combat Action Spell Management (Lua Example) Source: https://github.com/wealdly/justac/blob/main/Documentation/ASSISTED_COMBAT_API_DEEP_DIVE.md Demonstrates the management of the current primary action spell within the AssistedCombatManager. This involves setting the action spell ID and asynchronously loading its associated data. ```lua actionSpellID = nil spellDescription = nil -- Updated via SetActionSpell(actionSpellID) -- Loads spell data asynchronously ``` -------------------------------- ### Get Damage Meter Session Duration (Lua) Source: https://github.com/wealdly/justac/blob/main/Documentation/12.0_COMPATIBILITY.md Retrieves the duration of the current damage meter session in seconds. This provides a real combat timer and is available from 2026-02-25. ```lua C_DamageMeter.GetSessionDurationSeconds(type) ``` -------------------------------- ### Module Event Pattern in Lua Source: https://github.com/wealdly/justac/blob/main/Documentation/STYLE_GUIDE_JUSTAC.md Illustrates a pattern where modules export functions that are called by the core addon in response to specific events. This promotes modularity and separation of concerns within the application. ```lua -- Modules export functions called by core function FormCache.OnPlayerLogin() UpdateFormCache() ScanSpellbookForFormSpells() end function ActionBarScanner.OnUIChanged() InvalidateStateCache() InvalidateKeybindCache() end ``` -------------------------------- ### Lua Example: Handling Version-Specific API Changes Source: https://github.com/wealdly/justac/blob/main/Documentation/VERSION_CONDITIONALS.md This Lua code snippet demonstrates how to safely call APIs that have changed between game versions (e.g., pre-12.0 and 12.0). It checks the game version using BlizzardAPI.IsMidnightOrLater() and uses different API calls based on the result, ensuring backward compatibility and proper functionality in the new version. It also includes comments explaining the cause of the error and the purpose of the different code paths. ```lua -- ERROR in 12.0: "attempt to call field 'GetOverrideSpell' (a nil value)" -- CAUSE: C_Spell.GetOverrideSpell removed in 12.0 local function GetDisplaySpell(baseSpellID) if BlizzardAPI.IsMidnightOrLater() then -- 12.0: Use new SpecializationInfo API if C_ClassTalents and C_ClassTalents.GetActiveSpecOverride then return C_ClassTalents.GetActiveSpecOverride(baseSpellID) or baseSpellID end return baseSpellID -- No override available else -- Pre-12.0: Original API if C_Spell and C_Spell.GetOverrideSpell then return C_Spell.GetOverrideSpell(baseSpellID) or baseSpellID end return baseSpellID end end ``` -------------------------------- ### Lua Assisted Combat Action Filtering Source: https://github.com/wealdly/justac/blob/main/Documentation/STYLE_GUIDE_JUSTAC.md Filters out actions identified as 'assistedcombat' in Lua. This is crucial for preventing unintended actions when using combat assistance features, ensuring only player-intended actions are processed. ```lua -- MUST: Filter "assistedcombat" string actionType local actionType, id = GetActionInfo(slot) -- Check multiple ways local isAssistantButton = (actionType == "spell" and type(id) == "string" and id == "assistedcombat") local isAssistedCombatAction = C_ActionBar and C_ActionBar.IsAssistedCombatAction and C_ActionBar.IsAssistedCombatAction(slot) if isAssistantButton or isAssistedCombatAction then return nil -- Skip this slot end ``` -------------------------------- ### Lua Throttling Pattern Source: https://github.com/wealdly/justac/blob/main/Documentation/STYLE_GUIDE_JUSTAC.md Implements a throttling pattern in Lua to manage high-frequency operations. It limits the execution rate of a function by checking the time elapsed since the last execution, ensuring performance. ```lua -- MUST: Use for high-frequency operations local lastUpdate = 0 function Update() local now = GetTime() local throttleInterval = 0.03 -- 30fps max if now - lastUpdate < throttleInterval then return -- Skip update end lastUpdate = now -- Do expensive work end ``` -------------------------------- ### Manage Defensive Spells with DefensiveEngine Source: https://context7.com/wealdly/justac/llms.txt The DefensiveEngine module handles the defensive spell system, including health-based queue building, proc detection, and potion auto-insertion. It requires initialization with the addon and provides functions to get spell lists, manage defaults, retrieve spell queues, and find healing potions. Call InvalidatePotionCache on action bar or bag changes. ```lua local DefensiveEngine = LibStub("JustAC-DefensiveEngine") local addon = LibStub("AceAddon-3.0"):GetAddon("JustAssistedCombat") -- Initialize defensive spells for current class (call on load) DefensiveEngine.InitializeDefensiveSpells(addon) -- Get class-specific spell list local defensives = DefensiveEngine.GetClassSpellList(addon, "defensiveSpells") local petHeals = DefensiveEngine.GetClassSpellList(addon, "petHealSpells") local petRez = DefensiveEngine.GetClassSpellList(addon, "petRezSpells") -- Restore defaults for a spell list type DefensiveEngine.RestoreDefensiveDefaults(addon, "defensive") -- "defensive", "petheal", "petrez" -- Get defensive spell queue (with health-based filtering) local isLow = true -- Player health is low local inCombat = UnitAffectingCombat("player") local exclusions = {} -- Spells already shown in DPS queue local queue = DefensiveEngine.GetDefensiveSpellQueue(addon, isLow, inCombat, exclusions) for _, entry in ipairs(queue) do print(entry.spellID, entry.isItem, entry.isProcced, entry.unusable) end -- Get usable defensive spells (with proc prioritization) local alreadyAdded = {} local spells = DefensiveEngine.GetUsableDefensiveSpells(addon, defensives, 4, alreadyAdded) -- Find healing potion on action bar (auto-inserts when health is low) local itemID, slot = DefensiveEngine.FindHealingPotionOnActionBar(addon) if itemID then print("Found potion: " .. itemID .. " on slot " .. slot) end -- Invalidate potion cache (call on action bar or bag changes) DefensiveEngine.InvalidatePotionCache() -- Handle health change events (main entry point) DefensiveEngine.OnHealthChanged(addon, "UNIT_HEALTH", "player") DefensiveEngine.OnHealthChanged(addon, nil, "pet") -- nil event bypasses throttle -- Update cooldown displays on visible defensive icons DefensiveEngine.UpdateDefensiveCooldowns(addon) -- Register defensive spells for 12.0 cooldown tracking DefensiveEngine.RegisterDefensivesForTracking(addon) ``` -------------------------------- ### Lua Cache Invalidation Strategy Source: https://github.com/wealdly/justac/blob/main/Documentation/STYLE_GUIDE_JUSTAC.md Implements a fundamental cache invalidation strategy in Lua. It ensures that cache data is explicitly marked as invalid and can be rebuilt when necessary, preventing stale data retrieval. ```lua -- MUST: Every cache needs invalidation logic local cache = {} local cacheValid = false function InvalidateCache() cacheValid = false wipe(cache) end function GetCachedData() if not cacheValid then RebuildCache() end return cache end ``` -------------------------------- ### Get Shapeshift Form Info (Lua) Source: https://github.com/wealdly/justac/blob/main/Documentation/12.0_COMPATIBILITY.md This function retrieves information about the player's current shapeshift form. It is noted as not being restricted by secret API values, indicating reliable access. ```lua GetShapeshiftFormInfo ``` -------------------------------- ### Blizzard AuraUtil Pattern Example Source: https://github.com/wealdly/justac/blob/main/Documentation/AURA_DETECTION_ALTERNATIVES.md Demonstrates Blizzard's internal use of AuraUtil.ForEachAura with slot-based iteration for retrieving aura information. This pattern relies on GetAuraSlots() and GetAuraDataBySlot(), which may have different secret behaviors compared to index-based retrieval. ```lua -- From Blizzard_FrameXMLUtil/AuraUtil.lua function AuraUtil.ForEachAura(unit, filter, batchSize, func, usePackedAura) local continuationToken repeat continuationToken = ForEachAuraHelper(unit, filter, func, usePackedAura, C_UnitAuras.GetAuraSlots(unit, filter, batchSize, continuationToken)) until continuationToken == nil end ``` -------------------------------- ### Get Active Loss of Control Data Count (Lua) Source: https://github.com/wealdly/justac/blob/main/Documentation/12.0_COMPATIBILITY.md Retrieves the count of currently active loss of control effects. This API is part of the Loss of Control module and returns a number. ```lua C_LossOfControl.GetActiveLossOfControlDataCount() ```