@pkmn/engine 0.1.0-dev.89cc1c98 → 0.1.0-dev.900756a9
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/build/tools/debug.js +3 -1
- package/build/tools/debug.js.map +1 -1
- package/build.zig +19 -13
- package/package.json +1 -1
- package/src/lib/common/protocol.zig +35 -14
- package/src/lib/common/rational.zig +1 -1
- package/src/lib/common/rng.zig +9 -0
- package/src/lib/gen1/mechanics.zig +19 -23
- package/src/lib/gen2/README.md +0 -1
- package/src/lib/gen2/data.zig +4 -2
- package/src/lib/gen2/generated.zig +23 -72
- package/src/lib/gen2/mechanics.zig +788 -294
package/build/tools/debug.js
CHANGED
|
@@ -60,6 +60,8 @@ function display(gens, data, error, seed) {
|
|
|
60
60
|
let offset = 0;
|
|
61
61
|
const showdown = !!view.getUint8(offset++);
|
|
62
62
|
const gen = gens.get(view.getUint8(offset++));
|
|
63
|
+
const N = view.getUint16(offset, data_2.LE);
|
|
64
|
+
offset += 2;
|
|
63
65
|
const lookup = data_2.Lookup.get(gen);
|
|
64
66
|
const size = data_2.LAYOUT[gen.num - 1].sizes.Battle;
|
|
65
67
|
const deserialize = (buf) => {
|
|
@@ -83,7 +85,7 @@ function display(gens, data, error, seed) {
|
|
|
83
85
|
partial.parsed.push(r.value);
|
|
84
86
|
r = it.next();
|
|
85
87
|
}
|
|
86
|
-
offset += r.value;
|
|
88
|
+
offset += N || r.value;
|
|
87
89
|
if (offset >= view.byteLength)
|
|
88
90
|
break;
|
|
89
91
|
partial.battle = deserialize(data.subarray(offset, offset += size));
|
package/build/tools/debug.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"debug.js","sourceRoot":"","sources":["../../src/tools/debug.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,uCAAyB;AAEzB,qCAAmD;AAEnD,gCAAmE;AACnE,oDAAsC;AACtC,
|
|
1
|
+
{"version":3,"file":"debug.js","sourceRoot":"","sources":["../../src/tools/debug.ts"],"names":[],"mappings":"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"}
|
package/build.zig
CHANGED
|
@@ -224,30 +224,32 @@ pub fn build(b: *std.Build) !void {
|
|
|
224
224
|
var benchmark_config = tools;
|
|
225
225
|
benchmark_config.general.optimize = .ReleaseFast;
|
|
226
226
|
benchmark_config.general.strip = true;
|
|
227
|
-
const benchmark = tool(b, "src/test/benchmark.zig", benchmark_config);
|
|
227
|
+
const benchmark = try tool(b, "src/test/benchmark.zig", benchmark_config);
|
|
228
228
|
|
|
229
229
|
var fuzz_config = tools;
|
|
230
230
|
fuzz_config.general.strip = false;
|
|
231
231
|
fuzz_config.tool.name = "fuzz";
|
|
232
|
-
const fuzz = tool(b, "src/test/fuzz.zig", fuzz_config);
|
|
232
|
+
const fuzz = try tool(b, "src/test/fuzz.zig", fuzz_config);
|
|
233
233
|
|
|
234
|
-
const analyze = tool(b, "src/tools/analyze.zig", tools);
|
|
235
|
-
const dump = tool(b, "src/tools/dump.zig", tools);
|
|
236
|
-
const transitions = tool(b, "src/tools/transitions.zig", tools);
|
|
234
|
+
const analyze = try tool(b, "src/tools/analyze.zig", tools);
|
|
235
|
+
const dump = try tool(b, "src/tools/dump.zig", tools);
|
|
236
|
+
const transitions = try tool(b, "src/tools/transitions.zig", tools);
|
|
237
237
|
|
|
238
238
|
// FIXME: serde randomly fails to build in some release configurations
|
|
239
239
|
var hack = tools;
|
|
240
240
|
if (optimize != .Debug) hack.tool.tests = null;
|
|
241
|
-
const serde = tool(b, "src/tools/serde.zig", hack);
|
|
241
|
+
const serde = try tool(b, "src/tools/serde.zig", hack);
|
|
242
242
|
|
|
243
|
-
b.step("analyze", "Run LLVM analysis tool").dependOn(&
|
|
244
|
-
b.step("benchmark", "Run benchmark code").dependOn(&
|
|
245
|
-
b.step("dump", "Run protocol dump tool").dependOn(&
|
|
246
|
-
b.step("fuzz", "Run fuzz tester").dependOn(&
|
|
247
|
-
b.step("serde", "Run serialization/deserialization tool").dependOn(&
|
|
243
|
+
if (analyze) |t| b.step("analyze", "Run LLVM analysis tool").dependOn(&t.step);
|
|
244
|
+
if (benchmark) |t| b.step("benchmark", "Run benchmark code").dependOn(&t.step);
|
|
245
|
+
if (dump) |t| b.step("dump", "Run protocol dump tool").dependOn(&t.step);
|
|
246
|
+
if (fuzz) |t| b.step("fuzz", "Run fuzz tester").dependOn(&t.step);
|
|
247
|
+
if (serde) |t| b.step("serde", "Run serialization/deserialization tool").dependOn(&t.step);
|
|
248
248
|
b.step("test", "Run all tests").dependOn(&tests.step);
|
|
249
249
|
b.step("tools", "Install tools").dependOn(&ToolsStep.create(b, &exes).step);
|
|
250
|
-
|
|
250
|
+
if (transitions) |t| {
|
|
251
|
+
b.step("transitions", "Visualize transitions algorithm search").dependOn(&t.step);
|
|
252
|
+
}
|
|
251
253
|
}
|
|
252
254
|
|
|
253
255
|
fn maybeStrip(
|
|
@@ -326,7 +328,11 @@ const ToolConfig = struct {
|
|
|
326
328
|
},
|
|
327
329
|
};
|
|
328
330
|
|
|
329
|
-
fn tool(b: *std.Build, path: []const u8, config: ToolConfig)
|
|
331
|
+
fn tool(b: *std.Build, path: []const u8, config: ToolConfig) !?*std.Build.RunStep {
|
|
332
|
+
std.fs.cwd().access(path, .{}) catch |err| switch (err) {
|
|
333
|
+
error.FileNotFound => return null,
|
|
334
|
+
else => |e| return e,
|
|
335
|
+
};
|
|
330
336
|
var name = config.tool.name orelse std.fs.path.basename(path);
|
|
331
337
|
const index = std.mem.lastIndexOfScalar(u8, name, '.');
|
|
332
338
|
if (index) |i| name = name[0..i];
|
package/package.json
CHANGED
|
@@ -213,6 +213,8 @@ pub const Activate = enum(u8) {
|
|
|
213
213
|
DestinyBond,
|
|
214
214
|
|
|
215
215
|
BeatUp, // FIXME of
|
|
216
|
+
|
|
217
|
+
Magnitude,
|
|
216
218
|
};
|
|
217
219
|
|
|
218
220
|
pub const Start = enum(u8) {
|
|
@@ -257,6 +259,7 @@ pub const End = enum(u8) {
|
|
|
257
259
|
Encore,
|
|
258
260
|
FutureSight,
|
|
259
261
|
LeechSeed,
|
|
262
|
+
|
|
260
263
|
Bind,
|
|
261
264
|
Wrap,
|
|
262
265
|
FireSpin,
|
|
@@ -272,6 +275,8 @@ pub const End = enum(u8) {
|
|
|
272
275
|
LightScreenSilent,
|
|
273
276
|
ReflectSilent,
|
|
274
277
|
BideSilent,
|
|
278
|
+
|
|
279
|
+
LeechSeedFrom,
|
|
275
280
|
};
|
|
276
281
|
|
|
277
282
|
pub const Immune = enum(u8) {
|
|
@@ -449,14 +454,15 @@ pub fn Log(comptime Writer: type) type {
|
|
|
449
454
|
});
|
|
450
455
|
}
|
|
451
456
|
|
|
452
|
-
|
|
457
|
+
// args: ident: ID, pokemon: anytype, reason: Heal
|
|
458
|
+
pub fn heal(self: Self, args: anytype) Error!void {
|
|
453
459
|
if (!enabled) return;
|
|
454
460
|
|
|
455
|
-
assert(
|
|
456
|
-
try self.writer.writeAll(&.{ @intFromEnum(ArgType.Heal), @as(u8, @bitCast(
|
|
457
|
-
try self.writer.writeIntNative(u16,
|
|
458
|
-
try self.writer.writeIntNative(u16,
|
|
459
|
-
try self.writer.writeAll(&.{
|
|
461
|
+
assert(args[2] != .Drain);
|
|
462
|
+
try self.writer.writeAll(&.{ @intFromEnum(ArgType.Heal), @as(u8, @bitCast(args[0])) });
|
|
463
|
+
try self.writer.writeIntNative(u16, args[1].hp);
|
|
464
|
+
try self.writer.writeIntNative(u16, args[1].stats.hp);
|
|
465
|
+
try self.writer.writeAll(&.{ args[1].status, @intFromEnum(args[2]) });
|
|
460
466
|
}
|
|
461
467
|
|
|
462
468
|
pub fn drain(self: Self, source: ID, pokemon: anytype, target: ID) Error!void {
|
|
@@ -593,6 +599,17 @@ pub fn Log(comptime Writer: type) type {
|
|
|
593
599
|
});
|
|
594
600
|
}
|
|
595
601
|
|
|
602
|
+
pub fn magnitude(self: Self, ident: ID, num: u8) Error!void {
|
|
603
|
+
if (!enabled) return;
|
|
604
|
+
|
|
605
|
+
try self.writer.writeAll(&.{
|
|
606
|
+
@intFromEnum(ArgType.Activate),
|
|
607
|
+
@as(u8, @bitCast(ident)),
|
|
608
|
+
@intFromEnum(Activate.Magnitude),
|
|
609
|
+
num,
|
|
610
|
+
});
|
|
611
|
+
}
|
|
612
|
+
|
|
596
613
|
pub fn fieldactivate(self: Self) Error!void {
|
|
597
614
|
if (!enabled) return;
|
|
598
615
|
|
|
@@ -780,14 +797,13 @@ pub fn Log(comptime Writer: type) type {
|
|
|
780
797
|
});
|
|
781
798
|
}
|
|
782
799
|
|
|
783
|
-
pub fn spikesend(self: Self,
|
|
800
|
+
pub fn spikesend(self: Self, source: ID) Error!void {
|
|
784
801
|
if (!enabled) return;
|
|
785
802
|
|
|
786
803
|
try self.writer.writeAll(&.{
|
|
787
804
|
@intFromEnum(ArgType.SideEnd),
|
|
788
|
-
@intFromEnum(player),
|
|
805
|
+
@intFromEnum(source.player),
|
|
789
806
|
@intFromEnum(Side.Spikes),
|
|
790
|
-
@intFromEnum(m),
|
|
791
807
|
@as(u8, @bitCast(source)),
|
|
792
808
|
});
|
|
793
809
|
}
|
|
@@ -1495,7 +1511,7 @@ test "|-heal|" {
|
|
|
1495
1511
|
var chansey = gen1.helpers.Pokemon.init(.{ .species = .Chansey, .moves = &.{.Splash} });
|
|
1496
1512
|
chansey.hp = 612;
|
|
1497
1513
|
chansey.status = gen1.Status.slp(1);
|
|
1498
|
-
try log.heal(p2.ident(2), &chansey, .None);
|
|
1514
|
+
try log.heal(.{ p2.ident(2), &chansey, Heal.None });
|
|
1499
1515
|
var expected: []const u8 = switch (endian) {
|
|
1500
1516
|
.Big => &.{ N(ArgType.Heal), 0b1010, 2, 100, 2, 191, 1, N(Heal.None) },
|
|
1501
1517
|
.Little => &.{ N(ArgType.Heal), 0b1010, 100, 2, 191, 2, 1, N(Heal.None) },
|
|
@@ -1506,7 +1522,7 @@ test "|-heal|" {
|
|
|
1506
1522
|
chansey.hp = 100;
|
|
1507
1523
|
chansey.stats.hp = 256;
|
|
1508
1524
|
chansey.status = 0;
|
|
1509
|
-
try log.heal(p2.ident(2), &chansey, .Silent);
|
|
1525
|
+
try log.heal(.{ p2.ident(2), &chansey, Heal.Silent });
|
|
1510
1526
|
expected = switch (endian) {
|
|
1511
1527
|
.Big => &.{ N(ArgType.Heal), 0b1010, 0, 100, 1, 0, 0, N(Heal.Silent) },
|
|
1512
1528
|
.Little => &.{ N(ArgType.Heal), 0b1010, 100, 0, 0, 1, 0, N(Heal.Silent) },
|
|
@@ -1632,6 +1648,12 @@ test "|-activate|" {
|
|
|
1632
1648
|
try log.activate(p1.ident(2), .Splash);
|
|
1633
1649
|
try expectLog1(&.{ N(ArgType.Activate), 0b0010, N(Activate.Splash) }, buf[0..3]);
|
|
1634
1650
|
stream.reset();
|
|
1651
|
+
|
|
1652
|
+
// TODO activateMove
|
|
1653
|
+
|
|
1654
|
+
try log.magnitude(p1.ident(3), 5);
|
|
1655
|
+
try expectLog1(&.{ N(ArgType.Activate), 0b0011, N(Activate.Magnitude), 5 }, buf[0..4]);
|
|
1656
|
+
stream.reset();
|
|
1635
1657
|
}
|
|
1636
1658
|
|
|
1637
1659
|
test "|-fieldactivate|" {
|
|
@@ -1805,14 +1827,13 @@ test "|-sideend|" {
|
|
|
1805
1827
|
try expectLog2(&.{ N(ArgType.SideEnd), 1, N(Side.LightScreen) }, buf[0..3]);
|
|
1806
1828
|
stream.reset();
|
|
1807
1829
|
|
|
1808
|
-
try log.spikesend(
|
|
1830
|
+
try log.spikesend(p1.ident(3));
|
|
1809
1831
|
try expectLog2(&.{
|
|
1810
1832
|
N(ArgType.SideEnd),
|
|
1811
1833
|
0,
|
|
1812
1834
|
N(Side.Spikes),
|
|
1813
|
-
N(M2.RapidSpin),
|
|
1814
1835
|
0b0011,
|
|
1815
|
-
}, buf[0..
|
|
1836
|
+
}, buf[0..4]);
|
|
1816
1837
|
stream.reset();
|
|
1817
1838
|
}
|
|
1818
1839
|
|
|
@@ -44,7 +44,7 @@ pub fn Rational(comptime T: type) type {
|
|
|
44
44
|
/// Both p and q must be >= 1, and if computable at comptime must have no common factors.
|
|
45
45
|
pub fn update(r: *Self, p: anytype, q: anytype) Error!void {
|
|
46
46
|
// FIXME
|
|
47
|
-
// std.debug.print("({d}/{d}) * ", .{p, q});
|
|
47
|
+
// std.debug.print("({d}/{d}) * ", .{ p, q });
|
|
48
48
|
assert(p >= 1);
|
|
49
49
|
assert(q >= 1);
|
|
50
50
|
|
package/src/lib/common/rng.zig
CHANGED
|
@@ -25,6 +25,11 @@ pub fn PRNG(comptime gen: comptime_int) type {
|
|
|
25
25
|
pub fn next(self: *Self) Output(gen) {
|
|
26
26
|
return self.src.next();
|
|
27
27
|
}
|
|
28
|
+
|
|
29
|
+
pub fn advance(self: *Self, n: usize) void {
|
|
30
|
+
if (!options.advance) return;
|
|
31
|
+
for (0..n) |_| self.src.advance();
|
|
32
|
+
}
|
|
28
33
|
};
|
|
29
34
|
}
|
|
30
35
|
|
|
@@ -89,6 +94,10 @@ pub const Gen12 = extern struct {
|
|
|
89
94
|
self.index = (self.index + 1) % 9;
|
|
90
95
|
return val;
|
|
91
96
|
}
|
|
97
|
+
|
|
98
|
+
pub fn advance(self: *Gen12) void {
|
|
99
|
+
_ = self.next();
|
|
100
|
+
}
|
|
92
101
|
};
|
|
93
102
|
|
|
94
103
|
test Gen12 {
|
|
@@ -1553,7 +1553,7 @@ fn handleResidual(battle: anytype, player: Player, options: anytype) !void {
|
|
|
1553
1553
|
// Uncapped damage is added back to the foe
|
|
1554
1554
|
foe_stored.hp = @min(foe_stored.hp + damage, foe_stored.stats.hp);
|
|
1555
1555
|
// Pokémon Showdown uses the less specific heal here instead of drain... because reasons?
|
|
1556
|
-
if (foe_stored.hp > before) try options.log.heal(foe_ident, foe_stored, .Silent);
|
|
1556
|
+
if (foe_stored.hp > before) try options.log.heal(.{ foe_ident, foe_stored, Heal.Silent });
|
|
1557
1557
|
}
|
|
1558
1558
|
}
|
|
1559
1559
|
|
|
@@ -2025,7 +2025,7 @@ pub const Effects = struct {
|
|
|
2025
2025
|
// GLITCH: HP recovery move failure glitches
|
|
2026
2026
|
const delta = stored.stats.hp - stored.hp;
|
|
2027
2027
|
if (delta == 0 or (delta & 255 == 255 and stored.hp % 256 != 0)) {
|
|
2028
|
-
return
|
|
2028
|
+
return options.log.fail(ident, .None);
|
|
2029
2029
|
}
|
|
2030
2030
|
|
|
2031
2031
|
const rest = side.last_selected_move == .Rest;
|
|
@@ -2038,7 +2038,7 @@ pub const Effects = struct {
|
|
|
2038
2038
|
} else {
|
|
2039
2039
|
stored.hp = @min(stored.stats.hp, stored.hp + (stored.stats.hp / 2));
|
|
2040
2040
|
}
|
|
2041
|
-
try options.log.heal(ident, stored, if (rest) Heal.Silent else Heal.None);
|
|
2041
|
+
try options.log.heal(.{ ident, stored, if (rest) Heal.Silent else Heal.None });
|
|
2042
2042
|
}
|
|
2043
2043
|
|
|
2044
2044
|
fn hyperBeam(battle: anytype, player: Player, options: anytype) !void {
|
|
@@ -2107,7 +2107,7 @@ pub const Effects = struct {
|
|
|
2107
2107
|
// Invulnerable foes or 1/256 miss can trigger |-miss| instead of |-fail|
|
|
2108
2108
|
if (!try checkHit(battle, player, move, options)) return;
|
|
2109
2109
|
try options.chance.commit(player, .hit);
|
|
2110
|
-
return
|
|
2110
|
+
return options.log.fail(battle.active(player.foe()), .None);
|
|
2111
2111
|
}
|
|
2112
2112
|
}
|
|
2113
2113
|
if (!try checkHit(battle, player, move, options)) return;
|
|
@@ -2325,8 +2325,7 @@ pub const Effects = struct {
|
|
|
2325
2325
|
fn substitute(battle: anytype, player: Player, residual: *bool, options: anytype) !void {
|
|
2326
2326
|
var side = battle.side(player);
|
|
2327
2327
|
if (side.active.volatiles.Substitute) {
|
|
2328
|
-
|
|
2329
|
-
return;
|
|
2328
|
+
return options.log.fail(battle.active(player), .Substitute);
|
|
2330
2329
|
}
|
|
2331
2330
|
|
|
2332
2331
|
assert(side.stored().stats.hp <= 1023);
|
|
@@ -2337,10 +2336,7 @@ pub const Effects = struct {
|
|
|
2337
2336
|
// the target's HP is exactly divisible by 4 (here we're using an inlined divCeil routine to
|
|
2338
2337
|
// avoid having to convert to floating point)
|
|
2339
2338
|
const required_hp = if (showdown) @divFloor(side.stored().stats.hp - 1, 4) + 1 else hp;
|
|
2340
|
-
if (side.stored().hp < required_hp)
|
|
2341
|
-
try options.log.fail(battle.active(player), .Weak);
|
|
2342
|
-
return;
|
|
2343
|
-
}
|
|
2339
|
+
if (side.stored().hp < required_hp) return options.log.fail(battle.active(player), .Weak);
|
|
2344
2340
|
|
|
2345
2341
|
// GLITCH: can leave the user with 0 HP (faints later) because didn't check '<=' above
|
|
2346
2342
|
side.stored().hp -= hp;
|
|
@@ -2432,7 +2428,7 @@ pub const Effects = struct {
|
|
|
2432
2428
|
switch (move.effect) {
|
|
2433
2429
|
.AttackUp1, .AttackUp2, .Rage => {
|
|
2434
2430
|
assert(boosts.atk >= -6 and boosts.atk <= 6);
|
|
2435
|
-
if (boosts.atk == 6) return
|
|
2431
|
+
if (boosts.atk == 6) return log.fail(ident, .None);
|
|
2436
2432
|
const n: u2 = if (move.effect == .AttackUp2) 2 else 1;
|
|
2437
2433
|
boosts.atk = @as(i4, @intCast(@min(6, @as(i8, boosts.atk) + n)));
|
|
2438
2434
|
const reason = if (move.effect == .Rage) Boost.Rage else Boost.Attack;
|
|
@@ -2443,7 +2439,7 @@ pub const Effects = struct {
|
|
|
2443
2439
|
try log.boost(ident, Boost.Attack, -1);
|
|
2444
2440
|
if (move.effect == .Rage) return;
|
|
2445
2441
|
}
|
|
2446
|
-
return
|
|
2442
|
+
return log.fail(ident, .None);
|
|
2447
2443
|
}
|
|
2448
2444
|
var mod = BOOSTS[@as(u4, @intCast(@as(i8, boosts.atk) + 6))];
|
|
2449
2445
|
const stat = unmodifiedStats(battle, side).atk;
|
|
@@ -2454,7 +2450,7 @@ pub const Effects = struct {
|
|
|
2454
2450
|
},
|
|
2455
2451
|
.DefenseUp1, .DefenseUp2 => {
|
|
2456
2452
|
assert(boosts.def >= -6 and boosts.def <= 6);
|
|
2457
|
-
if (boosts.def == 6) return
|
|
2453
|
+
if (boosts.def == 6) return log.fail(ident, .None);
|
|
2458
2454
|
const n: u2 = if (move.effect == .DefenseUp2) 2 else 1;
|
|
2459
2455
|
boosts.def = @intCast(@min(6, @as(i8, boosts.def) + n));
|
|
2460
2456
|
if (stats.def == MAX_STAT_VALUE) {
|
|
@@ -2463,7 +2459,7 @@ pub const Effects = struct {
|
|
|
2463
2459
|
try log.boost(ident, .Defense, n);
|
|
2464
2460
|
try log.boost(ident, .Defense, -1);
|
|
2465
2461
|
}
|
|
2466
|
-
return
|
|
2462
|
+
return log.fail(ident, .None);
|
|
2467
2463
|
}
|
|
2468
2464
|
var mod = BOOSTS[@as(u4, @intCast(@as(i8, boosts.def) + 6))];
|
|
2469
2465
|
const stat = unmodifiedStats(battle, side).def;
|
|
@@ -2472,7 +2468,7 @@ pub const Effects = struct {
|
|
|
2472
2468
|
},
|
|
2473
2469
|
.SpeedUp2 => {
|
|
2474
2470
|
assert(boosts.spe >= -6 and boosts.spe <= 6);
|
|
2475
|
-
if (boosts.spe == 6) return
|
|
2471
|
+
if (boosts.spe == 6) return log.fail(ident, .None);
|
|
2476
2472
|
boosts.spe = @intCast(@min(6, @as(i8, boosts.spe) + 2));
|
|
2477
2473
|
if (stats.spe == MAX_STAT_VALUE) {
|
|
2478
2474
|
boosts.spe -= 1;
|
|
@@ -2480,7 +2476,7 @@ pub const Effects = struct {
|
|
|
2480
2476
|
try log.boost(ident, .Speed, 2);
|
|
2481
2477
|
try log.boost(ident, .Speed, -1);
|
|
2482
2478
|
}
|
|
2483
|
-
return
|
|
2479
|
+
return log.fail(ident, .None);
|
|
2484
2480
|
}
|
|
2485
2481
|
var mod = BOOSTS[@as(u4, @intCast(@as(i8, boosts.spe) + 6))];
|
|
2486
2482
|
const stat = unmodifiedStats(battle, side).spe;
|
|
@@ -2489,7 +2485,7 @@ pub const Effects = struct {
|
|
|
2489
2485
|
},
|
|
2490
2486
|
.SpecialUp1, .SpecialUp2 => {
|
|
2491
2487
|
assert(boosts.spc >= -6 and boosts.spc <= 6);
|
|
2492
|
-
if (boosts.spc == 6) return
|
|
2488
|
+
if (boosts.spc == 6) return log.fail(ident, .None);
|
|
2493
2489
|
const n: u2 = if (move.effect == .SpecialUp2) 2 else 1;
|
|
2494
2490
|
boosts.spc = @intCast(@min(6, @as(i8, boosts.spc) + n));
|
|
2495
2491
|
if (stats.spc == MAX_STAT_VALUE) {
|
|
@@ -2500,7 +2496,7 @@ pub const Effects = struct {
|
|
|
2500
2496
|
try log.boost(ident, .SpecialDefense, n);
|
|
2501
2497
|
try log.boost(ident, .SpecialDefense, -1);
|
|
2502
2498
|
}
|
|
2503
|
-
return
|
|
2499
|
+
return log.fail(ident, .None);
|
|
2504
2500
|
}
|
|
2505
2501
|
var mod = BOOSTS[@as(u4, @intCast(@as(i8, boosts.spc) + 6))];
|
|
2506
2502
|
const stat = unmodifiedStats(battle, side).spc;
|
|
@@ -2510,7 +2506,7 @@ pub const Effects = struct {
|
|
|
2510
2506
|
},
|
|
2511
2507
|
.EvasionUp1 => {
|
|
2512
2508
|
assert(boosts.evasion >= -6 and boosts.evasion <= 6);
|
|
2513
|
-
if (boosts.evasion == 6) return
|
|
2509
|
+
if (boosts.evasion == 6) return log.fail(ident, .None);
|
|
2514
2510
|
boosts.evasion = @intCast(@min(6, @as(i8, boosts.evasion) + 1));
|
|
2515
2511
|
try log.boost(ident, .Evasion, 1);
|
|
2516
2512
|
},
|
|
@@ -2553,7 +2549,7 @@ pub const Effects = struct {
|
|
|
2553
2549
|
try log.boost(foe_ident, .Attack, -1);
|
|
2554
2550
|
try log.boost(foe_ident, .Attack, 1);
|
|
2555
2551
|
}
|
|
2556
|
-
return
|
|
2552
|
+
return log.fail(foe_ident, .None);
|
|
2557
2553
|
}
|
|
2558
2554
|
var mod = BOOSTS[@as(u4, @intCast(@as(i8, boosts.atk) + 6))];
|
|
2559
2555
|
const stat = unmodifiedStats(battle, foe).atk;
|
|
@@ -2571,7 +2567,7 @@ pub const Effects = struct {
|
|
|
2571
2567
|
try log.boost(foe_ident, .Defense, -@as(i8, n));
|
|
2572
2568
|
try log.boost(foe_ident, .Defense, 1);
|
|
2573
2569
|
}
|
|
2574
|
-
return
|
|
2570
|
+
return log.fail(foe_ident, .None);
|
|
2575
2571
|
}
|
|
2576
2572
|
var mod = BOOSTS[@as(u4, @intCast(@as(i8, boosts.def) + 6))];
|
|
2577
2573
|
const stat = unmodifiedStats(battle, foe).def;
|
|
@@ -2588,7 +2584,7 @@ pub const Effects = struct {
|
|
|
2588
2584
|
try log.boost(foe_ident, .Speed, -1);
|
|
2589
2585
|
try log.boost(foe_ident, .Speed, 1);
|
|
2590
2586
|
}
|
|
2591
|
-
return
|
|
2587
|
+
return log.fail(foe_ident, .None);
|
|
2592
2588
|
}
|
|
2593
2589
|
var mod = BOOSTS[@as(u4, @intCast(@as(i8, boosts.spe) + 6))];
|
|
2594
2590
|
const stat = unmodifiedStats(battle, foe).spe;
|
|
@@ -2608,7 +2604,7 @@ pub const Effects = struct {
|
|
|
2608
2604
|
try log.boost(foe_ident, .SpecialDefense, -1);
|
|
2609
2605
|
try log.boost(foe_ident, .SpecialDefense, 1);
|
|
2610
2606
|
}
|
|
2611
|
-
return
|
|
2607
|
+
return log.fail(foe_ident, .None);
|
|
2612
2608
|
}
|
|
2613
2609
|
var mod = BOOSTS[@as(u4, @intCast(@as(i8, boosts.spc) + 6))];
|
|
2614
2610
|
const stat = unmodifiedStats(battle, foe).spc;
|
package/src/lib/gen2/README.md
CHANGED
|
@@ -49,7 +49,6 @@ The following information is required to simulate a Generation II Pokémon battl
|
|
|
49
49
|
| `volatiles.bind` | `PlayerWrapCount` | `volatiles.partiallytrapped.duration` |
|
|
50
50
|
| `volatiles.bind_reason` | `PlayerTrappingMove` | `volatiles.effectState.sourceEffect` |
|
|
51
51
|
| | `PlayerCharging` | |
|
|
52
|
-
| `volatiles.trapped FIXME` | `FIXME` | `pokemon.trapped` |
|
|
53
52
|
| `volatiles.switched` | `TODO` | `pokemon.switchFlag` |
|
|
54
53
|
| `volatiles.switching` | `PlayerIsSwitching` | `pokemon.switchFlag` |
|
|
55
54
|
| `volatiles.frozen` | `PlayerJustGotFrozen` | `volatiles.frozen` |
|
package/src/lib/gen2/data.zig
CHANGED
|
@@ -314,16 +314,18 @@ pub const Volatiles = packed struct(u128) {
|
|
|
314
314
|
Encore: bool = false,
|
|
315
315
|
LockOn: bool = false,
|
|
316
316
|
DestinyBond: bool = false,
|
|
317
|
+
Trapped: bool = false,
|
|
317
318
|
|
|
318
|
-
trapped: bool = false,
|
|
319
319
|
switched: bool = false,
|
|
320
|
+
// TODO: replace with simply looking at Choice on Battle
|
|
320
321
|
switching: bool = false,
|
|
322
|
+
// TODO: simply store both last moves on side
|
|
321
323
|
dirty: bool = false,
|
|
322
324
|
|
|
323
325
|
frozen: bool = false,
|
|
324
326
|
minimized: bool = false,
|
|
325
327
|
_: u10 = 0,
|
|
326
|
-
// TODO?
|
|
328
|
+
// TODO: is this needed for unmodified stats?
|
|
327
329
|
transform: u4 = 0,
|
|
328
330
|
|
|
329
331
|
bide: u16 = 0,
|