@pkmn/engine 0.1.0-dev.c5fe6d07 → 0.1.0-dev.cdc837af
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 +46 -19
- package/build/pkg/addon/browser.d.ts +3 -0
- package/build/pkg/addon/browser.js +44 -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 +97 -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 +21 -0
- package/build/pkg/addon/wasm.js.map +1 -0
- package/build/pkg/addon.d.ts +22 -0
- package/build/pkg/addon.js +35 -58
- package/build/pkg/addon.js.map +1 -1
- package/build/pkg/data/ids.json +12 -12
- package/build/pkg/data/layout.json +2 -2
- package/build/pkg/data/protocol.json +69 -12
- package/build/pkg/data.d.ts +27 -5
- package/build/pkg/data.js.map +1 -1
- package/build/pkg/gen1.js +3 -3
- package/build/pkg/gen1.js.map +1 -1
- package/build/pkg/index.d.ts +24 -10
- package/build/pkg/index.js +15 -10
- 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 +36 -68
- package/build/tools/debug.js.map +1 -1
- package/build/tools/display/debug.jsx +141 -0
- package/build/tools/display/debug.jsx.map +1 -0
- package/build/tools/display/index.js +141 -0
- package/build/tools/display/index.js.map +1 -0
- package/build/tools/display/ui.jsx +349 -0
- package/build/tools/display/ui.jsx.map +1 -0
- package/build/tools/display/util.js +18 -0
- package/build/tools/display/util.js.map +1 -0
- package/build.zig +259 -107
- package/package.json +72 -32
- package/src/bin/install-pkmn-engine +29 -19
- package/src/bin/pkmn-debug +1 -1
- package/src/lib/common/array.zig +77 -0
- package/src/lib/common/data.zig +12 -24
- package/src/lib/common/debug.zig +39 -8
- package/src/lib/common/js.zig +4 -2
- package/src/lib/common/optional.zig +21 -10
- package/src/lib/common/options.zig +4 -0
- package/src/lib/common/protocol.zig +808 -332
- package/src/lib/common/rational.zig +132 -36
- package/src/lib/common/rng.zig +22 -15
- package/src/lib/common/util.zig +50 -1
- package/src/lib/gen1/calc.zig +688 -162
- package/src/lib/gen1/chance.zig +436 -295
- 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 +8 -9
- package/src/lib/gen1/data.zig +55 -70
- package/src/lib/gen1/helpers.zig +91 -562
- package/src/lib/gen1/mechanics.zig +610 -561
- package/src/lib/gen2/calc.zig +153 -0
- package/src/lib/gen2/chance.zig +902 -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 +135 -33
- package/src/lib/gen2/data.zig +115 -91
- package/src/lib/gen2/generated.zig +801 -0
- package/src/lib/gen2/helpers.zig +54 -37
- package/src/lib/gen2/mechanics.zig +3569 -29
- package/src/lib/{binding/node.zig → node.zig} +9 -14
- package/src/lib/pkmn.zig +36 -15
- package/src/lib/{binding/wasm.zig → wasm.zig} +1 -1
- package/src/tools/display/dom.ts +96 -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/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,22 @@
|
|
|
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
|
-
|
|
18
|
+
|
|
19
|
+
const Struct = if (@hasField(std.builtin.Type, "struct")) .@"struct" else .Struct;
|
|
29
20
|
|
|
30
21
|
pub const Options = struct {
|
|
31
22
|
cleric: bool = showdown,
|
|
@@ -48,7 +39,7 @@ pub const Battle = struct {
|
|
|
48
39
|
comptime rolls: anytype,
|
|
49
40
|
p1: []const Pokemon,
|
|
50
41
|
p2: []const Pokemon,
|
|
51
|
-
) data.Battle(rng.FixedRNG(
|
|
42
|
+
) data.Battle(rng.FixedRNG(2, rolls.len)) {
|
|
52
43
|
return .{
|
|
53
44
|
.rng = .{ .rolls = rolls },
|
|
54
45
|
.sides = .{ Side.init(p1), Side.init(p2) },
|
|
@@ -65,17 +56,47 @@ pub const Battle = struct {
|
|
|
65
56
|
};
|
|
66
57
|
|
|
67
58
|
pub fn prng(rand: *PSRNG) data.PRNG {
|
|
68
|
-
// FIXME: what is max range in gen2?
|
|
69
59
|
return .{
|
|
70
60
|
.src = .{
|
|
71
61
|
.seed = if (showdown)
|
|
72
62
|
rand.newSeed()
|
|
73
|
-
else
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
63
|
+
else seed: {
|
|
64
|
+
// GLITCH: The initial RNG seed in Gen II link battles is heavily constrained
|
|
65
|
+
// https://www.smogon.com/forums/threads/rng-in-rby-link-battles.3746779
|
|
66
|
+
var seed = [_]u8{ 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
|
67
|
+
|
|
68
|
+
// Bytes in seed can only range from 0-252, not 0-255
|
|
69
|
+
const max: u8 = 253;
|
|
70
|
+
// Instructions take multiples of 4 cycles to execute
|
|
71
|
+
var timer: u16 = 4 * rand.range(u16, 0, 16384);
|
|
72
|
+
var add: u8 = rand.range(u8, 0, 256);
|
|
73
|
+
var sub: u8 = rand.range(u8, 0, 256);
|
|
74
|
+
var carry: u8 = 0;
|
|
75
|
+
var div: u8 = 0;
|
|
76
|
+
|
|
77
|
+
var i: u8 = 0;
|
|
78
|
+
while (i < seed.len) {
|
|
79
|
+
div = @intCast(timer >> 8);
|
|
80
|
+
// This is effectively @addWithOverflow but with three operands
|
|
81
|
+
const result = @as(u16, add) + @as(u16, div) + @as(u16, carry);
|
|
82
|
+
add = @intCast(result & 255);
|
|
83
|
+
carry = @intFromBool(result > 255);
|
|
84
|
+
timer +%= 44;
|
|
85
|
+
div = @intCast(timer >> 8);
|
|
86
|
+
sub -%= div +% carry;
|
|
87
|
+
|
|
88
|
+
if (sub < max) {
|
|
89
|
+
seed[i] = sub;
|
|
90
|
+
i += 1;
|
|
91
|
+
timer +%= 152;
|
|
92
|
+
carry = 1;
|
|
93
|
+
} else {
|
|
94
|
+
timer +%= 132;
|
|
95
|
+
carry = 0;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
break :seed seed;
|
|
99
|
+
},
|
|
79
100
|
},
|
|
80
101
|
};
|
|
81
102
|
}
|
|
@@ -87,7 +108,7 @@ pub const Side = struct {
|
|
|
87
108
|
|
|
88
109
|
for (0..ps.len) |i| {
|
|
89
110
|
side.pokemon[i] = Pokemon.init(ps[i]);
|
|
90
|
-
|
|
111
|
+
side.pokemon[i].position = @as(u4, @intCast(i)) + 1;
|
|
91
112
|
}
|
|
92
113
|
return side;
|
|
93
114
|
}
|
|
@@ -98,7 +119,7 @@ pub const Side = struct {
|
|
|
98
119
|
|
|
99
120
|
for (0..n) |i| {
|
|
100
121
|
side.pokemon[i] = Pokemon.random(rand, opt);
|
|
101
|
-
side.pokemon[i].position = i + 1;
|
|
122
|
+
side.pokemon[i].position = @as(u4, @intCast(i)) + 1;
|
|
102
123
|
}
|
|
103
124
|
|
|
104
125
|
return side;
|
|
@@ -121,7 +142,7 @@ pub const Pokemon = struct {
|
|
|
121
142
|
var pokemon = data.Pokemon{};
|
|
122
143
|
pokemon.species = p.species;
|
|
123
144
|
const species = Species.get(p.species);
|
|
124
|
-
inline for (@typeInfo(@TypeOf(pokemon.stats))
|
|
145
|
+
inline for (@field(@typeInfo(@TypeOf(pokemon.stats)), @tagName(Struct)).fields) |field| {
|
|
125
146
|
const hp = comptime std.mem.eql(u8, field.name, "hp");
|
|
126
147
|
const spc =
|
|
127
148
|
comptime std.mem.eql(u8, field.name, "spa") or std.mem.eql(u8, field.name, "spd");
|
|
@@ -135,12 +156,9 @@ pub const Pokemon = struct {
|
|
|
135
156
|
}
|
|
136
157
|
assert(p.moves.len > 0 and p.moves.len <= 4);
|
|
137
158
|
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
|
-
};
|
|
159
|
+
pokemon.moves[j].id = m;
|
|
160
|
+
// NB: PP can be at most 61 legally (though can overflow to 63)
|
|
161
|
+
pokemon.moves[j].pp = @intCast(@min(Move.pp(m) / 5 * 8, 61));
|
|
144
162
|
}
|
|
145
163
|
pokemon.item = p.item;
|
|
146
164
|
if (p.hp) |hp| {
|
|
@@ -151,7 +169,7 @@ pub const Pokemon = struct {
|
|
|
151
169
|
pokemon.status = p.status;
|
|
152
170
|
pokemon.types = species.types;
|
|
153
171
|
pokemon.level = p.level;
|
|
154
|
-
pokemon.dvs = DVs.from(p.dvs);
|
|
172
|
+
pokemon.dvs = DVs.from(p.species, p.dvs);
|
|
155
173
|
return pokemon;
|
|
156
174
|
}
|
|
157
175
|
|
|
@@ -165,7 +183,7 @@ pub const Pokemon = struct {
|
|
|
165
183
|
|
|
166
184
|
var stats: Stats(u16) = .{};
|
|
167
185
|
const dvs = gen1.DVs.random(rand);
|
|
168
|
-
inline for (@typeInfo(@TypeOf(stats))
|
|
186
|
+
inline for (@field(@typeInfo(@TypeOf(stats)), @tagName(Struct)).fields) |field| {
|
|
169
187
|
const hp = std.mem.eql(u8, field.name, "hp");
|
|
170
188
|
const spc = std.mem.eql(u8, field.name, "spa") or std.mem.eql(u8, field.name, "spd");
|
|
171
189
|
@field(stats, field.name) = Stats(u16).calc(
|
|
@@ -192,14 +210,13 @@ pub const Pokemon = struct {
|
|
|
192
210
|
const max_pp: u8 = @intCast(Move.pp(m) + pp_ups * @min(Move.pp(m) / 5, 7));
|
|
193
211
|
ms[i] = .{
|
|
194
212
|
.id = m,
|
|
195
|
-
.pp_ups = pp_ups,
|
|
196
213
|
.pp = if (opt.cleric) max_pp else rand.range(u8, 0, max_pp + 1),
|
|
197
214
|
};
|
|
198
215
|
}
|
|
199
216
|
return .{
|
|
200
217
|
.species = s,
|
|
201
218
|
.types = species.types,
|
|
202
|
-
.dvs = DVs.from(dvs),
|
|
219
|
+
.dvs = DVs.from(s, dvs),
|
|
203
220
|
.level = lvl,
|
|
204
221
|
.stats = stats,
|
|
205
222
|
.hp = if (opt.cleric) stats.hp else rand.range(u16, 0, stats.hp + 1),
|