- addons load in the order NTFS lists a folder, case-insensitive with an underscore before the letters, the order the vanilla corpus was written against and the one that decides which addon provides a shared library (2178) - GetNumAddOns and the index form of every AddOn verb walk a title-sorted list that hides the Blizzard addons the server says to hide, and the character-select AddOns list is in title order (2175) - SetPoint and SetAllPoints raise the reference's own errors for a frame name that does not exist or an omitted relative frame instead of quietly anchoring to the parent, and an explicit nil means the screen root (2176) - a tooltip owned with ANCHOR_CURSOR follows the mouse, which pfUI's tooltip, xpbar and chat modules, pfQuest's browser and TipBuddy ask for; an omitted or unknown anchor is ANCHOR_LEFT (2176) - a $parent name handed to CreateFrame, CreateTexture or CreateFontString expands as it does in XML, so FonzAppraiser's thirty dropdowns and pfQuest's search icon get the names they asked for (2176) Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
80 lines
2.9 KiB
Rust
80 lines
2.9 KiB
Rust
//! The taxi seam (decision 0484): the app-pushed snapshot surfaces through the Era bindings the
|
|
//! reference `TaxiFrame.lua` reads, and the click/close intents drain back out.
|
|
|
|
use super::common::script;
|
|
use crate::script::*;
|
|
|
|
/// The full round trip: push a two-node snapshot, read it back exactly as the reference Lua does
|
|
/// (count, type, position, name, cost, route segments), click a node + close, drain both intents,
|
|
/// and `SetTaxiMap` paints the pushed art onto the target texture region.
|
|
#[test]
|
|
fn taxi_snapshot_surfaces_and_intents_drain() {
|
|
let mut s = script();
|
|
s.set_screen_size(800.0, 600.0);
|
|
s.set_taxi(Some(TaxiUiState {
|
|
art: "Interface\\TaxiFrame\\TAXIMAP1".into(),
|
|
nodes: vec![
|
|
TaxiUiNode {
|
|
name: "Crossroads, The Barrens".into(),
|
|
node_type: TaxiNodeType::Current,
|
|
pos: (0.5, 0.6),
|
|
cost: 0,
|
|
routes: vec![],
|
|
},
|
|
TaxiUiNode {
|
|
name: "Orgrimmar, Durotar".into(),
|
|
node_type: TaxiNodeType::Reachable,
|
|
pos: (0.55, 0.8),
|
|
cost: 110,
|
|
routes: vec![[0.5, 0.6, 0.55, 0.8]],
|
|
},
|
|
],
|
|
}));
|
|
|
|
s.run(
|
|
r#"
|
|
f = CreateFrame("Frame", "TaxiHost")
|
|
f:SetWidth(316); f:SetHeight(352); f:SetPoint("CENTER", 0, 0)
|
|
map = f:CreateTexture("TaxiMapTex", "OVERLAY")
|
|
SetTaxiMap(map)
|
|
|
|
assert(NumTaxiNodes() == 2)
|
|
assert(TaxiNodeGetType(1) == "CURRENT")
|
|
assert(TaxiNodeGetType(2) == "REACHABLE")
|
|
assert(TaxiNodeGetType(3) == "NONE") -- out of range hides, ref-style
|
|
local x, y = TaxiNodePosition(2)
|
|
assert(math.abs(x - 0.55) < 1e-6 and math.abs(y - 0.8) < 1e-6)
|
|
assert(TaxiNodeName(2) == "Orgrimmar, Durotar")
|
|
assert(TaxiNodeCost(2) == 110)
|
|
TaxiNodeSetCurrent(2) -- faithful no-op
|
|
assert(GetNumRoutes(1) == 0 and GetNumRoutes(2) == 1)
|
|
assert(math.abs(TaxiGetSrcX(2, 1) - 0.5) < 1e-6)
|
|
assert(math.abs(TaxiGetDestY(2, 1) - 0.8) < 1e-6)
|
|
assert(UnitOnTaxi("player") == nil) -- 1/nil, never a boolean (2043)
|
|
|
|
TakeTaxiNode(2)
|
|
CloseTaxiMap()
|
|
"#,
|
|
)
|
|
.unwrap();
|
|
|
|
assert_eq!(s.take_taxi_node(), vec![2]);
|
|
assert!(s.take_taxi_close());
|
|
assert!(!s.take_taxi_close(), "the close flag drains");
|
|
|
|
// SetTaxiMap assigned the pushed art onto the texture region.
|
|
s.resolve();
|
|
assert!(
|
|
s.extract().iter().any(|q| matches!(
|
|
&q.content,
|
|
QuadContent::Texture { path: Some(p), .. } if p == "Interface\\TaxiFrame\\TAXIMAP1"
|
|
)),
|
|
"the continent art draws on the SetTaxiMap target"
|
|
);
|
|
|
|
// The ride flag reaches UnitOnTaxi.
|
|
s.set_on_taxi(true);
|
|
s.run(r#"assert(UnitOnTaxi("player") == 1)"#).unwrap();
|
|
assert!(s.errors().is_empty(), "script errors: {:?}", s.errors());
|
|
}
|