Skip to content

Haze Auto Dagger ​

Here's a Haze script that locks onto an enemy and throws a Sleep Dagger (ability 1) while you hold mouse5.

What this shows ​

  • Reading menu settings at runtime. config.get_float("fov") reads the current value from TSUKI's settings UI every tick. If you drag the slider in-game, the script uses the new value right away without a reload.
  • fire_and_hold keeps the aim locked for hold_time ms after the press. Haze's throw has a windup. If the snap let go on the keypress, the dagger would miss.
  • while true + coroutine.yield(). on_tick always runs as a coroutine, so fire_and_hold can yield during its hold. The loop is optional. The yield() at the bottom hands control back to the engine each tick, and returning from on_tick instead works the same way.
  • targeting.get_fov(target, bone) returns the angle in degrees from the camera forward to that bone.
  • snap_to_target() every tick. Each call moves the camera for one frame only, so call it every tick to follow the target until the dagger fires.

Script ​

lua
-- Haze Auto Dagger
-- Hold mouse5 -> track closest enemy -> fire when on target -> hold lock 200ms

name = "Haze Auto Dagger"
id = hero_id.haze

settings = {
    { key = "fov",        label = "FOV (degrees)",        type = "float", default = 15.0, min = 1.0, max = 30.0 },
    { key = "max_range",  label = "Max Range (m)",        type = "float", default = 30.0, min = 5.0, max = 100.0 },
    { key = "fire_angle", label = "Fire Threshold (deg)", type = "float", default = 1.5,  min = 0.3, max = 5.0 },
    { key = "hold_time",  label = "Lock After Fire (ms)", type = "float", default = 200,  min = 0, max = 2000 },
}

function on_tick()
    while true do
        local lp = local_player()
        if lp and lp:is_alive() and input.is_key_held(VK.XBUTTON2) then
            if lp:is_ability_ready(slot.ability1) then
                local target = targeting.find_closest_by_fov(
                    config.get_float("fov"),
                    config.get_float("max_range")
                )
                if target and target:is_targetable() then
                    snap_to_target(target, { bone = bone.chest })

                    local angle = targeting.get_fov(target, bone.chest)
                    if angle and angle < config.get_float("fire_angle") then
                        fire_and_hold(target, slot.ability1, {
                            bone = bone.chest,
                            hold_time = config.get_float("hold_time")
                        })
                        toast(string.format("Dagger → %s", target:hero_name() or "?"), 2, {
                            bg = {r=40, g=15, b=50, a=220},
                            text = {r=200, g=140, b=255},
                        })
                    end
                end
            end
        end
        coroutine.yield()
    end
end

Notes ​

id = hero_id.haze locks the script to Haze only. It goes idle automatically when you pick a different hero. Comment that line out (or delete it) if you want to try the same logic with another hero's ability 1.

bone.chest works well on heroes at medium range. At long range, where targets have more time to dodge, bone.pelvis hits slightly more often. Try both.

A lower fire_angle makes the script wait until the crosshair lines up tightly with the target. A higher value, such as 3 to 4 degrees, fires sooner, before the snap has fully caught up. You get fewer perfect shots and more good-enough ones.