@pkmn/engine 0.1.0-dev.8b192003 → 0.1.0-dev.8cf7e679

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.
Files changed (76) hide show
  1. package/README.md +9 -6
  2. package/build/pkg/addon/browser.d.ts +3 -0
  3. package/build/pkg/addon/browser.js +44 -0
  4. package/build/pkg/addon/browser.js.map +1 -0
  5. package/build/pkg/addon/node.d.ts +3 -0
  6. package/build/pkg/addon/node.js +97 -0
  7. package/build/pkg/addon/node.js.map +1 -0
  8. package/build/pkg/addon/wasm.d.ts +2 -0
  9. package/build/pkg/addon/wasm.js +44 -0
  10. package/build/pkg/addon/wasm.js.map +1 -0
  11. package/build/pkg/addon.d.ts +25 -3
  12. package/build/pkg/addon.js +34 -65
  13. package/build/pkg/addon.js.map +1 -1
  14. package/build/pkg/data/layout.json +15 -2
  15. package/build/pkg/data/protocol.json +23 -9
  16. package/build/pkg/data.d.ts +23 -1
  17. package/build/pkg/data.js.map +1 -1
  18. package/build/pkg/gen1.d.ts +13 -17
  19. package/build/pkg/gen1.js +6 -10
  20. package/build/pkg/gen1.js.map +1 -1
  21. package/build/pkg/index.d.ts +38 -90
  22. package/build/pkg/index.js +6 -63
  23. package/build/pkg/index.js.map +1 -1
  24. package/build/pkg/protocol.d.ts +20 -1
  25. package/build/pkg/protocol.js +105 -103
  26. package/build/pkg/protocol.js.map +1 -1
  27. package/build/tools/debug.js +35 -69
  28. package/build/tools/debug.js.map +1 -1
  29. package/build/tools/display/debug.jsx +141 -0
  30. package/build/tools/display/debug.jsx.map +1 -0
  31. package/build/tools/display/index.js +141 -0
  32. package/build/tools/display/index.js.map +1 -0
  33. package/build/tools/display/ui.jsx +349 -0
  34. package/build/tools/display/ui.jsx.map +1 -0
  35. package/build/tools/display/util.js +18 -0
  36. package/build/tools/display/util.js.map +1 -0
  37. package/build.zig +254 -77
  38. package/package.json +50 -134
  39. package/src/bin/install-pkmn-engine +9 -7
  40. package/src/bin/pkmn-debug +1 -1
  41. package/src/lib/common/array.zig +77 -0
  42. package/src/lib/common/data.zig +8 -8
  43. package/src/lib/common/debug.zig +39 -8
  44. package/src/lib/common/js.zig +4 -2
  45. package/src/lib/common/optional.zig +13 -9
  46. package/src/lib/common/options.zig +4 -0
  47. package/src/lib/common/protocol.zig +45 -44
  48. package/src/lib/common/rational.zig +53 -51
  49. package/src/lib/common/rng.zig +5 -7
  50. package/src/lib/common/util.zig +50 -1
  51. package/src/lib/gen1/calc.zig +295 -154
  52. package/src/lib/gen1/chance.zig +477 -119
  53. package/src/lib/gen1/data/moves.zig +2 -4
  54. package/src/lib/gen1/data/species.zig +1 -3
  55. package/src/lib/gen1/data/types.zig +1 -2
  56. package/src/lib/gen1/data.zig +35 -38
  57. package/src/lib/gen1/helpers.zig +17 -27
  58. package/src/lib/gen1/mechanics.zig +248 -148
  59. package/src/lib/gen2/calc.zig +37 -27
  60. package/src/lib/gen2/chance.zig +87 -67
  61. package/src/lib/gen2/data/items.zig +1 -3
  62. package/src/lib/gen2/data/moves.zig +2 -4
  63. package/src/lib/gen2/data/species.zig +1 -3
  64. package/src/lib/gen2/data/types.zig +1 -2
  65. package/src/lib/gen2/data.zig +26 -29
  66. package/src/lib/gen2/generated.zig +18 -23
  67. package/src/lib/gen2/helpers.zig +9 -18
  68. package/src/lib/gen2/mechanics.zig +81 -81
  69. package/src/lib/node.zig +2 -4
  70. package/src/lib/pkmn.zig +11 -5
  71. package/src/lib/wasm.zig +36 -1
  72. package/src/tools/display/dom.ts +96 -0
  73. package/src/tools/display/ui.css +354 -0
  74. package/build/test/display.js +0 -400
  75. package/build/test/display.js.map +0 -1
  76. package/src/test/display/pkmn.html.tmpl +0 -368
@@ -1,22 +1,22 @@
1
- const std = @import("std");
2
-
3
- const pkmn = @import("../pkmn.zig");
4
-
1
+ const chance = @import("chance.zig");
5
2
  const common = @import("../common/data.zig");
3
+ const Optional = @import("../common/optional.zig").Optional;
4
+ const pkmn = @import("../pkmn.zig");
5
+ const std = @import("std");
6
6
  const util = @import("../common/util.zig");
7
7
 
8
- const chance = @import("chance.zig");
9
-
8
+ const Action = chance.Action;
9
+ const Actions = chance.Actions;
10
10
  const assert = std.debug.assert;
11
-
11
+ const Criticals = chance.Criticals;
12
+ const Damages = chance.Damages;
12
13
  const enabled = pkmn.options.calc;
13
-
14
+ const isPointerTo = util.isPointerTo;
14
15
  const Player = common.Player;
15
-
16
16
  const PointerType = util.PointerType;
17
17
 
18
- const Actions = chance.Actions;
19
- const Action = chance.Action;
18
+ const Int = if (@hasField(std.builtin.Type, "int")) .int else .Int;
19
+ const Enum = if (@hasField(std.builtin.Type, "enum")) .@"enum" else .Enum;
20
20
 
21
21
  /// Information relevant to damage calculation that occured during a Generation II battle `update`.
22
22
  pub const Summaries = extern struct {
@@ -31,7 +31,7 @@ pub const Summaries = extern struct {
31
31
 
32
32
  /// Returns the `Summary` for the given `player`.
33
33
  pub fn get(self: anytype, player: Player) PointerType(@TypeOf(self), Summary) {
34
- assert(@typeInfo(@TypeOf(self)).Pointer.child == Summaries);
34
+ assert(isPointerTo(self, Summaries));
35
35
  return if (player == .P1) &self.p1 else &self.p2;
36
36
  }
37
37
  };
@@ -65,33 +65,34 @@ pub const Summary = extern struct {
65
65
  }
66
66
  };
67
67
 
68
- /// TODO
69
- pub const Overrides = extern struct {
70
- /// TODO
71
- actions: Actions = .{},
72
- };
73
-
74
68
  /// Allows for forcing the value of specific RNG events during a Generation II battle `update` via
75
69
  /// `overrides` and tracks `summaries` of information relevant to damage calculation.
76
70
  pub const Calc = struct {
77
71
  /// Overrides the normal behavior of the RNG during an `update` to force specific outcomes.
78
- overrides: Overrides = .{},
72
+ overrides: Actions = .{},
79
73
  /// Information relevant to damage calculation.
80
74
  summaries: Summaries = .{},
81
75
 
82
76
  pub fn overridden(
83
77
  self: Calc,
84
78
  player: Player,
79
+ hit: u3,
85
80
  comptime field: Action.Field,
86
- ) ?std.meta.FieldType(Action, field) {
81
+ ) ReturnType(field) {
87
82
  if (!enabled) return null;
88
83
 
89
- const overrides =
90
- if (player == .P1) self.overrides.actions.p1 else self.overrides.actions.p2;
91
- const val = @field(overrides, @tagName(field));
84
+ const val = switch (field) {
85
+ .damages => Damages.get(self.overrides.get(player).damages, hit),
86
+ .critical_hits => Criticals.get(self.overrides.get(player).critical_hits, hit),
87
+ else => val: {
88
+ assert(hit == 0);
89
+ break :val @field(self.overrides.get(player), @tagName(field));
90
+ },
91
+ };
92
+
92
93
  return if (switch (@typeInfo(@TypeOf(val))) {
93
- .Enum => val != .None,
94
- .Int => val != 0,
94
+ Enum => val != .None,
95
+ Int => val != 0,
95
96
  else => unreachable,
96
97
  }) val else null;
97
98
  }
@@ -123,9 +124,10 @@ const Null = struct {
123
124
  pub fn overridden(
124
125
  self: Null,
125
126
  player: Player,
127
+ hit: u3,
126
128
  comptime field: Action.Field,
127
- ) ?std.meta.FieldType(Action, field) {
128
- _ = .{ self, player };
129
+ ) ReturnType(field) {
130
+ _ = .{ self, player, hit };
129
131
  return null;
130
132
  }
131
133
 
@@ -141,3 +143,11 @@ const Null = struct {
141
143
  _ = .{ self, player };
142
144
  }
143
145
  };
146
+
147
+ fn ReturnType(comptime field: Action.Field) type {
148
+ return ?(switch (field) {
149
+ .damages => u8,
150
+ .critical_hits => Optional(bool),
151
+ else => std.meta.FieldType(Action, field),
152
+ });
153
+ }
@@ -8,9 +8,9 @@ const expectEqual = std.testing.expectEqual;
8
8
 
9
9
  const options = @import("../common/options.zig");
10
10
  const rational = @import("../common/rational.zig");
11
- const rng = @import("../common/rng.zig");
12
11
  const util = @import("../common/util.zig");
13
12
 
13
+ const Array = @import("../common/array.zig").Array;
14
14
  const Player = @import("../common/data.zig").Player;
15
15
  const Optional = @import("../common/optional.zig").Optional;
16
16
 
@@ -19,13 +19,18 @@ const data = @import("data.zig");
19
19
  const enabled = options.chance;
20
20
  const showdown = options.showdown;
21
21
 
22
- const Gen12 = rng.Gen12;
22
+ const PointerType = util.PointerType;
23
+ const isPointerTo = util.isPointerTo;
23
24
 
24
25
  const Move = data.Move;
25
26
  const Type = data.Type;
26
27
  const Effectiveness = data.Effectiveness;
27
28
  const TriAttack = data.TriAttack;
28
29
 
30
+ const Int = if (@hasField(std.builtin.Type, "int")) .int else .Int;
31
+ const Enum = if (@hasField(std.builtin.Type, "enum")) .@"enum" else .Enum;
32
+ const Struct = if (@hasField(std.builtin.Type, "struct")) .@"struct" else .Struct;
33
+
29
34
  /// Actions taken by a hypothetical "chance player" that convey information about which RNG events
30
35
  /// were observed during a Generation II battle `update`. This can additionally be provided as input
31
36
  /// to the `update` call to override the normal behavior of the RNG in order to force specific
@@ -37,8 +42,8 @@ pub const Actions = extern struct {
37
42
  p2: Action = .{},
38
43
 
39
44
  /// Returns the `Action` for the given `player`.
40
- pub fn get(self: anytype, player: Player) util.PointerType(@TypeOf(self), Action) {
41
- assert(@typeInfo(@TypeOf(self)).Pointer.child == Actions);
45
+ pub fn get(self: anytype, player: Player) PointerType(@TypeOf(self), Action) {
46
+ assert(isPointerTo(self, Actions));
42
47
  return if (player == .P1) &self.p1 else &self.p2;
43
48
  }
44
49
 
@@ -52,15 +57,15 @@ pub const Actions = extern struct {
52
57
  /// same shape if they have the same fields set (though those fields need not necessarily be
53
58
  /// set to the same value).
54
59
  pub fn matches(a: Actions, b: Actions) bool {
55
- inline for (@typeInfo(Actions).Struct.fields) |player| {
56
- inline for (@typeInfo(Action).Struct.fields) |field| {
60
+ inline for (@field(@typeInfo(Actions), @tagName(Struct)).fields) |player| {
61
+ inline for (@field(@typeInfo(Action), @tagName(Struct)).fields) |field| {
57
62
  const a_val = @field(@field(a, player.name), field.name);
58
63
  const b_val = @field(@field(b, player.name), field.name);
59
64
 
60
65
  switch (@typeInfo(@TypeOf(a_val))) {
61
- .Enum => if ((@intFromEnum(a_val) > 0) != (@intFromEnum(b_val) > 0))
66
+ Enum => if ((@intFromEnum(a_val) > 0) != (@intFromEnum(b_val) > 0))
62
67
  return false,
63
- .Int => if ((a_val > 0) != (b_val > 0)) return false,
68
+ Int => if ((a_val > 0) != (b_val > 0)) return false,
64
69
  else => unreachable,
65
70
  }
66
71
  }
@@ -82,10 +87,9 @@ pub const Actions = extern struct {
82
87
  }
83
88
  };
84
89
 
85
- // TODO: ziglang/zig#19730
86
90
  test Actions {
87
- const a: Actions = .{ .p1 = .{ .hit = .true, .critical_hit = .false, .damage = 245 } };
88
- const b: Actions = .{ .p1 = .{ .hit = .false, .critical_hit = .true, .damage = 246 } };
91
+ const a: Actions = .{ .p1 = .{ .hit = .true, .confused = .false, .damages = 245 } };
92
+ const b: Actions = .{ .p1 = .{ .hit = .false, .confused = .true, .damages = 246 } };
89
93
  const c: Actions = .{ .p1 = .{ .hit = .true } };
90
94
 
91
95
  try expect(a.eql(a));
@@ -101,11 +105,19 @@ test Actions {
101
105
  try expect(!c.matches(a));
102
106
  }
103
107
 
108
+ /// Observation made about a duration - whether the duration has started, been continued, or ended.
109
+ pub const Observation = enum { started, continuing, ended };
110
+
111
+ pub const Damages = Array(5, u8);
112
+ pub const Criticals = Array(5, Optional(bool));
113
+
104
114
  /// Information about the RNG that was observed during a Generation II battle `update` for a
105
115
  /// single player.
106
116
  pub const Action = packed struct(u128) {
107
- /// If not 0, the roll to be returned Rolls.damage.
108
- damage: u8 = 0,
117
+ /// TODO
118
+ damages: Damages.T = 0,
119
+ // TODO
120
+ critical_hits: Criticals.T = 0,
109
121
 
110
122
  /// If not None, the Player to be returned by Rolls.speedTie.
111
123
  speed_tie: Optional(Player) = .None,
@@ -113,50 +125,58 @@ pub const Action = packed struct(u128) {
113
125
  quick_claw: Optional(bool) = .None,
114
126
  /// If not None, the value to return for Rolls.hit.
115
127
  hit: Optional(bool) = .None,
116
- /// If not None, the value to be returned by Rolls.criticalHit.
117
- critical_hit: Optional(bool) = .None,
118
-
119
128
  /// If not None, the value to return for Rolls.confused.
120
129
  confused: Optional(bool) = .None,
130
+
121
131
  /// If not None, the value to return for Rolls.attract.
122
132
  attract: Optional(bool) = .None,
123
133
  /// If not None, the value to return for Rolls.paralyzed.
124
134
  paralyzed: Optional(bool) = .None,
125
135
  /// If not None, the value to return for Rolls.defrost.
126
136
  defrost: Optional(bool) = .None,
127
-
128
137
  /// If not None, the value to be returned for Rolls.secondaryChance.
129
138
  secondary_chance: Optional(bool) = .None,
139
+
130
140
  /// If not None, the value to be returned for Rolls.item (Focus Band / King's Rock).
131
141
  item: Optional(bool) = .None,
132
142
  /// If not None, the value to be returned for Rolls.protect.
133
143
  protect: Optional(bool) = .None,
134
144
  /// If not None, the value to return for Rolls.triAttack.
135
145
  tri_attack: Optional(TriAttack) = .None,
146
+ /// If not 0, the value to return for Rolls.tripleKick.
147
+ triple_kick: u2 = 0,
136
148
 
137
149
  /// If not 0, (present - 1) * 40 should be returned as the base power for Rolls.present.
138
150
  present: u3 = 0,
139
151
  /// If not 0, magnitude + 3 should be returned as the number for Rolls.magnitude.
140
152
  magnitude: u3 = 0,
141
- /// If not 0, the value to return for Rolls.tripleKick.
142
- triple_kick: u2 = 0,
143
-
144
- /// If not 0, the amount of PP to deduct for Rolls.spite.
153
+ /// If not 0, the amount of PP to deduct for Rolls.spite.
145
154
  spite: u3 = 0,
146
- /// If not None, the value to return for Rolls.conversion2.
147
- conversion_2: Optional(Type) = .None,
148
-
149
155
  /// If not 0, the move slot (1-4) to return in Rolls.moveSlot. If present as an override,
150
156
  /// invalid values (eg. due to empty move slots or 0 PP) will be ignored.
151
- move_slot: u4 = 0,
157
+ move_slot: u3 = 0,
152
158
  /// If not 0, the party slot (1-6) to return in Rolls.forceSwitch. If present as an override,
153
159
  /// invalid values (eg. due to empty party slots or fainted members) will be ignored.
154
- force_switch: u4 = 0,
155
-
160
+ force_switch: u3 = 0,
156
161
  /// If not 0, the value (2-5) to return for Rolls.distribution for multi hit.
157
- multi_hit: u4 = 0,
162
+ multi_hit: u3 = 0,
163
+
164
+ sleep: Optional(Observation) = .None,
165
+ /// TODO
166
+ confusion: Optional(Observation) = .None,
167
+ /// TODO
168
+ disable: Optional(Observation) = .None,
169
+ /// TODO
170
+ attacking: Optional(Observation) = .None,
171
+ /// TODO
172
+ binding: Optional(Observation) = .None,
173
+ /// TODO
174
+ encore: Optional(Observation) = .None,
175
+
158
176
  /// If not 0, the value to by one of the Rolls.*Duration rolls.
159
- duration: u4 = 0,
177
+ duration: u3 = 0,
178
+ /// If not None, the value to return for Rolls.conversion2.
179
+ conversion_2: Optional(Type) = .None,
160
180
 
161
181
  /// If not 0, psywave should be returned as the damage roll for Rolls.psywave.
162
182
  psywave: u8 = 0,
@@ -164,8 +184,6 @@ pub const Action = packed struct(u128) {
164
184
  /// If not None, the Move to return for Rolls.metronome.
165
185
  metronome: Move = .None,
166
186
 
167
- _: u48 = 0, // TODO
168
-
169
187
  pub const Field = std.meta.FieldEnum(Action);
170
188
 
171
189
  pub fn format(a: Action, comptime f: []const u8, o: std.fmt.FormatOptions, w: anytype) !void {
@@ -176,10 +194,10 @@ pub const Action = packed struct(u128) {
176
194
  pub fn fmt(self: Action, writer: anytype, shape: bool) !void {
177
195
  try writer.writeByte('(');
178
196
  var printed = false;
179
- inline for (@typeInfo(Action).Struct.fields) |field| {
197
+ inline for (@field(@typeInfo(Action), @tagName(Struct)).fields) |field| {
180
198
  const val = @field(self, field.name);
181
199
  switch (@typeInfo(@TypeOf(val))) {
182
- .Enum => if (val != .None) {
200
+ Enum => if (val != .None) {
183
201
  if (printed) try writer.writeAll(", ");
184
202
  if (shape) {
185
203
  try writer.print("{s}:?", .{field.name});
@@ -193,7 +211,7 @@ pub const Action = packed struct(u128) {
193
211
  }
194
212
  printed = true;
195
213
  },
196
- .Int => if (val != 0) {
214
+ Int => if (val != 0) {
197
215
  if (printed) try writer.writeAll(", ");
198
216
  if (shape) {
199
217
  try writer.print("{s}:?", .{field.name});
@@ -255,19 +273,21 @@ pub fn Chance(comptime Rational: type) type {
255
273
  self.actions.get(player).hit = if (ok) .true else .false;
256
274
  }
257
275
 
258
- pub fn criticalHit(self: *Self, player: Player, crit: bool, rate: u8) Error!void {
276
+ pub fn criticalHit(self: *Self, player: Player, i: u3, crit: bool, rate: u8) Error!void {
259
277
  if (!enabled) return;
260
278
 
261
279
  const n = if (crit) rate else @as(u8, @intCast(256 - @as(u9, rate)));
262
280
  try self.probability.update(n, 256);
263
- self.actions.get(player).critical_hit = if (crit) .true else .false;
281
+ var a = self.actions.get(player);
282
+ a.critical_hits = Criticals.set(a.critical_hits, i, if (crit) .true else .false);
264
283
  }
265
284
 
266
- pub fn damage(self: *Self, player: Player, roll: u8) Error!void {
285
+ pub fn damage(self: *Self, player: Player, i: u3, roll: u8) Error!void {
267
286
  if (!enabled) return;
268
287
 
269
288
  try self.probability.update(1, 39);
270
- self.actions.get(player).damage = roll;
289
+ var a = self.actions.get(player);
290
+ a.damages = Damages.set(a.damages, i, roll);
271
291
  }
272
292
 
273
293
  pub fn confused(self: *Self, player: Player, cfz: bool) Error!void {
@@ -419,10 +439,10 @@ pub fn Chance(comptime Rational: type) type {
419
439
  self.actions.get(player).multi_hit = n;
420
440
  }
421
441
 
422
- pub fn duration(self: *Self, player: Player, turns: u4) void {
442
+ pub fn duration(self: *Self, player: Player, turns: u3) void {
423
443
  if (!enabled) return;
424
444
 
425
- self.actions.get(player).duration = if (options.key) 1 else turns;
445
+ self.actions.get(player).duration = if (options.key) 2 else turns;
426
446
  }
427
447
  };
428
448
  }
@@ -474,22 +494,22 @@ test "Chance.hit" {
474
494
  test "Chance.criticalHit" {
475
495
  var chance: Chance(rational.Rational(u64)) = .{ .probability = .{} };
476
496
 
477
- try chance.criticalHit(.P1, true, 17);
478
- try expectValue(Optional(bool).true, chance.actions.p1.critical_hit);
497
+ try chance.criticalHit(.P1, 0, true, 17);
498
+ try expectValue(Optional(bool).true, Criticals.get(chance.actions.p1.critical_hits, 0));
479
499
  try expectProbability(&chance.probability, 17, 256);
480
500
 
481
501
  chance.reset();
482
502
 
483
- try chance.criticalHit(.P2, false, 5);
503
+ try chance.criticalHit(.P2, 1, false, 5);
484
504
  try expectProbability(&chance.probability, 251, 256);
485
- try expectValue(Optional(bool).false, chance.actions.p2.critical_hit);
505
+ try expectValue(Optional(bool).false, Criticals.get(chance.actions.p2.critical_hits, 1));
486
506
  }
487
507
 
488
508
  test "Chance.damage" {
489
509
  var chance: Chance(rational.Rational(u64)) = .{ .probability = .{} };
490
510
 
491
- try chance.damage(.P1, 217);
492
- try expectValue(217, chance.actions.p1.damage);
511
+ try chance.damage(.P1, 0, 219);
512
+ try expectValue(@as(u8, 219), Damages.get(chance.actions.p1.damages, 0));
493
513
  try expectProbability(&chance.probability, 1, 39);
494
514
  }
495
515
 
@@ -614,7 +634,7 @@ test "Chance.present" {
614
634
  } else {
615
635
  try expectProbability(&chance.probability, 25, 256);
616
636
  }
617
- try expectValue(4, chance.actions.p2.present);
637
+ try expectValue(@as(u3, 4), chance.actions.p2.present);
618
638
 
619
639
  chance.reset();
620
640
 
@@ -624,7 +644,7 @@ test "Chance.present" {
624
644
  } else {
625
645
  try expectProbability(&chance.probability, 51, 256);
626
646
  }
627
- try expectValue(1, chance.actions.p1.present);
647
+ try expectValue(@as(u3, 1), chance.actions.p1.present);
628
648
  }
629
649
 
630
650
  test "Chance.magnitude" {
@@ -636,7 +656,7 @@ test "Chance.magnitude" {
636
656
  } else {
637
657
  try expectProbability(&chance.probability, 13, 256);
638
658
  }
639
- try expectValue(7, chance.actions.p2.magnitude);
659
+ try expectValue(@as(u3, 7), chance.actions.p2.magnitude);
640
660
 
641
661
  chance.reset();
642
662
 
@@ -646,7 +666,7 @@ test "Chance.magnitude" {
646
666
  } else {
647
667
  try expectProbability(&chance.probability, 51, 256);
648
668
  }
649
- try expectValue(5, chance.actions.p1.magnitude);
669
+ try expectValue(@as(u3, 5), chance.actions.p1.magnitude);
650
670
  }
651
671
 
652
672
  test "Chance.tripleKick" {
@@ -654,7 +674,7 @@ test "Chance.tripleKick" {
654
674
 
655
675
  try chance.tripleKick(.P1, 2);
656
676
  try expectProbability(&chance.probability, 1, 3);
657
- try expectValue(2, chance.actions.p1.triple_kick);
677
+ try expectValue(@as(u2, 2), chance.actions.p1.triple_kick);
658
678
  }
659
679
 
660
680
  test "Chance.spite" {
@@ -662,7 +682,7 @@ test "Chance.spite" {
662
682
 
663
683
  try chance.spite(.P1, 3);
664
684
  try expectProbability(&chance.probability, 1, 4);
665
- try expectValue(3, chance.actions.p1.spite);
685
+ try expectValue(@as(u3, 3), chance.actions.p1.spite);
666
686
  }
667
687
 
668
688
  test "Chance.conversion2" {
@@ -689,7 +709,7 @@ test "Chance.psywave" {
689
709
 
690
710
  try chance.psywave(.P2, 100, 150);
691
711
  try expectProbability(&chance.probability, 1, 150);
692
- try expectValue(100, chance.actions.p2.psywave);
712
+ try expectValue(@as(u8, 100), chance.actions.p2.psywave);
693
713
  }
694
714
 
695
715
  test "Chance.metronome" {
@@ -705,19 +725,19 @@ test "Chance.moveSlot" {
705
725
 
706
726
  try chance.moveSlot(.P2, 2, 2);
707
727
  try expectProbability(&chance.probability, 1, 2);
708
- try expectValue(2, chance.actions.p2.move_slot);
728
+ try expectValue(@as(u3, 2), chance.actions.p2.move_slot);
709
729
 
710
730
  chance.reset();
711
731
 
712
732
  try chance.moveSlot(.P1, 1, 3);
713
733
  try expectProbability(&chance.probability, 1, 3);
714
- try expectValue(1, chance.actions.p1.move_slot);
734
+ try expectValue(@as(u3, 1), chance.actions.p1.move_slot);
715
735
 
716
736
  chance.reset();
717
737
 
718
738
  try chance.moveSlot(.P1, 4, 1);
719
739
  try expectProbability(&chance.probability, 1, 1);
720
- try expectValue(4, chance.actions.p1.move_slot);
740
+ try expectValue(@as(u3, 4), chance.actions.p1.move_slot);
721
741
  }
722
742
 
723
743
  test "Chance.forceSwitch" {
@@ -725,19 +745,19 @@ test "Chance.forceSwitch" {
725
745
 
726
746
  try chance.forceSwitch(.P2, 2, 2);
727
747
  try expectProbability(&chance.probability, 1, 2);
728
- try expectValue(2, chance.actions.p2.force_switch);
748
+ try expectValue(@as(u3, 2), chance.actions.p2.force_switch);
729
749
 
730
750
  chance.reset();
731
751
 
732
752
  try chance.forceSwitch(.P1, 1, 3);
733
753
  try expectProbability(&chance.probability, 1, 3);
734
- try expectValue(1, chance.actions.p1.force_switch);
754
+ try expectValue(@as(u3, 1), chance.actions.p1.force_switch);
735
755
 
736
756
  chance.reset();
737
757
 
738
758
  try chance.forceSwitch(.P1, 4, 1);
739
759
  try expectProbability(&chance.probability, 1, 1);
740
- try expectValue(4, chance.actions.p1.force_switch);
760
+ try expectValue(@as(u3, 4), chance.actions.p1.force_switch);
741
761
  }
742
762
 
743
763
  test "Chance.multiHit" {
@@ -745,20 +765,20 @@ test "Chance.multiHit" {
745
765
 
746
766
  try chance.multiHit(.P1, 3);
747
767
  try expectProbability(&chance.probability, 3, 8);
748
- try expectValue(3, chance.actions.p1.multi_hit);
768
+ try expectValue(@as(u3, 3), chance.actions.p1.multi_hit);
749
769
 
750
770
  chance.reset();
751
771
 
752
772
  try chance.multiHit(.P2, 5);
753
773
  try expectProbability(&chance.probability, 1, 8);
754
- try expectValue(5, chance.actions.p2.multi_hit);
774
+ try expectValue(@as(u3, 5), chance.actions.p2.multi_hit);
755
775
  }
756
776
 
757
777
  test "Chance.duration" {
758
778
  var chance: Chance(rational.Rational(u64)) = .{ .probability = .{} };
759
779
 
760
780
  chance.duration(.P1, 2);
761
- try expectValue(2, chance.actions.p1.duration);
781
+ try expectValue(@as(u3, 2), chance.actions.p1.duration);
762
782
  }
763
783
 
764
784
  pub fn expectProbability(r: anytype, p: u64, q: u64) !void {
@@ -800,12 +820,12 @@ const Null = struct {
800
820
  _ = .{ self, player, ok, accuracy };
801
821
  }
802
822
 
803
- pub fn criticalHit(self: Null, player: Player, crit: bool, rate: u8) Error!void {
804
- _ = .{ self, player, crit, rate };
823
+ pub fn criticalHit(self: Null, player: Player, i: u3, crit: bool, rate: u8) Error!void {
824
+ _ = .{ self, player, i, crit, rate };
805
825
  }
806
826
 
807
- pub fn damage(self: Null, player: Player, roll: u8) Error!void {
808
- _ = .{ self, player, roll };
827
+ pub fn damage(self: Null, player: Player, i: u3, roll: u8) Error!void {
828
+ _ = .{ self, player, i, roll };
809
829
  }
810
830
 
811
831
  pub fn confused(self: Null, player: Player, ok: bool) Error!void {
@@ -876,7 +896,7 @@ const Null = struct {
876
896
  _ = .{ self, player, move, n };
877
897
  }
878
898
 
879
- pub fn duration(self: Null, player: Player, turns: u4) void {
899
+ pub fn duration(self: Null, player: Player, turns: u3) void {
880
900
  _ = .{ self, player, turns };
881
901
  }
882
902
  };
@@ -1,11 +1,9 @@
1
1
  //! Code generated by `tools/generate` - manual edits will be overwritten.
2
2
 
3
- const std = @import("std");
4
-
5
3
  const data = @import("../../gen2/data.zig");
4
+ const std = @import("std");
6
5
 
7
6
  const assert = std.debug.assert;
8
-
9
7
  const Type = data.Type;
10
8
 
11
9
  /// Representation of a held item in Generation II Pokémon.
@@ -1,12 +1,10 @@
1
1
  //! Code generated by `tools/generate` - manual edits will be overwritten.
2
2
 
3
- const std = @import("std");
4
-
5
- const rng = @import("../../common/rng.zig");
6
3
  const gen2 = @import("../../gen2/data.zig");
4
+ const rng = @import("../../common/rng.zig");
5
+ const std = @import("std");
7
6
 
8
7
  const assert = std.debug.assert;
9
-
10
8
  const percent = rng.Gen12.percent;
11
9
  const Type = gen2.Type;
12
10
 
@@ -1,11 +1,9 @@
1
1
  //! Code generated by `tools/generate` - manual edits will be overwritten.
2
2
 
3
- const std = @import("std");
4
-
5
3
  const gen2 = @import("../../gen2/data.zig");
4
+ const std = @import("std");
6
5
 
7
6
  const assert = std.debug.assert;
8
-
9
7
  const Stats = gen2.Stats;
10
8
  const Types = gen2.Types;
11
9
 
@@ -1,8 +1,7 @@
1
1
  //! Code generated by `tools/generate` - manual edits will be overwritten.
2
2
 
3
- const std = @import("std");
4
-
5
3
  const gen1 = @import("../../gen1/data.zig");
4
+ const std = @import("std");
6
5
 
7
6
  const assert = std.debug.assert;
8
7
  const Effectiveness = gen1.Effectiveness;