@eveshipfit/dogma-engine 13.0.0 → 13.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/README.md +26 -333
- package/esf_dogma_engine.d.ts +120 -0
- package/esf_dogma_engine.js +58 -0
- package/esf_dogma_engine_bg.wasm +0 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,11 +1,6 @@
|
|
|
1
|
-
# EVEShip.fit's Dogma Engine
|
|
1
|
+
# EVEShip.fit's Dogma Engine for Javascript
|
|
2
2
|
|
|
3
|
-
[](https://crates.io/crates/esf-dogma-engine)
|
|
4
3
|
[](https://www.npmjs.com/package/@eveshipfit/dogma-engine)
|
|
5
|
-
[](https://pypi.org/project/eveshipfit-dogma-engine/)
|
|
6
|
-
[](https://github.com/EVEShipFit/dogma-engine/actions/workflows/testing.yml)
|
|
7
|
-
[](https://docs.rs/esf-dogma-engine)
|
|
8
|
-
|
|
9
4
|
[](https://discord.gg/S5V5BkvNf7)
|
|
10
5
|
|
|
11
6
|
This library calculates accurately statistics of an EVE Online ship fit.
|
|
@@ -13,211 +8,32 @@ This library calculates accurately statistics of an EVE Online ship fit.
|
|
|
13
8
|
The input are several data-files provided by EVE Online, together with a ship fit.
|
|
14
9
|
The output are all the Dogma attributes of the ship, its items and the character.
|
|
15
10
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
This Dogma engine implements a multi-pass approach.
|
|
19
|
-
|
|
20
|
-
- [pass 1](./crates/esf-dogma-engine/src/calculate/pass_1.rs): collect all the Dogma attributes of the hull and modules.
|
|
21
|
-
- [pass 2](./crates/esf-dogma-engine/src/calculate/pass_2.rs): collect all the Dogma effects of the hull and modules.
|
|
22
|
-
- [pass 3](./crates/esf-dogma-engine/src/calculate/pass_3.rs): apply all the Dogma effects to the hull/modules, calculating the actual Dogma attribute values.
|
|
23
|
-
- [pass 4](./crates/esf-dogma-engine/src/calculate/pass_4.rs): augment the Dogma attributes with EVEShip.fit specific attributes, that are too complex for the Dogma itself to handle.
|
|
24
|
-
|
|
25
|
-
## Input and output
|
|
26
|
-
|
|
27
|
-
`calculate` takes a fit and options, and returns a calculation.
|
|
28
|
-
All identifiers are those from the SDE.
|
|
29
|
-
|
|
30
|
-
### Fit
|
|
31
|
-
|
|
32
|
-
- `name` (optional): name of the fit.
|
|
33
|
-
- `ship`: the ship being fitted.
|
|
34
|
-
- `type_id`: its type.
|
|
35
|
-
- `mode` (optional): type ID of the active mode, for ships that have modes.
|
|
36
|
-
_Whether the mode belongs to the ship is not checked._
|
|
37
|
-
- `items`: everything fitted or carried. Each item has:
|
|
38
|
-
- `type_id`: its type.
|
|
39
|
-
- `slot`: where the item is.
|
|
40
|
-
- `type`: `high`, `medium`, `low`, `rig`, `subsystem`, `service`, `fighter_tube`, `fighter_bay`, `implant`, `booster`, `drone_bay` or `cargo`.
|
|
41
|
-
- `index`: position within that slot type, starting at 0 (`implant` and `booster` starting at 1).
|
|
42
|
-
Absent for `fighter_bay`, `drone_bay` and `cargo`.
|
|
43
|
-
- `quantity` (optional, default 1): stack size for drones, fighters and cargo. For fighters in a tube, the squadron size.
|
|
44
|
-
- `state`: requested state; `offline`, `online`, `active` or `overload`.
|
|
45
|
-
- `charge` (optional): the loaded charge, as `type_id`.
|
|
46
|
-
- `mutation` (optional): for mutated items (Abyssal modules, mutated drones, ...).
|
|
47
|
-
- `base`: type ID of the item before it was mutated.
|
|
48
|
-
- `attributes`: the rolled value per attribute ID.
|
|
49
|
-
- `fighter_abilities` (optional): the abilities a fighter uses, as effect IDs. Absent means the fighter's default abilities.
|
|
50
|
-
- `booster_side_effects` (optional): the side effects a booster rolled, as effect IDs. Absent means none.
|
|
51
|
-
- `spool` (optional): for modules whose bonus grows every cycle, how far it has spooled.
|
|
52
|
-
Only per-second stats use it; volley is always unspooled. Absent means fully spooled.
|
|
53
|
-
- `multiplier_bonus`: the bonus reached so far; 0.0 is unspooled, 2.125 is +212.5%.
|
|
54
|
-
- `character` (optional):
|
|
55
|
-
- `skills`: level (0 to 5) per skill type ID. A missing skill gives no bonuses.
|
|
56
|
-
- `security_status` (optional, default 0.0): the pilot's security status, -10.0 to 5.0.
|
|
57
|
-
- `environment` (optional): where the fit is.
|
|
58
|
-
- `damage_profile` (optional, default 0.25 each): incoming damage for effective hitpoints, as `em`, `explosive`, `kinetic` and `thermal` (relative to each other).
|
|
59
|
-
- `security` (optional, default `high_sec`): `high_sec`, `low_sec`, `null_sec` or `wormhole`.
|
|
60
|
-
- `reactive_armor` (optional, default `do_not_adapt`): what a Reactive Armor Hardener shifts its resistances towards.
|
|
61
|
-
`do_not_adapt` leaves them where EVE shows them, `damage_profile` shifts towards `damage_profile`, and
|
|
62
|
-
`{"profile": {..}}` shifts towards a profile of its own, written the same way as `damage_profile`.
|
|
63
|
-
- `incoming` (optional): what effects and buffs to apply that come from outside the ship.
|
|
64
|
-
A calculation reports the same shape as `outgoing`: feed one fit's result into another's `incoming` links them up.
|
|
65
|
-
- `buffs` (optional, default none): buffs to apply, like the ones a command burst hands out.
|
|
66
|
-
- `id`: which buff, as `dbuffCollections` in the SDE numbers them.
|
|
67
|
-
- `value`: how strong it is, in whatever the buff's operation reads.
|
|
68
|
-
- `effects` (optional, default none): effects aimed at the fit, like a stasis webifier.
|
|
69
|
-
- `type_id`: the type the effect belongs to; its category decides the stacking penalty.
|
|
70
|
-
- `effect_id`: which effect, as `dogmaEffects` in the SDE numbers them.
|
|
71
|
-
- `attributes`: the value per attribute ID the effect reads, worked out by the fit that aimed it.
|
|
72
|
-
|
|
73
|
-
### Options
|
|
74
|
-
|
|
75
|
-
- `sources` (optional, default false): report per attribute what its value was calculated from.
|
|
76
|
-
Leave it off unless you show it; it makes the calculation several times bigger.
|
|
77
|
-
- `validate` (optional, default false): also report the fitting rules the fit breaks, as `violations`.
|
|
78
|
-
|
|
79
|
-
### Calculation
|
|
80
|
-
|
|
81
|
-
- `ship`: result for the ship.
|
|
82
|
-
- `mode`: result for the mode; absent when the fit has no mode.
|
|
83
|
-
- `items`: one result per item of the fit, in the same order.
|
|
84
|
-
- `character`: result for the character.
|
|
85
|
-
- `buffs`: the buffs that landed, ordered by id. Those of `incoming`, plus the ones the fit's own bursts hand out: a fleet boost reaches the ship running it. What is missing lost to another source of the same buff, or the SDE has no such buff.
|
|
86
|
-
- `id`: which buff, as `dbuffCollections` in the SDE numbers them.
|
|
87
|
-
- `value`: how strong it is, in whatever the buff's operation reads.
|
|
88
|
-
- `outgoing`: what the fit hands to other fits, in the shape `incoming` takes.
|
|
89
|
-
- `violations`: the fitting rules the fit breaks; only with the `validate` option.
|
|
90
|
-
Absent means they were not looked for, an empty list means none were broken.
|
|
91
|
-
|
|
92
|
-
Each result has:
|
|
93
|
-
|
|
94
|
-
- `attributes`: per attribute ID, its `base` value before effects and its final `value`.
|
|
95
|
-
With the `sources` option, also `sources`: every modifier on it, in the order they were applied. Each has:
|
|
96
|
-
- `from`: where it comes from; `type` is `ship`, `mode`, `character`, `item` or `charge` (with the `index` into `items`), `projected` (with the `index` into `incoming.effects`), `skill` (with its `type_id`) or `buff` (with its `id`).
|
|
97
|
-
- `effect_id`: the effect that holds the modifier; `null` for a buff, which has none.
|
|
98
|
-
- `source_attribute_id`: the attribute on the source that holds `value`; `null` for a buff, which carries its own strength.
|
|
99
|
-
- `operator`: `pre_assign`, `pre_mul`, `pre_div`, `mod_add`, `mod_sub`, `post_mul`, `post_div`, `post_percent` or `post_assign`.
|
|
100
|
-
- `value`: the value of the modifying attribute, or the strength of the buff.
|
|
101
|
-
- `quantity`: how many times it counts. A stacking penalised stack is listed once per item instead.
|
|
102
|
-
- `penalty`: the stacking penalty factor it got, or `null` if not penalised.
|
|
103
|
-
- `applied`: false when the source's state is too low for the effect.
|
|
104
|
-
|
|
105
|
-
How much each source added is not reported: multiplications compound and stacking penalties depend on order, so there is no single answer.
|
|
106
|
-
- `state`: the state the item reached, which can be lower than requested.
|
|
107
|
-
- `max_state`: the highest state the item can reach.
|
|
108
|
-
- `charge`: result for its charge, if it has one.
|
|
109
|
-
|
|
110
|
-
## EVEShip.fit's specific attributes
|
|
111
|
-
|
|
112
|
-
`Pass 4` create Dogma attributes that do not exist in-game, but are rather complicated to calculate.
|
|
113
|
-
To make rendering a fit easier, these are calculated by this library, and presented as new Dogma attributes.
|
|
114
|
-
|
|
115
|
-
Their identifier is always a negative value, to visually separate them.
|
|
116
|
-
What additional attributes exist are defined in [EVEShipFit/sde-patched](https://github.com/EVEShipFit/sde-patched) repository.
|
|
117
|
-
|
|
118
|
-
## Validation
|
|
119
|
-
|
|
120
|
-
The `validate` option checks if the fit violates any rules that would prevent you from flying it in-game.
|
|
121
|
-
The calculation then carries `violations`, grouped by the kind of rule and, within a kind, in the order of `items`.
|
|
122
|
-
An empty list means the fit breaks no rules; absent means the option was off.
|
|
123
|
-
|
|
124
|
-
Every rule reads the values after skills and modules changed them, so validation is part of `calculate()`
|
|
125
|
-
rather than a call of its own; asking for both costs one calculation, not two.
|
|
126
|
-
|
|
127
|
-
Each violation has:
|
|
128
|
-
|
|
129
|
-
- `target`: what the rule is about.
|
|
130
|
-
- `ship`, for what the ship carries as a whole.
|
|
131
|
-
- `item`, with the `index` into `items`.
|
|
132
|
-
- `charge`, with the `index` into `items` of the item holding it.
|
|
133
|
-
- `rule`: the rule, and the values that failed it. `type` says which:
|
|
134
|
-
- `resource`: `resource` ran out, `used` of `available`.
|
|
135
|
-
One of `cpu`, `powergrid`, `calibration`, `drone_bay`, `drone_bandwidth`, `launched_drones`, `fighter_bay`, `fighter_tubes`, `light_fighter_tubes`, `support_fighter_tubes`, `heavy_fighter_tubes`, `cargo_bay` or `charge_capacity`.
|
|
136
|
-
- `slots`: more items in the `slot` rack than the ship has, `used` of `available`.
|
|
137
|
-
One of `high`, `medium`, `low`, `rig`, `subsystem`, `service`, `turret` or `launcher`; the last two are hardpoints a weapon takes on top of its slot.
|
|
138
|
-
- `wrong_slot`: the item belongs in the `expected` rack.
|
|
139
|
-
- `slot_taken`: another item of the fit is in this slot too.
|
|
140
|
-
- `wrong_slot_index`: an implant or booster outside the slot it occupies, which is `expected`.
|
|
141
|
-
- `subsystem_taken`: another subsystem covers the same part of the ship.
|
|
142
|
-
- `skill`: the character is missing `type_id`, or has it at `level` where the item asks for `required`.
|
|
143
|
-
- `rig_size`: a rig of size `item` where the `ship` takes another.
|
|
144
|
-
- `ship_restricted`: the item cannot go on this ship at all.
|
|
145
|
-
- `capital_item`: a capital item on a ship that is not a capital.
|
|
146
|
-
- `max_group`: `used` of `group_id` are `limit` (`fitted`, `online` or `active`), where `allowed` may be.
|
|
147
|
-
This is what keeps a second propulsion module from running: an afterburner and a microwarpdrive share a group.
|
|
148
|
-
- `max_type`: `used` of `type_id` are fitted, where `allowed` may be.
|
|
149
|
-
- `charge_group`: a charge of a group the module does not take.
|
|
150
|
-
- `charge_size`: a charge of size `charge` where the `module` takes another.
|
|
151
|
-
|
|
152
|
-
## Usage
|
|
153
|
-
|
|
154
|
-
The engine is published for Rust, Javascript and Python; all three calculate the same way.
|
|
155
|
-
Each hands over `sde.dat` once, and every lookup after that happens inside Rust.
|
|
156
|
-
An EFT import matches the English names in `sde.dat`; hand over `names.dat` too to also match the other languages EVE supports.
|
|
157
|
-
|
|
158
|
-
How each package is built is explained under [Integration](#integration).
|
|
11
|
+
The engine is written in Rust and runs as WebAssembly, so everything is calculated in the browser; no server needed.
|
|
159
12
|
|
|
160
|
-
|
|
13
|
+
## Install
|
|
161
14
|
|
|
162
|
-
|
|
163
|
-
`esf-data` reads `sde.dat`.
|
|
15
|
+
[`@eveshipfit/sde`](https://www.npmjs.com/package/@eveshipfit/sde) ships `sde.dat` in its `dist` folder; serve or bundle that file.
|
|
164
16
|
|
|
165
17
|
```bash
|
|
166
|
-
|
|
167
|
-
```
|
|
168
|
-
|
|
169
|
-
```rust
|
|
170
|
-
use esf_data::{InfoSde, Sde};
|
|
171
|
-
use esf_dogma_engine::{Fit, Options, beacon, calculate};
|
|
172
|
-
|
|
173
|
-
let bytes = std::fs::read("sde.dat")?;
|
|
174
|
-
let sde = Sde::new(&bytes)?;
|
|
175
|
-
let info = InfoSde::new(&sde);
|
|
176
|
-
|
|
177
|
-
let fit: Fit = serde_json::from_str(
|
|
178
|
-
r#"{
|
|
179
|
-
"ship": {"type_id": 587},
|
|
180
|
-
"items": [
|
|
181
|
-
{
|
|
182
|
-
"type_id": 2873,
|
|
183
|
-
"slot": {"type": "high", "index": 0},
|
|
184
|
-
"state": "active",
|
|
185
|
-
"charge": {"type_id": 185}
|
|
186
|
-
}
|
|
187
|
-
],
|
|
188
|
-
"character": {"skills": {"3300": 5}}
|
|
189
|
-
}"#,
|
|
190
|
-
)?;
|
|
191
|
-
|
|
192
|
-
let calculation = calculate(&info, &fit, &Options::default());
|
|
193
|
-
// Or if you want to know the source of the effects:
|
|
194
|
-
let with_sources = calculate(&info, &fit, &Options { sources: true, ..Default::default() });
|
|
195
|
-
// Or if you have a beacon in space (like wormhole effects):
|
|
196
|
-
let with_beacon = calculate(&info, &Fit { incoming: beacon(&info, beacon_type_id), ..fit }, &Options::default());
|
|
197
|
-
|
|
198
|
-
// What EVE would not let you fly, in `violations` of the calculation:
|
|
199
|
-
let validated = calculate(&info, &fit, &Options { validate: true, ..Default::default() });
|
|
18
|
+
npm install @eveshipfit/dogma-engine @eveshipfit/sde
|
|
200
19
|
```
|
|
201
20
|
|
|
202
|
-
### Javascript (WebAssembly)
|
|
203
|
-
|
|
204
|
-
The WebAssembly variant is published on npm as
|
|
205
|
-
[`@eveshipfit/dogma-engine`](https://www.npmjs.com/package/@eveshipfit/dogma-engine).
|
|
206
|
-
[`@eveshipfit/sde`](https://www.npmjs.com/package/@eveshipfit/sde) ships `sde.dat` in its `dist` folder; serve or bundle that file.
|
|
207
|
-
|
|
208
21
|
The package is an ES module with TypeScript types included, and it runs anywhere: under a bundler
|
|
209
22
|
(Vite, webpack, ...), from a CDN, or in a plain `<script type="module">`.
|
|
210
|
-
Its default export loads the WebAssembly and has to be awaited once before any other function is called.
|
|
211
23
|
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
24
|
+
## Usage
|
|
25
|
+
|
|
26
|
+
The default export loads the WebAssembly and has to be awaited once before any other function is called.
|
|
215
27
|
|
|
216
28
|
```js
|
|
217
29
|
import wasmInit, {
|
|
218
30
|
load_sde,
|
|
219
31
|
load_eft,
|
|
220
32
|
save_eft,
|
|
33
|
+
load_esi_fitting,
|
|
34
|
+
save_esi_fitting,
|
|
35
|
+
load_killmail,
|
|
36
|
+
load_link,
|
|
221
37
|
calculate,
|
|
222
38
|
beacon,
|
|
223
39
|
} from "@eveshipfit/dogma-engine";
|
|
@@ -241,149 +57,26 @@ const withBeacon = calculate({ ...fit, incoming: beacon(beaconTypeId) });
|
|
|
241
57
|
const imported = calculate(load_eft("[Rifter, My Rifter]\n200mm AutoCannon I"));
|
|
242
58
|
/* And to write a fit back out as EFT: */
|
|
243
59
|
const eft = save_eft(fit);
|
|
60
|
+
/* Or if you have a fitting a character saved in game, as ESI returns it (and the other way around): */
|
|
61
|
+
const fromEsi = load_esi_fitting(fitting);
|
|
62
|
+
const toEsi = save_esi_fitting(fit);
|
|
63
|
+
/* Or if you have a killmail, as ESI returns it, for the fit of the ship that died: */
|
|
64
|
+
const fromKillmail = load_killmail(killmail);
|
|
65
|
+
/* Or if you have an EVEShip.fit link, `<version>:<payload>`, with the payload gunzipped and unbase64'd: */
|
|
66
|
+
const fromLink = load_link(version, payload);
|
|
244
67
|
|
|
245
68
|
/* What EVE would not let you fly, in `violations` of the calculation: */
|
|
246
69
|
const validated = calculate(fit, { validate: true });
|
|
247
70
|
```
|
|
248
71
|
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
The Python variant is published on PyPI as
|
|
252
|
-
[`eveshipfit-dogma-engine`](https://pypi.org/project/eveshipfit-dogma-engine/).
|
|
253
|
-
The `sde` extra brings in [`eveshipfit-sde`](https://pypi.org/project/eveshipfit-sde/), which ships `sde.dat`.
|
|
254
|
-
|
|
255
|
-
```bash
|
|
256
|
-
pip install eveshipfit-dogma-engine[sde]
|
|
257
|
-
```
|
|
258
|
-
|
|
259
|
-
```python
|
|
260
|
-
import esf_dogma_engine as dogma
|
|
261
|
-
from eveshipfit_sde import sde_path
|
|
262
|
-
|
|
263
|
-
build_number = dogma.load_sde_from_file(sde_path())
|
|
72
|
+
`load_sde` may only be called once.
|
|
264
73
|
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
"items": [
|
|
268
|
-
{
|
|
269
|
-
"type_id": 2873,
|
|
270
|
-
"slot": {"type": "high", "index": 0},
|
|
271
|
-
"state": "active",
|
|
272
|
-
"charge": {"type_id": 185},
|
|
273
|
-
}
|
|
274
|
-
],
|
|
275
|
-
"character": {"skills": {3300: 5}},
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
calculation = dogma.calculate(fit)
|
|
279
|
-
# Or if you want to know the source of the effects:
|
|
280
|
-
with_sources = dogma.calculate(fit, {"sources": True})
|
|
281
|
-
# Or if you have a beacon in space (like wormhole effects):
|
|
282
|
-
with_beacon = dogma.calculate({**fit, "incoming": dogma.beacon(beacon_type_id)})
|
|
283
|
-
# Or if you have an EFT, the text format EVE copies a fit to the clipboard in:
|
|
284
|
-
imported = dogma.calculate(dogma.load_eft("[Rifter, My Rifter]\n200mm AutoCannon I"))
|
|
285
|
-
# And to write a fit back out as EFT:
|
|
286
|
-
eft = dogma.save_eft(fit)
|
|
287
|
-
|
|
288
|
-
# What EVE would not let you fly, in `violations` of the calculation:
|
|
289
|
-
validated = dogma.calculate(fit, {"validate": True})
|
|
290
|
-
```
|
|
74
|
+
An EFT import matches the English names in `sde.dat`.
|
|
75
|
+
To also match the other languages EVE supports, hand `names.dat` (also in `@eveshipfit/sde`) to `load_names` the same way, after `load_sde`.
|
|
291
76
|
|
|
292
|
-
Fits and calculations are plain
|
|
77
|
+
Fits and calculations are plain objects, described by the included TypeScript types.
|
|
78
|
+
What every field means is explained under [Input and output](https://github.com/EVEShipFit/dogma-engine#input-and-output).
|
|
293
79
|
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
## Development
|
|
297
|
-
|
|
298
|
-
Make sure you have [Rust installed](https://www.rust-lang.org/tools/install).
|
|
299
|
-
|
|
300
|
-
Next, we need the data-files.
|
|
301
|
-
They are Flatbuffers, built by [sde-patched](https://github.com/EVEShipFit/sde-patched) and published on npm as [`@eveshipfit/sde`](https://www.npmjs.com/package/@eveshipfit/sde):
|
|
302
|
-
|
|
303
|
-
```bash
|
|
304
|
-
npm ci
|
|
305
|
-
```
|
|
306
|
-
|
|
307
|
-
- `sde.dat` holds everything needed to calculate a fit.
|
|
308
|
-
- `names.dat` holds the type names in the other seven languages EVE supports.
|
|
309
|
-
It is optional.
|
|
310
|
-
|
|
311
|
-
English names live in `sde.dat`, so an EFT-fit written in English imports without it; `names.dat` is only consulted when a name does not match.
|
|
312
|
-
|
|
313
|
-
After that, we can run the application.
|
|
314
|
-
|
|
315
|
-
```bash
|
|
316
|
-
flatc --rust --gen-onefile -o crates/esf-data/src/sde/ node_modules/@eveshipfit/sde/specs/eve.fbs node_modules/@eveshipfit/sde/specs/names.fbs
|
|
317
|
-
cargo run --release -p esf-cli
|
|
318
|
-
```
|
|
319
|
-
|
|
320
|
-
For example, some attributes of a fit with every skill at L0 except two:
|
|
321
|
-
|
|
322
|
-
```bash
|
|
323
|
-
printf '[Nergal, Spool]\nLight Entropic Disintegrator II, Occult S\n' \
|
|
324
|
-
| cargo run --release -p esf-cli -- -l 0 --skill "Gunnery=4" --skill "Rapid Firing=2" -a damage -a speed
|
|
325
|
-
```
|
|
326
|
-
|
|
327
|
-
It prints a table on a terminal and JSON otherwise; see `--help` for the rest.
|
|
328
|
-
|
|
329
|
-
Or to write the fit back out as EFT, instead of calculating it:
|
|
330
|
-
|
|
331
|
-
```bash
|
|
332
|
-
printf '[Nergal, Spool]\nLight Entropic Disintegrator II, Occult S\n' \
|
|
333
|
-
| cargo run --release -p esf-cli -- --eft
|
|
334
|
-
```
|
|
335
|
-
|
|
336
|
-
The regression suite reads the same paths; set `ESF_SDE` and `ESF_NAMES` to point it elsewhere.
|
|
337
|
-
|
|
338
|
-
## Regression
|
|
339
|
-
|
|
340
|
-
The engine is locked down by snapshot tests.
|
|
341
|
-
A case calculates one fit with one set of skills, and compares the result against a stored snapshot in [tests/snapshots](./tests/snapshots).
|
|
342
|
-
|
|
343
|
-
```bash
|
|
344
|
-
cargo test
|
|
345
|
-
```
|
|
346
|
-
|
|
347
|
-
If failures are expected differences, use `insta` to resolve them:
|
|
348
|
-
|
|
349
|
-
```bash
|
|
350
|
-
cargo install cargo-insta
|
|
351
|
-
cargo insta review
|
|
352
|
-
```
|
|
353
|
-
|
|
354
|
-
## Integration
|
|
355
|
-
|
|
356
|
-
Every variant is built from the same Rust crates; the `flatc` step from [Development](#development) comes first.
|
|
357
|
-
|
|
358
|
-
### Rust
|
|
359
|
-
|
|
360
|
-
The engine itself is a plain crate; [`esf-cli`](./crates/esf-cli) is an example of using it.
|
|
361
|
-
|
|
362
|
-
```bash
|
|
363
|
-
cargo build --release -p esf-dogma-engine
|
|
364
|
-
```
|
|
365
|
-
|
|
366
|
-
### Javascript (WebAssembly)
|
|
367
|
-
|
|
368
|
-
The primary goal of this library is to build a WebAssembly variant that can easily be used in the browser.
|
|
369
|
-
This means that there is no need for a server-component, and everything can be calculated in the browser.
|
|
370
|
-
|
|
371
|
-
This is done with [wasm-pack](https://rustwasm.github.io/wasm-pack/):
|
|
372
|
-
|
|
373
|
-
```bash
|
|
374
|
-
cargo install wasm-pack
|
|
375
|
-
wasm-pack build crates/esf-wasm --release --target web --out-dir ../../pkg
|
|
376
|
-
```
|
|
377
|
-
|
|
378
|
-
In the `pkg` folder is now a NPM module to use.
|
|
379
|
-
|
|
380
|
-
### Python
|
|
381
|
-
|
|
382
|
-
This is done with [maturin](https://www.maturin.rs/):
|
|
383
|
-
|
|
384
|
-
```bash
|
|
385
|
-
cargo install maturin
|
|
386
|
-
maturin build --release
|
|
387
|
-
```
|
|
80
|
+
## More
|
|
388
81
|
|
|
389
|
-
|
|
82
|
+
How the engine works, the attributes EVEShip.fit adds and the fitting rules it validates are all in the [main repository](https://github.com/EVEShipFit/dogma-engine).
|
package/esf_dogma_engine.d.ts
CHANGED
|
@@ -10,6 +10,47 @@ export interface Charge {
|
|
|
10
10
|
type_id: number;
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
+
/**
|
|
14
|
+
* A fitting as ESI saves it for a character.
|
|
15
|
+
*/
|
|
16
|
+
export interface EsiFitting {
|
|
17
|
+
/**
|
|
18
|
+
* Only on fittings ESI returns.
|
|
19
|
+
*/
|
|
20
|
+
fitting_id?: number;
|
|
21
|
+
/**
|
|
22
|
+
* The name of the fitting.
|
|
23
|
+
*/
|
|
24
|
+
name: string;
|
|
25
|
+
/**
|
|
26
|
+
* The description of the fitting.
|
|
27
|
+
*/
|
|
28
|
+
description?: string;
|
|
29
|
+
/**
|
|
30
|
+
* The type id of the ship.
|
|
31
|
+
*/
|
|
32
|
+
ship_type_id: number;
|
|
33
|
+
/**
|
|
34
|
+
* Everything on and in the ship.
|
|
35
|
+
*/
|
|
36
|
+
items: EsiFittingItem[];
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* A killmail as ESI returns it; only what a fit is made from. Anything else
|
|
41
|
+
* in it is ignored.
|
|
42
|
+
*/
|
|
43
|
+
export interface EsiKillmail {
|
|
44
|
+
/**
|
|
45
|
+
* The id of the killmail.
|
|
46
|
+
*/
|
|
47
|
+
killmail_id: number;
|
|
48
|
+
/**
|
|
49
|
+
* The ship that died.
|
|
50
|
+
*/
|
|
51
|
+
victim: EsiKillmailVictim;
|
|
52
|
+
}
|
|
53
|
+
|
|
13
54
|
/**
|
|
14
55
|
* A module, drone, fighter squadron, implant, booster or item in cargo.
|
|
15
56
|
*/
|
|
@@ -138,6 +179,46 @@ export interface Fit {
|
|
|
138
179
|
incoming?: Projection;
|
|
139
180
|
}
|
|
140
181
|
|
|
182
|
+
/**
|
|
183
|
+
* An item of a killmail.
|
|
184
|
+
*/
|
|
185
|
+
export interface EsiKillmailItem {
|
|
186
|
+
/**
|
|
187
|
+
* An inventory flag, like 27 for the first high slot.
|
|
188
|
+
*/
|
|
189
|
+
flag: number;
|
|
190
|
+
/**
|
|
191
|
+
* The type id of the item.
|
|
192
|
+
*/
|
|
193
|
+
item_type_id: number;
|
|
194
|
+
/**
|
|
195
|
+
* How many of the item were destroyed.
|
|
196
|
+
*/
|
|
197
|
+
quantity_destroyed?: number;
|
|
198
|
+
/**
|
|
199
|
+
* How many of the item dropped.
|
|
200
|
+
*/
|
|
201
|
+
quantity_dropped?: number;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* An item of an ESI fitting.
|
|
206
|
+
*/
|
|
207
|
+
export interface EsiFittingItem {
|
|
208
|
+
/**
|
|
209
|
+
* An inventory flag by name, like `HiSlot0`, `DroneBay` or `Cargo`.
|
|
210
|
+
*/
|
|
211
|
+
flag: string;
|
|
212
|
+
/**
|
|
213
|
+
* How many of the item.
|
|
214
|
+
*/
|
|
215
|
+
quantity: number;
|
|
216
|
+
/**
|
|
217
|
+
* The type id of the item.
|
|
218
|
+
*/
|
|
219
|
+
type_id: number;
|
|
220
|
+
}
|
|
221
|
+
|
|
141
222
|
/**
|
|
142
223
|
* How a modifier changes an attribute. They are applied in this order.
|
|
143
224
|
*/
|
|
@@ -370,6 +451,20 @@ export interface Ship {
|
|
|
370
451
|
*/
|
|
371
452
|
export type State = "offline" | "online" | "active" | "overload";
|
|
372
453
|
|
|
454
|
+
/**
|
|
455
|
+
* The victim of a killmail.
|
|
456
|
+
*/
|
|
457
|
+
export interface EsiKillmailVictim {
|
|
458
|
+
/**
|
|
459
|
+
* The type id of the ship.
|
|
460
|
+
*/
|
|
461
|
+
ship_type_id: number;
|
|
462
|
+
/**
|
|
463
|
+
* Everything on and in the ship.
|
|
464
|
+
*/
|
|
465
|
+
items?: EsiKillmailItem[];
|
|
466
|
+
}
|
|
467
|
+
|
|
373
468
|
/**
|
|
374
469
|
* What [`calculate()`] reports on top of the values.
|
|
375
470
|
*/
|
|
@@ -450,6 +545,22 @@ export function calculate(fit: Fit, options?: Options | null): Calculation;
|
|
|
450
545
|
*/
|
|
451
546
|
export function load_eft(eft: string): Fit;
|
|
452
547
|
|
|
548
|
+
/**
|
|
549
|
+
* Load a fit from an ESI fitting, the fits a character saves in game.
|
|
550
|
+
*/
|
|
551
|
+
export function load_esi_fitting(fitting: EsiFitting): Fit;
|
|
552
|
+
|
|
553
|
+
/**
|
|
554
|
+
* Load the fit of the ship that died from a killmail, as ESI returns it.
|
|
555
|
+
*/
|
|
556
|
+
export function load_killmail(killmail: EsiKillmail): Fit;
|
|
557
|
+
|
|
558
|
+
/**
|
|
559
|
+
* Load a fit from an EVEShip.fit link, given its version and its payload
|
|
560
|
+
* once unbase64'd and gunzipped.
|
|
561
|
+
*/
|
|
562
|
+
export function load_link(version: string, payload: string): Fit;
|
|
563
|
+
|
|
453
564
|
/**
|
|
454
565
|
* Load `names.dat`, so an EFT written in another language than English also
|
|
455
566
|
* imports. Optional; without it only English names match. Has to be called
|
|
@@ -468,6 +579,11 @@ export function load_sde(bytes: Uint8Array): number;
|
|
|
468
579
|
*/
|
|
469
580
|
export function save_eft(fit: Fit): string;
|
|
470
581
|
|
|
582
|
+
/**
|
|
583
|
+
* Write a fit as an ESI fitting, the fits a character saves in game.
|
|
584
|
+
*/
|
|
585
|
+
export function save_esi_fitting(fit: Fit): EsiFitting;
|
|
586
|
+
|
|
471
587
|
export function set_panic_hook(): void;
|
|
472
588
|
|
|
473
589
|
export type InitInput = RequestInfo | URL | Response | BufferSource | WebAssembly.Module;
|
|
@@ -477,9 +593,13 @@ export interface InitOutput {
|
|
|
477
593
|
readonly beacon: (a: number) => [number, number, number];
|
|
478
594
|
readonly calculate: (a: any, b: number) => [number, number, number];
|
|
479
595
|
readonly load_eft: (a: number, b: number) => [number, number, number];
|
|
596
|
+
readonly load_esi_fitting: (a: any) => [number, number, number];
|
|
597
|
+
readonly load_killmail: (a: any) => [number, number, number];
|
|
598
|
+
readonly load_link: (a: number, b: number, c: number, d: number) => [number, number, number];
|
|
480
599
|
readonly load_names: (a: number, b: number) => [number, number, number];
|
|
481
600
|
readonly load_sde: (a: number, b: number) => [number, number, number];
|
|
482
601
|
readonly save_eft: (a: any) => [number, number, number, number];
|
|
602
|
+
readonly save_esi_fitting: (a: any) => [number, number, number];
|
|
483
603
|
readonly set_panic_hook: () => void;
|
|
484
604
|
readonly __wbindgen_malloc: (a: number, b: number) => number;
|
|
485
605
|
readonly __wbindgen_realloc: (a: number, b: number, c: number, d: number) => number;
|
package/esf_dogma_engine.js
CHANGED
|
@@ -43,6 +43,51 @@ export function load_eft(eft) {
|
|
|
43
43
|
return takeFromExternrefTable0(ret[0]);
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
+
/**
|
|
47
|
+
* Load a fit from an ESI fitting, the fits a character saves in game.
|
|
48
|
+
* @param {EsiFitting} fitting
|
|
49
|
+
* @returns {Fit}
|
|
50
|
+
*/
|
|
51
|
+
export function load_esi_fitting(fitting) {
|
|
52
|
+
const ret = wasm.load_esi_fitting(fitting);
|
|
53
|
+
if (ret[2]) {
|
|
54
|
+
throw takeFromExternrefTable0(ret[1]);
|
|
55
|
+
}
|
|
56
|
+
return takeFromExternrefTable0(ret[0]);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Load the fit of the ship that died from a killmail, as ESI returns it.
|
|
61
|
+
* @param {EsiKillmail} killmail
|
|
62
|
+
* @returns {Fit}
|
|
63
|
+
*/
|
|
64
|
+
export function load_killmail(killmail) {
|
|
65
|
+
const ret = wasm.load_killmail(killmail);
|
|
66
|
+
if (ret[2]) {
|
|
67
|
+
throw takeFromExternrefTable0(ret[1]);
|
|
68
|
+
}
|
|
69
|
+
return takeFromExternrefTable0(ret[0]);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Load a fit from an EVEShip.fit link, given its version and its payload
|
|
74
|
+
* once unbase64'd and gunzipped.
|
|
75
|
+
* @param {string} version
|
|
76
|
+
* @param {string} payload
|
|
77
|
+
* @returns {Fit}
|
|
78
|
+
*/
|
|
79
|
+
export function load_link(version, payload) {
|
|
80
|
+
const ptr0 = passStringToWasm0(version, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
|
81
|
+
const len0 = WASM_VECTOR_LEN;
|
|
82
|
+
const ptr1 = passStringToWasm0(payload, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
|
83
|
+
const len1 = WASM_VECTOR_LEN;
|
|
84
|
+
const ret = wasm.load_link(ptr0, len0, ptr1, len1);
|
|
85
|
+
if (ret[2]) {
|
|
86
|
+
throw takeFromExternrefTable0(ret[1]);
|
|
87
|
+
}
|
|
88
|
+
return takeFromExternrefTable0(ret[0]);
|
|
89
|
+
}
|
|
90
|
+
|
|
46
91
|
/**
|
|
47
92
|
* Load `names.dat`, so an EFT written in another language than English also
|
|
48
93
|
* imports. Optional; without it only English names match. Has to be called
|
|
@@ -100,6 +145,19 @@ export function save_eft(fit) {
|
|
|
100
145
|
}
|
|
101
146
|
}
|
|
102
147
|
|
|
148
|
+
/**
|
|
149
|
+
* Write a fit as an ESI fitting, the fits a character saves in game.
|
|
150
|
+
* @param {Fit} fit
|
|
151
|
+
* @returns {EsiFitting}
|
|
152
|
+
*/
|
|
153
|
+
export function save_esi_fitting(fit) {
|
|
154
|
+
const ret = wasm.save_esi_fitting(fit);
|
|
155
|
+
if (ret[2]) {
|
|
156
|
+
throw takeFromExternrefTable0(ret[1]);
|
|
157
|
+
}
|
|
158
|
+
return takeFromExternrefTable0(ret[0]);
|
|
159
|
+
}
|
|
160
|
+
|
|
103
161
|
export function set_panic_hook() {
|
|
104
162
|
wasm.set_panic_hook();
|
|
105
163
|
}
|
package/esf_dogma_engine_bg.wasm
CHANGED
|
Binary file
|