Documentation for the core framework used in Zarillion's HandyNotes expansion plugins.
The utilities module provides various helper functions for common operations like link resolution, calendar events, item checking, and localization support.
The framework supports automatic resolution of game links (items, spells, achievements, etc.) in text strings.
{item:12345}
- Item links{spell:136}
- Spell links{achievement:123}
- Achievement links{quest:456}
- Quest links{currency:789}
- Currency links{faction:47}
- Faction linksPrepares text containing link placeholders for later resolution:
local text = 'Requires {item:12345} and {spell:136}'
ns.PrepareLinks(text)
-- Links are cached for efficient resolution
Renders prepared links into their final display format:
local text = 'Complete {achievement:123} to unlock'
local rendered = ns.RenderLinks(text)
-- Returns: "Complete [Achievement Name] to unlock"
-- Name-only rendering (no color/formatting)
local nameOnly = ns.RenderLinks(text, true)
-- Returns: "Complete Achievement Name to unlock"
local node = ns.node.NPC({
label = 'Quest Giver',
note = 'Rewards {item:12345} and teaches {spell:136}'
})
-- Links are automatically resolved when tooltip is displayed
Functions for checking active World of Warcraft calendar events:
Check if a specific calendar event is currently active:
if ns.IsCalendarEventActive(423) then -- Hallow's End
print('Halloween event is active!')
end
local node = ns.node.NPC({
label = 'Holiday Vendor',
requires = ns.requirement.Event(423), -- Hallow's End
note = 'Only available during Hallow\'s End'
})
Check if the player has a specific item with optional quantity:
-- Check if player has the item
if ns.PlayerHasItem(12345) then
print('Player has item 12345')
end
-- Check for specific quantity
if ns.PlayerHasItem(12345, 5) then
print('Player has at least 5 of item 12345')
end
local node = ns.node.NPC({
label = 'Item Exchange',
note = function()
if ns.PlayerHasItem(12345) then
return 'You can exchange your item here'
else
return 'Bring {item:12345} to make an exchange'
end
end
})
Safely navigate nested table structures:
-- Navigate to nested data safely
local data = ns.GetDatabaseTable('maps', mapID, 'nodes', coord, 'rewards')
if data then
-- Process reward data
end
This prevents errors when intermediate tables don’t exist.
The framework provides comprehensive localization support:
-- Get localized string
local text = L['some_key']
-- Prepare links in localized text
ns.PrepareLinks(L['tooltip_text'])
Register localization data for a specific locale:
ns.RegisterLocale('enUS', {
['node_rare'] = 'Rare Enemy',
['node_treasure'] = 'Treasure Chest',
['requires_quest'] = 'Requires quest: %s'
})
ns.RegisterLocale('deDE', {
['node_rare'] = 'Seltener Gegner',
['node_treasure'] = 'Schatztruhe',
['requires_quest'] = 'Benötigt Quest: %s'
})
Converts a value to a table format, handling both single values and arrays:
-- Single value becomes table
local t1 = ns.AsTable(123) -- {123}
local t2 = ns.AsTable({1,2,3}) -- {1,2,3} (unchanged)
local t3 = ns.AsTable(nil) -- {} (empty table)
-- Normalize quest IDs to table format
function Node:Initialize(attrs)
self.quest = ns.AsTable(self.quest)
-- Now self.quest is always a table, whether input was single ID or array
end
Split a string by delimiter:
local parts = ns.Split('one,two,three', ',')
-- Returns: {'one', 'two', 'three'}
Remove leading and trailing whitespace:
local clean = ns.Trim(' hello world ')
-- Returns: 'hello world'
PrepareLinks()
once during initialization, not repeatedlyGetDatabaseTable()
is safe but adds overhead for deep nestingThe utilities module is used throughout the framework: