### Sound Debugging: OnStartSound Source: https://github.com/nerve11/uczone-documentation/blob/main/uczone-docs/Starting Guide.txt Logs the initiation of a sound event. It verifies that sound callbacks are enabled before proceeding to print a message indicating that a sound has started. This function is a placeholder for more detailed sound event logging. ```Lua function debug.OnStartSound(obj) if not ui.callbacks.sound:Get() then return end print("OnStartSound") if ui.callbacks_settings.add_more_info:Get() then ``` -------------------------------- ### Particle Creation Notifications and Chat Source: https://github.com/nerve11/uczone-documentation/blob/main/uczone-docs/Starting Guide.txt Handles particle creation events, displaying information via chat messages and UI notifications. It checks global switches and particle notification settings before processing. Includes example data structure for particle events. ```Lua --#region Callbacks example.OnParticleCreate = function (data) if not ui.global_switch:Get() or not ui.particle_notif:Get() then return end --[[ data: { "index": "4", "entity_id": "-1", "fullName": "particles/units/heroes/hero_crystalmaiden/maiden_crystal_nova.vpcf", "hash": "3519047136", "particleNameIndex": "-2119646217882970990", "name": "maiden_crystal_nova", "attachType": "2", "entityForModifiers": "", "entity_for_modifiers_id": "214" } ]] if data.entityForModifiers then local str = ''.." "..data.fullName Chat.Print("ConsoleChat", str) --chat Notification ({ duration = 3, timer = 3, hero = Entity.GetUnitName(data.entityForModifiers), secondary_text = data.fullName, position = Entity.GetAbsOrigin(data.entityForModifiers) }) else Chat.Print("ConsoleChat", data.fullName) --chat Notification ({ duration = 3, timer = 3, primary_text = "Particle Create", primary_image = "panorama/images/emoticons/dotakin_roshan_stars_png.vtex_c", secondary_image = "\u{2b}", secondary_text = data.fullName }) end end --#endregion Callbacks ``` -------------------------------- ### Organized Callback Registration via Script Table (Lua) Source: https://github.com/nerve11/uczone-documentation/blob/main/uc.zone-documentation-HTML-format-v2.0/api-v2.0/Starting-Guide.md This example illustrates a more structured approach for managing multiple callbacks in larger Lua scripts. Functions are defined as methods of a local table, which is then returned, providing a clean way to register all necessary callbacks like 'OnUpdate'. ```Lua local script = {} function script.OnUpdate() print("OnUpdate") end return script ``` -------------------------------- ### Logging Sound Start Events in Lua Source: https://github.com/nerve11/uczone-documentation/blob/main/uc.zone-documentation-HTML-format-v2.0/api-v2.0/Starting-Guide.md The `OnStartSound` function is a callback designed to log details when a sound event begins. If enabled, it copies the sound object and prepares to add more information, useful for debugging audio cues in the game. ```Lua --#region Sound function debug.OnStartSound(obj) if not ui.callbacks.sound:Get() then return end print("OnStartSound") if ui.callbacks_settings.add_more_info:Get() then obj = table.copy(obj) ``` -------------------------------- ### World to Screen Rendering Source: https://github.com/nerve11/uczone-documentation/blob/main/uczone-docs/Starting Guide.txt Loads a font and implements logic to render world positions to screen coordinates. It checks if VBE render is enabled and if the hero is visible to enemies before attempting the conversion. ```lua local font = Render.LoadFont("MuseoSansEx", Enum.FontCreate.FONTFLAG_ANTIALIAS) local vbe_render = function () if not ui.vbe_render:Get() then return end local is_visible = NPC.IsVisibleToEnemies(my_hero) if not is_visible then return end local pos = Entity.GetAbsOrigin(my_hero) + Vector(0, 0, NPC.GetHealthBarOffset(my_hero)) local render_pos, pos_is_visible = Render.WorldToScreen(pos) if not pos_is_visible then return end ``` -------------------------------- ### Debugging Output Source: https://github.com/nerve11/uczone-documentation/blob/main/uczone-docs/Starting Guide.txt Illustrates how to use the `print` function for debugging in Lua, specifically to log tower names and their absolute origins. This helps in understanding game object properties during development. ```Lua -- print all towers names and their positions for _, tower in pairs(Towers.GetAll()) do print(NPC.GetUnitName(tower), Entity.GetAbsOrigin(tower)) end ``` -------------------------------- ### Render Text with Shadow Source: https://github.com/nerve11/uczone-documentation/blob/main/uczone-docs/Starting Guide.txt Demonstrates rendering text with a shadow effect in Lua. It calculates text size and position, then draws the text twice with different colors for the shadow and foreground. ```Lua local x, y = render_pos.x, render_pos.y - 80 local text = "Visible" local text_size = Render.TextSize(font, 30, text) x = x - text_size.x / 2 Render.Text(font, 30, text, Vec2(x + 1, y + 1), Color(0, 0, 0)) Render.Text(font, 30, text, Vec2(x, y), Color(255, 255, 255)) ``` -------------------------------- ### Auto Phase Boots Logic Source: https://github.com/nerve11/uczone-documentation/blob/main/uczone-docs/Starting Guide.txt Implements logic to automatically cast Phase Boots on the hero. It checks if the item is available, castable (mana permitting), and if the hero is currently running. ```lua local auto_phase = function () if not ui.auto_phase:Get() then return end local item = NPC.GetItem(my_hero, "item_phase_boots") if not item then return end if not Ability.IsCastable(item, NPC.GetMana(my_hero)) then return end if not NPC.IsRunning(my_hero) then return end Ability.CastNoTarget(item) return true end ``` -------------------------------- ### Debug Unit Order Preparation Source: https://github.com/nerve11/uczone-documentation/blob/main/uczone-docs/Starting Guide.txt Handles the `OnPrepareUnitOrders` callback, enriching the order object with NPC names, ability names, and order names if specific UI settings are enabled. It uses pre-computed reversed enums for order and issuer types. ```lua local flipped_order_enum = {} for i, v in pairs(Enum.UnitOrder) do flipped_order_enum[v] = i end local flipped_issuer_enum = {} for i, v in pairs(Enum.PlayerOrderIssuer) do flipped_issuer_enum[v] = i end function debug.OnPrepareUnitOrders(order) if not ui.callbacks.order:Get() then return end print("OnPrepareUnitOrders") if ui.callbacks_settings.add_more_info:Get() then order = table.copy(order) if (order.npc and Entity.IsNPC(order.npc)) then local unit_name = NPC.GetUnitName(order.npc) order["[m]npc_name"] = unit_name end if (order.target and Entity.IsNPC(order.target)) then local unit_name = NPC.GetUnitName(order.target) order["[m]target_name"] = unit_name end if (order.ability and Entity.IsAbility(order.ability)) then local ability_name = Ability.GetName(order.ability) order["[m]ability_name"] = ability_name end if (order.order) then local order_name = flipped_order_enum[order.order] if order_name then order["[m]order_name"] = order_name end end end print(order) add_divider() ``` -------------------------------- ### UI Element Creation and Configuration Source: https://github.com/nerve11/uczone-documentation/blob/main/uczone-docs/Starting Guide.txt This snippet demonstrates the creation and configuration of various UI elements using a custom menu API. It includes switches, sliders, and color pickers, along with callbacks for user interaction and disabling/enabling elements based on global settings. ```lua local example = {} --#region UI local tab = Menu.Create("General", "Main", "Example") tab:Icon("\u{f6b6}") local group = tab:Create("Main"):Create("Group") local ui = {} ui.global_switch = group:Switch("Global Switch", false, "\u{f00c}") ui.auto_phase = group:Switch("Auto Phase Boots", true, "panorama/images/items/phase_boots_png.vtex_c") ui.custom_radius = group:Slider("Custom Radius", 0, 1000, 0, function (value) if value == 0 then return "Disabled" end return tostring(value) end) ui.custom_radius:Icon("\u{f1ce}") ui.radius_color = group:ColorPicker("Radius Color", Color(255, 255, 255), "\u{f53f}") ui.vbe_render = group:Switch("VBE Render", false, "\u{f06e}") ui.particle_notif = group:Switch("Particle Notification", false, "\u{f0f3}") ui.global_switch:SetCallback(function () ui.auto_phase:Disabled(not ui.global_switch:Get()) ui.custom_radius:Disabled(not ui.global_switch:Get()) ui.radius_color:Disabled(not ui.global_switch:Get()) ui.vbe_render:Disabled(not ui.global_switch:Get()) ui.particle_notif:Disabled(not ui.global_switch:Get()) end, true) --#endregion UI ``` -------------------------------- ### Debug Draw and Update Logic Source: https://github.com/nerve11/uczone-documentation/blob/main/uczone-docs/Starting Guide.txt Defines functions for handling drawing and updating events in a debug context. It checks a UI setting to determine whether to execute the main processing logic. ```lua function debug.OnDraw() if not ui.inworld_settings.on_draw:Get() then return end inworld_processing() end function debug.OnUpdate() if ui.inworld_settings.on_draw:Get() then return end inworld_processing() end return debug ``` -------------------------------- ### Lua Example: Get Hero's Forward Position Source: https://github.com/nerve11/uczone-documentation/blob/main/uczone-docs/Core/Entity.txt This Lua script demonstrates how to get the local hero's rotation and position, calculate a point 100 units in front of the hero, and draw a circle on screen at that calculated position if it's visible. ```lua -- forward_pos.lua return { -- get local hero's forward position and draw a circle around it OnUpdate = function () local hero = Heroes.GetLocal(); local rotation = Entity.GetRotation(hero); -- forward_direction is a vector that points 100 units in direction of my hero's rotation local forward_direction = rotation:GetForward():Normalized():Scaled(100); -- add forward_direction to my hero's position to get the forward position local forward_pos = Entity.GetAbsOrigin(hero) + forward_direction; -- screen_x and screen_y are the coordinates of forward_pos on the screen local screen_x, screen_y, is_on_screen = Renderer.WorldToScreen(forward_pos); if is_on_screen then -- draw a circle around the position Renderer.SetDrawColor(255, 255, 255, 255); Renderer.DrawFilledCircle(screen_x, screen_y, 10, 10); -- result: https://i.imgur.com/ERf1Pxk.png end end } ``` -------------------------------- ### Drawing and Update Logic Source: https://github.com/nerve11/uczone-documentation/blob/main/uczone-docs/Starting Guide.txt Contains logic for drawing updates and main game loop updates. The drawing function checks global switches and hero availability. The update function manages a global switch, particle cleanup, hero initialization, custom radius calculations, and auto-phase checks. ```Lua example.OnDraw = function () if not ui.global_switch:Get() or not my_hero then return end vbe_render() end example.OnUpdate = function () if not ui.global_switch:Get() then if particle then Particle.Destroy(particle) particle = nil end return end if not my_hero then my_hero = Heroes.GetLocal(); return end custom_radius() if auto_phase() then return end end ``` -------------------------------- ### Projectile Debugging: OnProjectile Source: https://github.com/nerve11/uczone-documentation/blob/main/uczone-docs/Starting Guide.txt Handles general projectile events, logging projectile data. If additional information is enabled, it enriches the projectile data with source and target unit names if they are NPCs. This is useful for tracking projectile behavior and origins. ```Lua function debug.OnProjectile(proj) -- range autoatacks, target abilities if not ui.callbacks.projectile:Get() then return end print("OnProjectile") if ui.callbacks_settings.add_more_info:Get() then proj = table.copy(proj) if (proj.source and Entity.IsNPC(proj.source)) then local unit_name = NPC.GetUnitName(proj.source) proj["[m]unit_name"] = unit_name end if (proj.target and Entity.IsNPC(proj.target)) then local unit_name = NPC.GetUnitName(proj.target) proj["[m]target_name"] = unit_name end end print(proj) add_divider() end ``` -------------------------------- ### Logging Unit Animation Events in Lua Source: https://github.com/nerve11/uczone-documentation/blob/main/uc.zone-documentation-HTML-format-v2.0/api-v2.0/Starting-Guide.md The `OnUnitAnimation` and `OnUnitAnimationEnd` functions are callbacks that trigger when a unit's animation starts or ends. If enabled, they copy the event data and add the unit's name for more context before printing the event details to the console. ```Lua --#region Animation function debug.OnUnitAnimation(a) if not ui.callbacks.animation:Get() then return end print("OnUnitAnimation") if (ui.callbacks_settings.add_more_info:Get() and a.unit and Entity.IsNPC(a.unit)) then a = table.copy(a) local unit_name = NPC.GetUnitName(a.unit) a["[m]unit_name"] = unit_name end print(a) add_divider() end function debug.OnUnitAnimationEnd(a) if not ui.callbacks.animation:Get() then return end print("OnUnitAnimationEnd") if (ui.callbacks_settings.add_more_info:Get() and a.unit and Entity.IsNPC(a.unit)) then a = table.copy(a) local unit_name = NPC.GetUnitName(a.unit) a["[m]unit_name"] = unit_name end print(a) add_divider() end --#endregion ``` -------------------------------- ### Render NPC States and Durations Source: https://github.com/nerve11/uczone-documentation/blob/main/uczone-docs/Starting Guide.txt This snippet demonstrates how to check NPC states, render state names if present, and display the duration of modifier states. It iterates through predefined states and formats the output for display. ```lua local has_state = NPC.HasState(unit, state_value) if (has_state) then local text = state_name Render.Text(font, font_size, text, screen_pos, text_color) screen_pos = screen_pos + Vec2(0, line_height) end -- ... (rest of the first code block) local payload = {} for i = 0, Enum.ModifierState.MODIFIER_STATE_LAST, 1 do payload[i] = true end local states = NPC.GetStatesDuration(unit, payload, false) for mod_state, duration in pairs(states) do if (duration > 0.0) then local name = flipped_modstate_enum[mod_state] if (name) then local text = ("%s: %.2f"):format(name, duration) Render.Text(font, font_size, text, screen_pos, text_color) screen_pos = screen_pos + Vec2(0, line_height) end end end ``` -------------------------------- ### Custom Radius Particle Rendering Source: https://github.com/nerve11/uczone-documentation/blob/main/uczone-docs/Starting Guide.txt Handles the creation and updating of a custom radius particle effect around the hero. It manages particle destruction, creation, and setting control points for radius size and color based on UI inputs. ```lua local custom_radius = function () if ui.custom_radius:Get() == 0 or need_update_particle or not Entity.IsAlive(my_hero) then Particle.Destroy(particle) particle = nil need_update_particle = false return end if not particle then particle = Particle.Create("particles/ui_mouseactions/drag_selected_ring.vpcf", Enum.ParticleAttachment.PATTACH_ABSORIGIN_FOLLOW, my_hero) Particle.SetControlPoint(particle, 2, Vector(ui.custom_radius:Get(), 255, 255)) local color = ui.radius_color:Get() color = Vector(color.r, color.g, color.b) Particle.SetControlPoint(particle, 1, color) end if particle and need_update_color then local color = ui.radius_color:Get() color = Vector(color.r, color.g, color.b) Particle.SetControlPoint(particle, 1, color) end end ``` -------------------------------- ### In-World Unit Information Rendering Source: https://github.com/nerve11/uczone-documentation/blob/main/uczone-docs/Starting Guide.txt Renders various details about units (NPCs or Heroes) directly in the game world based on UI settings. It can display unit names, positions, modifiers, abilities, items, and modifier states, checking for screen visibility. ```lua local text_color = Color(255, 255, 255, 255) local font_size = 14 local line_height = 18 local floor = math.floor local flipped_modstate_enum = {} for i, v in pairs(Enum.ModifierState) do flipped_modstate_enum[v] = i end local function inworld_processing() if not ui.inworld.global_switch:Get() then return end local render_names = ui.inworld.name:Get() local render_position = ui.inworld.position:Get() local render_modifiers = ui.inworld.modifier:Get() local render_abilities = ui.inworld.ability:Get() local render_items = ui.inworld.item:Get() local render_modifier_state = ui.inworld.modifier_state:Get() local render_modifier_state_duration = ui.inworld.modifier_state_duration:Get() local list = ui.inworld.hero_only:Get() and Heroes.GetAll() or NPCs.GetAll() for i, unit in pairs(list) do if unit then local pos = Entity.GetAbsOrigin(unit) local screen_pos, is_visible = pos:ToScreen() if not is_visible then goto continue end if render_names then local text = ("%s | %s | %d"):format( Entity.GetClassName(unit), Entity.GetClassName(unit), Entity.GetIndex(unit) ) Render.Text(font, font_size, text, screen_pos, text_color) screen_pos = screen_pos + Vec2(0, line_height) end if render_position then local text = ("%d, %d, %d"):format( floor(pos.x), floor(pos.y), floor(pos.z) ) Render.Text(font, font_size, text, screen_pos, text_color) screen_pos = screen_pos + Vec2(0, line_height) end if render_modifiers then local modifiers = NPC.GetModifiers(unit) if modifiers then for _, mod in pairs(modifiers) do local text = Modifier.GetName(mod) Render.Text(font, font_size, text, screen_pos, text_color) screen_pos = screen_pos + Vec2(0, line_height) end end end if render_abilities then for i = 0, 25 do local ab = NPC.GetAbilityByIndex(unit, i) if ab then local text = ("%d: %s"):format(i, Ability.GetName(ab)) Render.Text(font, font_size, text, screen_pos, text_color) screen_pos = screen_pos + Vec2(0, line_height) end end end if render_items then for i = 0, 20 do local item = NPC.GetItemByIndex(unit, i) if item then local text = ("%d: %s"):format(i, Ability.GetName(item)) Render.Text(font, font_size, text, screen_pos, text_color) screen_pos = screen_pos + Vec2(0, line_height) end end end if render_modifier_state then for state_name, state_value in pairs(Enum.ModifierState) do ``` -------------------------------- ### Basic Callback Registration (Lua) Source: https://github.com/nerve11/uczone-documentation/blob/main/uc.zone-documentation-HTML-format-v2.0/api-v2.0/Starting-Guide.md This snippet demonstrates the fundamental structure for registering a single callback function in a Lua script. The script returns a table where the key is the callback name and the value is the function handler, allowing the Uczone environment to invoke it. ```Lua return { CallbackName = FuncHandler, } ``` -------------------------------- ### Register Callback Function Source: https://github.com/nerve11/uczone-documentation/blob/main/uczone-docs/Starting Guide.txt Shows the required table format for registering callback functions in Lua scripts. The script must return a table where keys are callback names and values are handler functions. This is essential for the script to be recognized and executed by the system. ```lua return { CallbackName = FuncHandler, } ``` ```lua -- much more convenient way for big scripts local script = {} function script.OnUpdate() print("OnUpdate") end return script ``` ```lua return { OnUpdate = function() print("OnUpdate") end, } ``` -------------------------------- ### Debug Script for Game Events Source: https://github.com/nerve11/uczone-documentation/blob/main/uczone-docs/Starting Guide.txt This Lua script provides a comprehensive debugging UI for game events. It allows users to enable/disable logging for various game elements like modifiers, animations, and entity changes. It relies on a game-specific API for UI creation and event handling. ```lua ---@diagnostic disable: undefined-global, param-type-mismatch, inject-field local debug = {} local tab = Menu.Create("General", "Debug", "Debug", "Debug") local inworld_group = tab:Create("In-World") local callbacks_group = tab:Create("Callbacks") local inworld_settings_group = tab:Create("In-World Settings", 1) local callbacks_settings_group = tab:Create("Callbacks Settings", 2) --#region UI local ui = {} ui.inworld = {} ui.inworld.global_switch = inworld_group:Switch("In-World Enabled", false) ui.inworld.name = inworld_group:Switch("Unit Name", false) ui.inworld.position = inworld_group:Switch("Unit Position", false) ui.inworld.modifier = inworld_group:Switch("Modifiers", false) ui.inworld.ability = inworld_group:Switch("Abilities", false) ui.inworld.item = inworld_group:Switch("Items", false) ui.inworld.modifier_state = inworld_group:Switch("Modifier State", false) ui.inworld.modifier_state_duration = inworld_group:Switch("Modifier State Duration", false) ui.inworld_settings = {} ui.inworld_settings.hero_only = inworld_settings_group:Switch("Only heroes", true) ui.inworld_settings.on_draw = inworld_settings_group:Switch("Render in OnDraw \a{primary}fps drop", false) ui.callbacks = {} ui.callbacks.modifier = callbacks_group:Switch("Modifier", false) ui.callbacks.animation = callbacks_group:Switch("Animation", false) ui.callbacks.add_entity = callbacks_group:Switch("Entity Create/Remove", false) ui.callbacks.projectile = callbacks_group:Switch("Projectile", false) ui.callbacks.particle = callbacks_group:Switch("Particle", false) ui.callbacks.gesture = callbacks_group:Switch("Gesture", false) ui.callbacks.sound = callbacks_group:Switch("Sound", false) ui.callbacks.order = callbacks_group:Switch("Unit Order", false) ui.callbacks_settings = {} ui.callbacks_settings.divider = callbacks_settings_group:Switch("Add 'divider' in the end of the log message", true) ui.callbacks_settings.add_more_info = callbacks_settings_group:Switch("More info. Starts with [m] prefix", true) --#endregion local font = Render.LoadFont("Arial", 0, 500) local function add_divider() if ui.callbacks_settings.divider:Get() then print("+---+---+---+---+---+---+---+") end end -- we can't modify the original table in callbacks, so we need to copy it to add more info function table.copy(t) local u = { } for k, v in pairs(t) do u[k] = v end return u end --#region Callbacks --#region Modifier function debug.OnModifierCreate(ent, mod) if not ui.callbacks.modifier:Get() then return end print("OnModifierCreate") local modifier_name = Modifier.GetName(mod) local owner = Ability.GetOwner(Modifier.GetAbility(mod)) local owner_name = NPC.GetUnitName(owner) print(('%s | %s -> %s'):format(modifier_name, owner_name, NPC.GetUnitName(ent))) add_divider() end function debug.OnModifierDestroy(ent, mod) if not ui.callbacks.modifier:Get() then return end print("OnModifierDestroy") local modifier_name = Modifier.GetName(mod) local owner = Ability.GetOwner(Modifier.GetAbility(mod)) local owner_name = NPC.GetUnitName(owner) print(('%s | %s -> %s'):format(modifier_name, owner_name, NPC.GetUnitName(ent))) add_divider() end --#endregion --#region Animation function debug.OnUnitAnimation(a) if not ui.callbacks.animation:Get() then return end print("OnUnitAnimation") if (ui.callbacks_settings.add_more_info:Get() and a.unit and Entity.IsNPC(a.unit)) then a = table.copy(a) local unit_name = NPC.GetUnitName(a.unit) a["[m]unit_name"] = unit_name end print(a) add_divider() end function debug.OnUnitAnimationEnd(a) if not ui.callbacks.animation:Get() then return end print("OnUnitAnimationEnd") if (ui.callbacks_settings.add_more_info:Get() and a.unit and Entity.IsNPC(a.unit)) then a = table.copy(a) local unit_name = NPC.GetUnitName(a.unit) a["[m]unit_name"] = unit_name end print(a) add_divider() end --#endregion --#region EntityCreate function debug.OnEntityCreate(entity) if not ui.callbacks.add_entity:Get() then return end print('OnEntityCreate') -- can't use NPC.GetUnitNameor Abilit.GetName because entity is not fully filled in the first tick local type = (function () if Entity.IsAbility(entity) then return "Ability" elseif Entity.IsNPC(entity) then return "NPC" elseif Entity.IsPlayer(entity) then return "Player" else return "Entity" end end)() print(('%s | %s | %d'):format(type, Entity.GetClassName(entity), Entity.GetIndex(entity))) add_divider() end function debug.OnEntityDestroy(entity) ``` -------------------------------- ### Inline Callback Registration with Anonymous Functions (Lua) Source: https://github.com/nerve11/uczone-documentation/blob/main/uc.zone-documentation-HTML-format-v2.0/api-v2.0/Starting-Guide.md This snippet presents an alternative, concise method for registering callbacks directly within the returned table using anonymous functions. This is suitable for simple callback implementations, such as the 'OnUpdate' function shown here. ```Lua return { OnUpdate = function() print("OnUpdate") end, } ``` -------------------------------- ### Variable Management and UI Callbacks Source: https://github.com/nerve11/uczone-documentation/blob/main/uczone-docs/Starting Guide.txt Manages game-related variables like `my_hero` and particle states. It sets up callbacks for UI elements to update these variables, including logic to disable color pickers based on slider values and trigger particle updates. ```lua --#endregion Vars local my_hero = nil local particle = nil local need_update_particle = false local need_update_color = false ui.custom_radius:SetCallback(function () need_update_particle = true if ui.global_switch:Get() then ui.radius_color:Disabled(ui.custom_radius:Get() == 0) end end, true) ui.radius_color:SetCallback(function () need_update_color = true end) ``` -------------------------------- ### Projectile Debugging: OnLinearProjectileCreate Source: https://github.com/nerve11/uczone-documentation/blob/main/uczone-docs/Starting Guide.txt Logs the creation of linear projectiles, such as Mirana's arrow. It checks if projectile callbacks are enabled and optionally adds source NPC unit names to the projectile data. This helps in debugging specific projectile types. ```Lua function debug.OnLinearProjectileCreate(proj) -- mirana's arrow if not ui.callbacks.projectile:Get() then return end print("OnLinearProjectileCreate") if ui.callbacks_settings.add_more_info:Get() then proj = table.copy(proj) if (proj.source and Entity.IsNPC(proj.source)) then local unit_name = NPC.GetUnitName(proj.source) proj["[m]unit_name"] = unit_name end end print(proj) add_divider() end ``` -------------------------------- ### Logging Projectile Events in Lua Source: https://github.com/nerve11/uczone-documentation/blob/main/uc.zone-documentation-HTML-format-v2.0/api-v2.0/Starting-Guide.md This set of functions (`OnProjectile`, `OnLinearProjectileCreate`, `OnProjectileLoc`) handles various projectile-related events. They log details about projectiles, including their source and target unit names if available, providing insights into ranged attacks and abilities. ```Lua --#region Projectile function debug.OnProjectile(proj) -- range autoatacks, target abilities if not ui.callbacks.projectile:Get() then return end print("OnProjectile") if ui.callbacks_settings.add_more_info:Get() then proj = table.copy(proj) if (proj.source and Entity.IsNPC(proj.source)) then local unit_name = NPC.GetUnitName(proj.source) proj["[m]unit_name"] = unit_name end if (proj.target and Entity.IsNPC(proj.target)) then local unit_name = NPC.GetUnitName(proj.target) proj["[m]target_name"] = unit_name end end print(proj) add_divider() end function debug.OnLinearProjectileCreate(proj) -- mirana's arrow if not ui.callbacks.projectile:Get() then return end print("OnLinearProjectileCreate") if ui.callbacks_settings.add_more_info:Get() then proj = table.copy(proj) if (proj.source and Entity.IsNPC(proj.source)) then local unit_name = NPC.GetUnitName(proj.source) proj["[m]unit_name"] = unit_name end end print(proj) add_divider() end function debug.OnProjectileLoc(proj) if not ui.callbacks.projectile:Get() then return end -- tinker's rockets print("OnProjectileLoc") print(proj) add_divider() end --#endregion ``` -------------------------------- ### Debugging: Printing All Tower Names and Positions in Lua Source: https://github.com/nerve11/uczone-documentation/blob/main/uc.zone-documentation-HTML-format-v2.0/api-v2.0/Starting-Guide.md This debugging snippet iterates through all available towers in the game. For each tower, it prints its unit name and absolute origin (position) to the console, which is useful for verifying tower locations or debugging game state. ```Lua for _, tower in pairs(Towers.GetAll()) do print(NPC.GetUnitName(tower), Entity.GetAbsOrigin(tower)) end ``` -------------------------------- ### Particle Debugging: OnParticleCreate Source: https://github.com/nerve11/uczone-documentation/blob/main/uczone-docs/Starting Guide.txt Handles the creation of particle effects. It checks for particle callback enablement and, if enhanced info is on, associates NPC unit names with the particle's entity and entityForModifiers. It also stores the particle name using its index for later reference. ```Lua local particle_name_map = {} function debug.OnParticleCreate(prt) if not ui.callbacks.particle:Get() then return end print("OnParticleCreate") if ui.callbacks_settings.add_more_info:Get() then prt = table.copy(prt) if (prt.entity and Entity.IsNPC(prt.entity)) then local unit_name = NPC.GetUnitName(prt.entity) prt["[m]entity_name"] = unit_name end if (prt.entityForModifiers and Entity.IsNPC(prt.entityForModifiers)) then local unit_name = NPC.GetUnitName(prt.entityForModifiers) prt["[m]entityForModifiers_name"] = unit_name end particle_name_map[prt.index] = prt.name end print(prt) add_divider() end ``` -------------------------------- ### Rendering Centered Text with Shadow in Lua Source: https://github.com/nerve11/uczone-documentation/blob/main/uc.zone-documentation-HTML-format-v2.0/api-v2.0/Starting-Guide.md This snippet demonstrates how to render text on the screen with a shadow effect. It calculates the text size to center it horizontally and then draws the text twice: first in black slightly offset for the shadow, and then in white at the main position for the foreground. ```Lua local text_size = Render.TextSize(font, 30, text) x = x - text_size.x / 2 Render.Text(font, 30, text, Vec2(x + 1, y + 1), Color(0, 0, 0)) Render.Text(font, 30, text, Vec2(x, y), Color(255, 255, 255)) end ``` -------------------------------- ### Example: Get Entity by Index - Lua Source: https://github.com/nerve11/uczone-documentation/blob/main/uc.zone-documentation-HTML-format-v2.0/api-v2.0/game-components/core/entity/Entity___API_v2.0.html This example demonstrates how to retrieve an entity using its game index. It gets the local hero, retrieves its index, then uses `Entity.Get()` with that index to obtain the entity, asserting that the retrieved entity is the same as the original hero. ```Lua -- get_by_index.lua local hero = Heroes.GetLocal(); local index = Entity.GetIndex(hero); local entity_by_index = Entity.Get(index); assert(hero == entity_by_index, "Entity.Get() is broken!"); -- true ``` -------------------------------- ### GetStockCount Example Source: https://github.com/nerve11/uczone-documentation/blob/main/uczone-docs/Game Engine/GameRules.txt Demonstrates how to get the available stock count for an item using its ID. ```lua -- "item_ward_observer": { -- "ID": "42", Log.Write("Observers available: " .. GameRules.GetStockCount(42)) } ``` -------------------------------- ### Initializing Debug UI Menu in Lua Source: https://github.com/nerve11/uczone-documentation/blob/main/uc.zone-documentation-HTML-format-v2.0/api-v2.0/Starting-Guide.md This snippet initializes the main debug menu and its sub-groups for in-world and callback settings. It creates various UI switches to enable or disable specific debug logging features, allowing users to control what information is displayed during gameplay. ```Lua ---@diagnostic disable: undefined-global, param-type-mismatch, inject-field local debug = {} local tab = Menu.Create("General", "Debug", "Debug", "Debug") local inworld_group = tab:Create("In-World") local callbacks_group = tab:Create("Callbacks") local inworld_settings_group = tab:Create("In-World Settings", 1) local callbacks_settings_group = tab:Create("Callbacks Settings", 2) --#region UI local ui = {} ui.inworld = {} ui.inworld.global_switch = inworld_group:Switch("In-World Enabled", false) ui.inworld.name = inworld_group:Switch("Unit Name", false) ui.inworld.position = inworld_group:Switch("Unit Position", false) ui.inworld.modifier = inworld_group:Switch("Modifiers", false) ui.inworld.ability = inworld_group:Switch("Abilities", false) ui.inworld.item = inworld_group:Switch("Items", false) ui.inworld.modifier_state = inworld_group:Switch("Modifier State", false) ui.inworld.modifier_state_duration = inworld_group:Switch("Modifier State Duration", false) ui.inworld_settings = {} ui.inworld_settings.hero_only = inworld_settings_group:Switch("Only heroes", true) ui.inworld_settings.on_draw = inworld_settings_group:Switch("Render in OnDraw \a{primary}fps drop", false) ui.callbacks = {} ui.callbacks.modifier = callbacks_group:Switch("Modifier", false) ui.callbacks.animation = callbacks_group:Switch("Animation", false) ui.callbacks.add_entity = callbacks_group:Switch("Entity Create/Remove", false) ui.callbacks.projectile = callbacks_group:Switch("Projectile", false) ui.callbacks.particle = callbacks_group:Switch("Particle", false) ui.callbacks.gesture = callbacks_group:Switch("Gesture", false) ui.callbacks.sound = callbacks_group:Switch("Sound", false) ui.callbacks.order = callbacks_group:Switch("Unit Order", false) ui.callbacks_settings = {} ui.callbacks_settings.divider = callbacks_settings_group:Switch("Add 'divider' in the end of the log message", true) ui.callbacks_settings.add_more_info = callbacks_settings_group:Switch("More info. Starts with [m] prefix", true) --#endregion ``` -------------------------------- ### Getting Ability Override Cast Point (Lua) Source: https://github.com/nerve11/uczone-documentation/blob/main/uc.zone-documentation-HTML-format-v2.0/api-v2.0/game-components/core/ability/Ability___API_v2.0.html Returns the overridden cast point value (as a 'number') for the specified 'ability', for example, due to Arcane Blink. ```Lua Ability.GetOverrideCastPoint(ability): number ``` -------------------------------- ### APIDOC: OnStartSound Callback Source: https://github.com/nerve11/uczone-documentation/blob/main/uczone-docs/Callbacks.txt Documentation for the OnStartSound callback, which is triggered when a sound event begins. It provides details about the sound, including its source entity, hash, GUID, seed, name, and position. ```APIDOC Callbacks.OnStartSound(data) - Called when sound is started. - Parameters: - data (table): The data about the event. - source? ([CEntity](../game-components/core/entity)): The source of sound. (default: nil) - hash (integer): The hash of sound. - guid (integer): The guid of sound. - seed (integer): The seed of sound. - name (string): The name of sound. - position ([Vector](classes/math/vector)): The position of sound. - Returns: nil ``` -------------------------------- ### Example: Calculating Forward Position and Drawing - Lua Source: https://github.com/nerve11/uczone-documentation/blob/main/uc.zone-documentation-HTML-format-v2.0/api-v2.0/game-components/core/entity/Entity___API_v2.0.html This example demonstrates how to calculate an entity's forward position based on its rotation and then draw a circle at that screen position. It uses `Entity.GetRotation()` to get the hero's orientation, calculates a forward vector, and then uses `Renderer.WorldToScreen()` to convert the world position to screen coordinates for drawing. ```Lua -- forward_pos.lua return { -- get local hero's forward position and draw a circle around it OnUpdate = function () local hero = Heroes.GetLocal(); local rotation = Entity.GetRotation(hero); -- forward_direction is a vector that points 100 units in direction of my hero's rotation local forward_direction = rotation:GetForward():Normalized():Scaled(100); -- add forward_direction to my hero's position to get the forward position local forward_pos = Entity.GetAbsOrigin(hero) + forward_direction; -- screen_x and screen_y are the coordinates of forward_pos on the screen local screen_x, screen_y, is_on_screen = Renderer.WorldToScreen(forward_pos); if is_on_screen then -- draw a circle around the position Renderer.SetDrawColor(255, 255, 255, 255); Renderer.DrawFilledCircle(screen_x, screen_y, 10, 10); -- result: https://i.imgur.com/ERf1Pxk.png end end } ``` -------------------------------- ### CreateConfig Lua Example Source: https://github.com/nerve11/uczone-documentation/blob/main/uczone-docs/Game Engine/Engine.txt Example demonstrating how to use the Engine.CreateConfig function in Lua to define hero grid configurations with multiple categories. ```lua Engine.CreateConfig("From lua", { { name = "55%+", hero_ids = {1, 2, 3, 4}, x = 0.0, y = 0.0, width = 300.0, height = 200.0 }, { name = "52%+", hero_ids = {5, 6}, x = 350.0, y = 0.0, width = 300.0, height = 200.0 } }); ``` -------------------------------- ### Getting Ability Cast Start Time (Lua) Source: https://github.com/nerve11/uczone-documentation/blob/main/uc.zone-documentation-HTML-format-v2.0/api-v2.0/game-components/core/ability/Ability___API_v2.0.html Returns the game time (as a 'number') when the specified 'ability' will be cast. This method requires the ability to be in its cast state when called. ```Lua Ability.GetCastStartTime(ability): number ``` -------------------------------- ### Getting Ability Toggle State (Lua) Source: https://github.com/nerve11/uczone-documentation/blob/main/uc.zone-documentation-HTML-format-v2.0/api-v2.0/game-components/core/ability/Ability___API_v2.0.html Retrieves the toggle state of the specified 'ability', for example, Medusa's Shield. Returns 'true' if toggled on, 'false' if toggled off. ```Lua Ability.GetToggleState(ability): boolean ``` -------------------------------- ### Performing a GET HTTP Request in Lua Source: https://github.com/nerve11/uczone-documentation/blob/main/uc.zone-documentation-HTML-format-v2.0/api-v2.0/game-components/networking-and-apis/http/HTTP___API_v2.0.html This Lua example demonstrates how to make a GET request to a specified URL using `HTTP.Request`. It includes setting custom headers, defining a callback function to process the response (including status code, headers, and body), and parsing the JSON response to extract specific data. The `JSON` module is required for parsing. ```Lua -- http_request.lua local url = "https://reqres.in/api/users/2"; local headers = { ["User-Agent"] = "Umbrella/1.0", ['Connection'] = 'Keep-Alive', } local JSON = require('assets.JSON') local callback = function(response) Log.Write(response["response"]); Log.Write(response["code"]); Log.Write(response["header"]); Log.Write(response["param"]); local json = JSON:decode(response["response"]); Log.Write(json["data"]["email"]); end HTTP.Request("GET", url, { headers = headers, }, callback, "reqres_get"); ``` -------------------------------- ### Lua Example: Get Cursor Position Source: https://github.com/nerve11/uczone-documentation/blob/main/uczone-docs/Game Engine/Input.txt A simple Lua code snippet demonstrating how to retrieve the screen cursor's X and Y coordinates using the Input.GetCursorPos() function. ```lua local x, y = Input.GetCursorPos() ``` -------------------------------- ### Getting Ability Channel Start Time (Lua) Source: https://github.com/nerve11/uczone-documentation/blob/main/uc.zone-documentation-HTML-format-v2.0/api-v2.0/game-components/core/ability/Ability___API_v2.0.html Returns the game time (as a 'number') when the channeling of the specified 'ability' will begin. This method requires the ability to be in its cast state when called. ```Lua Ability.GetChannelStartTime(ability): number ``` -------------------------------- ### Engine.SetQuickBuy() - Manage Quick Buy List Source: https://github.com/nerve11/uczone-documentation/blob/main/uczone-docs/Game Engine/Engine.txt Adds an item to the quick buy list. Optionally resets the list before adding. ```APIDOC Engine.SetQuickBuy(item_name: string, reset: boolean = true): nil - Adds an item to the quick buy list. - Parameters: - item_name: The name of the item to quick buy (e.g., `blink`, `relic`). - reset: Optional. If true, resets the quick buy list before adding the item. Defaults to true. ``` -------------------------------- ### Gesture Debugging: OnUnitAddGesture Source: https://github.com/nerve11/uczone-documentation/blob/main/uczone-docs/Starting Guide.txt Logs when a gesture is added to a unit. It first checks if gesture callbacks are enabled. If so, it prints a message indicating the event and the gesture data associated with the unit. ```Lua function debug.OnUnitAddGesture(a) if not ui.callbacks.gesture:Get() then return end print("OnUnitAddGesture") print(a) add_divider() end ``` -------------------------------- ### Getting Attachment Position of NPC (Lua) Source: https://github.com/nerve11/uczone-documentation/blob/main/uc.zone-documentation-HTML-format-v2.0/api-v2.0/game-components/core/npc/NPC___API_v2.0.html Retrieves the 3D vector position of a named attachment point on the specified Non-Player Character. Examples include 'attach_hitloc' for hit locations. ```Lua NPC.GetAttachment(npc, name) ``` -------------------------------- ### Getting Item Initial Charges in Lua Source: https://github.com/nerve11/uczone-documentation/blob/main/uc.zone-documentation-HTML-format-v2.0/api-v2.0/game-components/core/item/Item___API_v2.0.html This function returns the initial number of charges an item has when acquired. For example, a Bottle might have 3 initial charges, and Dust of Appearance 1. ```Lua Item.GetInitialCharges(item): integer ``` -------------------------------- ### SetStyle Example Source: https://github.com/nerve11/uczone-documentation/blob/main/uczone-docs/Rendering & Visuals/Panorama/UIPanel.txt Demonstrates how to apply custom CSS styles to a panel using the SetStyle method in Lua. ```Lua local css_like_table = { ["horizontal-align"] = "center", ["vertical-align"] = "center", ["transform"] = "translate3d( 0px, -0px, 0px ) scale3d(1, 1, 1)", ["padding-left"] = "0px", ["margin"] = "0px", ["border-radius"] = "4px", ["background-color"] = "none", ["box-shadow"] = "none", ["color"] = "gradient( linear, 0% 100%, 0% 0%, from( #ff00FF ), to( #5C9C68 ) )", ["font-size"] = "20px", ["text-align"] = "center", ["text-decoration"] = "none", ["background-size"] = "0% 0%", ["opacity-mask"] = 'url("s2r://panorama/images/masks/hudchat_mask_psd.vtex") 1.0', ["hue-rotation"] = "-10deg", ["text-shadow"] = "2px 2px #111111b0", ["blur"] = "gaussian(0px)", ["line-height"] = "120%", ["font-family"] = "Radiance", ["border-brush"] = "gradient( linear, 0% 0%, 0% 100%, from( #96c5ff96 ), to( #12142d2d ) )", } local function css_to_string(tbl) local str = "" for k, v in pairs(tbl) do str = str .. k .. ": " .. v .. "; " end return str; end local health_label = Panorama.GetPanelByName("HealthLabel"); if (health_label) then health_label:SetStyle(css_to_string(css_like_table)) end ``` -------------------------------- ### Getting Ally NPCs in Radius (Lua) Source: https://github.com/nerve11/uczone-documentation/blob/main/uc.zone-documentation-HTML-format-v2.0/api-v2.0/game-components/core/entity/Entity___API_v2.0.html This example shows how to use `Entity.GetUnitsInRadius()` to find all allied NPCs within a 1200 radius of the local hero. It specifies `Enum.TeamType.TEAM_FRIEND` to filter for allies. ```Lua local hero = Heroes.GetLocal() -- get all ally NPCs in 1200 radius local units_around = Entity.GetUnitsInRadius(hero, 1200, Enum.TeamType.TEAM_FRIEND) for i = 1, #units_around do local unit = units_around[i]; Log.Write(NPC.GetUnitName(unit) .. " is near!"); end ```