@pkmn/engine 0.1.0-dev.c5fe6d07 → 0.1.0-dev.ce4c0b2a
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 +43 -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 +96 -0
- package/build/pkg/addon/node.js.map +1 -0
- package/build/pkg/addon.d.ts +2 -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 +128 -0
- package/build/tools/display/debug.jsx.map +1 -0
- package/build/tools/display/index.js +132 -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 +230 -99
- package/package.json +63 -30
- 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 +11 -6
- 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 +807 -327
- package/src/lib/common/rational.zig +125 -31
- package/src/lib/common/rng.zig +22 -13
- package/src/lib/common/util.zig +50 -1
- package/src/lib/gen1/calc.zig +660 -137
- package/src/lib/gen1/chance.zig +409 -284
- package/src/lib/gen1/data/moves.zig +192 -180
- package/src/lib/gen1/data/species.zig +3 -3
- package/src/lib/gen1/data/types.zig +7 -7
- package/src/lib/gen1/data.zig +48 -59
- package/src/lib/gen1/helpers.zig +94 -552
- package/src/lib/gen1/mechanics.zig +580 -518
- package/src/lib/gen2/calc.zig +161 -0
- package/src/lib/gen2/chance.zig +902 -0
- package/src/lib/gen2/data/items.zig +12 -18
- package/src/lib/gen2/data/moves.zig +663 -569
- package/src/lib/gen2/data/species.zig +1 -1
- package/src/lib/gen2/data/types.zig +134 -31
- package/src/lib/gen2/data.zig +107 -79
- package/src/lib/gen2/generated.zig +806 -0
- package/src/lib/gen2/helpers.zig +49 -25
- package/src/lib/gen2/mechanics.zig +3560 -12
- package/src/lib/{binding/node.zig → node.zig} +10 -13
- package/src/lib/pkmn.zig +32 -15
- package/src/lib/{binding/wasm.zig → wasm.zig} +2 -1
- package/src/tools/display/dom.ts +96 -0
- package/src/tools/display/ui.css +351 -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
|
@@ -2,7 +2,6 @@ const std = @import("std");
|
|
|
2
2
|
|
|
3
3
|
const common = @import("../common/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
6
|
|
|
8
7
|
const gen1 = @import("../gen1/data.zig");
|
|
@@ -11,8 +10,6 @@ const data = @import("data.zig");
|
|
|
11
10
|
|
|
12
11
|
const assert = std.debug.assert;
|
|
13
12
|
|
|
14
|
-
const expectEqual = std.testing.expectEqual;
|
|
15
|
-
|
|
16
13
|
const Choice = common.Choice;
|
|
17
14
|
|
|
18
15
|
const showdown = options.showdown;
|
|
@@ -25,7 +22,8 @@ const Move = data.Move;
|
|
|
25
22
|
const MoveSlot = data.MoveSlot;
|
|
26
23
|
const Species = data.Species;
|
|
27
24
|
const Stats = data.Stats;
|
|
28
|
-
|
|
25
|
+
|
|
26
|
+
const Struct = if (@hasField(std.builtin.Type, "struct")) .@"struct" else .Struct;
|
|
29
27
|
|
|
30
28
|
pub const Options = struct {
|
|
31
29
|
cleric: bool = showdown,
|
|
@@ -48,7 +46,7 @@ pub const Battle = struct {
|
|
|
48
46
|
comptime rolls: anytype,
|
|
49
47
|
p1: []const Pokemon,
|
|
50
48
|
p2: []const Pokemon,
|
|
51
|
-
) data.Battle(rng.FixedRNG(
|
|
49
|
+
) data.Battle(rng.FixedRNG(2, rolls.len)) {
|
|
52
50
|
return .{
|
|
53
51
|
.rng = .{ .rolls = rolls },
|
|
54
52
|
.sides = .{ Side.init(p1), Side.init(p2) },
|
|
@@ -65,17 +63,47 @@ pub const Battle = struct {
|
|
|
65
63
|
};
|
|
66
64
|
|
|
67
65
|
pub fn prng(rand: *PSRNG) data.PRNG {
|
|
68
|
-
// FIXME: what is max range in gen2?
|
|
69
66
|
return .{
|
|
70
67
|
.src = .{
|
|
71
68
|
.seed = if (showdown)
|
|
72
69
|
rand.newSeed()
|
|
73
|
-
else
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
70
|
+
else seed: {
|
|
71
|
+
// GLITCH: The initial RNG seed in Gen II link battles is heavily constrained
|
|
72
|
+
// https://www.smogon.com/forums/threads/rng-in-rby-link-battles.3746779
|
|
73
|
+
var seed = [_]u8{ 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
|
74
|
+
|
|
75
|
+
// Bytes in seed can only range from 0-252, not 0-255
|
|
76
|
+
const max: u8 = 253;
|
|
77
|
+
// Instructions take multiples of 4 cycles to execute
|
|
78
|
+
var timer: u16 = 4 * rand.range(u16, 0, 16384);
|
|
79
|
+
var add: u8 = rand.range(u8, 0, 256);
|
|
80
|
+
var sub: u8 = rand.range(u8, 0, 256);
|
|
81
|
+
var carry: u8 = 0;
|
|
82
|
+
var div: u8 = 0;
|
|
83
|
+
|
|
84
|
+
var i: u8 = 0;
|
|
85
|
+
while (i < seed.len) {
|
|
86
|
+
div = @intCast(timer >> 8);
|
|
87
|
+
// This is effectively @addWithOverflow but with three operands
|
|
88
|
+
const result = @as(u16, add) + @as(u16, div) + @as(u16, carry);
|
|
89
|
+
add = @intCast(result & 255);
|
|
90
|
+
carry = @intFromBool(result > 255);
|
|
91
|
+
timer +%= 44;
|
|
92
|
+
div = @intCast(timer >> 8);
|
|
93
|
+
sub -%= div +% carry;
|
|
94
|
+
|
|
95
|
+
if (sub < max) {
|
|
96
|
+
seed[i] = sub;
|
|
97
|
+
i += 1;
|
|
98
|
+
timer +%= 152;
|
|
99
|
+
carry = 1;
|
|
100
|
+
} else {
|
|
101
|
+
timer +%= 132;
|
|
102
|
+
carry = 0;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
break :seed seed;
|
|
106
|
+
},
|
|
79
107
|
},
|
|
80
108
|
};
|
|
81
109
|
}
|
|
@@ -87,7 +115,7 @@ pub const Side = struct {
|
|
|
87
115
|
|
|
88
116
|
for (0..ps.len) |i| {
|
|
89
117
|
side.pokemon[i] = Pokemon.init(ps[i]);
|
|
90
|
-
|
|
118
|
+
side.pokemon[i].position = @as(u4, @intCast(i)) + 1;
|
|
91
119
|
}
|
|
92
120
|
return side;
|
|
93
121
|
}
|
|
@@ -98,7 +126,7 @@ pub const Side = struct {
|
|
|
98
126
|
|
|
99
127
|
for (0..n) |i| {
|
|
100
128
|
side.pokemon[i] = Pokemon.random(rand, opt);
|
|
101
|
-
side.pokemon[i].position = i + 1;
|
|
129
|
+
side.pokemon[i].position = @as(u4, @intCast(i)) + 1;
|
|
102
130
|
}
|
|
103
131
|
|
|
104
132
|
return side;
|
|
@@ -121,7 +149,7 @@ pub const Pokemon = struct {
|
|
|
121
149
|
var pokemon = data.Pokemon{};
|
|
122
150
|
pokemon.species = p.species;
|
|
123
151
|
const species = Species.get(p.species);
|
|
124
|
-
inline for (@typeInfo(@TypeOf(pokemon.stats))
|
|
152
|
+
inline for (@field(@typeInfo(@TypeOf(pokemon.stats)), @tagName(Struct)).fields) |field| {
|
|
125
153
|
const hp = comptime std.mem.eql(u8, field.name, "hp");
|
|
126
154
|
const spc =
|
|
127
155
|
comptime std.mem.eql(u8, field.name, "spa") or std.mem.eql(u8, field.name, "spd");
|
|
@@ -135,12 +163,9 @@ pub const Pokemon = struct {
|
|
|
135
163
|
}
|
|
136
164
|
assert(p.moves.len > 0 and p.moves.len <= 4);
|
|
137
165
|
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
|
-
};
|
|
166
|
+
pokemon.moves[j].id = m;
|
|
167
|
+
// NB: PP can be at most 61 legally (though can overflow to 63)
|
|
168
|
+
pokemon.moves[j].pp = @intCast(@min(Move.pp(m) / 5 * 8, 61));
|
|
144
169
|
}
|
|
145
170
|
pokemon.item = p.item;
|
|
146
171
|
if (p.hp) |hp| {
|
|
@@ -151,7 +176,7 @@ pub const Pokemon = struct {
|
|
|
151
176
|
pokemon.status = p.status;
|
|
152
177
|
pokemon.types = species.types;
|
|
153
178
|
pokemon.level = p.level;
|
|
154
|
-
pokemon.dvs = DVs.from(p.dvs);
|
|
179
|
+
pokemon.dvs = DVs.from(p.species, p.dvs);
|
|
155
180
|
return pokemon;
|
|
156
181
|
}
|
|
157
182
|
|
|
@@ -165,7 +190,7 @@ pub const Pokemon = struct {
|
|
|
165
190
|
|
|
166
191
|
var stats: Stats(u16) = .{};
|
|
167
192
|
const dvs = gen1.DVs.random(rand);
|
|
168
|
-
inline for (@typeInfo(@TypeOf(stats))
|
|
193
|
+
inline for (@field(@typeInfo(@TypeOf(stats)), @tagName(Struct)).fields) |field| {
|
|
169
194
|
const hp = std.mem.eql(u8, field.name, "hp");
|
|
170
195
|
const spc = std.mem.eql(u8, field.name, "spa") or std.mem.eql(u8, field.name, "spd");
|
|
171
196
|
@field(stats, field.name) = Stats(u16).calc(
|
|
@@ -192,14 +217,13 @@ pub const Pokemon = struct {
|
|
|
192
217
|
const max_pp: u8 = @intCast(Move.pp(m) + pp_ups * @min(Move.pp(m) / 5, 7));
|
|
193
218
|
ms[i] = .{
|
|
194
219
|
.id = m,
|
|
195
|
-
.pp_ups = pp_ups,
|
|
196
220
|
.pp = if (opt.cleric) max_pp else rand.range(u8, 0, max_pp + 1),
|
|
197
221
|
};
|
|
198
222
|
}
|
|
199
223
|
return .{
|
|
200
224
|
.species = s,
|
|
201
225
|
.types = species.types,
|
|
202
|
-
.dvs = DVs.from(dvs),
|
|
226
|
+
.dvs = DVs.from(s, dvs),
|
|
203
227
|
.level = lvl,
|
|
204
228
|
.stats = stats,
|
|
205
229
|
.hp = if (opt.cleric) stats.hp else rand.range(u16, 0, stats.hp + 1),
|