@pkmn/engine 0.1.0-dev.f3aaee39 → 0.1.0-dev.f3b63b86
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 +1 -3
- package/README.md +77 -23
- package/build/pkg/addon/browser.d.ts +3 -0
- package/build/pkg/addon/browser.js +47 -0
- package/build/pkg/addon/browser.js.map +1 -0
- package/build/pkg/addon/node.d.ts +3 -0
- package/build/pkg/addon/node.js +110 -0
- package/build/pkg/addon/node.js.map +1 -0
- package/build/pkg/addon/wasm.d.ts +2 -0
- package/build/pkg/addon/wasm.js +53 -0
- package/build/pkg/addon/wasm.js.map +1 -0
- package/build/pkg/addon.d.ts +26 -4
- package/build/pkg/addon.js +39 -71
- package/build/pkg/addon.js.map +1 -1
- package/build/pkg/data/ids.json +12 -12
- package/build/pkg/data/layout.json +17 -4
- package/build/pkg/data/protocol.json +84 -13
- package/build/pkg/data.d.ts +27 -5
- package/build/pkg/data.js.map +1 -1
- package/build/pkg/gen1.d.ts +15 -18
- package/build/pkg/gen1.js +30 -21
- package/build/pkg/gen1.js.map +1 -1
- package/build/pkg/index.d.ts +42 -91
- package/build/pkg/index.js +23 -70
- package/build/pkg/index.js.map +1 -1
- package/build/pkg/protocol.d.ts +20 -1
- package/build/pkg/protocol.js +123 -102
- package/build/pkg/protocol.js.map +1 -1
- package/build/tools/debug.js +69 -74
- package/build/tools/debug.js.map +1 -1
- package/build/tools/display/debug.jsx +152 -0
- package/build/tools/display/debug.jsx.map +1 -0
- package/build/tools/display/index.js +152 -0
- package/build/tools/display/index.js.map +1 -0
- package/build/tools/display/ui.jsx +359 -0
- package/build/tools/display/ui.jsx.map +1 -0
- package/build/tools/display/util.js +33 -0
- package/build/tools/display/util.js.map +1 -0
- package/build.zig +273 -120
- package/package.json +64 -123
- package/src/bin/install-pkmn-engine +47 -21
- package/src/bin/pkmn-debug +1 -1
- package/src/lib/bindings/c.zig +200 -0
- package/src/lib/{binding → bindings}/node.zig +15 -32
- package/src/lib/bindings/wasm.zig +50 -0
- package/src/lib/common/array.zig +70 -0
- package/src/lib/common/data.zig +12 -24
- package/src/lib/common/debug.zig +32 -11
- package/src/lib/common/js.zig +3 -7
- package/src/lib/common/optional.zig +19 -18
- package/src/lib/common/options.zig +6 -0
- package/src/lib/common/protocol.zig +919 -430
- package/src/lib/common/rational.zig +341 -254
- package/src/lib/common/rng.zig +22 -15
- package/src/lib/common/util.zig +33 -1
- package/src/lib/gen1/calc.zig +706 -177
- package/src/lib/gen1/chance.zig +428 -302
- package/src/lib/gen1/data/moves.zig +193 -183
- package/src/lib/gen1/data/species.zig +4 -6
- package/src/lib/gen1/data/types.zig +9 -10
- package/src/lib/gen1/data.zig +60 -75
- package/src/lib/gen1/helpers.zig +90 -563
- package/src/lib/gen1/mechanics.zig +682 -600
- package/src/lib/gen2/calc.zig +150 -0
- package/src/lib/gen2/chance.zig +896 -0
- package/src/lib/gen2/data/items.zig +13 -21
- package/src/lib/gen2/data/moves.zig +664 -572
- package/src/lib/gen2/data/species.zig +2 -4
- package/src/lib/gen2/data/types.zig +139 -34
- package/src/lib/gen2/data.zig +121 -96
- package/src/lib/gen2/generated.zig +801 -0
- package/src/lib/gen2/helpers.zig +53 -38
- package/src/lib/gen2/mechanics.zig +3580 -29
- package/src/lib/napi.h +2 -0
- package/src/lib/node.zig +14 -0
- package/src/lib/pkmn.zig +125 -29
- package/src/lib/wasm.zig +13 -0
- package/src/tools/display/dom.ts +93 -0
- package/src/tools/display/ui.css +354 -0
- package/build/test/display.js +0 -400
- package/build/test/display.js.map +0 -1
- package/src/lib/binding/wasm.zig +0 -12
- package/src/lib/gen1/README.md +0 -892
- package/src/lib/gen2/README.md +0 -308
- package/src/test/display/pkmn.html.tmpl +0 -368
package/src/lib/gen2/helpers.zig
CHANGED
|
@@ -1,31 +1,20 @@
|
|
|
1
|
-
const std = @import("std");
|
|
2
|
-
|
|
3
1
|
const common = @import("../common/data.zig");
|
|
2
|
+
const data = @import("data.zig");
|
|
3
|
+
const gen1 = @import("../gen1/data.zig");
|
|
4
4
|
const options = @import("../common/options.zig");
|
|
5
|
-
const protocol = @import("../common/protocol.zig");
|
|
6
5
|
const rng = @import("../common/rng.zig");
|
|
7
|
-
|
|
8
|
-
const gen1 = @import("../gen1/data.zig");
|
|
9
|
-
|
|
10
|
-
const data = @import("data.zig");
|
|
6
|
+
const std = @import("std");
|
|
11
7
|
|
|
12
8
|
const assert = std.debug.assert;
|
|
13
|
-
|
|
14
|
-
const expectEqual = std.testing.expectEqual;
|
|
15
|
-
|
|
16
9
|
const Choice = common.Choice;
|
|
17
|
-
|
|
18
|
-
const showdown = options.showdown;
|
|
19
|
-
|
|
20
|
-
const PSRNG = rng.PSRNG;
|
|
21
|
-
|
|
22
10
|
const DVs = data.DVs;
|
|
23
11
|
const Item = data.Item;
|
|
24
12
|
const Move = data.Move;
|
|
25
13
|
const MoveSlot = data.MoveSlot;
|
|
14
|
+
const PSRNG = rng.PSRNG;
|
|
15
|
+
const showdown = options.showdown;
|
|
26
16
|
const Species = data.Species;
|
|
27
17
|
const Stats = data.Stats;
|
|
28
|
-
const Status = data.Status;
|
|
29
18
|
|
|
30
19
|
pub const Options = struct {
|
|
31
20
|
cleric: bool = showdown,
|
|
@@ -48,7 +37,7 @@ pub const Battle = struct {
|
|
|
48
37
|
comptime rolls: anytype,
|
|
49
38
|
p1: []const Pokemon,
|
|
50
39
|
p2: []const Pokemon,
|
|
51
|
-
) data.Battle(rng.FixedRNG(
|
|
40
|
+
) data.Battle(rng.FixedRNG(2, rolls.len)) {
|
|
52
41
|
return .{
|
|
53
42
|
.rng = .{ .rolls = rolls },
|
|
54
43
|
.sides = .{ Side.init(p1), Side.init(p2) },
|
|
@@ -65,17 +54,47 @@ pub const Battle = struct {
|
|
|
65
54
|
};
|
|
66
55
|
|
|
67
56
|
pub fn prng(rand: *PSRNG) data.PRNG {
|
|
68
|
-
// FIXME: what is max range in gen2?
|
|
69
57
|
return .{
|
|
70
58
|
.src = .{
|
|
71
59
|
.seed = if (showdown)
|
|
72
60
|
rand.newSeed()
|
|
73
|
-
else
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
61
|
+
else seed: {
|
|
62
|
+
// GLITCH: The initial RNG seed in Gen II link battles is heavily constrained
|
|
63
|
+
// https://www.smogon.com/forums/threads/rng-in-rby-link-battles.3746779
|
|
64
|
+
var seed = [_]u8{ 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
|
65
|
+
|
|
66
|
+
// Bytes in seed can only range from 0-252, not 0-255
|
|
67
|
+
const max: u8 = 253;
|
|
68
|
+
// Instructions take multiples of 4 cycles to execute
|
|
69
|
+
var timer: u16 = 4 * rand.range(u16, 0, 16384);
|
|
70
|
+
var add: u8 = rand.range(u8, 0, 256);
|
|
71
|
+
var sub: u8 = rand.range(u8, 0, 256);
|
|
72
|
+
var carry: u8 = 0;
|
|
73
|
+
var div: u8 = 0;
|
|
74
|
+
|
|
75
|
+
var i: usize = 0;
|
|
76
|
+
while (i < seed.len) {
|
|
77
|
+
div = @intCast(timer >> 8);
|
|
78
|
+
// This is effectively @addWithOverflow but with three operands
|
|
79
|
+
const result = @as(u16, add) + @as(u16, div) + @as(u16, carry);
|
|
80
|
+
add = @intCast(result & 255);
|
|
81
|
+
carry = @intFromBool(result > 255);
|
|
82
|
+
timer +%= 44;
|
|
83
|
+
div = @intCast(timer >> 8);
|
|
84
|
+
sub -%= div +% carry;
|
|
85
|
+
|
|
86
|
+
if (sub < max) {
|
|
87
|
+
seed[i] = sub;
|
|
88
|
+
i += 1;
|
|
89
|
+
timer +%= 152;
|
|
90
|
+
carry = 1;
|
|
91
|
+
} else {
|
|
92
|
+
timer +%= 132;
|
|
93
|
+
carry = 0;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
break :seed seed;
|
|
97
|
+
},
|
|
79
98
|
},
|
|
80
99
|
};
|
|
81
100
|
}
|
|
@@ -87,7 +106,7 @@ pub const Side = struct {
|
|
|
87
106
|
|
|
88
107
|
for (0..ps.len) |i| {
|
|
89
108
|
side.pokemon[i] = Pokemon.init(ps[i]);
|
|
90
|
-
|
|
109
|
+
side.pokemon[i].position = @as(u4, @intCast(i)) + 1;
|
|
91
110
|
}
|
|
92
111
|
return side;
|
|
93
112
|
}
|
|
@@ -98,7 +117,7 @@ pub const Side = struct {
|
|
|
98
117
|
|
|
99
118
|
for (0..n) |i| {
|
|
100
119
|
side.pokemon[i] = Pokemon.random(rand, opt);
|
|
101
|
-
side.pokemon[i].position = i + 1;
|
|
120
|
+
side.pokemon[i].position = @as(u4, @intCast(i)) + 1;
|
|
102
121
|
}
|
|
103
122
|
|
|
104
123
|
return side;
|
|
@@ -121,7 +140,7 @@ pub const Pokemon = struct {
|
|
|
121
140
|
var pokemon = data.Pokemon{};
|
|
122
141
|
pokemon.species = p.species;
|
|
123
142
|
const species = Species.get(p.species);
|
|
124
|
-
inline for (@typeInfo(@TypeOf(pokemon.stats)).
|
|
143
|
+
inline for (@typeInfo(@TypeOf(pokemon.stats)).@"struct".fields) |field| {
|
|
125
144
|
const hp = comptime std.mem.eql(u8, field.name, "hp");
|
|
126
145
|
const spc =
|
|
127
146
|
comptime std.mem.eql(u8, field.name, "spa") or std.mem.eql(u8, field.name, "spd");
|
|
@@ -135,12 +154,9 @@ pub const Pokemon = struct {
|
|
|
135
154
|
}
|
|
136
155
|
assert(p.moves.len > 0 and p.moves.len <= 4);
|
|
137
156
|
for (p.moves, 0..) |m, j| {
|
|
138
|
-
pokemon.moves[j] =
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
// NB: PP can be at most 61 legally (though can overflow to 63)
|
|
142
|
-
.pp = @intCast(@min(Move.pp(m) / 5 * 8, 61)),
|
|
143
|
-
};
|
|
157
|
+
pokemon.moves[j].id = m;
|
|
158
|
+
// NB: PP can be at most 61 legally (though can overflow to 63)
|
|
159
|
+
pokemon.moves[j].pp = @intCast(@min(Move.pp(m) / 5 * 8, 61));
|
|
144
160
|
}
|
|
145
161
|
pokemon.item = p.item;
|
|
146
162
|
if (p.hp) |hp| {
|
|
@@ -151,7 +167,7 @@ pub const Pokemon = struct {
|
|
|
151
167
|
pokemon.status = p.status;
|
|
152
168
|
pokemon.types = species.types;
|
|
153
169
|
pokemon.level = p.level;
|
|
154
|
-
pokemon.dvs = DVs.from(p.dvs);
|
|
170
|
+
pokemon.dvs = DVs.from(p.species, p.dvs);
|
|
155
171
|
return pokemon;
|
|
156
172
|
}
|
|
157
173
|
|
|
@@ -165,7 +181,7 @@ pub const Pokemon = struct {
|
|
|
165
181
|
|
|
166
182
|
var stats: Stats(u16) = .{};
|
|
167
183
|
const dvs = gen1.DVs.random(rand);
|
|
168
|
-
inline for (@typeInfo(@TypeOf(stats)).
|
|
184
|
+
inline for (@typeInfo(@TypeOf(stats)).@"struct".fields) |field| {
|
|
169
185
|
const hp = std.mem.eql(u8, field.name, "hp");
|
|
170
186
|
const spc = std.mem.eql(u8, field.name, "spa") or std.mem.eql(u8, field.name, "spd");
|
|
171
187
|
@field(stats, field.name) = Stats(u16).calc(
|
|
@@ -177,7 +193,7 @@ pub const Pokemon = struct {
|
|
|
177
193
|
);
|
|
178
194
|
}
|
|
179
195
|
|
|
180
|
-
var ms
|
|
196
|
+
var ms: [4]MoveSlot = @splat(.{});
|
|
181
197
|
const n = if (rand.chance(u8, 1, 100)) rand.range(u4, 1, 3 + 1) else 4;
|
|
182
198
|
for (0..n) |i| {
|
|
183
199
|
var m: Move = .None;
|
|
@@ -192,14 +208,13 @@ pub const Pokemon = struct {
|
|
|
192
208
|
const max_pp: u8 = @intCast(Move.pp(m) + pp_ups * @min(Move.pp(m) / 5, 7));
|
|
193
209
|
ms[i] = .{
|
|
194
210
|
.id = m,
|
|
195
|
-
.pp_ups = pp_ups,
|
|
196
211
|
.pp = if (opt.cleric) max_pp else rand.range(u8, 0, max_pp + 1),
|
|
197
212
|
};
|
|
198
213
|
}
|
|
199
214
|
return .{
|
|
200
215
|
.species = s,
|
|
201
216
|
.types = species.types,
|
|
202
|
-
.dvs = DVs.from(dvs),
|
|
217
|
+
.dvs = DVs.from(s, dvs),
|
|
203
218
|
.level = lvl,
|
|
204
219
|
.stats = stats,
|
|
205
220
|
.hp = if (opt.cleric) stats.hp else rand.range(u16, 0, stats.hp + 1),
|