@pkmn/engine 0.1.0-dev.dc33f678 → 0.1.0-dev.deda8593

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 (49) hide show
  1. package/LICENSE +1 -3
  2. package/README.md +44 -19
  3. package/build/pkg/addon.js +6 -7
  4. package/build/pkg/addon.js.map +1 -1
  5. package/build/pkg/data.d.ts +4 -4
  6. package/build/pkg/data.js.map +1 -1
  7. package/build/pkg/gen1.js.map +1 -1
  8. package/build/pkg/index.d.ts +2 -1
  9. package/build/pkg/index.js.map +1 -1
  10. package/build/pkg/protocol.js +5 -5
  11. package/build/pkg/protocol.js.map +1 -1
  12. package/build/test/display.js +2 -2
  13. package/build/test/display.js.map +1 -1
  14. package/build/tools/debug.js +5 -4
  15. package/build/tools/debug.js.map +1 -1
  16. package/build.zig +100 -102
  17. package/package.json +33 -22
  18. package/src/bin/install-pkmn-engine +26 -18
  19. package/src/lib/common/data.zig +8 -8
  20. package/src/lib/common/debug.zig +2 -2
  21. package/src/lib/common/optional.zig +1 -1
  22. package/src/lib/common/options.zig +2 -0
  23. package/src/lib/common/protocol.zig +397 -384
  24. package/src/lib/common/rational.zig +11 -8
  25. package/src/lib/common/rng.zig +20 -11
  26. package/src/lib/gen1/calc.zig +217 -47
  27. package/src/lib/gen1/chance.zig +91 -92
  28. package/src/lib/gen1/data/moves.zig +10 -10
  29. package/src/lib/gen1/data/species.zig +3 -3
  30. package/src/lib/gen1/data/types.zig +5 -5
  31. package/src/lib/gen1/data.zig +35 -35
  32. package/src/lib/gen1/helpers.zig +136 -55
  33. package/src/lib/gen1/mechanics.zig +333 -312
  34. package/src/lib/gen2/calc.zig +143 -0
  35. package/src/lib/gen2/chance.zig +1315 -0
  36. package/src/lib/gen2/data/items.zig +3 -3
  37. package/src/lib/gen2/data/moves.zig +5 -5
  38. package/src/lib/gen2/data/species.zig +1 -1
  39. package/src/lib/gen2/data/types.zig +10 -10
  40. package/src/lib/gen2/data.zig +27 -37
  41. package/src/lib/gen2/generated.zig +806 -0
  42. package/src/lib/gen2/helpers.zig +37 -7
  43. package/src/lib/gen2/mechanics.zig +1621 -456
  44. package/src/lib/{binding/node.zig → node.zig} +9 -12
  45. package/src/lib/pkmn.zig +27 -12
  46. package/src/lib/{binding/wasm.zig → wasm.zig} +2 -1
  47. package/src/test/display/pkmn.html.tmpl +5 -5
  48. package/src/lib/gen1/README.md +0 -894
  49. package/src/lib/gen2/README.md +0 -330
@@ -14,7 +14,7 @@ const util = @import("../common/util.zig");
14
14
  const Player = @import("../common/data.zig").Player;
15
15
  const Optional = @import("../common/optional.zig").Optional;
16
16
 
17
- const data = @import("./data.zig");
17
+ const data = @import("data.zig");
18
18
 
19
19
  const enabled = options.chance;
20
20
  const showdown = options.showdown;
@@ -37,19 +37,19 @@ pub const Actions = extern struct {
37
37
  }
38
38
 
39
39
  /// Returns the `Action` for the given `player`.
40
- pub inline fn get(self: anytype, player: Player) util.PointerType(@TypeOf(self), Action) {
40
+ pub fn get(self: anytype, player: Player) util.PointerType(@TypeOf(self), Action) {
41
41
  assert(@typeInfo(@TypeOf(self)).Pointer.child == Actions);
42
42
  return if (player == .P1) &self.p1 else &self.p2;
43
43
  }
44
44
 
45
45
  /// Perform a reset by clearing fields which should not persist across updates.
46
- pub inline fn reset(self: *Actions) void {
46
+ pub fn reset(self: *Actions) void {
47
47
  self.p1.reset();
48
48
  self.p2.reset();
49
49
  }
50
50
 
51
51
  /// Returns true if `a` is equal to `b`.
52
- pub inline fn eql(a: Actions, b: Actions) bool {
52
+ pub fn eql(a: Actions, b: Actions) bool {
53
53
  return @as(u128, @bitCast(a)) == @as(u128, @bitCast(b));
54
54
  }
55
55
 
@@ -92,13 +92,14 @@ pub const Actions = extern struct {
92
92
  }
93
93
  };
94
94
 
95
+ // TODO: ziglang/zig#19730
95
96
  test Actions {
96
97
  const a: Actions = .{ .p1 = .{ .hit = .true, .critical_hit = .false, .damage = 245 } };
97
98
  const b: Actions = .{ .p1 = .{ .hit = .false, .critical_hit = .true, .damage = 246 } };
98
99
  const c: Actions = .{ .p1 = .{ .hit = .true } };
99
- const d: Actions = .{ .p2 = .{ .hit = .true, .durations = .{ .sleep = 2 } } };
100
- const e: Actions = .{ .p2 = .{ .hit = .false, .durations = .{ .sleep = 4 } } };
101
- const f: Actions = .{ .p1 = .{ .hit = .false, .durations = .{ .sleep = 4 } } };
100
+ // const d: Actions = .{ .p2 = .{ .hit = .true, .durations = .{ .sleep = 2 } } };
101
+ // const e: Actions = .{ .p2 = .{ .hit = .false, .durations = .{ .sleep = 4 } } };
102
+ // const f: Actions = .{ .p1 = .{ .hit = .false, .durations = .{ .sleep = 4 } } };
102
103
 
103
104
  try expect(a.eql(a));
104
105
  try expect(!a.eql(b));
@@ -111,8 +112,8 @@ test Actions {
111
112
  try expect(b.matches(a));
112
113
  try expect(!a.matches(c));
113
114
  try expect(!c.matches(a));
114
- try expect(d.matches(e));
115
- try expect(!d.matches(f));
115
+ // try expect(d.matches(e));
116
+ // try expect(!d.matches(f));
116
117
  }
117
118
 
118
119
  /// Information about the RNG that was observed during a Generation I battle `update` for a
@@ -159,7 +160,7 @@ pub const Action = packed struct(u64) {
159
160
  pub const Field = std.meta.FieldEnum(Action);
160
161
 
161
162
  /// Perform a reset by clearing fields which should not persist across updates.
162
- pub inline fn reset(self: *Action) void {
163
+ pub fn reset(self: *Action) void {
163
164
  self.* = @bitCast(@as(u64, @bitCast(self.*)) & DURATIONS);
164
165
  }
165
166
 
@@ -254,6 +255,8 @@ pub const Duration = packed struct(u16) {
254
255
 
255
256
  pub const Commit = enum { hit, miss, binding };
256
257
 
258
+ const uN = if (options.miss) u8 else u9;
259
+
257
260
  /// Tracks chance actions and their associated probability during a Generation I battle update when
258
261
  /// `options.chance` is enabled.
259
262
  pub fn Chance(comptime Rational: type) type {
@@ -290,15 +293,12 @@ pub fn Chance(comptime Rational: type) type {
290
293
  //
291
294
  // Finally, because each player's actions are processed sequentially we only need a single
292
295
  // shared structure to track this information (though it needs to be cleared appropriately)
293
- pending: if (showdown) struct {
294
- hit: bool = false,
295
- hit_probablity: u8 = 0,
296
- } else struct {
296
+ pending: if (showdown) struct {} else struct {
297
297
  crit: bool = false,
298
298
  crit_probablity: u8 = 0,
299
299
  damage_roll: u8 = 0,
300
300
  hit: bool = false,
301
- hit_probablity: u8 = 0,
301
+ hit_probablity: uN = 0,
302
302
  binding: u8 = 0,
303
303
  } = .{},
304
304
 
@@ -307,25 +307,29 @@ pub fn Chance(comptime Rational: type) type {
307
307
 
308
308
  /// Convenience helper to clear fields which typically should be cleared between updates.
309
309
  pub fn reset(self: *Self) void {
310
+ if (!enabled) return;
311
+
310
312
  self.probability.reset();
311
313
  self.actions.reset();
312
314
  self.pending = .{};
313
315
  }
314
316
 
315
317
  pub fn commit(self: *Self, player: Player, kind: Commit) Error!void {
318
+ if (!enabled) return;
319
+
320
+ assert(!showdown);
321
+
316
322
  var action = self.actions.get(player);
317
323
 
318
324
  // We need to handle binding specially because we still need to commit it when attacking
319
325
  // into a Pokémon that is immune
320
- if (!showdown) {
321
- if (kind != .miss and self.pending.binding != 0) {
322
- assert(action.duration == 0);
323
- action.duration = @intCast(self.pending.binding);
324
- assert(action.durations.binding == 0);
325
- action.durations.binding = 1;
326
- }
327
- if (kind == .binding) return;
328
- } else assert(kind != .binding);
326
+ if (kind != .miss and self.pending.binding != 0) {
327
+ assert(action.duration == 0);
328
+ action.duration = @intCast(self.pending.binding);
329
+ assert(action.durations.binding == 0);
330
+ action.durations.binding = 1;
331
+ }
332
+ if (kind == .binding) return;
329
333
 
330
334
  // Always commit the hit result if we make it here (commit won't be called at all if the
331
335
  // target is immune/behind a sub/etc)
@@ -334,19 +338,19 @@ pub fn Chance(comptime Rational: type) type {
334
338
  action.hit = if (self.pending.hit) .true else .false;
335
339
  }
336
340
 
337
- if (showdown) return;
341
+ // If the move actually lands we can commit any past critical hit / damage rolls. Note
342
+ // we can't rely on the presence or absence of a damage roll to determine whether a
343
+ // "critical hit" was spurious or not as moves that do 1 or less damage don't rol for
344
+ // damage but can still crit (instead, whether or not a roll is deemed to be a no-op is
345
+ // passed to the critical hit helper)
346
+ if (kind != .hit) return assert(!self.pending.crit or self.pending.crit_probablity > 0);
338
347
 
339
- // If the move actually lands we can commit any past critical hit / damage rolls. We
340
- // avoid updating anything if there wasn't a damage roll as any "critical hit" not tied
341
- // to a damage roll is actually a no-op
342
- if (kind == .hit and self.pending.damage_roll > 0) {
343
- assert(!self.pending.crit or self.pending.crit_probablity > 0);
344
-
345
- if (self.pending.crit_probablity != 0) {
346
- try self.probability.update(self.pending.crit_probablity, 256);
347
- action.critical_hit = if (self.pending.crit) .true else .false;
348
- }
348
+ if (self.pending.crit_probablity != 0) {
349
+ try self.probability.update(self.pending.crit_probablity, 256);
350
+ action.critical_hit = if (self.pending.crit) .true else .false;
351
+ }
349
352
 
353
+ if (self.pending.damage_roll > 0) {
350
354
  try self.probability.update(1, 39);
351
355
  action.damage = self.pending.damage_roll;
352
356
  }
@@ -397,12 +401,17 @@ pub fn Chance(comptime Rational: type) type {
397
401
  self.actions.p2.speed_tie = self.actions.p1.speed_tie;
398
402
  }
399
403
 
400
- pub fn hit(self: *Self, ok: bool, accuracy: u8) void {
404
+ pub fn hit(self: *Self, player: Player, ok: bool, accuracy: uN) Error!void {
401
405
  if (!enabled) return;
402
406
 
403
407
  const p = if (ok) accuracy else @as(u8, @intCast(256 - @as(u9, accuracy)));
404
- self.pending.hit = ok;
405
- self.pending.hit_probablity = p;
408
+ if (showdown) {
409
+ try self.probability.update(p, 256);
410
+ self.actions.get(player).hit = if (ok) .true else .false;
411
+ } else {
412
+ self.pending.hit = ok;
413
+ self.pending.hit_probablity = p;
414
+ }
406
415
  }
407
416
 
408
417
  pub fn criticalHit(self: *Self, player: Player, crit: bool, rate: u8) Error!void {
@@ -620,19 +629,25 @@ test "Chance.speedTie" {
620
629
  test "Chance.hit" {
621
630
  var chance: Chance(rational.Rational(u64)) = .{ .probability = .{} };
622
631
 
623
- chance.hit(true, 229);
624
- try expectProbability(&chance.probability, 1, 1);
625
- try expectValue(Optional(bool).None, chance.actions.p1.hit);
626
- try chance.commit(.P1, .hit);
632
+ try chance.hit(.P1, true, 229);
633
+ if (!showdown) {
634
+ try expectProbability(&chance.probability, 1, 1);
635
+ try expectValue(Optional(bool).None, chance.actions.p1.hit);
636
+
637
+ try chance.commit(.P1, .hit);
638
+ }
627
639
  try expectValue(Optional(bool).true, chance.actions.p1.hit);
628
640
  try expectProbability(&chance.probability, 229, 256);
629
641
 
630
642
  chance.reset();
631
643
 
632
- chance.hit(false, 255);
633
- try expectProbability(&chance.probability, 1, 1);
634
- try expectValue(Optional(bool).None, chance.actions.p2.hit);
635
- try chance.commit(.P2, .miss);
644
+ try chance.hit(.P2, false, 255);
645
+ if (!showdown) {
646
+ try expectProbability(&chance.probability, 1, 1);
647
+ try expectValue(Optional(bool).None, chance.actions.p2.hit);
648
+
649
+ try chance.commit(.P2, .miss);
650
+ }
636
651
  try expectValue(Optional(bool).false, chance.actions.p2.hit);
637
652
  try expectProbability(&chance.probability, 1, 256);
638
653
  }
@@ -648,26 +663,18 @@ test "Chance.criticalHit" {
648
663
  try expectProbability(&chance.probability, 1, 1);
649
664
  try expectValue(Optional(bool).None, chance.actions.p1.critical_hit);
650
665
 
651
- try chance.commit(.P1, .hit);
652
- try expectProbability(&chance.probability, 1, 1);
653
- try expectValue(Optional(bool).None, chance.actions.p1.critical_hit);
654
-
655
- chance.hit(true, 128);
666
+ try chance.hit(.P1, true, 128);
656
667
 
657
- try chance.commit(.P1, .hit);
658
- try expectProbability(&chance.probability, 1, 2);
668
+ try expectProbability(&chance.probability, 1, 1);
659
669
  try expectValue(Optional(bool).None, chance.actions.p1.critical_hit);
660
670
 
661
- chance.probability.reset();
662
671
  try chance.damage(.P1, 217);
663
672
 
664
- try chance.commit(.P1, .miss);
665
- try expectProbability(&chance.probability, 1, 2);
673
+ try expectProbability(&chance.probability, 1, 1);
666
674
  try expectValue(Optional(bool).None, chance.actions.p1.critical_hit);
667
675
 
668
- chance.probability.reset();
669
-
670
676
  try chance.commit(.P1, .hit);
677
+
671
678
  try expectProbability(&chance.probability, 17, 19968); // (1/2) * (17/256) * (1/39)
672
679
  try expectValue(Optional(bool).true, chance.actions.p1.critical_hit);
673
680
  }
@@ -682,20 +689,14 @@ test "Chance.criticalHit" {
682
689
  try expectProbability(&chance.probability, 1, 1);
683
690
  try expectValue(Optional(bool).None, chance.actions.p1.critical_hit);
684
691
 
685
- try chance.commit(.P1, .hit);
686
- try expectProbability(&chance.probability, 1, 1);
687
- try expectValue(Optional(bool).None, chance.actions.p1.critical_hit);
688
-
689
- chance.hit(true, 128);
692
+ try chance.hit(.P1, true, 128);
690
693
 
691
- try chance.commit(.P1, .hit);
692
- try expectProbability(&chance.probability, 1, 2);
694
+ try expectProbability(&chance.probability, 1, 1);
693
695
  try expectValue(Optional(bool).None, chance.actions.p1.critical_hit);
694
696
 
695
- chance.probability.reset();
696
697
  try chance.damage(.P1, 217);
697
-
698
698
  try chance.commit(.P1, .hit);
699
+
699
700
  try expectProbability(&chance.probability, 251, 19968); // (1/2) * (251/256) * (1/39)
700
701
  try expectValue(Optional(bool).false, chance.actions.p1.critical_hit);
701
702
  }
@@ -706,19 +707,16 @@ test "Chance.damage" {
706
707
 
707
708
  try chance.damage(.P1, 217);
708
709
  if (showdown) {
709
- try expectValue(@as(u8, 217), chance.actions.p1.damage);
710
+ try expectValue(217, chance.actions.p1.damage);
710
711
  try expectProbability(&chance.probability, 1, 39);
711
712
  } else {
712
713
  try expectProbability(&chance.probability, 1, 1);
713
- try expectValue(@as(u8, 0), chance.actions.p1.damage);
714
-
715
- try chance.commit(.P1, .miss);
716
- try expectProbability(&chance.probability, 1, 1);
717
- try expectValue(@as(u8, 0), chance.actions.p1.damage);
714
+ try expectValue(0, chance.actions.p1.damage);
718
715
 
719
716
  try chance.commit(.P1, .hit);
717
+
720
718
  try expectProbability(&chance.probability, 1, 39);
721
- try expectValue(@as(u8, 217), chance.actions.p1.damage);
719
+ try expectValue(217, chance.actions.p1.damage);
722
720
  }
723
721
  }
724
722
 
@@ -770,13 +768,13 @@ test "Chance.moveSlot" {
770
768
 
771
769
  try chance.moveSlot(.P2, 2, &ms, 2);
772
770
  try expectProbability(&chance.probability, 1, 2);
773
- try expectValue(@as(u4, 2), chance.actions.p2.move_slot);
771
+ try expectValue(2, chance.actions.p2.move_slot);
774
772
 
775
773
  chance.reset();
776
774
 
777
775
  try chance.moveSlot(.P1, 1, &ms, 0);
778
776
  try expectProbability(&chance.probability, 1, 3);
779
- try expectValue(@as(u4, 1), chance.actions.p1.move_slot);
777
+ try expectValue(1, chance.actions.p1.move_slot);
780
778
  }
781
779
 
782
780
  test "Chance.multiHit" {
@@ -784,32 +782,33 @@ test "Chance.multiHit" {
784
782
 
785
783
  try chance.multiHit(.P1, 3);
786
784
  try expectProbability(&chance.probability, 3, 8);
787
- try expectValue(@as(u4, 3), chance.actions.p1.multi_hit);
785
+ try expectValue(3, chance.actions.p1.multi_hit);
788
786
 
789
787
  chance.reset();
790
788
 
791
789
  try chance.multiHit(.P2, 5);
792
790
  try expectProbability(&chance.probability, 1, 8);
793
- try expectValue(@as(u4, 5), chance.actions.p2.multi_hit);
791
+ try expectValue(5, chance.actions.p2.multi_hit);
794
792
  }
795
793
 
796
794
  test "Chance.duration" {
797
795
  var chance: Chance(rational.Rational(u64)) = .{ .probability = .{} };
798
796
 
799
797
  chance.duration(.sleep, .P1, .P2, 2);
800
- try expectValue(@as(u4, 2), chance.actions.p1.duration);
801
- try expectValue(@as(u3, 1), chance.actions.p2.durations.sleep);
798
+ try expectValue(2, chance.actions.p1.duration);
799
+ try expectValue(1, chance.actions.p2.durations.sleep);
802
800
 
803
801
  chance.reset();
804
802
 
805
803
  chance.duration(.binding, .P2, .P2, 4);
806
804
  if (!showdown) {
807
- try expectValue(@as(u4, 0), chance.actions.p2.duration);
808
- try expectValue(@as(u3, 0), chance.actions.p2.durations.binding);
805
+ try expectValue(0, chance.actions.p2.duration);
806
+ try expectValue(0, chance.actions.p2.durations.binding);
807
+
809
808
  try chance.commit(.P2, .hit);
810
809
  }
811
- try expectValue(@as(u4, 4), chance.actions.p2.duration);
812
- try expectValue(@as(u3, 1), chance.actions.p2.durations.binding);
810
+ try expectValue(4, chance.actions.p2.duration);
811
+ try expectValue(1, chance.actions.p2.durations.binding);
813
812
  }
814
813
 
815
814
  test "Chance.sleep" {
@@ -819,7 +818,7 @@ test "Chance.sleep" {
819
818
  chance.actions.p1.durations.sleep = @intCast(i);
820
819
  try chance.sleep(.P1, 0);
821
820
  try expectProbability(&chance.probability, 1, d);
822
- try expectValue(@as(u3, 0), chance.actions.p1.durations.sleep);
821
+ try expectValue(0, chance.actions.p1.durations.sleep);
823
822
 
824
823
  chance.reset();
825
824
 
@@ -842,7 +841,7 @@ test "Chance.confusion" {
842
841
  chance.actions.p2.durations.confusion = @intCast(i);
843
842
  try chance.confusion(.P2, 0);
844
843
  try expectProbability(&chance.probability, 1, d);
845
- try expectValue(@as(u3, 0), chance.actions.p2.durations.confusion);
844
+ try expectValue(0, chance.actions.p2.durations.confusion);
846
845
 
847
846
  chance.reset();
848
847
  }
@@ -865,7 +864,7 @@ test "Chance.disable" {
865
864
  chance.actions.p1.durations.disable = @intCast(i);
866
865
  try chance.disable(.P1, 0);
867
866
  try expectProbability(&chance.probability, 1, d);
868
- try expectValue(@as(u4, 0), chance.actions.p1.durations.disable);
867
+ try expectValue(0, chance.actions.p1.durations.disable);
869
868
 
870
869
  chance.reset();
871
870
 
@@ -888,7 +887,7 @@ test "Chance.attacking" {
888
887
  chance.actions.p2.durations.attacking = @intCast(i);
889
888
  try chance.attacking(.P2, 0);
890
889
  try expectProbability(&chance.probability, 1, d);
891
- try expectValue(@as(u3, 0), chance.actions.p2.durations.attacking);
890
+ try expectValue(0, chance.actions.p2.durations.attacking);
892
891
 
893
892
  chance.reset();
894
893
  }
@@ -914,7 +913,7 @@ test "Chance.binding" {
914
913
  chance.actions.p1.durations.binding = @intCast(i);
915
914
  try chance.binding(.P1, 0);
916
915
  try expectProbability(&chance.probability, p, q);
917
- try expectValue(@as(u3, 0), chance.actions.p1.durations.binding);
916
+ try expectValue(0, chance.actions.p1.durations.binding);
918
917
 
919
918
  chance.reset();
920
919
 
@@ -934,7 +933,7 @@ test "Chance.psywave" {
934
933
 
935
934
  try chance.psywave(.P2, 100, 150);
936
935
  try expectProbability(&chance.probability, 1, 150);
937
- try expectValue(@as(u8, 101), chance.actions.p2.psywave);
936
+ try expectValue(101, chance.actions.p2.psywave);
938
937
  }
939
938
 
940
939
  test "Chance.metronome" {
@@ -988,8 +987,8 @@ const Null = struct {
988
987
  _ = .{ self, p1 };
989
988
  }
990
989
 
991
- pub fn hit(self: Null, ok: bool, accuracy: u8) void {
992
- _ = .{ self, ok, accuracy };
990
+ pub fn hit(self: Null, player: Player, ok: bool, accuracy: uN) Error!void {
991
+ _ = .{ self, player, ok, accuracy };
993
992
  }
994
993
 
995
994
  pub fn criticalHit(self: Null, player: Player, crit: bool, rate: u8) Error!void {
@@ -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
 
@@ -1599,43 +1599,43 @@ pub const Move = enum(u8) {
1599
1599
  }
1600
1600
 
1601
1601
  /// Whether this effect activates during the "begin" step of move execution.
1602
- pub inline fn onBegin(effect: Effect) bool {
1602
+ pub fn onBegin(effect: Effect) bool {
1603
1603
  return @intFromEnum(effect) > 0 and @intFromEnum(effect) <= 16;
1604
1604
  }
1605
1605
 
1606
1606
  /// Whether this effect lowers stats.
1607
- pub inline fn isStatDown(effect: Effect) bool {
1607
+ pub fn isStatDown(effect: Effect) bool {
1608
1608
  return @intFromEnum(effect) > 16 and @intFromEnum(effect) <= 21;
1609
1609
  }
1610
1610
 
1611
1611
  /// Whether this effect activates during the "end" step of move execution.
1612
- pub inline fn onEnd(effect: Effect) bool {
1612
+ pub fn onEnd(effect: Effect) bool {
1613
1613
  return @intFromEnum(effect) > 16 and @intFromEnum(effect) <= 31;
1614
1614
  }
1615
1615
 
1616
1616
  /// Whether this effect is considered to "always happen".
1617
- pub inline fn alwaysHappens(effect: Effect) bool {
1617
+ pub fn alwaysHappens(effect: Effect) bool {
1618
1618
  return @intFromEnum(effect) > 31 and @intFromEnum(effect) <= 38;
1619
1619
  }
1620
1620
 
1621
1621
  /// Whether this effect is handled specially by the engine.
1622
- pub inline fn isSpecial(effect: Effect) bool {
1622
+ pub fn isSpecial(effect: Effect) bool {
1623
1623
  // NB: isSpecial includes isMulti up to Twineedle
1624
1624
  return @intFromEnum(effect) > 31 and @intFromEnum(effect) <= 46;
1625
1625
  }
1626
1626
 
1627
1627
  /// Whether this effect is a multi-hit effect.
1628
- pub inline fn isMulti(effect: Effect) bool {
1628
+ pub fn isMulti(effect: Effect) bool {
1629
1629
  return @intFromEnum(effect) > 44 and @intFromEnum(effect) <= 47;
1630
1630
  }
1631
1631
 
1632
1632
  /// Whether this effect is has chance of lowering stats.
1633
- pub inline fn isStatDownChance(effect: Effect) bool {
1633
+ pub fn isStatDownChance(effect: Effect) bool {
1634
1634
  return @intFromEnum(effect) > 47 and @intFromEnum(effect) <= 51;
1635
1635
  }
1636
1636
 
1637
1637
  /// Whether this effect has a secondary chance.
1638
- pub inline fn isSecondaryChance(effect: Effect) bool {
1638
+ pub fn isSecondaryChance(effect: Effect) bool {
1639
1639
  // NB: isSecondaryChance includes isStatDownChance as well as Twineedle
1640
1640
  return (@intFromEnum(effect) > 46 and @intFromEnum(effect) <= 61);
1641
1641
  }
@@ -1853,7 +1853,7 @@ pub const Move = enum(u8) {
1853
1853
  };
1854
1854
 
1855
1855
  /// Returns the `Data` corresponding to the move.
1856
- pub inline fn get(id: Move) Data {
1856
+ pub fn get(id: Move) Data {
1857
1857
  assert(id != .None and id != .SKIP_TURN);
1858
1858
  return DATA[@intFromEnum(id) - 1];
1859
1859
  }
@@ -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
 
@@ -1091,8 +1091,8 @@ pub const Species = enum(u8) {
1091
1091
  /// The number of Pokémon species in this generation.
1092
1092
  pub const size = 151;
1093
1093
 
1094
- /// The Pokémon's critical hit rate=io out of 256.
1095
- pub inline fn chance(id: Species) u8 {
1094
+ /// The Pokémon's critical hit ratio out of 256.
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
 
@@ -90,12 +90,12 @@ 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
 
@@ -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
  };