@vanduo-oss/framework 1.4.6 → 1.5.1

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.
@@ -1,233 +0,0 @@
1
- // Hex math utilities — Canonical source: framework/js/utils/hex-math.js
2
- // Based on web-civ utils/hex-math.js
3
-
4
- /**
5
- * Rotate a point around the origin
6
- * @param {number} x - X coordinate
7
- * @param {number} y - Y coordinate
8
- * @param {number} [rotation=0] - Rotation in radians
9
- * @returns {{x: number, y: number}} Rotated point
10
- */
11
- export function rotatePoint(x, y, rotation = 0) {
12
- if (!rotation) {
13
- return { x, y };
14
- }
15
-
16
- const cosRot = Math.cos(rotation);
17
- const sinRot = Math.sin(rotation);
18
-
19
- return {
20
- x: x * cosRot - y * sinRot,
21
- y: x * sinRot + y * cosRot
22
- };
23
- }
24
-
25
- /**
26
- * Apply the inverse of a rotation to a point
27
- * @param {number} x - X coordinate
28
- * @param {number} y - Y coordinate
29
- * @param {number} [rotation=0] - Rotation in radians
30
- * @returns {{x: number, y: number}} Unrotated point
31
- */
32
- export function unrotatePoint(x, y, rotation = 0) {
33
- return rotatePoint(x, y, -rotation);
34
- }
35
-
36
- /**
37
- * Convert hex axial coordinates to pixel coordinates (flat-top orientation)
38
- * @param {number} q - Hex column coordinate
39
- * @param {number} r - Hex row coordinate
40
- * @param {number} size - Hex radius
41
- * @param {number} [rotation=0] - Optional grid rotation in radians
42
- * @returns {{x: number, y: number}} Pixel coordinates
43
- */
44
- export function hexToPixel(q, r, size, rotation = 0) {
45
- const baseX = size * 1.5 * q;
46
- const baseY = size * Math.sqrt(3) * (r + q * 0.5);
47
- return rotatePoint(baseX, baseY, rotation);
48
- }
49
-
50
- /**
51
- * Convert pixel coordinates to hex axial coordinates (flat-top orientation)
52
- * @param {number} px - Pixel X coordinate
53
- * @param {number} py - Pixel Y coordinate
54
- * @param {number} size - Hex radius
55
- * @param {number} [rotation=0] - Optional grid rotation in radians
56
- * @returns {{q: number, r: number}} Hex coordinates (rounded)
57
- */
58
- export function pixelToHex(px, py, size, rotation = 0) {
59
- const point = unrotatePoint(px, py, rotation);
60
- const q = (2 / 3 * point.x) / size;
61
- const r = (-1 / 3 * point.x + Math.sqrt(3) / 3 * point.y) / size;
62
- return axialRound(q, r);
63
- }
64
-
65
- /**
66
- * Round fractional axial coordinates to nearest hex
67
- * @param {number} q - Fractional q coordinate
68
- * @param {number} r - Fractional r coordinate
69
- * @returns {{q: number, r: number}} Rounded hex coordinates
70
- */
71
- export function axialRound(q, r) {
72
- const s = -q - r;
73
- let rq = Math.round(q);
74
- let rr = Math.round(r);
75
- const rs = Math.round(s);
76
- const qDiff = Math.abs(rq - q);
77
- const rDiff = Math.abs(rr - r);
78
- const sDiff = Math.abs(rs - s);
79
- if (qDiff > rDiff && qDiff > sDiff) {
80
- rq = -rr - rs;
81
- } else if (rDiff > sDiff) {
82
- rr = -rq - rs;
83
- }
84
- return { q: rq, r: rr };
85
- }
86
-
87
- /**
88
- * Get the 6 corner points of a flat-top hexagon
89
- * @param {number} x - Center X coordinate
90
- * @param {number} y - Center Y coordinate
91
- * @param {number} size - Hex radius
92
- * @param {number} [rotation=0] - Optional hex rotation in radians
93
- * @returns {Array<{x: number, y: number}>} Array of 6 corner points
94
- */
95
- export function getHexCorners(x, y, size, rotation = 0) {
96
- const corners = [];
97
- for (let i = 0; i < 6; i++) {
98
- const angleRad = (Math.PI / 180) * (60 * i) + rotation;
99
- corners.push({
100
- x: x + size * Math.cos(angleRad),
101
- y: y + size * Math.sin(angleRad)
102
- });
103
- }
104
- return corners;
105
- }
106
-
107
- /**
108
- * Get the 6 adjacent hex coordinates from a given hex
109
- * @param {number} q - Hex column
110
- * @param {number} r - Hex row
111
- * @returns {Array<{q: number, r: number}>} Array of 6 adjacent hex coordinates
112
- */
113
- export function getAdjacentHexes(q, r) {
114
- return [
115
- { q: q + 1, r: r },
116
- { q: q + 1, r: r - 1 },
117
- { q: q, r: r - 1 },
118
- { q: q - 1, r: r },
119
- { q: q - 1, r: r + 1 },
120
- { q: q, r: r + 1 }
121
- ];
122
- }
123
-
124
- /**
125
- * Calculate distance between two hexes using axial coordinates
126
- * @param {number} q1 - First hex q coordinate
127
- * @param {number} r1 - First hex r coordinate
128
- * @param {number} q2 - Second hex q coordinate
129
- * @param {number} r2 - Second hex r coordinate
130
- * @returns {number} Distance in hex steps
131
- */
132
- export function hexDistance(q1, r1, q2, r2) {
133
- return (Math.abs(q1 - q2) + Math.abs(q1 + r1 - q2 - r2) + Math.abs(r1 - r2)) / 2;
134
- }
135
-
136
- /**
137
- * Terrain types available in the system
138
- */
139
- export const TerrainType = Object.freeze({
140
- GRASSLAND: 'Grassland',
141
- PLAINS: 'Plains',
142
- DESERT: 'Desert',
143
- TUNDRA: 'Tundra',
144
- SNOW: 'Snow',
145
- MOUNTAIN: 'Mountain',
146
- OCEAN: 'Ocean',
147
- COAST: 'Coast'
148
- });
149
-
150
- /**
151
- * Terrain colors for rendering
152
- */
153
- export const TERRAIN_COLORS = Object.freeze({
154
- [TerrainType.GRASSLAND]: '#47602f',
155
- [TerrainType.PLAINS]: '#6e6838',
156
- [TerrainType.DESERT]: '#bd9a60',
157
- [TerrainType.TUNDRA]: '#75787b',
158
- [TerrainType.SNOW]: '#cfdce4',
159
- [TerrainType.MOUNTAIN]: '#464543',
160
- [TerrainType.OCEAN]: '#1d354c',
161
- [TerrainType.COAST]: '#295170'
162
- });
163
-
164
- /**
165
- * Default terrain color for unknown types
166
- */
167
- export const DEFAULT_TERRAIN_COLOR = '#FF00FF';
168
-
169
- /**
170
- * Terrain yields - resources generated per turn from each terrain type
171
- */
172
- export const TERRAIN_YIELDS = Object.freeze({
173
- [TerrainType.GRASSLAND]: { food: 2, production: 0, gold: 0 },
174
- [TerrainType.PLAINS]: { food: 1, production: 1, gold: 0 },
175
- [TerrainType.DESERT]: { food: 0, production: 1, gold: 0 },
176
- [TerrainType.TUNDRA]: { food: 1, production: 0, gold: 0 },
177
- [TerrainType.SNOW]: { food: 0, production: 0, gold: 0 },
178
- [TerrainType.COAST]: { food: 1, production: 0, gold: 0 },
179
- [TerrainType.OCEAN]: { food: 0, production: 0, gold: 0 },
180
- [TerrainType.MOUNTAIN]: { food: 0, production: 0, gold: 0 }
181
- });
182
-
183
- /**
184
- * Movement costs for units based on terrain
185
- * Higher cost = harder to move through
186
- */
187
- export const TERRAIN_MOVEMENT_COSTS = Object.freeze({
188
- [TerrainType.GRASSLAND]: 1,
189
- [TerrainType.PLAINS]: 1,
190
- [TerrainType.DESERT]: 1,
191
- [TerrainType.TUNDRA]: 1,
192
- [TerrainType.SNOW]: 2,
193
- [TerrainType.COAST]: 1,
194
- [TerrainType.OCEAN]: 999, // Impassable for land units
195
- [TerrainType.MOUNTAIN]: 999 // Impassable
196
- });
197
-
198
- /**
199
- * Check if terrain is passable for land units
200
- * @param {string} terrainType - Terrain type
201
- * @returns {boolean} True if passable
202
- */
203
- export function isPassable(terrainType) {
204
- const cost = TERRAIN_MOVEMENT_COSTS[terrainType];
205
- return cost !== undefined && cost < 999;
206
- }
207
-
208
- /**
209
- * Get movement cost for terrain
210
- * @param {string} terrainType - Terrain type
211
- * @returns {number} Movement cost
212
- */
213
- export function getMovementCost(terrainType) {
214
- return TERRAIN_MOVEMENT_COSTS[terrainType] ?? 999;
215
- }
216
-
217
- /**
218
- * Get terrain yields
219
- * @param {string} terrainType - Terrain type
220
- * @returns {Object} Yields object {food, production, gold}
221
- */
222
- export function getTerrainYields(terrainType) {
223
- return TERRAIN_YIELDS[terrainType] || { food: 0, production: 0, gold: 0 };
224
- }
225
-
226
- /**
227
- * Get terrain color
228
- * @param {string} terrainType - Terrain type
229
- * @returns {string} Hex color string
230
- */
231
- export function getTerrainColor(terrainType) {
232
- return TERRAIN_COLORS[terrainType] || DEFAULT_TERRAIN_COLOR;
233
- }