ultimatedarktower 4.0.1 → 5.0.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/CHANGELOG.md +44 -0
- package/README.md +105 -253
- package/dist/esm/index.mjs +2061 -132
- package/dist/src/UltimateDarkTower.d.ts +7 -0
- package/dist/src/UltimateDarkTower.js +13 -1
- package/dist/src/UltimateDarkTower.js.map +1 -1
- package/dist/src/adapters/NoopBluetoothAdapter.d.ts +26 -0
- package/dist/src/adapters/NoopBluetoothAdapter.js +50 -0
- package/dist/src/adapters/NoopBluetoothAdapter.js.map +1 -0
- package/dist/src/data/board/index.d.ts +9 -0
- package/dist/src/data/board/index.js +26 -0
- package/dist/src/data/board/index.js.map +1 -0
- package/dist/src/data/board/udtBoardAdjacency.d.ts +25 -0
- package/dist/src/data/board/udtBoardAdjacency.js +397 -0
- package/dist/src/data/board/udtBoardAdjacency.js.map +1 -0
- package/dist/src/data/board/udtBoardAnchors.d.ts +34 -0
- package/dist/src/data/board/udtBoardAnchors.js +357 -0
- package/dist/src/data/board/udtBoardAnchors.js.map +1 -0
- package/dist/src/data/board/udtGameBoard.js.map +1 -0
- package/dist/src/data/index.d.ts +19 -0
- package/dist/src/data/index.js +56 -0
- package/dist/src/data/index.js.map +1 -0
- package/dist/src/data/udtBoxInventory.d.ts +47 -0
- package/dist/src/data/udtBoxInventory.js +679 -0
- package/dist/src/data/udtBoxInventory.js.map +1 -0
- package/dist/src/data/udtFoes.d.ts +53 -0
- package/dist/src/data/udtFoes.js +47 -0
- package/dist/src/data/udtFoes.js.map +1 -0
- package/dist/src/data/udtGameContent.d.ts +418 -0
- package/dist/src/data/udtGameContent.js +293 -0
- package/dist/src/data/udtGameContent.js.map +1 -0
- package/dist/src/data/udtHeroes.d.ts +30 -0
- package/dist/src/data/udtHeroes.js +38 -0
- package/dist/src/data/udtHeroes.js.map +1 -0
- package/dist/src/data/udtMonuments.d.ts +23 -0
- package/dist/src/data/udtMonuments.js +20 -0
- package/dist/src/data/udtMonuments.js.map +1 -0
- package/dist/src/index.d.ts +2 -5
- package/dist/src/index.js +30 -27
- package/dist/src/index.js.map +1 -1
- package/dist/src/seed/index.d.ts +7 -0
- package/dist/src/seed/index.js +24 -0
- package/dist/src/seed/index.js.map +1 -0
- package/dist/src/seed/udtSeedParser.js.map +1 -0
- package/dist/src/seed/udtSystemRandom.js.map +1 -0
- package/dist/src/udtBleConnection.d.ts +13 -0
- package/dist/src/udtBleConnection.js +66 -19
- package/dist/src/udtBleConnection.js.map +1 -1
- package/dist/src/udtBluetoothAdapterFactory.d.ts +3 -1
- package/dist/src/udtBluetoothAdapterFactory.js +6 -0
- package/dist/src/udtBluetoothAdapterFactory.js.map +1 -1
- package/dist/src/udtDisplayExports.d.ts +2 -0
- package/dist/src/udtDisplayExports.js +26 -0
- package/dist/src/udtDisplayExports.js.map +1 -0
- package/dist/src/udtTowerResponse.js +1 -2
- package/dist/src/udtTowerResponse.js.map +1 -1
- package/package.json +2 -2
- package/dist/src/udtGameBoard.js.map +0 -1
- package/dist/src/udtSeedParser.js.map +0 -1
- package/dist/src/udtSystemRandom.js.map +0 -1
- /package/dist/src/{udtGameBoard.d.ts → data/board/udtGameBoard.d.ts} +0 -0
- /package/dist/src/{udtGameBoard.js → data/board/udtGameBoard.js} +0 -0
- /package/dist/src/{udtSeedParser.d.ts → seed/udtSeedParser.d.ts} +0 -0
- /package/dist/src/{udtSeedParser.js → seed/udtSeedParser.js} +0 -0
- /package/dist/src/{udtSystemRandom.d.ts → seed/udtSystemRandom.d.ts} +0 -0
- /package/dist/src/{udtSystemRandom.js → seed/udtSystemRandom.js} +0 -0
package/dist/esm/index.mjs
CHANGED
|
@@ -9,8 +9,13 @@ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require
|
|
|
9
9
|
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
10
10
|
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
11
11
|
});
|
|
12
|
-
var __esm = (fn, res) => function __init() {
|
|
13
|
-
|
|
12
|
+
var __esm = (fn, res, err) => function __init() {
|
|
13
|
+
if (err) throw err[0];
|
|
14
|
+
try {
|
|
15
|
+
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
16
|
+
} catch (e) {
|
|
17
|
+
throw err = [e], e;
|
|
18
|
+
}
|
|
14
19
|
};
|
|
15
20
|
var __export = (target, all) => {
|
|
16
21
|
for (var name in all)
|
|
@@ -862,6 +867,52 @@ var init_NodeBluetoothAdapter = __esm({
|
|
|
862
867
|
}
|
|
863
868
|
});
|
|
864
869
|
|
|
870
|
+
// src/adapters/NoopBluetoothAdapter.ts
|
|
871
|
+
var NoopBluetoothAdapter_exports = {};
|
|
872
|
+
__export(NoopBluetoothAdapter_exports, {
|
|
873
|
+
NoopBluetoothAdapter: () => NoopBluetoothAdapter
|
|
874
|
+
});
|
|
875
|
+
var NoopBluetoothAdapter;
|
|
876
|
+
var init_NoopBluetoothAdapter = __esm({
|
|
877
|
+
"src/adapters/NoopBluetoothAdapter.ts"() {
|
|
878
|
+
"use strict";
|
|
879
|
+
init_udtBluetoothAdapter();
|
|
880
|
+
NoopBluetoothAdapter = class {
|
|
881
|
+
async connect(_deviceName, _serviceUuids) {
|
|
882
|
+
void _deviceName;
|
|
883
|
+
void _serviceUuids;
|
|
884
|
+
throw new BluetoothError("Bluetooth is disabled (platform: none)");
|
|
885
|
+
}
|
|
886
|
+
async disconnect() {
|
|
887
|
+
}
|
|
888
|
+
isConnected() {
|
|
889
|
+
return false;
|
|
890
|
+
}
|
|
891
|
+
isGattConnected() {
|
|
892
|
+
return false;
|
|
893
|
+
}
|
|
894
|
+
async writeCharacteristic(_data) {
|
|
895
|
+
void _data;
|
|
896
|
+
throw new BluetoothError("Bluetooth is disabled (platform: none)");
|
|
897
|
+
}
|
|
898
|
+
onCharacteristicValueChanged(callback) {
|
|
899
|
+
this.characteristicCallback = callback;
|
|
900
|
+
}
|
|
901
|
+
onDisconnect(callback) {
|
|
902
|
+
this.disconnectCallback = callback;
|
|
903
|
+
}
|
|
904
|
+
onBluetoothAvailabilityChanged(callback) {
|
|
905
|
+
this.availabilityCallback = callback;
|
|
906
|
+
}
|
|
907
|
+
async readDeviceInformation() {
|
|
908
|
+
return {};
|
|
909
|
+
}
|
|
910
|
+
async cleanup() {
|
|
911
|
+
}
|
|
912
|
+
};
|
|
913
|
+
}
|
|
914
|
+
});
|
|
915
|
+
|
|
865
916
|
// src/UltimateDarkTower.ts
|
|
866
917
|
init_udtConstants();
|
|
867
918
|
|
|
@@ -1457,9 +1508,8 @@ var TowerResponseProcessor = class {
|
|
|
1457
1508
|
return [towerCommand.name, commandToPacketString(command)];
|
|
1458
1509
|
case TC.BATTERY: {
|
|
1459
1510
|
const millivolts = getMilliVoltsFromTowerResponse(command);
|
|
1460
|
-
const retval = [towerCommand.name, milliVoltsToPercentage(millivolts)];
|
|
1511
|
+
const retval = [towerCommand.name, `${milliVoltsToPercentage(millivolts)} (${(millivolts / 1e3).toFixed(2)}mv)`];
|
|
1461
1512
|
if (this.logDetail) {
|
|
1462
|
-
retval.push(`${millivolts}mv`);
|
|
1463
1513
|
retval.push(commandToPacketString(command));
|
|
1464
1514
|
}
|
|
1465
1515
|
return retval;
|
|
@@ -1500,11 +1550,12 @@ var TowerResponseProcessor = class {
|
|
|
1500
1550
|
};
|
|
1501
1551
|
|
|
1502
1552
|
// src/udtBluetoothAdapterFactory.ts
|
|
1503
|
-
var BluetoothPlatform = /* @__PURE__ */ ((
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1553
|
+
var BluetoothPlatform = /* @__PURE__ */ ((BluetoothPlatform2) => {
|
|
1554
|
+
BluetoothPlatform2["WEB"] = "web";
|
|
1555
|
+
BluetoothPlatform2["NODE"] = "node";
|
|
1556
|
+
BluetoothPlatform2["AUTO"] = "auto";
|
|
1557
|
+
BluetoothPlatform2["NONE"] = "none";
|
|
1558
|
+
return BluetoothPlatform2;
|
|
1508
1559
|
})(BluetoothPlatform || {});
|
|
1509
1560
|
var BluetoothAdapterFactory = class {
|
|
1510
1561
|
/**
|
|
@@ -1523,6 +1574,10 @@ var BluetoothAdapterFactory = class {
|
|
|
1523
1574
|
const { NodeBluetoothAdapter: NodeBluetoothAdapter2 } = (init_NodeBluetoothAdapter(), __toCommonJS(NodeBluetoothAdapter_exports));
|
|
1524
1575
|
return new NodeBluetoothAdapter2();
|
|
1525
1576
|
}
|
|
1577
|
+
case "none" /* NONE */: {
|
|
1578
|
+
const { NoopBluetoothAdapter: NoopBluetoothAdapter2 } = (init_NoopBluetoothAdapter(), __toCommonJS(NoopBluetoothAdapter_exports));
|
|
1579
|
+
return new NoopBluetoothAdapter2();
|
|
1580
|
+
}
|
|
1526
1581
|
default:
|
|
1527
1582
|
throw new Error(`Unsupported Bluetooth platform: ${detectedPlatform}`);
|
|
1528
1583
|
}
|
|
@@ -1559,6 +1614,12 @@ var UdtBleConnection = class {
|
|
|
1559
1614
|
// higher-level state (command queue, tower state, broken seals) at the
|
|
1560
1615
|
// moment a disconnect cause fires.
|
|
1561
1616
|
this.snapshotProviders = null;
|
|
1617
|
+
// Bluetooth adapter (platform-agnostic).
|
|
1618
|
+
// Null until an adapter is provided or lazily created on first connect() —
|
|
1619
|
+
// construction never triggers platform detection, so creating an
|
|
1620
|
+
// UltimateDarkTower in a non-Bluetooth environment (e.g. iOS Safari) does
|
|
1621
|
+
// not throw. The detection error, if any, surfaces at connect() time.
|
|
1622
|
+
this.bluetoothAdapter = null;
|
|
1562
1623
|
// Connection state
|
|
1563
1624
|
this.isConnected = false;
|
|
1564
1625
|
this.isDisposed = false;
|
|
@@ -1604,17 +1665,41 @@ var UdtBleConnection = class {
|
|
|
1604
1665
|
this.callbacks = callbacks;
|
|
1605
1666
|
this.responseProcessor = new TowerResponseProcessor();
|
|
1606
1667
|
this.recorder = recorder ?? null;
|
|
1607
|
-
|
|
1608
|
-
|
|
1668
|
+
if (adapter) {
|
|
1669
|
+
this.bluetoothAdapter = adapter;
|
|
1670
|
+
this.wireAdapterCallbacks(adapter);
|
|
1671
|
+
}
|
|
1672
|
+
}
|
|
1673
|
+
/**
|
|
1674
|
+
* Wires this connection's internal handlers onto a Bluetooth adapter.
|
|
1675
|
+
* Called when an adapter is supplied at construction, or when one is
|
|
1676
|
+
* lazily created on first connect().
|
|
1677
|
+
*/
|
|
1678
|
+
wireAdapterCallbacks(adapter) {
|
|
1679
|
+
adapter.onCharacteristicValueChanged((data) => {
|
|
1609
1680
|
this.onRxData(data);
|
|
1610
1681
|
});
|
|
1611
|
-
|
|
1682
|
+
adapter.onDisconnect(() => {
|
|
1612
1683
|
this.onTowerDeviceDisconnected();
|
|
1613
1684
|
});
|
|
1614
|
-
|
|
1685
|
+
adapter.onBluetoothAvailabilityChanged((available) => {
|
|
1615
1686
|
this.bleAvailabilityChange(available);
|
|
1616
1687
|
});
|
|
1617
1688
|
}
|
|
1689
|
+
/**
|
|
1690
|
+
* Returns the Bluetooth adapter, lazily creating one via platform
|
|
1691
|
+
* auto-detection on first use. Platform-detection errors (e.g. no Web
|
|
1692
|
+
* Bluetooth on iOS) surface here, at connect time, rather than at
|
|
1693
|
+
* construction.
|
|
1694
|
+
*/
|
|
1695
|
+
ensureAdapter() {
|
|
1696
|
+
if (!this.bluetoothAdapter) {
|
|
1697
|
+
const adapter = BluetoothAdapterFactory.create("auto" /* AUTO */);
|
|
1698
|
+
this.bluetoothAdapter = adapter;
|
|
1699
|
+
this.wireAdapterCallbacks(adapter);
|
|
1700
|
+
}
|
|
1701
|
+
return this.bluetoothAdapter;
|
|
1702
|
+
}
|
|
1618
1703
|
setDiagnosticsSnapshotProviders(providers) {
|
|
1619
1704
|
this.snapshotProviders = providers;
|
|
1620
1705
|
}
|
|
@@ -1650,7 +1735,8 @@ var UdtBleConnection = class {
|
|
|
1650
1735
|
}
|
|
1651
1736
|
this.logger.info("Looking for Tower...", "[UDT]");
|
|
1652
1737
|
try {
|
|
1653
|
-
|
|
1738
|
+
const adapter = this.ensureAdapter();
|
|
1739
|
+
await adapter.connect(
|
|
1654
1740
|
TOWER_DEVICE_NAME,
|
|
1655
1741
|
[UART_SERVICE_UUID, DIS_SERVICE_UUID]
|
|
1656
1742
|
);
|
|
@@ -1675,8 +1761,9 @@ var UdtBleConnection = class {
|
|
|
1675
1761
|
if (this.isConnected) {
|
|
1676
1762
|
this.recordIncident("user_initiated");
|
|
1677
1763
|
}
|
|
1678
|
-
|
|
1679
|
-
|
|
1764
|
+
const adapter = this.bluetoothAdapter;
|
|
1765
|
+
if (adapter?.isConnected()) {
|
|
1766
|
+
await adapter.disconnect();
|
|
1680
1767
|
this.logger.info("Tower disconnected", "[UDT]");
|
|
1681
1768
|
}
|
|
1682
1769
|
this.handleDisconnection();
|
|
@@ -1686,8 +1773,12 @@ var UdtBleConnection = class {
|
|
|
1686
1773
|
* Used by UdtTowerCommands instead of direct characteristic access.
|
|
1687
1774
|
*/
|
|
1688
1775
|
async writeCommand(command) {
|
|
1776
|
+
const adapter = this.bluetoothAdapter;
|
|
1777
|
+
if (!adapter) {
|
|
1778
|
+
throw new Error("Cannot write command: not connected (no Bluetooth adapter)");
|
|
1779
|
+
}
|
|
1689
1780
|
this.recorder?.recordCommandPayload("cmd_sent", command, { len: command.length });
|
|
1690
|
-
return await
|
|
1781
|
+
return await adapter.writeCharacteristic(command);
|
|
1691
1782
|
}
|
|
1692
1783
|
/**
|
|
1693
1784
|
* Processes received data from the RX characteristic (platform-agnostic).
|
|
@@ -1732,7 +1823,7 @@ var UdtBleConnection = class {
|
|
|
1732
1823
|
}
|
|
1733
1824
|
handleTowerStateResponse(receivedData) {
|
|
1734
1825
|
const dataSkullDropCount = receivedData[SKULL_DROP_COUNT_POS];
|
|
1735
|
-
const state = rtdt_unpack_state(receivedData);
|
|
1826
|
+
const state = rtdt_unpack_state(receivedData.slice(TOWER_STATE_DATA_OFFSET, TOWER_STATE_RESPONSE_MIN_LENGTH));
|
|
1736
1827
|
this.logger.debug(`Tower State: ${JSON.stringify(state)} `, "[UDT][BLE]");
|
|
1737
1828
|
this.recorder?.recordEvent("tower_state_response");
|
|
1738
1829
|
if (this.performingCalibration) {
|
|
@@ -1812,7 +1903,7 @@ var UdtBleConnection = class {
|
|
|
1812
1903
|
if (!this.isConnected) {
|
|
1813
1904
|
return;
|
|
1814
1905
|
}
|
|
1815
|
-
if (!this.bluetoothAdapter
|
|
1906
|
+
if (!(this.bluetoothAdapter?.isGattConnected() ?? false)) {
|
|
1816
1907
|
this.logger.warn("GATT connection lost detected during health check", "[UDT][BLE]");
|
|
1817
1908
|
this.recordIncident("gatt_health_check");
|
|
1818
1909
|
this.handleDisconnection();
|
|
@@ -1830,7 +1921,7 @@ var UdtBleConnection = class {
|
|
|
1830
1921
|
}
|
|
1831
1922
|
if (this.batteryHeartbeatVerifyConnection) {
|
|
1832
1923
|
this.logger.info("Verifying tower connection status before triggering disconnection...", "[UDT][BLE]");
|
|
1833
|
-
if (this.bluetoothAdapter
|
|
1924
|
+
if (this.bluetoothAdapter?.isGattConnected() ?? false) {
|
|
1834
1925
|
this.logger.info("GATT connection still available - heartbeat timeout may be temporary", "[UDT][BLE]");
|
|
1835
1926
|
this.recorder?.recordEvent("heartbeat_late", {
|
|
1836
1927
|
sinceMs: timeSinceLastBatteryHeartbeat,
|
|
@@ -1878,7 +1969,7 @@ var UdtBleConnection = class {
|
|
|
1878
1969
|
if (!this.isConnected) {
|
|
1879
1970
|
return false;
|
|
1880
1971
|
}
|
|
1881
|
-
return this.bluetoothAdapter
|
|
1972
|
+
return this.bluetoothAdapter?.isGattConnected() ?? false;
|
|
1882
1973
|
}
|
|
1883
1974
|
getConnectionStatus() {
|
|
1884
1975
|
const now = Date.now();
|
|
@@ -1886,7 +1977,7 @@ var UdtBleConnection = class {
|
|
|
1886
1977
|
const timeSinceLastCommand = this.lastSuccessfulCommand ? now - this.lastSuccessfulCommand : -1;
|
|
1887
1978
|
return {
|
|
1888
1979
|
isConnected: this.isConnected,
|
|
1889
|
-
isGattConnected: this.bluetoothAdapter
|
|
1980
|
+
isGattConnected: this.bluetoothAdapter?.isGattConnected() ?? false,
|
|
1890
1981
|
lastBatteryHeartbeatMs: timeSinceLastBattery,
|
|
1891
1982
|
lastCommandResponseMs: timeSinceLastCommand,
|
|
1892
1983
|
batteryHeartbeatHealthy: timeSinceLastBattery >= 0 && timeSinceLastBattery < this.batteryHeartbeatTimeout,
|
|
@@ -1901,9 +1992,11 @@ var UdtBleConnection = class {
|
|
|
1901
1992
|
return { ...this.deviceInformation };
|
|
1902
1993
|
}
|
|
1903
1994
|
async readDeviceInformation() {
|
|
1995
|
+
const adapter = this.bluetoothAdapter;
|
|
1996
|
+
if (!adapter) return;
|
|
1904
1997
|
try {
|
|
1905
1998
|
this.logger.info("Reading device information service...", "[UDT][BLE]");
|
|
1906
|
-
this.deviceInformation = await
|
|
1999
|
+
this.deviceInformation = await adapter.readDeviceInformation();
|
|
1907
2000
|
for (const [key, value] of Object.entries(this.deviceInformation)) {
|
|
1908
2001
|
if (key !== "lastUpdated" && value) {
|
|
1909
2002
|
this.logger.info(`Device ${key}: ${value}`, "[UDT][BLE]");
|
|
@@ -1921,7 +2014,7 @@ var UdtBleConnection = class {
|
|
|
1921
2014
|
if (this.isConnected) {
|
|
1922
2015
|
await this.disconnect();
|
|
1923
2016
|
}
|
|
1924
|
-
await this.bluetoothAdapter
|
|
2017
|
+
await this.bluetoothAdapter?.cleanup();
|
|
1925
2018
|
}
|
|
1926
2019
|
};
|
|
1927
2020
|
|
|
@@ -3126,6 +3219,15 @@ var UltimateDarkTower = class {
|
|
|
3126
3219
|
void oldState;
|
|
3127
3220
|
void source;
|
|
3128
3221
|
};
|
|
3222
|
+
/**
|
|
3223
|
+
* Called with the raw bytes of every non-battery tower notification (e.g.
|
|
3224
|
+
* tower-state responses). Use this when you need the verbatim packet rather
|
|
3225
|
+
* than the decoded `TowerState` from {@link onTowerStateUpdate} — for example
|
|
3226
|
+
* a relay forwarding the tower's exact 20-byte state to other consumers.
|
|
3227
|
+
*/
|
|
3228
|
+
this.onTowerResponse = (response) => {
|
|
3229
|
+
void response;
|
|
3230
|
+
};
|
|
3129
3231
|
// utility
|
|
3130
3232
|
this._logDetail = false;
|
|
3131
3233
|
this.initializeLogger();
|
|
@@ -3162,7 +3264,7 @@ var UltimateDarkTower = class {
|
|
|
3162
3264
|
let adapter;
|
|
3163
3265
|
if (config?.adapter) {
|
|
3164
3266
|
adapter = config.adapter;
|
|
3165
|
-
} else if (config?.platform) {
|
|
3267
|
+
} else if (config?.platform && config.platform !== "auto" /* AUTO */) {
|
|
3166
3268
|
adapter = BluetoothAdapterFactory.create(config.platform);
|
|
3167
3269
|
}
|
|
3168
3270
|
this.towerEventCallbacks = this.createTowerEventCallbacks();
|
|
@@ -3213,6 +3315,7 @@ var UltimateDarkTower = class {
|
|
|
3213
3315
|
this.updateTowerStateFromResponse(stateData);
|
|
3214
3316
|
}
|
|
3215
3317
|
}
|
|
3318
|
+
this.onTowerResponse(response);
|
|
3216
3319
|
};
|
|
3217
3320
|
}
|
|
3218
3321
|
/**
|
|
@@ -4067,7 +4170,1928 @@ var IndexedDBSink = class {
|
|
|
4067
4170
|
}
|
|
4068
4171
|
};
|
|
4069
4172
|
|
|
4070
|
-
// src/
|
|
4173
|
+
// src/data/index.ts
|
|
4174
|
+
var data_exports = {};
|
|
4175
|
+
__export(data_exports, {
|
|
4176
|
+
board: () => board_exports,
|
|
4177
|
+
content: () => udtGameContent_exports,
|
|
4178
|
+
foes: () => udtFoes_exports,
|
|
4179
|
+
heroes: () => udtHeroes_exports,
|
|
4180
|
+
inventory: () => udtBoxInventory_exports,
|
|
4181
|
+
monuments: () => udtMonuments_exports
|
|
4182
|
+
});
|
|
4183
|
+
|
|
4184
|
+
// src/data/udtHeroes.ts
|
|
4185
|
+
var udtHeroes_exports = {};
|
|
4186
|
+
__export(udtHeroes_exports, {
|
|
4187
|
+
HEROES: () => HEROES,
|
|
4188
|
+
HERO_BY_ID: () => HERO_BY_ID
|
|
4189
|
+
});
|
|
4190
|
+
var HEROES = [
|
|
4191
|
+
// Base (4)
|
|
4192
|
+
{ id: "brutal-warlord", name: "Brutal Warlord", source: "base" },
|
|
4193
|
+
{ id: "orphaned-scion", name: "Orphaned Scion", source: "base" },
|
|
4194
|
+
{ id: "relic-hunter", name: "Relic Hunter", source: "base" },
|
|
4195
|
+
{ id: "spymaster", name: "Spymaster", source: "base" },
|
|
4196
|
+
// Alliances (2)
|
|
4197
|
+
{ id: "archwright", name: "Archwright", source: "alliances" },
|
|
4198
|
+
{ id: "haunted-recluse", name: "Haunted Recluse", source: "alliances" },
|
|
4199
|
+
// Covenant (4)
|
|
4200
|
+
{ id: "devious-swindler", name: "Devious Swindler", source: "covenant" },
|
|
4201
|
+
{ id: "relentless-warden", name: "Relentless Warden", source: "covenant" },
|
|
4202
|
+
{ id: "reverent-astromancer", name: "Reverent Astromancer", source: "covenant" },
|
|
4203
|
+
{ id: "undaunted-aegis", name: "Undaunted Aegis", source: "covenant" },
|
|
4204
|
+
// Expeditions (4, unreleased — provisional)
|
|
4205
|
+
{ id: "jocular-druid", name: "Jocular Druid", source: "expeditions" },
|
|
4206
|
+
{ id: "grizzled-mariner", name: "Grizzled Mariner", source: "expeditions" },
|
|
4207
|
+
{ id: "clever-tinkerer", name: "Clever Tinkerer", source: "expeditions" },
|
|
4208
|
+
{ id: "enlightened-ascetic", name: "Enlightened Ascetic", source: "expeditions" }
|
|
4209
|
+
];
|
|
4210
|
+
var HERO_BY_ID = Object.freeze(
|
|
4211
|
+
HEROES.reduce((acc, hero) => {
|
|
4212
|
+
acc[hero.id] = hero;
|
|
4213
|
+
return acc;
|
|
4214
|
+
}, {})
|
|
4215
|
+
);
|
|
4216
|
+
|
|
4217
|
+
// src/data/udtMonuments.ts
|
|
4218
|
+
var udtMonuments_exports = {};
|
|
4219
|
+
__export(udtMonuments_exports, {
|
|
4220
|
+
MONUMENTS: () => MONUMENTS,
|
|
4221
|
+
MONUMENT_BY_ID: () => MONUMENT_BY_ID
|
|
4222
|
+
});
|
|
4223
|
+
var MONUMENTS = [
|
|
4224
|
+
{ id: "arch-of-the-golden-sun", name: "Arch of the Golden Sun", source: "covenant" },
|
|
4225
|
+
{ id: "argent-oak", name: "Argent Oak", source: "covenant" },
|
|
4226
|
+
{ id: "cenotaph-of-the-first-prophet", name: "Cenotaph of the First Prophet", source: "covenant" },
|
|
4227
|
+
{ id: "colossus-of-bjorn", name: "Colossus of Bjorn", source: "covenant" },
|
|
4228
|
+
{ id: "endless-necropolis", name: "Endless Necropolis", source: "covenant" },
|
|
4229
|
+
{ id: "moonstone-temple", name: "Moonstone Temple", source: "covenant" },
|
|
4230
|
+
{ id: "nightmare-cage", name: "Nightmare Cage", source: "covenant" },
|
|
4231
|
+
{ id: "tower-shard", name: "Tower Shard", source: "covenant" }
|
|
4232
|
+
];
|
|
4233
|
+
var MONUMENT_BY_ID = Object.freeze(
|
|
4234
|
+
MONUMENTS.reduce((acc, monument) => {
|
|
4235
|
+
acc[monument.id] = monument;
|
|
4236
|
+
return acc;
|
|
4237
|
+
}, {})
|
|
4238
|
+
);
|
|
4239
|
+
|
|
4240
|
+
// src/data/udtFoes.ts
|
|
4241
|
+
var udtFoes_exports = {};
|
|
4242
|
+
__export(udtFoes_exports, {
|
|
4243
|
+
ADVERSARY_ROSTER: () => ADVERSARY_ROSTER,
|
|
4244
|
+
ALL_FOES: () => ALL_FOES,
|
|
4245
|
+
FOES: () => FOES,
|
|
4246
|
+
FOE_BY_ID: () => FOE_BY_ID,
|
|
4247
|
+
FOE_BY_NAME: () => FOE_BY_NAME,
|
|
4248
|
+
FOE_STATUSES: () => FOE_STATUSES
|
|
4249
|
+
});
|
|
4250
|
+
var FOE_STATUSES = ["panicked", "unsteady", "ready", "savage", "lethal"];
|
|
4251
|
+
var FOES = [
|
|
4252
|
+
// Tier 1 — level 2
|
|
4253
|
+
{ id: "brigands", name: "Brigands", kind: "foe", level: 2, tier: 1, source: "base" },
|
|
4254
|
+
{ id: "oreks", name: "Oreks", kind: "foe", level: 2, tier: 1, source: "base" },
|
|
4255
|
+
{ id: "shadow-wolves", name: "Shadow Wolves", kind: "foe", level: 2, tier: 1, source: "base" },
|
|
4256
|
+
{ id: "spine-fiends", name: "Spine Fiends", kind: "foe", level: 2, tier: 1, source: "base" },
|
|
4257
|
+
// Tier 2 — level 3
|
|
4258
|
+
{ id: "frost-trolls", name: "Frost Trolls", kind: "foe", level: 3, tier: 2, source: "base" },
|
|
4259
|
+
{ id: "clan-of-neuri", name: "Clan of Neuri", kind: "foe", level: 3, tier: 2, source: "base" },
|
|
4260
|
+
{ id: "lemures", name: "Lemures", kind: "foe", level: 3, tier: 2, source: "base" },
|
|
4261
|
+
{ id: "widowmade-spiders", name: "Widowmade Spiders", kind: "foe", level: 3, tier: 2, source: "base" },
|
|
4262
|
+
// Tier 3 — level 4
|
|
4263
|
+
{ id: "dragons", name: "Dragons", kind: "foe", level: 4, tier: 3, source: "base" },
|
|
4264
|
+
{ id: "mormos", name: "Mormos", kind: "foe", level: 4, tier: 3, source: "base" },
|
|
4265
|
+
{ id: "striga", name: "Striga", kind: "foe", level: 4, tier: 3, source: "base" },
|
|
4266
|
+
{ id: "titans", name: "Titans", kind: "foe", level: 4, tier: 3, source: "base" }
|
|
4267
|
+
];
|
|
4268
|
+
var ADVERSARY_ROSTER = [
|
|
4269
|
+
{ id: "ashstrider", name: "Ashstrider", kind: "adversary", level: 5, source: "base" },
|
|
4270
|
+
{ id: "bane-of-omens", name: "Bane of Omens", kind: "adversary", level: 5, source: "base" },
|
|
4271
|
+
{ id: "empress-of-shades", name: "Empress of Shades", kind: "adversary", level: 5, source: "base" },
|
|
4272
|
+
{ id: "gaze-eternal", name: "Gaze Eternal", kind: "adversary", level: 5, source: "base" },
|
|
4273
|
+
{ id: "gravemaw", name: "Gravemaw", kind: "adversary", level: 5, source: "base" },
|
|
4274
|
+
{ id: "isa-the-exile", name: "Isa the Exile", kind: "adversary", level: 5, source: "base" },
|
|
4275
|
+
{ id: "lingering-rot", name: "Lingering Rot", kind: "adversary", level: 5, source: "base" },
|
|
4276
|
+
{ id: "utuk-ku", name: "Utuk'Ku", kind: "adversary", level: 5, source: "base" }
|
|
4277
|
+
];
|
|
4278
|
+
var ALL_FOES = [...FOES, ...ADVERSARY_ROSTER];
|
|
4279
|
+
var FOE_BY_ID = Object.freeze(
|
|
4280
|
+
ALL_FOES.reduce((acc, foe) => {
|
|
4281
|
+
acc[foe.id] = foe;
|
|
4282
|
+
return acc;
|
|
4283
|
+
}, {})
|
|
4284
|
+
);
|
|
4285
|
+
var FOE_BY_NAME = Object.freeze(
|
|
4286
|
+
ALL_FOES.reduce((acc, foe) => {
|
|
4287
|
+
acc[foe.name] = foe;
|
|
4288
|
+
return acc;
|
|
4289
|
+
}, {})
|
|
4290
|
+
);
|
|
4291
|
+
|
|
4292
|
+
// src/data/board/index.ts
|
|
4293
|
+
var board_exports = {};
|
|
4294
|
+
__export(board_exports, {
|
|
4295
|
+
BOARD_ADJACENCY: () => BOARD_ADJACENCY,
|
|
4296
|
+
BOARD_ANCHORS: () => BOARD_ANCHORS,
|
|
4297
|
+
BOARD_GROUPINGS: () => BOARD_GROUPINGS,
|
|
4298
|
+
BOARD_IMAGE_INFO: () => BOARD_IMAGE_INFO,
|
|
4299
|
+
BOARD_LOCATIONS: () => BOARD_LOCATIONS,
|
|
4300
|
+
BOARD_LOCATION_BY_NAME: () => BOARD_LOCATION_BY_NAME,
|
|
4301
|
+
neighborsOf: () => neighborsOf,
|
|
4302
|
+
shortestPath: () => shortestPath,
|
|
4303
|
+
stepDistance: () => stepDistance
|
|
4304
|
+
});
|
|
4305
|
+
|
|
4306
|
+
// src/data/board/udtGameBoard.ts
|
|
4307
|
+
var BOARD_GROUPINGS = {
|
|
4308
|
+
/** Dayside and Fivepint (North kingdom lakes). */
|
|
4309
|
+
LONG_WATER: "Long Water",
|
|
4310
|
+
/** Delmsmire, Arkartus, and Yellowpike (West kingdom forests). */
|
|
4311
|
+
THE_GREAT_WOODS: "The Great Woods",
|
|
4312
|
+
/** The Throne, The Cloister, and Archmont (South kingdom grasslands). */
|
|
4313
|
+
REGAL_RUN: "Regal Run"
|
|
4314
|
+
};
|
|
4315
|
+
var BOARD_LOCATIONS = [
|
|
4316
|
+
// ── North ───────────────────────────────────────────────────────────────
|
|
4317
|
+
{ name: "Broken Lands", terrain: "Hills", kingdom: "north" },
|
|
4318
|
+
{ name: "Dayside", terrain: "Lake", building: "Bazaar", kingdom: "north", grouping: BOARD_GROUPINGS.LONG_WATER },
|
|
4319
|
+
{ name: "Egan's End", terrain: "Grasslands", building: "Village", kingdom: "north" },
|
|
4320
|
+
{ name: "Fivepint", terrain: "Lake", kingdom: "north", grouping: BOARD_GROUPINGS.LONG_WATER },
|
|
4321
|
+
{ name: "Green Bridge", terrain: "Grasslands", kingdom: "north" },
|
|
4322
|
+
{ name: "Lodestone Mountains", terrain: "Mountains", kingdom: "north" },
|
|
4323
|
+
{ name: "Lower Ice Fangs", terrain: "Mountains", kingdom: "north" },
|
|
4324
|
+
{ name: "Muted Forest", terrain: "Forest", kingdom: "north" },
|
|
4325
|
+
{ name: "Peaks of the Djinn", terrain: "Mountains", kingdom: "north" },
|
|
4326
|
+
{ name: "Pearl of the North", terrain: "Grasslands", kingdom: "north" },
|
|
4327
|
+
{ name: "Radiant Mountains", terrain: "Mountains", building: "Citadel", kingdom: "north" },
|
|
4328
|
+
{ name: "Rimeweald", terrain: "Forest", kingdom: "north" },
|
|
4329
|
+
{ name: "The Tundra", terrain: "Desert", kingdom: "north" },
|
|
4330
|
+
{ name: "Tower Scar Desert", terrain: "Desert", kingdom: "north" },
|
|
4331
|
+
{ name: "Upper Ice Fangs", terrain: "Mountains", building: "Sanctuary", kingdom: "north" },
|
|
4332
|
+
// ── East ────────────────────────────────────────────────────────────────
|
|
4333
|
+
{ name: "Big Sister", terrain: "Mountains", kingdom: "east" },
|
|
4334
|
+
{ name: "Bleak Wastes", terrain: "Desert", kingdom: "east" },
|
|
4335
|
+
{ name: "Copper Grove", terrain: "Forest", kingdom: "east" },
|
|
4336
|
+
{ name: "Dragontooth Lake", terrain: "Lake", kingdom: "east" },
|
|
4337
|
+
{ name: "Duwani", terrain: "Grasslands", building: "Village", kingdom: "east" },
|
|
4338
|
+
{ name: "Forest of Shades", terrain: "Forest", kingdom: "east" },
|
|
4339
|
+
{ name: "Greater Tombstones", terrain: "Hills", building: "Sanctuary", kingdom: "east" },
|
|
4340
|
+
{ name: "Inner Kinghills", terrain: "Hills", building: "Citadel", kingdom: "east" },
|
|
4341
|
+
{ name: "Jewel Hills", terrain: "Hills", kingdom: "east" },
|
|
4342
|
+
{ name: "Lake of Songs", terrain: "Lake", kingdom: "east" },
|
|
4343
|
+
{ name: "Lesser Tombstones", terrain: "Hills", kingdom: "east" },
|
|
4344
|
+
{ name: "Outer Kinghills", terrain: "Hills", kingdom: "east" },
|
|
4345
|
+
{ name: "The Decaying Wilds", terrain: "Grasslands", kingdom: "east" },
|
|
4346
|
+
{ name: "Three Rivers", terrain: "Grasslands", building: "Bazaar", kingdom: "east" },
|
|
4347
|
+
{ name: "Utar's Barrows", terrain: "Desert", kingdom: "east" },
|
|
4348
|
+
// ── West ────────────────────────────────────────────────────────────────
|
|
4349
|
+
{ name: "Anza", terrain: "Grasslands", building: "Village", kingdom: "west" },
|
|
4350
|
+
{ name: "Arkartus", terrain: "Forest", building: "Sanctuary", kingdom: "west", grouping: BOARD_GROUPINGS.THE_GREAT_WOODS },
|
|
4351
|
+
{ name: "Ash Hills", terrain: "Hills", kingdom: "west" },
|
|
4352
|
+
{ name: "Cloudhold", terrain: "Mountains", kingdom: "west" },
|
|
4353
|
+
{ name: "Delmsmire", terrain: "Forest", kingdom: "west", grouping: BOARD_GROUPINGS.THE_GREAT_WOODS },
|
|
4354
|
+
{ name: "Hissing Groves", terrain: "Forest", building: "Citadel", kingdom: "west" },
|
|
4355
|
+
{ name: "Idran Forest", terrain: "Forest", kingdom: "west" },
|
|
4356
|
+
{ name: "Lonelight Hills", terrain: "Hills", kingdom: "west" },
|
|
4357
|
+
{ name: "Lost Lands", terrain: "Desert", kingdom: "west" },
|
|
4358
|
+
{ name: "Plains of Plovo", terrain: "Grasslands", building: "Bazaar", kingdom: "west" },
|
|
4359
|
+
{ name: "Plains of Woldra", terrain: "Grasslands", kingdom: "west" },
|
|
4360
|
+
{ name: "The Empty Glade", terrain: "Grasslands", kingdom: "west" },
|
|
4361
|
+
{ name: "The Grass Sea", terrain: "Grasslands", kingdom: "west" },
|
|
4362
|
+
{ name: "Weeping Waters", terrain: "Lake", kingdom: "west" },
|
|
4363
|
+
{ name: "Yellowpike", terrain: "Forest", kingdom: "west", grouping: BOARD_GROUPINGS.THE_GREAT_WOODS },
|
|
4364
|
+
// ── South ───────────────────────────────────────────────────────────────
|
|
4365
|
+
{ name: "Archmont", terrain: "Grasslands", kingdom: "south", grouping: BOARD_GROUPINGS.REGAL_RUN },
|
|
4366
|
+
{ name: "Azkol's Bane", terrain: "Desert", kingdom: "south" },
|
|
4367
|
+
{ name: "Bone Hills", terrain: "Hills", kingdom: "south" },
|
|
4368
|
+
{ name: "Howling Desert", terrain: "Desert", building: "Citadel", kingdom: "south" },
|
|
4369
|
+
{ name: "Irontops", terrain: "Mountains", kingdom: "south" },
|
|
4370
|
+
{ name: "Little Sister", terrain: "Mountains", kingdom: "south" },
|
|
4371
|
+
{ name: "Middle Sister", terrain: "Mountains", kingdom: "south" },
|
|
4372
|
+
{ name: "Mountains of the Watchers", terrain: "Mountains", kingdom: "south" },
|
|
4373
|
+
{ name: "Pine Barrens", terrain: "Forest", kingdom: "south" },
|
|
4374
|
+
{ name: "Sands of Madness", terrain: "Desert", building: "Sanctuary", kingdom: "south" },
|
|
4375
|
+
{ name: "Southern Wastes", terrain: "Desert", building: "Village", kingdom: "south" },
|
|
4376
|
+
{ name: "The Cloister", terrain: "Grasslands", kingdom: "south", grouping: BOARD_GROUPINGS.REGAL_RUN },
|
|
4377
|
+
{ name: "The Emerald Expanse", terrain: "Grasslands", building: "Bazaar", kingdom: "south" },
|
|
4378
|
+
{ name: "The Throne", terrain: "Grasslands", kingdom: "south", grouping: BOARD_GROUPINGS.REGAL_RUN },
|
|
4379
|
+
{ name: "Ulamel's Hollow", terrain: "Grasslands", kingdom: "south" }
|
|
4380
|
+
];
|
|
4381
|
+
var BOARD_LOCATION_BY_NAME = Object.fromEntries(BOARD_LOCATIONS.map((loc) => [loc.name, loc]));
|
|
4382
|
+
|
|
4383
|
+
// src/data/board/udtBoardAnchors.ts
|
|
4384
|
+
var BOARD_IMAGE_INFO = {
|
|
4385
|
+
width: 4096,
|
|
4386
|
+
height: 4096,
|
|
4387
|
+
centerX: 0.5,
|
|
4388
|
+
centerY: 0.5,
|
|
4389
|
+
radius: 0.5,
|
|
4390
|
+
northHeadingDegrees: 135
|
|
4391
|
+
};
|
|
4392
|
+
var BOARD_ANCHORS = {
|
|
4393
|
+
"Broken Lands": {
|
|
4394
|
+
hero: { x: 0.80599, y: 0.51238 },
|
|
4395
|
+
foe: { x: 0.8355, y: 0.50648 },
|
|
4396
|
+
marker: { x: 0.81451, y: 0.53009 }
|
|
4397
|
+
},
|
|
4398
|
+
Dayside: {
|
|
4399
|
+
building: { x: 0.74564, y: 0.7754 },
|
|
4400
|
+
skull: { x: 0.75351, y: 0.77147 },
|
|
4401
|
+
hero: { x: 0.78708, y: 0.84542 },
|
|
4402
|
+
foe: { x: 0.82397, y: 0.81232 },
|
|
4403
|
+
marker: { x: 0.79742, y: 0.81818 }
|
|
4404
|
+
},
|
|
4405
|
+
"Egan's End": {
|
|
4406
|
+
building: { x: 0.57088, y: 0.9152 },
|
|
4407
|
+
skull: { x: 0.57506, y: 0.92844 },
|
|
4408
|
+
hero: { x: 0.65606, y: 0.89196 },
|
|
4409
|
+
foe: { x: 0.66675, y: 0.91679 },
|
|
4410
|
+
marker: { x: 0.63365, y: 0.91644 }
|
|
4411
|
+
},
|
|
4412
|
+
Fivepint: {
|
|
4413
|
+
marker: { x: 0.84691, y: 0.76433 },
|
|
4414
|
+
hero: { x: 0.82, y: 0.75615 },
|
|
4415
|
+
foe: { x: 0.83838, y: 0.73603 }
|
|
4416
|
+
},
|
|
4417
|
+
"Green Bridge": {
|
|
4418
|
+
hero: { x: 0.73574, y: 0.71149 },
|
|
4419
|
+
foe: { x: 0.77097, y: 0.67222 },
|
|
4420
|
+
marker: { x: 0.76259, y: 0.69647 }
|
|
4421
|
+
},
|
|
4422
|
+
"Lodestone Mountains": {
|
|
4423
|
+
hero: { x: 0.90983, y: 0.54979 },
|
|
4424
|
+
foe: { x: 0.93133, y: 0.52482 },
|
|
4425
|
+
marker: { x: 0.92439, y: 0.57164 }
|
|
4426
|
+
},
|
|
4427
|
+
"Lower Ice Fangs": {
|
|
4428
|
+
hero: { x: 0.644, y: 0.75336 },
|
|
4429
|
+
foe: { x: 0.60986, y: 0.76715 },
|
|
4430
|
+
marker: { x: 0.65399, y: 0.77853 }
|
|
4431
|
+
},
|
|
4432
|
+
"Muted Forest": {
|
|
4433
|
+
hero: { x: 0.72254, y: 0.57754 },
|
|
4434
|
+
foe: { x: 0.71006, y: 0.53557 },
|
|
4435
|
+
marker: { x: 0.74474, y: 0.54875 }
|
|
4436
|
+
},
|
|
4437
|
+
"Peaks of the Djinn": {
|
|
4438
|
+
hero: { x: 0.52263, y: 0.73716 },
|
|
4439
|
+
foe: { x: 0.53056, y: 0.76095 },
|
|
4440
|
+
marker: { x: 0.53401, y: 0.78715 }
|
|
4441
|
+
},
|
|
4442
|
+
"Pearl of the North": {
|
|
4443
|
+
marker: { x: 0.90091, y: 0.66962 },
|
|
4444
|
+
hero: { x: 0.89715, y: 0.69647 },
|
|
4445
|
+
foe: { x: 0.91852, y: 0.64046 }
|
|
4446
|
+
},
|
|
4447
|
+
"Radiant Mountains": {
|
|
4448
|
+
building: { x: 0.82063, y: 0.64652 },
|
|
4449
|
+
skull: { x: 0.82727, y: 0.64883 },
|
|
4450
|
+
hero: { x: 0.81081, y: 0.6058 },
|
|
4451
|
+
foe: { x: 0.82294, y: 0.57982 },
|
|
4452
|
+
marker: { x: 0.85182, y: 0.59425 }
|
|
4453
|
+
},
|
|
4454
|
+
Rimeweald: {
|
|
4455
|
+
hero: { x: 0.58228, y: 0.83094 },
|
|
4456
|
+
foe: { x: 0.54746, y: 0.84576 },
|
|
4457
|
+
marker: { x: 0.614, y: 0.84852 }
|
|
4458
|
+
},
|
|
4459
|
+
"The Tundra": {
|
|
4460
|
+
hero: { x: 0.71123, y: 0.84955 },
|
|
4461
|
+
foe: { x: 0.69675, y: 0.82094 },
|
|
4462
|
+
marker: { x: 0.72778, y: 0.87369 }
|
|
4463
|
+
},
|
|
4464
|
+
"Tower Scar Desert": {
|
|
4465
|
+
marker: { x: 0.63365, y: 0.57476 },
|
|
4466
|
+
hero: { x: 0.64227, y: 0.53994 },
|
|
4467
|
+
foe: { x: 0.58642, y: 0.61028 }
|
|
4468
|
+
},
|
|
4469
|
+
"Upper Ice Fangs": {
|
|
4470
|
+
building: { x: 0.68089, y: 0.66613 },
|
|
4471
|
+
skull: { x: 0.68571, y: 0.66096 },
|
|
4472
|
+
foe: { x: 0.5478, y: 0.67889 },
|
|
4473
|
+
hero: { x: 0.63882, y: 0.7044 },
|
|
4474
|
+
marker: { x: 0.59159, y: 0.67578 }
|
|
4475
|
+
},
|
|
4476
|
+
"Big Sister": {
|
|
4477
|
+
hero: { x: 0.29269, y: 0.60241 },
|
|
4478
|
+
foe: { x: 0.28651, y: 0.56064 },
|
|
4479
|
+
marker: { x: 0.26136, y: 0.54023 }
|
|
4480
|
+
},
|
|
4481
|
+
"Bleak Wastes": {
|
|
4482
|
+
marker: { x: 0.45929, y: 0.67741 },
|
|
4483
|
+
hero: { x: 0.44885, y: 0.64751 },
|
|
4484
|
+
foe: { x: 0.47163, y: 0.65937 }
|
|
4485
|
+
},
|
|
4486
|
+
"Copper Grove": {
|
|
4487
|
+
hero: { x: 0.34044, y: 0.8742 },
|
|
4488
|
+
foe: { x: 0.37074, y: 0.91984 },
|
|
4489
|
+
marker: { x: 0.3369, y: 0.90017 }
|
|
4490
|
+
},
|
|
4491
|
+
"Dragontooth Lake": {
|
|
4492
|
+
marker: { x: 0.43784, y: 0.75253 },
|
|
4493
|
+
hero: { x: 0.38955, y: 0.70385 },
|
|
4494
|
+
foe: { x: 0.38599, y: 0.7367 }
|
|
4495
|
+
},
|
|
4496
|
+
Duwani: {
|
|
4497
|
+
building: { x: 0.21975, y: 0.79014 },
|
|
4498
|
+
skull: { x: 0.22094, y: 0.79251 },
|
|
4499
|
+
hero: { x: 0.20946, y: 0.83367 },
|
|
4500
|
+
foe: { x: 0.18729, y: 0.76599 },
|
|
4501
|
+
marker: { x: 0.16988, y: 0.77905 }
|
|
4502
|
+
},
|
|
4503
|
+
"Forest of Shades": {
|
|
4504
|
+
hero: { x: 0.36184, y: 0.57047 },
|
|
4505
|
+
foe: { x: 0.35393, y: 0.54355 },
|
|
4506
|
+
marker: { x: 0.37965, y: 0.6053 }
|
|
4507
|
+
},
|
|
4508
|
+
"Greater Tombstones": {
|
|
4509
|
+
building: { x: 0.31989, y: 0.66902 },
|
|
4510
|
+
skull: { x: 0.32384, y: 0.66467 },
|
|
4511
|
+
hero: { x: 0.27041, y: 0.67773 },
|
|
4512
|
+
foe: { x: 0.22133, y: 0.66546 },
|
|
4513
|
+
marker: { x: 0.25933, y: 0.65675 }
|
|
4514
|
+
},
|
|
4515
|
+
"Inner Kinghills": {
|
|
4516
|
+
building: { x: 0.4061, y: 0.83461 },
|
|
4517
|
+
skull: { x: 0.41279, y: 0.83658 },
|
|
4518
|
+
hero: { x: 0.45685, y: 0.81494 },
|
|
4519
|
+
foe: { x: 0.43364, y: 0.87592 },
|
|
4520
|
+
marker: { x: 0.46236, y: 0.84169 }
|
|
4521
|
+
},
|
|
4522
|
+
"Jewel Hills": {
|
|
4523
|
+
marker: { x: 0.26293, y: 0.86082 },
|
|
4524
|
+
foe: { x: 0.29301, y: 0.81688 },
|
|
4525
|
+
hero: { x: 0.27599, y: 0.84063 }
|
|
4526
|
+
},
|
|
4527
|
+
"Lake of Songs": {
|
|
4528
|
+
hero: { x: 0.1157, y: 0.71675 },
|
|
4529
|
+
foe: { x: 0.14498, y: 0.72862 },
|
|
4530
|
+
marker: { x: 0.10778, y: 0.68825 }
|
|
4531
|
+
},
|
|
4532
|
+
"Lesser Tombstones": {
|
|
4533
|
+
hero: { x: 0.19169, y: 0.5889 },
|
|
4534
|
+
foe: { x: 0.18179, y: 0.6178 },
|
|
4535
|
+
marker: { x: 0.1715, y: 0.655 }
|
|
4536
|
+
},
|
|
4537
|
+
"Outer Kinghills": {
|
|
4538
|
+
hero: { x: 0.49606, y: 0.90673 },
|
|
4539
|
+
foe: { x: 0.44183, y: 0.91306 },
|
|
4540
|
+
marker: { x: 0.46242, y: 0.9289 }
|
|
4541
|
+
},
|
|
4542
|
+
"The Decaying Wilds": {
|
|
4543
|
+
marker: { x: 0.34526, y: 0.79037 },
|
|
4544
|
+
hero: { x: 0.31399, y: 0.77414 },
|
|
4545
|
+
foe: { x: 0.33339, y: 0.76503 }
|
|
4546
|
+
},
|
|
4547
|
+
"Three Rivers": {
|
|
4548
|
+
building: { x: 0.10461, y: 0.59524 },
|
|
4549
|
+
skull: { x: 0.10976, y: 0.59445 },
|
|
4550
|
+
hero: { x: 0.10066, y: 0.56159 },
|
|
4551
|
+
foe: { x: 0.05672, y: 0.60869 },
|
|
4552
|
+
marker: { x: 0.07216, y: 0.56516 }
|
|
4553
|
+
},
|
|
4554
|
+
"Utar's Barrows": {
|
|
4555
|
+
hero: { x: 0.21227, y: 0.72268 },
|
|
4556
|
+
foe: { x: 0.27322, y: 0.75554 },
|
|
4557
|
+
marker: { x: 0.25502, y: 0.73416 }
|
|
4558
|
+
},
|
|
4559
|
+
Archmont: {
|
|
4560
|
+
marker: { x: 0.28906, y: 0.28849 },
|
|
4561
|
+
hero: { x: 0.2475, y: 0.26474 },
|
|
4562
|
+
foe: { x: 0.22375, y: 0.24297 }
|
|
4563
|
+
},
|
|
4564
|
+
"Azkol's Bane": {
|
|
4565
|
+
hero: { x: 0.31755, y: 0.2026 },
|
|
4566
|
+
foe: { x: 0.35515, y: 0.20339 },
|
|
4567
|
+
marker: { x: 0.2851, y: 0.22002 }
|
|
4568
|
+
},
|
|
4569
|
+
"Bone Hills": {
|
|
4570
|
+
marker: { x: 0.26112, y: 0.1386 },
|
|
4571
|
+
hero: { x: 0.23354, y: 0.15298 },
|
|
4572
|
+
foe: { x: 0.28374, y: 0.10136 }
|
|
4573
|
+
},
|
|
4574
|
+
"Howling Desert": {
|
|
4575
|
+
building: { x: 0.46416, y: 0.25928 },
|
|
4576
|
+
skull: { x: 0.46145, y: 0.25218 },
|
|
4577
|
+
hero: { x: 0.41951, y: 0.22546 },
|
|
4578
|
+
foe: { x: 0.47464, y: 0.2011 },
|
|
4579
|
+
marker: { x: 0.44488, y: 0.20009 }
|
|
4580
|
+
},
|
|
4581
|
+
Irontops: {
|
|
4582
|
+
hero: { x: 0.44934, y: 0.35744 },
|
|
4583
|
+
foe: { x: 0.46636, y: 0.32986 },
|
|
4584
|
+
marker: { x: 0.425, y: 0.33632 }
|
|
4585
|
+
},
|
|
4586
|
+
"Little Sister": {
|
|
4587
|
+
hero: { x: 0.23451, y: 0.34805 },
|
|
4588
|
+
foe: { x: 0.21272, y: 0.32604 },
|
|
4589
|
+
marker: { x: 0.19827, y: 0.36466 }
|
|
4590
|
+
},
|
|
4591
|
+
"Middle Sister": {
|
|
4592
|
+
hero: { x: 0.16203, y: 0.46453 },
|
|
4593
|
+
foe: { x: 0.1493, y: 0.49904 },
|
|
4594
|
+
marker: { x: 0.15513, y: 0.43088 }
|
|
4595
|
+
},
|
|
4596
|
+
"Mountains of the Watchers": {
|
|
4597
|
+
hero: { x: 0.49023, y: 0.12066 },
|
|
4598
|
+
foe: { x: 0.45633, y: 0.09633 },
|
|
4599
|
+
marker: { x: 0.4994, y: 0.18246 }
|
|
4600
|
+
},
|
|
4601
|
+
"Pine Barrens": {
|
|
4602
|
+
hero: { x: 0.06957, y: 0.49147 },
|
|
4603
|
+
foe: { x: 0.07316, y: 0.4185 },
|
|
4604
|
+
marker: { x: 0.06957, y: 0.45478 }
|
|
4605
|
+
},
|
|
4606
|
+
"Sands of Madness": {
|
|
4607
|
+
building: { x: 0.27133, y: 0.44721 },
|
|
4608
|
+
skull: { x: 0.26256, y: 0.44561 },
|
|
4609
|
+
hero: { x: 0.28249, y: 0.39777 },
|
|
4610
|
+
foe: { x: 0.30083, y: 0.33636 },
|
|
4611
|
+
marker: { x: 0.29964, y: 0.37464 }
|
|
4612
|
+
},
|
|
4613
|
+
"Southern Wastes": {
|
|
4614
|
+
marker: { x: 0.16607, y: 0.22512 },
|
|
4615
|
+
building: { x: 0.16248, y: 0.29211 },
|
|
4616
|
+
skull: { x: 0.1553, y: 0.28931 },
|
|
4617
|
+
hero: { x: 0.16686, y: 0.24466 },
|
|
4618
|
+
foe: { x: 0.17723, y: 0.19242 }
|
|
4619
|
+
},
|
|
4620
|
+
"The Cloister": {
|
|
4621
|
+
hero: { x: 0.35027, y: 0.30566 },
|
|
4622
|
+
foe: { x: 0.39692, y: 0.28014 },
|
|
4623
|
+
marker: { x: 0.36862, y: 0.28254 }
|
|
4624
|
+
},
|
|
4625
|
+
"The Emerald Expanse": {
|
|
4626
|
+
building: { x: 0.3746, y: 0.14179 },
|
|
4627
|
+
skull: { x: 0.37699, y: 0.14817 },
|
|
4628
|
+
hero: { x: 0.34071, y: 0.08955 },
|
|
4629
|
+
foe: { x: 0.43121, y: 0.05407 },
|
|
4630
|
+
marker: { x: 0.38177, y: 0.08357 }
|
|
4631
|
+
},
|
|
4632
|
+
"The Throne": {
|
|
4633
|
+
marker: { x: 0.35865, y: 0.43166 },
|
|
4634
|
+
hero: { x: 0.36782, y: 0.38979 },
|
|
4635
|
+
foe: { x: 0.33991, y: 0.46236 }
|
|
4636
|
+
},
|
|
4637
|
+
"Ulamel's Hollow": {
|
|
4638
|
+
foe: { x: 0.10307, y: 0.38022 },
|
|
4639
|
+
hero: { x: 0.11981, y: 0.34872 },
|
|
4640
|
+
marker: { x: 0.0935, y: 0.34952 }
|
|
4641
|
+
},
|
|
4642
|
+
Anza: {
|
|
4643
|
+
building: { x: 0.69519, y: 0.13269 },
|
|
4644
|
+
skull: { x: 0.69876, y: 0.1242 },
|
|
4645
|
+
hero: { x: 0.67642, y: 0.16664 },
|
|
4646
|
+
foe: { x: 0.72244, y: 0.16888 },
|
|
4647
|
+
marker: { x: 0.74656, y: 0.14609 }
|
|
4648
|
+
},
|
|
4649
|
+
Arkartus: {
|
|
4650
|
+
building: { x: 0.81849, y: 0.28504 },
|
|
4651
|
+
skull: { x: 0.82832, y: 0.27789 },
|
|
4652
|
+
hero: { x: 0.81983, y: 0.23544 },
|
|
4653
|
+
foe: { x: 0.87702, y: 0.25376 },
|
|
4654
|
+
marker: { x: 0.84753, y: 0.24036 }
|
|
4655
|
+
},
|
|
4656
|
+
"Ash Hills": {
|
|
4657
|
+
hero: { x: 0.68312, y: 0.44364 },
|
|
4658
|
+
foe: { x: 0.69161, y: 0.46732 },
|
|
4659
|
+
marker: { x: 0.71618, y: 0.45347 }
|
|
4660
|
+
},
|
|
4661
|
+
Cloudhold: {
|
|
4662
|
+
marker: { x: 0.80375, y: 0.41683 },
|
|
4663
|
+
hero: { x: 0.77694, y: 0.42041 },
|
|
4664
|
+
foe: { x: 0.79124, y: 0.44274 }
|
|
4665
|
+
},
|
|
4666
|
+
Delmsmire: {
|
|
4667
|
+
foe: { x: 0.83994, y: 0.34892 },
|
|
4668
|
+
hero: { x: 0.86675, y: 0.32703 },
|
|
4669
|
+
marker: { x: 0.89221, y: 0.31631 }
|
|
4670
|
+
},
|
|
4671
|
+
"Hissing Groves": {
|
|
4672
|
+
marker: { x: 0.67151, y: 0.33865 },
|
|
4673
|
+
building: { x: 0.70502, y: 0.3869 },
|
|
4674
|
+
skull: { x: 0.71127, y: 0.38422 },
|
|
4675
|
+
hero: { x: 0.66436, y: 0.38645 },
|
|
4676
|
+
foe: { x: 0.64783, y: 0.36054 }
|
|
4677
|
+
},
|
|
4678
|
+
"Idran Forest": {
|
|
4679
|
+
hero: { x: 0.54105, y: 0.21221 },
|
|
4680
|
+
foe: { x: 0.54865, y: 0.23455 },
|
|
4681
|
+
marker: { x: 0.58394, y: 0.22294 }
|
|
4682
|
+
},
|
|
4683
|
+
"Lonelight Hills": {
|
|
4684
|
+
marker: { x: 0.58573, y: 0.30291 },
|
|
4685
|
+
hero: { x: 0.58662, y: 0.32524 },
|
|
4686
|
+
foe: { x: 0.54507, y: 0.30112 }
|
|
4687
|
+
},
|
|
4688
|
+
"Lost Lands": {
|
|
4689
|
+
hero: { x: 0.56339, y: 0.08935 },
|
|
4690
|
+
foe: { x: 0.57813, y: 0.10633 },
|
|
4691
|
+
marker: { x: 0.57367, y: 0.0688 }
|
|
4692
|
+
},
|
|
4693
|
+
"Plains of Plovo": {
|
|
4694
|
+
marker: { x: 0.92348, y: 0.42532 },
|
|
4695
|
+
building: { x: 0.88238, y: 0.39717 },
|
|
4696
|
+
skull: { x: 0.89042, y: 0.3936 },
|
|
4697
|
+
hero: { x: 0.89221, y: 0.43158 },
|
|
4698
|
+
foe: { x: 0.91053, y: 0.44632 }
|
|
4699
|
+
},
|
|
4700
|
+
"Plains of Woldra": {
|
|
4701
|
+
hero: { x: 0.62862, y: 0.12107 },
|
|
4702
|
+
foe: { x: 0.57322, y: 0.15815 },
|
|
4703
|
+
marker: { x: 0.60851, y: 0.16798 }
|
|
4704
|
+
},
|
|
4705
|
+
"The Empty Glade": {
|
|
4706
|
+
hero: { x: 0.72646, y: 0.29352 },
|
|
4707
|
+
foe: { x: 0.78052, y: 0.34982 },
|
|
4708
|
+
marker: { x: 0.74746, y: 0.32078 }
|
|
4709
|
+
},
|
|
4710
|
+
"The Grass Sea": {
|
|
4711
|
+
hero: { x: 0.57099, y: 0.37662 },
|
|
4712
|
+
foe: { x: 0.62281, y: 0.43426 },
|
|
4713
|
+
marker: { x: 0.60181, y: 0.40343 }
|
|
4714
|
+
},
|
|
4715
|
+
"Weeping Waters": {
|
|
4716
|
+
hero: { x: 0.64202, y: 0.24795 },
|
|
4717
|
+
foe: { x: 0.65453, y: 0.23053 },
|
|
4718
|
+
marker: { x: 0.67464, y: 0.24393 }
|
|
4719
|
+
},
|
|
4720
|
+
Yellowpike: {
|
|
4721
|
+
marker: { x: 0.76533, y: 0.22338 },
|
|
4722
|
+
hero: { x: 0.79348, y: 0.19792 },
|
|
4723
|
+
foe: { x: 0.81492, y: 0.17379 }
|
|
4724
|
+
}
|
|
4725
|
+
};
|
|
4726
|
+
|
|
4727
|
+
// src/data/board/udtBoardAdjacency.ts
|
|
4728
|
+
var BOARD_ADJACENCY = {
|
|
4729
|
+
"Howling Desert": [
|
|
4730
|
+
"Azkol's Bane",
|
|
4731
|
+
"Idran Forest",
|
|
4732
|
+
"Irontops",
|
|
4733
|
+
"Lonelight Hills",
|
|
4734
|
+
"Mountains of the Watchers",
|
|
4735
|
+
"The Cloister",
|
|
4736
|
+
"The Emerald Expanse"
|
|
4737
|
+
],
|
|
4738
|
+
"Mountains of the Watchers": [
|
|
4739
|
+
"Howling Desert",
|
|
4740
|
+
"Idran Forest",
|
|
4741
|
+
"Lost Lands",
|
|
4742
|
+
"Plains of Woldra",
|
|
4743
|
+
"The Emerald Expanse"
|
|
4744
|
+
],
|
|
4745
|
+
"The Emerald Expanse": [
|
|
4746
|
+
"Azkol's Bane",
|
|
4747
|
+
"Bone Hills",
|
|
4748
|
+
"Howling Desert",
|
|
4749
|
+
"Lost Lands",
|
|
4750
|
+
"Mountains of the Watchers"
|
|
4751
|
+
],
|
|
4752
|
+
"Azkol's Bane": [
|
|
4753
|
+
"Archmont",
|
|
4754
|
+
"Bone Hills",
|
|
4755
|
+
"Howling Desert",
|
|
4756
|
+
"The Cloister",
|
|
4757
|
+
"The Emerald Expanse"
|
|
4758
|
+
],
|
|
4759
|
+
"The Cloister": [
|
|
4760
|
+
"Archmont",
|
|
4761
|
+
"Azkol's Bane",
|
|
4762
|
+
"Howling Desert",
|
|
4763
|
+
"Irontops",
|
|
4764
|
+
"Sands of Madness",
|
|
4765
|
+
"The Throne"
|
|
4766
|
+
],
|
|
4767
|
+
Irontops: ["Howling Desert", "Lonelight Hills", "The Cloister", "The Grass Sea", "The Throne"],
|
|
4768
|
+
"Idran Forest": [
|
|
4769
|
+
"Anza",
|
|
4770
|
+
"Howling Desert",
|
|
4771
|
+
"Lonelight Hills",
|
|
4772
|
+
"Mountains of the Watchers",
|
|
4773
|
+
"Plains of Woldra",
|
|
4774
|
+
"Weeping Waters"
|
|
4775
|
+
],
|
|
4776
|
+
"Lonelight Hills": [
|
|
4777
|
+
"Hissing Groves",
|
|
4778
|
+
"Howling Desert",
|
|
4779
|
+
"Idran Forest",
|
|
4780
|
+
"Irontops",
|
|
4781
|
+
"The Grass Sea",
|
|
4782
|
+
"Weeping Waters"
|
|
4783
|
+
],
|
|
4784
|
+
"The Grass Sea": [
|
|
4785
|
+
"Ash Hills",
|
|
4786
|
+
"Hissing Groves",
|
|
4787
|
+
"Irontops",
|
|
4788
|
+
"Lonelight Hills",
|
|
4789
|
+
"Tower Scar Desert"
|
|
4790
|
+
],
|
|
4791
|
+
"The Throne": [
|
|
4792
|
+
"Big Sister",
|
|
4793
|
+
"Forest of Shades",
|
|
4794
|
+
"Irontops",
|
|
4795
|
+
"Sands of Madness",
|
|
4796
|
+
"The Cloister"
|
|
4797
|
+
],
|
|
4798
|
+
"Sands of Madness": [
|
|
4799
|
+
"Archmont",
|
|
4800
|
+
"Big Sister",
|
|
4801
|
+
"Little Sister",
|
|
4802
|
+
"Middle Sister",
|
|
4803
|
+
"The Cloister",
|
|
4804
|
+
"The Throne"
|
|
4805
|
+
],
|
|
4806
|
+
Archmont: [
|
|
4807
|
+
"Azkol's Bane",
|
|
4808
|
+
"Bone Hills",
|
|
4809
|
+
"Little Sister",
|
|
4810
|
+
"Sands of Madness",
|
|
4811
|
+
"Southern Wastes",
|
|
4812
|
+
"The Cloister"
|
|
4813
|
+
],
|
|
4814
|
+
"Bone Hills": ["Archmont", "Azkol's Bane", "Southern Wastes", "The Emerald Expanse"],
|
|
4815
|
+
"Little Sister": [
|
|
4816
|
+
"Archmont",
|
|
4817
|
+
"Middle Sister",
|
|
4818
|
+
"Sands of Madness",
|
|
4819
|
+
"Southern Wastes",
|
|
4820
|
+
"Ulamel's Hollow"
|
|
4821
|
+
],
|
|
4822
|
+
"Forest of Shades": [
|
|
4823
|
+
"Big Sister",
|
|
4824
|
+
"Bleak Wastes",
|
|
4825
|
+
"Dragontooth Lake",
|
|
4826
|
+
"Greater Tombstones",
|
|
4827
|
+
"The Throne"
|
|
4828
|
+
],
|
|
4829
|
+
"Big Sister": [
|
|
4830
|
+
"Forest of Shades",
|
|
4831
|
+
"Greater Tombstones",
|
|
4832
|
+
"Lesser Tombstones",
|
|
4833
|
+
"Middle Sister",
|
|
4834
|
+
"Sands of Madness",
|
|
4835
|
+
"The Throne"
|
|
4836
|
+
],
|
|
4837
|
+
"Middle Sister": [
|
|
4838
|
+
"Big Sister",
|
|
4839
|
+
"Lesser Tombstones",
|
|
4840
|
+
"Little Sister",
|
|
4841
|
+
"Pine Barrens",
|
|
4842
|
+
"Sands of Madness",
|
|
4843
|
+
"Three Rivers",
|
|
4844
|
+
"Ulamel's Hollow"
|
|
4845
|
+
],
|
|
4846
|
+
"Southern Wastes": ["Archmont", "Bone Hills", "Little Sister", "Ulamel's Hollow"],
|
|
4847
|
+
"Ulamel's Hollow": ["Little Sister", "Middle Sister", "Pine Barrens", "Southern Wastes"],
|
|
4848
|
+
"Pine Barrens": ["Middle Sister", "Three Rivers", "Ulamel's Hollow"],
|
|
4849
|
+
"Plains of Woldra": ["Anza", "Idran Forest", "Lost Lands", "Mountains of the Watchers"],
|
|
4850
|
+
"Lost Lands": ["Mountains of the Watchers", "Plains of Woldra", "The Emerald Expanse"],
|
|
4851
|
+
"Weeping Waters": [
|
|
4852
|
+
"Anza",
|
|
4853
|
+
"Hissing Groves",
|
|
4854
|
+
"Idran Forest",
|
|
4855
|
+
"Lonelight Hills",
|
|
4856
|
+
"The Empty Glade",
|
|
4857
|
+
"Yellowpike"
|
|
4858
|
+
],
|
|
4859
|
+
Anza: ["Idran Forest", "Plains of Woldra", "Weeping Waters", "Yellowpike"],
|
|
4860
|
+
"Hissing Groves": [
|
|
4861
|
+
"Ash Hills",
|
|
4862
|
+
"Cloudhold",
|
|
4863
|
+
"Lonelight Hills",
|
|
4864
|
+
"The Empty Glade",
|
|
4865
|
+
"The Grass Sea",
|
|
4866
|
+
"Weeping Waters"
|
|
4867
|
+
],
|
|
4868
|
+
"Ash Hills": [
|
|
4869
|
+
"Broken Lands",
|
|
4870
|
+
"Cloudhold",
|
|
4871
|
+
"Hissing Groves",
|
|
4872
|
+
"Muted Forest",
|
|
4873
|
+
"The Grass Sea",
|
|
4874
|
+
"Tower Scar Desert"
|
|
4875
|
+
],
|
|
4876
|
+
"The Empty Glade": [
|
|
4877
|
+
"Arkartus",
|
|
4878
|
+
"Cloudhold",
|
|
4879
|
+
"Delmsmire",
|
|
4880
|
+
"Hissing Groves",
|
|
4881
|
+
"Weeping Waters",
|
|
4882
|
+
"Yellowpike"
|
|
4883
|
+
],
|
|
4884
|
+
Yellowpike: ["Anza", "Arkartus", "The Empty Glade", "Weeping Waters"],
|
|
4885
|
+
Arkartus: ["Delmsmire", "The Empty Glade", "Yellowpike"],
|
|
4886
|
+
Delmsmire: ["Arkartus", "Cloudhold", "Plains of Plovo", "The Empty Glade"],
|
|
4887
|
+
Cloudhold: [
|
|
4888
|
+
"Ash Hills",
|
|
4889
|
+
"Broken Lands",
|
|
4890
|
+
"Delmsmire",
|
|
4891
|
+
"Hissing Groves",
|
|
4892
|
+
"Plains of Plovo",
|
|
4893
|
+
"The Empty Glade"
|
|
4894
|
+
],
|
|
4895
|
+
"Plains of Plovo": ["Broken Lands", "Cloudhold", "Delmsmire", "Lodestone Mountains"],
|
|
4896
|
+
"Lodestone Mountains": [
|
|
4897
|
+
"Broken Lands",
|
|
4898
|
+
"Pearl of the North",
|
|
4899
|
+
"Plains of Plovo",
|
|
4900
|
+
"Radiant Mountains"
|
|
4901
|
+
],
|
|
4902
|
+
"Broken Lands": [
|
|
4903
|
+
"Ash Hills",
|
|
4904
|
+
"Cloudhold",
|
|
4905
|
+
"Lodestone Mountains",
|
|
4906
|
+
"Muted Forest",
|
|
4907
|
+
"Plains of Plovo",
|
|
4908
|
+
"Radiant Mountains"
|
|
4909
|
+
],
|
|
4910
|
+
"Muted Forest": [
|
|
4911
|
+
"Ash Hills",
|
|
4912
|
+
"Broken Lands",
|
|
4913
|
+
"Green Bridge",
|
|
4914
|
+
"Radiant Mountains",
|
|
4915
|
+
"Tower Scar Desert",
|
|
4916
|
+
"Upper Ice Fangs"
|
|
4917
|
+
],
|
|
4918
|
+
"Tower Scar Desert": [
|
|
4919
|
+
"Ash Hills",
|
|
4920
|
+
"Bleak Wastes",
|
|
4921
|
+
"Muted Forest",
|
|
4922
|
+
"The Grass Sea",
|
|
4923
|
+
"Upper Ice Fangs"
|
|
4924
|
+
],
|
|
4925
|
+
"Radiant Mountains": [
|
|
4926
|
+
"Broken Lands",
|
|
4927
|
+
"Fivepint",
|
|
4928
|
+
"Green Bridge",
|
|
4929
|
+
"Lodestone Mountains",
|
|
4930
|
+
"Muted Forest",
|
|
4931
|
+
"Pearl of the North"
|
|
4932
|
+
],
|
|
4933
|
+
"Pearl of the North": ["Fivepint", "Lodestone Mountains", "Radiant Mountains"],
|
|
4934
|
+
"Green Bridge": [
|
|
4935
|
+
"Dayside",
|
|
4936
|
+
"Fivepint",
|
|
4937
|
+
"Lower Ice Fangs",
|
|
4938
|
+
"Muted Forest",
|
|
4939
|
+
"Radiant Mountains",
|
|
4940
|
+
"Upper Ice Fangs"
|
|
4941
|
+
],
|
|
4942
|
+
Fivepint: ["Dayside", "Green Bridge", "Pearl of the North", "Radiant Mountains"],
|
|
4943
|
+
Dayside: ["Fivepint", "Green Bridge", "Lower Ice Fangs", "The Tundra"],
|
|
4944
|
+
"Upper Ice Fangs": [
|
|
4945
|
+
"Bleak Wastes",
|
|
4946
|
+
"Green Bridge",
|
|
4947
|
+
"Lower Ice Fangs",
|
|
4948
|
+
"Muted Forest",
|
|
4949
|
+
"Peaks of the Djinn",
|
|
4950
|
+
"Tower Scar Desert"
|
|
4951
|
+
],
|
|
4952
|
+
"Bleak Wastes": [
|
|
4953
|
+
"Dragontooth Lake",
|
|
4954
|
+
"Forest of Shades",
|
|
4955
|
+
"Peaks of the Djinn",
|
|
4956
|
+
"Tower Scar Desert",
|
|
4957
|
+
"Upper Ice Fangs"
|
|
4958
|
+
],
|
|
4959
|
+
"Lower Ice Fangs": [
|
|
4960
|
+
"Dayside",
|
|
4961
|
+
"Green Bridge",
|
|
4962
|
+
"Peaks of the Djinn",
|
|
4963
|
+
"Rimeweald",
|
|
4964
|
+
"The Tundra",
|
|
4965
|
+
"Upper Ice Fangs"
|
|
4966
|
+
],
|
|
4967
|
+
"Peaks of the Djinn": [
|
|
4968
|
+
"Bleak Wastes",
|
|
4969
|
+
"Dragontooth Lake",
|
|
4970
|
+
"Inner Kinghills",
|
|
4971
|
+
"Lower Ice Fangs",
|
|
4972
|
+
"Rimeweald",
|
|
4973
|
+
"Upper Ice Fangs"
|
|
4974
|
+
],
|
|
4975
|
+
Rimeweald: [
|
|
4976
|
+
"Egan's End",
|
|
4977
|
+
"Inner Kinghills",
|
|
4978
|
+
"Lower Ice Fangs",
|
|
4979
|
+
"Outer Kinghills",
|
|
4980
|
+
"Peaks of the Djinn",
|
|
4981
|
+
"The Tundra"
|
|
4982
|
+
],
|
|
4983
|
+
"Egan's End": ["Outer Kinghills", "Rimeweald", "The Tundra"],
|
|
4984
|
+
"The Tundra": ["Dayside", "Egan's End", "Lower Ice Fangs", "Rimeweald"],
|
|
4985
|
+
"Outer Kinghills": ["Copper Grove", "Egan's End", "Inner Kinghills", "Rimeweald"],
|
|
4986
|
+
"Inner Kinghills": [
|
|
4987
|
+
"Copper Grove",
|
|
4988
|
+
"Dragontooth Lake",
|
|
4989
|
+
"Outer Kinghills",
|
|
4990
|
+
"Peaks of the Djinn",
|
|
4991
|
+
"Rimeweald",
|
|
4992
|
+
"The Decaying Wilds"
|
|
4993
|
+
],
|
|
4994
|
+
"Copper Grove": ["Inner Kinghills", "Jewel Hills", "Outer Kinghills", "The Decaying Wilds"],
|
|
4995
|
+
"The Decaying Wilds": [
|
|
4996
|
+
"Copper Grove",
|
|
4997
|
+
"Dragontooth Lake",
|
|
4998
|
+
"Greater Tombstones",
|
|
4999
|
+
"Inner Kinghills",
|
|
5000
|
+
"Jewel Hills",
|
|
5001
|
+
"Utar's Barrows"
|
|
5002
|
+
],
|
|
5003
|
+
"Dragontooth Lake": [
|
|
5004
|
+
"Bleak Wastes",
|
|
5005
|
+
"Forest of Shades",
|
|
5006
|
+
"Greater Tombstones",
|
|
5007
|
+
"Inner Kinghills",
|
|
5008
|
+
"Peaks of the Djinn",
|
|
5009
|
+
"The Decaying Wilds"
|
|
5010
|
+
],
|
|
5011
|
+
"Greater Tombstones": [
|
|
5012
|
+
"Big Sister",
|
|
5013
|
+
"Dragontooth Lake",
|
|
5014
|
+
"Forest of Shades",
|
|
5015
|
+
"Lesser Tombstones",
|
|
5016
|
+
"The Decaying Wilds",
|
|
5017
|
+
"Utar's Barrows"
|
|
5018
|
+
],
|
|
5019
|
+
"Jewel Hills": ["Copper Grove", "Duwani", "The Decaying Wilds", "Utar's Barrows"],
|
|
5020
|
+
"Utar's Barrows": [
|
|
5021
|
+
"Duwani",
|
|
5022
|
+
"Greater Tombstones",
|
|
5023
|
+
"Jewel Hills",
|
|
5024
|
+
"Lake of Songs",
|
|
5025
|
+
"Lesser Tombstones",
|
|
5026
|
+
"The Decaying Wilds"
|
|
5027
|
+
],
|
|
5028
|
+
Duwani: ["Jewel Hills", "Lake of Songs", "Utar's Barrows"],
|
|
5029
|
+
"Lesser Tombstones": [
|
|
5030
|
+
"Big Sister",
|
|
5031
|
+
"Greater Tombstones",
|
|
5032
|
+
"Lake of Songs",
|
|
5033
|
+
"Middle Sister",
|
|
5034
|
+
"Three Rivers",
|
|
5035
|
+
"Utar's Barrows"
|
|
5036
|
+
],
|
|
5037
|
+
"Lake of Songs": ["Duwani", "Lesser Tombstones", "Three Rivers", "Utar's Barrows"],
|
|
5038
|
+
"Three Rivers": ["Lake of Songs", "Lesser Tombstones", "Middle Sister", "Pine Barrens"]
|
|
5039
|
+
};
|
|
5040
|
+
function neighborsOf(loc) {
|
|
5041
|
+
return BOARD_ADJACENCY[loc] ?? [];
|
|
5042
|
+
}
|
|
5043
|
+
function stepDistance(a, b) {
|
|
5044
|
+
if (a === b) return 0;
|
|
5045
|
+
const visited = /* @__PURE__ */ new Set([a]);
|
|
5046
|
+
let frontier = [a];
|
|
5047
|
+
let dist = 0;
|
|
5048
|
+
while (frontier.length > 0) {
|
|
5049
|
+
dist++;
|
|
5050
|
+
const next = [];
|
|
5051
|
+
for (const node of frontier) {
|
|
5052
|
+
for (const n of neighborsOf(node)) {
|
|
5053
|
+
if (n === b) return dist;
|
|
5054
|
+
if (!visited.has(n)) {
|
|
5055
|
+
visited.add(n);
|
|
5056
|
+
next.push(n);
|
|
5057
|
+
}
|
|
5058
|
+
}
|
|
5059
|
+
}
|
|
5060
|
+
frontier = next;
|
|
5061
|
+
}
|
|
5062
|
+
return Infinity;
|
|
5063
|
+
}
|
|
5064
|
+
function shortestPath(a, b) {
|
|
5065
|
+
if (a === b) return [a];
|
|
5066
|
+
const prev = /* @__PURE__ */ new Map();
|
|
5067
|
+
const visited = /* @__PURE__ */ new Set([a]);
|
|
5068
|
+
let frontier = [a];
|
|
5069
|
+
while (frontier.length > 0) {
|
|
5070
|
+
const next = [];
|
|
5071
|
+
for (const node of frontier) {
|
|
5072
|
+
for (const n of neighborsOf(node)) {
|
|
5073
|
+
if (visited.has(n)) continue;
|
|
5074
|
+
visited.add(n);
|
|
5075
|
+
prev.set(n, node);
|
|
5076
|
+
if (n === b) {
|
|
5077
|
+
const path = [b];
|
|
5078
|
+
let cur = b;
|
|
5079
|
+
while (cur !== void 0 && cur !== a) {
|
|
5080
|
+
cur = prev.get(cur);
|
|
5081
|
+
if (cur !== void 0) path.push(cur);
|
|
5082
|
+
}
|
|
5083
|
+
return path.reverse();
|
|
5084
|
+
}
|
|
5085
|
+
next.push(n);
|
|
5086
|
+
}
|
|
5087
|
+
}
|
|
5088
|
+
frontier = next;
|
|
5089
|
+
}
|
|
5090
|
+
return [];
|
|
5091
|
+
}
|
|
5092
|
+
|
|
5093
|
+
// src/data/udtGameContent.ts
|
|
5094
|
+
var udtGameContent_exports = {};
|
|
5095
|
+
__export(udtGameContent_exports, {
|
|
5096
|
+
ADVERSARIES: () => ADVERSARIES,
|
|
5097
|
+
COMPANIONS: () => COMPANIONS,
|
|
5098
|
+
FOES: () => FOES2,
|
|
5099
|
+
HEROES: () => HEROES2,
|
|
5100
|
+
KINGDOM_VIRTUES: () => KINGDOM_VIRTUES,
|
|
5101
|
+
adversaries: () => adversaries,
|
|
5102
|
+
companions: () => companions,
|
|
5103
|
+
foes: () => foes,
|
|
5104
|
+
heroes: () => heroes,
|
|
5105
|
+
kingdomVirtues: () => kingdomVirtues
|
|
5106
|
+
});
|
|
5107
|
+
var HEROES2 = {
|
|
5108
|
+
Spymaster: {
|
|
5109
|
+
name: "Spymaster",
|
|
5110
|
+
expansion: "Base Game",
|
|
5111
|
+
bannerAction: "Place your hero on any space in your current kingdom.",
|
|
5112
|
+
defaultVirtues: [
|
|
5113
|
+
{ name: "Alert", ability: "+1 Stealth Advantage." },
|
|
5114
|
+
{ name: "Swift", ability: "Your base move is 4." }
|
|
5115
|
+
],
|
|
5116
|
+
unlockableVirtues: [
|
|
5117
|
+
{ name: "Resourceful", ability: "At the end of each month, gain 15 warriors." },
|
|
5118
|
+
{
|
|
5119
|
+
name: "Fortunate",
|
|
5120
|
+
ability: "You may Reinforce twice per turn at the same building."
|
|
5121
|
+
},
|
|
5122
|
+
{
|
|
5123
|
+
name: "Unseen",
|
|
5124
|
+
ability: "When you complete a monthly quest, you may remove a foe instead of gaining spirit."
|
|
5125
|
+
}
|
|
5126
|
+
]
|
|
5127
|
+
},
|
|
5128
|
+
"Brutal Warlord": {
|
|
5129
|
+
name: "Brutal Warlord",
|
|
5130
|
+
expansion: "Base Game",
|
|
5131
|
+
bannerAction: "Gain 5 warriors.",
|
|
5132
|
+
defaultVirtues: [
|
|
5133
|
+
{ name: "Baleful", ability: "+1 Melee Advantage." },
|
|
5134
|
+
{ name: "Veteran", ability: "+1 Wild Advantage when you Battle." }
|
|
5135
|
+
],
|
|
5136
|
+
unlockableVirtues: [
|
|
5137
|
+
{ name: "Inspiring", ability: "After you Reinforce, also gain 6 warriors." },
|
|
5138
|
+
{
|
|
5139
|
+
name: "Callous",
|
|
5140
|
+
ability: "After you Battle, if you lost at least 10 warriors, gain a treasure from the market."
|
|
5141
|
+
},
|
|
5142
|
+
{ name: "Relentless", ability: "If you double your move, gain +1 Wild Advantage." }
|
|
5143
|
+
]
|
|
5144
|
+
},
|
|
5145
|
+
"Orphaned Scion": {
|
|
5146
|
+
name: "Orphaned Scion",
|
|
5147
|
+
expansion: "Base Game",
|
|
5148
|
+
bannerAction: "Gain 1 spirit.",
|
|
5149
|
+
defaultVirtues: [
|
|
5150
|
+
{ name: "Arcane", ability: "+1 Magic Advantage." },
|
|
5151
|
+
{ name: "Generous", ability: "After you Cleanse, remove 1 skull from any building." }
|
|
5152
|
+
],
|
|
5153
|
+
unlockableVirtues: [
|
|
5154
|
+
{
|
|
5155
|
+
name: "Infused",
|
|
5156
|
+
ability: "At the start of your turn, remove 1 skull from a building in your home kingdom."
|
|
5157
|
+
},
|
|
5158
|
+
{
|
|
5159
|
+
name: "Blessed",
|
|
5160
|
+
ability: "Spend 1 spirit to prevent up to 6 warrior losses from a battle card or dungeon room."
|
|
5161
|
+
},
|
|
5162
|
+
{
|
|
5163
|
+
name: "Anointed",
|
|
5164
|
+
ability: "+1 Wild Advantage for each building with no skulls on or adjacent to your space."
|
|
5165
|
+
}
|
|
5166
|
+
]
|
|
5167
|
+
},
|
|
5168
|
+
"Relic Hunter": {
|
|
5169
|
+
name: "Relic Hunter",
|
|
5170
|
+
expansion: "Base Game",
|
|
5171
|
+
bannerAction: "Gain 1 potion.",
|
|
5172
|
+
defaultVirtues: [
|
|
5173
|
+
{ name: "Precise", ability: "+1 Humanoid Advantage." },
|
|
5174
|
+
{
|
|
5175
|
+
name: "Prepared",
|
|
5176
|
+
ability: "When you Reinforce at a bazaar, spend 1 less spirit to gain a treasure."
|
|
5177
|
+
}
|
|
5178
|
+
],
|
|
5179
|
+
unlockableVirtues: [
|
|
5180
|
+
{ name: "Crafty", ability: "When you spend a potion, double the number on it." },
|
|
5181
|
+
{
|
|
5182
|
+
name: "Lucky",
|
|
5183
|
+
ability: "When you spend (not lose) a treasure, gain the top card of the treasure deck."
|
|
5184
|
+
},
|
|
5185
|
+
{ name: "Inventive", ability: "Spend 4 potions to remove a foe from your space." }
|
|
5186
|
+
]
|
|
5187
|
+
},
|
|
5188
|
+
"Haunted Recluse": {
|
|
5189
|
+
name: "Haunted Recluse",
|
|
5190
|
+
expansion: "Alliances",
|
|
5191
|
+
bannerAction: "Move 1 skull from any building to any other building with 2 or fewer skulls.",
|
|
5192
|
+
defaultVirtues: [
|
|
5193
|
+
{ name: "Spiritreaver", ability: "+1 Undead Advantage." },
|
|
5194
|
+
{
|
|
5195
|
+
name: "Skullweaver",
|
|
5196
|
+
ability: "When a skull emerges in your home kingdom, you can place it on any building with 2 or fewer skulls in any kingdom."
|
|
5197
|
+
}
|
|
5198
|
+
],
|
|
5199
|
+
unlockableVirtues: [
|
|
5200
|
+
{
|
|
5201
|
+
name: "Shadowspinner",
|
|
5202
|
+
ability: "+1 Wild Advantage for each building with skulls on or adjacent to your space."
|
|
5203
|
+
},
|
|
5204
|
+
{
|
|
5205
|
+
name: "Soulreaper",
|
|
5206
|
+
ability: "Prevent up to 2 warrior losses per battle card for each skull on or adjacent to your space."
|
|
5207
|
+
},
|
|
5208
|
+
{
|
|
5209
|
+
name: "Sinbearer",
|
|
5210
|
+
ability: "At the end of the month you can spend up to 12 warriors to remove all skulls from your current kingdom."
|
|
5211
|
+
}
|
|
5212
|
+
]
|
|
5213
|
+
},
|
|
5214
|
+
Archwright: {
|
|
5215
|
+
name: "Archwright",
|
|
5216
|
+
expansion: "Alliances",
|
|
5217
|
+
bannerAction: "Place a battlement on any space or move a battlement up to 2 spaces.",
|
|
5218
|
+
defaultVirtues: [
|
|
5219
|
+
{ name: "Innovative", ability: "+1 Beast Advantage." },
|
|
5220
|
+
{ name: "Clever", ability: "Battlements give you +2 Wild Advantages (instead of +1)." }
|
|
5221
|
+
],
|
|
5222
|
+
unlockableVirtues: [
|
|
5223
|
+
{
|
|
5224
|
+
name: "Tactical",
|
|
5225
|
+
ability: "While on a battlement, you can Battle a foe on an adjacent space. (Terrain advantages use the space you are on.)"
|
|
5226
|
+
},
|
|
5227
|
+
{
|
|
5228
|
+
name: "Wily",
|
|
5229
|
+
ability: "Battlements give you advantages when you Quest (in addition to when you Battle)."
|
|
5230
|
+
},
|
|
5231
|
+
{
|
|
5232
|
+
name: "Exalted",
|
|
5233
|
+
ability: "While on a battlement, you may Cleanse to remove skulls from all adjacent buildings."
|
|
5234
|
+
}
|
|
5235
|
+
]
|
|
5236
|
+
},
|
|
5237
|
+
"Relentless Warden": {
|
|
5238
|
+
name: "Relentless Warden",
|
|
5239
|
+
expansion: "Covenant",
|
|
5240
|
+
bannerAction: "Place quarry token on a foe if it is not already, else move quarry token up to 2 spaces.",
|
|
5241
|
+
defaultVirtues: [
|
|
5242
|
+
{ name: "Perceptive", ability: "+1 Wild Advantage vs. your quarry." },
|
|
5243
|
+
{
|
|
5244
|
+
name: "Guarded",
|
|
5245
|
+
ability: "Prevent up to 3 warrior losses per battle card when you Battle your quarry."
|
|
5246
|
+
}
|
|
5247
|
+
],
|
|
5248
|
+
unlockableVirtues: [
|
|
5249
|
+
{ name: "Keen-Eyed", ability: "+2 Wild Advantages vs. your quarry." },
|
|
5250
|
+
{
|
|
5251
|
+
name: "Instinctive",
|
|
5252
|
+
ability: "You may remove your quarry token to ignore your quarry during its strike event."
|
|
5253
|
+
},
|
|
5254
|
+
{
|
|
5255
|
+
name: "Inspiring",
|
|
5256
|
+
ability: "When you defeat your quarry, remove all skulls on or adjacent to your space."
|
|
5257
|
+
}
|
|
5258
|
+
]
|
|
5259
|
+
},
|
|
5260
|
+
"Undaunted Aegis": {
|
|
5261
|
+
name: "Undaunted Aegis",
|
|
5262
|
+
expansion: "Covenant",
|
|
5263
|
+
bannerAction: "For each corruption you have, gain 3 warriors. You may spend 10 warriors to remove one of your corruptions.",
|
|
5264
|
+
defaultVirtues: [
|
|
5265
|
+
{
|
|
5266
|
+
name: "Ascetic",
|
|
5267
|
+
ability: "Gain 1 spirit for each battle card you spend no advantages on."
|
|
5268
|
+
},
|
|
5269
|
+
{
|
|
5270
|
+
name: "Iron-Willed",
|
|
5271
|
+
ability: "You can have an additional corruption. Start the game with 1 random corruption."
|
|
5272
|
+
}
|
|
5273
|
+
],
|
|
5274
|
+
unlockableVirtues: [
|
|
5275
|
+
{ name: "Emboldened", ability: "+1 Wild Advantage for each corruption you have." },
|
|
5276
|
+
{
|
|
5277
|
+
name: "Resolute",
|
|
5278
|
+
ability: "When you Reinforce, spend 1 less spirit for each corruption you have."
|
|
5279
|
+
},
|
|
5280
|
+
{
|
|
5281
|
+
name: "Steeled",
|
|
5282
|
+
ability: "Once per turn, if another hero would gain a corruption, you may gain it instead and gain 2 spirit."
|
|
5283
|
+
}
|
|
5284
|
+
]
|
|
5285
|
+
},
|
|
5286
|
+
"Devious Swindler": {
|
|
5287
|
+
name: "Devious Swindler",
|
|
5288
|
+
expansion: "Covenant",
|
|
5289
|
+
bannerAction: "Roll the haggle die and gain the result.",
|
|
5290
|
+
defaultVirtues: [
|
|
5291
|
+
{
|
|
5292
|
+
name: "Inventive",
|
|
5293
|
+
ability: "When you Battle, gain all advantages in the treasure market."
|
|
5294
|
+
},
|
|
5295
|
+
{
|
|
5296
|
+
name: "Joyful",
|
|
5297
|
+
ability: "When you roll the haggle die, ignore the Cancelled symbol."
|
|
5298
|
+
}
|
|
5299
|
+
],
|
|
5300
|
+
unlockableVirtues: [
|
|
5301
|
+
{
|
|
5302
|
+
name: "Fortuitous",
|
|
5303
|
+
ability: "After you roll the haggle die, you may reroll once and take either result."
|
|
5304
|
+
},
|
|
5305
|
+
{
|
|
5306
|
+
name: "Opportunistic",
|
|
5307
|
+
ability: "When any player gains a treasure from the treasure market, you gain a blessing."
|
|
5308
|
+
},
|
|
5309
|
+
{
|
|
5310
|
+
name: "Calculating",
|
|
5311
|
+
ability: "You may ignore warrior and spirit losses on critical hit battle cards."
|
|
5312
|
+
}
|
|
5313
|
+
]
|
|
5314
|
+
},
|
|
5315
|
+
"Reverent Astromancer": {
|
|
5316
|
+
name: "Reverent Astromancer",
|
|
5317
|
+
expansion: "Covenant",
|
|
5318
|
+
bannerAction: "Remove a skull on or adjacent to your space.",
|
|
5319
|
+
defaultVirtues: [
|
|
5320
|
+
{
|
|
5321
|
+
name: "Well Versed",
|
|
5322
|
+
ability: "If you remove a skull with your Banner action, gain a blessing."
|
|
5323
|
+
},
|
|
5324
|
+
{
|
|
5325
|
+
name: "Pious",
|
|
5326
|
+
ability: "At the start of each month, prepare spells equal to the month number."
|
|
5327
|
+
}
|
|
5328
|
+
],
|
|
5329
|
+
unlockableVirtues: [
|
|
5330
|
+
{ name: "Exalted", ability: "You can prepare invocations." },
|
|
5331
|
+
{ name: "Zealous", ability: "Whenever you cast a spell, gain a blessing." },
|
|
5332
|
+
{
|
|
5333
|
+
name: "Bounteous",
|
|
5334
|
+
ability: "Once per turn, when you cast a spell, gain the top card of the treasure deck."
|
|
5335
|
+
}
|
|
5336
|
+
]
|
|
5337
|
+
}
|
|
5338
|
+
};
|
|
5339
|
+
var heroes = Object.values(HEROES2);
|
|
5340
|
+
var FOES2 = {
|
|
5341
|
+
Brigands: { name: "Brigands", level: 2 },
|
|
5342
|
+
Oreks: { name: "Oreks", level: 2 },
|
|
5343
|
+
"Shadow Wolves": { name: "Shadow Wolves", level: 2 },
|
|
5344
|
+
"Spine Fiend": { name: "Spine Fiend", level: 2 },
|
|
5345
|
+
"Clan Of Neuri": { name: "Clan Of Neuri", level: 3 },
|
|
5346
|
+
"Frost Troll": { name: "Frost Troll", level: 3 },
|
|
5347
|
+
Lemure: { name: "Lemure", level: 3 },
|
|
5348
|
+
"Widowmade Spider": { name: "Widowmade Spider", level: 3 },
|
|
5349
|
+
Dragon: { name: "Dragon", level: 4 },
|
|
5350
|
+
Mormo: { name: "Mormo", level: 4 },
|
|
5351
|
+
Striga: { name: "Striga", level: 4 },
|
|
5352
|
+
Titan: { name: "Titan", level: 4 }
|
|
5353
|
+
};
|
|
5354
|
+
var foes = Object.values(FOES2);
|
|
5355
|
+
var ADVERSARIES = {
|
|
5356
|
+
Ashstrider: { name: "Ashstrider", level: 5 },
|
|
5357
|
+
"Bane Of Omens": { name: "Bane Of Omens", level: 5 },
|
|
5358
|
+
"Empress Of Shades": { name: "Empress Of Shades", level: 5 },
|
|
5359
|
+
"Gaze Eternal": { name: "Gaze Eternal", level: 5 },
|
|
5360
|
+
Gravemaw: { name: "Gravemaw", level: 5 },
|
|
5361
|
+
"Isa The Exile": { name: "Isa The Exile", level: 5 },
|
|
5362
|
+
"Lingering Rot": { name: "Lingering Rot", level: 5 },
|
|
5363
|
+
"U'tuk-Ku The Ice Herald": { name: "U'tuk-Ku The Ice Herald", level: 5 }
|
|
5364
|
+
};
|
|
5365
|
+
var adversaries = Object.values(ADVERSARIES);
|
|
5366
|
+
var COMPANIONS = {
|
|
5367
|
+
Gleb: { name: "Gleb", title: "The Outlaw King" },
|
|
5368
|
+
Grigor: { name: "Grigor", title: "The Unbreakable" },
|
|
5369
|
+
Hakan: { name: "Hakan", title: "The Artificer" },
|
|
5370
|
+
Letha: { name: "Letha", title: "The Dryad" },
|
|
5371
|
+
Miras: { name: "Miras", title: "The Horselord" },
|
|
5372
|
+
Nimet: { name: "Nimet", title: "The Fathomless" },
|
|
5373
|
+
Tomas: { name: "Tomas", title: "The Scout" },
|
|
5374
|
+
Vasa: { name: "Vasa", title: "The Devine" },
|
|
5375
|
+
Yana: { name: "Yana", title: "The Assassin" },
|
|
5376
|
+
Zaida: { name: "Zaida", title: "The Efreet" }
|
|
5377
|
+
};
|
|
5378
|
+
var companions = Object.values(COMPANIONS);
|
|
5379
|
+
var KINGDOM_VIRTUES = {
|
|
5380
|
+
East: { name: "Champion of the East", ability: "+2 Wild Advantages in hills." },
|
|
5381
|
+
North: { name: "Champion of the North", ability: "+2 Wild Advantages in mountains." },
|
|
5382
|
+
South: { name: "Champion of the South", ability: "+2 Wild Advantages in deserts." },
|
|
5383
|
+
West: { name: "Champion of the West", ability: "+2 Wild Advantages in forests." }
|
|
5384
|
+
};
|
|
5385
|
+
var kingdomVirtues = Object.values(KINGDOM_VIRTUES);
|
|
5386
|
+
|
|
5387
|
+
// src/data/udtBoxInventory.ts
|
|
5388
|
+
var udtBoxInventory_exports = {};
|
|
5389
|
+
__export(udtBoxInventory_exports, {
|
|
5390
|
+
EXPANSIONS: () => EXPANSIONS,
|
|
5391
|
+
coffers: () => coffers,
|
|
5392
|
+
coffers2: () => coffers2,
|
|
5393
|
+
expansions: () => expansions,
|
|
5394
|
+
skullsPack: () => skullsPack,
|
|
5395
|
+
sleeves: () => sleeves
|
|
5396
|
+
});
|
|
5397
|
+
var expansions = [
|
|
5398
|
+
{
|
|
5399
|
+
name: "Base Game",
|
|
5400
|
+
categories: [
|
|
5401
|
+
{
|
|
5402
|
+
name: "Manuals / Sheets",
|
|
5403
|
+
section: "Misc",
|
|
5404
|
+
components: [
|
|
5405
|
+
{ name: "Are You Ready To Take On The Tower", count: 1 },
|
|
5406
|
+
{ name: "Re-Pack Sheet", count: 1 },
|
|
5407
|
+
{ name: "Rulebook", count: 1 }
|
|
5408
|
+
]
|
|
5409
|
+
},
|
|
5410
|
+
{
|
|
5411
|
+
name: "Tower",
|
|
5412
|
+
section: "Misc",
|
|
5413
|
+
components: [
|
|
5414
|
+
{ name: "Seals", count: 12 },
|
|
5415
|
+
{ name: "Tower", count: 1 }
|
|
5416
|
+
]
|
|
5417
|
+
},
|
|
5418
|
+
{
|
|
5419
|
+
name: "Boards",
|
|
5420
|
+
section: "Misc",
|
|
5421
|
+
components: [
|
|
5422
|
+
{ name: "Brutal Warlord", count: 1 },
|
|
5423
|
+
{ name: "Game Board", count: 1 },
|
|
5424
|
+
{ name: "Orphaned Scion", count: 1 },
|
|
5425
|
+
{ name: "Relic Hunter", count: 1 },
|
|
5426
|
+
{ name: "Spymaster", count: 1 }
|
|
5427
|
+
]
|
|
5428
|
+
},
|
|
5429
|
+
{
|
|
5430
|
+
name: "Minis",
|
|
5431
|
+
section: "Misc",
|
|
5432
|
+
components: [
|
|
5433
|
+
{ name: "Bazaars", count: 4 },
|
|
5434
|
+
{ name: "Citadels", count: 4 },
|
|
5435
|
+
{ name: "Hero Figures", count: 4 },
|
|
5436
|
+
{ name: "Sanctuaries", count: 4 },
|
|
5437
|
+
{ name: "Villages", count: 4 }
|
|
5438
|
+
]
|
|
5439
|
+
},
|
|
5440
|
+
{
|
|
5441
|
+
name: "Mini Bases",
|
|
5442
|
+
section: "Misc",
|
|
5443
|
+
components: [
|
|
5444
|
+
{ color: "Blue", count: 1 },
|
|
5445
|
+
{ color: "Brown", count: 1 },
|
|
5446
|
+
{ color: "Green", count: 1 },
|
|
5447
|
+
{ color: "White", count: 1 }
|
|
5448
|
+
]
|
|
5449
|
+
},
|
|
5450
|
+
{
|
|
5451
|
+
name: "Dungeons",
|
|
5452
|
+
section: "Tokens",
|
|
5453
|
+
components: [
|
|
5454
|
+
{ name: "Cave", count: 1 },
|
|
5455
|
+
{ name: "Encampment", count: 1 },
|
|
5456
|
+
{ name: "Fortress", count: 1 },
|
|
5457
|
+
{ name: "Ruins", count: 1 },
|
|
5458
|
+
{ name: "Shrine", count: 1 },
|
|
5459
|
+
{ name: "Tomb", count: 1 }
|
|
5460
|
+
]
|
|
5461
|
+
},
|
|
5462
|
+
{
|
|
5463
|
+
name: "Foes / Adversaries",
|
|
5464
|
+
section: "Tokens",
|
|
5465
|
+
components: [
|
|
5466
|
+
{ name: "Brigands", level: 2, count: 8 },
|
|
5467
|
+
{ name: "Oreks", level: 2, count: 6 },
|
|
5468
|
+
{ name: "Shadow Wolves", level: 2, count: 8 },
|
|
5469
|
+
{ name: "Spine Fiend", level: 2, count: 6 },
|
|
5470
|
+
{ name: "Clan Of Neuri", level: 3, count: 5 },
|
|
5471
|
+
{ name: "Frost Troll", level: 3, count: 4 },
|
|
5472
|
+
{ name: "Lemure", level: 3, count: 6 },
|
|
5473
|
+
{ name: "Widowmade Spider", level: 3, count: 5 },
|
|
5474
|
+
{ name: "Dragon", level: 4, count: 2 },
|
|
5475
|
+
{ name: "Mormo", level: 4, count: 4 },
|
|
5476
|
+
{ name: "Striga", level: 4, count: 2 },
|
|
5477
|
+
{ name: "Titan", level: 4, count: 1 },
|
|
5478
|
+
{ name: "Ashstrider", level: 5, count: 1 },
|
|
5479
|
+
{ name: "Bane Of Omens", level: 5, count: 1 },
|
|
5480
|
+
{ name: "Empress Of Shades", level: 5, count: 1 },
|
|
5481
|
+
{ name: "Gaze Eternal", level: 5, count: 1 },
|
|
5482
|
+
{ name: "Gravemaw", level: 5, count: 1 },
|
|
5483
|
+
{ name: "Isa The Exile", level: 5, count: 1 },
|
|
5484
|
+
{ name: "Lingering Rot", level: 5, count: 1 },
|
|
5485
|
+
{ name: "U'tuk-Ku The Ice Herald", level: 5, count: 1 }
|
|
5486
|
+
]
|
|
5487
|
+
},
|
|
5488
|
+
{
|
|
5489
|
+
name: "Quest Markers & Bases",
|
|
5490
|
+
section: "Tokens",
|
|
5491
|
+
components: [
|
|
5492
|
+
{ name: "Adversary", count: 1 },
|
|
5493
|
+
{ name: "Companion", count: 1 },
|
|
5494
|
+
{ name: "Main Goal", count: 1 }
|
|
5495
|
+
]
|
|
5496
|
+
},
|
|
5497
|
+
{
|
|
5498
|
+
name: "Special",
|
|
5499
|
+
section: "Tokens",
|
|
5500
|
+
components: [
|
|
5501
|
+
{ name: "Caravans", type: "Eastern", count: 1 },
|
|
5502
|
+
{ name: "Caravans", type: "Northern", count: 1 },
|
|
5503
|
+
{ name: "Caravans", type: "Western", count: 1 },
|
|
5504
|
+
{ name: "River Of Fire", count: 4 },
|
|
5505
|
+
{ name: "Siege Trees", count: 8 },
|
|
5506
|
+
{ name: "Spores", count: 8 }
|
|
5507
|
+
]
|
|
5508
|
+
},
|
|
5509
|
+
{
|
|
5510
|
+
name: "Spirits",
|
|
5511
|
+
section: "Tokens",
|
|
5512
|
+
components: [
|
|
5513
|
+
{ name: "1's", count: 25 },
|
|
5514
|
+
{ name: "5's", count: 19 }
|
|
5515
|
+
]
|
|
5516
|
+
},
|
|
5517
|
+
{
|
|
5518
|
+
name: "Virtues",
|
|
5519
|
+
section: "Tokens",
|
|
5520
|
+
components: [
|
|
5521
|
+
{ name: "Anointed", count: 1 },
|
|
5522
|
+
{ name: "Blessed", count: 1 },
|
|
5523
|
+
{ name: "Callous", count: 1 },
|
|
5524
|
+
{ name: "Champion Of The East", count: 1 },
|
|
5525
|
+
{ name: "Champion Of The North", count: 1 },
|
|
5526
|
+
{ name: "Champion Of The South", count: 1 },
|
|
5527
|
+
{ name: "Champion Of The West", count: 1 },
|
|
5528
|
+
{ name: "Crafty", count: 1 },
|
|
5529
|
+
{ name: "Fortunate", count: 1 },
|
|
5530
|
+
{ name: "Infused", count: 1 },
|
|
5531
|
+
{ name: "Inspiring", count: 1 },
|
|
5532
|
+
{ name: "Inventive", count: 1 },
|
|
5533
|
+
{ name: "Lucky", count: 1 },
|
|
5534
|
+
{ name: "Relentless", count: 1 },
|
|
5535
|
+
{ name: "Resourceful", count: 1 },
|
|
5536
|
+
{ name: "Unseen", count: 1 }
|
|
5537
|
+
]
|
|
5538
|
+
},
|
|
5539
|
+
{
|
|
5540
|
+
name: "Warriors",
|
|
5541
|
+
section: "Tokens",
|
|
5542
|
+
components: [
|
|
5543
|
+
{ name: "1's", count: 30 },
|
|
5544
|
+
{ name: "5's", count: 25 }
|
|
5545
|
+
]
|
|
5546
|
+
},
|
|
5547
|
+
{
|
|
5548
|
+
name: "Companion",
|
|
5549
|
+
section: "Cards",
|
|
5550
|
+
components: [
|
|
5551
|
+
{ name: "Gleb", description: "The Outlaw King", count: 1 },
|
|
5552
|
+
{ name: "Grigor", description: "The Unbreakable", count: 1 },
|
|
5553
|
+
{ name: "Hakan", description: "The Artificer", count: 1 },
|
|
5554
|
+
{ name: "Letha", description: "The Dryad", count: 1 },
|
|
5555
|
+
{ name: "Miras", description: "The Horselord", count: 1 },
|
|
5556
|
+
{ name: "Nimet", description: "The Fathomless", count: 1 },
|
|
5557
|
+
{ name: "Tomas", description: "The Scout", count: 1 },
|
|
5558
|
+
{ name: "Vasa", description: "The Devine", count: 1 },
|
|
5559
|
+
{ name: "Yana", description: "The Assassin", count: 1 },
|
|
5560
|
+
{ name: "Zaida", description: "The Efreet", count: 1 }
|
|
5561
|
+
]
|
|
5562
|
+
},
|
|
5563
|
+
{
|
|
5564
|
+
name: "Corruption",
|
|
5565
|
+
section: "Cards",
|
|
5566
|
+
components: [
|
|
5567
|
+
{ name: "Cruel", count: 1 },
|
|
5568
|
+
{ name: "Cursed", count: 1 },
|
|
5569
|
+
{ name: "Feeble", count: 1 },
|
|
5570
|
+
{ name: "Feral", count: 1 },
|
|
5571
|
+
{ name: "Feverish", count: 1 },
|
|
5572
|
+
{ name: "Greedy", count: 1 },
|
|
5573
|
+
{ name: "Lost", count: 1 },
|
|
5574
|
+
{ name: "Selfish", count: 1 },
|
|
5575
|
+
{ name: "Suspicious", count: 1 },
|
|
5576
|
+
{ name: "Tempted", count: 1 },
|
|
5577
|
+
{ name: "Uncertain", count: 1 },
|
|
5578
|
+
{ name: "Weak", count: 1 }
|
|
5579
|
+
]
|
|
5580
|
+
},
|
|
5581
|
+
{
|
|
5582
|
+
name: "Foes",
|
|
5583
|
+
section: "Cards",
|
|
5584
|
+
components: [
|
|
5585
|
+
{ name: "Brigands", level: 2, count: 1 },
|
|
5586
|
+
{ name: "Oreks", level: 2, count: 1 },
|
|
5587
|
+
{ name: "Shadow Wolves", level: 2, count: 1 },
|
|
5588
|
+
{ name: "Spine Fiend", level: 2, count: 1 },
|
|
5589
|
+
{ name: "Clan Of Neuri", level: 3, count: 1 },
|
|
5590
|
+
{ name: "Frost Troll", level: 3, count: 1 },
|
|
5591
|
+
{ name: "Lemure", level: 3, count: 1 },
|
|
5592
|
+
{ name: "Widowmade Spider", level: 3, count: 1 },
|
|
5593
|
+
{ name: "Dragon", level: 4, count: 1 },
|
|
5594
|
+
{ name: "Mormo", level: 4, count: 1 },
|
|
5595
|
+
{ name: "Striga", level: 4, count: 1 },
|
|
5596
|
+
{ name: "Titan", level: 4, count: 1 },
|
|
5597
|
+
{ name: "Ashstrider", level: 5, count: 1 },
|
|
5598
|
+
{ name: "Bane Of Omens", level: 5, count: 1 },
|
|
5599
|
+
{ name: "Empress Of Shades", level: 5, count: 1 },
|
|
5600
|
+
{ name: "Gaze Eternal", level: 5, count: 1 },
|
|
5601
|
+
{ name: "Gravemaw", level: 5, count: 1 },
|
|
5602
|
+
{ name: "Isa The Exile", level: 5, count: 1 },
|
|
5603
|
+
{ name: "Lingering Rot", level: 5, count: 1 },
|
|
5604
|
+
{ name: "U'tuk-Ku The Ice Herald", level: 5, count: 1 }
|
|
5605
|
+
]
|
|
5606
|
+
},
|
|
5607
|
+
{
|
|
5608
|
+
name: "Gear",
|
|
5609
|
+
section: "Cards",
|
|
5610
|
+
components: [
|
|
5611
|
+
{ name: "Blessed Scepters", count: 3 },
|
|
5612
|
+
{ name: "Brass Talismans", count: 3 },
|
|
5613
|
+
{ name: "Dusky Cloaks", count: 3 },
|
|
5614
|
+
{ name: "LeaTher Armor", count: 3 },
|
|
5615
|
+
{ name: "Longswords", count: 3 },
|
|
5616
|
+
{ name: "Trusted Maps", count: 3 }
|
|
5617
|
+
]
|
|
5618
|
+
},
|
|
5619
|
+
{
|
|
5620
|
+
name: "Heroic Tests",
|
|
5621
|
+
section: "Cards",
|
|
5622
|
+
components: [
|
|
5623
|
+
{ name: "Finish Building The Shrine", type: "Compassion", count: 1 },
|
|
5624
|
+
{ name: "Suffer With The Silent Sisters", type: "Compassion", count: 1 },
|
|
5625
|
+
{ name: "Guide Abandoned Pilgrims", type: "Compassion", count: 1 },
|
|
5626
|
+
{ name: "Hold A Moonless Vigil", type: "Compassion", count: 1 },
|
|
5627
|
+
{ name: "Perform The Song Of Peril", type: "Prowess", count: 1 },
|
|
5628
|
+
{ name: "Race To The Golden Obelisk", type: "Prowess", count: 1 },
|
|
5629
|
+
{ name: "Solve The Riddle Of The Marid", type: "Prowess", count: 1 },
|
|
5630
|
+
{ name: "Survive The Drowned Barrows", type: "Prowess", count: 1 },
|
|
5631
|
+
{ name: "Consecrate Akartus", type: "Sacrifice", count: 1 },
|
|
5632
|
+
{ name: "Lay Plovo's Ghost To Rest", type: "Sacrifice", count: 1 },
|
|
5633
|
+
{ name: "Repair The Weeping Damn", type: "Sacrifice", count: 1 },
|
|
5634
|
+
{ name: "Supply The WatchTowers", type: "Sacrifice", count: 1 },
|
|
5635
|
+
{ name: "Activate The Ley Lines", type: "Valor", count: 1 },
|
|
5636
|
+
{ name: "Impress The Winter Fey", type: "Valor", count: 1 },
|
|
5637
|
+
{ name: "Protect The Radiant Castle", type: "Valor", count: 1 },
|
|
5638
|
+
{ name: "Win Egan's Tournament", type: "Valor", count: 1 }
|
|
5639
|
+
]
|
|
5640
|
+
},
|
|
5641
|
+
{
|
|
5642
|
+
name: "Potions",
|
|
5643
|
+
section: "Cards",
|
|
5644
|
+
components: [
|
|
5645
|
+
{ name: "Potion Of Dragon Teeth", count: 3 },
|
|
5646
|
+
{ name: "Potion Of Fortune's Favor", count: 3 },
|
|
5647
|
+
{ name: "Potion Of one Thousand Strides", count: 3 },
|
|
5648
|
+
{ name: "Potion Of Purifying Breath", count: 3 },
|
|
5649
|
+
{ name: "Potion Of The Golden Sun", count: 3 },
|
|
5650
|
+
{ name: "Potion Of The Siren's Song", count: 3 }
|
|
5651
|
+
]
|
|
5652
|
+
},
|
|
5653
|
+
{
|
|
5654
|
+
name: "Quest Items",
|
|
5655
|
+
section: "Cards",
|
|
5656
|
+
components: [
|
|
5657
|
+
{ name: "Amulet Of Annihilation", count: 1 },
|
|
5658
|
+
{ name: "Amulet Of Hope", count: 4 },
|
|
5659
|
+
{ name: "Bezoar", count: 1 },
|
|
5660
|
+
{ name: "Dragon Scales", count: 1 },
|
|
5661
|
+
{ name: "Fulminating Silver", count: 1 },
|
|
5662
|
+
{ name: "Golden Wolf Pelt", count: 1 },
|
|
5663
|
+
{ name: "Herbal Remedy", count: 1 },
|
|
5664
|
+
{ name: "Horn Of The Elements", count: 1 },
|
|
5665
|
+
{ name: "Mark Of The Outlaw", count: 1 },
|
|
5666
|
+
{ name: "Orb Of Pure Snow", count: 1 },
|
|
5667
|
+
{ name: "Relic Of Light", count: 1 },
|
|
5668
|
+
{ name: "Smuggler's Coin", count: 1 },
|
|
5669
|
+
{ name: "The Black Mark", count: 1 },
|
|
5670
|
+
{ name: "Tomas's Map", count: 1 },
|
|
5671
|
+
{ name: "Tools Of The Saboteur", count: 1 },
|
|
5672
|
+
{ name: "Turquoise Urn", count: 1 },
|
|
5673
|
+
{ name: "Wraps Of Invisibility", count: 1 }
|
|
5674
|
+
]
|
|
5675
|
+
},
|
|
5676
|
+
{
|
|
5677
|
+
name: "Treasures",
|
|
5678
|
+
section: "Cards",
|
|
5679
|
+
components: [
|
|
5680
|
+
{ name: "Acorns Of The White Oak", count: 1 },
|
|
5681
|
+
{ name: "Amulet Of The Marid", count: 1 },
|
|
5682
|
+
{ name: "Axe Of Soul Rending", count: 1 },
|
|
5683
|
+
{ name: "Azkol's Banner", count: 1 },
|
|
5684
|
+
{ name: "Azkol's Horn", count: 1 },
|
|
5685
|
+
{ name: "Azkol's Idol", count: 1 },
|
|
5686
|
+
{ name: "Circlet Of Conviction", count: 1 },
|
|
5687
|
+
{ name: "Cloak Of Stars", count: 1 },
|
|
5688
|
+
{ name: "Crown Of Azkol", count: 1 },
|
|
5689
|
+
{ name: "Golden Mace Of Azkol", count: 1 },
|
|
5690
|
+
{ name: "Hallowed Reliquary", count: 1 },
|
|
5691
|
+
{ name: "Kamaria's Carpet", count: 1 },
|
|
5692
|
+
{ name: "Lamp Of Darkness", count: 1 },
|
|
5693
|
+
{ name: "Lamp Of Hope", count: 1 },
|
|
5694
|
+
{ name: "Necklace Of Haggling", count: 1 },
|
|
5695
|
+
{ name: "Oakstone Bow", count: 1 },
|
|
5696
|
+
{ name: "Scroll Of Burning Sands", count: 1 },
|
|
5697
|
+
{ name: "Scroll Of The Great Serpent", count: 1 },
|
|
5698
|
+
{ name: "Scroll Of Twilight Shadow", count: 1 },
|
|
5699
|
+
{ name: "Spear Of Atish", count: 1 },
|
|
5700
|
+
{ name: "Tears Of The Shedu", count: 1 },
|
|
5701
|
+
{ name: "White Cauldron", count: 1 }
|
|
5702
|
+
]
|
|
5703
|
+
}
|
|
5704
|
+
]
|
|
5705
|
+
},
|
|
5706
|
+
{
|
|
5707
|
+
name: "Alliances",
|
|
5708
|
+
categories: [
|
|
5709
|
+
{
|
|
5710
|
+
name: "Boards",
|
|
5711
|
+
section: "Misc",
|
|
5712
|
+
components: [
|
|
5713
|
+
{ name: "Arcane Scouts", count: 1 },
|
|
5714
|
+
{ name: "Archwright", count: 1 },
|
|
5715
|
+
{ name: "Druids Circle", count: 1 },
|
|
5716
|
+
{ name: "Heroic Action", count: 4 },
|
|
5717
|
+
{ name: "Hunted Recluse", count: 1 },
|
|
5718
|
+
{ name: "Influence Vessel", count: 1 },
|
|
5719
|
+
{ name: "Paladins Order", count: 1 },
|
|
5720
|
+
{ name: "Thieves Guild", count: 1 }
|
|
5721
|
+
]
|
|
5722
|
+
},
|
|
5723
|
+
{
|
|
5724
|
+
name: "Mini Bases",
|
|
5725
|
+
section: "Misc",
|
|
5726
|
+
components: [
|
|
5727
|
+
{ color: "Brown", count: 1 },
|
|
5728
|
+
{ color: "Yellow", count: 1 }
|
|
5729
|
+
]
|
|
5730
|
+
},
|
|
5731
|
+
{
|
|
5732
|
+
name: "Flags",
|
|
5733
|
+
section: "Misc",
|
|
5734
|
+
components: [
|
|
5735
|
+
{ type: "Arcane Scouts", count: 1 },
|
|
5736
|
+
{ type: "Druids Circle", count: 1 },
|
|
5737
|
+
{ type: "Paladins Order", count: 1 },
|
|
5738
|
+
{ type: "Thieves Guild", count: 1 }
|
|
5739
|
+
]
|
|
5740
|
+
},
|
|
5741
|
+
{
|
|
5742
|
+
name: "Skulls",
|
|
5743
|
+
section: "Misc",
|
|
5744
|
+
components: [
|
|
5745
|
+
{ color: "Blue (Frost)", count: 11 },
|
|
5746
|
+
{ color: "Green (Blight)", count: 11 },
|
|
5747
|
+
{ color: "Purple (Omen)", count: 11 },
|
|
5748
|
+
{ color: "Red (Fire)", count: 11 }
|
|
5749
|
+
]
|
|
5750
|
+
},
|
|
5751
|
+
{
|
|
5752
|
+
name: "Influence",
|
|
5753
|
+
section: "Tokens",
|
|
5754
|
+
components: [
|
|
5755
|
+
{ name: "1's", count: 17 },
|
|
5756
|
+
{ name: "5's", count: 23 }
|
|
5757
|
+
]
|
|
5758
|
+
},
|
|
5759
|
+
{
|
|
5760
|
+
name: "Virtues",
|
|
5761
|
+
section: "Tokens",
|
|
5762
|
+
components: [
|
|
5763
|
+
{ name: "Exalted", count: 1 },
|
|
5764
|
+
{ name: "Shadowspinner", count: 1 },
|
|
5765
|
+
{ name: "Sinbearer", count: 1 },
|
|
5766
|
+
{ name: "Soulreaper", count: 1 },
|
|
5767
|
+
{ name: "Tactical", count: 1 },
|
|
5768
|
+
{ name: "Wily", count: 1 }
|
|
5769
|
+
]
|
|
5770
|
+
},
|
|
5771
|
+
{
|
|
5772
|
+
name: "Companion",
|
|
5773
|
+
section: "Cards",
|
|
5774
|
+
components: [
|
|
5775
|
+
{ name: "Amani", description: "The Vizier", count: 1 },
|
|
5776
|
+
{ name: "Berat", description: "The Wizard", count: 1 },
|
|
5777
|
+
{ name: "Burgoyn", description: "The Herbalist", count: 1 },
|
|
5778
|
+
{ name: "Ema", description: "The Grand Merchant", count: 1 },
|
|
5779
|
+
{ name: "Haraswa", description: "The Pegasus", count: 1 },
|
|
5780
|
+
{ name: "Lukas", description: "The Plunderer", count: 1 },
|
|
5781
|
+
{ name: "Maxim", description: "The Beast", count: 1 },
|
|
5782
|
+
{ name: "Omar", description: "The Healer", count: 1 },
|
|
5783
|
+
{ name: "Oola", description: "The Nomad", count: 1 },
|
|
5784
|
+
{ name: "Ruska", description: "The Barbarian", count: 1 },
|
|
5785
|
+
{ name: "Sanzhar", description: "The Zealot", count: 1 },
|
|
5786
|
+
{ name: "Xyr", description: "The Oracle", count: 1 }
|
|
5787
|
+
]
|
|
5788
|
+
},
|
|
5789
|
+
{
|
|
5790
|
+
name: "Treasures",
|
|
5791
|
+
section: "Cards",
|
|
5792
|
+
components: [
|
|
5793
|
+
{ name: "Coffer Of The Master Thief", count: 1 },
|
|
5794
|
+
{ name: "Crystal Blade", count: 1 },
|
|
5795
|
+
{ name: "Crystal Platemail", count: 1 },
|
|
5796
|
+
{ name: "Crystal Shield", count: 1 },
|
|
5797
|
+
{ name: "Diadem Of The Emmisary", count: 1 },
|
|
5798
|
+
{ name: "Druid's Incense", count: 1 },
|
|
5799
|
+
{ name: "Everlasting Brazier", count: 1 },
|
|
5800
|
+
{ name: "Ewer Of The Silent Child", count: 1 },
|
|
5801
|
+
{ name: "Forbidden Grimoire", count: 1 },
|
|
5802
|
+
{ name: "Iron Hound Of Azkol", count: 1 },
|
|
5803
|
+
{ name: "Jeweled Goblet Of Azkol", count: 1 },
|
|
5804
|
+
{ name: "Paladin's Greatshield", count: 1 },
|
|
5805
|
+
{ name: "Ring Of The Emmisary", count: 1 },
|
|
5806
|
+
{ name: "Robes Of The Last Sultan", count: 1 },
|
|
5807
|
+
{ name: "Scroll Of Forged Friendship", count: 1 },
|
|
5808
|
+
{ name: "Standard Of The Scouts", count: 1 },
|
|
5809
|
+
{ name: "Staff Of Wishes", count: 1 },
|
|
5810
|
+
{ name: "Trebblok's Hammer", count: 1 },
|
|
5811
|
+
{ name: "Vestments Of The Emmisary", count: 1 },
|
|
5812
|
+
{ name: "Zemayir's Teeth", count: 1 }
|
|
5813
|
+
]
|
|
5814
|
+
}
|
|
5815
|
+
]
|
|
5816
|
+
},
|
|
5817
|
+
{
|
|
5818
|
+
name: "Covenant",
|
|
5819
|
+
categories: [
|
|
5820
|
+
{
|
|
5821
|
+
name: "Boards",
|
|
5822
|
+
section: "Misc",
|
|
5823
|
+
components: [
|
|
5824
|
+
{ name: "Devious Swindler", count: 1 },
|
|
5825
|
+
{ name: "Relentless Warden", count: 1 },
|
|
5826
|
+
{ name: "Reverent Astromancer", count: 1 },
|
|
5827
|
+
{ name: "Undaunted Aegis", count: 1 }
|
|
5828
|
+
]
|
|
5829
|
+
},
|
|
5830
|
+
{
|
|
5831
|
+
name: "Mini Bases",
|
|
5832
|
+
section: "Misc",
|
|
5833
|
+
components: [
|
|
5834
|
+
{ color: "Blue", count: 1 },
|
|
5835
|
+
{ color: "Brown", count: 1 },
|
|
5836
|
+
{ color: "Green", count: 1 },
|
|
5837
|
+
{ color: "Orange", count: 1 }
|
|
5838
|
+
]
|
|
5839
|
+
},
|
|
5840
|
+
{
|
|
5841
|
+
name: "Monuments",
|
|
5842
|
+
section: "Misc",
|
|
5843
|
+
components: [
|
|
5844
|
+
{ type: "Arch of the Golden Sun", count: 1 },
|
|
5845
|
+
{ type: "Argent Oak", count: 1 },
|
|
5846
|
+
{ type: "Cenotaph of the First Prophet", count: 1 },
|
|
5847
|
+
{ type: "Colossus of Bjorn", count: 1 },
|
|
5848
|
+
{ type: "Endless Necropolis", count: 1 },
|
|
5849
|
+
{ type: "Moonstone Temple", count: 1 },
|
|
5850
|
+
{ type: "Nightmare Cage", count: 1 },
|
|
5851
|
+
{ type: "Tower Shard", count: 1 }
|
|
5852
|
+
]
|
|
5853
|
+
},
|
|
5854
|
+
{
|
|
5855
|
+
name: "Foundation",
|
|
5856
|
+
section: "Tokens",
|
|
5857
|
+
components: [
|
|
5858
|
+
{ name: "Arch of the Golden Sun / Nightmare Cage", count: 1 },
|
|
5859
|
+
{ name: "Argent Oak / Moonstone Temple", count: 1 },
|
|
5860
|
+
{ name: "Cenotaph of the First Prophet / Tower Shard", count: 1 },
|
|
5861
|
+
{ name: "Colossus of Bjorn / Endless Necropolis", count: 1 }
|
|
5862
|
+
]
|
|
5863
|
+
},
|
|
5864
|
+
{
|
|
5865
|
+
name: "Virtues",
|
|
5866
|
+
section: "Tokens",
|
|
5867
|
+
components: [
|
|
5868
|
+
{ name: "Bounteous", count: 1 },
|
|
5869
|
+
{ name: "Exalted", count: 1 },
|
|
5870
|
+
{ name: "Zealous", count: 1 },
|
|
5871
|
+
{ name: "Emboldened", count: 1 },
|
|
5872
|
+
{ name: "Resolute", count: 1 },
|
|
5873
|
+
{ name: "Steeled", count: 1 },
|
|
5874
|
+
{ name: "Keen-Eyed", count: 1 },
|
|
5875
|
+
{ name: "Inspiring", count: 1 },
|
|
5876
|
+
{ name: "Instinctive", count: 1 },
|
|
5877
|
+
{ name: "Calculating", count: 1 },
|
|
5878
|
+
{ name: "Opportunistic", count: 1 },
|
|
5879
|
+
{ name: "Fortuitous", count: 1 }
|
|
5880
|
+
]
|
|
5881
|
+
},
|
|
5882
|
+
{
|
|
5883
|
+
name: "Corruption",
|
|
5884
|
+
section: "Cards",
|
|
5885
|
+
components: [
|
|
5886
|
+
{ name: "Aquaphobic", count: 1 },
|
|
5887
|
+
{ name: "Arrogant", count: 1 },
|
|
5888
|
+
{ name: "Crestfallen", count: 1 },
|
|
5889
|
+
{ name: "Disreputable", count: 1 },
|
|
5890
|
+
{ name: "Fatigued", count: 1 },
|
|
5891
|
+
{ name: "Indolent", count: 1 },
|
|
5892
|
+
{ name: "Inobservant", count: 1 },
|
|
5893
|
+
{ name: "Reckless", count: 1 },
|
|
5894
|
+
{ name: "Shaken", count: 1 },
|
|
5895
|
+
{ name: "Snobby", count: 1 },
|
|
5896
|
+
{ name: "Timid", count: 1 },
|
|
5897
|
+
{ name: "Vain", count: 1 }
|
|
5898
|
+
]
|
|
5899
|
+
},
|
|
5900
|
+
{
|
|
5901
|
+
name: "Invocation",
|
|
5902
|
+
section: "Cards",
|
|
5903
|
+
components: [
|
|
5904
|
+
{ name: "Abate the Darkness", count: 1 },
|
|
5905
|
+
{ name: "Celestial Jaunt", count: 1 },
|
|
5906
|
+
{ name: "Commanding Rebuke", count: 1 },
|
|
5907
|
+
{ name: "Smite the Wicked", count: 1 }
|
|
5908
|
+
]
|
|
5909
|
+
},
|
|
5910
|
+
{
|
|
5911
|
+
name: "Monument",
|
|
5912
|
+
section: "Cards",
|
|
5913
|
+
components: [
|
|
5914
|
+
{ name: "Arch of the Golden Sun", description: "Bazaar", count: 1 },
|
|
5915
|
+
{ name: "Argent Oak", description: "Sanctuary", count: 1 },
|
|
5916
|
+
{ name: "Cenotaph of the First Prophet", description: "Citadel", count: 1 },
|
|
5917
|
+
{ name: "Colossus of Bjorn", description: "Village", count: 1 },
|
|
5918
|
+
{ name: "Endless Necropolis", description: "Village", count: 1 },
|
|
5919
|
+
{ name: "Moonstone Temple", description: "Sanctuary", count: 1 },
|
|
5920
|
+
{ name: "Nightmare Cage", description: "Bazaar", count: 1 },
|
|
5921
|
+
{ name: "Tower Shard", description: "Citadel", count: 1 }
|
|
5922
|
+
]
|
|
5923
|
+
},
|
|
5924
|
+
{
|
|
5925
|
+
name: "Spell",
|
|
5926
|
+
section: "Cards",
|
|
5927
|
+
components: [
|
|
5928
|
+
{ name: "Aura of Friendship", count: 1 },
|
|
5929
|
+
{ name: "Bestow Blessing", count: 1 },
|
|
5930
|
+
{ name: "Bounty of the Gods", count: 1 },
|
|
5931
|
+
{ name: "Ritual of Warding", count: 1 },
|
|
5932
|
+
{ name: "Soothing Word", count: 1 },
|
|
5933
|
+
{ name: "Winds of Change", count: 1 }
|
|
5934
|
+
]
|
|
5935
|
+
},
|
|
5936
|
+
{
|
|
5937
|
+
name: "Treasures",
|
|
5938
|
+
section: "Cards",
|
|
5939
|
+
components: [
|
|
5940
|
+
{ name: "Archwright's Sledge", count: 1 },
|
|
5941
|
+
{ name: "Azkol's Chakram", count: 1 },
|
|
5942
|
+
{ name: "Azkol's Ichor", count: 1 },
|
|
5943
|
+
{ name: "Azkol's Scroll", count: 1 },
|
|
5944
|
+
{ name: "Azkol's Vambraces", count: 1 },
|
|
5945
|
+
{ name: "Beacon Stone", count: 1 },
|
|
5946
|
+
{ name: "Brutal Warlord's Bell", count: 1 },
|
|
5947
|
+
{ name: "Everfilled Chest", count: 1 },
|
|
5948
|
+
{ name: "Grim Whisper", count: 1 },
|
|
5949
|
+
{ name: "Haunted Recluse's Effigy", count: 1 },
|
|
5950
|
+
{ name: "Opal of Protection", count: 1 },
|
|
5951
|
+
{ name: "Orhpaned Scion's Charm", count: 1 },
|
|
5952
|
+
{ name: "Relic Hunter's Flagon", count: 1 },
|
|
5953
|
+
{ name: "Sanctified Flask", count: 1 },
|
|
5954
|
+
{ name: "Spymaster's Journal", count: 1 },
|
|
5955
|
+
{ name: "Tent of Revelry", count: 1 },
|
|
5956
|
+
{ name: "The Iron Wall", count: 1 },
|
|
5957
|
+
{ name: "Wand of Celerity", count: 1 },
|
|
5958
|
+
{ name: "Wand of Conflagration", count: 1 },
|
|
5959
|
+
{ name: "Wand of Pacification", count: 1 }
|
|
5960
|
+
]
|
|
5961
|
+
}
|
|
5962
|
+
]
|
|
5963
|
+
},
|
|
5964
|
+
{
|
|
5965
|
+
name: "Dark Horde",
|
|
5966
|
+
categories: [
|
|
5967
|
+
{
|
|
5968
|
+
name: "Storage Tray 1 (Top)",
|
|
5969
|
+
section: "Minis",
|
|
5970
|
+
components: [
|
|
5971
|
+
{ name: "Briagands", count: 8 },
|
|
5972
|
+
{ name: "Clan Of Neuri", count: 5 },
|
|
5973
|
+
{ name: "Isa The Exile", count: 1 },
|
|
5974
|
+
{ name: "Lemure", count: 6 },
|
|
5975
|
+
{ name: "Mormo", count: 4 },
|
|
5976
|
+
{ name: "Oreks", count: 6 },
|
|
5977
|
+
{ name: "Shadow Wolves", count: 8 },
|
|
5978
|
+
{ name: "Spine Fiend", count: 6 },
|
|
5979
|
+
{ name: "Widowmade Spider", count: 5 }
|
|
5980
|
+
]
|
|
5981
|
+
},
|
|
5982
|
+
{
|
|
5983
|
+
name: "Storage Tray 2 (Bottom)",
|
|
5984
|
+
section: "Minis",
|
|
5985
|
+
components: [
|
|
5986
|
+
{ name: "Frost Trolls", count: 4 },
|
|
5987
|
+
{ name: "Gravemaw", count: 1 },
|
|
5988
|
+
{ name: "Dragon", count: 2 },
|
|
5989
|
+
{ name: "Empress Of Shades", count: 1 },
|
|
5990
|
+
{ name: "Bane Of Omens", count: 1 },
|
|
5991
|
+
{ name: "Lingering Rot", count: 1 },
|
|
5992
|
+
{ name: "Striga", count: 2 },
|
|
5993
|
+
{ name: "Ashstrider", count: 1 },
|
|
5994
|
+
{ name: "Titan", count: 1 },
|
|
5995
|
+
{ name: "Gaze Eternal", count: 1 },
|
|
5996
|
+
{ name: "U'tuk-Ku The Ice Herald", count: 1 },
|
|
5997
|
+
{ name: "Main Goal Marker", count: 1 },
|
|
5998
|
+
{ name: "Guild Quest Marker", count: 1 },
|
|
5999
|
+
{ name: "Adversary Quest Marker", count: 1 },
|
|
6000
|
+
{ name: "Companion Quest Marker", count: 1 }
|
|
6001
|
+
]
|
|
6002
|
+
}
|
|
6003
|
+
]
|
|
6004
|
+
}
|
|
6005
|
+
];
|
|
6006
|
+
var EXPANSIONS = expansions.reduce(
|
|
6007
|
+
(acc, e) => {
|
|
6008
|
+
acc[e.name] = e;
|
|
6009
|
+
return acc;
|
|
6010
|
+
},
|
|
6011
|
+
{}
|
|
6012
|
+
);
|
|
6013
|
+
var coffers = [
|
|
6014
|
+
{
|
|
6015
|
+
resource: "Influence",
|
|
6016
|
+
denominations: [
|
|
6017
|
+
{ name: "1's", count: 8 },
|
|
6018
|
+
{ name: "5's", count: 17 }
|
|
6019
|
+
],
|
|
6020
|
+
total: 25
|
|
6021
|
+
},
|
|
6022
|
+
{
|
|
6023
|
+
resource: "Spirits",
|
|
6024
|
+
denominations: [
|
|
6025
|
+
{ name: "1's", count: 24 },
|
|
6026
|
+
{ name: "5's", count: 16 }
|
|
6027
|
+
],
|
|
6028
|
+
total: 40
|
|
6029
|
+
},
|
|
6030
|
+
{
|
|
6031
|
+
resource: "Warriors",
|
|
6032
|
+
denominations: [
|
|
6033
|
+
{ name: "1's", count: 28 },
|
|
6034
|
+
{ name: "5's", count: 22 }
|
|
6035
|
+
],
|
|
6036
|
+
total: 50
|
|
6037
|
+
}
|
|
6038
|
+
];
|
|
6039
|
+
var coffers2 = {
|
|
6040
|
+
tokens: [
|
|
6041
|
+
{ name: "Advantage", count: 10 },
|
|
6042
|
+
{ name: "Charge", count: 10 },
|
|
6043
|
+
{ name: "Foundation", count: 4 },
|
|
6044
|
+
{ name: "Guild", count: 4 },
|
|
6045
|
+
{ name: "Protection", count: 6 },
|
|
6046
|
+
{ name: "Quarry", count: 1 },
|
|
6047
|
+
{ name: "Wasteland", count: 32 }
|
|
6048
|
+
],
|
|
6049
|
+
total: 67
|
|
6050
|
+
};
|
|
6051
|
+
var skullsPack = {
|
|
6052
|
+
tokens: [
|
|
6053
|
+
{ name: "White (Normal)", count: 10 },
|
|
6054
|
+
{ name: "Black (Doom)", count: 2 },
|
|
6055
|
+
{ name: "Blue (Frost)", count: 2 },
|
|
6056
|
+
{ name: "Green (Blight)", count: 2 },
|
|
6057
|
+
{ name: "Purple (Omen)", count: 2 },
|
|
6058
|
+
{ name: "Red (Fire)", count: 2 }
|
|
6059
|
+
],
|
|
6060
|
+
total: 20
|
|
6061
|
+
};
|
|
6062
|
+
var sleeves = [
|
|
6063
|
+
{ name: "Printed Large Sleeves", purposes: ["Monuments", "Treasure Cards"] },
|
|
6064
|
+
{
|
|
6065
|
+
name: "Printed Mini Sleeves",
|
|
6066
|
+
purposes: ["Gear", "Heroic Tests", "Invocations", "Potions", "Quest Items", "Spells"]
|
|
6067
|
+
},
|
|
6068
|
+
{ name: "Clear Large Sleeves", purposes: ["Companions", "Foes"] },
|
|
6069
|
+
{ name: "Clear Mini Sleeves", purposes: ["Blessings", "Corruptions"] }
|
|
6070
|
+
];
|
|
6071
|
+
|
|
6072
|
+
// src/seed/index.ts
|
|
6073
|
+
var seed_exports = {};
|
|
6074
|
+
__export(seed_exports, {
|
|
6075
|
+
ADVERSARIES: () => ADVERSARIES2,
|
|
6076
|
+
ALLIES: () => ALLIES,
|
|
6077
|
+
DIFFICULTIES: () => DIFFICULTIES,
|
|
6078
|
+
GAME_SOURCES: () => GAME_SOURCES,
|
|
6079
|
+
SystemRandom: () => SystemRandom,
|
|
6080
|
+
TIER1_FOES: () => TIER1_FOES,
|
|
6081
|
+
TIER2_FOES: () => TIER2_FOES,
|
|
6082
|
+
TIER3_FOES: () => TIER3_FOES,
|
|
6083
|
+
charToValue: () => charToValue,
|
|
6084
|
+
compareSeedsRaw: () => compareSeedsRaw,
|
|
6085
|
+
createSeed: () => createSeed,
|
|
6086
|
+
decodeRngSeed: () => decodeRngSeed,
|
|
6087
|
+
decodeSeed: () => decodeSeed,
|
|
6088
|
+
dumpSeedChars: () => dumpSeedChars,
|
|
6089
|
+
encodeSeed: () => encodeSeed,
|
|
6090
|
+
validateSeed: () => validateSeed,
|
|
6091
|
+
valueToChar: () => valueToChar
|
|
6092
|
+
});
|
|
6093
|
+
|
|
6094
|
+
// src/seed/udtSeedParser.ts
|
|
4071
6095
|
var ALPHABET = "a123456789bcdefghijklmnpqrstuvwxyz";
|
|
4072
6096
|
var BASE = 34;
|
|
4073
6097
|
var SETUP_LENGTH = 6;
|
|
@@ -4082,7 +6106,7 @@ for (let i = 0; i < ALPHABET.length; i++) {
|
|
|
4082
6106
|
var TIER1_FOES = ["Brigands", "Oreks", "Shadow Wolves", "Spine Fiends"];
|
|
4083
6107
|
var TIER2_FOES = ["Frost Trolls", "Clan of Neuri", "Lemures", "Widowmade Spiders"];
|
|
4084
6108
|
var TIER3_FOES = ["Dragons", "Mormos", "Striga", "Titans"];
|
|
4085
|
-
var
|
|
6109
|
+
var ADVERSARIES2 = [
|
|
4086
6110
|
"Ashstrider",
|
|
4087
6111
|
"Bane of Omens",
|
|
4088
6112
|
"Empress of Shades",
|
|
@@ -4157,9 +6181,9 @@ function decodeSeed(seed) {
|
|
|
4157
6181
|
const expansionBits = (extra & 6) >> 1;
|
|
4158
6182
|
const sourceBits = (extra & 8) >> 2;
|
|
4159
6183
|
const playerCount = (setup[5] & 3) + 1;
|
|
4160
|
-
const
|
|
4161
|
-
if (expansionBits & 1)
|
|
4162
|
-
if (expansionBits & 2)
|
|
6184
|
+
const expansions2 = [];
|
|
6185
|
+
if (expansionBits & 1) expansions2.push("Monuments");
|
|
6186
|
+
if (expansionBits & 2) expansions2.push("Alliances");
|
|
4163
6187
|
let source;
|
|
4164
6188
|
switch (sourceBits) {
|
|
4165
6189
|
case 2:
|
|
@@ -4179,11 +6203,11 @@ function decodeSeed(seed) {
|
|
|
4179
6203
|
tier1Foe: TIER1_FOES[tier1],
|
|
4180
6204
|
tier2Foe: TIER2_FOES[tier2],
|
|
4181
6205
|
tier3Foe: TIER3_FOES[tier3],
|
|
4182
|
-
adversary:
|
|
6206
|
+
adversary: ADVERSARIES2[adversaryIndex],
|
|
4183
6207
|
ally: ALLIES[allyIndex],
|
|
4184
6208
|
difficulty: DIFFICULTIES[difficultyIndex],
|
|
4185
6209
|
source,
|
|
4186
|
-
expansions,
|
|
6210
|
+
expansions: expansions2,
|
|
4187
6211
|
playerCount,
|
|
4188
6212
|
rngSeed,
|
|
4189
6213
|
seedBank,
|
|
@@ -4213,7 +6237,7 @@ function createSeed(config) {
|
|
|
4213
6237
|
foeByteA |= (tier2Index & 3) << 2;
|
|
4214
6238
|
foeByteA |= (tier3Index & 1) << 4;
|
|
4215
6239
|
foeByteB |= (tier3Index >> 1 & 1) << 4;
|
|
4216
|
-
const adversaryIndex =
|
|
6240
|
+
const adversaryIndex = ADVERSARIES2.indexOf(config.adversary);
|
|
4217
6241
|
if (adversaryIndex < 0) throw new Error(`Invalid adversary: ${config.adversary}`);
|
|
4218
6242
|
foeByteB |= adversaryIndex & 15;
|
|
4219
6243
|
const allyIndex = ALLIES.indexOf(config.ally);
|
|
@@ -4257,7 +6281,7 @@ function encodeSeed(config, rngValue) {
|
|
|
4257
6281
|
foeByteA |= (tier2Index & 3) << 2;
|
|
4258
6282
|
foeByteA |= (tier3Index & 1) << 4;
|
|
4259
6283
|
foeByteB |= (tier3Index >> 1 & 1) << 4;
|
|
4260
|
-
const adversaryIndex =
|
|
6284
|
+
const adversaryIndex = ADVERSARIES2.indexOf(config.adversary);
|
|
4261
6285
|
if (adversaryIndex < 0) throw new Error(`Invalid adversary: ${config.adversary}`);
|
|
4262
6286
|
foeByteB |= adversaryIndex & 15;
|
|
4263
6287
|
const allyIndex = ALLIES.indexOf(config.ally);
|
|
@@ -4339,7 +6363,7 @@ function dumpSeedChars(seed) {
|
|
|
4339
6363
|
return { seed: normalized, chars };
|
|
4340
6364
|
}
|
|
4341
6365
|
|
|
4342
|
-
// src/udtSystemRandom.ts
|
|
6366
|
+
// src/seed/udtSystemRandom.ts
|
|
4343
6367
|
var INT32_MAX = 2147483647;
|
|
4344
6368
|
var MSEED = 161803398;
|
|
4345
6369
|
function toInt32(n) {
|
|
@@ -4452,93 +6476,11 @@ var SystemRandom = class {
|
|
|
4452
6476
|
}
|
|
4453
6477
|
};
|
|
4454
6478
|
|
|
4455
|
-
// src/udtGameBoard.ts
|
|
4456
|
-
var BOARD_GROUPINGS = {
|
|
4457
|
-
/** Dayside and Fivepint (North kingdom lakes). */
|
|
4458
|
-
LONG_WATER: "Long Water",
|
|
4459
|
-
/** Delmsmire, Arkartus, and Yellowpike (West kingdom forests). */
|
|
4460
|
-
THE_GREAT_WOODS: "The Great Woods",
|
|
4461
|
-
/** The Throne, The Cloister, and Archmont (South kingdom grasslands). */
|
|
4462
|
-
REGAL_RUN: "Regal Run"
|
|
4463
|
-
};
|
|
4464
|
-
var BOARD_LOCATIONS = [
|
|
4465
|
-
// ── North ───────────────────────────────────────────────────────────────
|
|
4466
|
-
{ name: "Broken Lands", terrain: "Hills", kingdom: "north" },
|
|
4467
|
-
{ name: "Dayside", terrain: "Lake", building: "Bazaar", kingdom: "north", grouping: BOARD_GROUPINGS.LONG_WATER },
|
|
4468
|
-
{ name: "Egan's End", terrain: "Grasslands", building: "Village", kingdom: "north" },
|
|
4469
|
-
{ name: "Fivepint", terrain: "Lake", kingdom: "north", grouping: BOARD_GROUPINGS.LONG_WATER },
|
|
4470
|
-
{ name: "Green Bridge", terrain: "Grasslands", kingdom: "north" },
|
|
4471
|
-
{ name: "Lodestone Mountains", terrain: "Mountains", kingdom: "north" },
|
|
4472
|
-
{ name: "Lower Ice Fangs", terrain: "Mountains", kingdom: "north" },
|
|
4473
|
-
{ name: "Muted Forest", terrain: "Forest", kingdom: "north" },
|
|
4474
|
-
{ name: "Peaks of the Djinn", terrain: "Mountains", kingdom: "north" },
|
|
4475
|
-
{ name: "Pearl of the North", terrain: "Grasslands", kingdom: "north" },
|
|
4476
|
-
{ name: "Radiant Mountains", terrain: "Mountains", building: "Citadel", kingdom: "north" },
|
|
4477
|
-
{ name: "Rimeweald", terrain: "Forest", kingdom: "north" },
|
|
4478
|
-
{ name: "The Tundra", terrain: "Desert", kingdom: "north" },
|
|
4479
|
-
{ name: "Tower Scar Desert", terrain: "Desert", kingdom: "north" },
|
|
4480
|
-
{ name: "Upper Ice Fangs", terrain: "Mountains", building: "Sanctuary", kingdom: "north" },
|
|
4481
|
-
// ── East ────────────────────────────────────────────────────────────────
|
|
4482
|
-
{ name: "Big Sister", terrain: "Mountains", kingdom: "east" },
|
|
4483
|
-
{ name: "Bleak Wastes", terrain: "Desert", kingdom: "east" },
|
|
4484
|
-
{ name: "Copper Grove", terrain: "Forest", kingdom: "east" },
|
|
4485
|
-
{ name: "Dragontooth Lake", terrain: "Lake", kingdom: "east" },
|
|
4486
|
-
{ name: "Duwani", terrain: "Grasslands", building: "Village", kingdom: "east" },
|
|
4487
|
-
{ name: "Forest of Shades", terrain: "Forest", kingdom: "east" },
|
|
4488
|
-
{ name: "Greater Tombstones", terrain: "Hills", building: "Sanctuary", kingdom: "east" },
|
|
4489
|
-
{ name: "Inner Kinghills", terrain: "Hills", building: "Citadel", kingdom: "east" },
|
|
4490
|
-
{ name: "Jewel Hills", terrain: "Hills", kingdom: "east" },
|
|
4491
|
-
{ name: "Lake of Songs", terrain: "Lake", kingdom: "east" },
|
|
4492
|
-
{ name: "Lesser Tombstones", terrain: "Hills", kingdom: "east" },
|
|
4493
|
-
{ name: "Outer Kinghills", terrain: "Hills", kingdom: "east" },
|
|
4494
|
-
{ name: "The Decaying Wilds", terrain: "Grasslands", kingdom: "east" },
|
|
4495
|
-
{ name: "Three Rivers", terrain: "Grasslands", building: "Bazaar", kingdom: "east" },
|
|
4496
|
-
{ name: "Utar's Barrows", terrain: "Desert", kingdom: "east" },
|
|
4497
|
-
// ── West ────────────────────────────────────────────────────────────────
|
|
4498
|
-
{ name: "Anza", terrain: "Grasslands", building: "Village", kingdom: "west" },
|
|
4499
|
-
{ name: "Arkartus", terrain: "Forest", building: "Sanctuary", kingdom: "west", grouping: BOARD_GROUPINGS.THE_GREAT_WOODS },
|
|
4500
|
-
{ name: "Ash Hills", terrain: "Hills", kingdom: "west" },
|
|
4501
|
-
{ name: "Cloudhold", terrain: "Mountains", kingdom: "west" },
|
|
4502
|
-
{ name: "Delmsmire", terrain: "Forest", kingdom: "west", grouping: BOARD_GROUPINGS.THE_GREAT_WOODS },
|
|
4503
|
-
{ name: "Hissing Groves", terrain: "Forest", building: "Citadel", kingdom: "west" },
|
|
4504
|
-
{ name: "Idran Forest", terrain: "Forest", kingdom: "west" },
|
|
4505
|
-
{ name: "Lonelight Hills", terrain: "Hills", kingdom: "west" },
|
|
4506
|
-
{ name: "Lost Lands", terrain: "Desert", kingdom: "west" },
|
|
4507
|
-
{ name: "Plains of Plovo", terrain: "Grasslands", building: "Bazaar", kingdom: "west" },
|
|
4508
|
-
{ name: "Plains of Woldra", terrain: "Grasslands", kingdom: "west" },
|
|
4509
|
-
{ name: "The Empty Glade", terrain: "Grasslands", kingdom: "west" },
|
|
4510
|
-
{ name: "The Grass Sea", terrain: "Grasslands", kingdom: "west" },
|
|
4511
|
-
{ name: "Weeping Waters", terrain: "Lake", kingdom: "west" },
|
|
4512
|
-
{ name: "Yellowpike", terrain: "Forest", kingdom: "west", grouping: BOARD_GROUPINGS.THE_GREAT_WOODS },
|
|
4513
|
-
// ── South ───────────────────────────────────────────────────────────────
|
|
4514
|
-
{ name: "Archmont", terrain: "Grasslands", kingdom: "south", grouping: BOARD_GROUPINGS.REGAL_RUN },
|
|
4515
|
-
{ name: "Azkol's Bane", terrain: "Desert", kingdom: "south" },
|
|
4516
|
-
{ name: "Bone Hills", terrain: "Hills", kingdom: "south" },
|
|
4517
|
-
{ name: "Howling Desert", terrain: "Desert", building: "Citadel", kingdom: "south" },
|
|
4518
|
-
{ name: "Irontops", terrain: "Mountains", kingdom: "south" },
|
|
4519
|
-
{ name: "Little Sister", terrain: "Mountains", kingdom: "south" },
|
|
4520
|
-
{ name: "Middle Sister", terrain: "Mountains", kingdom: "south" },
|
|
4521
|
-
{ name: "Mountains of the Watchers", terrain: "Mountains", kingdom: "south" },
|
|
4522
|
-
{ name: "Pine Barrens", terrain: "Forest", kingdom: "south" },
|
|
4523
|
-
{ name: "Sands of Madness", terrain: "Desert", building: "Sanctuary", kingdom: "south" },
|
|
4524
|
-
{ name: "Southern Wastes", terrain: "Desert", building: "Village", kingdom: "south" },
|
|
4525
|
-
{ name: "The Cloister", terrain: "Grasslands", kingdom: "south", grouping: BOARD_GROUPINGS.REGAL_RUN },
|
|
4526
|
-
{ name: "The Emerald Expanse", terrain: "Grasslands", building: "Bazaar", kingdom: "south" },
|
|
4527
|
-
{ name: "The Throne", terrain: "Grasslands", kingdom: "south", grouping: BOARD_GROUPINGS.REGAL_RUN },
|
|
4528
|
-
{ name: "Ulamel's Hollow", terrain: "Grasslands", kingdom: "south" }
|
|
4529
|
-
];
|
|
4530
|
-
var BOARD_LOCATION_BY_NAME = Object.fromEntries(BOARD_LOCATIONS.map((loc) => [loc.name, loc]));
|
|
4531
|
-
|
|
4532
6479
|
// src/index.ts
|
|
4533
6480
|
var index_default = UltimateDarkTower_default;
|
|
4534
6481
|
export {
|
|
4535
|
-
ADVERSARIES,
|
|
4536
|
-
ALLIES,
|
|
4537
6482
|
AUDIO_COMMAND_POS,
|
|
4538
6483
|
BATTERY_STATUS_FREQUENCY,
|
|
4539
|
-
BOARD_GROUPINGS,
|
|
4540
|
-
BOARD_LOCATIONS,
|
|
4541
|
-
BOARD_LOCATION_BY_NAME,
|
|
4542
6484
|
BluetoothAdapterFactory,
|
|
4543
6485
|
BluetoothConnectionError,
|
|
4544
6486
|
BluetoothDeviceNotFoundError,
|
|
@@ -4552,7 +6494,6 @@ export {
|
|
|
4552
6494
|
DEFAULT_CONNECTION_MONITORING_FREQUENCY,
|
|
4553
6495
|
DEFAULT_CONNECTION_MONITORING_TIMEOUT,
|
|
4554
6496
|
DEFAULT_RETRY_SEND_COMMAND_MAX,
|
|
4555
|
-
DIFFICULTIES,
|
|
4556
6497
|
DIS_FIRMWARE_REVISION_UUID,
|
|
4557
6498
|
DIS_HARDWARE_REVISION_UUID,
|
|
4558
6499
|
DIS_IEEE_REGULATORY_UUID,
|
|
@@ -4565,7 +6506,6 @@ export {
|
|
|
4565
6506
|
DIS_SYSTEM_ID_UUID,
|
|
4566
6507
|
DOMOutput,
|
|
4567
6508
|
DRUM_PACKETS,
|
|
4568
|
-
GAME_SOURCES,
|
|
4569
6509
|
GLYPHS,
|
|
4570
6510
|
InMemorySink,
|
|
4571
6511
|
IndexedDBSink,
|
|
@@ -4578,11 +6518,7 @@ export {
|
|
|
4578
6518
|
RING_LIGHT_POSITIONS,
|
|
4579
6519
|
SKULL_DROP_COUNT_POS,
|
|
4580
6520
|
STATE_DATA_LENGTH,
|
|
4581
|
-
SystemRandom,
|
|
4582
6521
|
TC,
|
|
4583
|
-
TIER1_FOES,
|
|
4584
|
-
TIER2_FOES,
|
|
4585
|
-
TIER3_FOES,
|
|
4586
6522
|
TOWER_AUDIO_LIBRARY,
|
|
4587
6523
|
TOWER_COMMANDS,
|
|
4588
6524
|
TOWER_COMMAND_HEADER_SIZE,
|
|
@@ -4605,16 +6541,10 @@ export {
|
|
|
4605
6541
|
VOLUME_DESCRIPTIONS,
|
|
4606
6542
|
VOLUME_ICONS,
|
|
4607
6543
|
bytesToHex,
|
|
4608
|
-
charToValue,
|
|
4609
|
-
compareSeedsRaw,
|
|
4610
6544
|
createDefaultTowerState,
|
|
4611
|
-
|
|
4612
|
-
decodeRngSeed,
|
|
4613
|
-
decodeSeed,
|
|
6545
|
+
data_exports as data,
|
|
4614
6546
|
index_default as default,
|
|
4615
6547
|
drumPositionCmds,
|
|
4616
|
-
dumpSeedChars,
|
|
4617
|
-
encodeSeed,
|
|
4618
6548
|
isCalibrated,
|
|
4619
6549
|
logger,
|
|
4620
6550
|
milliVoltsToPercentage,
|
|
@@ -4622,6 +6552,5 @@ export {
|
|
|
4622
6552
|
parseDifferentialReadings,
|
|
4623
6553
|
rtdt_pack_state,
|
|
4624
6554
|
rtdt_unpack_state,
|
|
4625
|
-
|
|
4626
|
-
valueToChar
|
|
6555
|
+
seed_exports as seed
|
|
4627
6556
|
};
|