pets get their action bar, macros arrive, and hunters draw the bow

- a hunter's or warlock's pet has its action bar now: attack, follow, stay, the pet's own spells with cooldowns and autocast sparkles
- the macro system lands: the macro window, the icon chooser, /cast and /macro, and macros dragged onto the action bar
- hunter shots look right at last: the bow draws and releases on the shot, and the arrow lays a spark trail its whole flight
- the options window re-dresses in 1.12's own art with the classic dialog look, and gets a working search box and clickable steppers

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Sam
2026-08-05 19:03:13 +07:00
co-authored by Claude Fable 5
parent 994be22f5c
commit 77dc8f8ead
98 changed files with 8922 additions and 1089 deletions
@@ -336,6 +336,32 @@ pub(super) fn install_methods(lua: &Lua, m: &Table) -> mlua::Result<()> {
set_spell_by_id(lua, &this, spell_id, name, false, false, None)
})?,
)?;
// GameTooltip:SetPetAction(index) — the pet-bar hover (decision 0982). Only ever reached for a
// SPELL slot: the reference's `PetActionButton_OnEnter` builds a token slot's tooltip inline
// from `tooltipName`/`tooltipSubtext` and never calls this. A slot with no spell (a token, an
// empty slot, an out-of-range index) is a no-op, leaving whatever was shown — the same shape
// as SetSpell's out-of-range.
m.set(
"SetPetAction",
lua.create_function(|lua, (this, index): (Table, usize)| {
let (spell_id, name) = {
let model = lua.app_data_mut::<Model>().expect("model app_data");
match model
.pet_bar
.slots
.get(index.saturating_sub(1))
.filter(|s| !s.view.is_token)
{
Some(s) => match s.view.spell_id {
Some(id) => (id, s.view.name.clone()),
None => return Ok(()),
},
None => return Ok(()),
}
};
set_spell_by_id(lua, &this, spell_id, name, false, false, None)
})?,
)?;
// GameTooltip:SetPlayerBuff(index [, filter]) — the buff-bar hover: the aura variant (white
// AuraDescription) + the duration-remaining line only this entry point appends
// (byte-verified; remaining computed live off the aura's GetTime expiry — the TEXT shape is