@pkmn/engine 0.1.0-dev.dd5b9081 → 0.1.0-dev.e0e37c1b
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/README.md +5 -5
- 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 +2 -2
- package/build/pkg/gen1.js +2 -2
- package/build/pkg/gen1.js.map +1 -1
- package/build/pkg/protocol.js +56 -37
- package/build/pkg/protocol.js.map +1 -1
- package/build/tools/debug.js +3 -1
- package/build/tools/debug.js.map +1 -1
- package/build.zig +21 -15
- package/package.json +28 -16
- package/src/lib/binding/node.zig +1 -1
- package/src/lib/common/data.zig +5 -5
- package/src/lib/common/optional.zig +8 -1
- package/src/lib/common/protocol.zig +695 -270
- package/src/lib/common/rational.zig +5 -5
- package/src/lib/common/rng.zig +14 -5
- package/src/lib/gen1/README.md +28 -28
- package/src/lib/gen1/calc.zig +4 -4
- package/src/lib/gen1/chance.zig +53 -29
- package/src/lib/gen1/data/moves.zig +190 -176
- package/src/lib/gen1/data/species.zig +2 -2
- package/src/lib/gen1/data/types.zig +7 -7
- package/src/lib/gen1/data.zig +25 -25
- package/src/lib/gen1/helpers.zig +26 -41
- package/src/lib/gen1/mechanics.zig +283 -324
- package/src/lib/gen2/README.md +18 -72
- package/src/lib/gen2/calc.zig +143 -0
- package/src/lib/gen2/chance.zig +1314 -0
- package/src/lib/gen2/data/items.zig +12 -18
- package/src/lib/gen2/data/moves.zig +377 -344
- package/src/lib/gen2/data/species.zig +1 -1
- package/src/lib/gen2/data/types.zig +134 -31
- package/src/lib/gen2/data.zig +44 -36
- package/src/lib/gen2/generated.zig +808 -0
- package/src/lib/gen2/mechanics.zig +3000 -206
|
@@ -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
|
|
|
@@ -185,12 +185,12 @@ pub fn Rational(comptime T: type) type {
|
|
|
185
185
|
try writer.print("{d}/{d}", .{ self.p, self.q });
|
|
186
186
|
}
|
|
187
187
|
|
|
188
|
-
|
|
188
|
+
fn multiplication(r: *Self, p: anytype, q: anytype) !void {
|
|
189
189
|
r.p = try std.math.mul(T, r.p, p);
|
|
190
190
|
r.q = try std.math.mul(T, r.q, q);
|
|
191
191
|
}
|
|
192
192
|
|
|
193
|
-
|
|
193
|
+
fn addition(r: *Self, p: anytype, q: anytype) !void {
|
|
194
194
|
// (a/b) + (c/d) = (ad+bc)/(bd)
|
|
195
195
|
var d = try std.math.mul(T, r.q, q);
|
|
196
196
|
var n1 = try std.math.mul(T, r.p, q);
|
|
@@ -203,7 +203,7 @@ pub fn Rational(comptime T: type) type {
|
|
|
203
203
|
}
|
|
204
204
|
|
|
205
205
|
// https://en.wikipedia.org/wiki/Euclidean_algorithm
|
|
206
|
-
|
|
206
|
+
fn gcd(p: anytype, q: anytype) @TypeOf(p, q) {
|
|
207
207
|
assert(p >= 1);
|
|
208
208
|
assert(q >= 1);
|
|
209
209
|
|
|
@@ -275,7 +275,7 @@ pub const BigRational = struct {
|
|
|
275
275
|
/// Create a new BigRational wrapper. A small amount of memory will be allocated on
|
|
276
276
|
/// initialization. Not default initialized to 1 - you must explicitly `reset` first.
|
|
277
277
|
pub fn init(alloc: std.mem.Allocator) !BigRational {
|
|
278
|
-
return
|
|
278
|
+
return .{ .val = try std.math.big.Rational.init(alloc) };
|
|
279
279
|
}
|
|
280
280
|
|
|
281
281
|
/// Frees all memory associated with a rational.
|
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
|
|
|
@@ -64,7 +69,7 @@ pub const PSRNG = extern struct {
|
|
|
64
69
|
};
|
|
65
70
|
|
|
66
71
|
test PSRNG {
|
|
67
|
-
var psrng =
|
|
72
|
+
var psrng: PSRNG = .{ .src = .{ .seed = 0x0001000200030004 } };
|
|
68
73
|
try expectEqual(@as(u8, 121), psrng.range(u8, 0, 256));
|
|
69
74
|
try expectEqual(false, psrng.chance(u8, 128, 256)); // 226 < 128
|
|
70
75
|
}
|
|
@@ -89,11 +94,15 @@ 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 {
|
|
95
104
|
const expected = [_]u8{ 6, 11, 16, 21, 26, 31, 36, 41, 46, 31, 56, 81 };
|
|
96
|
-
var rng =
|
|
105
|
+
var rng: Gen12 = .{ .seed = .{ 1, 2, 3, 4, 5, 6, 7, 8, 9 } };
|
|
97
106
|
for (expected) |e| {
|
|
98
107
|
try expectEqual(e, rng.next());
|
|
99
108
|
}
|
|
@@ -129,7 +138,7 @@ test Gen34 {
|
|
|
129
138
|
.{ 0x80000000, 5, 0x0E425287 }, .{ 0x80000000, 10, 0x6F2CF4B2 },
|
|
130
139
|
};
|
|
131
140
|
for (data) |d| {
|
|
132
|
-
var rng =
|
|
141
|
+
var rng: Gen34 = .{ .seed = d[0] };
|
|
133
142
|
for (0..d[1]) |_| _ = rng.next();
|
|
134
143
|
try expectEqual(d[2], rng.seed);
|
|
135
144
|
}
|
|
@@ -161,7 +170,7 @@ test Gen56 {
|
|
|
161
170
|
.{ 0x8000000000000000, 10, 0xE7795501267F125A },
|
|
162
171
|
};
|
|
163
172
|
for (data) |d| {
|
|
164
|
-
var rng =
|
|
173
|
+
var rng: Gen56 = .{ .seed = d[0] };
|
|
165
174
|
for (0..d[1]) |_| _ = rng.next();
|
|
166
175
|
try expectEqual(d[2], rng.seed);
|
|
167
176
|
}
|
|
@@ -213,7 +222,7 @@ pub fn FixedRNG(comptime gen: comptime_int, comptime len: usize) type {
|
|
|
213
222
|
test FixedRNG {
|
|
214
223
|
const Type = if (showdown) u32 else u8;
|
|
215
224
|
const expected = [_]Type{ 42, 255, 0 };
|
|
216
|
-
var rng
|
|
225
|
+
var rng: FixedRNG(1, expected.len) = .{ .rolls = expected };
|
|
217
226
|
for (expected) |e| {
|
|
218
227
|
try expectEqual(e, rng.next());
|
|
219
228
|
}
|
package/src/lib/gen1/README.md
CHANGED
|
@@ -427,34 +427,34 @@ data in the browser for ease of debugging.
|
|
|
427
427
|
|
|
428
428
|
> **NOTE:** The offsets in the following table represent *bits* and **not** bytes.
|
|
429
429
|
|
|
430
|
-
| Start | End | Data
|
|
431
|
-
| ----- | --- |
|
|
432
|
-
| 0 | 1 | `Bide`
|
|
433
|
-
| 1 | 2 | `Thrashing`
|
|
434
|
-
| 2 | 3 | `MultiHit`
|
|
435
|
-
| 3 | 4 | `Flinch`
|
|
436
|
-
| 4 | 5 | `Charging`
|
|
437
|
-
| 5 | 6 | `Binding`
|
|
438
|
-
| 6 | 7 | `Invulnerable`
|
|
439
|
-
| 7 | 8 | `Confusion`
|
|
440
|
-
| 8 | 9 | `Mist`
|
|
441
|
-
| 9 | 10 | `FocusEnergy`
|
|
442
|
-
| 10 | 11 | `Substitute`
|
|
443
|
-
| 11 | 12 | `Recharging`
|
|
444
|
-
| 12 | 13 | `Rage`
|
|
445
|
-
| 13 | 14 | `LeechSeed`
|
|
446
|
-
| 14 | 15 | `Toxic`
|
|
447
|
-
| 15 | 16 | `LightScreen`
|
|
448
|
-
| 16 | 17 | `Reflect`
|
|
449
|
-
| 17 | 18 | `Transform`
|
|
450
|
-
| 18 | 21 | `confusion`
|
|
451
|
-
| 21 | 24 | `attacks`
|
|
452
|
-
| 24 | 40 | `state`
|
|
453
|
-
| 40 | 48 | `substitute`
|
|
454
|
-
| 48 | 52 | `transform`
|
|
455
|
-
| 52 | 56 | `
|
|
456
|
-
| 56 | 59 | `
|
|
457
|
-
| 59 | 64 | `toxic`
|
|
430
|
+
| Start | End | Data | Description |
|
|
431
|
+
| ----- | --- | -------------------| ----------------------------------------------------------- |
|
|
432
|
+
| 0 | 1 | `Bide` | Whether the "Bide" volatile status is present |
|
|
433
|
+
| 1 | 2 | `Thrashing` | Whether the "Thrashing" volatile status is present |
|
|
434
|
+
| 2 | 3 | `MultiHit` | Whether the "MultiHit" volatile status is present |
|
|
435
|
+
| 3 | 4 | `Flinch` | Whether the "Flinch" volatile status is present |
|
|
436
|
+
| 4 | 5 | `Charging` | Whether the "Charging" volatile status is present |
|
|
437
|
+
| 5 | 6 | `Binding` | Whether the "Binding" volatile status is present |
|
|
438
|
+
| 6 | 7 | `Invulnerable` | Whether the "Invulnerable" volatile status is present |
|
|
439
|
+
| 7 | 8 | `Confusion` | Whether the "Confusion" volatile status is present |
|
|
440
|
+
| 8 | 9 | `Mist` | Whether the "Mist" volatile status is present |
|
|
441
|
+
| 9 | 10 | `FocusEnergy` | Whether the "FocusEnergy" volatile status is present |
|
|
442
|
+
| 10 | 11 | `Substitute` | Whether the "Substitute" volatile status is present |
|
|
443
|
+
| 11 | 12 | `Recharging` | Whether the "Recharging" volatile status is present |
|
|
444
|
+
| 12 | 13 | `Rage` | Whether the "Rage" volatile status is present |
|
|
445
|
+
| 13 | 14 | `LeechSeed` | Whether the "LeechSeed" volatile status is present |
|
|
446
|
+
| 14 | 15 | `Toxic` | Whether the "Toxic" volatile status is present |
|
|
447
|
+
| 15 | 16 | `LightScreen` | Whether the "LightScreen" volatile status is present |
|
|
448
|
+
| 16 | 17 | `Reflect` | Whether the "Reflect" volatile status is present |
|
|
449
|
+
| 17 | 18 | `Transform` | Whether the "Transform" volatile status is present |
|
|
450
|
+
| 18 | 21 | `confusion` | The remaining turns of confusion |
|
|
451
|
+
| 21 | 24 | `attacks` | The number of attacks remaining |
|
|
452
|
+
| 24 | 40 | `state` | A union of either: <ul><li>the total accumulated damage from Bide</li><li>the overwritten accuracy of certain moves</li></ul> |
|
|
453
|
+
| 40 | 48 | `substitute` | The remaining HP of the Substitute |
|
|
454
|
+
| 48 | 52 | `transform` | The identity of whom the active Pokémon is transformed into |
|
|
455
|
+
| 52 | 56 | `disable_duration` | The remaining turns the move is disabled |
|
|
456
|
+
| 56 | 59 | `disable_move` | The move slot (1-4) that's disabled |
|
|
457
|
+
| 59 | 64 | `toxic` | The number of turns toxic damage has been accumulating |
|
|
458
458
|
|
|
459
459
|
### `Pokemon`
|
|
460
460
|
|
package/src/lib/gen1/calc.zig
CHANGED
|
@@ -50,7 +50,7 @@ pub const Summaries = extern struct {
|
|
|
50
50
|
}
|
|
51
51
|
|
|
52
52
|
/// Returns the `Summary` for the given `player`.
|
|
53
|
-
pub
|
|
53
|
+
pub fn get(self: anytype, player: Player) PointerType(@TypeOf(self), Summary) {
|
|
54
54
|
assert(@typeInfo(@TypeOf(self)).Pointer.child == Summaries);
|
|
55
55
|
return if (player == .P1) &self.p1 else &self.p2;
|
|
56
56
|
}
|
|
@@ -157,7 +157,7 @@ pub const Calc = struct {
|
|
|
157
157
|
|
|
158
158
|
/// Null object pattern implementation of Generation I `Calc` which does nothing, though damage
|
|
159
159
|
/// calculator support should additionally be turned off entirely via `options.calc`.
|
|
160
|
-
pub const NULL =
|
|
160
|
+
pub const NULL: Null = .{};
|
|
161
161
|
|
|
162
162
|
const Null = struct {
|
|
163
163
|
pub fn overridden(
|
|
@@ -255,7 +255,7 @@ pub fn transitions(
|
|
|
255
255
|
|
|
256
256
|
try debug(writer, template, true, .{ .color = i, .bold = true, .background = true });
|
|
257
257
|
|
|
258
|
-
var a =
|
|
258
|
+
var a: Actions = .{ .p1 = .{ .metronome = p1_move }, .p2 = .{ .metronome = p2_move } };
|
|
259
259
|
|
|
260
260
|
for (Rolls.speedTie(template.p1)) |tie| { a.p1.speed_tie = tie; a.p2.speed_tie = tie;
|
|
261
261
|
for (Rolls.sleep(template.p1, actions.p1)) |p1_slp| { a.p1.durations.sleep = p1_slp;
|
|
@@ -387,7 +387,7 @@ pub fn transitions(
|
|
|
387
387
|
return stats;
|
|
388
388
|
}
|
|
389
389
|
|
|
390
|
-
|
|
390
|
+
fn matches(actions: Actions, i: usize, frontier: []Actions) bool {
|
|
391
391
|
for (frontier, 0..) |f, j| {
|
|
392
392
|
// TODO: is skipping this redundant check worth it?
|
|
393
393
|
if (i == j) continue;
|
package/src/lib/gen1/chance.zig
CHANGED
|
@@ -14,12 +14,14 @@ 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
|
|
18
|
-
const MoveSlot = @import("data.zig").MoveSlot;
|
|
17
|
+
const data = @import("./data.zig");
|
|
19
18
|
|
|
20
19
|
const enabled = options.chance;
|
|
21
20
|
const showdown = options.showdown;
|
|
22
21
|
|
|
22
|
+
const Move = data.Move;
|
|
23
|
+
const MoveSlot = data.MoveSlot;
|
|
24
|
+
|
|
23
25
|
/// Actions taken by a hypothetical "chance player" that convey information about which RNG events
|
|
24
26
|
/// were observed during a Generation I battle `update`. This can additionally be provided as input
|
|
25
27
|
/// to the `update` call to override the normal behavior of the RNG in order to force specific
|
|
@@ -35,19 +37,19 @@ pub const Actions = extern struct {
|
|
|
35
37
|
}
|
|
36
38
|
|
|
37
39
|
/// Returns the `Action` for the given `player`.
|
|
38
|
-
pub
|
|
40
|
+
pub fn get(self: anytype, player: Player) util.PointerType(@TypeOf(self), Action) {
|
|
39
41
|
assert(@typeInfo(@TypeOf(self)).Pointer.child == Actions);
|
|
40
42
|
return if (player == .P1) &self.p1 else &self.p2;
|
|
41
43
|
}
|
|
42
44
|
|
|
43
45
|
/// Perform a reset by clearing fields which should not persist across updates.
|
|
44
|
-
pub
|
|
46
|
+
pub fn reset(self: *Actions) void {
|
|
45
47
|
self.p1.reset();
|
|
46
48
|
self.p2.reset();
|
|
47
49
|
}
|
|
48
50
|
|
|
49
51
|
/// Returns true if `a` is equal to `b`.
|
|
50
|
-
pub
|
|
52
|
+
pub fn eql(a: Actions, b: Actions) bool {
|
|
51
53
|
return @as(u128, @bitCast(a)) == @as(u128, @bitCast(b));
|
|
52
54
|
}
|
|
53
55
|
|
|
@@ -157,7 +159,7 @@ pub const Action = packed struct(u64) {
|
|
|
157
159
|
pub const Field = std.meta.FieldEnum(Action);
|
|
158
160
|
|
|
159
161
|
/// Perform a reset by clearing fields which should not persist across updates.
|
|
160
|
-
pub
|
|
162
|
+
pub fn reset(self: *Action) void {
|
|
161
163
|
self.* = @bitCast(@as(u64, @bitCast(self.*)) & DURATIONS);
|
|
162
164
|
}
|
|
163
165
|
|
|
@@ -215,7 +217,7 @@ pub const Action = packed struct(u64) {
|
|
|
215
217
|
};
|
|
216
218
|
|
|
217
219
|
test Action {
|
|
218
|
-
var a =
|
|
220
|
+
var a: Action = .{ .hit = .true, .durations = .{ .sleep = 3 }, .damage = 225 };
|
|
219
221
|
a.reset();
|
|
220
222
|
|
|
221
223
|
try expectEqual(Action{ .hit = .None, .durations = .{ .sleep = 3 }, .damage = 0 }, a);
|
|
@@ -514,22 +516,6 @@ pub fn Chance(comptime Rational: type) type {
|
|
|
514
516
|
}
|
|
515
517
|
}
|
|
516
518
|
|
|
517
|
-
pub fn disable(self: *Self, player: Player, turns: u4) Error!void {
|
|
518
|
-
if (!enabled) return;
|
|
519
|
-
|
|
520
|
-
var durations = &self.actions.get(player).durations;
|
|
521
|
-
const n = durations.disable;
|
|
522
|
-
if (turns == 0) {
|
|
523
|
-
assert(n >= 1 and n <= 8);
|
|
524
|
-
if (n != 8) try self.probability.update(1, 9 - @as(u4, n));
|
|
525
|
-
durations.disable = 0;
|
|
526
|
-
} else {
|
|
527
|
-
assert(n >= 1 and n < 8);
|
|
528
|
-
try self.probability.update(9 - @as(u4, n) - 1, 9 - @as(u4, n));
|
|
529
|
-
durations.disable += 1;
|
|
530
|
-
}
|
|
531
|
-
}
|
|
532
|
-
|
|
533
519
|
pub fn confusion(self: *Self, player: Player, turns: u4) Error!void {
|
|
534
520
|
if (!enabled) return;
|
|
535
521
|
|
|
@@ -546,6 +532,22 @@ pub fn Chance(comptime Rational: type) type {
|
|
|
546
532
|
}
|
|
547
533
|
}
|
|
548
534
|
|
|
535
|
+
pub fn disable(self: *Self, player: Player, turns: u4) Error!void {
|
|
536
|
+
if (!enabled) return;
|
|
537
|
+
|
|
538
|
+
var durations = &self.actions.get(player).durations;
|
|
539
|
+
const n = durations.disable;
|
|
540
|
+
if (turns == 0) {
|
|
541
|
+
assert(n >= 1 and n <= 8);
|
|
542
|
+
if (n != 8) try self.probability.update(1, 9 - @as(u4, n));
|
|
543
|
+
durations.disable = 0;
|
|
544
|
+
} else {
|
|
545
|
+
assert(n >= 1 and n < 8);
|
|
546
|
+
try self.probability.update(9 - @as(u4, n) - 1, 9 - @as(u4, n));
|
|
547
|
+
durations.disable += 1;
|
|
548
|
+
}
|
|
549
|
+
}
|
|
550
|
+
|
|
549
551
|
pub fn attacking(self: *Self, player: Player, turns: u4) Error!void {
|
|
550
552
|
if (!enabled) return;
|
|
551
553
|
|
|
@@ -593,7 +595,7 @@ pub fn Chance(comptime Rational: type) type {
|
|
|
593
595
|
pub fn metronome(self: *Self, player: Player, move: Move) Error!void {
|
|
594
596
|
if (!enabled) return;
|
|
595
597
|
|
|
596
|
-
try self.probability.update(1, Move.
|
|
598
|
+
try self.probability.update(1, Move.METRONOME.len);
|
|
597
599
|
self.actions.get(player).metronome = move;
|
|
598
600
|
}
|
|
599
601
|
};
|
|
@@ -856,6 +858,28 @@ test "Chance.confusion" {
|
|
|
856
858
|
}
|
|
857
859
|
}
|
|
858
860
|
|
|
861
|
+
test "Chance.disable" {
|
|
862
|
+
var chance: Chance(rational.Rational(u64)) = .{ .probability = .{} };
|
|
863
|
+
|
|
864
|
+
for ([_]u8{ 8, 7, 6, 5, 4, 3, 2, 1 }, 1..9) |d, i| {
|
|
865
|
+
chance.actions.p1.durations.disable = @intCast(i);
|
|
866
|
+
try chance.disable(.P1, 0);
|
|
867
|
+
try expectProbability(&chance.probability, 1, d);
|
|
868
|
+
try expectValue(@as(u4, 0), chance.actions.p1.durations.disable);
|
|
869
|
+
|
|
870
|
+
chance.reset();
|
|
871
|
+
|
|
872
|
+
if (i < 8) {
|
|
873
|
+
chance.actions.p1.durations.disable = @intCast(i);
|
|
874
|
+
try chance.disable(.P1, 1);
|
|
875
|
+
try expectProbability(&chance.probability, d - 1, d);
|
|
876
|
+
try expectValue(@as(u4, @intCast(i)) + 1, chance.actions.p1.durations.disable);
|
|
877
|
+
|
|
878
|
+
chance.reset();
|
|
879
|
+
}
|
|
880
|
+
}
|
|
881
|
+
}
|
|
882
|
+
|
|
859
883
|
test "Chance.attacking" {
|
|
860
884
|
var chance: Chance(rational.Rational(u64)) = .{ .probability = .{} };
|
|
861
885
|
|
|
@@ -939,7 +963,7 @@ pub fn expectValue(a: anytype, b: anytype) !void {
|
|
|
939
963
|
|
|
940
964
|
/// Null object pattern implementation of Generation I `Chance` which does nothing, though chance
|
|
941
965
|
/// tracking should additionally be turned off entirely via `options.chance`.
|
|
942
|
-
pub const NULL =
|
|
966
|
+
pub const NULL: Null = .{};
|
|
943
967
|
|
|
944
968
|
const Null = struct {
|
|
945
969
|
pub const Error = error{};
|
|
@@ -976,10 +1000,6 @@ const Null = struct {
|
|
|
976
1000
|
_ = .{ self, player, roll };
|
|
977
1001
|
}
|
|
978
1002
|
|
|
979
|
-
pub fn secondaryChance(self: Null, player: Player, proc: bool, rate: u8) Error!void {
|
|
980
|
-
_ = .{ self, player, proc, rate };
|
|
981
|
-
}
|
|
982
|
-
|
|
983
1003
|
pub fn confused(self: Null, player: Player, ok: bool) Error!void {
|
|
984
1004
|
_ = .{ self, player, ok };
|
|
985
1005
|
}
|
|
@@ -988,6 +1008,10 @@ const Null = struct {
|
|
|
988
1008
|
_ = .{ self, player, ok };
|
|
989
1009
|
}
|
|
990
1010
|
|
|
1011
|
+
pub fn secondaryChance(self: Null, player: Player, proc: bool, rate: u8) Error!void {
|
|
1012
|
+
_ = .{ self, player, proc, rate };
|
|
1013
|
+
}
|
|
1014
|
+
|
|
991
1015
|
pub fn moveSlot(self: Null, player: Player, slot: u4, ms: []const MoveSlot, n: u4) Error!void {
|
|
992
1016
|
_ = .{ self, player, slot, ms, n };
|
|
993
1017
|
}
|