@pkmn/engine 0.1.0-dev.028ab165 → 0.1.0-dev.047d6e71
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 +32 -9
- package/build/pkg/addon.js.map +1 -1
- package/build/pkg/data.d.ts +3 -2
- package/build/pkg/data.js.map +1 -1
- package/build/pkg/gen1.js.map +1 -1
- package/build/pkg/index.d.ts +2 -1
- package/build/pkg/index.js.map +1 -1
- package/build/pkg/protocol.js.map +1 -1
- package/build/test/display.js.map +1 -1
- package/build/tools/debug.js.map +1 -1
- package/build.zig +65 -57
- package/package.json +29 -21
- package/src/bin/install-pkmn-engine +14 -14
- package/src/lib/common/data.zig +4 -4
- package/src/lib/common/optional.zig +1 -1
- package/src/lib/common/protocol.zig +67 -72
- package/src/lib/common/rational.zig +7 -3
- package/src/lib/common/rng.zig +11 -11
- package/src/lib/gen1/calc.zig +5 -5
- package/src/lib/gen1/chance.zig +21 -21
- package/src/lib/gen1/data/species.zig +1 -1
- package/src/lib/gen1/data.zig +18 -18
- package/src/lib/gen1/helpers.zig +7 -7
- package/src/lib/gen1/mechanics.zig +57 -31
- package/src/lib/gen2/chance.zig +27 -27
- package/src/lib/gen2/data.zig +9 -9
- package/src/lib/gen2/generated.zig +1 -3
- package/src/lib/gen2/mechanics.zig +132 -51
- package/src/lib/{binding/node.zig → node.zig} +9 -12
- package/src/lib/pkmn.zig +26 -3
- package/src/lib/{binding/wasm.zig → wasm.zig} +2 -1
- package/src/lib/gen1/README.md +0 -894
- package/src/lib/gen2/README.md +0 -329
|
@@ -3,8 +3,8 @@ const builtin = @import("builtin");
|
|
|
3
3
|
|
|
4
4
|
const pkmn = @import("../pkmn.zig");
|
|
5
5
|
|
|
6
|
-
const data = @import("
|
|
7
|
-
const options = @import("
|
|
6
|
+
const data = @import("data.zig");
|
|
7
|
+
const options = @import("options.zig");
|
|
8
8
|
|
|
9
9
|
const assert = std.debug.assert;
|
|
10
10
|
const print = std.debug.print;
|
|
@@ -14,6 +14,8 @@ const enabled = options.log;
|
|
|
14
14
|
const Player = data.Player;
|
|
15
15
|
const ID = data.ID;
|
|
16
16
|
|
|
17
|
+
const endian = builtin.cpu.arch.endian();
|
|
18
|
+
|
|
17
19
|
pub const ArgType = enum(u8) {
|
|
18
20
|
None,
|
|
19
21
|
|
|
@@ -71,7 +73,7 @@ pub const ArgType = enum(u8) {
|
|
|
71
73
|
EndAbility,
|
|
72
74
|
ClearNegativeBoost,
|
|
73
75
|
FormeChange,
|
|
74
|
-
|
|
76
|
+
LastNoTarget, // FIXME
|
|
75
77
|
|
|
76
78
|
// Gen 4
|
|
77
79
|
SwapBoost,
|
|
@@ -218,6 +220,7 @@ pub const Activate = enum(u8) {
|
|
|
218
220
|
BeatUp, // FIXME of
|
|
219
221
|
|
|
220
222
|
Magnitude,
|
|
223
|
+
Spite,
|
|
221
224
|
};
|
|
222
225
|
|
|
223
226
|
pub const Start = enum(u8) {
|
|
@@ -359,8 +362,8 @@ pub fn Log(comptime Writer: type) type {
|
|
|
359
362
|
} else {
|
|
360
363
|
try self.writer.writeAll(&.{ @intFromEnum(args[1].species), args[1].level });
|
|
361
364
|
}
|
|
362
|
-
try self.writer.
|
|
363
|
-
try self.writer.
|
|
365
|
+
try self.writer.writeInt(u16, args[1].hp, endian);
|
|
366
|
+
try self.writer.writeInt(u16, args[1].stats.hp, endian);
|
|
364
367
|
try self.writer.writeAll(&.{args[1].status});
|
|
365
368
|
}
|
|
366
369
|
|
|
@@ -391,7 +394,7 @@ pub fn Log(comptime Writer: type) type {
|
|
|
391
394
|
if (!enabled) return;
|
|
392
395
|
|
|
393
396
|
try self.writer.writeByte(@intFromEnum(ArgType.Turn));
|
|
394
|
-
try self.writer.
|
|
397
|
+
try self.writer.writeInt(u16, args[0], endian);
|
|
395
398
|
try self.writer.writeByte(@intFromEnum(ArgType.None));
|
|
396
399
|
}
|
|
397
400
|
|
|
@@ -423,8 +426,8 @@ pub fn Log(comptime Writer: type) type {
|
|
|
423
426
|
@intFromEnum(ArgType.Damage),
|
|
424
427
|
@as(u8, @bitCast(args[0])),
|
|
425
428
|
});
|
|
426
|
-
try self.writer.
|
|
427
|
-
try self.writer.
|
|
429
|
+
try self.writer.writeInt(u16, args[1].hp, endian);
|
|
430
|
+
try self.writer.writeInt(u16, args[1].stats.hp, endian);
|
|
428
431
|
try self.writer.writeAll(&.{ args[1].status, @intFromEnum(@as(Damage, args[2])) });
|
|
429
432
|
if (args.len == 4) try self.writer.writeByte(@as(u8, @bitCast(args[3])));
|
|
430
433
|
}
|
|
@@ -436,8 +439,8 @@ pub fn Log(comptime Writer: type) type {
|
|
|
436
439
|
|
|
437
440
|
assert(args[2] != .Drain or args.len == 4);
|
|
438
441
|
try self.writer.writeAll(&.{ @intFromEnum(ArgType.Heal), @as(u8, @bitCast(args[0])) });
|
|
439
|
-
try self.writer.
|
|
440
|
-
try self.writer.
|
|
442
|
+
try self.writer.writeInt(u16, args[1].hp, endian);
|
|
443
|
+
try self.writer.writeInt(u16, args[1].stats.hp, endian);
|
|
441
444
|
try self.writer.writeAll(&.{ args[1].status, @intFromEnum(@as(Heal, args[2])) });
|
|
442
445
|
if (args.len == 4) try self.writer.writeByte(@as(u8, @bitCast(args[3])));
|
|
443
446
|
}
|
|
@@ -542,6 +545,7 @@ pub fn Log(comptime Writer: type) type {
|
|
|
542
545
|
// ident: ID, reason: Activate
|
|
543
546
|
// ident: ID, reason: .SubstituteBlock, m: <Move>
|
|
544
547
|
// ident: ID, reason: .Magnitude, num: u8
|
|
548
|
+
// ident: ID, reason: .Spite, m: <Move>, num: u8
|
|
545
549
|
pub fn activate(self: Self, args: anytype) Error!void {
|
|
546
550
|
if (!enabled) return;
|
|
547
551
|
|
|
@@ -559,6 +563,9 @@ pub fn Log(comptime Writer: type) type {
|
|
|
559
563
|
assert(reason == .Magnitude);
|
|
560
564
|
try self.writer.writeByte(args[2]);
|
|
561
565
|
}
|
|
566
|
+
} else if (args.len == 4) {
|
|
567
|
+
assert(reason == .Spite);
|
|
568
|
+
try self.writer.writeAll(&.{ @intFromEnum(args[2]), args[3] });
|
|
562
569
|
}
|
|
563
570
|
}
|
|
564
571
|
|
|
@@ -706,8 +713,8 @@ pub fn Log(comptime Writer: type) type {
|
|
|
706
713
|
if (!enabled) return;
|
|
707
714
|
|
|
708
715
|
try self.writer.writeAll(&.{ @intFromEnum(ArgType.SetHP), @as(u8, @bitCast(args[0])) });
|
|
709
|
-
try self.writer.
|
|
710
|
-
try self.writer.
|
|
716
|
+
try self.writer.writeInt(u16, args[1].hp, endian);
|
|
717
|
+
try self.writer.writeInt(u16, args[1].stats.hp, endian);
|
|
711
718
|
try self.writer.writeAll(&.{args[1].status});
|
|
712
719
|
try self.writer.writeByte(@intFromEnum(@as(SetHP, args[2])));
|
|
713
720
|
}
|
|
@@ -831,10 +838,10 @@ pub const ByteStream = struct {
|
|
|
831
838
|
try self.stream.writeByte(byte);
|
|
832
839
|
}
|
|
833
840
|
|
|
834
|
-
pub fn
|
|
841
|
+
pub fn writeInt(self: Writer, comptime T: type, v: T, end: std.builtin.Endian) Error!void {
|
|
835
842
|
// TODO: rework this to write directly to the buffer?
|
|
836
|
-
var bytes: [(@typeInfo(T).Int.bits
|
|
837
|
-
std.mem.
|
|
843
|
+
var bytes: [@divExact(@typeInfo(T).Int.bits, 8)]u8 = undefined;
|
|
844
|
+
std.mem.writeInt(std.math.ByteAlignedInt(@TypeOf(v)), &bytes, v, end);
|
|
838
845
|
return self.writeAll(&bytes);
|
|
839
846
|
}
|
|
840
847
|
};
|
|
@@ -943,19 +950,19 @@ pub fn format(
|
|
|
943
950
|
if (a[i] == N(gen.Gender.Unknown)) {
|
|
944
951
|
i += 1;
|
|
945
952
|
} else {
|
|
946
|
-
|
|
953
|
+
const gender = if (a[i] == N(gen.Gender.Male)) "M" else "F";
|
|
947
954
|
printc(", {s}", .{gender}, a, b, &i, 1, color);
|
|
948
955
|
}
|
|
949
956
|
}
|
|
950
957
|
printc(" L{d}", .{a[i]}, a, b, &i, 1, color);
|
|
951
958
|
switch (endian) {
|
|
952
|
-
.
|
|
959
|
+
.big => {
|
|
953
960
|
var hp = @as(u16, a[i]) << 8 | @as(u16, a[i + 1]);
|
|
954
961
|
printc(" {d}", .{hp}, a, b, &i, 2, color);
|
|
955
962
|
hp = @as(u16, a[i]) << 8 | @as(u16, a[i + 1]);
|
|
956
963
|
printc("/{d}", .{hp}, a, b, &i, 2, color);
|
|
957
964
|
},
|
|
958
|
-
.
|
|
965
|
+
.little => {
|
|
959
966
|
var hp = @as(u16, a[i + 1]) << 8 | @as(u16, a[i]);
|
|
960
967
|
printc(" {d}", .{hp}, a, b, &i, 2, color);
|
|
961
968
|
hp = @as(u16, a[i + 1]) << 8 | @as(u16, a[i]);
|
|
@@ -986,8 +993,8 @@ pub fn format(
|
|
|
986
993
|
},
|
|
987
994
|
.Turn => {
|
|
988
995
|
const turn = switch (endian) {
|
|
989
|
-
.
|
|
990
|
-
.
|
|
996
|
+
.big => @as(u16, a[i]) << 8 | @as(u16, a[i + 1]),
|
|
997
|
+
.little => @as(u16, a[i + 1]) << 8 | @as(u16, a[i]),
|
|
991
998
|
};
|
|
992
999
|
printc(" {d}", .{turn}, a, b, &i, 2, color);
|
|
993
1000
|
},
|
|
@@ -998,13 +1005,13 @@ pub fn format(
|
|
|
998
1005
|
var id = ID.from(@intCast(a[i]));
|
|
999
1006
|
printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
|
|
1000
1007
|
switch (endian) {
|
|
1001
|
-
.
|
|
1008
|
+
.big => {
|
|
1002
1009
|
var hp = @as(u16, a[i]) << 8 | @as(u16, a[i + 1]);
|
|
1003
1010
|
printc(" {d}", .{hp}, a, b, &i, 2, color);
|
|
1004
1011
|
hp = @as(u16, a[i]) << 8 | @as(u16, a[i + 1]);
|
|
1005
1012
|
printc("/{d}", .{hp}, a, b, &i, 2, color);
|
|
1006
1013
|
},
|
|
1007
|
-
.
|
|
1014
|
+
.little => {
|
|
1008
1015
|
var hp = @as(u16, a[i + 1]) << 8 | @as(u16, a[i]);
|
|
1009
1016
|
printc(" {d}", .{hp}, a, b, &i, 2, color);
|
|
1010
1017
|
hp = @as(u16, a[i + 1]) << 8 | @as(u16, a[i]);
|
|
@@ -1126,13 +1133,13 @@ pub fn format(
|
|
|
1126
1133
|
const id = ID.from(@intCast(a[i]));
|
|
1127
1134
|
printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
|
|
1128
1135
|
switch (endian) {
|
|
1129
|
-
.
|
|
1136
|
+
.big => {
|
|
1130
1137
|
var hp = @as(u16, a[i]) << 8 | @as(u16, a[i + 1]);
|
|
1131
1138
|
printc(" {d}", .{hp}, a, b, &i, 2, color);
|
|
1132
1139
|
hp = @as(u16, a[i]) << 8 | @as(u16, a[i + 1]);
|
|
1133
1140
|
printc("/{d}", .{hp}, a, b, &i, 2, color);
|
|
1134
1141
|
},
|
|
1135
|
-
.
|
|
1142
|
+
.little => {
|
|
1136
1143
|
var hp = @as(u16, a[i + 1]) << 8 | @as(u16, a[i]);
|
|
1137
1144
|
printc(" {d}", .{hp}, a, b, &i, 2, color);
|
|
1138
1145
|
hp = @as(u16, a[i + 1]) << 8 | @as(u16, a[i]);
|
|
@@ -1200,14 +1207,11 @@ pub fn expectLog(
|
|
|
1200
1207
|
) !void {
|
|
1201
1208
|
if (!enabled) return;
|
|
1202
1209
|
|
|
1203
|
-
const color =
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
} else {
|
|
1209
|
-
break :color std.io.getStdErr().supportsAnsiEscapeCodes();
|
|
1210
|
-
}
|
|
1210
|
+
const color = if (std.process.hasEnvVarConstant("ZIG_DEBUG_COLOR"))
|
|
1211
|
+
true
|
|
1212
|
+
else switch (std.io.tty.detectConfig(std.io.getStdErr())) {
|
|
1213
|
+
.escape_codes => true,
|
|
1214
|
+
else => false,
|
|
1211
1215
|
};
|
|
1212
1216
|
|
|
1213
1217
|
expectEqualBytes(expected, actual, offset) catch |err| switch (err) {
|
|
@@ -1239,8 +1243,6 @@ fn expectEqualBytes(expected: []const u8, actual: []const u8, offset: usize) !vo
|
|
|
1239
1243
|
}
|
|
1240
1244
|
}
|
|
1241
1245
|
|
|
1242
|
-
const endian = builtin.target.cpu.arch.endian();
|
|
1243
|
-
|
|
1244
1246
|
fn N(e: anytype) u8 {
|
|
1245
1247
|
return @intFromEnum(e);
|
|
1246
1248
|
}
|
|
@@ -1248,20 +1250,13 @@ fn N(e: anytype) u8 {
|
|
|
1248
1250
|
const p1 = Player.P1;
|
|
1249
1251
|
const p2 = Player.P2;
|
|
1250
1252
|
|
|
1251
|
-
const gen1 = struct {
|
|
1252
|
-
pub usingnamespace @import("../gen1/data.zig");
|
|
1253
|
-
pub const helpers = @import("../gen1/helpers.zig");
|
|
1254
|
-
};
|
|
1255
|
-
|
|
1256
|
-
const gen2 = struct {
|
|
1257
|
-
pub usingnamespace @import("../gen2/data.zig");
|
|
1258
|
-
pub const helpers = @import("../gen2/helpers.zig");
|
|
1259
|
-
};
|
|
1260
|
-
|
|
1261
1253
|
var buf: [pkmn.LOGS_SIZE]u8 = undefined;
|
|
1262
1254
|
var stream: ByteStream = .{ .buffer = &buf };
|
|
1263
1255
|
var log: FixedLog = .{ .writer = stream.writer() };
|
|
1264
1256
|
|
|
1257
|
+
const gen1 = pkmn.gen1;
|
|
1258
|
+
const gen2 = pkmn.gen2;
|
|
1259
|
+
|
|
1265
1260
|
const M1 = gen1.Move;
|
|
1266
1261
|
const S1 = gen1.Species;
|
|
1267
1262
|
|
|
@@ -1350,8 +1345,8 @@ test "|switch|" {
|
|
|
1350
1345
|
try log.switched(.{ p2.ident(3), &snorlax });
|
|
1351
1346
|
const par = 0b1000000;
|
|
1352
1347
|
var expected: []const u8 = switch (endian) {
|
|
1353
|
-
.
|
|
1354
|
-
.
|
|
1348
|
+
.big => &.{ N(ArgType.Switch), 0b1011, N(S1.Snorlax), 91, 0, 200, 1, 144, par },
|
|
1349
|
+
.little => &.{ N(ArgType.Switch), 0b1011, N(S1.Snorlax), 91, 200, 0, 144, 1, par },
|
|
1355
1350
|
};
|
|
1356
1351
|
try expectLog1(expected, buf[0..9]);
|
|
1357
1352
|
stream.reset();
|
|
@@ -1361,8 +1356,8 @@ test "|switch|" {
|
|
|
1361
1356
|
snorlax.status = 0;
|
|
1362
1357
|
try log.switched(.{ p2.ident(3), &snorlax });
|
|
1363
1358
|
expected = switch (endian) {
|
|
1364
|
-
.
|
|
1365
|
-
.
|
|
1359
|
+
.big => &.{ N(ArgType.Switch), 0b1011, N(S1.Snorlax), 100, 0, 0, 1, 144, 0 },
|
|
1360
|
+
.little => &.{ N(ArgType.Switch), 0b1011, N(S1.Snorlax), 100, 0, 0, 144, 1, 0 },
|
|
1366
1361
|
};
|
|
1367
1362
|
try expectLog1(expected, buf[0..9]);
|
|
1368
1363
|
stream.reset();
|
|
@@ -1370,8 +1365,8 @@ test "|switch|" {
|
|
|
1370
1365
|
snorlax.hp = 400;
|
|
1371
1366
|
try log.switched(.{ p2.ident(3), &snorlax });
|
|
1372
1367
|
expected = switch (endian) {
|
|
1373
|
-
.
|
|
1374
|
-
.
|
|
1368
|
+
.big => &.{ N(ArgType.Switch), 0b1011, N(S1.Snorlax), 100, 1, 144, 1, 144, 0 },
|
|
1369
|
+
.little => &.{ N(ArgType.Switch), 0b1011, N(S1.Snorlax), 100, 144, 1, 144, 1, 0 },
|
|
1375
1370
|
};
|
|
1376
1371
|
try expectLog1(expected, buf[0..9]);
|
|
1377
1372
|
stream.reset();
|
|
@@ -1389,8 +1384,8 @@ test "|switch|" {
|
|
|
1389
1384
|
N(gen2.Gender.Female),
|
|
1390
1385
|
91,
|
|
1391
1386
|
} ++ switch (endian) {
|
|
1392
|
-
.
|
|
1393
|
-
.
|
|
1387
|
+
.big => .{ 0, 200, 1, 144, par },
|
|
1388
|
+
.little => .{ 200, 0, 144, 1, par },
|
|
1394
1389
|
});
|
|
1395
1390
|
try expectLog2(expected, buf[0..10]);
|
|
1396
1391
|
stream.reset();
|
|
@@ -1418,9 +1413,9 @@ test "|faint|" {
|
|
|
1418
1413
|
|
|
1419
1414
|
test "|turn|" {
|
|
1420
1415
|
try log.turn(.{42});
|
|
1421
|
-
|
|
1422
|
-
.
|
|
1423
|
-
.
|
|
1416
|
+
const expected = switch (endian) {
|
|
1417
|
+
.big => &.{ N(ArgType.Turn), 0, 42, N(ArgType.None) },
|
|
1418
|
+
.little => &.{ N(ArgType.Turn), 42, 0, N(ArgType.None) },
|
|
1424
1419
|
};
|
|
1425
1420
|
try expectLog1(expected, buf[0..4]);
|
|
1426
1421
|
stream.reset();
|
|
@@ -1444,8 +1439,8 @@ test "|-damage|" {
|
|
|
1444
1439
|
chansey.status = gen1.Status.slp(1);
|
|
1445
1440
|
try log.damage(.{ p2.ident(2), &chansey, .None });
|
|
1446
1441
|
var expected: []const u8 = switch (endian) {
|
|
1447
|
-
.
|
|
1448
|
-
.
|
|
1442
|
+
.big => &.{ N(ArgType.Damage), 0b1010, 2, 100, 2, 191, 1, N(Damage.None) },
|
|
1443
|
+
.little => &.{ N(ArgType.Damage), 0b1010, 100, 2, 191, 2, 1, N(Damage.None) },
|
|
1449
1444
|
};
|
|
1450
1445
|
try expectLog1(expected, buf[0..8]);
|
|
1451
1446
|
stream.reset();
|
|
@@ -1455,8 +1450,8 @@ test "|-damage|" {
|
|
|
1455
1450
|
chansey.status = 0;
|
|
1456
1451
|
try log.damage(.{ p2.ident(2), &chansey, .Confusion });
|
|
1457
1452
|
expected = switch (endian) {
|
|
1458
|
-
.
|
|
1459
|
-
.
|
|
1453
|
+
.big => &.{ N(ArgType.Damage), 0b1010, 0, 100, 1, 0, 0, N(Damage.Confusion) },
|
|
1454
|
+
.little => &.{ N(ArgType.Damage), 0b1010, 100, 0, 0, 1, 0, N(Damage.Confusion) },
|
|
1460
1455
|
};
|
|
1461
1456
|
try expectLog1(expected, buf[0..8]);
|
|
1462
1457
|
stream.reset();
|
|
@@ -1464,8 +1459,8 @@ test "|-damage|" {
|
|
|
1464
1459
|
chansey.status = gen1.Status.init(.PSN);
|
|
1465
1460
|
try log.damage(.{ p2.ident(2), &chansey, .RecoilOf, p1.ident(1) });
|
|
1466
1461
|
expected = switch (endian) {
|
|
1467
|
-
.
|
|
1468
|
-
.
|
|
1462
|
+
.big => &.{ N(ArgType.Damage), 0b1010, 0, 100, 1, 0, 0b1000, N(Damage.RecoilOf), 1 },
|
|
1463
|
+
.little => &.{ N(ArgType.Damage), 0b1010, 100, 0, 0, 1, 0b1000, N(Damage.RecoilOf), 1 },
|
|
1469
1464
|
};
|
|
1470
1465
|
try expectLog1(expected, buf[0..9]);
|
|
1471
1466
|
stream.reset();
|
|
@@ -1477,8 +1472,8 @@ test "|-heal|" {
|
|
|
1477
1472
|
chansey.status = gen1.Status.slp(1);
|
|
1478
1473
|
try log.heal(.{ p2.ident(2), &chansey, .None });
|
|
1479
1474
|
var expected: []const u8 = switch (endian) {
|
|
1480
|
-
.
|
|
1481
|
-
.
|
|
1475
|
+
.big => &.{ N(ArgType.Heal), 0b1010, 2, 100, 2, 191, 1, N(Heal.None) },
|
|
1476
|
+
.little => &.{ N(ArgType.Heal), 0b1010, 100, 2, 191, 2, 1, N(Heal.None) },
|
|
1482
1477
|
};
|
|
1483
1478
|
try expectLog1(expected, buf[0..8]);
|
|
1484
1479
|
stream.reset();
|
|
@@ -1488,16 +1483,16 @@ test "|-heal|" {
|
|
|
1488
1483
|
chansey.status = 0;
|
|
1489
1484
|
try log.heal(.{ p2.ident(2), &chansey, .Silent });
|
|
1490
1485
|
expected = switch (endian) {
|
|
1491
|
-
.
|
|
1492
|
-
.
|
|
1486
|
+
.big => &.{ N(ArgType.Heal), 0b1010, 0, 100, 1, 0, 0, N(Heal.Silent) },
|
|
1487
|
+
.little => &.{ N(ArgType.Heal), 0b1010, 100, 0, 0, 1, 0, N(Heal.Silent) },
|
|
1493
1488
|
};
|
|
1494
1489
|
try expectLog1(expected, buf[0..8]);
|
|
1495
1490
|
stream.reset();
|
|
1496
1491
|
|
|
1497
1492
|
try log.heal(.{ p2.ident(2), &chansey, .Drain, p1.ident(1) });
|
|
1498
1493
|
expected = switch (endian) {
|
|
1499
|
-
.
|
|
1500
|
-
.
|
|
1494
|
+
.big => &.{ N(ArgType.Heal), 0b1010, 0, 100, 1, 0, 0, N(Heal.Drain), 1 },
|
|
1495
|
+
.little => &.{ N(ArgType.Heal), 0b1010, 100, 0, 0, 1, 0, N(Heal.Drain), 1 },
|
|
1501
1496
|
};
|
|
1502
1497
|
try expectLog1(expected, buf[0..9]);
|
|
1503
1498
|
stream.reset();
|
|
@@ -1740,8 +1735,8 @@ test "|drag|" {
|
|
|
1740
1735
|
N(gen2.Gender.Female),
|
|
1741
1736
|
91,
|
|
1742
1737
|
} ++ switch (endian) {
|
|
1743
|
-
.
|
|
1744
|
-
.
|
|
1738
|
+
.big => .{ 0, 200, 1, 144, par },
|
|
1739
|
+
.little => .{ 200, 0, 144, 1, par },
|
|
1745
1740
|
});
|
|
1746
1741
|
try expectLog2(expected, buf[0..10]);
|
|
1747
1742
|
stream.reset();
|
|
@@ -1773,9 +1768,9 @@ test "|-sethp|" {
|
|
|
1773
1768
|
var blissey = gen2.helpers.Pokemon.init(.{ .species = .Blissey, .moves = &.{.PainSplit} });
|
|
1774
1769
|
blissey.hp = 612;
|
|
1775
1770
|
try log.sethp(.{ p2.ident(2), &blissey, .Silent });
|
|
1776
|
-
|
|
1777
|
-
.
|
|
1778
|
-
.
|
|
1771
|
+
const expected: []const u8 = switch (endian) {
|
|
1772
|
+
.big => &.{ N(ArgType.SetHP), 0b1010, 2, 100, 2, 201, 0, N(SetHP.Silent) },
|
|
1773
|
+
.little => &.{ N(ArgType.SetHP), 0b1010, 100, 2, 201, 2, 0, N(SetHP.Silent) },
|
|
1779
1774
|
};
|
|
1780
1775
|
try expectLog2(expected, buf[0..8]);
|
|
1781
1776
|
stream.reset();
|
|
@@ -192,9 +192,9 @@ pub fn Rational(comptime T: type) type {
|
|
|
192
192
|
|
|
193
193
|
fn addition(r: *Self, p: anytype, q: anytype) !void {
|
|
194
194
|
// (a/b) + (c/d) = (ad+bc)/(bd)
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
195
|
+
const d = try std.math.mul(T, r.q, q);
|
|
196
|
+
const n1 = try std.math.mul(T, r.p, q);
|
|
197
|
+
const n2 = try std.math.mul(T, r.q, p);
|
|
198
198
|
|
|
199
199
|
r.p = try std.math.add(T, n1, n2);
|
|
200
200
|
r.q = d;
|
|
@@ -234,6 +234,8 @@ test Rational {
|
|
|
234
234
|
var r: Rational(t) = .{};
|
|
235
235
|
|
|
236
236
|
var c: t = 128;
|
|
237
|
+
_ = &c;
|
|
238
|
+
|
|
237
239
|
try r.update(c, 256);
|
|
238
240
|
try doTurn(&r);
|
|
239
241
|
|
|
@@ -320,6 +322,8 @@ test BigRational {
|
|
|
320
322
|
try r.reset();
|
|
321
323
|
|
|
322
324
|
var c: u8 = 128;
|
|
325
|
+
_ = &c;
|
|
326
|
+
|
|
323
327
|
try r.update(c, 256);
|
|
324
328
|
try doTurn(&r);
|
|
325
329
|
|
package/src/lib/common/rng.zig
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
const std = @import("std");
|
|
2
2
|
|
|
3
|
-
const options = @import("
|
|
3
|
+
const options = @import("options.zig");
|
|
4
4
|
|
|
5
5
|
const assert = std.debug.assert;
|
|
6
6
|
const expectEqual = std.testing.expectEqual;
|
|
@@ -66,11 +66,15 @@ pub const PSRNG = extern struct {
|
|
|
66
66
|
(@as(u64, self.range(u16, 0, 0x10000)) << 16) |
|
|
67
67
|
(@as(u64, self.range(u16, 0, 0x10000)));
|
|
68
68
|
}
|
|
69
|
+
|
|
70
|
+
pub fn Bound(comptime T: type) type {
|
|
71
|
+
return std.math.IntFittingRange(0, std.math.maxInt(T) + 1);
|
|
72
|
+
}
|
|
69
73
|
};
|
|
70
74
|
|
|
71
75
|
test PSRNG {
|
|
72
76
|
var psrng: PSRNG = .{ .src = .{ .seed = 0x0001000200030004 } };
|
|
73
|
-
try expectEqual(
|
|
77
|
+
try expectEqual(121, psrng.range(u8, 0, 256));
|
|
74
78
|
try expectEqual(false, psrng.chance(u8, 128, 256)); // 226 < 128
|
|
75
79
|
}
|
|
76
80
|
|
|
@@ -107,9 +111,9 @@ test Gen12 {
|
|
|
107
111
|
try expectEqual(e, rng.next());
|
|
108
112
|
}
|
|
109
113
|
|
|
110
|
-
try expectEqual(
|
|
111
|
-
try expectEqual(
|
|
112
|
-
try expectEqual(
|
|
114
|
+
try expectEqual(16, Gen12.percent(6) + 1);
|
|
115
|
+
try expectEqual(16, Gen12.percent(7) - 1);
|
|
116
|
+
try expectEqual(128, Gen12.percent(50) + 1);
|
|
113
117
|
}
|
|
114
118
|
|
|
115
119
|
// https://pkmn.cc/pokeemerald/src/random.c
|
|
@@ -197,7 +201,7 @@ pub fn FixedRNG(comptime gen: comptime_int, comptime len: usize) type {
|
|
|
197
201
|
for (0..n) |_| _ = self.next();
|
|
198
202
|
}
|
|
199
203
|
|
|
200
|
-
pub fn range(self: *Self, comptime T: type, from: T, to: Bound(T)) T {
|
|
204
|
+
pub fn range(self: *Self, comptime T: type, from: T, to: PSRNG.Bound(T)) T {
|
|
201
205
|
assert(showdown);
|
|
202
206
|
return @intCast(@as(u64, self.next()) * (to - from) / divisor + from);
|
|
203
207
|
}
|
|
@@ -206,7 +210,7 @@ pub fn FixedRNG(comptime gen: comptime_int, comptime len: usize) type {
|
|
|
206
210
|
self: *Self,
|
|
207
211
|
comptime T: type,
|
|
208
212
|
numerator: T,
|
|
209
|
-
denominator: Bound(T),
|
|
213
|
+
denominator: PSRNG.Bound(T),
|
|
210
214
|
) bool {
|
|
211
215
|
assert(showdown);
|
|
212
216
|
assert(denominator > 0);
|
|
@@ -237,7 +241,3 @@ fn Output(comptime gen: comptime_int) type {
|
|
|
237
241
|
else => unreachable,
|
|
238
242
|
};
|
|
239
243
|
}
|
|
240
|
-
|
|
241
|
-
fn Bound(comptime T: type) type {
|
|
242
|
-
return std.math.IntFittingRange(0, std.math.maxInt(T) + 1);
|
|
243
|
-
}
|
package/src/lib/gen1/calc.zig
CHANGED
|
@@ -211,8 +211,8 @@ pub fn transitions(
|
|
|
211
211
|
) !?Stats {
|
|
212
212
|
var stats: Stats = .{};
|
|
213
213
|
|
|
214
|
-
|
|
215
|
-
|
|
214
|
+
const actions = options.actions;
|
|
215
|
+
const cap = options.cap;
|
|
216
216
|
|
|
217
217
|
var seen = std.AutoHashMap(Actions, void).init(allocator);
|
|
218
218
|
defer seen.deinit();
|
|
@@ -232,8 +232,8 @@ pub fn transitions(
|
|
|
232
232
|
_ = try b.update(c1, c2, &opts);
|
|
233
233
|
stats.updates += 1;
|
|
234
234
|
|
|
235
|
-
|
|
236
|
-
|
|
235
|
+
const p1 = b.side(.P1);
|
|
236
|
+
const p2 = b.side(.P2);
|
|
237
237
|
|
|
238
238
|
var p: Rational(u128) = .{ .p = 0, .q = 1 };
|
|
239
239
|
try frontier.append(opts.chance.actions);
|
|
@@ -247,7 +247,7 @@ pub fn transitions(
|
|
|
247
247
|
var i: usize = 0;
|
|
248
248
|
assert(frontier.items.len == 1);
|
|
249
249
|
while (i < frontier.items.len) : (i += 1) {
|
|
250
|
-
|
|
250
|
+
const template = frontier.items[i];
|
|
251
251
|
opts.calc.overrides.durations = .{
|
|
252
252
|
.p1 = template.p1.durations,
|
|
253
253
|
.p2 = template.p2.durations,
|
package/src/lib/gen1/chance.zig
CHANGED
|
@@ -14,7 +14,7 @@ const util = @import("../common/util.zig");
|
|
|
14
14
|
const Player = @import("../common/data.zig").Player;
|
|
15
15
|
const Optional = @import("../common/optional.zig").Optional;
|
|
16
16
|
|
|
17
|
-
const data = @import("
|
|
17
|
+
const data = @import("data.zig");
|
|
18
18
|
|
|
19
19
|
const enabled = options.chance;
|
|
20
20
|
const showdown = options.showdown;
|
|
@@ -706,19 +706,19 @@ test "Chance.damage" {
|
|
|
706
706
|
|
|
707
707
|
try chance.damage(.P1, 217);
|
|
708
708
|
if (showdown) {
|
|
709
|
-
try expectValue(
|
|
709
|
+
try expectValue(217, chance.actions.p1.damage);
|
|
710
710
|
try expectProbability(&chance.probability, 1, 39);
|
|
711
711
|
} else {
|
|
712
712
|
try expectProbability(&chance.probability, 1, 1);
|
|
713
|
-
try expectValue(
|
|
713
|
+
try expectValue(0, chance.actions.p1.damage);
|
|
714
714
|
|
|
715
715
|
try chance.commit(.P1, .miss);
|
|
716
716
|
try expectProbability(&chance.probability, 1, 1);
|
|
717
|
-
try expectValue(
|
|
717
|
+
try expectValue(0, chance.actions.p1.damage);
|
|
718
718
|
|
|
719
719
|
try chance.commit(.P1, .hit);
|
|
720
720
|
try expectProbability(&chance.probability, 1, 39);
|
|
721
|
-
try expectValue(
|
|
721
|
+
try expectValue(217, chance.actions.p1.damage);
|
|
722
722
|
}
|
|
723
723
|
}
|
|
724
724
|
|
|
@@ -770,13 +770,13 @@ test "Chance.moveSlot" {
|
|
|
770
770
|
|
|
771
771
|
try chance.moveSlot(.P2, 2, &ms, 2);
|
|
772
772
|
try expectProbability(&chance.probability, 1, 2);
|
|
773
|
-
try expectValue(
|
|
773
|
+
try expectValue(2, chance.actions.p2.move_slot);
|
|
774
774
|
|
|
775
775
|
chance.reset();
|
|
776
776
|
|
|
777
777
|
try chance.moveSlot(.P1, 1, &ms, 0);
|
|
778
778
|
try expectProbability(&chance.probability, 1, 3);
|
|
779
|
-
try expectValue(
|
|
779
|
+
try expectValue(1, chance.actions.p1.move_slot);
|
|
780
780
|
}
|
|
781
781
|
|
|
782
782
|
test "Chance.multiHit" {
|
|
@@ -784,32 +784,32 @@ test "Chance.multiHit" {
|
|
|
784
784
|
|
|
785
785
|
try chance.multiHit(.P1, 3);
|
|
786
786
|
try expectProbability(&chance.probability, 3, 8);
|
|
787
|
-
try expectValue(
|
|
787
|
+
try expectValue(3, chance.actions.p1.multi_hit);
|
|
788
788
|
|
|
789
789
|
chance.reset();
|
|
790
790
|
|
|
791
791
|
try chance.multiHit(.P2, 5);
|
|
792
792
|
try expectProbability(&chance.probability, 1, 8);
|
|
793
|
-
try expectValue(
|
|
793
|
+
try expectValue(5, chance.actions.p2.multi_hit);
|
|
794
794
|
}
|
|
795
795
|
|
|
796
796
|
test "Chance.duration" {
|
|
797
797
|
var chance: Chance(rational.Rational(u64)) = .{ .probability = .{} };
|
|
798
798
|
|
|
799
799
|
chance.duration(.sleep, .P1, .P2, 2);
|
|
800
|
-
try expectValue(
|
|
801
|
-
try expectValue(
|
|
800
|
+
try expectValue(2, chance.actions.p1.duration);
|
|
801
|
+
try expectValue(1, chance.actions.p2.durations.sleep);
|
|
802
802
|
|
|
803
803
|
chance.reset();
|
|
804
804
|
|
|
805
805
|
chance.duration(.binding, .P2, .P2, 4);
|
|
806
806
|
if (!showdown) {
|
|
807
|
-
try expectValue(
|
|
808
|
-
try expectValue(
|
|
807
|
+
try expectValue(0, chance.actions.p2.duration);
|
|
808
|
+
try expectValue(0, chance.actions.p2.durations.binding);
|
|
809
809
|
try chance.commit(.P2, .hit);
|
|
810
810
|
}
|
|
811
|
-
try expectValue(
|
|
812
|
-
try expectValue(
|
|
811
|
+
try expectValue(4, chance.actions.p2.duration);
|
|
812
|
+
try expectValue(1, chance.actions.p2.durations.binding);
|
|
813
813
|
}
|
|
814
814
|
|
|
815
815
|
test "Chance.sleep" {
|
|
@@ -819,7 +819,7 @@ test "Chance.sleep" {
|
|
|
819
819
|
chance.actions.p1.durations.sleep = @intCast(i);
|
|
820
820
|
try chance.sleep(.P1, 0);
|
|
821
821
|
try expectProbability(&chance.probability, 1, d);
|
|
822
|
-
try expectValue(
|
|
822
|
+
try expectValue(0, chance.actions.p1.durations.sleep);
|
|
823
823
|
|
|
824
824
|
chance.reset();
|
|
825
825
|
|
|
@@ -842,7 +842,7 @@ test "Chance.confusion" {
|
|
|
842
842
|
chance.actions.p2.durations.confusion = @intCast(i);
|
|
843
843
|
try chance.confusion(.P2, 0);
|
|
844
844
|
try expectProbability(&chance.probability, 1, d);
|
|
845
|
-
try expectValue(
|
|
845
|
+
try expectValue(0, chance.actions.p2.durations.confusion);
|
|
846
846
|
|
|
847
847
|
chance.reset();
|
|
848
848
|
}
|
|
@@ -865,7 +865,7 @@ test "Chance.disable" {
|
|
|
865
865
|
chance.actions.p1.durations.disable = @intCast(i);
|
|
866
866
|
try chance.disable(.P1, 0);
|
|
867
867
|
try expectProbability(&chance.probability, 1, d);
|
|
868
|
-
try expectValue(
|
|
868
|
+
try expectValue(0, chance.actions.p1.durations.disable);
|
|
869
869
|
|
|
870
870
|
chance.reset();
|
|
871
871
|
|
|
@@ -888,7 +888,7 @@ test "Chance.attacking" {
|
|
|
888
888
|
chance.actions.p2.durations.attacking = @intCast(i);
|
|
889
889
|
try chance.attacking(.P2, 0);
|
|
890
890
|
try expectProbability(&chance.probability, 1, d);
|
|
891
|
-
try expectValue(
|
|
891
|
+
try expectValue(0, chance.actions.p2.durations.attacking);
|
|
892
892
|
|
|
893
893
|
chance.reset();
|
|
894
894
|
}
|
|
@@ -914,7 +914,7 @@ test "Chance.binding" {
|
|
|
914
914
|
chance.actions.p1.durations.binding = @intCast(i);
|
|
915
915
|
try chance.binding(.P1, 0);
|
|
916
916
|
try expectProbability(&chance.probability, p, q);
|
|
917
|
-
try expectValue(
|
|
917
|
+
try expectValue(0, chance.actions.p1.durations.binding);
|
|
918
918
|
|
|
919
919
|
chance.reset();
|
|
920
920
|
|
|
@@ -934,7 +934,7 @@ test "Chance.psywave" {
|
|
|
934
934
|
|
|
935
935
|
try chance.psywave(.P2, 100, 150);
|
|
936
936
|
try expectProbability(&chance.probability, 1, 150);
|
|
937
|
-
try expectValue(
|
|
937
|
+
try expectValue(101, chance.actions.p2.psywave);
|
|
938
938
|
}
|
|
939
939
|
|
|
940
940
|
test "Chance.metronome" {
|
|
@@ -1091,7 +1091,7 @@ pub const Species = enum(u8) {
|
|
|
1091
1091
|
/// The number of Pokémon species in this generation.
|
|
1092
1092
|
pub const size = 151;
|
|
1093
1093
|
|
|
1094
|
-
/// The Pokémon's critical hit
|
|
1094
|
+
/// The Pokémon's critical hit ratio out of 256.
|
|
1095
1095
|
pub fn chance(id: Species) u8 {
|
|
1096
1096
|
assert(id != .None);
|
|
1097
1097
|
return CHANCES[@intFromEnum(id) - 1];
|