@pkmn/engine 0.1.0-dev.a93847b2 → 0.1.0-dev.abd68573

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 (44) hide show
  1. package/LICENSE +1 -3
  2. package/README.md +39 -16
  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 +90 -76
  17. package/package.json +31 -23
  18. package/src/bin/install-pkmn-engine +26 -18
  19. package/src/lib/common/data.zig +8 -8
  20. package/src/lib/common/optional.zig +1 -1
  21. package/src/lib/common/protocol.zig +393 -396
  22. package/src/lib/common/rational.zig +11 -7
  23. package/src/lib/common/rng.zig +20 -11
  24. package/src/lib/gen1/calc.zig +7 -7
  25. package/src/lib/gen1/chance.zig +31 -30
  26. package/src/lib/gen1/data/moves.zig +9 -9
  27. package/src/lib/gen1/data/species.zig +2 -2
  28. package/src/lib/gen1/data/types.zig +4 -4
  29. package/src/lib/gen1/data.zig +32 -32
  30. package/src/lib/gen1/helpers.zig +48 -28
  31. package/src/lib/gen1/mechanics.zig +277 -255
  32. package/src/lib/gen2/calc.zig +1 -1
  33. package/src/lib/gen2/chance.zig +42 -41
  34. package/src/lib/gen2/data/items.zig +2 -2
  35. package/src/lib/gen2/data/moves.zig +2 -2
  36. package/src/lib/gen2/data/types.zig +9 -9
  37. package/src/lib/gen2/data.zig +23 -21
  38. package/src/lib/gen2/generated.zig +27 -78
  39. package/src/lib/gen2/mechanics.zig +1052 -459
  40. package/src/lib/{binding/node.zig → node.zig} +9 -12
  41. package/src/lib/pkmn.zig +27 -12
  42. package/src/lib/{binding/wasm.zig → wasm.zig} +2 -1
  43. package/src/lib/gen1/README.md +0 -894
  44. package/src/lib/gen2/README.md +0 -330
@@ -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,16 +185,16 @@ pub fn Rational(comptime T: type) type {
185
185
  try writer.print("{d}/{d}", .{ self.p, self.q });
186
186
  }
187
187
 
188
- inline fn multiplication(r: *Self, p: anytype, q: anytype) !void {
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
- inline fn addition(r: *Self, p: anytype, q: anytype) !void {
193
+ fn addition(r: *Self, p: anytype, q: anytype) !void {
194
194
  // (a/b) + (c/d) = (ad+bc)/(bd)
195
- var d = try std.math.mul(T, r.q, q);
196
- var n1 = try std.math.mul(T, r.p, q);
197
- var n2 = try std.math.mul(T, r.q, p);
195
+ const d = try std.math.mul(T, r.q, q);
196
+ const n1 = try std.math.mul(T, r.p, q);
197
+ const n2 = try std.math.mul(T, r.q, p);
198
198
 
199
199
  r.p = try std.math.add(T, n1, n2);
200
200
  r.q = d;
@@ -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
- inline fn gcd(p: anytype, q: anytype) @TypeOf(p, q) {
206
+ fn gcd(p: anytype, q: anytype) @TypeOf(p, q) {
207
207
  assert(p >= 1);
208
208
  assert(q >= 1);
209
209
 
@@ -234,6 +234,8 @@ test Rational {
234
234
  var r: Rational(t) = .{};
235
235
 
236
236
  var c: t = 128;
237
+ _ = &c;
238
+
237
239
  try r.update(c, 256);
238
240
  try doTurn(&r);
239
241
 
@@ -320,6 +322,8 @@ test BigRational {
320
322
  try r.reset();
321
323
 
322
324
  var c: u8 = 128;
325
+ _ = &c;
326
+
323
327
  try r.update(c, 256);
324
328
  try doTurn(&r);
325
329
 
@@ -1,6 +1,6 @@
1
1
  const std = @import("std");
2
2
 
3
- const options = @import("./options.zig");
3
+ const options = @import("options.zig");
4
4
 
5
5
  const assert = std.debug.assert;
6
6
  const expectEqual = std.testing.expectEqual;
@@ -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
 
@@ -61,11 +66,15 @@ pub const PSRNG = extern struct {
61
66
  (@as(u64, self.range(u16, 0, 0x10000)) << 16) |
62
67
  (@as(u64, self.range(u16, 0, 0x10000)));
63
68
  }
69
+
70
+ pub fn Bound(comptime T: type) type {
71
+ return std.math.IntFittingRange(0, std.math.maxInt(T) + 1);
72
+ }
64
73
  };
65
74
 
66
75
  test PSRNG {
67
76
  var psrng: PSRNG = .{ .src = .{ .seed = 0x0001000200030004 } };
68
- try expectEqual(@as(u8, 121), psrng.range(u8, 0, 256));
77
+ try expectEqual(121, psrng.range(u8, 0, 256));
69
78
  try expectEqual(false, psrng.chance(u8, 128, 256)); // 226 < 128
70
79
  }
71
80
 
@@ -89,6 +98,10 @@ pub const Gen12 = extern struct {
89
98
  self.index = (self.index + 1) % 9;
90
99
  return val;
91
100
  }
101
+
102
+ pub fn advance(self: *Gen12) void {
103
+ _ = self.next();
104
+ }
92
105
  };
93
106
 
94
107
  test Gen12 {
@@ -98,9 +111,9 @@ test Gen12 {
98
111
  try expectEqual(e, rng.next());
99
112
  }
100
113
 
101
- try expectEqual(@as(u8, 16), Gen12.percent(6) + 1);
102
- try expectEqual(@as(u8, 16), Gen12.percent(7) - 1);
103
- try expectEqual(@as(u8, 128), Gen12.percent(50) + 1);
114
+ try expectEqual(16, Gen12.percent(6) + 1);
115
+ try expectEqual(16, Gen12.percent(7) - 1);
116
+ try expectEqual(128, Gen12.percent(50) + 1);
104
117
  }
105
118
 
106
119
  // https://pkmn.cc/pokeemerald/src/random.c
@@ -188,7 +201,7 @@ pub fn FixedRNG(comptime gen: comptime_int, comptime len: usize) type {
188
201
  for (0..n) |_| _ = self.next();
189
202
  }
190
203
 
191
- pub fn range(self: *Self, comptime T: type, from: T, to: Bound(T)) T {
204
+ pub fn range(self: *Self, comptime T: type, from: T, to: PSRNG.Bound(T)) T {
192
205
  assert(showdown);
193
206
  return @intCast(@as(u64, self.next()) * (to - from) / divisor + from);
194
207
  }
@@ -197,7 +210,7 @@ pub fn FixedRNG(comptime gen: comptime_int, comptime len: usize) type {
197
210
  self: *Self,
198
211
  comptime T: type,
199
212
  numerator: T,
200
- denominator: Bound(T),
213
+ denominator: PSRNG.Bound(T),
201
214
  ) bool {
202
215
  assert(showdown);
203
216
  assert(denominator > 0);
@@ -228,7 +241,3 @@ fn Output(comptime gen: comptime_int) type {
228
241
  else => unreachable,
229
242
  };
230
243
  }
231
-
232
- fn Bound(comptime T: type) type {
233
- return std.math.IntFittingRange(0, std.math.maxInt(T) + 1);
234
- }
@@ -50,7 +50,7 @@ pub const Summaries = extern struct {
50
50
  }
51
51
 
52
52
  /// Returns the `Summary` for the given `player`.
53
- pub inline fn get(self: anytype, player: Player) PointerType(@TypeOf(self), Summary) {
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
  }
@@ -211,8 +211,8 @@ pub fn transitions(
211
211
  ) !?Stats {
212
212
  var stats: Stats = .{};
213
213
 
214
- var actions = options.actions;
215
- var cap = options.cap;
214
+ const actions = options.actions;
215
+ const cap = options.cap;
216
216
 
217
217
  var seen = std.AutoHashMap(Actions, void).init(allocator);
218
218
  defer seen.deinit();
@@ -232,8 +232,8 @@ pub fn transitions(
232
232
  _ = try b.update(c1, c2, &opts);
233
233
  stats.updates += 1;
234
234
 
235
- var p1 = b.side(.P1);
236
- var p2 = b.side(.P2);
235
+ const p1 = b.side(.P1);
236
+ const p2 = b.side(.P2);
237
237
 
238
238
  var p: Rational(u128) = .{ .p = 0, .q = 1 };
239
239
  try frontier.append(opts.chance.actions);
@@ -247,7 +247,7 @@ pub fn transitions(
247
247
  var i: usize = 0;
248
248
  assert(frontier.items.len == 1);
249
249
  while (i < frontier.items.len) : (i += 1) {
250
- var template = frontier.items[i];
250
+ const template = frontier.items[i];
251
251
  opts.calc.overrides.durations = .{
252
252
  .p1 = template.p1.durations,
253
253
  .p2 = template.p2.durations,
@@ -387,7 +387,7 @@ pub fn transitions(
387
387
  return stats;
388
388
  }
389
389
 
390
- inline fn matches(actions: Actions, i: usize, frontier: []Actions) bool {
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;
@@ -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
 
@@ -706,19 +707,19 @@ 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
+ try expectValue(0, chance.actions.p1.damage);
714
715
 
715
716
  try chance.commit(.P1, .miss);
716
717
  try expectProbability(&chance.probability, 1, 1);
717
- try expectValue(@as(u8, 0), chance.actions.p1.damage);
718
+ try expectValue(0, chance.actions.p1.damage);
718
719
 
719
720
  try chance.commit(.P1, .hit);
720
721
  try expectProbability(&chance.probability, 1, 39);
721
- try expectValue(@as(u8, 217), chance.actions.p1.damage);
722
+ try expectValue(217, chance.actions.p1.damage);
722
723
  }
723
724
  }
724
725
 
@@ -770,13 +771,13 @@ test "Chance.moveSlot" {
770
771
 
771
772
  try chance.moveSlot(.P2, 2, &ms, 2);
772
773
  try expectProbability(&chance.probability, 1, 2);
773
- try expectValue(@as(u4, 2), chance.actions.p2.move_slot);
774
+ try expectValue(2, chance.actions.p2.move_slot);
774
775
 
775
776
  chance.reset();
776
777
 
777
778
  try chance.moveSlot(.P1, 1, &ms, 0);
778
779
  try expectProbability(&chance.probability, 1, 3);
779
- try expectValue(@as(u4, 1), chance.actions.p1.move_slot);
780
+ try expectValue(1, chance.actions.p1.move_slot);
780
781
  }
781
782
 
782
783
  test "Chance.multiHit" {
@@ -784,32 +785,32 @@ test "Chance.multiHit" {
784
785
 
785
786
  try chance.multiHit(.P1, 3);
786
787
  try expectProbability(&chance.probability, 3, 8);
787
- try expectValue(@as(u4, 3), chance.actions.p1.multi_hit);
788
+ try expectValue(3, chance.actions.p1.multi_hit);
788
789
 
789
790
  chance.reset();
790
791
 
791
792
  try chance.multiHit(.P2, 5);
792
793
  try expectProbability(&chance.probability, 1, 8);
793
- try expectValue(@as(u4, 5), chance.actions.p2.multi_hit);
794
+ try expectValue(5, chance.actions.p2.multi_hit);
794
795
  }
795
796
 
796
797
  test "Chance.duration" {
797
798
  var chance: Chance(rational.Rational(u64)) = .{ .probability = .{} };
798
799
 
799
800
  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);
801
+ try expectValue(2, chance.actions.p1.duration);
802
+ try expectValue(1, chance.actions.p2.durations.sleep);
802
803
 
803
804
  chance.reset();
804
805
 
805
806
  chance.duration(.binding, .P2, .P2, 4);
806
807
  if (!showdown) {
807
- try expectValue(@as(u4, 0), chance.actions.p2.duration);
808
- try expectValue(@as(u3, 0), chance.actions.p2.durations.binding);
808
+ try expectValue(0, chance.actions.p2.duration);
809
+ try expectValue(0, chance.actions.p2.durations.binding);
809
810
  try chance.commit(.P2, .hit);
810
811
  }
811
- try expectValue(@as(u4, 4), chance.actions.p2.duration);
812
- try expectValue(@as(u3, 1), chance.actions.p2.durations.binding);
812
+ try expectValue(4, chance.actions.p2.duration);
813
+ try expectValue(1, chance.actions.p2.durations.binding);
813
814
  }
814
815
 
815
816
  test "Chance.sleep" {
@@ -819,7 +820,7 @@ test "Chance.sleep" {
819
820
  chance.actions.p1.durations.sleep = @intCast(i);
820
821
  try chance.sleep(.P1, 0);
821
822
  try expectProbability(&chance.probability, 1, d);
822
- try expectValue(@as(u3, 0), chance.actions.p1.durations.sleep);
823
+ try expectValue(0, chance.actions.p1.durations.sleep);
823
824
 
824
825
  chance.reset();
825
826
 
@@ -842,7 +843,7 @@ test "Chance.confusion" {
842
843
  chance.actions.p2.durations.confusion = @intCast(i);
843
844
  try chance.confusion(.P2, 0);
844
845
  try expectProbability(&chance.probability, 1, d);
845
- try expectValue(@as(u3, 0), chance.actions.p2.durations.confusion);
846
+ try expectValue(0, chance.actions.p2.durations.confusion);
846
847
 
847
848
  chance.reset();
848
849
  }
@@ -865,7 +866,7 @@ test "Chance.disable" {
865
866
  chance.actions.p1.durations.disable = @intCast(i);
866
867
  try chance.disable(.P1, 0);
867
868
  try expectProbability(&chance.probability, 1, d);
868
- try expectValue(@as(u4, 0), chance.actions.p1.durations.disable);
869
+ try expectValue(0, chance.actions.p1.durations.disable);
869
870
 
870
871
  chance.reset();
871
872
 
@@ -888,7 +889,7 @@ test "Chance.attacking" {
888
889
  chance.actions.p2.durations.attacking = @intCast(i);
889
890
  try chance.attacking(.P2, 0);
890
891
  try expectProbability(&chance.probability, 1, d);
891
- try expectValue(@as(u3, 0), chance.actions.p2.durations.attacking);
892
+ try expectValue(0, chance.actions.p2.durations.attacking);
892
893
 
893
894
  chance.reset();
894
895
  }
@@ -914,7 +915,7 @@ test "Chance.binding" {
914
915
  chance.actions.p1.durations.binding = @intCast(i);
915
916
  try chance.binding(.P1, 0);
916
917
  try expectProbability(&chance.probability, p, q);
917
- try expectValue(@as(u3, 0), chance.actions.p1.durations.binding);
918
+ try expectValue(0, chance.actions.p1.durations.binding);
918
919
 
919
920
  chance.reset();
920
921
 
@@ -934,7 +935,7 @@ test "Chance.psywave" {
934
935
 
935
936
  try chance.psywave(.P2, 100, 150);
936
937
  try expectProbability(&chance.probability, 1, 150);
937
- try expectValue(@as(u8, 101), chance.actions.p2.psywave);
938
+ try expectValue(101, chance.actions.p2.psywave);
938
939
  }
939
940
 
940
941
  test "Chance.metronome" {
@@ -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
  }
@@ -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
  }
@@ -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
  };