Evade Helper
Overview
The Evade Helper provides an API for adding custom danger zones to the evade system. You can define circles, rectangles, and cones that the evade system will recognize and avoid. This is useful for adding custom spell awareness, boss mechanics, or any ground effects that aren't in the default database.
Key Features:
- Multiple Geometries - Add circles, rectangles, and cones
- Automatic Deduplication - Safe to call every frame; entries are deduplicated by key and geometry
- Customizable Danger Levels - Set visual, low, medium, high, or extreme danger
- Growth Animation - Support for expanding zones over time
- Point Safety Checks - Query if a position is safe from all danger zones
Importing The Module
---@type evade_helper
local evade = require("common/utility/evade_helper")
Access functions with : (colon), not . (dot).
Functions
evade:add_circle
Syntax
evade:add_circle(key: string, params: table): boolean, string
Parameters
| Parameter | Type | Description |
|---|---|---|
key | string | Unique identifier for this danger zone |
params | table | Circle parameters (see below) |
Params Table
| Field | Type | Default | Description |
|---|---|---|---|
name | string | nil | Display name |
radius | number | Required | Circle radius in yards |
time_alive | number | 5.0 | How long the zone persists |
growth_ratio | number | 0.0 | Expansion rate over time |
object_id | integer | nil | Used for deduplication with geometry |
caster_id | integer | 0 | Caster identifier |
danger_level | integer | visual | Danger level enum value |
danger_level_dropdown | integer | same as danger_level | UI dropdown level |
is_debug | boolean | false | Enable debug visualization |
boolean- True if added successfullystring- Reason if not added
Example Usage
local evade = require("common/utility/evade_helper")
local db = require("root/core_lua/proxy/evade/danger_database")
local ok, why = evade:add_circle("my_spell_circle", {
name = "My Spell Circle",
radius = 6.5,
time_alive = 8.0,
object_id = 123456,
danger_level = db.danger_level_enum.extreme,
danger_level_dropdown = db.danger_level_enum.extreme
})
if not ok then
core.log("[evade_helper] not added: " .. why)
end
evade:add_rect
Syntax
evade:add_rect(key: string, params: table): boolean, string
Params Table
| Field | Type | Default | Description |
|---|---|---|---|
name | string | nil | Display name |
width | number | Required | Rectangle width in yards |
length | number | Required | Rectangle length in yards |
time_alive | number | 5.0 | How long the zone persists |
growth_ratio | number | 0.0 | Expansion rate over time |
is_projectile | boolean | false | Whether this is a moving projectile |
object_id | integer | nil | Used for deduplication |
caster_id | integer | 0 | Caster identifier |
danger_level | integer | visual | Danger level enum value |
danger_level_dropdown | integer | same | UI dropdown level |
is_debug | boolean | false | Enable debug visualization |
Example Usage
evade:add_rect("boss_line_aoe", {
name = "Boss Line AOE",
width = 4.0,
length = 18.0,
time_alive = 4.0,
object_id = 998877
})
evade:add_cone
Syntax
evade:add_cone(key: string, params: table): boolean, string
Params Table
| Field | Type | Default | Description |
|---|---|---|---|
name | string | nil | Display name |
radius | number | Required | Cone radius (length) in yards |
angle | number | Required | Cone angle in degrees |
time_alive | number | 3.0 | How long the zone persists |
growth_ratio | number | 0.0 | Expansion rate over time |
anim_speed | number | 2.0 | Animation speed |
object_id | integer | nil | Used for deduplication |
caster_id | integer | -1 | Caster identifier |
danger_level | integer | visual | Danger level enum value |
danger_level_dropdown | integer | same | UI dropdown level |
is_debug | boolean | false | Enable debug visualization |
Example Usage
evade:add_cone("frontal_breath", {
name = "Frontal Breath",
radius = 12.0,
angle = 60.0,
anim_speed = 1.5,
time_alive = 3.0,
is_debug = true
})
evade:add_custom
Syntax
evade:add_custom(key: string, data: table): boolean, string
Forwards your exact table to the database. Must include geometry_type and all geometry-specific fields. Still deduplicated by key and geometry+object_id.
Example Usage
local db = require("root/core_lua/proxy/evade/danger_database")
evade:add_custom("rare_custom_shape", {
name = "Rare Shape",
geometry_type = db.geometry_type_enum.rect,
danger_level = db.danger_level_enum.visual,
danger_level_dropdown = db.danger_level_enum.extreme,
enable_check = core.menu.checkbox(true, "rare_custom_shape:enable_check"),
color = core.menu.colorpicker(db.danger_level_colors.extreme, "rare_custom_shape:color"),
object_id = -1,
caster_id = 0,
width = 3.0,
length = 9.0,
time_alive = 6.0,
is_projectile = false,
growth_ratio = 10.0,
is_debug = true
})
evade:is_point_safe
Syntax
evade:is_point_safe(point: vec3): boolean
Checks if a position is safe from all registered danger zones.
Example Usage
local safe_pos = vec3.new(100, 200, 30)
if evade:is_point_safe(safe_pos) then
core.log("Position is safe!")
end
evade:is_point_safe_full
Syntax
evade:is_point_safe_full(point: vec3, fall_threshold?: number): boolean
Extended safety check that also considers fall damage threshold.
evade:has_entry
evade:has_entry(key: string): boolean
Checks if a danger zone with the given key already exists.
evade:clear_cache
evade:clear_cache(): nil
Clears all cached danger zone entries.
Query Functions
evade:get_database_info(): any -- Get database information
evade:get_geometry(): any -- Get geometry data
evade:get_geometry_inst(): any -- Get geometry instances
evade:get_customizations(): any -- Get customization data
evade:add_debug_spells
evade:add_debug_spells(key: string, add_cone: boolean, add_rect: boolean, add_circle: boolean): any
Adds debug visualizations for testing purposes.
Danger Level Enum
Access danger levels through the database module:
local db = require("root/core_lua/proxy/evade/danger_database")
db.danger_level_enum.visual -- Lowest, just visual indicator
db.danger_level_enum.low
db.danger_level_enum.medium
db.danger_level_enum.high
db.danger_level_enum.extreme -- Highest priority
Complete Example
Boss Mechanic Handler
local evade = require("common/utility/evade_helper")
local db = require("root/core_lua/proxy/evade/danger_database")
-- Track boss mechanics
local function on_spell_cast(data)
local spell_id = data.spell_id
local caster = data.caster
-- Boss frontal cone attack
if spell_id == 123456 then
local pos = caster:get_position()
local facing = caster:get_facing()
evade:add_cone("boss_frontal_" .. tostring(caster), {
name = "Boss Frontal",
radius = 20.0,
angle = 90.0,
time_alive = 3.0,
danger_level = db.danger_level_enum.extreme,
object_id = caster:get_id()
})
end
-- Ground circle AoE
if spell_id == 789012 then
local target_pos = data.target_position
evade:add_circle("ground_aoe_" .. core.game_time(), {
name = "Ground AoE",
radius = 8.0,
time_alive = 5.0,
growth_ratio = 2.0, -- Expands over time
danger_level = db.danger_level_enum.high
})
end
end
core.register_on_spell_cast_callback(on_spell_cast)
Safe Position Finder
local evade = require("common/utility/evade_helper")
local function find_safe_position(center, max_distance, step)
step = step or 2
for distance = step, max_distance, step do
for angle = 0, 360, 30 do
local rad = math.rad(angle)
local test_pos = vec3.new(
center.x + math.cos(rad) * distance,
center.y + math.sin(rad) * distance,
center.z
)
if evade:is_point_safe(test_pos) then
return test_pos
end
end
end
return nil -- No safe position found
end