Modifier Tracker ​
Tracks enemy purchases and detects debuffs landing on you with caster attribution. Demonstrates on_modifier_added, on_ability_cast, on_item_used, and a per-tick item-purchase diff.
lua
-- Track enemy purchases and detect debuffs with caster attribution
local prev = {}
function on_modifier_added(player, modifier)
if not player:is_local() then return end
if not modifier.caster or not modifier.caster:is_enemy() then return end
local who = modifier.caster:hero_name()
local name = modifier.name or ""
if name:find("glitch") then
toast("CURSED by " .. who .. "!")
elseif name:find("stunned") then
toast("STUNNED by " .. who .. "!")
elseif name:find("sleep") then
toast("SLEEP by " .. who .. "!")
end
end
function on_ability_cast(player, ability)
if player:is_enemy() then
toast(player:hero_name() .. " cast " .. ability.name
.. " (" .. string.format("%.0f", ability.cooldown) .. "s)")
end
end
function on_item_used(player, item)
if item.name:find("metal_skin") and player:is_enemy() then
toast(player:hero_name() .. " popped Metal Skin!")
end
end
function on_tick()
for _, p in ipairs(get_players()) do
if not p:is_enemy() then goto next end
local hero = p:hero_name()
local cur = {}
for _, it in ipairs(p:get_items()) do
cur[it.token] = it.name or "?"
end
if prev[hero] then
for tok, name in pairs(cur) do
if not prev[hero][tok] then
toast(hero .. " bought " .. name)
end
end
end
prev[hero] = cur
::next::
end
endWhat this teaches ​
on_modifier_addedwith caster attribution:modifier.casteris a player object you can call methods on. Always checkis_enemy()before reacting to incoming debuffs, otherwise teammates' debuffs to you will trigger your warnings too.- Substring matching modifier names: engine RTTI strings have prefixes like
modifier_glitch_root.string.findmatches anywhere in the string. on_ability_castincludes cooldown: useful for predicting when an ability is about to come back up.on_item_usedfor self-cast items: Metal Skin'splayerargument is the user, since the item targets the user themselves.- Item purchase diff: comparing
prev[hero]against the current items each tick catches new buys. Token-keyed so duplicate-name items still register.