@eveshipfit/dogma-engine 10.3.0 → 11.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/README.md +183 -25
- package/esf_dogma_engine.d.ts +18 -0
- package/esf_dogma_engine.js +1 -1
- package/esf_dogma_engine_bg.js +46 -0
- package/esf_dogma_engine_bg.wasm +0 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
[](https://crates.io/crates/esf-dogma-engine)
|
|
4
4
|
[](https://www.npmjs.com/package/@eveshipfit/dogma-engine)
|
|
5
|
+
[](https://pypi.org/project/eveshipfit-dogma-engine/)
|
|
5
6
|
[](https://github.com/EVEShipFit/dogma-engine/actions/workflows/testing.yml)
|
|
6
7
|
[](https://docs.rs/esf-dogma-engine)
|
|
7
8
|
|
|
@@ -36,15 +37,38 @@ All identifiers are those from the SDE.
|
|
|
36
37
|
- `items`: everything fitted or carried. Each item has:
|
|
37
38
|
- `type_id`: its type.
|
|
38
39
|
- `slot`: where the item is.
|
|
39
|
-
- `type`: `high`, `medium`, `low`, `rig`, `subsystem`, `service`, `fighter_tube`, `fighter_bay`, `drone_bay` or `cargo`.
|
|
40
|
-
|
|
41
|
-
|
|
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`.
|
|
42
43
|
- `quantity` (optional, default 1): stack size for drones, fighters and cargo. For fighters in a tube, the squadron size.
|
|
43
44
|
- `state`: requested state; `offline`, `online`, `active` or `overload`.
|
|
44
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.
|
|
45
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%.
|
|
46
54
|
- `character` (optional):
|
|
47
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.
|
|
48
72
|
|
|
49
73
|
### Options
|
|
50
74
|
|
|
@@ -57,16 +81,20 @@ All identifiers are those from the SDE.
|
|
|
57
81
|
- `mode`: result for the mode; absent when the fit has no mode.
|
|
58
82
|
- `items`: one result per item of the fit, in the same order.
|
|
59
83
|
- `character`: result for the character.
|
|
84
|
+
- `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.
|
|
85
|
+
- `id`: which buff, as `dbuffCollections` in the SDE numbers them.
|
|
86
|
+
- `value`: how strong it is, in whatever the buff's operation reads.
|
|
87
|
+
- `outgoing`: what the fit hands to other fits, in the shape `incoming` takes.
|
|
60
88
|
|
|
61
89
|
Each result has:
|
|
62
90
|
|
|
63
91
|
- `attributes`: per attribute ID, its `base` value before effects and its final `value`.
|
|
64
92
|
With the `sources` option, also `sources`: every modifier on it, in the order they were applied. Each has:
|
|
65
|
-
- `from`: where it comes from; `type` is `ship`, `mode`, `character`, `item` or `charge` (with the `index` into `items`),
|
|
66
|
-
- `effect_id`: the effect that
|
|
67
|
-
- `source_attribute_id`: the attribute on the source that holds `value
|
|
93
|
+
- `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`).
|
|
94
|
+
- `effect_id`: the effect that holds the modifier; `null` for a buff, which has none.
|
|
95
|
+
- `source_attribute_id`: the attribute on the source that holds `value`; `null` for a buff, which carries its own strength.
|
|
68
96
|
- `operator`: `pre_assign`, `pre_mul`, `pre_div`, `mod_add`, `mod_sub`, `post_mul`, `post_div`, `post_percent` or `post_assign`.
|
|
69
|
-
- `value`: the value of the modifying attribute.
|
|
97
|
+
- `value`: the value of the modifying attribute, or the strength of the buff.
|
|
70
98
|
- `quantity`: how many times it counts. A stacking penalised stack is listed once per item instead.
|
|
71
99
|
- `penalty`: the stacking penalty factor it got, or `null` if not penalised.
|
|
72
100
|
- `applied`: false when the source's state is too low for the effect.
|
|
@@ -84,6 +112,128 @@ To make rendering a fit easier, these are calculated by this library, and presen
|
|
|
84
112
|
Their identifier is always a negative value, to visually separate them.
|
|
85
113
|
What additional attributes exist are defined in [EVEShipFit/sde-patched](https://github.com/EVEShipFit/sde-patched) repository.
|
|
86
114
|
|
|
115
|
+
## Usage
|
|
116
|
+
|
|
117
|
+
The engine is published for Rust, Javascript and Python; all three calculate the same way.
|
|
118
|
+
Each hands over `sde.dat` once, and every lookup after that happens inside Rust.
|
|
119
|
+
An EFT import matches the English names in `sde.dat`; hand over `names.dat` too to also match the other languages EVE supports.
|
|
120
|
+
|
|
121
|
+
How each package is built is explained under [Integration](#integration).
|
|
122
|
+
|
|
123
|
+
### Rust
|
|
124
|
+
|
|
125
|
+
The crate is published on crates.io as [`esf-dogma-engine`](https://crates.io/crates/esf-dogma-engine).
|
|
126
|
+
`esf-data` reads `sde.dat`.
|
|
127
|
+
|
|
128
|
+
```bash
|
|
129
|
+
cargo add esf-dogma-engine esf-data
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
```rust
|
|
133
|
+
use esf_data::{InfoSde, Sde};
|
|
134
|
+
use esf_dogma_engine::{Fit, Options, beacon, calculate};
|
|
135
|
+
|
|
136
|
+
let bytes = std::fs::read("sde.dat")?;
|
|
137
|
+
let sde = Sde::new(&bytes)?;
|
|
138
|
+
let info = InfoSde::new(&sde);
|
|
139
|
+
|
|
140
|
+
let fit: Fit = serde_json::from_str(
|
|
141
|
+
r#"{
|
|
142
|
+
"ship": {"type_id": 587},
|
|
143
|
+
"items": [
|
|
144
|
+
{
|
|
145
|
+
"type_id": 2873,
|
|
146
|
+
"slot": {"type": "high", "index": 0},
|
|
147
|
+
"state": "active",
|
|
148
|
+
"charge": {"type_id": 185}
|
|
149
|
+
}
|
|
150
|
+
],
|
|
151
|
+
"character": {"skills": {"3300": 5}}
|
|
152
|
+
}"#,
|
|
153
|
+
)?;
|
|
154
|
+
|
|
155
|
+
let calculation = calculate(&info, &fit, &Options::default());
|
|
156
|
+
// Or if you want to know the source of the effects:
|
|
157
|
+
let with_sources = calculate(&info, &fit, &Options { sources: true, ..Default::default() });
|
|
158
|
+
// Or if you have a beacon in space (like wormhole effects):
|
|
159
|
+
let with_beacon = calculate(&info, &Fit { incoming: beacon(&info, beacon_type_id), ..fit }, &Options::default());
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
### Javascript (WebAssembly)
|
|
163
|
+
|
|
164
|
+
The WebAssembly variant is published on npm as
|
|
165
|
+
[`@eveshipfit/dogma-engine`](https://www.npmjs.com/package/@eveshipfit/dogma-engine).
|
|
166
|
+
[`@eveshipfit/sde`](https://www.npmjs.com/package/@eveshipfit/sde) ships `sde.dat` in its `dist` folder; serve or bundle that file.
|
|
167
|
+
|
|
168
|
+
```bash
|
|
169
|
+
npm install @eveshipfit/dogma-engine @eveshipfit/sde
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
```js
|
|
173
|
+
import init, { init as initPanicHook, load_sde, load_eft, calculate, beacon } from "@eveshipfit/dogma-engine";
|
|
174
|
+
|
|
175
|
+
await init();
|
|
176
|
+
initPanicHook();
|
|
177
|
+
|
|
178
|
+
const sde = await fetch("/sde.dat").then((response) => response.arrayBuffer());
|
|
179
|
+
const buildNumber = load_sde(new Uint8Array(sde));
|
|
180
|
+
const fit = {
|
|
181
|
+
ship: { type_id: 587 },
|
|
182
|
+
items: [{ type_id: 2873, slot: { type: "high", index: 0 }, state: "active", charge: { type_id: 185 } }],
|
|
183
|
+
character: { skills: { 3300: 5 } },
|
|
184
|
+
};
|
|
185
|
+
|
|
186
|
+
const calculation = calculate(fit);
|
|
187
|
+
/* Or if you want to know the source of the effects: */
|
|
188
|
+
const withSources = calculate(fit, { sources: true });
|
|
189
|
+
/* Or if you have a beacon in space (like wormhole effects): */
|
|
190
|
+
const withBeacon = calculate({ ...fit, incoming: beacon(beaconTypeId) });
|
|
191
|
+
/* Or if you have an EFT, the text format EVE copies a fit to the clipboard in: */
|
|
192
|
+
const imported = calculate(load_eft("[Rifter, My Rifter]\n200mm AutoCannon I"));
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
### Python
|
|
196
|
+
|
|
197
|
+
The Python variant is published on PyPI as
|
|
198
|
+
[`eveshipfit-dogma-engine`](https://pypi.org/project/eveshipfit-dogma-engine/).
|
|
199
|
+
The `sde` extra brings in [`eveshipfit-sde`](https://pypi.org/project/eveshipfit-sde/), which ships `sde.dat`.
|
|
200
|
+
|
|
201
|
+
```bash
|
|
202
|
+
pip install eveshipfit-dogma-engine[sde]
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
```python
|
|
206
|
+
import esf_dogma_engine as dogma
|
|
207
|
+
from eveshipfit_sde import sde_path
|
|
208
|
+
|
|
209
|
+
build_number = dogma.load_sde_from_file(sde_path())
|
|
210
|
+
|
|
211
|
+
fit = {
|
|
212
|
+
"ship": {"type_id": 587},
|
|
213
|
+
"items": [
|
|
214
|
+
{
|
|
215
|
+
"type_id": 2873,
|
|
216
|
+
"slot": {"type": "high", "index": 0},
|
|
217
|
+
"state": "active",
|
|
218
|
+
"charge": {"type_id": 185},
|
|
219
|
+
}
|
|
220
|
+
],
|
|
221
|
+
"character": {"skills": {3300: 5}},
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
calculation = dogma.calculate(fit)
|
|
225
|
+
# Or if you want to know the source of the effects:
|
|
226
|
+
with_sources = dogma.calculate(fit, {"sources": True})
|
|
227
|
+
# Or if you have a beacon in space (like wormhole effects):
|
|
228
|
+
with_beacon = dogma.calculate({**fit, "incoming": dogma.beacon(beacon_type_id)})
|
|
229
|
+
# Or if you have an EFT, the text format EVE copies a fit to the clipboard in:
|
|
230
|
+
imported = dogma.calculate(dogma.load_eft("[Rifter, My Rifter]\n200mm AutoCannon I"))
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
Fits and calculations are plain dicts, typed with `TypedDict` in `esf_dogma_engine.types`.
|
|
234
|
+
|
|
235
|
+
`load_eft`, `calculate` and `beacon` release the GIL while they work, so a thread pool calculates fits in parallel.
|
|
236
|
+
|
|
87
237
|
## Development
|
|
88
238
|
|
|
89
239
|
Make sure you have [Rust installed](https://www.rust-lang.org/tools/install).
|
|
@@ -108,6 +258,15 @@ flatc --rust --gen-onefile -o crates/esf-data/src/sde/ node_modules/@eveshipfit/
|
|
|
108
258
|
cargo run --release -p esf-cli
|
|
109
259
|
```
|
|
110
260
|
|
|
261
|
+
For example, some attributes of a fit with every skill at L0 except two:
|
|
262
|
+
|
|
263
|
+
```bash
|
|
264
|
+
printf '[Nergal, Spool]\nLight Entropic Disintegrator II, Occult S\n' \
|
|
265
|
+
| cargo run --release -p esf-cli -- -l 0 --skill "Gunnery=4" --skill "Rapid Firing=2" -a damage -a speed
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
It prints a table on a terminal and JSON otherwise; see `--help` for the rest.
|
|
269
|
+
|
|
111
270
|
The regression suite reads the same paths; set `ESF_SDE` and `ESF_NAMES` to point it elsewhere.
|
|
112
271
|
|
|
113
272
|
## Regression
|
|
@@ -128,6 +287,16 @@ cargo insta review
|
|
|
128
287
|
|
|
129
288
|
## Integration
|
|
130
289
|
|
|
290
|
+
Every variant is built from the same Rust crates; the `flatc` step from [Development](#development) comes first.
|
|
291
|
+
|
|
292
|
+
### Rust
|
|
293
|
+
|
|
294
|
+
The engine itself is a plain crate; [`esf-cli`](./crates/esf-cli) is an example of using it.
|
|
295
|
+
|
|
296
|
+
```bash
|
|
297
|
+
cargo build --release -p esf-dogma-engine
|
|
298
|
+
```
|
|
299
|
+
|
|
131
300
|
### Javascript (WebAssembly)
|
|
132
301
|
|
|
133
302
|
The primary goal of this library is to build a WebAssembly variant that can easily be used in the browser.
|
|
@@ -142,24 +311,13 @@ wasm-pack build crates/esf-wasm --release --out-dir ../../pkg
|
|
|
142
311
|
|
|
143
312
|
In the `pkg` folder is now a NPM module to use.
|
|
144
313
|
|
|
145
|
-
|
|
146
|
-
The file is a Flatbuffer, so nothing is parsed: the bytes are used where they land.
|
|
314
|
+
### Python
|
|
147
315
|
|
|
148
|
-
|
|
149
|
-
import init, { init as initPanicHook, load_sde, calculate } from "@eveshipfit/dogma-engine";
|
|
316
|
+
This is done with [maturin](https://www.maturin.rs/):
|
|
150
317
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
const sde = await fetch("/sde.dat").then((response) => response.arrayBuffer());
|
|
155
|
-
const buildNumber = load_sde(new Uint8Array(sde));
|
|
156
|
-
const fit = {
|
|
157
|
-
ship: { type_id: 587 },
|
|
158
|
-
items: [{ type_id: 2873, slot: { type: "high", index: 0 }, state: "active", charge: { type_id: 185 } }],
|
|
159
|
-
character: { skills: { 3300: 5 } },
|
|
160
|
-
};
|
|
161
|
-
|
|
162
|
-
const calculation = calculate(fit);
|
|
163
|
-
/* Or if you want to know the source of the effects: */
|
|
164
|
-
const withSources = calculate(fit, { sources: true });
|
|
318
|
+
```bash
|
|
319
|
+
cargo install maturin
|
|
320
|
+
maturin build --release
|
|
165
321
|
```
|
|
322
|
+
|
|
323
|
+
In the `target/wheels` folder is now a wheel to install.
|
package/esf_dogma_engine.d.ts
CHANGED
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
/* tslint:disable */
|
|
2
2
|
/* eslint-disable */
|
|
3
3
|
|
|
4
|
+
/**
|
|
5
|
+
* What a beacon in space hands to every fit in there with it. Put the result
|
|
6
|
+
* in `incoming` of a fit to have it applied.
|
|
7
|
+
*/
|
|
8
|
+
export function beacon(type_id: number): any;
|
|
9
|
+
|
|
4
10
|
/**
|
|
5
11
|
* `js_options` may be left out; it then uses the defaults.
|
|
6
12
|
*/
|
|
@@ -8,6 +14,18 @@ export function calculate(js_fit: any, js_options: any): any;
|
|
|
8
14
|
|
|
9
15
|
export function init(): void;
|
|
10
16
|
|
|
17
|
+
/**
|
|
18
|
+
* Load a fit from EFT, the text format EVE copies a fit to the clipboard in.
|
|
19
|
+
*/
|
|
20
|
+
export function load_eft(eft: string): any;
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Load `names.dat`, so an EFT written in another language than English also
|
|
24
|
+
* imports. Optional; without it only English names match. Has to be called
|
|
25
|
+
* after `load_sde`, and calling it twice is an error.
|
|
26
|
+
*/
|
|
27
|
+
export function load_names(bytes: Uint8Array): number;
|
|
28
|
+
|
|
11
29
|
/**
|
|
12
30
|
* Load `sde.dat`. Has to be called before `calculate`; calling it twice is an
|
|
13
31
|
* error, as the first buffer is borrowed for the rest of the session.
|
package/esf_dogma_engine.js
CHANGED
package/esf_dogma_engine_bg.js
CHANGED
|
@@ -1,3 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What a beacon in space hands to every fit in there with it. Put the result
|
|
3
|
+
* in `incoming` of a fit to have it applied.
|
|
4
|
+
* @param {number} type_id
|
|
5
|
+
* @returns {any}
|
|
6
|
+
*/
|
|
7
|
+
export function beacon(type_id) {
|
|
8
|
+
const ret = wasm.beacon(type_id);
|
|
9
|
+
if (ret[2]) {
|
|
10
|
+
throw takeFromExternrefTable0(ret[1]);
|
|
11
|
+
}
|
|
12
|
+
return takeFromExternrefTable0(ret[0]);
|
|
13
|
+
}
|
|
14
|
+
|
|
1
15
|
/**
|
|
2
16
|
* `js_options` may be left out; it then uses the defaults.
|
|
3
17
|
* @param {any} js_fit
|
|
@@ -16,6 +30,38 @@ export function init() {
|
|
|
16
30
|
wasm.init();
|
|
17
31
|
}
|
|
18
32
|
|
|
33
|
+
/**
|
|
34
|
+
* Load a fit from EFT, the text format EVE copies a fit to the clipboard in.
|
|
35
|
+
* @param {string} eft
|
|
36
|
+
* @returns {any}
|
|
37
|
+
*/
|
|
38
|
+
export function load_eft(eft) {
|
|
39
|
+
const ptr0 = passStringToWasm0(eft, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
|
40
|
+
const len0 = WASM_VECTOR_LEN;
|
|
41
|
+
const ret = wasm.load_eft(ptr0, len0);
|
|
42
|
+
if (ret[2]) {
|
|
43
|
+
throw takeFromExternrefTable0(ret[1]);
|
|
44
|
+
}
|
|
45
|
+
return takeFromExternrefTable0(ret[0]);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Load `names.dat`, so an EFT written in another language than English also
|
|
50
|
+
* imports. Optional; without it only English names match. Has to be called
|
|
51
|
+
* after `load_sde`, and calling it twice is an error.
|
|
52
|
+
* @param {Uint8Array} bytes
|
|
53
|
+
* @returns {number}
|
|
54
|
+
*/
|
|
55
|
+
export function load_names(bytes) {
|
|
56
|
+
const ptr0 = passArray8ToWasm0(bytes, wasm.__wbindgen_malloc);
|
|
57
|
+
const len0 = WASM_VECTOR_LEN;
|
|
58
|
+
const ret = wasm.load_names(ptr0, len0);
|
|
59
|
+
if (ret[2]) {
|
|
60
|
+
throw takeFromExternrefTable0(ret[1]);
|
|
61
|
+
}
|
|
62
|
+
return ret[0];
|
|
63
|
+
}
|
|
64
|
+
|
|
19
65
|
/**
|
|
20
66
|
* Load `sde.dat`. Has to be called before `calculate`; calling it twice is an
|
|
21
67
|
* error, as the first buffer is borrowed for the rest of the session.
|
package/esf_dogma_engine_bg.wasm
CHANGED
|
Binary file
|