@pkmn/engine 0.1.0-dev.437f6a52 → 0.1.0-dev.4438e918

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.
Files changed (86) hide show
  1. package/LICENSE +1 -3
  2. package/README.md +104 -59
  3. package/build/pkg/addon/browser.d.ts +3 -0
  4. package/build/pkg/addon/browser.js +47 -0
  5. package/build/pkg/addon/browser.js.map +1 -0
  6. package/build/pkg/addon/node.d.ts +3 -0
  7. package/build/pkg/addon/node.js +110 -0
  8. package/build/pkg/addon/node.js.map +1 -0
  9. package/build/pkg/addon/wasm.d.ts +2 -0
  10. package/build/pkg/addon/wasm.js +53 -0
  11. package/build/pkg/addon/wasm.js.map +1 -0
  12. package/build/pkg/addon.d.ts +26 -4
  13. package/build/pkg/addon.js +39 -71
  14. package/build/pkg/addon.js.map +1 -1
  15. package/build/pkg/data/ids.json +12 -12
  16. package/build/pkg/data/layout.json +17 -4
  17. package/build/pkg/data/protocol.json +84 -13
  18. package/build/pkg/data.d.ts +27 -5
  19. package/build/pkg/data.js.map +1 -1
  20. package/build/pkg/gen1.d.ts +15 -18
  21. package/build/pkg/gen1.js +30 -21
  22. package/build/pkg/gen1.js.map +1 -1
  23. package/build/pkg/index.d.ts +42 -91
  24. package/build/pkg/index.js +23 -70
  25. package/build/pkg/index.js.map +1 -1
  26. package/build/pkg/protocol.d.ts +29 -1
  27. package/build/pkg/protocol.js +123 -102
  28. package/build/pkg/protocol.js.map +1 -1
  29. package/build/tools/debug.js +84 -73
  30. package/build/tools/debug.js.map +1 -1
  31. package/build/tools/display/debug.jsx +66 -0
  32. package/build/tools/display/debug.jsx.map +1 -0
  33. package/build/tools/display/index.js +152 -0
  34. package/build/tools/display/index.js.map +1 -0
  35. package/build/tools/display/ui.jsx +360 -0
  36. package/build/tools/display/ui.jsx.map +1 -0
  37. package/build/tools/display/util.js +157 -0
  38. package/build/tools/display/util.js.map +1 -0
  39. package/build.zig +304 -142
  40. package/package.json +71 -121
  41. package/src/bin/install-pkmn-engine +48 -22
  42. package/src/bin/pkmn-debug +1 -1
  43. package/src/lib/bindings/c.zig +200 -0
  44. package/src/lib/{binding → bindings}/node.zig +15 -32
  45. package/src/lib/bindings/wasm.zig +50 -0
  46. package/src/lib/common/array.zig +70 -0
  47. package/src/lib/common/battle.zig +17 -0
  48. package/src/lib/common/data.zig +12 -24
  49. package/src/lib/common/debug.zig +33 -28
  50. package/src/lib/common/js.zig +114 -0
  51. package/src/lib/common/optional.zig +61 -0
  52. package/src/lib/common/options.zig +6 -0
  53. package/src/lib/common/protocol.zig +964 -450
  54. package/src/lib/common/rational.zig +440 -0
  55. package/src/lib/common/rng.zig +22 -15
  56. package/src/lib/common/util.zig +44 -0
  57. package/src/lib/gen1/calc.zig +975 -0
  58. package/src/lib/gen1/chance.zig +1222 -0
  59. package/src/lib/gen1/data/moves.zig +193 -183
  60. package/src/lib/gen1/data/species.zig +4 -6
  61. package/src/lib/gen1/data/types.zig +9 -10
  62. package/src/lib/gen1/data.zig +71 -81
  63. package/src/lib/gen1/helpers.zig +90 -410
  64. package/src/lib/gen1/mechanics.zig +712 -648
  65. package/src/lib/gen2/calc.zig +150 -0
  66. package/src/lib/gen2/chance.zig +896 -0
  67. package/src/lib/gen2/data/items.zig +13 -21
  68. package/src/lib/gen2/data/moves.zig +664 -572
  69. package/src/lib/gen2/data/species.zig +2 -4
  70. package/src/lib/gen2/data/types.zig +139 -34
  71. package/src/lib/gen2/data.zig +121 -96
  72. package/src/lib/gen2/generated.zig +801 -0
  73. package/src/lib/gen2/helpers.zig +53 -38
  74. package/src/lib/gen2/mechanics.zig +3580 -29
  75. package/src/lib/napi.h +2 -0
  76. package/src/lib/node.zig +14 -0
  77. package/src/lib/pkmn.zig +125 -29
  78. package/src/lib/wasm.zig +13 -0
  79. package/src/tools/display/dom.ts +108 -0
  80. package/src/tools/display/ui.css +354 -0
  81. package/build/test/display.js +0 -400
  82. package/build/test/display.js.map +0 -1
  83. package/src/lib/binding/wasm.zig +0 -12
  84. package/src/lib/gen1/README.md +0 -814
  85. package/src/lib/gen2/README.md +0 -309
  86. package/src/test/display/pkmn.html.tmpl +0 -368
package/package.json CHANGED
@@ -1,19 +1,31 @@
1
1
  {
2
2
  "name": "@pkmn/engine",
3
- "version": "0.1.0-dev.437f6a52",
3
+ "version": "0.1.0-dev.4438e918",
4
4
  "description": "A minimal, complete, Pokémon battle simulation engine optimized for performance",
5
5
  "repository": "github:pkmn/engine",
6
6
  "license": "MIT",
7
7
  "sideEffects": false,
8
8
  "main": "build/pkg/index.js",
9
9
  "types": "build/pkg/index.d.ts",
10
+ "browser": {
11
+ "./build/pkg/addon/node.js": "./build/pkg/addon/browser.js"
12
+ },
10
13
  "files": [
11
14
  "build.zig",
12
- "build/pkg/data.d.ts",
13
- "build/pkg/data.js.map",
14
15
  "build/pkg/addon.d.ts",
15
16
  "build/pkg/addon.js.map",
16
17
  "build/pkg/addon.js",
18
+ "build/pkg/addon/browser.d.ts",
19
+ "build/pkg/addon/browser.js.map",
20
+ "build/pkg/addon/browser.js",
21
+ "build/pkg/addon/node.d.ts",
22
+ "build/pkg/addon/node.js.map",
23
+ "build/pkg/addon/node.js",
24
+ "build/pkg/addon/wasm.d.ts",
25
+ "build/pkg/addon/wasm.js.map",
26
+ "build/pkg/addon/wasm.js",
27
+ "build/pkg/data.d.ts",
28
+ "build/pkg/data.js.map",
17
29
  "build/pkg/data.js",
18
30
  "build/pkg/data/ids.json",
19
31
  "build/pkg/data/layout.json",
@@ -27,33 +39,54 @@
27
39
  "build/pkg/protocol.d.ts",
28
40
  "build/pkg/protocol.js.map",
29
41
  "build/pkg/protocol.js",
30
- "build/test/display.js.map",
31
- "build/test/display.js",
32
42
  "build/tools/debug.js.map",
33
43
  "build/tools/debug.js",
34
- "src/bin/install-pkmn-engine",
35
- "src/lib/binding/node.zig",
36
- "src/lib/binding/wasm.zig",
44
+ "build/tools/display/index.js.map",
45
+ "build/tools/display/index.js",
46
+ "build/tools/display/debug.jsx.map",
47
+ "build/tools/display/debug.jsx",
48
+ "build/tools/display/ui.jsx.map",
49
+ "build/tools/display/ui.jsx",
50
+ "build/tools/display/util.js.map",
51
+ "build/tools/display/util.js",
52
+ "src/lib/bindings/c.zig",
53
+ "src/lib/bindings/node.zig",
54
+ "src/lib/bindings/wasm.zig",
55
+ "src/lib/common/array.zig",
56
+ "src/lib/common/battle.zig",
37
57
  "src/lib/common/data.zig",
38
58
  "src/lib/common/debug.zig",
59
+ "src/lib/common/js.zig",
60
+ "src/lib/common/optional.zig",
39
61
  "src/lib/common/options.zig",
40
62
  "src/lib/common/protocol.zig",
63
+ "src/lib/common/rational.zig",
41
64
  "src/lib/common/rng.zig",
65
+ "src/lib/common/util.zig",
66
+ "src/lib/gen1/calc.zig",
67
+ "src/lib/gen1/chance.zig",
42
68
  "src/lib/gen1/data.zig",
43
69
  "src/lib/gen1/data/moves.zig",
44
70
  "src/lib/gen1/data/species.zig",
45
71
  "src/lib/gen1/data/types.zig",
46
72
  "src/lib/gen1/helpers.zig",
47
73
  "src/lib/gen1/mechanics.zig",
74
+ "src/lib/gen2/calc.zig",
75
+ "src/lib/gen2/chance.zig",
48
76
  "src/lib/gen2/data.zig",
49
77
  "src/lib/gen2/data/items.zig",
50
78
  "src/lib/gen2/data/moves.zig",
51
79
  "src/lib/gen2/data/species.zig",
52
80
  "src/lib/gen2/data/types.zig",
81
+ "src/lib/gen2/generated.zig",
53
82
  "src/lib/gen2/helpers.zig",
54
83
  "src/lib/gen2/mechanics.zig",
84
+ "src/lib/napi.h",
85
+ "src/lib/node.zig",
55
86
  "src/lib/pkmn.zig",
56
- "src/test/display/pkmn.html.tmpl"
87
+ "src/lib/wasm.zig",
88
+ "src/tools/display/dom.ts",
89
+ "src/tools/display/ui.css"
57
90
  ],
58
91
  "engines": {
59
92
  "node": ">=16.0.0"
@@ -66,138 +99,55 @@
66
99
  "access": "public"
67
100
  },
68
101
  "dependencies": {
69
- "@pkmn/data": "^0.7.44",
70
- "@pkmn/protocol": "^0.6.12"
102
+ "@pkmn/data": "0.9.35",
103
+ "@pkmn/protocol": "^0.7.2"
71
104
  },
72
105
  "devDependencies": {
73
- "@pkmn/eslint-config": "^3.2.0",
74
- "@pkmn/img": "^0.2.12",
75
- "@pkmn/sets": "^5.0.4",
76
- "@pkmn/sim": "0.7.44",
77
- "@types/html-minifier": "^4.0.2",
78
- "@types/jest": "^29.5.2",
79
- "@types/minimist": "^1.2.2",
80
- "@types/mustache": "^4.2.2",
81
- "@types/node": "^20.3.1",
82
- "@vitest/coverage-c8": "^0.32.2",
83
- "binaryen": "^113.0.0",
84
- "eslint": "^8.43.0",
106
+ "@pkmn/dex-types": "0.9.35",
107
+ "@pkmn/eslint-config": "^9.27.0",
108
+ "@pkmn/img": "^0.3.3",
109
+ "@pkmn/sets": "^5.2.0",
110
+ "@pkmn/sim": "0.9.31",
111
+ "@pkmn/smogon": "0.5.21",
112
+ "@types/html-minifier": "^4.0.6",
113
+ "@types/jest": "^30.0.0",
114
+ "@types/minimist": "^1.2.5",
115
+ "@types/mustache": "^4.2.6",
116
+ "@types/node": "^25.6.0",
117
+ "@types/react": "^19.2.14",
118
+ "@types/semver": "^7.7.1",
119
+ "@types/vscode": "^1.118.0",
120
+ "@vitest/coverage-v8": "^4.1.5",
121
+ "@vscode/vsce": "^3.9.1",
122
+ "binaryen": "^129.0.0",
123
+ "esbuild": "^0.28.0",
124
+ "eslint": "<10",
85
125
  "html-minifier": "^4.0.0",
86
126
  "json-stringify-pretty-compact": "3.0.0",
87
127
  "minimist": "^1.2.8",
88
128
  "mustache": "^4.2.0",
129
+ "semver": "^7.7.4",
89
130
  "source-map-support": "^0.5.21",
131
+ "table": "^6.9.0",
90
132
  "trakr": "^0.2.0",
91
- "typescript": "^5.1.3",
92
- "vitest": "^0.32.2"
133
+ "typescript": "^6.0.3",
134
+ "vitest": "^4.1.5"
93
135
  },
94
136
  "scripts": {
95
- "lint": "eslint --cache src --ext ts,js && eslint src/bin/*",
96
- "fix": "eslint --fix src --ext ts,js && eslint --fix src/bin/*",
137
+ "lint": "eslint --cache src",
138
+ "fix": "eslint --fix src",
97
139
  "compile": "tsc -p .",
98
140
  "build": "npm run compile",
99
141
  "test": "vitest src/pkg",
100
142
  "test:integration": "vitest src/test",
101
143
  "debug": "npm run compile && node build/tools/debug",
144
+ "demo": "npm run compile && node build/tools/demo",
102
145
  "fuzz": "npm run compile && node build/test/fuzz",
103
146
  "generate": "npm run compile && node build/tools/generate",
104
147
  "release": "npm run compile && node build/tools/release",
105
148
  "benchmark": "npm run compile && node build/test/benchmark",
106
149
  "integration": "npm run compile && node build/test/integration",
150
+ "extension": "npm -C src/tools/vscode run build",
107
151
  "postinstall": "node src/bin/install-pkmn-engine"
108
- },
109
- "eslintConfig": {
110
- "extends": "@pkmn",
111
- "ignorePatterns": [
112
- "dist/",
113
- "node_modules/",
114
- "src/examples/zig",
115
- "build/"
116
- ],
117
- "env": {
118
- "es6": true,
119
- "node": true,
120
- "browser": true
121
- },
122
- "overrides": [
123
- {
124
- "files": [
125
- "**/*.ts"
126
- ],
127
- "parserOptions": {
128
- "project": [
129
- "./tsconfig.json",
130
- "./src/examples/js/tsconfig.json"
131
- ]
132
- }
133
- },
134
- {
135
- "files": [
136
- "src/pkg/index.ts",
137
- "src/test/display.ts",
138
- "src/test/integration.ts"
139
- ],
140
- "rules": {
141
- "no-control-regex": "off",
142
- "@typescript-eslint/no-empty-interface": "off",
143
- "@typescript-eslint/no-shadow": "off"
144
- }
145
- },
146
- {
147
- "files": [
148
- "src/pkg/addon.ts"
149
- ],
150
- "rules": {
151
- "@typescript-eslint/no-var-requires": "off"
152
- }
153
- },
154
- {
155
- "files": [
156
- "src/test/benchmark*.ts"
157
- ],
158
- "rules": {
159
- "@typescript-eslint/no-unused-vars": "off"
160
- }
161
- },
162
- {
163
- "files": [
164
- "src/test/*.test.ts",
165
- "src/test/regression/*.test.ts"
166
- ],
167
- "rules": {
168
- "jest/no-standalone-expect": "off"
169
- }
170
- },
171
- {
172
- "files": [
173
- "src/test/showdown/**"
174
- ],
175
- "rules": {
176
- "jest/expect-expect": [
177
- "warn",
178
- {
179
- "assertFunctionNames": [
180
- "expect",
181
- "expectLog",
182
- "verify"
183
- ]
184
- }
185
- ]
186
- }
187
- },
188
- {
189
- "files": [
190
- "src/tools/generate.ts"
191
- ],
192
- "rules": {
193
- "@typescript-eslint/restrict-template-expressions": [
194
- "error",
195
- {
196
- "allowBoolean": true
197
- }
198
- ]
199
- }
200
- }
201
- ]
202
152
  }
203
153
  }
@@ -10,7 +10,7 @@ const path = require('path');
10
10
  const {pipeline} = require('stream/promises');
11
11
  const tty = require('tty');
12
12
 
13
- const ZIG_VERSION = {major: 0, minor: 11, patch: 0, dev: 3859};
13
+ const ZIG_VERSION = {major: 0, minor: 16, patch: 0};
14
14
  const DEV = ZIG_VERSION.dev ? `-dev.${ZIG_VERSION.dev}` : '';
15
15
  const VERSION = `${ZIG_VERSION.major}.${ZIG_VERSION.minor}.${ZIG_VERSION.patch}${DEV}`;
16
16
  const INDEX = 'https://ziglang.org/download/index.json';
@@ -111,15 +111,31 @@ const unpack = async (input, output) => {
111
111
  }
112
112
  };
113
113
 
114
+ const parse = s => {
115
+ try {
116
+ return JSON.parse(s);
117
+ } catch (e) {
118
+ if (!(e instanceof SyntaxError)) throw e;
119
+ const json = s
120
+ // "key": -> "key": (ensures keys are quoted)
121
+ .replace(/\.([a-zA-Z_][a-zA-Z0-9_]*)\s*=/g, '"$1":')
122
+ // .{ -> { (converts ZON struct to JSON object)
123
+ .replace(/\.\{/g, '{')
124
+ // Remove trailing commas, which are invalid in JSON
125
+ .replace(/,\s*([}\]])/g, '$1');
126
+ return JSON.parse(json);
127
+ }
128
+ };
129
+
114
130
  const find = zig => {
115
131
  try {
116
- const {zig_exe, version} = JSON.parse(sh(zig, ['env']));
132
+ const {zig_exe, version} = parse(sh(zig, ['env']));
117
133
  const [major, minor, patch, dev] = version.split('.').map(n => parseInt(n));
118
134
 
119
135
  const compatible = major > ZIG_VERSION.major ||
120
136
  (major >= ZIG_VERSION.major && minor > ZIG_VERSION.minor) ||
121
137
  (major >= ZIG_VERSION.major && minor >= ZIG_VERSION.minor && patch >= ZIG_VERSION.patch &&
122
- (!ZIG_VERSION.dev || (dev && dev >= ZIG_VERSION.dev)));
138
+ (!ZIG_VERSION.dev || (dev && dev >= parseInt(ZIG_VERSION.dev))));
123
139
 
124
140
  if (compatible) {
125
141
  log('Found existing compatible Zig executable:', zig_exe);
@@ -164,6 +180,7 @@ const install = async () => {
164
180
 
165
181
  const index = JSON.parse(await fetch(INDEX));
166
182
  const version = Object.keys(index)[+!ZIG_VERSION.dev];
183
+ // const version = VERSION; // TODO
167
184
  const release = index[version][`${arch}-${platform}`];
168
185
  const url = release.tarball;
169
186
 
@@ -255,7 +272,7 @@ const downloadImportLib = async () => {
255
272
  }
256
273
 
257
274
  const dir = path.join(ROOT, 'build', 'lib');
258
- const url = new URL('./win-x64/node.lib', process.release.headersUrl).href;
275
+ const url = process.release.libUrl;
259
276
  const dest = path.join(dir, path.basename(url));
260
277
  if (fs.existsSync(path.join(dest))) {
261
278
  log('Node import library:', dest);
@@ -283,19 +300,19 @@ const downloadImportLib = async () => {
283
300
  let error = false;
284
301
  for (let i = 2; i < process.argv.length; i++) {
285
302
  switch (process.argv[i]) {
286
- case "--silent": {
287
- SILENT = true;
288
- break;
289
- }
290
- case "--zig": {
291
- if (options || only) error = true;
292
- only = true;
293
- break;
294
- }
295
- default: {
296
- if (options || only || !process.argv[i].startsWith('--options=')) error = true;
297
- options = process.argv[i].slice(10).split(' ');
298
- }
303
+ case "--silent": {
304
+ SILENT = true;
305
+ break;
306
+ }
307
+ case "--zig": {
308
+ if (options || only) error = true;
309
+ only = true;
310
+ break;
311
+ }
312
+ default: {
313
+ if (options || only || !process.argv[i].startsWith('--options=')) error = true;
314
+ options = process.argv[i].slice(10).split(' ');
315
+ }
299
316
  }
300
317
  }
301
318
  if (error) {
@@ -323,6 +340,7 @@ const downloadImportLib = async () => {
323
340
  const libs = path.join(ROOT, 'build', 'lib');
324
341
  if (fs.existsSync(libs)) {
325
342
  for (const file of fs.readdirSync(libs)) {
343
+ if (!file.startsWith('pkmn')) continue;
326
344
  const type = path.extname(file).slice(1);
327
345
  if (type !== 'node' && type !== 'wasm') continue;
328
346
  // If we don't copy the addon before loading it Windows will return an
@@ -358,7 +376,7 @@ const downloadImportLib = async () => {
358
376
  // either the default options or whatever was passed in
359
377
  if (!configs.size) {
360
378
  node = true;
361
- const DEFAULT = ['-Dshowdown', '-Dlog', '-Dchance', '-Dcalc'];
379
+ const DEFAULT = ['-Dshowdown'];
362
380
  configs.set('node', {type: 'node', options: options || DEFAULT});
363
381
  configs.set('wasm', {type: 'wasm', options: options || DEFAULT});
364
382
  }
@@ -370,8 +388,10 @@ const downloadImportLib = async () => {
370
388
  const args = ['build', '-p', 'build', ...opts];
371
389
  if (!process.env.DEBUG_PKMN_ENGINE) args.push('-Doptimize=ReleaseFast', '-Dstrip');
372
390
  if (config.type === 'node') {
373
- args.push(`-Dnode-headers=${headers}`);
374
- if (process.platform === 'win32') args.push(`-Dnode-import-library=${lib}`);
391
+ args.push(`-Dnode-headers=${path.relative(ROOT, headers)}`);
392
+ if (process.platform === 'win32') {
393
+ args.push(`-Dnode-import-library=${path.relative(ROOT, lib)}`);
394
+ }
375
395
  } else {
376
396
  args.push('-Dwasm');
377
397
  }
@@ -386,8 +406,14 @@ const downloadImportLib = async () => {
386
406
  const prefix = process.platform === 'win32' ? '' : 'lib';
387
407
  const ext = process.platform === 'darwin'
388
408
  ? 'dylib' : process.platform === 'win32' ? 'dll' : 'so';
389
- const actual = path.join('build', 'lib', `${prefix}pkmn${suffix}.node.${ext}`);
390
- fs.renameSync(path.join(ROOT, actual), path.join(ROOT, artifact));
409
+ try {
410
+ const actual = path.join(ROOT, 'build', 'lib', `${prefix}pkmn${suffix}.node.${ext}`);
411
+ fs.renameSync(actual, artifact);
412
+ } catch {
413
+ // ziglang/zig#19743 changed this path
414
+ const actual = path.join(ROOT, 'build', 'bin', `${prefix}pkmn${suffix}.node.${ext}`);
415
+ fs.renameSync(actual, artifact);
416
+ }
391
417
  }
392
418
  }
393
419
  })().catch(e => {
@@ -15,7 +15,7 @@ const ROOT = resolve(__dirname, '..', '..');
15
15
  const packageJSON = JSON.parse(readFileSync(join(ROOT, 'package.json'), 'utf8'));
16
16
 
17
17
  const missing = [];
18
- for (const dep of ['@pkmn/img', 'html-minifier', 'mustache']) {
18
+ for (const dep of ['@pkmn/img', 'html-minifier', 'esbuild']) {
19
19
  try {
20
20
  require.resolve(dep);
21
21
  } catch (e) {
@@ -0,0 +1,200 @@
1
+ const pkmn = @import("../pkmn.zig");
2
+ const std = @import("std");
3
+
4
+ const assert = std.debug.assert;
5
+
6
+ const ERROR: u8 = 0b1100;
7
+
8
+ pub const OPTIONS: extern struct {
9
+ showdown: bool,
10
+ log: bool,
11
+ chance: bool,
12
+ calc: bool,
13
+ } = .{
14
+ .showdown = pkmn.options.showdown,
15
+ .log = pkmn.options.log,
16
+ .chance = pkmn.options.chance,
17
+ .calc = pkmn.options.calc,
18
+ };
19
+
20
+ pub const MAX_CHOICES = pkmn.MAX_CHOICES;
21
+ pub const CHOICES_SIZE = pkmn.CHOICES_SIZE;
22
+ pub const MAX_LOGS = pkmn.MAX_LOGS;
23
+ pub const LOGS_SIZE = pkmn.LOGS_SIZE;
24
+
25
+ pub fn choice_init(choice: u8, data: u8) callconv(.c) u8 {
26
+ assert(choice <= @typeInfo(pkmn.Choice.Type).@"enum".fields.len);
27
+ assert(data <= 6);
28
+ return @bitCast(pkmn.Choice{ .type = @enumFromInt(choice), .data = @intCast(data) });
29
+ }
30
+
31
+ pub fn choice_type(choice: u8) callconv(.c) u8 {
32
+ return @intFromEnum(@as(pkmn.Choice, @bitCast(choice)).type);
33
+ }
34
+
35
+ pub fn choice_data(choice: u8) callconv(.c) u8 {
36
+ return @as(u8, @as(pkmn.Choice, @bitCast(choice)).data);
37
+ }
38
+
39
+ pub fn result_type(result: u8) callconv(.c) u8 {
40
+ return @intFromEnum(@as(pkmn.Result, @bitCast(result)).type);
41
+ }
42
+
43
+ pub fn result_p1(result: u8) callconv(.c) u8 {
44
+ assert(!err(result));
45
+ return @intFromEnum(@as(pkmn.Result, @bitCast(result)).p1);
46
+ }
47
+
48
+ pub fn result_p2(result: u8) callconv(.c) u8 {
49
+ assert(!err(result));
50
+ return @intFromEnum(@as(pkmn.Result, @bitCast(result)).p2);
51
+ }
52
+
53
+ pub fn err(result: u8) callconv(.c) bool {
54
+ return result == ERROR;
55
+ }
56
+
57
+ pub fn psrng_init(prng: *pkmn.PSRNG, seed: u64) callconv(.c) void {
58
+ prng.src = .{ .seed = seed };
59
+ }
60
+
61
+ pub fn psrng_next(prng: *pkmn.PSRNG) callconv(.c) u32 {
62
+ return prng.next();
63
+ }
64
+
65
+ pub fn rational_init(rational: *pkmn.Rational(f64)) callconv(.c) void {
66
+ rational.reset();
67
+ }
68
+
69
+ pub fn rational_reduce(rational: *pkmn.Rational(f64)) callconv(.c) void {
70
+ rational.reduce();
71
+ }
72
+
73
+ pub fn rational_numerator(rational: *const pkmn.Rational(f64)) callconv(.c) f64 {
74
+ return rational.p;
75
+ }
76
+
77
+ pub fn rational_denominator(rational: *const pkmn.Rational(f64)) callconv(.c) f64 {
78
+ return rational.q;
79
+ }
80
+
81
+ const log_options = extern struct {
82
+ buf: [*]u8,
83
+ len: usize,
84
+ };
85
+
86
+ pub fn gen(comptime num: comptime_int) type {
87
+ const g = @field(pkmn, "gen" ++ std.fmt.comptimePrint("{d}", .{num}));
88
+
89
+ return struct {
90
+ pub const MAX_CHOICES = g.MAX_CHOICES;
91
+ pub const CHOICES_SIZE = g.CHOICES_SIZE;
92
+ pub const MAX_LOGS = g.MAX_LOGS;
93
+ pub const LOGS_SIZE = g.LOGS_SIZE;
94
+
95
+ const chance_options = extern struct {
96
+ probability: pkmn.Rational(f64),
97
+ actions: g.chance.Actions,
98
+ durations: g.chance.Durations,
99
+ };
100
+
101
+ const calc_options = extern struct {
102
+ overrides: g.chance.Actions,
103
+ };
104
+
105
+ const battle_options = struct {
106
+ writer: pkmn.protocol.Writer,
107
+ log: pkmn.protocol.FixedLog,
108
+ chance: g.Chance(pkmn.Rational(f64)),
109
+ calc: g.Calc,
110
+
111
+ comptime {
112
+ assert(@sizeOf(battle_options) <= 128);
113
+ }
114
+ };
115
+
116
+ pub fn battle_options_set(
117
+ options: *battle_options,
118
+ log: ?*const log_options,
119
+ chance: ?*const chance_options,
120
+ calc: ?*const calc_options,
121
+ ) callconv(.c) void {
122
+ if (pkmn.options.log) {
123
+ if (log) |l| {
124
+ options.writer = .{ .buffer = l.buf[0..l.len] };
125
+ options.log = .{ .writer = &options.writer };
126
+ } else {
127
+ options.writer.reset();
128
+ }
129
+ }
130
+ if (pkmn.options.chance) {
131
+ if (chance) |c| {
132
+ options.chance = .{
133
+ .probability = c.probability,
134
+ .actions = c.actions,
135
+ .durations = c.durations,
136
+ };
137
+ } else {
138
+ options.chance.reset();
139
+ }
140
+ }
141
+ if (pkmn.options.calc) {
142
+ if (calc) |c| {
143
+ options.calc = .{ .overrides = c.overrides };
144
+ } else {
145
+ options.calc = .{};
146
+ }
147
+ }
148
+ }
149
+
150
+ pub fn battle_options_chance_probability(
151
+ options: *battle_options,
152
+ ) callconv(.c) *pkmn.Rational(f64) {
153
+ return &options.chance.probability;
154
+ }
155
+
156
+ pub fn battle_options_chance_actions(
157
+ options: *battle_options,
158
+ ) callconv(.c) *g.chance.Actions {
159
+ return &options.chance.actions;
160
+ }
161
+
162
+ pub fn battle_options_chance_durations(
163
+ options: *battle_options,
164
+ ) callconv(.c) *g.chance.Durations {
165
+ return &options.chance.durations;
166
+ }
167
+
168
+ pub fn battle_options_calc_summaries(
169
+ options: *battle_options,
170
+ ) callconv(.c) *g.calc.Summaries {
171
+ return &options.calc.summaries;
172
+ }
173
+
174
+ pub fn battle_update(
175
+ battle: *g.Battle(g.PRNG),
176
+ c1: pkmn.Choice,
177
+ c2: pkmn.Choice,
178
+ opts: ?*battle_options,
179
+ ) callconv(.c) pkmn.Result {
180
+ if ((pkmn.options.log or pkmn.options.chance or pkmn.options.calc) and opts != null) {
181
+ return battle.update(c1, c2, opts.?) catch return @bitCast(ERROR);
182
+ }
183
+ return battle.update(c1, c2, &g.NULL) catch unreachable;
184
+ }
185
+
186
+ pub fn battle_choices(
187
+ battle: *const g.Battle(g.PRNG),
188
+ player: u8,
189
+ request: u8,
190
+ out: [*]u8,
191
+ n: usize,
192
+ ) callconv(.c) u8 {
193
+ assert(player <= @typeInfo(pkmn.Player).@"enum".fields.len);
194
+ assert(request <= @typeInfo(pkmn.Choice.Type).@"enum".fields.len);
195
+
196
+ assert(!pkmn.options.showdown or n > 0);
197
+ return battle.choices(@enumFromInt(player), @enumFromInt(request), @ptrCast(out[0..n]));
198
+ }
199
+ };
200
+ }