@pkmn/engine 0.1.0-dev.d3e796d5 → 0.1.0-dev.d56bdadd

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.
@@ -1,4 +1,4 @@
1
- //! Code generated by `tools/generate` - manual edits will be overwritten
1
+ //! Code generated by `tools/generate` - manual edits will be overwritten.
2
2
 
3
3
  const std = @import("std");
4
4
 
@@ -1092,7 +1092,7 @@ pub const Species = enum(u8) {
1092
1092
  pub const size = 151;
1093
1093
 
1094
1094
  /// The Pokémon's critical hit rate=io out of 256.
1095
- pub inline fn chance(id: Species) u8 {
1095
+ pub fn chance(id: Species) u8 {
1096
1096
  assert(id != .None);
1097
1097
  return CHANCES[@intFromEnum(id) - 1];
1098
1098
  }
@@ -1,4 +1,4 @@
1
- //! Code generated by `tools/generate` - manual edits will be overwritten
1
+ //! Code generated by `tools/generate` - manual edits will be overwritten.
2
2
 
3
3
  const std = @import("std");
4
4
 
@@ -30,7 +30,7 @@ pub const Type = enum(u4) {
30
30
  Ice,
31
31
  Dragon,
32
32
 
33
- const CHART = [15][15]Effectiveness{
33
+ const CHART: [15][15]Effectiveness = .{
34
34
  [_]Effectiveness{ N, N, N, N, N, R, N, I, N, N, N, N, N, N, N }, // Normal
35
35
  [_]Effectiveness{ S, N, R, R, N, S, R, I, N, N, N, N, R, S, N }, // Fighting
36
36
  [_]Effectiveness{ N, S, N, N, N, R, S, N, N, N, S, R, N, N, N }, // Flying
@@ -90,16 +90,16 @@ pub const Type = enum(u4) {
90
90
  pub const size = 15;
91
91
 
92
92
  /// Whether or not this type is considered to be special as opposed to physical.
93
- pub inline fn special(self: Type) bool {
93
+ pub fn special(self: Type) bool {
94
94
  return @intFromEnum(self) >= @intFromEnum(Type.Fire);
95
95
  }
96
96
 
97
97
  /// The `Effectiveness` of type `t2` vs. type `t1`.
98
- pub inline fn effectiveness(t1: Type, t2: Type) Effectiveness {
98
+ pub fn effectiveness(t1: Type, t2: Type) Effectiveness {
99
99
  return CHART[@intFromEnum(t1)][@intFromEnum(t2)];
100
100
  }
101
101
 
102
- /// The precedence order of type `t2` vs. type `t1`.
102
+ /// The precedence order of Type `t2` vs. Type `t1`.
103
103
  pub fn precedence(t1: Type, t2: Type) u8 {
104
104
  for (PRECEDENCE, 0..) |matchup, i| {
105
105
  if (matchup.type1 == t1 and matchup.type2 == t2) return @intCast(i);
@@ -120,12 +120,12 @@ pub const Types = packed struct {
120
120
  }
121
121
 
122
122
  /// Whether this typing is immune to type `t`.
123
- pub inline fn immune(self: Types, t: Type) bool {
123
+ pub fn immune(self: Types, t: Type) bool {
124
124
  return t.effectiveness(self.type1) == I or t.effectiveness(self.type2) == I;
125
125
  }
126
126
 
127
127
  /// Whether this typing includes type `t`.
128
- pub inline fn includes(self: Types, t: Type) bool {
128
+ pub fn includes(self: Types, t: Type) bool {
129
129
  return self.type1 == t or self.type2 == t;
130
130
  }
131
131
  };
@@ -70,24 +70,24 @@ pub fn Battle(comptime RNG: anytype) type {
70
70
  rng: RNG,
71
71
 
72
72
  /// Returns the `Side` for the given `player`.
73
- pub inline fn side(self: anytype, player: Player) PointerType(@TypeOf(self), Side) {
73
+ pub fn side(self: anytype, player: Player) PointerType(@TypeOf(self), Side) {
74
74
  assert(@typeInfo(@TypeOf(self)).Pointer.child == Self);
75
75
  return &self.sides[@intFromEnum(player)];
76
76
  }
77
77
 
78
78
  /// Returns the `Side` of the opponent for the given `player`
79
- pub inline fn foe(self: anytype, player: Player) PointerType(@TypeOf(self), Side) {
79
+ pub fn foe(self: anytype, player: Player) PointerType(@TypeOf(self), Side) {
80
80
  assert(@typeInfo(@TypeOf(self)).Pointer.child == Self);
81
81
  return &self.sides[@intFromEnum(player.foe())];
82
82
  }
83
83
 
84
84
  /// Returns an identifier for the active Pokémon of `player`.
85
- pub inline fn active(self: *const Self, player: Player) ID {
85
+ pub fn active(self: *const Self, player: Player) ID {
86
86
  return player.ident(@intCast(self.side(player).order[0]));
87
87
  }
88
88
 
89
89
  /// Returns the `MoveDetails` for the given `player`.
90
- pub inline fn lastMove(
90
+ pub fn lastMove(
91
91
  self: anytype,
92
92
  player: Player,
93
93
  ) PointerType(@TypeOf(self), MoveDetails) {
@@ -141,7 +141,7 @@ pub const Side = extern struct {
141
141
  }
142
142
 
143
143
  /// Returns the stored `Pokemon` corresponding to the one-indexed party `slot`.
144
- pub inline fn get(self: anytype, slot: u8) PointerType(@TypeOf(self), Pokemon) {
144
+ pub fn get(self: anytype, slot: u8) PointerType(@TypeOf(self), Pokemon) {
145
145
  assert(@typeInfo(@TypeOf(self)).Pointer.child == Side);
146
146
  assert(slot > 0 and slot <= 6);
147
147
  const id = self.order[slot - 1];
@@ -150,7 +150,7 @@ pub const Side = extern struct {
150
150
  }
151
151
 
152
152
  /// Returns the stored `Pokemon` corresponding to the `active` Pokémon (slot 1).
153
- pub inline fn stored(self: anytype) PointerType(@TypeOf(self), Pokemon) {
153
+ pub fn stored(self: anytype) PointerType(@TypeOf(self), Pokemon) {
154
154
  assert(@typeInfo(@TypeOf(self)).Pointer.child == Side);
155
155
  return self.get(1);
156
156
  }
@@ -176,7 +176,7 @@ pub const ActivePokemon = extern struct {
176
176
  }
177
177
 
178
178
  /// Returns the active Pokémon's current move slot located at the one-indexed `mslot`.
179
- pub inline fn move(self: anytype, mslot: u8) PointerType(@TypeOf(self), MoveSlot) {
179
+ pub fn move(self: anytype, mslot: u8) PointerType(@TypeOf(self), MoveSlot) {
180
180
  assert(@typeInfo(@TypeOf(self)).Pointer.child == ActivePokemon);
181
181
  assert(mslot > 0 and mslot <= 4);
182
182
  assert(self.moves[mslot - 1].id != .None);
@@ -206,7 +206,7 @@ pub const Pokemon = extern struct {
206
206
  }
207
207
 
208
208
  /// Returns the Pokémon's original move slot located at the one-indexed `mslot`.
209
- pub inline fn move(self: anytype, mslot: u8) PointerType(@TypeOf(self), MoveSlot) {
209
+ pub fn move(self: anytype, mslot: u8) PointerType(@TypeOf(self), MoveSlot) {
210
210
  assert(@typeInfo(@TypeOf(self)).Pointer.child == Pokemon);
211
211
  assert(mslot > 0 and mslot <= 4);
212
212
  assert(self.moves[mslot - 1].id != .None);
@@ -214,7 +214,7 @@ pub const Pokemon = extern struct {
214
214
  }
215
215
  };
216
216
 
217
- /// Representation of a Generation I & II Pokémon's move slot in a battle.
217
+ /// Representation of a Generation I Pokémon's move slot in a battle.
218
218
  pub const MoveSlot = extern struct {
219
219
  /// The identifier for the move.
220
220
  id: Move = .None,
@@ -222,20 +222,16 @@ pub const MoveSlot = extern struct {
222
222
  pp: u8 = 0,
223
223
 
224
224
  comptime {
225
- assert(@sizeOf(MoveSlot) == @sizeOf(u16));
225
+ assert(@sizeOf(MoveSlot) == 2);
226
226
  }
227
227
  };
228
228
 
229
229
  /// Details required to detect desyncs based on the move last selected/executed by players.
230
- pub const MoveDetails = packed struct {
230
+ pub const MoveDetails = packed struct(if (showdown) u16 else u8) {
231
231
  /// The move slot index of the last move selected in the battle menu.
232
232
  index: if (showdown) u8 else u4 = 0,
233
233
  /// Whether the last move executed was counterable.
234
234
  counterable: if (showdown) u8 else u4 = 0,
235
-
236
- comptime {
237
- assert(@sizeOf(MoveDetails) == if (showdown) 2 else 1);
238
- }
239
235
  };
240
236
 
241
237
  /// Bitfield representation of a Generation I & II Pokémon's major status condition.
@@ -262,36 +258,36 @@ pub const Status = enum(u8) {
262
258
  const SLP = 0b111;
263
259
 
264
260
  /// Whether or not the status `num` is the same as `status`.
265
- pub inline fn is(num: u8, status: Status) bool {
261
+ pub fn is(num: u8, status: Status) bool {
266
262
  if (status == .SLP) return Status.duration(num) > 0;
267
263
  return ((num >> @intCast(@intFromEnum(status))) & 1) != 0;
268
264
  }
269
265
 
270
266
  /// Initializes a non-sleep `status`. Use `slp` or `slf` to initialize a sleep status.
271
- pub inline fn init(status: Status) u8 {
267
+ pub fn init(status: Status) u8 {
272
268
  assert(status != .SLP and status != .EXT);
273
269
  return @as(u8, 1) << @intCast(@intFromEnum(status));
274
270
  }
275
271
 
276
272
  /// Initializes a non self-inflicted sleep status with duration `dur`.
277
- pub inline fn slp(dur: u3) u8 {
273
+ pub fn slp(dur: u3) u8 {
278
274
  assert(dur > 0);
279
275
  return @as(u8, dur);
280
276
  }
281
277
 
282
278
  /// Initializes a self-inflicted sleep status with duration `dur`.
283
- pub inline fn slf(dur: u3) u8 {
279
+ pub fn slf(dur: u3) u8 {
284
280
  assert(dur > 0);
285
281
  return 0x80 | slp(dur);
286
282
  }
287
283
 
288
284
  /// Returns the duration of a sleep status.
289
- pub inline fn duration(num: u8) u3 {
285
+ pub fn duration(num: u8) u3 {
290
286
  return @intCast(num & SLP);
291
287
  }
292
288
 
293
289
  /// Returns whether `num` reflects any status.
294
- pub inline fn any(num: u8) bool {
290
+ pub fn any(num: u8) bool {
295
291
  return num > 0;
296
292
  }
297
293
 
@@ -329,7 +325,7 @@ test Status {
329
325
  }
330
326
 
331
327
  /// Bitfield representation of volatile statuses and associated data in Generation I.
332
- pub const Volatiles = packed struct {
328
+ pub const Volatiles = packed struct(u64) {
333
329
  /// Whether the "Bide" volatile status is present.
334
330
  Bide: bool = false,
335
331
  /// Whether the "Thrashing" volatile status is present.
@@ -382,19 +378,15 @@ pub const Volatiles = packed struct {
382
378
  /// The identity of whom the active Pokémon is transformed into.
383
379
  transform: u4 = 0,
384
380
  /// The remaining turns the move is disabled.
385
- disabled_duration: u4 = 0,
381
+ disable_duration: u4 = 0,
386
382
  /// The move slot (1-4) that is disabled.
387
- disabled_move: u3 = 0,
383
+ disable_move: u3 = 0,
388
384
  /// The number of turns toxic damage has been accumulating.
389
385
  toxic: u5 = 0,
390
-
391
- comptime {
392
- assert(@sizeOf(Volatiles) == 8);
393
- }
394
386
  };
395
387
 
396
388
  test Volatiles {
397
- var volatiles = Volatiles{};
389
+ var volatiles: Volatiles = .{};
398
390
  volatiles.Confusion = true;
399
391
  volatiles.confusion = 2;
400
392
  volatiles.Thrashing = true;
@@ -403,8 +395,8 @@ test Volatiles {
403
395
  volatiles.Substitute = true;
404
396
  volatiles.substitute = 42;
405
397
  volatiles.toxic = 4;
406
- volatiles.disabled_move = 2;
407
- volatiles.disabled_duration = 4;
398
+ volatiles.disable_move = 2;
399
+ volatiles.disable_duration = 4;
408
400
 
409
401
  try expect(volatiles.Confusion);
410
402
  try expect(volatiles.Thrashing);
@@ -415,8 +407,8 @@ test Volatiles {
415
407
 
416
408
  try expectEqual(@as(u16, 235), volatiles.state);
417
409
  try expectEqual(@as(u8, 42), volatiles.substitute);
418
- try expectEqual(@as(u4, 2), volatiles.disabled_move);
419
- try expectEqual(@as(u4, 4), volatiles.disabled_duration);
410
+ try expectEqual(@as(u4, 2), volatiles.disable_move);
411
+ try expectEqual(@as(u4, 4), volatiles.disable_duration);
420
412
  try expectEqual(@as(u4, 2), volatiles.confusion);
421
413
  try expectEqual(@as(u5, 4), volatiles.toxic);
422
414
  try expectEqual(@as(u4, 3), volatiles.attacks);
@@ -456,7 +448,7 @@ test Stats {
456
448
  }
457
449
 
458
450
  /// Representation of a Pokémon's boosts in Generation I.
459
- pub const Boosts = packed struct {
451
+ pub const Boosts = packed struct(u32) {
460
452
  /// A Pokémon's Attack boosts.
461
453
  atk: i4 = 0,
462
454
  /// A Pokémon's Defense boosts.
@@ -471,14 +463,10 @@ pub const Boosts = packed struct {
471
463
  evasion: i4 = 0,
472
464
 
473
465
  _: u8 = 0,
474
-
475
- comptime {
476
- assert(@sizeOf(Boosts) == 4);
477
- }
478
466
  };
479
467
 
480
468
  test Boosts {
481
- const boosts = Boosts{ .spc = -6 };
469
+ const boosts: Boosts = .{ .spc = -6 };
482
470
  try expectEqual(0, boosts.atk);
483
471
  try expectEqual(-6, boosts.spc);
484
472
  }
@@ -490,7 +478,7 @@ test Move {
490
478
  try expectEqual(2, @intFromEnum(Move.KarateChop));
491
479
  const move = Move.get(.Fissure);
492
480
  try expectEqual(Move.Effect.OHKO, move.effect);
493
- try expectEqual(@as(u8, 30), move.accuracy);
481
+ try expectEqual(rng.Gen12.percent(30), move.accuracy);
494
482
  try expectEqual(Type.Ground, move.type);
495
483
 
496
484
  try expect(!Move.Effect.onBegin(.None));
@@ -628,16 +616,16 @@ pub const DVs = struct {
628
616
  };
629
617
 
630
618
  test DVs {
631
- var dvs = DVs{ .spc = 15, .spe = 15 };
619
+ var dvs: DVs = .{ .spc = 15, .spe = 15 };
632
620
  try expectEqual(@as(u4, 15), dvs.hp());
633
- dvs = DVs{
621
+ dvs = .{
634
622
  .atk = 5,
635
623
  .def = 15,
636
624
  .spe = 13,
637
625
  .spc = 13,
638
626
  };
639
627
  try expectEqual(@as(u4, 15), dvs.hp());
640
- dvs = DVs{
628
+ dvs = .{
641
629
  .def = 3,
642
630
  .spe = 10,
643
631
  .spc = 11,
@@ -266,7 +266,7 @@ pub const Rolls = struct {
266
266
  const PLAYERS = [_]Optional(Player){ .P1, .P2 };
267
267
 
268
268
  /// Returns a slice with the correct range of values for speed ties given the `action` state.
269
- pub inline fn speedTie(action: Action) []const Optional(Player) {
269
+ pub fn speedTie(action: Action) []const Optional(Player) {
270
270
  return if (@field(action, "speed_tie") == .None) &PLAYER_NONE else &PLAYERS;
271
271
  }
272
272
 
@@ -275,14 +275,14 @@ pub const Rolls = struct {
275
275
 
276
276
  /// Returns a slice with the correct range of values for hits given the `action` state
277
277
  /// and the state of the `parent` (whether the player's Pokémon was fully paralyzed).
278
- pub inline fn hit(action: Action, parent: Optional(bool)) []const Optional(bool) {
278
+ pub fn hit(action: Action, parent: Optional(bool)) []const Optional(bool) {
279
279
  if (parent == .true) return &BOOL_NONE;
280
280
  return if (@field(action, "hit") == .None) &BOOL_NONE else &BOOLS;
281
281
  }
282
282
 
283
283
  /// Returns a slice with the correct range of values for critical hits given the `action` state
284
284
  /// and the state of the `parent` (whether the player's Pokémon's move hit).
285
- pub inline fn criticalHit(
285
+ pub fn criticalHit(
286
286
  action: Action,
287
287
  parent: Optional(bool),
288
288
  ) []const Optional(bool) {
@@ -292,7 +292,7 @@ pub const Rolls = struct {
292
292
 
293
293
  /// Returns a slice with the correct range of values for secondary chances hits given the
294
294
  /// `action` state and the state of the `parent` (whether the player's Pokémon's move hit).
295
- pub inline fn secondaryChance(
295
+ pub fn secondaryChance(
296
296
  action: Action,
297
297
  parent: Optional(bool),
298
298
  ) []const Optional(bool) {
@@ -305,7 +305,7 @@ pub const Rolls = struct {
305
305
 
306
306
  /// Returns the range bounding damage rolls given the `action` state and the state of
307
307
  /// the `parent` (whether the player's Pokémon's move hit).
308
- pub inline fn damage(action: Action, parent: Optional(bool)) Range {
308
+ pub fn damage(action: Action, parent: Optional(bool)) Range {
309
309
  return if (parent == .false or @field(action, "damage") == 0)
310
310
  .{ .min = 0, .max = 1 }
311
311
  else
@@ -314,7 +314,7 @@ pub const Rolls = struct {
314
314
 
315
315
  /// Returns the max damage roll which will produce the same damage as `roll`
316
316
  /// given the base damage in `summaries`.
317
- pub inline fn coalesce(player: Player, roll: u8, summaries: *calc.Summaries, cap: bool) !u8 {
317
+ pub fn coalesce(player: Player, roll: u8, summaries: *calc.Summaries, cap: bool) !u8 {
318
318
  if (roll == 0) return roll;
319
319
 
320
320
  const dmg = summaries.get(player.foe()).damage;
@@ -326,13 +326,13 @@ pub const Rolls = struct {
326
326
 
327
327
  /// Returns a slice with the correct range of values for confused given the `action` state
328
328
  /// and the state of the `parent` (the player's Pokémon's remaining confusion turns).
329
- pub inline fn confused(action: Action, parent: u4) []const Optional(bool) {
329
+ pub fn confused(action: Action, parent: u4) []const Optional(bool) {
330
330
  return if (parent == 0 or @field(action, "confused") == .None) &BOOL_NONE else &BOOLS;
331
331
  }
332
332
 
333
333
  /// Returns a slice with the correct range of values for paralysis given the `action` state
334
334
  /// and the state of the `parent` (whether the player's Pokémon was confused).
335
- pub inline fn paralyzed(action: Action, parent: Optional(bool)) []const Optional(bool) {
335
+ pub fn paralyzed(action: Action, parent: Optional(bool)) []const Optional(bool) {
336
336
  if (parent == .true) return &BOOL_NONE;
337
337
  return if (@field(action, "paralyzed") == .None) &BOOL_NONE else &BOOLS;
338
338
  }
@@ -342,7 +342,7 @@ pub const Rolls = struct {
342
342
 
343
343
  /// Returns a slice with a range of values for duration given the `action` state
344
344
  /// and the state of the `parent` (whether the player's Pokémon's move hit).
345
- pub inline fn duration(action: Action, parent: Optional(bool)) []const u1 {
345
+ pub fn duration(action: Action, parent: Optional(bool)) []const u1 {
346
346
  if (parent == .false) return &DURATION_NONE;
347
347
  return if (@field(action, "duration") == 0) &DURATION_NONE else &DURATION;
348
348
  }
@@ -418,7 +418,7 @@ pub const Rolls = struct {
418
418
  /// and the state of the `parent` (whether the player's Pokémon's move hit).
419
419
  ///
420
420
  /// These slots may or **may not be valid** as slots may be unset / have 0 PP.
421
- pub inline fn moveSlot(action: Action, parent: Optional(bool)) []const u4 {
421
+ pub fn moveSlot(action: Action, parent: Optional(bool)) []const u4 {
422
422
  if (parent == .false) return &SLOT_NONE;
423
423
  return if (@field(action, "move_slot") == 0) &SLOT_NONE else &SLOT;
424
424
  }
@@ -428,7 +428,7 @@ pub const Rolls = struct {
428
428
 
429
429
  /// Returns a slice with the correct range of values for multi hit given the `action` state
430
430
  /// and the state of the `parent` (whether the player's Pokémon's move hit).
431
- pub inline fn multiHit(action: Action, parent: Optional(bool)) []const u4 {
431
+ pub fn multiHit(action: Action, parent: Optional(bool)) []const u4 {
432
432
  if (parent == .false) return &MULTI_NONE;
433
433
  return if (@field(action, "multi_hit") == 0) &MULTI_NONE else &MULTI;
434
434
  }
@@ -442,7 +442,7 @@ pub const Rolls = struct {
442
442
 
443
443
  /// Returns a slice with the correct range of values for psywave given the `action` state,
444
444
  /// the `side`, and the state of the `parent` (whether the player's Pokémon's move hit).
445
- pub inline fn psywave(
445
+ pub fn psywave(
446
446
  action: Action,
447
447
  side: *data.Side,
448
448
  parent: Optional(bool),
@@ -455,36 +455,21 @@ pub const Rolls = struct {
455
455
  }
456
456
 
457
457
  const MOVE_NONE = [_]Move{.None};
458
- const MOVES = init: {
459
- var moves: [Move.size - 2]Move = undefined;
460
- var i: usize = 0;
461
- for (@typeInfo(Move).Enum.fields) |f| {
462
- if (!(std.mem.eql(u8, f.name, "None") or
463
- std.mem.eql(u8, f.name, "Metronome") or
464
- std.mem.eql(u8, f.name, "Struggle") or
465
- std.mem.eql(u8, f.name, "SKIP_TURN")))
466
- {
467
- moves[i] = @field(Move, f.name);
468
- i += 1;
469
- }
470
- }
471
- break :init moves;
472
- };
473
458
 
474
459
  /// Returns a slice with the correct range of values for metronome given the `action` state.
475
- pub inline fn metronome(action: Action) []const Move {
476
- return if (@field(action, "metronome") == .None) &MOVE_NONE else &MOVES;
460
+ pub fn metronome(action: Action) []const Move {
461
+ return if (@field(action, "metronome") == .None) &MOVE_NONE else &Move.METRONOME;
477
462
  }
478
463
  };
479
464
 
480
465
  test "Rolls.speedTie" {
481
- const actions = Actions{ .p1 = .{ .speed_tie = .P2 } };
466
+ const actions: Actions = .{ .p1 = .{ .speed_tie = .P2 } };
482
467
  try expectEqualSlices(Optional(Player), &.{ .P1, .P2 }, Rolls.speedTie(actions.p1));
483
468
  try expectEqualSlices(Optional(Player), &.{.None}, Rolls.speedTie(actions.p2));
484
469
  }
485
470
 
486
471
  test "Rolls.damage" {
487
- const actions = Actions{ .p2 = .{ .damage = 221 } };
472
+ const actions: Actions = .{ .p2 = .{ .damage = 221 } };
488
473
  try expectEqual(Rolls.Range{ .min = 0, .max = 1 }, Rolls.damage(actions.p1, .None));
489
474
  try expectEqual(Rolls.Range{ .min = 217, .max = 256 }, Rolls.damage(actions.p2, .None));
490
475
  try expectEqual(Rolls.Range{ .min = 0, .max = 1 }, Rolls.damage(actions.p2, .false));
@@ -502,7 +487,7 @@ test "Rolls.coalesce" {
502
487
  }
503
488
 
504
489
  test "Rolls.hit" {
505
- const actions = Actions{ .p2 = .{ .hit = .true } };
490
+ const actions: Actions = .{ .p2 = .{ .hit = .true } };
506
491
  try expectEqualSlices(Optional(bool), &.{.None}, Rolls.hit(actions.p1, .None));
507
492
  try expectEqualSlices(Optional(bool), &.{ .false, .true }, Rolls.hit(actions.p2, .None));
508
493
  try expectEqualSlices(Optional(bool), &.{.None}, Rolls.hit(actions.p2, .true));
@@ -510,7 +495,7 @@ test "Rolls.hit" {
510
495
  }
511
496
 
512
497
  test "Rolls.secondaryChance" {
513
- const actions = Actions{ .p1 = .{ .secondary_chance = .true } };
498
+ const actions: Actions = .{ .p1 = .{ .secondary_chance = .true } };
514
499
  try expectEqualSlices(
515
500
  Optional(bool),
516
501
  &.{ .false, .true },
@@ -521,7 +506,7 @@ test "Rolls.secondaryChance" {
521
506
  }
522
507
 
523
508
  test "Rolls.criticalHit" {
524
- const actions = Actions{ .p1 = .{ .critical_hit = .true } };
509
+ const actions: Actions = .{ .p1 = .{ .critical_hit = .true } };
525
510
  try expectEqualSlices(
526
511
  Optional(bool),
527
512
  &.{ .false, .true },
@@ -532,14 +517,14 @@ test "Rolls.criticalHit" {
532
517
  }
533
518
 
534
519
  test "Rolls.confused" {
535
- const actions = Actions{ .p2 = .{ .confused = .true } };
520
+ const actions: Actions = .{ .p2 = .{ .confused = .true } };
536
521
  try expectEqualSlices(Optional(bool), &.{.None}, Rolls.confused(actions.p1, 1));
537
522
  try expectEqualSlices(Optional(bool), &.{ .false, .true }, Rolls.confused(actions.p2, 1));
538
523
  try expectEqualSlices(Optional(bool), &.{.None}, Rolls.confused(actions.p2, 0));
539
524
  }
540
525
 
541
526
  test "Rolls.paralyzed" {
542
- const actions = Actions{ .p2 = .{ .paralyzed = .true } };
527
+ const actions: Actions = .{ .p2 = .{ .paralyzed = .true } };
543
528
  try expectEqualSlices(Optional(bool), &.{.None}, Rolls.paralyzed(actions.p1, .None));
544
529
  try expectEqualSlices(Optional(bool), &.{ .false, .true }, Rolls.paralyzed(actions.p2, .None));
545
530
  try expectEqualSlices(Optional(bool), &.{ .false, .true }, Rolls.paralyzed(actions.p2, .false));
@@ -547,7 +532,7 @@ test "Rolls.paralyzed" {
547
532
  }
548
533
 
549
534
  test "Rolls.duration" {
550
- const actions = Actions{ .p2 = .{ .duration = 3 } };
535
+ const actions: Actions = .{ .p2 = .{ .duration = 3 } };
551
536
  try expectEqualSlices(u1, &.{0}, Rolls.duration(actions.p1, .None));
552
537
  try expectEqualSlices(u1, &.{1}, Rolls.duration(actions.p2, .None));
553
538
  try expectEqualSlices(u1, &.{0}, Rolls.duration(actions.p2, .false));
@@ -757,27 +742,27 @@ test "Rolls.binding" {
757
742
  }
758
743
 
759
744
  test "Rolls.moveSlot" {
760
- const actions = Actions{ .p2 = .{ .move_slot = 3 } };
745
+ const actions: Actions = .{ .p2 = .{ .move_slot = 3 } };
761
746
  try expectEqualSlices(u4, &.{0}, Rolls.moveSlot(actions.p1, .None));
762
747
  try expectEqualSlices(u4, &.{ 1, 2, 3, 4 }, Rolls.moveSlot(actions.p2, .None));
763
748
  try expectEqualSlices(u4, &.{0}, Rolls.moveSlot(actions.p2, .false));
764
749
  }
765
750
 
766
751
  test "Rolls.multiHit" {
767
- const actions = Actions{ .p2 = .{ .multi_hit = 3 } };
752
+ const actions: Actions = .{ .p2 = .{ .multi_hit = 3 } };
768
753
  try expectEqualSlices(u4, &.{0}, Rolls.multiHit(actions.p1, .None));
769
754
  try expectEqualSlices(u4, &.{ 2, 3, 4, 5 }, Rolls.multiHit(actions.p2, .None));
770
755
  try expectEqualSlices(u4, &.{0}, Rolls.multiHit(actions.p2, .false));
771
756
  }
772
757
 
773
758
  test "Rolls.metronome" {
774
- const actions = Actions{ .p2 = .{ .metronome = .Surf } };
759
+ const actions: Actions = .{ .p2 = .{ .metronome = .Surf } };
775
760
  try expectEqualSlices(Move, &.{.None}, Rolls.metronome(actions.p1));
776
761
  try expectEqual(@as(Move, @enumFromInt(24)), Rolls.metronome(actions.p2)[23]);
777
762
  }
778
763
 
779
764
  test "Rolls.psywave" {
780
- const actions = Actions{ .p2 = .{ .psywave = 79 } };
765
+ const actions: Actions = .{ .p2 = .{ .psywave = 79 } };
781
766
  var side = Side.init(&[_]Pokemon{.{
782
767
  .species = .Bulbasaur,
783
768
  .level = 100,