@poe2-toolkit/tree-core 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +451 -0
- package/dist/geometry/centre.d.ts +17 -0
- package/dist/geometry/centre.d.ts.map +1 -0
- package/dist/geometry/centre.js +59 -0
- package/dist/geometry/centre.js.map +1 -0
- package/dist/geometry/framing.d.ts +27 -0
- package/dist/geometry/framing.d.ts.map +1 -0
- package/dist/geometry/framing.js +101 -0
- package/dist/geometry/framing.js.map +1 -0
- package/dist/geometry/orbit.d.ts +23 -0
- package/dist/geometry/orbit.d.ts.map +1 -0
- package/dist/geometry/orbit.js +28 -0
- package/dist/geometry/orbit.js.map +1 -0
- package/dist/geometry/project.d.ts +20 -0
- package/dist/geometry/project.d.ts.map +1 -0
- package/dist/geometry/project.js +149 -0
- package/dist/geometry/project.js.map +1 -0
- package/dist/ggg/normalize.d.ts +109 -0
- package/dist/ggg/normalize.d.ts.map +1 -0
- package/dist/ggg/normalize.js +279 -0
- package/dist/ggg/normalize.js.map +1 -0
- package/dist/index.d.ts +25 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +24 -0
- package/dist/index.js.map +1 -0
- package/dist/scene/allocate.d.ts +61 -0
- package/dist/scene/allocate.d.ts.map +1 -0
- package/dist/scene/allocate.js +239 -0
- package/dist/scene/allocate.js.map +1 -0
- package/dist/scene/buildScene.d.ts +21 -0
- package/dist/scene/buildScene.d.ts.map +1 -0
- package/dist/scene/buildScene.js +212 -0
- package/dist/scene/buildScene.js.map +1 -0
- package/dist/scene/connections.d.ts +13 -0
- package/dist/scene/connections.d.ts.map +1 -0
- package/dist/scene/connections.js +75 -0
- package/dist/scene/connections.js.map +1 -0
- package/dist/scene/nodeSize.d.ts +26 -0
- package/dist/scene/nodeSize.d.ts.map +1 -0
- package/dist/scene/nodeSize.js +72 -0
- package/dist/scene/nodeSize.js.map +1 -0
- package/dist/types.d.ts +426 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +16 -0
- package/dist/types.js.map +1 -0
- package/package.json +50 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"allocate.js","sourceRoot":"","sources":["../../src/scene/allocate.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Assemble a render-ready {@link Scene} from {@link TreeData} and the current
|
|
3
|
+
* build state. Every node is positioned and sized, every connection resolved to
|
|
4
|
+
* a line or arc, every effect pattern placed — nothing left for the renderer to
|
|
5
|
+
* compute.
|
|
6
|
+
*/
|
|
7
|
+
import type { BuildAllocation, NodeOption, Scene, SceneOptions, TreeData, TreeNode } from '../types.js';
|
|
8
|
+
export declare function buildScene(data: TreeData, opts?: SceneOptions): Scene;
|
|
9
|
+
/**
|
|
10
|
+
* The attribute option a build assigned to a generic +attribute node, or
|
|
11
|
+
* undefined when the node isn't an assigned attribute node.
|
|
12
|
+
*/
|
|
13
|
+
export declare function chosenAttributeOption(node: TreeNode, allocation: BuildAllocation | undefined): NodeOption | undefined;
|
|
14
|
+
/**
|
|
15
|
+
* The node a class actually shows at `node`'s position. When the active class
|
|
16
|
+
* overrides it (e.g. the Witch's "Spell and Minion Damage" for the generic
|
|
17
|
+
* "Spell Damage"), the override's name/stats/icon replace the base node's; the
|
|
18
|
+
* geometry and kind flags stay. Returns the node unchanged otherwise.
|
|
19
|
+
*/
|
|
20
|
+
export declare function classOverrideNode(data: TreeData, classId: number | null | undefined, node: TreeNode): TreeNode;
|
|
21
|
+
//# sourceMappingURL=buildScene.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"buildScene.d.ts","sourceRoot":"","sources":["../../src/scene/buildScene.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,KAAK,EACV,eAAe,EACf,UAAU,EAIV,KAAK,EACL,YAAY,EACZ,QAAQ,EACR,QAAQ,EAET,MAAM,aAAa,CAAC;AAIrB,wBAAgB,UAAU,CAAC,IAAI,EAAE,QAAQ,EAAE,IAAI,GAAE,YAAiB,GAAG,KAAK,CAmKzE;AAUD;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,eAAe,GAAG,SAAS,GAAG,UAAU,GAAG,SAAS,CAcrH;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,QAAQ,EACd,OAAO,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EAClC,IAAI,EAAE,QAAQ,GACb,QAAQ,CAaV"}
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Assemble a render-ready {@link Scene} from {@link TreeData} and the current
|
|
3
|
+
* build state. Every node is positioned and sized, every connection resolved to
|
|
4
|
+
* a line or arc, every effect pattern placed — nothing left for the renderer to
|
|
5
|
+
* compute.
|
|
6
|
+
*/
|
|
7
|
+
import { computeCentreLayout } from '../geometry/centre.js';
|
|
8
|
+
import { nodePosition } from '../geometry/orbit.js';
|
|
9
|
+
import { placeConnection } from './connections.js';
|
|
10
|
+
import { classifyNode, nodeTargetSize } from './nodeSize.js';
|
|
11
|
+
export function buildScene(data, opts = {}) {
|
|
12
|
+
const allocated = new Set(opts.allocation?.allocated ?? []);
|
|
13
|
+
// The active ascendancy's start node (the diamond every first node launches
|
|
14
|
+
// from) is implicitly allocated — you have the ascendancy — so its rails into
|
|
15
|
+
// the first allocated nodes render as active instead of looking disconnected.
|
|
16
|
+
const ascId = opts.allocation?.ascendId;
|
|
17
|
+
if (ascId) {
|
|
18
|
+
for (const node of Object.values(data.nodes)) {
|
|
19
|
+
if (node.isAscendancyStart && node.ascendancyName === ascId) {
|
|
20
|
+
allocated.add(node.skill);
|
|
21
|
+
break;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
// Active class's per-node display overrides (the Witch's "Spell and Minion
|
|
26
|
+
// Damage" for the generic "Spell Damage" node, etc.).
|
|
27
|
+
const overridePairs = data.classes.find((cls) => cls.id === opts.allocation?.classId)?.overridePairs;
|
|
28
|
+
const nodes = [];
|
|
29
|
+
const masteryEffects = [];
|
|
30
|
+
const connections = [];
|
|
31
|
+
const seenEdges = new Set();
|
|
32
|
+
const mainExtent = new Extent();
|
|
33
|
+
for (const node of Object.values(data.nodes)) {
|
|
34
|
+
// Skip nodes we can't place (missing/holed group, unknown orbit).
|
|
35
|
+
if (!data.groups[node.group]) {
|
|
36
|
+
continue;
|
|
37
|
+
}
|
|
38
|
+
// Class-start nodes are invisible launch points; edges start from the first
|
|
39
|
+
// real nodes, not from the start point. Keep them out of the scene entirely
|
|
40
|
+
// (the centre layout reads them from the data, not from here).
|
|
41
|
+
if (isClassStart(node)) {
|
|
42
|
+
continue;
|
|
43
|
+
}
|
|
44
|
+
// Hidden special sockets (the "Sinister Jewel Socket" decorations): not part
|
|
45
|
+
// of the base tree, so the official tree never draws them. Keep them out.
|
|
46
|
+
if (isHiddenSocket(node)) {
|
|
47
|
+
continue;
|
|
48
|
+
}
|
|
49
|
+
// Conditional nodes (GGG `unlockConstraint`, e.g. Oracle-locked passives):
|
|
50
|
+
// the official tree never renders these — they only surface in-game when the
|
|
51
|
+
// constraint is met — so keep them out entirely.
|
|
52
|
+
if (node.conditional) {
|
|
53
|
+
continue;
|
|
54
|
+
}
|
|
55
|
+
let position;
|
|
56
|
+
try {
|
|
57
|
+
position = nodePosition(data, node.skill);
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
continue;
|
|
61
|
+
}
|
|
62
|
+
const size = nodeTargetSize(node);
|
|
63
|
+
// The active class's override icon for this node, if any (e.g. the Witch's
|
|
64
|
+
// "Spell and Minion Damage" art over the generic "Spell Damage").
|
|
65
|
+
const overrideTarget = overridePairs?.[node.skill];
|
|
66
|
+
const overrideIcon = overrideTarget !== undefined ? data.nodes[overrideTarget]?.icon : undefined;
|
|
67
|
+
nodes.push({
|
|
68
|
+
skill: node.skill,
|
|
69
|
+
x: position.x,
|
|
70
|
+
y: position.y,
|
|
71
|
+
kind: classifyNode(node),
|
|
72
|
+
// Attribute choice wins, then the class override, then the base icon.
|
|
73
|
+
icon: chosenAttributeOption(node, opts.allocation)?.icon || overrideIcon || node.icon,
|
|
74
|
+
// The game draws each sprite at 2*width centred on the node, so the world
|
|
75
|
+
// diameter is twice the target width. Same rule as the centre ring layers.
|
|
76
|
+
iconSize: size.icon * 2,
|
|
77
|
+
frameSize: size.overlay * 2,
|
|
78
|
+
radius: Math.max(size.icon, size.overlay),
|
|
79
|
+
allocated: allocated.has(node.skill),
|
|
80
|
+
...(node.ascendancyName !== undefined ? { ascendancy: node.ascendancyName } : {}),
|
|
81
|
+
// Display-only jewel socketed here (from the build); no radius effect.
|
|
82
|
+
...(opts.allocation?.jewels?.[node.skill] ? { jewel: opts.allocation.jewels[node.skill] } : {}),
|
|
83
|
+
});
|
|
84
|
+
if (!node.ascendancyName) {
|
|
85
|
+
const reach = Math.max(size.icon, size.overlay) / 2;
|
|
86
|
+
mainExtent.add(position.x, position.y, reach);
|
|
87
|
+
}
|
|
88
|
+
if (node.activeEffectImage) {
|
|
89
|
+
// Notables carry an explicit effect size; masteries *are* the pattern
|
|
90
|
+
// (their icon size doubles as the effect size). Same 2*width world rule.
|
|
91
|
+
const effectSize = (size.effect > 0 ? size.effect : size.icon) * 2;
|
|
92
|
+
// A mastery isn't allocatable itself; it lights up when any node it links
|
|
93
|
+
// to (its merged in/out neighbours) is allocated — matching the in-game
|
|
94
|
+
// tree, where unconnected masteries in the same cluster stay dim.
|
|
95
|
+
masteryEffects.push({
|
|
96
|
+
skill: node.skill,
|
|
97
|
+
x: position.x,
|
|
98
|
+
y: position.y,
|
|
99
|
+
size: effectSize,
|
|
100
|
+
patternKey: node.activeEffectImage,
|
|
101
|
+
active: node.connections.some((conn) => allocated.has(conn.id)),
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
for (const conn of node.connections) {
|
|
105
|
+
const target = data.nodes[conn.id];
|
|
106
|
+
// Drop edges to/from class-start nodes (the invisible launch point) and
|
|
107
|
+
// mastery nodes (drawn as a background pattern, not a connectable node —
|
|
108
|
+
// their edges would dangle into nothing, as they don't on the live tree).
|
|
109
|
+
if (!target ||
|
|
110
|
+
isClassStart(target) ||
|
|
111
|
+
isHiddenSocket(target) ||
|
|
112
|
+
target.conditional ||
|
|
113
|
+
node.isMastery ||
|
|
114
|
+
target.isMastery) {
|
|
115
|
+
continue;
|
|
116
|
+
}
|
|
117
|
+
// Drop edges that cross the main-tree <-> ascendancy boundary: the
|
|
118
|
+
// ascendancy start's link into the main tree is never drawn (the
|
|
119
|
+
// ascendancy is a separate, relocated panel).
|
|
120
|
+
if (Boolean(node.ascendancyName) !== Boolean(target.ascendancyName)) {
|
|
121
|
+
continue;
|
|
122
|
+
}
|
|
123
|
+
const key = node.skill < conn.id ? `${node.skill}|${conn.id}` : `${conn.id}|${node.skill}`;
|
|
124
|
+
if (seenEdges.has(key)) {
|
|
125
|
+
continue;
|
|
126
|
+
}
|
|
127
|
+
seenEdges.add(key);
|
|
128
|
+
try {
|
|
129
|
+
const active = allocated.has(node.skill) && allocated.has(conn.id);
|
|
130
|
+
const placed = placeConnection(data, node.skill, conn.id, conn.arcCentre, active);
|
|
131
|
+
// Tag intra-ascendancy edges so the renderer can relocate them too.
|
|
132
|
+
if (node.ascendancyName && node.ascendancyName === target.ascendancyName) {
|
|
133
|
+
placed.ascendancy = node.ascendancyName;
|
|
134
|
+
}
|
|
135
|
+
connections.push(placed);
|
|
136
|
+
}
|
|
137
|
+
catch {
|
|
138
|
+
// One unplaceable endpoint — drop the edge rather than fail the scene.
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
return {
|
|
143
|
+
nodes,
|
|
144
|
+
connections,
|
|
145
|
+
masteryEffects,
|
|
146
|
+
centre: computeCentreLayout(data),
|
|
147
|
+
bounds: data.bounds,
|
|
148
|
+
mainBounds: mainExtent.toRect(data.bounds),
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
/** A class-start node: the invisible point a class's tree launches from. */
|
|
152
|
+
function isClassStart(node) {
|
|
153
|
+
return (node.classesStart?.length ?? 0) > 0;
|
|
154
|
+
}
|
|
155
|
+
/** Attribute-choice key -> the option name to match in the node's options. */
|
|
156
|
+
const ATTRIBUTE_OPTION_NAME = { str: 'Strength', dex: 'Dexterity', int: 'Intelligence' };
|
|
157
|
+
/**
|
|
158
|
+
* The attribute option a build assigned to a generic +attribute node, or
|
|
159
|
+
* undefined when the node isn't an assigned attribute node.
|
|
160
|
+
*/
|
|
161
|
+
export function chosenAttributeOption(node, allocation) {
|
|
162
|
+
if (!node.isAttribute || !node.options) {
|
|
163
|
+
return undefined;
|
|
164
|
+
}
|
|
165
|
+
const choice = allocation?.attributeChoices?.[node.skill];
|
|
166
|
+
if (!choice) {
|
|
167
|
+
return undefined;
|
|
168
|
+
}
|
|
169
|
+
const wanted = ATTRIBUTE_OPTION_NAME[choice];
|
|
170
|
+
return node.options.find((option) => option.name === wanted);
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* The node a class actually shows at `node`'s position. When the active class
|
|
174
|
+
* overrides it (e.g. the Witch's "Spell and Minion Damage" for the generic
|
|
175
|
+
* "Spell Damage"), the override's name/stats/icon replace the base node's; the
|
|
176
|
+
* geometry and kind flags stay. Returns the node unchanged otherwise.
|
|
177
|
+
*/
|
|
178
|
+
export function classOverrideNode(data, classId, node) {
|
|
179
|
+
if (classId == null) {
|
|
180
|
+
return node;
|
|
181
|
+
}
|
|
182
|
+
const target = data.classes.find((cls) => cls.id === classId)?.overridePairs?.[node.skill];
|
|
183
|
+
const override = target !== undefined ? data.nodes[target] : undefined;
|
|
184
|
+
if (!override) {
|
|
185
|
+
return node;
|
|
186
|
+
}
|
|
187
|
+
return { ...node, name: override.name, stats: override.stats, icon: override.icon };
|
|
188
|
+
}
|
|
189
|
+
/** A hidden special socket (the Sinister sockets): never drawn on the base tree. */
|
|
190
|
+
function isHiddenSocket(node) {
|
|
191
|
+
return node.noRadius === true && node.isJewelSocket === true;
|
|
192
|
+
}
|
|
193
|
+
/** Accumulates a bounding box from points + their reach; empty -> a fallback. */
|
|
194
|
+
class Extent {
|
|
195
|
+
minX = Infinity;
|
|
196
|
+
minY = Infinity;
|
|
197
|
+
maxX = -Infinity;
|
|
198
|
+
maxY = -Infinity;
|
|
199
|
+
add(x, y, reach) {
|
|
200
|
+
this.minX = Math.min(this.minX, x - reach);
|
|
201
|
+
this.minY = Math.min(this.minY, y - reach);
|
|
202
|
+
this.maxX = Math.max(this.maxX, x + reach);
|
|
203
|
+
this.maxY = Math.max(this.maxY, y + reach);
|
|
204
|
+
}
|
|
205
|
+
toRect(fallback) {
|
|
206
|
+
if (this.minX > this.maxX) {
|
|
207
|
+
return fallback;
|
|
208
|
+
}
|
|
209
|
+
return { minX: this.minX, minY: this.minY, maxX: this.maxX, maxY: this.maxY };
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
//# sourceMappingURL=buildScene.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"buildScene.js","sourceRoot":"","sources":["../../src/scene/buildScene.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Connection geometry: a straight line, or an arc following an orbit.
|
|
3
|
+
*
|
|
4
|
+
* GGG's `edges` table gives the arc centre directly (`orbitX`/`orbitY`), carried
|
|
5
|
+
* on the connection as `arcCentre`; when present the edge is the minor arc around
|
|
6
|
+
* that centre. As a fallback (a handful of arc edges ship no centre), an edge
|
|
7
|
+
* whose endpoints share a group orbit arcs around the group centre. Everything
|
|
8
|
+
* else is a straight line. A single canvas `arc()` has no 90°-per-sprite limit,
|
|
9
|
+
* so no split is needed.
|
|
10
|
+
*/
|
|
11
|
+
import type { PlacedConnection, Point, TreeData } from '../types.js';
|
|
12
|
+
export declare function placeConnection(data: TreeData, fromSkill: number, toSkill: number, arcCentre?: Point | undefined, active?: boolean): PlacedConnection;
|
|
13
|
+
//# sourceMappingURL=connections.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connections.d.ts","sourceRoot":"","sources":["../../src/scene/connections.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,KAAK,EAAE,gBAAgB,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAIrE,wBAAgB,eAAe,CAC7B,IAAI,EAAE,QAAQ,EACd,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,EACf,SAAS,GAAE,KAAK,GAAG,SAAqB,EACxC,MAAM,UAAQ,GACb,gBAAgB,CAqClB"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Connection geometry: a straight line, or an arc following an orbit.
|
|
3
|
+
*
|
|
4
|
+
* GGG's `edges` table gives the arc centre directly (`orbitX`/`orbitY`), carried
|
|
5
|
+
* on the connection as `arcCentre`; when present the edge is the minor arc around
|
|
6
|
+
* that centre. As a fallback (a handful of arc edges ship no centre), an edge
|
|
7
|
+
* whose endpoints share a group orbit arcs around the group centre. Everything
|
|
8
|
+
* else is a straight line. A single canvas `arc()` has no 90°-per-sprite limit,
|
|
9
|
+
* so no split is needed.
|
|
10
|
+
*/
|
|
11
|
+
import { nodePosition } from '../geometry/orbit.js';
|
|
12
|
+
const TWO_PI = Math.PI * 2;
|
|
13
|
+
export function placeConnection(data, fromSkill, toSkill, arcCentre = undefined, active = false) {
|
|
14
|
+
const a = nodePosition(data, fromSkill);
|
|
15
|
+
const b = nodePosition(data, toSkill);
|
|
16
|
+
const line = { from: fromSkill, to: toSkill, kind: 'line', a, b, active };
|
|
17
|
+
// Preferred: GGG's explicit arc centre.
|
|
18
|
+
if (arcCentre) {
|
|
19
|
+
const radius = Math.hypot(a.x - arcCentre.x, a.y - arcCentre.y);
|
|
20
|
+
if (radius > 0) {
|
|
21
|
+
return toArc(fromSkill, toSkill, a, b, arcCentre, radius, 0, active);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
// Fallback: endpoints on the same group orbit arc around the group centre.
|
|
25
|
+
const fromNode = data.nodes[fromSkill];
|
|
26
|
+
const toNode = data.nodes[toSkill];
|
|
27
|
+
if (fromNode &&
|
|
28
|
+
toNode &&
|
|
29
|
+
fromNode.group === toNode.group &&
|
|
30
|
+
fromNode.orbit === toNode.orbit &&
|
|
31
|
+
fromNode.orbit > 0) {
|
|
32
|
+
const group = data.groups[fromNode.group];
|
|
33
|
+
if (group) {
|
|
34
|
+
const radius = Math.hypot(a.x - group.x, a.y - group.y);
|
|
35
|
+
if (radius > 0) {
|
|
36
|
+
return toArc(fromSkill, toSkill, a, b, { x: group.x, y: group.y }, radius, fromNode.orbit, active);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
return line;
|
|
41
|
+
}
|
|
42
|
+
function toArc(from, to, a, b, centre, radius, orbit, active) {
|
|
43
|
+
const startAngle = Math.atan2(a.y - centre.y, a.x - centre.x);
|
|
44
|
+
const endAngle = Math.atan2(b.y - centre.y, b.x - centre.x);
|
|
45
|
+
return {
|
|
46
|
+
from,
|
|
47
|
+
to,
|
|
48
|
+
kind: 'arc',
|
|
49
|
+
a,
|
|
50
|
+
b,
|
|
51
|
+
active,
|
|
52
|
+
arc: {
|
|
53
|
+
cx: centre.x,
|
|
54
|
+
cy: centre.y,
|
|
55
|
+
radius,
|
|
56
|
+
startAngle,
|
|
57
|
+
endAngle,
|
|
58
|
+
// The shorter sweep from start to end; renderer draws that direction.
|
|
59
|
+
clockwise: shortestDelta(startAngle, endAngle) < 0,
|
|
60
|
+
orbit,
|
|
61
|
+
},
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
/** Signed shortest angular distance from a1 to a2, in (-π, π]. */
|
|
65
|
+
function shortestDelta(a1, a2) {
|
|
66
|
+
let delta = (a2 - a1) % TWO_PI;
|
|
67
|
+
if (delta <= -Math.PI) {
|
|
68
|
+
delta += TWO_PI;
|
|
69
|
+
}
|
|
70
|
+
else if (delta > Math.PI) {
|
|
71
|
+
delta -= TWO_PI;
|
|
72
|
+
}
|
|
73
|
+
return delta;
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=connections.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connections.js","sourceRoot":"","sources":["../../src/scene/connections.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Node classification and world sizes.
|
|
3
|
+
*
|
|
4
|
+
* GGG's export ships no per-node sizes, so they are derived here from a fixed
|
|
5
|
+
* size per node *type* (icon, overlay frame, and the effect pattern behind
|
|
6
|
+
* notables/keystones/masteries). The constants and the cascade order match Path
|
|
7
|
+
* of Building's `GetNodeTargetSize` (the reference renderer); order matters, the
|
|
8
|
+
* first match wins. In PoE2 these are world units directly.
|
|
9
|
+
*/
|
|
10
|
+
import type { NodeKind, TreeNode } from '../types.js';
|
|
11
|
+
export interface NodeSize {
|
|
12
|
+
/** World diameter of the skill icon (0 when the node has no icon). */
|
|
13
|
+
icon: number;
|
|
14
|
+
/** World diameter of the overlay frame (0 when none). */
|
|
15
|
+
overlay: number;
|
|
16
|
+
/** World diameter of the effect pattern behind the node (0 when none). */
|
|
17
|
+
effect: number;
|
|
18
|
+
}
|
|
19
|
+
/** Classify a node into a render kind (drives colour/frame, not just size). */
|
|
20
|
+
export declare function classifyNode(node: TreeNode): NodeKind;
|
|
21
|
+
/**
|
|
22
|
+
* World sizes for a node, following Path of Building's `GetNodeTargetSize`
|
|
23
|
+
* cascade.
|
|
24
|
+
*/
|
|
25
|
+
export declare function nodeTargetSize(node: TreeNode): NodeSize;
|
|
26
|
+
//# sourceMappingURL=nodeSize.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nodeSize.d.ts","sourceRoot":"","sources":["../../src/scene/nodeSize.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAEtD,MAAM,WAAW,QAAQ;IACvB,sEAAsE;IACtE,IAAI,EAAE,MAAM,CAAC;IACb,yDAAyD;IACzD,OAAO,EAAE,MAAM,CAAC;IAChB,0EAA0E;IAC1E,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,+EAA+E;AAC/E,wBAAgB,YAAY,CAAC,IAAI,EAAE,QAAQ,GAAG,QAAQ,CAkCrD;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,QAAQ,GAAG,QAAQ,CAqCvD"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Node classification and world sizes.
|
|
3
|
+
*
|
|
4
|
+
* GGG's export ships no per-node sizes, so they are derived here from a fixed
|
|
5
|
+
* size per node *type* (icon, overlay frame, and the effect pattern behind
|
|
6
|
+
* notables/keystones/masteries). The constants and the cascade order match Path
|
|
7
|
+
* of Building's `GetNodeTargetSize` (the reference renderer); order matters, the
|
|
8
|
+
* first match wins. In PoE2 these are world units directly.
|
|
9
|
+
*/
|
|
10
|
+
/** Classify a node into a render kind (drives colour/frame, not just size). */
|
|
11
|
+
export function classifyNode(node) {
|
|
12
|
+
if (node.isAscendancyStart) {
|
|
13
|
+
return 'ascendancyStart';
|
|
14
|
+
}
|
|
15
|
+
if (node.ascendancyName) {
|
|
16
|
+
return node.isNotable ? 'ascendancyNotable' : 'ascendancyNormal';
|
|
17
|
+
}
|
|
18
|
+
if (node.isJewelSocket) {
|
|
19
|
+
return 'jewel';
|
|
20
|
+
}
|
|
21
|
+
if (node.isNotable) {
|
|
22
|
+
return 'notable';
|
|
23
|
+
}
|
|
24
|
+
if (node.isMastery) {
|
|
25
|
+
return 'mastery';
|
|
26
|
+
}
|
|
27
|
+
if (node.isKeystone) {
|
|
28
|
+
return 'keystone';
|
|
29
|
+
}
|
|
30
|
+
if (node.classesStart && node.classesStart.length > 0) {
|
|
31
|
+
return 'classStart';
|
|
32
|
+
}
|
|
33
|
+
if (node.isAttribute) {
|
|
34
|
+
return 'attribute';
|
|
35
|
+
}
|
|
36
|
+
return 'normal';
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* World sizes for a node, following Path of Building's `GetNodeTargetSize`
|
|
40
|
+
* cascade.
|
|
41
|
+
*/
|
|
42
|
+
export function nodeTargetSize(node) {
|
|
43
|
+
if (node.isAscendancyStart) {
|
|
44
|
+
return { icon: 0, overlay: 50, effect: 0 };
|
|
45
|
+
}
|
|
46
|
+
if (node.ascendancyName && !node.isNotable) {
|
|
47
|
+
return { icon: 37, overlay: 80, effect: 0 };
|
|
48
|
+
}
|
|
49
|
+
if (node.isJewelSocket) {
|
|
50
|
+
return { icon: 80, overlay: 80, effect: 0 };
|
|
51
|
+
}
|
|
52
|
+
if (node.ascendancyName) {
|
|
53
|
+
// ascendancy notable
|
|
54
|
+
return { icon: 54, overlay: 100, effect: 0 };
|
|
55
|
+
}
|
|
56
|
+
if (node.isNotable) {
|
|
57
|
+
return { icon: 54, overlay: 80, effect: 380 };
|
|
58
|
+
}
|
|
59
|
+
if (node.isMastery) {
|
|
60
|
+
// "OnlyImage": the node *is* a large pattern image, no overlay.
|
|
61
|
+
return { icon: 380, overlay: 0, effect: 0 };
|
|
62
|
+
}
|
|
63
|
+
if (node.isKeystone) {
|
|
64
|
+
return { icon: 82, overlay: 120, effect: 380 };
|
|
65
|
+
}
|
|
66
|
+
if (node.classesStart && node.classesStart.length > 0) {
|
|
67
|
+
// Class-start node: a normal icon under an effectively invisible frame.
|
|
68
|
+
return { icon: 37, overlay: 1, effect: 0 };
|
|
69
|
+
}
|
|
70
|
+
return { icon: 37, overlay: 54, effect: 0 };
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=nodeSize.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nodeSize.js","sourceRoot":"","sources":["../../src/scene/nodeSize.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAaH,+EAA+E;AAC/E,MAAM,UAAU,YAAY,CAAC,IAAc;IACzC,IAAI,IAAI,CAAC,iBAAiB,EAAE,CAAC;QAC3B,OAAO,iBAAiB,CAAC;IAC3B,CAAC;IAED,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;QACxB,OAAO,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC,kBAAkB,CAAC;IACnE,CAAC;IAED,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;QACvB,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;QACnB,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;QACnB,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;QACpB,OAAO,UAAU,CAAC;IACpB,CAAC;IAED,IAAI,IAAI,CAAC,YAAY,IAAI,IAAI,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACtD,OAAO,YAAY,CAAC;IACtB,CAAC;IAED,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;QACrB,OAAO,WAAW,CAAC;IACrB,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,cAAc,CAAC,IAAc;IAC3C,IAAI,IAAI,CAAC,iBAAiB,EAAE,CAAC;QAC3B,OAAO,EAAE,IAAI,EAAE,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC;IAC7C,CAAC;IAED,IAAI,IAAI,CAAC,cAAc,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;QAC3C,OAAO,EAAE,IAAI,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC;IAC9C,CAAC;IAED,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;QACvB,OAAO,EAAE,IAAI,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC;IAC9C,CAAC;IAED,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;QACxB,qBAAqB;QACrB,OAAO,EAAE,IAAI,EAAE,EAAE,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC;IAC/C,CAAC;IAED,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;QACnB,OAAO,EAAE,IAAI,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC;IAChD,CAAC;IAED,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;QACnB,gEAAgE;QAChE,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC;IAC9C,CAAC;IAED,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;QACpB,OAAO,EAAE,IAAI,EAAE,EAAE,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC;IACjD,CAAC;IAED,IAAI,IAAI,CAAC,YAAY,IAAI,IAAI,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACtD,wEAAwE;QACxE,OAAO,EAAE,IAAI,EAAE,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC;IAC7C,CAAC;IAED,OAAO,EAAE,IAAI,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC;AAC9C,CAAC"}
|