diff --git a/Icons/Arrows/AllianceArrow.tga b/Icons/Arrows/AllianceArrow.tga new file mode 100644 index 0000000..6948d08 Binary files /dev/null and b/Icons/Arrows/AllianceArrow.tga differ diff --git a/Icons/Arrows/AllianceArrow_preview.tga b/Icons/Arrows/AllianceArrow_preview.tga new file mode 100644 index 0000000..ffa0f5c Binary files /dev/null and b/Icons/Arrows/AllianceArrow_preview.tga differ diff --git a/Icons/Arrows/HordeArrow.tga b/Icons/Arrows/HordeArrow.tga new file mode 100644 index 0000000..b46bf8c Binary files /dev/null and b/Icons/Arrows/HordeArrow.tga differ diff --git a/Icons/Arrows/HordeArrow_preview.tga b/Icons/Arrows/HordeArrow_preview.tga new file mode 100644 index 0000000..dc2d94d Binary files /dev/null and b/Icons/Arrows/HordeArrow_preview.tga differ diff --git a/Modules/Arrow/QuestieArrowAssets.lua b/Modules/Arrow/QuestieArrowAssets.lua index fe5b4b8..131ca81 100644 --- a/Modules/Arrow/QuestieArrowAssets.lua +++ b/Modules/Arrow/QuestieArrowAssets.lua @@ -50,6 +50,24 @@ QuestieArrowAssets.styles = { displayHeight = 96, visualBottomInset = 0, }, + ["hordearrow"] = { + label = "Horde Arrow", + texture = "Icons\\Arrows\\HordeArrow.tga", + preview = "Icons\\Arrows\\HordeArrow_preview.tga", + mode = "image", + displayWidth = 96, + displayHeight = 96, + visualBottomInset = 0, + }, + ["alliancearrow"] = { + label = "Alliance Arrow", + texture = "Icons\\Arrows\\AllianceArrow.tga", + preview = "Icons\\Arrows\\AllianceArrow_preview.tga", + mode = "image", + displayWidth = 96, + displayHeight = 96, + visualBottomInset = 0, + }, ["minimal1"] = { label = "Waypoint 1", texture = "Icons\\Arrows\\Minimal1.tga", @@ -94,6 +112,8 @@ QuestieArrowAssets.order = { "arrow3", "arrow4", "arcanearrow", + "hordearrow", + "alliancearrow", "minimal1", "minimal2", "minimal3", diff --git a/README.md b/README.md index f93f4a2..815ebca 100644 --- a/README.md +++ b/README.md @@ -198,6 +198,7 @@ Bundled arrow assets are detected automatically as either sprite sheets or regul - `Arrow1` through `Arrow4` are the bundled image styles, while `arrowold` remains the only bundled sprite sheet. - `Arcane Arrow` adds a more ornate gold-and-blue option for players who want something a little fancier than the plain waypoint shapes. +- `Horde Arrow` and `Alliance Arrow` add faction-themed styles with their insignia built into the art. - `Waypoint 1` through `Waypoint 3` add a calmer, lower-profile look for players who want something closer to a plain game marker. - The dropdown now uses generated preview swatches from `Icons/Arrows`, so each bundled style shows a live thumbnail instead of a text-only entry. - Image arrows rotate as a single texture and keep their native art, while sprite sheets only use sheet-cell logic when the style is explicitly `arrowold` or a custom sheet is marked as such. diff --git a/Tests/QuestieArrowAssets_spec.lua b/Tests/QuestieArrowAssets_spec.lua new file mode 100644 index 0000000..19afe15 --- /dev/null +++ b/Tests/QuestieArrowAssets_spec.lua @@ -0,0 +1,113 @@ +local lfs = require("lfs") + +local function read_file(path) + local handle = assert(io.open(path, "rb")) + local content = assert(handle:read("*a")) + handle:close() + return content +end + +local function list_arrows() + local names = {} + for entry in lfs.dir("Icons/Arrows") do + if entry ~= "." and entry ~= ".." then + names[#names + 1] = entry + end + end + table.sort(names) + return names +end + +local function extract_block(content, key) + local needle = ' ["' .. key .. '"] = {' + local startPos = assert(content:find(needle, 1, true), "missing style block for " .. key) + local tail = content:sub(startPos) + local endPos = assert(tail:find("\n },", 1, true), "missing terminator for style block " .. key) + return tail:sub(1, endPos) +end + +local function extract_mode(content, key) + local block = extract_block(content, key) + return assert(block:match('mode%s*=%s*"([^"]+)"'), "missing mode for " .. key) +end + +local function extract_texture(content, key) + local block = extract_block(content, key) + return assert(block:match('texture%s*=%s*"([^"]+)"'), "missing texture for " .. key) +end + +describe("QuestieArrowAssets manifest", function() + local content = read_file("Modules/Arrow/QuestieArrowAssets.lua") + local arrowLua = read_file("Modules/Arrow/QuestieArrow.lua") + + it("keeps the default arrow as a regular image", function() + assert.are.equal("image", extract_mode(content, "arrow1")) + assert.are.equal("Icons\\\\Arrows\\\\Arrow1.tga", extract_texture(content, "arrow1")) + end) + + it("keeps the old arrow as a sprite sheet", function() + assert.are.equal("sheet", extract_mode(content, "arrowold")) + end) + + it("keeps the other bundled arrows as regular images", function() + assert.are.equal("image", extract_mode(content, "arrow2")) + assert.are.equal("image", extract_mode(content, "arrow3")) + assert.are.equal("image", extract_mode(content, "arrow4")) + assert.are.equal("image", extract_mode(content, "arcanearrow")) + assert.are.equal("image", extract_mode(content, "hordearrow")) + assert.are.equal("image", extract_mode(content, "alliancearrow")) + assert.are.equal("image", extract_mode(content, "minimal1")) + assert.are.equal("image", extract_mode(content, "minimal2")) + assert.are.equal("image", extract_mode(content, "minimal3")) + end) + + it("only treats arrowold as a bundled sprite sheet", function() + assert.are.equal("sheet", extract_mode(content, "arrowold")) + assert.are.equal("image", extract_mode(content, "arrow1")) + assert.are.equal("image", extract_mode(content, "arrow2")) + assert.are.equal("image", extract_mode(content, "arrow3")) + assert.are.equal("image", extract_mode(content, "arrow4")) + assert.are.equal("image", extract_mode(content, "arcanearrow")) + assert.are.equal("image", extract_mode(content, "hordearrow")) + assert.are.equal("image", extract_mode(content, "alliancearrow")) + assert.are.equal("image", extract_mode(content, "minimal1")) + assert.are.equal("image", extract_mode(content, "minimal2")) + assert.are.equal("image", extract_mode(content, "minimal3")) + end) + + it("keeps the runtime default pointed at arrow1 and the sheet guard locked to arrowold", function() + assert.is_truthy(arrowLua:find('local ARROW_DEFAULT_STYLE = "arrow1"', 1, true)) + assert.is_truthy(arrowLua:find('return styleKey == "arrowold"', 1, true)) + assert.is_truthy(arrowLua:find('if styleKey == "arrow" then', 1, true)) + assert.is_truthy(arrowLua:find('self.arrow:SetTexCoord(0, 1, 0, 1)', 1, true)) + assert.is_truthy(arrowLua:find('local runtimeTexture = style.preview', 1, true)) + assert.is_truthy(arrowLua:find('sourceTexturePath = QuestieLib.AddonPath .. style.texture', 1, true)) + end) + + it("keeps the bundled arrow folder clean and named consistently", function() + assert.are.same({ + "AllianceArrow.tga", + "AllianceArrow_preview.tga", + "ArcaneArrow.tga", + "ArcaneArrow_preview.tga", + "Arrow1.tga", + "Arrow1_preview.tga", + "Arrow2.tga", + "Arrow2_preview.tga", + "Arrow3.tga", + "Arrow3_preview.tga", + "Arrow4.tga", + "Arrow4_preview.tga", + "HordeArrow.tga", + "HordeArrow_preview.tga", + "Minimal1.tga", + "Minimal1_preview.tga", + "Minimal2.tga", + "Minimal2_preview.tga", + "Minimal3.tga", + "Minimal3_preview.tga", + "arrowold.tga", + "arrowold_preview.tga", + }, list_arrows()) + end) +end)