uesp-eso-build-wrapper 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +167 -0
- package/THIRD_PARTY_NOTICES +39 -0
- package/dist/lib/eso-engine/calculator.d.ts +39 -0
- package/dist/lib/eso-engine/calculator.d.ts.map +1 -0
- package/dist/lib/eso-engine/calculator.js +189 -0
- package/dist/lib/eso-engine/calculator.js.map +1 -0
- package/dist/lib/eso-engine/env-setup.d.ts +25 -0
- package/dist/lib/eso-engine/env-setup.d.ts.map +1 -0
- package/dist/lib/eso-engine/env-setup.js +238 -0
- package/dist/lib/eso-engine/env-setup.js.map +1 -0
- package/dist/lib/eso-engine/index.d.ts +58 -0
- package/dist/lib/eso-engine/index.d.ts.map +1 -0
- package/dist/lib/eso-engine/index.js +119 -0
- package/dist/lib/eso-engine/index.js.map +1 -0
- package/dist/lib/eso-engine/loader.d.ts +25 -0
- package/dist/lib/eso-engine/loader.d.ts.map +1 -0
- package/dist/lib/eso-engine/loader.js +189 -0
- package/dist/lib/eso-engine/loader.js.map +1 -0
- package/dist/lib/eso-engine/types.d.ts +136 -0
- package/dist/lib/eso-engine/types.d.ts.map +1 -0
- package/dist/lib/eso-engine/types.js +21 -0
- package/dist/lib/eso-engine/types.js.map +1 -0
- package/package.json +55 -0
- package/vendor/uesp-data/uesp-init-data.json +8294 -0
- package/vendor/uesp-esochardata/LICENSE +21 -0
- package/vendor/uesp-esochardata/resources/esoEditBuild.js +15221 -0
- package/vendor/uesp-esochardata/resources/esobuilddata.js +3575 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 srtomy
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
# uesp-eso-build-wrapper
|
|
2
|
+
|
|
3
|
+
A Node.js/TypeScript wrapper around the [UESP ESO Build Editor](https://github.com/uesp/uesp-esochardata) math engine.
|
|
4
|
+
|
|
5
|
+
Calculate Elder Scrolls Online **Computed Character Statistics** — Health, Magicka, Stamina, mitigation, crit chance, regeneration, and 200+ more — using UESP's own formulas. No formula reimplementation. No database.
|
|
6
|
+
|
|
7
|
+
## Features
|
|
8
|
+
|
|
9
|
+
- ✅ **100% UESP formulas** — same engine powering [esobuilds.uesp.net](https://esobuilds.uesp.net)
|
|
10
|
+
- ✅ **221 computed stats** — all `Computed Character Statistics` from the build editor
|
|
11
|
+
- ✅ **Zero runtime dependencies** — pure Node.js
|
|
12
|
+
- ✅ **Full TypeScript types** — typed inputs and outputs
|
|
13
|
+
- ✅ **Singleton loader** — loads the engine once per process, fast on subsequent calls
|
|
14
|
+
|
|
15
|
+
## Installation
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
npm install uesp-eso-build-wrapper
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Quick Start
|
|
22
|
+
|
|
23
|
+
```ts
|
|
24
|
+
import { initEsoEngine, calculateBuild } from 'uesp-eso-build-wrapper';
|
|
25
|
+
|
|
26
|
+
// Initialize once — resolves bundled vendor files automatically
|
|
27
|
+
initEsoEngine();
|
|
28
|
+
|
|
29
|
+
const stats = calculateBuild({
|
|
30
|
+
character: {
|
|
31
|
+
race: 'High Elf',
|
|
32
|
+
class: 'Sorcerer',
|
|
33
|
+
level: 50,
|
|
34
|
+
attributes: { health: 0, magicka: 64, stamina: 0 },
|
|
35
|
+
},
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
console.log(stats.Health); // 16000
|
|
39
|
+
console.log(stats.Magicka); // 19104
|
|
40
|
+
console.log(stats.MagickaRegen); // 514
|
|
41
|
+
console.log(stats.SpellDamage); // 1000
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## With Equipped Items
|
|
45
|
+
|
|
46
|
+
Items are passed directly as returned by the [UESP public item API](https://esolog.uesp.net/exportJson.php?table=minedItem&id=70&level=50&quality=5).
|
|
47
|
+
|
|
48
|
+
```ts
|
|
49
|
+
// 1. Fetch item data from UESP API
|
|
50
|
+
const res = await fetch(
|
|
51
|
+
'https://esolog.uesp.net/exportJson.php?table=minedItem&id=70&level=50&quality=5'
|
|
52
|
+
);
|
|
53
|
+
const data = await res.json();
|
|
54
|
+
const item = data.minedItem[0]; // pick the variant you want
|
|
55
|
+
|
|
56
|
+
// 2. Pass it directly — no mapping needed
|
|
57
|
+
const stats = calculateBuild({
|
|
58
|
+
character: {
|
|
59
|
+
race: 'Nord',
|
|
60
|
+
class: 'Dragonknight',
|
|
61
|
+
level: 50,
|
|
62
|
+
attributes: { health: 64, magicka: 0, stamina: 0 },
|
|
63
|
+
},
|
|
64
|
+
items: {
|
|
65
|
+
Chest: item,
|
|
66
|
+
},
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
console.log(stats.Health); // includes item enchant + set bonus
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## API
|
|
73
|
+
|
|
74
|
+
### `initEsoEngine(resourcesPath?, initDataPath?)`
|
|
75
|
+
|
|
76
|
+
Initializes the UESP math engine. **Must be called once** before `calculateBuild()`.
|
|
77
|
+
|
|
78
|
+
Safe to call multiple times — only executes on the first call.
|
|
79
|
+
|
|
80
|
+
| Param | Type | Default | Description |
|
|
81
|
+
|---|---|---|---|
|
|
82
|
+
| `resourcesPath` | `string` | bundled vendor | Path to `esoEditBuild.js` and `esobuilddata.js` |
|
|
83
|
+
| `initDataPath` | `string` | bundled vendor | Path to `uesp-init-data.json` with game formulas |
|
|
84
|
+
|
|
85
|
+
### `calculateBuild(input: BuildInput): ComputedStats`
|
|
86
|
+
|
|
87
|
+
Runs the UESP engine and returns the computed stats.
|
|
88
|
+
|
|
89
|
+
#### `BuildInput`
|
|
90
|
+
|
|
91
|
+
```ts
|
|
92
|
+
interface BuildInput {
|
|
93
|
+
character: {
|
|
94
|
+
race: string; // "High Elf" | "Nord" | "Breton" | "Khajiit" | ...
|
|
95
|
+
class: string; // "Sorcerer" | "Dragonknight" | "Nightblade" | ...
|
|
96
|
+
level: number; // 1–50
|
|
97
|
+
attributes: {
|
|
98
|
+
health: number; // attribute points (max 64 total)
|
|
99
|
+
magicka: number;
|
|
100
|
+
stamina: number;
|
|
101
|
+
};
|
|
102
|
+
mundusStone?: string; // "The Thief" | "The Apprentice" | ...
|
|
103
|
+
cyrodiil?: boolean; // Battle Spirit (PvP)
|
|
104
|
+
vampireStage?: number; // 0–4
|
|
105
|
+
werewolfStage?: number; // 0 or 1
|
|
106
|
+
championPoints?: number; // 0–3600
|
|
107
|
+
rulesVersion?: string; // "Live" (default) | "PTS"
|
|
108
|
+
};
|
|
109
|
+
items?: Partial<Record<EquipSlot, UespItemApiData>>;
|
|
110
|
+
}
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
#### `EquipSlot`
|
|
114
|
+
|
|
115
|
+
```
|
|
116
|
+
Head | Shoulders | Chest | Hands | Legs | Waist | Feet |
|
|
117
|
+
Neck | Ring1 | Ring2 |
|
|
118
|
+
MainHand1 | OffHand1 | MainHand2 | OffHand2 |
|
|
119
|
+
Poison1 | Poison2 | Food | Potion
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
#### `ComputedStats`
|
|
123
|
+
|
|
124
|
+
Key stats returned (see [`types.ts`](src/lib/eso-engine/types.ts) for full list):
|
|
125
|
+
|
|
126
|
+
| Property | Description |
|
|
127
|
+
|---|---|
|
|
128
|
+
| `Health` / `Magicka` / `Stamina` | Maximum resource pools |
|
|
129
|
+
| `HealthRegen` / `MagickaRegen` / `StaminaRegen` | Out-of-combat regeneration |
|
|
130
|
+
| `WeaponDamage` / `SpellDamage` | Base damage |
|
|
131
|
+
| `WeaponCrit` / `SpellCrit` | Critical chance |
|
|
132
|
+
| `PhysicalResist` / `SpellResist` / `CritResist` | Resistances |
|
|
133
|
+
| `PhysicalPenetration` / `SpellPenetration` | Armor penetration |
|
|
134
|
+
| `DefensePhysicalMitigation` / `DefenseSpellMitigation` | Effective mitigation % |
|
|
135
|
+
| `HealingDone` / `HealingTaken` | Healing modifiers |
|
|
136
|
+
| `RunSpeed` / `SprintSpeed` | Movement speed |
|
|
137
|
+
| `raw` | All 221 stats as `Record<string, number>` |
|
|
138
|
+
|
|
139
|
+
> All stat IDs match `g_EsoComputedStats` from the UESP engine (version 49+).
|
|
140
|
+
|
|
141
|
+
## Updating Formulas After a New ESO Patch
|
|
142
|
+
|
|
143
|
+
When ZeniMax releases a new patch or DLC, the formulas may change. To update:
|
|
144
|
+
|
|
145
|
+
```bash
|
|
146
|
+
# 1. Update the UESP submodule
|
|
147
|
+
cd vendor/uesp-esochardata
|
|
148
|
+
git fetch upstream && git merge upstream/master
|
|
149
|
+
cd ../..
|
|
150
|
+
|
|
151
|
+
# 2. Re-extract the formulas from the UESP website
|
|
152
|
+
# Open https://esobuilds.uesp.net in a browser
|
|
153
|
+
# Run vendor/uesp-data/browser-extract.js in DevTools Console
|
|
154
|
+
# Save the result to vendor/uesp-data/uesp-init-data.json
|
|
155
|
+
|
|
156
|
+
# 3. Run tests to verify
|
|
157
|
+
npm test
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
## License
|
|
161
|
+
|
|
162
|
+
MIT © srtomy
|
|
163
|
+
|
|
164
|
+
This package bundles files from [uesp/uesp-esochardata](https://github.com/uesp/uesp-esochardata) (MIT).
|
|
165
|
+
See [THIRD_PARTY_NOTICES](THIRD_PARTY_NOTICES) for details.
|
|
166
|
+
|
|
167
|
+
Elder Scrolls Online is a trademark of ZeniMax Media Inc. This project is not affiliated with or endorsed by ZeniMax Media Inc.
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
Third-Party Notices
|
|
2
|
+
===================
|
|
3
|
+
|
|
4
|
+
This package bundles portions of the following open-source project:
|
|
5
|
+
|
|
6
|
+
--------------------------------------------------------------------------------
|
|
7
|
+
uesp/uesp-esochardata
|
|
8
|
+
https://github.com/uesp/uesp-esochardata
|
|
9
|
+
|
|
10
|
+
MIT License
|
|
11
|
+
|
|
12
|
+
Copyright (c) UESP (Unofficial Elder Scrolls Pages)
|
|
13
|
+
|
|
14
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
15
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
16
|
+
in the Software without restriction, including without limitation the rights
|
|
17
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
18
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
19
|
+
furnished to do so, subject to the following conditions:
|
|
20
|
+
|
|
21
|
+
The above copyright notice and this permission notice shall be included in all
|
|
22
|
+
copies or substantial portions of the Software.
|
|
23
|
+
|
|
24
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
25
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
26
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
27
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
28
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
29
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
30
|
+
SOFTWARE.
|
|
31
|
+
--------------------------------------------------------------------------------
|
|
32
|
+
|
|
33
|
+
Bundled files from uesp/uesp-esochardata:
|
|
34
|
+
- vendor/uesp-esochardata/resources/esoEditBuild.js
|
|
35
|
+
- vendor/uesp-esochardata/resources/esobuilddata.js
|
|
36
|
+
- vendor/uesp-data/uesp-init-data.json (formulas extracted from the UESP website)
|
|
37
|
+
|
|
38
|
+
Elder Scrolls Online is a trademark of ZeniMax Media Inc. This project is not
|
|
39
|
+
affiliated with or endorsed by ZeniMax Media Inc. or Bethesda Softworks.
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Motor de cálculo de builds do ESO.
|
|
3
|
+
*
|
|
4
|
+
* Implementa a ideia central da arquitetura:
|
|
5
|
+
*
|
|
6
|
+
* 1. Injetar dados do personagem nos elementos mock do DOM
|
|
7
|
+
* (jQuery vai ler via $("#esotbRace").val(), etc.)
|
|
8
|
+
*
|
|
9
|
+
* 2. Injetar dados dos itens DIRETAMENTE em g_EsoBuildItemData[slot]
|
|
10
|
+
* — sem precisar mockar jQuery para cada campo de item.
|
|
11
|
+
* Os campos vêm exatamente no formato da API pública da UESP:
|
|
12
|
+
* GET https://esolog.uesp.net/exportJson.php?table=minedItem&id=<id>&level=<lv>&quality=<q>
|
|
13
|
+
*
|
|
14
|
+
* 3. Chamar UpdateEsoComputedStatsList_Real(null, true)
|
|
15
|
+
* — o parâmetro `noUpdate=true` faz o motor calcular tudo mas pular
|
|
16
|
+
* as atualizações de DOM (DisplayEsoAllComputedStats, UpdateReadOnlyStats, etc.)
|
|
17
|
+
*
|
|
18
|
+
* 4. Ler os resultados de g_EsoComputedStats[statId].value
|
|
19
|
+
*/
|
|
20
|
+
import type { BuildInput, ComputedStats } from './types';
|
|
21
|
+
/**
|
|
22
|
+
* Calcula os Computed Character Statistics para a build fornecida.
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* ```ts
|
|
26
|
+
* import { calculateBuild } from './src/lib/eso-engine';
|
|
27
|
+
*
|
|
28
|
+
* const stats = calculateBuild({
|
|
29
|
+
* character: { race: 'High Elf', class: 'Sorcerer', level: 50,
|
|
30
|
+
* attributes: { health: 0, magicka: 64, stamina: 0 } },
|
|
31
|
+
* items: {
|
|
32
|
+
* Chest: chestItemFromUespApi, // objeto retornado por esolog.uesp.net/exportJson.php
|
|
33
|
+
* },
|
|
34
|
+
* });
|
|
35
|
+
* console.log(stats.MaxMagicka, stats.SpellDamage);
|
|
36
|
+
* ```
|
|
37
|
+
*/
|
|
38
|
+
export declare function calculateBuild(input: BuildInput): ComputedStats;
|
|
39
|
+
//# sourceMappingURL=calculator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"calculator.d.ts","sourceRoot":"","sources":["../../../src/lib/eso-engine/calculator.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAGH,OAAO,KAAK,EAAE,UAAU,EAAE,aAAa,EAAa,MAAM,SAAS,CAAC;AAuBpE;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,UAAU,GAAG,aAAa,CAyJ/D"}
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Motor de cálculo de builds do ESO.
|
|
4
|
+
*
|
|
5
|
+
* Implementa a ideia central da arquitetura:
|
|
6
|
+
*
|
|
7
|
+
* 1. Injetar dados do personagem nos elementos mock do DOM
|
|
8
|
+
* (jQuery vai ler via $("#esotbRace").val(), etc.)
|
|
9
|
+
*
|
|
10
|
+
* 2. Injetar dados dos itens DIRETAMENTE em g_EsoBuildItemData[slot]
|
|
11
|
+
* — sem precisar mockar jQuery para cada campo de item.
|
|
12
|
+
* Os campos vêm exatamente no formato da API pública da UESP:
|
|
13
|
+
* GET https://esolog.uesp.net/exportJson.php?table=minedItem&id=<id>&level=<lv>&quality=<q>
|
|
14
|
+
*
|
|
15
|
+
* 3. Chamar UpdateEsoComputedStatsList_Real(null, true)
|
|
16
|
+
* — o parâmetro `noUpdate=true` faz o motor calcular tudo mas pular
|
|
17
|
+
* as atualizações de DOM (DisplayEsoAllComputedStats, UpdateReadOnlyStats, etc.)
|
|
18
|
+
*
|
|
19
|
+
* 4. Ler os resultados de g_EsoComputedStats[statId].value
|
|
20
|
+
*/
|
|
21
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
22
|
+
exports.calculateBuild = calculateBuild;
|
|
23
|
+
const env_setup_1 = require("./env-setup");
|
|
24
|
+
const ALL_SLOTS = [
|
|
25
|
+
'Head', 'Shoulders', 'Chest', 'Hands', 'Legs', 'Waist', 'Feet',
|
|
26
|
+
'Neck', 'Ring1', 'Ring2',
|
|
27
|
+
'MainHand1', 'OffHand1', 'MainHand2', 'OffHand2',
|
|
28
|
+
'Poison1', 'Poison2', 'Food', 'Potion',
|
|
29
|
+
];
|
|
30
|
+
/**
|
|
31
|
+
* Normaliza os dados de um item garantindo que todos os campos opcionais
|
|
32
|
+
* existam com defaults seguros. Sem isso, o motor lança TypeError ao tentar
|
|
33
|
+
* chamar .includes() em campos de set bonus undefined (setBonusDesc5..12).
|
|
34
|
+
*/
|
|
35
|
+
function normalizeItemData(item) {
|
|
36
|
+
const defaults = {};
|
|
37
|
+
for (let i = 1; i <= 12; i++) {
|
|
38
|
+
defaults[`setBonusCount${i}`] = item[`setBonusCount${i}`] ?? '-1';
|
|
39
|
+
defaults[`setBonusDesc${i}`] = item[`setBonusDesc${i}`] ?? '';
|
|
40
|
+
}
|
|
41
|
+
return { ...defaults, ...item };
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Calcula os Computed Character Statistics para a build fornecida.
|
|
45
|
+
*
|
|
46
|
+
* @example
|
|
47
|
+
* ```ts
|
|
48
|
+
* import { calculateBuild } from './src/lib/eso-engine';
|
|
49
|
+
*
|
|
50
|
+
* const stats = calculateBuild({
|
|
51
|
+
* character: { race: 'High Elf', class: 'Sorcerer', level: 50,
|
|
52
|
+
* attributes: { health: 0, magicka: 64, stamina: 0 } },
|
|
53
|
+
* items: {
|
|
54
|
+
* Chest: chestItemFromUespApi, // objeto retornado por esolog.uesp.net/exportJson.php
|
|
55
|
+
* },
|
|
56
|
+
* });
|
|
57
|
+
* console.log(stats.MaxMagicka, stats.SpellDamage);
|
|
58
|
+
* ```
|
|
59
|
+
*/
|
|
60
|
+
function calculateBuild(input) {
|
|
61
|
+
// -------------------------------------------------------------------------
|
|
62
|
+
// PASSO 1: Injeta stats do personagem nos elementos mock do DOM.
|
|
63
|
+
// O motor lê esses valores via jQuery: $("#esotbRace").val(), etc.
|
|
64
|
+
// -------------------------------------------------------------------------
|
|
65
|
+
(0, env_setup_1.resetDomValues)();
|
|
66
|
+
const { character, items } = input;
|
|
67
|
+
(0, env_setup_1.setDomValue)('esotbRace', character.race);
|
|
68
|
+
(0, env_setup_1.setDomValue)('esotbClass', character.class);
|
|
69
|
+
(0, env_setup_1.setDomValue)('esotbLevel', String(Math.min(character.level, 50)));
|
|
70
|
+
(0, env_setup_1.setDomValue)('esotbAttrHea', String(character.attributes.health ?? 0));
|
|
71
|
+
(0, env_setup_1.setDomValue)('esotbAttrMag', String(character.attributes.magicka ?? 0));
|
|
72
|
+
(0, env_setup_1.setDomValue)('esotbAttrSta', String(character.attributes.stamina ?? 0));
|
|
73
|
+
// Mundus Stone (pedra de Mundus)
|
|
74
|
+
if (character.mundusStone) {
|
|
75
|
+
(0, env_setup_1.setDomValue)('esotbMundus', character.mundusStone);
|
|
76
|
+
}
|
|
77
|
+
// PvP Cyrodiil (Battle Spirit)
|
|
78
|
+
if (character.cyrodiil) {
|
|
79
|
+
(0, env_setup_1.setDomValue)('esotbCyrodiil', 'true'); // prop("checked") retorna true quando valor é "true"
|
|
80
|
+
}
|
|
81
|
+
// Vampiro / Lobisomem
|
|
82
|
+
if (character.vampireStage != null)
|
|
83
|
+
(0, env_setup_1.setDomValue)('esotbVampireStage', String(character.vampireStage));
|
|
84
|
+
if (character.werewolfStage != null)
|
|
85
|
+
(0, env_setup_1.setDomValue)('esotbWerewolfStage', String(character.werewolfStage));
|
|
86
|
+
// Champion Points
|
|
87
|
+
if (character.championPoints != null) {
|
|
88
|
+
(0, env_setup_1.setDomValue)('esotbCPTotalPoints', String(character.championPoints));
|
|
89
|
+
}
|
|
90
|
+
// Versão das regras (padrão: Live)
|
|
91
|
+
(0, env_setup_1.setDomValue)('esotbRulesVersion', character.rulesVersion ?? 'Live');
|
|
92
|
+
// Campos obrigatórios com defaults seguros
|
|
93
|
+
(0, env_setup_1.setDomValue)('esotbMountSpeedBonus', '0');
|
|
94
|
+
(0, env_setup_1.setDomValue)('esotbBaseWalkSpeed', '3.0');
|
|
95
|
+
(0, env_setup_1.setDomValue)('esotbBuildDescription', '');
|
|
96
|
+
(0, env_setup_1.setDomValue)('esotbUsePtsRules', 'false');
|
|
97
|
+
(0, env_setup_1.setDomValue)('esotbEnableRaceAutoPurchase', 'false');
|
|
98
|
+
(0, env_setup_1.setDomValue)('esotbTargetResistance', '0');
|
|
99
|
+
// -------------------------------------------------------------------------
|
|
100
|
+
// PASSO 2: Injeta dados de itens DIRETAMENTE em g_EsoBuildItemData[slot].
|
|
101
|
+
//
|
|
102
|
+
// Esta é a ideia central: em vez de mockar jQuery para cada campo de item,
|
|
103
|
+
// populamos a variável global que o motor lê nativamente.
|
|
104
|
+
// Os dados vêm exatamente no formato da API pública da UESP — sem adaptação.
|
|
105
|
+
// -------------------------------------------------------------------------
|
|
106
|
+
const itemData = global.g_EsoBuildItemData;
|
|
107
|
+
const enchantData = global.g_EsoBuildEnchantData;
|
|
108
|
+
// Reseta todos os slots (evita dados de chamada anterior)
|
|
109
|
+
for (const slot of ALL_SLOTS) {
|
|
110
|
+
itemData[slot] = {};
|
|
111
|
+
if (enchantData)
|
|
112
|
+
enchantData[slot] = {};
|
|
113
|
+
}
|
|
114
|
+
// Injeta os itens fornecidos (normalizados com defaults seguros)
|
|
115
|
+
if (items) {
|
|
116
|
+
for (const [slot, item] of Object.entries(items)) {
|
|
117
|
+
if (item && item.itemId) {
|
|
118
|
+
itemData[slot] = normalizeItemData(item);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
// -------------------------------------------------------------------------
|
|
123
|
+
// PASSO 3: Executa o cálculo.
|
|
124
|
+
//
|
|
125
|
+
// UpdateEsoComputedStatsList_Real(keepSaveResults, noUpdate)
|
|
126
|
+
// - keepSaveResults = null → reseta os resultados salvos (comportamento padrão)
|
|
127
|
+
// - noUpdate = true → pula DisplayEsoAllComputedStats e UpdateReadOnlyStats
|
|
128
|
+
// (operações de DOM que não precisamos)
|
|
129
|
+
// -------------------------------------------------------------------------
|
|
130
|
+
const updateFn = global.UpdateEsoComputedStatsList_Real;
|
|
131
|
+
if (typeof updateFn !== 'function') {
|
|
132
|
+
throw new Error('[eso-engine] UpdateEsoComputedStatsList_Real não está disponível. ' +
|
|
133
|
+
'Certifique-se de chamar initEsoEngine() antes de calculateBuild().');
|
|
134
|
+
}
|
|
135
|
+
updateFn(null, true);
|
|
136
|
+
// -------------------------------------------------------------------------
|
|
137
|
+
// PASSO 4: Lê os resultados de g_EsoComputedStats[statId].value
|
|
138
|
+
// -------------------------------------------------------------------------
|
|
139
|
+
const computedStats = global.g_EsoComputedStats ?? {};
|
|
140
|
+
const raw = {};
|
|
141
|
+
for (const statId of Object.keys(computedStats)) {
|
|
142
|
+
const stat = computedStats[statId];
|
|
143
|
+
if (stat && typeof stat === 'object' && typeof stat.value === 'number') {
|
|
144
|
+
raw[statId] = stat.value;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
return {
|
|
148
|
+
// Atributos máximos
|
|
149
|
+
Health: raw['Health'] ?? 0,
|
|
150
|
+
Magicka: raw['Magicka'] ?? 0,
|
|
151
|
+
Stamina: raw['Stamina'] ?? 0,
|
|
152
|
+
// Regeneração
|
|
153
|
+
HealthRegen: raw['HealthRegen'] ?? 0,
|
|
154
|
+
MagickaRegen: raw['MagickaRegen'] ?? 0,
|
|
155
|
+
StaminaRegen: raw['StaminaRegen'] ?? 0,
|
|
156
|
+
// Dano
|
|
157
|
+
WeaponDamage: raw['WeaponDamage'] ?? 0,
|
|
158
|
+
SpellDamage: raw['SpellDamage'] ?? 0,
|
|
159
|
+
// Crítico
|
|
160
|
+
WeaponCrit: raw['WeaponCrit'] ?? 0,
|
|
161
|
+
SpellCrit: raw['SpellCrit'] ?? 0,
|
|
162
|
+
SpellCritDamage: raw['SpellCritDamage'] ?? 0,
|
|
163
|
+
WeaponCritDamage: raw['WeaponCritDamage'] ?? 0,
|
|
164
|
+
// Resistências
|
|
165
|
+
PhysicalResist: raw['PhysicalResist'] ?? 0,
|
|
166
|
+
SpellResist: raw['SpellResist'] ?? 0,
|
|
167
|
+
CritResist: raw['CritResist'] ?? 0,
|
|
168
|
+
// Penetração
|
|
169
|
+
PhysicalPenetration: raw['PhysicalPenetration'] ?? 0,
|
|
170
|
+
SpellPenetration: raw['SpellPenetration'] ?? 0,
|
|
171
|
+
// Poder efetivo
|
|
172
|
+
EffectiveSpellPower: raw['EffectiveSpellPower'] ?? 0,
|
|
173
|
+
EffectiveWeaponPower: raw['EffectiveWeaponPower'] ?? 0,
|
|
174
|
+
EffectivePower: raw['EffectivePower'] ?? 0,
|
|
175
|
+
// Cura
|
|
176
|
+
HealingDone: raw['HealingDone'] ?? 0,
|
|
177
|
+
HealingTaken: raw['HealingTaken'] ?? 0,
|
|
178
|
+
// Velocidade
|
|
179
|
+
RunSpeed: raw['RunSpeed'] ?? 0,
|
|
180
|
+
SprintSpeed: raw['SprintSpeed'] ?? 0,
|
|
181
|
+
// Mitigação
|
|
182
|
+
AttackSpellMitigation: raw['AttackSpellMitigation'] ?? 0,
|
|
183
|
+
AttackPhysicalMitigation: raw['AttackPhysicalMitigation'] ?? 0,
|
|
184
|
+
DefenseSpellMitigation: raw['DefenseSpellMitigation'] ?? 0,
|
|
185
|
+
DefensePhysicalMitigation: raw['DefensePhysicalMitigation'] ?? 0,
|
|
186
|
+
raw,
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
//# sourceMappingURL=calculator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"calculator.js","sourceRoot":"","sources":["../../../src/lib/eso-engine/calculator.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Configura o ambiente global do Node.js para simular o browser.
|
|
3
|
+
*
|
|
4
|
+
* O motor da UESP (esoEditBuild.js) foi escrito para rodar no browser e usa:
|
|
5
|
+
* - window.* — para variáveis e funções globais
|
|
6
|
+
* - document.getElementById / $ — para ler/escrever valores do DOM
|
|
7
|
+
* - navigator — verificação de agente
|
|
8
|
+
*
|
|
9
|
+
* Esta camada cria mocks controlados desses objetos ANTES de carregar
|
|
10
|
+
* o script da UESP, de forma que:
|
|
11
|
+
* 1. O script inicia sem erros (jQuery mock chainável)
|
|
12
|
+
* 2. Nosso código pode injetar valores de entrada (race, class, level, etc.)
|
|
13
|
+
* via setDomValue() antes de chamar o cálculo
|
|
14
|
+
* 3. O motor lê esses valores normalmente via $("#elementId").val()
|
|
15
|
+
*/
|
|
16
|
+
/** Armazena os valores que o jQuery vai "ler" como se fossem campos HTML */
|
|
17
|
+
export declare const domValueStore: Map<string, string>;
|
|
18
|
+
/** Define o valor de um elemento mock (equivale a preencher um campo HTML) */
|
|
19
|
+
export declare function setDomValue(id: string, value: string): void;
|
|
20
|
+
/** Lê o valor de um elemento mock */
|
|
21
|
+
export declare function getDomValue(id: string): string;
|
|
22
|
+
/** Reseta todos os valores do DOM mock */
|
|
23
|
+
export declare function resetDomValues(): void;
|
|
24
|
+
export declare function setupNodeEnvironment(): void;
|
|
25
|
+
//# sourceMappingURL=env-setup.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"env-setup.d.ts","sourceRoot":"","sources":["../../../src/lib/eso-engine/env-setup.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,4EAA4E;AAC5E,eAAO,MAAM,aAAa,qBAA4B,CAAC;AAEvD,8EAA8E;AAC9E,wBAAgB,WAAW,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAE3D;AAED,qCAAqC;AACrC,wBAAgB,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAE9C;AAED,0CAA0C;AAC1C,wBAAgB,cAAc,IAAI,IAAI,CAErC;AA8JD,wBAAgB,oBAAoB,IAAI,IAAI,CA2C3C"}
|