### Usage Example for izi.simple_sequence Source: https://docs.project-sylvanas.net/dev/libraries/izi/izi-spells-sequences Example showing a burst sequence for a Mage. ```lua local izi = require("common/izi_sdk") -- Mage burst: Icy Veins -> Frozen Orb -> Blizzard local me = izi.me() local target = izi.ts() local burst_spells = { izi.spell(12472), -- Icy Veins izi.spell(84714), -- Frozen Orb izi.spell(190356), -- Blizzard } local burst_targets = { me, target, target } if izi.simple_sequence(burst_spells, burst_targets, 0, 5.0, "Frost Burst") then izi.print("Frost burst sequence started!") end ``` -------------------------------- ### Usage Examples for izi.a_into_b Source: https://docs.project-sylvanas.net/dev/libraries/izi/izi-spells-sequences Examples showing immediate execution and execution with a delay for global cooldown management. ```lua local izi = require("common/izi_sdk") local charge = izi.spell(100) local hamstring = izi.spell(1715) -- Charge then immediately Hamstring izi.a_into_b(charge, target, hamstring, target, 0, 2.0, "Charge->Hamstring") -- With a slight delay for GCD local heroic_leap = izi.spell(6544) local shockwave = izi.spell(46968) izi.a_into_b(heroic_leap, target, shockwave, me, 0.5, 3.0, "Leap->Shockwave") ``` -------------------------------- ### Check for active guide step Source: https://docs.project-sylvanas.net/dev/api/addons Verify both that the addon is loaded and that an active guide step exists. ```lua if core.addons.rested_xp.is_loaded() and core.addons.rested_xp.has_current_step() then core.log("RestedXP has an active step") end ``` -------------------------------- ### Execute confirmed_sequence example Source: https://docs.project-sylvanas.net/dev/libraries/izi/izi-spells-sequences Example usage of confirmed_sequence for a combo requiring server confirmation. ```lua local izi = require("common/izi_sdk") local me = izi.me() local target = izi.ts() -- Confirmed combo: Colossus Smash must land before Mortal Strike local steps = { { spell = izi.spell(167105), -- Colossus Smash target = target, confirm_debuff = 208086, -- Wait for debuff timeout = 2.0 }, { spell = izi.spell(12294), -- Mortal Strike target = target, -- No confirmation needed, just cast } } local opts = { timeout = 5.0, debug_name = "CS -> MS Combo", on_step = function(step_index) izi.printf("Step %d confirmed", step_index) end, on_complete = function() izi.print("Combo complete!") end } izi.confirmed_sequence(steps, opts) ``` -------------------------------- ### core.addons.rested_xp.get_current_stickies Source: https://docs.project-sylvanas.net/dev/api/addons Retrieves active sticky guide steps. ```APIDOC ## core.addons.rested_xp.get_current_stickies ### Description Returns RestedXP sticky steps that remain visible beside the current guide step. The current step itself is not included. ### Syntax `core.addons.rested_xp.get_current_stickies() -> rested_xp_step_info[]` ### Returns - **rested_xp_step_info[]** - Sticky guide steps. ``` -------------------------------- ### Move To Destination Example Source: https://docs.project-sylvanas.net/dev/api/sentinel-navigation Example usage of the move_to method with a callback to handle success or failure. ```lua client:move_to(vec3.new(-8900, 560, 94), function(ok, reason) if ok then core.log("Arrived at destination") else core.log_error("Move failed: " .. tostring(reason)) end end) ``` -------------------------------- ### Set Defensive Block Time Examples Source: https://docs.project-sylvanas.net/dev/api/plugin-helper Examples of setting block times for different defensive abilities to prevent overlapping or spamming. ```lua -- Using Divine Shield (8 second immunity) if divine_shield:cast() then -- Block for 6 seconds, so near the end we can prepare next defensive plugin_helper:set_defensive_block_time(6) end -- Using a Healthstone (instant, just prevent spam) if healthstone:use() then plugin_helper:set_defensive_block_time(1) end ``` -------------------------------- ### Execute advanced_sequence example Source: https://docs.project-sylvanas.net/dev/libraries/izi/izi-spells-sequences Example usage of advanced_sequence for a rogue opener with conditions and callbacks. ```lua local izi = require("common/izi_sdk") local me = izi.me() local target = izi.ts() -- Complex opener with conditions local entries = { { spell = izi.spell(1856), -- Vanish target = me, condition = function() return me:is_in_combat() end, on_cast = function() izi.print("Vanished!") end }, { spell = izi.spell(8676), -- Ambush target = target, delay = 0.1, -- Small delay to ensure stealth condition = function() return target:is_valid_enemy() end }, { spell = izi.spell(703), -- Garrote target = target, condition = function() return target:debuff_down(703) -- Only if not already applied end, on_skip = function() izi.print("Skipped Garrote - already applied") end } } local opts = { timeout = 5.0, cooldown = 30.0, -- 30 second cooldown debug_name = "Rogue Opener", on_complete = function() izi.print("Opener complete!") end } izi.advanced_sequence(entries, opts) ``` -------------------------------- ### Heal Setup Source: https://docs.project-sylvanas.net/dev/api/ts-override-helper Configure healing priority weights and range settings. ```lua local ts = require("common/utility/ts_override_helper") local W = ts.enums.weight local CTX = ts.enums.context ts:set_heal_enabled(true) ts:set_max_range_heal(40) ts:set_weight(CTX.HEAL, W.HEALTH_DECREASE, true, 3) ts:set_weight(CTX.HEAL, W.INJURED, true, 2) ts:set_weight(CTX.HEAL, W.LOW_HP, true, 4) ts:set_weight(CTX.HEAL, W.TANK, true, -1) ``` -------------------------------- ### Using set_pet_state Source: https://docs.project-sylvanas.net/dev/api/pet-handler Examples of setting pet states with optional delays. ```lua -- Set pet to passive immediately pet_handler:set_pet_state(pet_handler.pet_state.PASSIVE) -- Set pet to passive after 2 seconds pet_handler:set_pet_state(pet_handler.pet_state.PASSIVE, 2.0) -- Set pet to assist mode pet_handler:set_pet_state(pet_handler.pet_state.ASSIST) -- Set pet to defensive mode with delay pet_handler:set_pet_state(pet_handler.pet_state.DEFENSIVE, 0.5) ``` -------------------------------- ### Get Combat Start Game Time Source: https://docs.project-sylvanas.net/dev/api/auto-attack-helper Returns the core.game_time() when combat started. ```lua auto_attack:get_combat_start_game_time(): number ``` -------------------------------- ### Full Window Implementation Summary Source: https://docs.project-sylvanas.net/dev/guides/custom-ui Complete setup including imports, window initialization, and configuration sliders. ```lua ---@type color local color = require("common/color") ---@type vec2 local vec2 = require("common/geometry/vector_2") ---@type enums local enums = require("common/enums") -- Important: every window must have a unique identifier. -- In this case, the identifier is "Test window". local test_window = core.menu.window("Test window - ") local window_position_elements = { x = core.menu.slider_int(0, 10000, 500, "test_window_x_initial_position_"), y = core.menu.slider_int(0, 10000, 500, "test_window_y_initial_position_"), } local window_size_elements = { x = core.menu.slider_int(0, 10000, 500, "test_window_x_initial_size_"), y = core.menu.slider_int(0, 10000, 300, "test_window_y_initial_size_"), } local initial_size = vec2.new(window_size_elements.x:get(), window_size_elements.y:get()) test_window:set_initial_size(initial_size) local initial_position = vec2.new(window_position_elements.x:get(), window_position_elements.y:get()) test_window:set_initial_position(initial_position) local bg_color = color.new(16, 16, 20, 180) local border_color = color.new(100, 99, 150, 255) local color_picker_test = core.menu.colorpicker(bg_color, "color_picker_test_id_1") local window_popup = core.menu.window("Window Popup Test") window_popup:set_initial_size(vec2.new(300, 200)) -- this is relative to the parent window, not relative to screen, unlike the parent window initial position. window_popup:set_initial_position(vec2.new(500, 500)) local is_window_popup_open = false local is_popup_active = false core.register_on_render_window_callback(function() -- -- I know all these parameters might overwhelm you at the beginning, but don't worry since all these parameters are straightforward and pretty much self-explanatory. ``` -------------------------------- ### Full Plugin Settings Setup Source: https://docs.project-sylvanas.net/dev/modules/settings-manager Demonstrates the complete lifecycle of settings management, including menu definition, initialization, conditional access, and programmatic updates. ```lua local settings = require("common/modules/settings_manager") -- Set file name settings:set_file_name("fire_mage_rotation") -- Define menu structure local menu = { general = { enabled = core.menu.checkbox(true, "gen_enabled", "Enable Rotation"), debug = core.menu.checkbox(false, "gen_debug", "Debug Mode"), }, combat = { burst_enabled = core.menu.checkbox(true, "burst_enabled", "Enable Burst"), burst_hp = core.menu.slider(30, 0, 100, "burst_hp", "Burst Below HP%"), aoe_threshold = core.menu.slider(3, 1, 10, "aoe_thresh", "AoE Target Count"), }, defensives = { ice_block_hp = core.menu.slider(20, 5, 50, "ib_hp", "Ice Block HP%"), barrier_hp = core.menu.slider(50, 20, 80, "barrier_hp", "Barrier HP%"), }, } -- Attach and initialize settings:attach(menu) settings:init() -- Now you can use settings anywhere local function should_burst() local player = core.object_manager.get_local_player() local hp = player:get_health_percent() if not settings:get("combat.burst_enabled") then return false end return hp < settings:get("combat.burst_hp") end -- Programmatic changes local function on_boss_pull() -- Temporarily lower burst threshold for boss settings:set("combat.burst_hp", 50) end -- Reset button handler local function on_reset_clicked() settings:reset(true) -- Reset and save to file core.log("Settings reset to defaults") end ``` -------------------------------- ### Get Combat Start Core Time Source: https://docs.project-sylvanas.net/dev/api/auto-attack-helper Returns the core.time() when combat started. ```lua auto_attack:get_combat_start_core_time(): number ``` -------------------------------- ### Retrieve channel timing information Source: https://docs.project-sylvanas.net/dev/libraries/izi/izi-object-extensions Methods to get start, end, duration, elapsed, and remaining time for a channel. ```lua unit:get_channel_start_ms(): number ``` ```lua unit:get_channel_end_ms(): number ``` ```lua unit:get_channel_duration_ms(): number ``` ```lua unit:get_channel_elapsed_ms(): number ``` ```lua unit:get_channel_remaining_ms(): number ``` ```lua if target:get_channel_remaining_ms() < 500 then -- Channel almost finished end ``` ```lua unit:get_channel_remaining_sec(): number ``` -------------------------------- ### Quick Start for Settings Persistence Source: https://docs.project-sylvanas.net/dev/modules/settings-manager Initialize settings by defining a menu structure, attaching it to the manager, and calling the init method. ```lua local settings = require("common/modules/settings_manager") -- 1. Set the file name (saved to scripts_data/) settings:set_file_name("my_plugin_settings") -- 2. Define your menu elements local menu = { combat = { enabled = core.menu.checkbox(true, "combat_enabled", "Enable Combat"), burst_threshold = core.menu.slider(30, 0, 100, "burst_hp", "Burst HP%"), }, targeting = { max_range = core.menu.slider(40, 5, 100, "max_range", "Max Range"), }, } -- 3. Attach menu elements settings:attach(menu) -- 4. Initialize (loads from disk or uses defaults) settings:init() ``` -------------------------------- ### Configuring and Beginning a Window Source: https://docs.project-sylvanas.net/dev/guides/custom-ui Initializes a window with specific resizing, styling, and behavior flags, requiring a callback function as the final parameter. ```lua core.register_on_render_window_callback(function() -- I know all these parameters might overwhelm you at the beginning, but don't worry since all -- these parameters are straightforward and pretty much self-explanatory. -- Parameter 1: Resizing flags -> Accepts window_resizing_flags enum member: .NO_RESIZE or 0, -- .RESIZE_WIDTH, -- .RESIZE_HEIGHT, -- .RESIZE_BOTH_AXIS -- .NO_RESIZE: The draggable resizing areas will be completely disabled, -- making it impossible for the user to change the window's size. -- .RESIZE_WIDTH: Only the lateral draggable zone will be enabled, so the user will only be able to increase the window's width. -- .RESIZE_HEIGHT: Only the bottom draggable zone will be enabled, so the user will only be able to increase the window's height. -- .RESIZE_BOTH_AXIS: The bottom-right draggable zone will be enabled, so the user will be able to modify both, width and height. -- Parameter 2: Is adding cross -> Accepts Boolean. The cross refers to the top right X that when pressed will make the window invisible. If false, no cross will be rendered, -- so you will have to manually handle a way to close and open the window (eg. custom buttons). -- Parameter 3: Background color -> Accepts Color -- Parameter 4: Border color -> Accepts Color -- Parameter 5: Cross style flag -> Accepts window_cross_visuals enum member: DEFAULT = 0, -- PURPLE_THEME = 1, -- GREEN_THEME = 2, -- RED_THEME = 3, -- BLUE_THEME = 4, -- NO_BACKGROUND = 5, -- ONLY_HITBOX = 6, -- NO_BORDER = 7, -- NO_BACKGROUND_AND_NO_BORDER = 8, -- NO_CROSS = 9 -- The cross style enum names are self explanatory, but I advise you to play with all these values and see how they change. -- There are up to 3 extra possible parameters that are optional before we add the function call, which is always the last parameter no matter what. -- These parameters are just extra flags that we can add that will alter the way the window behaves. They are inside the enums.window_enums.window_behaviour_flags. -- These flags are: -- .NO_MOVE: Disables the window's movement, so the user won't be able to move the window by dragging it. -- .NO_SCROLLBAR: Disables scrollbars for the window. -- .ALWAYS_AUTO_RESIZE: Window will automatically resize according to the elements, always according to the dynamic spacing size (see advanced guide) -- NOTE: To use the default color, we need to pass color.new(0,0,0,0) test_window:begin(enums.window_enums.window_resizing_flags.RESIZE_BOTH_AXIS, true, color.new(0,0,0,0), color.new(0,0,0,0), enums.window_enums.window_cross_visuals.BLUE_THEME, function() end) end) ``` -------------------------------- ### Get Pet Stats Source: https://docs.project-sylvanas.net/dev/api/pet-battle Retrieves current health, power, speed, and rarity for a specific pet using its GUID. ```lua core.pet_battle.get_pet_stats(pet_id: string) -> table ``` -------------------------------- ### core.addons.rested_xp.get_current_step Source: https://docs.project-sylvanas.net/dev/api/addons Retrieves information about the current active guide step. ```APIDOC ## core.addons.rested_xp.get_current_step ### Description Returns the current RestedXP guide step. If no current step is available, num is 0 and goals is empty. ### Syntax `core.addons.rested_xp.get_current_step() -> rested_xp_step_info` ### Returns - **rested_xp_step_info** - The current step containing: - **num** (integer) - Current RestedXP step index. - **is_complete** (boolean) - Whether RestedXP marks the step complete. - **goals** (rested_xp_goal_info[]) - The step goals. ``` -------------------------------- ### Retrieve Zygor Objectives Source: https://docs.project-sylvanas.net/dev/api/addons Get an array of objective values from the current guide step, which may be numeric or string-based. ```lua core.addons.zygor.get_objectives() -> (number|string)[] ``` -------------------------------- ### Integrating PvP UI in Main File Source: https://docs.project-sylvanas.net/dev/libraries/mini-libs/pvp-ui Demonstrates how to require the module, initialize settings, and render the launch checkbox within the menu callback. ```lua local pvp_ui = require("pvp_ui_logics") ui_buttons_info:set_pvp_ui_buttons() ui_buttons_info:hide_time_slider() --- (this IS inside the on_render_menu callback) local on_render_menu() -- (...) pvp_ui.launch_pvp_ui_button:render("Enable PvP UI Window") -- (...) end ``` -------------------------------- ### Get Game Time Source: https://docs.project-sylvanas.net/dev/api/core Returns time elapsed since game start in milliseconds. Use this for game-related info like buff or spell durations. ```lua local game_time = core.game_time() core.log("Game time elapsed: " .. game_time .. " ms") ``` -------------------------------- ### Initialize and Configure a Custom Window Source: https://docs.project-sylvanas.net/dev/guides/custom-ui Demonstrates how to define a window with initial position and size sliders, and register a render callback to configure its behavior and appearance. ```lua ---@type color local color = require("common/color") ---@type vec2 local vec2 = require("common/geometry/vector_2") ---@type enums local enums = require("common/enums") local test_window = core.menu.window("Test window") -- Important: every window must have a unique identifier. -- In this case, the identifier is "Test window". local window_position_elements = { x = core.menu.slider_int(0, 10000, 500, "test_window_x_initial_position_"), y = core.menu.slider_int(0, 10000, 500, "test_window_y_initial_position_"), } local window_size_elements = { x = core.menu.slider_int(0, 10000, 500, "test_window_x_initial_size_"), y = core.menu.slider_int(0, 10000, 300, "test_window_y_initial_size_"), } local initial_size = vec2.new(window_size_elements.x:get(), window_size_elements.y:get()) test_window:set_initial_size(initial_size) local initial_position = vec2.new(window_position_elements.x:get(), window_position_elements.y:get()) test_window:set_initial_position(initial_position) core.register_on_render_window_callback(function() -- I know all these parameters might overwhelm you at the beginning, but don't worry since all these parameters are straightforward and pretty much self-explanatory. -- Parameter 1: Resizing flags -> Accepts window_resizing_flags enum member: .NO_RESIZE or 0, -- .RESIZE_WIDTH, -- .RESIZE_HEIGHT, -- .RESIZE_BOTH_AXIS -- .NO_RESIZE: The draggable resizing areas will be completely disabled, making it impossible for the user to change the window's size. -- .RESIZE_WIDTH: Only the lateral draggable zone will be enabled, so the user will only be able to increase the window's width. -- .RESIZE_HEIGHT: Only the bottom draggable zone will be enabled, so the user will only be able to increase the window's height. -- .RESIZE_BOTH_AXIS: The bottom-right draggable zone will be enabled, so the user will be able to modify both, width and height. -- Parameter 2: Is adding cross -> Accepts Boolean. The cross refers to the top right X that when pressed will make the window invisible. If false, no cross will be rendered, -- so you will have to manually handle a way to close and open the window (eg. custom buttons). -- Parameter 3: Background color -> Accepts Color -- Parameter 4: Border color -> Accepts Color -- Parameter 5: Cross style flag -> Accepts window_cross_visuals enum member: DEFAULT = 0, -- PURPLE_THEME = 1, -- GREEN_THEME = 2, -- RED_THEME = 3, -- BLUE_THEME = 4, -- NO_BACKGROUND = 5, -- ONLY_HITBOX = 6, -- NO_BORDER = 7, -- NO_BACKGROUND_AND_NO_BORDER = 8, -- NO_CROSS = 9 -- The cross style enum names are self explanatory, but I advise you to play with all these values and see how they change. -- There are up to 3 extra possible parameters that are optional before we add the function call, which is always the last parameter no matter what. -- These parameters are just extra flags that we can add that will alter the way the window behaves. They are inside the enums.window_enums.window_behaviour_flags. -- These flags are: -- .NO_MOVE: Disables the window's movement, so the user won't be able to move the window by dragging it. -- .NO_SCROLLBAR: Disables scrollbars for the window. -- .ALWAYS_AUTO_RESIZE: Window will automatically resize according to the elements, always according to the dynamic spacing size (see advanced guide) -- NOTE: To use the default color, we need to pass color.new(0,0,0,0) test_window:begin(enums.window_enums.window_resizing_flags.RESIZE_BOTH_AXIS, true, color.new(0,0,0,0), color.new(0,0,0,0), enums.window_enums.window_cross_visuals.BLUE_THEME, function() end) end) ``` -------------------------------- ### Get Pet Loadout Info Source: https://docs.project-sylvanas.net/dev/api/pet-battle Retrieves the pet GUID and ability configuration for a specific loadout slot. Check the locked field before accessing pet_guid. ```lua core.pet_battle.get_pet_load_out_info(slot_index: integer) -> table ``` -------------------------------- ### Complete HUD and World Rendering Example Source: https://docs.project-sylvanas.net/dev/libraries/izi/graphics Demonstrates registering asset packs, drawing HUD elements, and rendering world markers based on entity state. ```lua local izi = require("common/izi_sdk") local color = izi.color -- Register custom asset pack izi.register_zip_pack("rotation_icons", "ps/98765-rotation_icons.zip") -- HUD drawing function local function draw_hud() local me = izi.me() if not me then return end local base_x = 400 local base_y = 600 local icon_size = 48 local padding = 4 -- Draw class icon local class_icons = { [1] = "classicon-warrior", [2] = "classicon-paladin", [3] = "classicon-hunter", [8] = "classicon-mage", [9] = "classicon-warlock", } local class_icon = class_icons[me:get_class()] or "classicon-warrior" izi.draw_icon( class_icon, izi.vec2(base_x, base_y), icon_size, icon_size ) -- Draw resource bar using local texture local resource_pct = me:mana_pct() / 100 izi.draw_local_texture( "rotation_icons\\bar_bg.png", izi.vec2(base_x + icon_size + padding, base_y + 16), 100, 16 ) izi.draw_local_texture( "rotation_icons\\bar_fill.png", izi.vec2(base_x + icon_size + padding, base_y + 16), 100 * resource_pct, 16, color.blue() ) -- Draw cooldown icons using spell IDs (no manual icon name lookup!) local cooldown_spells = { { id = 12472, spell = izi.spell(12472) }, -- Icy Veins { id = 84714, spell = izi.spell(84714) }, -- Frozen Orb } for i, entry in ipairs(cooldown_spells) do local x = base_x + (i - 1) * (icon_size + padding) local y = base_y + icon_size + padding -- Draw spell icon directly from spell ID izi.draw_spell_icon( entry.id, izi.vec2(x, y), icon_size, icon_size, entry.spell:cooldown_up() and color.white() or color.grey(128) ) end end -- Draw target markers in world local function draw_world_markers() local enemies = izi.enemies(40) for _, enemy in ipairs(enemies) do local pos = enemy:get_position() -- Show what the enemy is casting using spell ID icons if enemy:is_casting() then local cast_id = enemy:get_active_cast_or_channel_id() if cast_id and cast_id > 0 then izi.draw_spell_icon( cast_id, pos, 24, 24, color.red() ) end elseif enemy:get_health_percentage() < 20 then izi.draw_icon( "ability_warrior_execute", pos, 24, 24, color.orange() ) end end end -- Register render callback core.register_on_render_callback(function() draw_hud() draw_world_markers() end) ``` -------------------------------- ### core.addons.zygor.get_current_step Source: https://docs.project-sylvanas.net/dev/api/addons Retrieves the current Zygor guide step and its associated goals. ```APIDOC ## core.addons.zygor.get_current_step ### Description Returns the current Zygor guide step and its goals. Check `has_current_step()` before calling. ### Syntax `core.addons.zygor.get_current_step() -> table` ### Returns - **table** - A table containing: - `num` (integer): The step number. - `is_complete` (boolean): Whether this step is complete. - `goals` (table[]): An array of goals, each containing `action` (string), `quest_id` (integer), `npc_id` (integer), `target_id` (integer), `target` (string), `npc` (string), and `is_complete` (boolean). ``` -------------------------------- ### Perform HTTP GET Requests Source: https://docs.project-sylvanas.net/dev/api/core Use these examples to fetch remote data such as JSON or images. The callback provides the HTTP status code and response body. ```lua core.http_get("https://httpbin.org/get", function(http_code, content_type, response_data, response_headers) core.log("Status: " .. http_code) core.log("Response: " .. response_data) end) ``` ```lua core.http_get("https://httpbin.org/get", { ["Authorization"] = "Bearer token123", ["User-Agent"] = "MyApp/1.0", ["Accept"] = "application/json" }, function(http_code, content_type, response_data, response_headers) core.log("Status: " .. http_code) core.log("Response: " .. response_data) end) ``` ```lua core.http_get("https://example.com/image.png", function(http_code, content_type, response_data, response_headers) if http_code == 200 and response_data and #response_data > 0 then local texture_id, width, height = core.graphics.load_texture(response_data) if texture_id then core.log("Texture loaded! ID: " .. texture_id .. ", Size: " .. width .. "x" .. height) end end end) ``` -------------------------------- ### Queue Helper Plugin Implementation Source: https://docs.project-sylvanas.net/dev/libraries/izi/queue A complete example demonstrating how to auto-focus the game window on queue popups and implement anti-AFK movement. ```lua local izi = require("common/izi_sdk") -- Configuration local config = { track_pvp = true, track_pve = true, anti_afk = true, focus_interval = 10.0, -- seconds between focus attempts afk_timeout = 60.0, -- seconds before anti-AFK nudge } -- State local last_focus_time = 0 local last_move_time = izi.now() local nudge_active = false local nudge_start = 0 local NUDGE_DURATION = 0.05 -- seconds local function on_update() local me = izi.me() if not me or not me:is_valid() then return end local now = izi.now() -- Track movement for anti-AFK if me:is_moving() then last_move_time = now end -- Check for queue popup local has_popup, info = izi.queue_popup_info() if has_popup then -- Check if we should focus the window local should_focus = false if info.kind == "pvp" and config.track_pvp then should_focus = true elseif info.kind == "pve" and config.track_pve then should_focus = true end if should_focus and (now - last_focus_time) >= config.focus_interval then if core.set_window_foremost then core.set_window_foremost() izi.printf("Queue popup! (%s)", info.kind) end last_focus_time = now end end -- Anti-AFK logic if config.anti_afk then -- End active nudge if nudge_active and (now - nudge_start) >= NUDGE_DURATION then nudge_active = false if core.input and core.input.move_forward_stop then core.input.move_forward_stop() end end -- Start new nudge if AFK too long if not nudge_active and (now - last_move_time) >= config.afk_timeout then if core.input and core.input.move_forward_start then core.input.move_forward_start() nudge_active = true nudge_start = now last_move_time = now izi.print("Anti-AFK nudge") end end end end -- Auto-accept queues local function auto_accept() local has_popup, info = izi.queue_popup_info() if not has_popup then return end -- Wait a moment before accepting (to be safe) if info.age_sec < 1.0 then return end if info.kind == "pvp" and config.track_pvp then if izi.queue_accept("pvp") then izi.print("Auto-accepted PvP queue!") end elseif info.kind == "pve" and config.track_pve then if izi.queue_accept("pve") then izi.print("Auto-accepted PvE queue!") end end end -- Register callbacks core.register_on_update_callback(on_update) core.register_on_update_callback(auto_accept) ``` -------------------------------- ### Creating and blending colors example Source: https://docs.project-sylvanas.net/dev/api/color Demonstrates the workflow of creating two colors, blending them, and logging the result. ```lua -- Example usage of creating and blending colors local color1 = color.new(255, 0, 0, 255) -- Red color local color2 = color.new(0, 255, 0, 255) -- Green color -- Blend colors with alpha of 0.5 local blended_color = color1:blend(color2, 0.5) core.log(blended_color:get()) -- Output: 127, 127, 0, 255 (Yellow color) ``` -------------------------------- ### get() / set(new_value) Source: https://docs.project-sylvanas.net/dev/api/ui Get or set the currently selected index. ```APIDOC ## get() / set(new_value) ### Description Get or set the currently selected index (1-based). ``` -------------------------------- ### Initialize Menu and Utilities Source: https://docs.project-sylvanas.net/dev/api/ui/control-panel Sets up the required utilities, enums, and menu elements. Keybinds are initialized to 7 (Unbinded) to ensure they appear in the control panel. ```lua ---@type key_helper local key_helper = require("common/utility/key_helper") ---@type control_panel_helper local control_panel_utility = require("common/utility/control_panel_helper") local combat_mode_enum = { AUTO = 1, AOE = 2, SINGLE = 3, } local combat_mode_options = { "Auto", "AoE", "Single" } local test_tree_node = core.menu.tree_node() local menu = { -- note that we are initializing the keybinds with the value "7". This value corresponds to "Unbinded". -- We do this so the user has to manually set the key they want. Otherwise, this menu element won't appear -- in the Control Panel, and will be treated as if its value were true. enable_toggle = core.menu.keybind(7, false, "enable_toggle"), switch_combat_mode = core.menu.keybind(7, false, "switch_combat_mode"), soft_cooldown_toggle = core.menu.keybind(7, false, "soft_cooldown_toggle"), heavy_cooldown_toggle = core.menu.keybind(7, false, "heavy_cooldown_toggle"), combat_mode = core.menu.combobox(combat_mode_enum.AUTO, "combat_mode_auto_aoe_single"), } local function on_render_menu_elements() ``` -------------------------------- ### Start Auto Attack Source: https://docs.project-sylvanas.net/dev/api/auto-attack-helper Starts auto attacking the specified target. ```lua auto_attack:start_attack(target: game_object, attack_type: integer): boolean ``` -------------------------------- ### Defensive Filters Usage Example Source: https://docs.project-sylvanas.net/dev/libraries/izi/types Example of applying defensive filters to a spell cast. ```lua local divine_shield = izi.spell(642) local filters = { block_time = 8.0, -- Don't cast another defensive for 8s health_percentage_threshold_raw = 30, -- Cast if HP <= 30% health_percentage_threshold_incoming = 20 -- Or if predicted HP <= 20% } divine_shield:cast_defensive(me, filters, "Emergency Bubble") ``` -------------------------------- ### Create Log Folder and File Source: https://docs.project-sylvanas.net/dev/api/file-io Demonstrates creating a nested directory structure within the logs folder and initializing a log file. ```lua -- Creates: /scripts_log/my_addon/ core.create_log_folder("my_addon") -- Then you can create log files inside it core.create_log_file("my_addon/combat.log") core.write_log_file("my_addon/combat.log", "Addon started\n") ``` -------------------------------- ### Implement Plugin with Smart Defaults Source: https://docs.project-sylvanas.net/dev/api/plugin-helper Demonstrates setting up a menu with keybinds and using is_toggle_enabled to control rotation, interrupts, and burst mode logic. ```lua local plugin_helper = require("common/utility/plugin_helper") -- Menu setup with smart defaults local menu = { -- Key 7: ON by default, invisible until user changes it enable_rotation = core.menu.keybind(7, "enable_rotation", "Enable Rotation"), enable_interrupts = core.menu.keybind(7, "enable_interrupts", "Enable Interrupts"), -- Key 999: OFF by default, visible so user can enable enable_burst = core.menu.keybind(999, "enable_burst", "Burst Mode"), enable_experimental = core.menu.keybind(999, "enable_experimental", "Experimental Features"), -- Normal keybind: user must set it up manual_cooldowns = core.menu.keybind(0, "manual_cooldowns", "Manual Cooldowns"), } local function on_update() -- Always check rotation toggle first if not plugin_helper:is_toggle_enabled(menu.enable_rotation) then return end -- Run rotation... execute_rotation() -- Interrupts (on by default) if plugin_helper:is_toggle_enabled(menu.enable_interrupts) then check_interrupts() end -- Burst mode (user must enable) if plugin_helper:is_toggle_enabled(menu.enable_burst) then execute_burst() end end ``` -------------------------------- ### Checking Unit Classification Source: https://docs.project-sylvanas.net/dev/libraries/mini-libs/unit-helper Examples for identifying training dummies and blacklisted NPCs. ```lua local is_training_dummy = unit_helper:is_dummy(unit) if is_training_dummy then core.log("The unit is a training dummy.") end ``` ```lua local is_blacklisted = unit_helper:is_blacklist(npcID) if is_blacklisted then core.log("The NPC is blacklisted.") end ``` -------------------------------- ### Complete Window Begin Function Source: https://docs.project-sylvanas.net/dev/guides/custom-ui Full implementation of the window's begin function, integrating the color picker, centered title, highlight, and separators. ```lua test_window:begin(enums.window_enums.window_resizing_flags.RESIZE_BOTH_AXIS, true, color_picker_test:get_color(), color.new(0,0,0,0), enums.window_enums.window_cross_visuals.BLUE_THEME, function() test_window:add_menu_element_pos_offset(vec2.new(13, 13)) color_picker_test:render("BG Color") test_window:add_menu_element_pos_offset(vec2.new(-3, -3)) local title_text = "Barney's UI Mini Demo" -- With this function we get the exact X position offset required to add to the current dynamic position so the text is in the center of the window: local text_centered_x_pos = window:get_text_centered_x_pos(title_text) -- This function accepts a string, returns a number (which is the X offset) -- We add the X position offset that we just calculated, and also we adjust the Y position: window:add_menu_element_pos_offset(vec2.new(text_centered_x_pos, -32)) -- This function accepts a vec2, returns nothing (the parameter is the position offset) -- Finally, we just render the text on the dynamic position that we just set: window:add_text_on_dynamic_pos(color.green_pale(255), title_text) -- This function accepts a color and a string. This just renders the string with the color. local text_size = window:get_text_size(title_text) -- Now we render the rectangle to highlight the title: -- This function accepts start_position (vec2), end_position (vec2), color, rounding, thickness and extra flags. The extra flags are covered in the docs, in the function info. window:render_rect(vec2.new(text_centered_x_pos - text_size.x / 20 - 3, 12.0), vec2.new(text_centered_x_pos + text_size.x * 1.05 - 1, 37), color.white(100), 0, 1.0) -- We finished rendering the title, so let's add some separators: -- This function accepts the following parameters: separation from right offset (number), separation from left offset (number), y offset (number), width_offset (number) and color. window:add_separator(3.0, 3.0, 15.0, 0.0, color.new(100, 99, 150, 255)) window:add_separator(3.0, 3.0, 17.0, 0.0, color.new(100, 99, 150, 255)) end) ``` -------------------------------- ### Summon Pet by GUID Source: https://docs.project-sylvanas.net/dev/api/pet-battle Summons a non-combat companion pet using its unique GUID. ```lua core.pet_battle.summon_pet_by_guid(pet_id: string) -> nil ``` -------------------------------- ### Commodity Purchase Workflow Example Source: https://docs.project-sylvanas.net/dev/api/auction-house Demonstrates the sequence of initiating, confirming, or cancelling a commodity purchase. ```lua -- Purchase 200 of an herb (item ID 168586) core.auction_house.start_commodities_purchase(168586, 200) -- After verifying the price is acceptable core.auction_house.confirm_commodities_purchase() -- Or cancel if the price is too high -- core.auction_house.cancel_commodities_purchase() ``` -------------------------------- ### Session Metadata Export Format Source: https://docs.project-sylvanas.net/dev/examples/tbc-warlock-affliction Example of the session summary header generated during recording. ```lua -- Session duration: 3.7s -- Casts: 3 | Failed: 2 | Skipped: 6 session_start = 3675.20, -- game time when recording started export_time = 3678.86, -- game time when exported current_time = 3.66, -- session duration at export resource_name = "Soul Shards", -- class resource tracked ``` -------------------------------- ### Initialize Dependencies Source: https://docs.project-sylvanas.net/dev/examples/nav-follower Required modules for geometry, color, SDK interaction, and HUD utilities. ```lua local vec2 = require("common/geometry/vector_2") local color = require("common/color") local izi = require("common/izi_sdk") local plugin_helper = require("common/utility/plugin_helper") ``` -------------------------------- ### Basic Damage Rotation Setup Source: https://docs.project-sylvanas.net/dev/api/ts-override-helper Configure standard damage rotation settings, safe for use in on_update loops. ```lua local ts = require("common/utility/ts_override_helper") local W = ts.enums.weight local CTX = ts.enums.context local function setup_ts() ts:set_damage_enabled(true) ts:set_max_range_damage(40) ts:set_mode(ts.enums.mode.SILENT_AUTO) ts:set_weight(CTX.DAMAGE, W.TARGET, true, 2) ts:set_weight(CTX.DAMAGE, W.HIGHEST_MAX_HP, true, 1) end ``` -------------------------------- ### Delete a file in the WoW installation folder Source: https://docs.project-sylvanas.net/dev/api/file-io Deletes a file within the sandboxed World of Warcraft installation directory. ```lua local success = core.delete_file("_retail_/WTF/old_config.bak") if success then core.log("File deleted successfully") end ``` -------------------------------- ### Implement a complete event-driven plugin Source: https://docs.project-sylvanas.net/dev/api/events A full example showing the dispatch pattern, including handlers for no-arg, fixed-arg, and multi-arg events. ```lua -------------------------------------------------------------------------------- -- Game events demo -------------------------------------------------------------------------------- local handlers = {} -- Simple, no-arg events ------------------------------------------------------- function handlers.PLAYER_REGEN_DISABLED() core.log("[events] entered combat") end function handlers.PLAYER_REGEN_ENABLED() core.log("[events] left combat") end -- Fixed-arg event ------------------------------------------------------------- function handlers.ENCOUNTER_START(args) core.log(("[events] pull: %s (%d players)"):format(args[2] or "?", args[4] or 0)) end -- Many-arg event -------------------------------------------------------------- function handlers.COMBAT_LOG_EVENT_UNFILTERED(args) if args[2] == "SPELL_INTERRUPT" then core.log(("[events] %s interrupted %s"):format(args[5] or "?", args[9] or "?")) end end core.register_on_game_event_callback(function(event_name, args) local handler = handlers[event_name] if handler then handler(args) end end) core.log("[events] demo loaded") ``` -------------------------------- ### Importing the Dungeons Helper Module Source: https://docs.project-sylvanas.net/dev/libraries/mini-libs/dungeons-helper Required setup to include the module in your project. ```lua ---@type dungeons_helper local dungeons_helper = require("common/utility/dungeons_helper") ``` -------------------------------- ### Get recipe information Source: https://docs.project-sylvanas.net/dev/api/professions Retrieve a curated subset of information for a specific recipe. ```lua core.trade_skill.get_recipe_info(recipe_spell_id: integer, recipe_level?: integer) -> recipe_info | nil ``` -------------------------------- ### Create and write a data file Source: https://docs.project-sylvanas.net/dev/api/file-io Initializes a new file and writes content to it. ```lua core.create_data_file("settings.json") core.write_data_file("settings.json", "{}") ``` -------------------------------- ### Include Required Plugins Source: https://docs.project-sylvanas.net/dev/api/ui/control-panel Load the necessary utility modules for key handling and control panel functionality. ```lua ---@type key_helper local key_helper = require("common/utility/key_helper") ---@type control_panel_helper local control_panel_utility = require("common/utility/control_panel_helper") ```