@pkmn/engine 0.1.0-dev.d716e940 → 0.1.0-dev.d952b7c9

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 (79) hide show
  1. package/LICENSE +1 -3
  2. package/README.md +97 -59
  3. package/build/pkg/addon/browser.d.ts +3 -0
  4. package/build/pkg/addon/browser.js +43 -0
  5. package/build/pkg/addon/browser.js.map +1 -0
  6. package/build/pkg/addon/node.d.ts +3 -0
  7. package/build/pkg/addon/node.js +96 -0
  8. package/build/pkg/addon/node.js.map +1 -0
  9. package/build/pkg/addon.d.ts +2 -0
  10. package/build/pkg/addon.js +35 -57
  11. package/build/pkg/addon.js.map +1 -1
  12. package/build/pkg/data/ids.json +12 -12
  13. package/build/pkg/data/layout.json +26 -4
  14. package/build/pkg/data/protocol.json +69 -12
  15. package/build/pkg/data.d.ts +27 -5
  16. package/build/pkg/data.js.map +1 -1
  17. package/build/pkg/gen1.js +16 -19
  18. package/build/pkg/gen1.js.map +1 -1
  19. package/build/pkg/index.d.ts +24 -10
  20. package/build/pkg/index.js +15 -10
  21. package/build/pkg/index.js.map +1 -1
  22. package/build/pkg/protocol.d.ts +20 -1
  23. package/build/pkg/protocol.js +123 -102
  24. package/build/pkg/protocol.js.map +1 -1
  25. package/build/tools/debug.js +36 -68
  26. package/build/tools/debug.js.map +1 -1
  27. package/build/tools/display/debug.jsx +128 -0
  28. package/build/tools/display/debug.jsx.map +1 -0
  29. package/build/tools/display/index.js +132 -0
  30. package/build/tools/display/index.js.map +1 -0
  31. package/build/tools/display/ui.jsx +349 -0
  32. package/build/tools/display/ui.jsx.map +1 -0
  33. package/build/tools/display/util.js +18 -0
  34. package/build/tools/display/util.js.map +1 -0
  35. package/build.zig +286 -131
  36. package/package.json +73 -31
  37. package/src/bin/install-pkmn-engine +39 -24
  38. package/src/bin/pkmn-debug +1 -1
  39. package/src/lib/common/array.zig +77 -0
  40. package/src/lib/common/battle.zig +17 -0
  41. package/src/lib/common/data.zig +19 -31
  42. package/src/lib/common/debug.zig +30 -16
  43. package/src/lib/common/js.zig +120 -0
  44. package/src/lib/common/optional.zig +71 -0
  45. package/src/lib/common/options.zig +13 -0
  46. package/src/lib/common/protocol.zig +911 -367
  47. package/src/lib/common/rational.zig +447 -0
  48. package/src/lib/common/rng.zig +31 -22
  49. package/src/lib/common/util.zig +61 -0
  50. package/src/lib/gen1/calc.zig +950 -0
  51. package/src/lib/gen1/chance.zig +1169 -0
  52. package/src/lib/gen1/data/moves.zig +202 -190
  53. package/src/lib/gen1/data/species.zig +5 -5
  54. package/src/lib/gen1/data/types.zig +10 -10
  55. package/src/lib/gen1/data.zig +92 -79
  56. package/src/lib/gen1/helpers.zig +141 -28
  57. package/src/lib/gen1/mechanics.zig +1118 -773
  58. package/src/lib/gen2/calc.zig +161 -0
  59. package/src/lib/gen2/chance.zig +902 -0
  60. package/src/lib/gen2/data/items.zig +14 -20
  61. package/src/lib/gen2/data/moves.zig +664 -570
  62. package/src/lib/gen2/data/species.zig +2 -2
  63. package/src/lib/gen2/data/types.zig +137 -34
  64. package/src/lib/gen2/data.zig +125 -86
  65. package/src/lib/gen2/generated.zig +806 -0
  66. package/src/lib/gen2/helpers.zig +54 -32
  67. package/src/lib/gen2/mechanics.zig +3564 -15
  68. package/src/lib/node.zig +131 -0
  69. package/src/lib/pkmn.zig +81 -5
  70. package/src/lib/wasm.zig +13 -0
  71. package/src/tools/display/dom.ts +96 -0
  72. package/src/tools/display/ui.css +351 -0
  73. package/build/test/display.js +0 -400
  74. package/build/test/display.js.map +0 -1
  75. package/src/lib/binding/node.zig +0 -229
  76. package/src/lib/binding/wasm.zig +0 -10
  77. package/src/lib/gen1/README.md +0 -812
  78. package/src/lib/gen2/README.md +0 -309
  79. package/src/test/display/pkmn.html.tmpl +0 -368
@@ -1,10 +1,13 @@
1
1
  const std = @import("std");
2
2
  const builtin = @import("builtin");
3
3
 
4
+ const pkmn = @import("../pkmn.zig");
5
+
4
6
  const data = @import("../common/data.zig");
5
7
  const DEBUG = @import("../common/debug.zig").print;
6
- const options = @import("../common/options.zig");
8
+ const protocol = @import("../common/protocol.zig");
7
9
  const rng = @import("../common/rng.zig");
10
+ const util = @import("../common/util.zig");
8
11
 
9
12
  const items = @import("data/items.zig");
10
13
  const moves = @import("data/moves.zig");
@@ -13,6 +16,8 @@ const types = @import("data/types.zig");
13
16
 
14
17
  const gen1 = @import("../gen1/data.zig");
15
18
 
19
+ const calc = @import("calc.zig");
20
+ const chance = @import("chance.zig");
16
21
  const mechanics = @import("mechanics.zig");
17
22
 
18
23
  const assert = std.debug.assert;
@@ -31,16 +36,23 @@ pub const LOGS_SIZE = if (builtin.mode == .ReleaseSmall)
31
36
  else
32
37
  std.math.ceilPowerOfTwo(usize, MAX_LOGS) catch unreachable;
33
38
 
39
+ /// Null object pattern implementation of pkmn.battle.Options for Generation II.
40
+ pub const NULL = pkmn.battle.options(protocol.NULL, chance.NULL, calc.NULL);
41
+
34
42
  const Choice = data.Choice;
35
43
  const ID = data.ID;
36
44
  const Player = data.Player;
37
45
  const Result = data.Result;
38
46
 
39
- const showdown = options.showdown;
47
+ const PointerType = util.PointerType;
48
+ const isPointerTo = util.isPointerTo;
49
+
50
+ const showdown = pkmn.options.showdown;
40
51
 
41
52
  pub const PRNG = rng.PRNG(2);
42
53
 
43
54
  pub fn Battle(comptime RNG: anytype) type {
55
+ const padding = if (!showdown) 3 else 5;
44
56
  return extern struct {
45
57
  const Self = @This();
46
58
 
@@ -49,20 +61,24 @@ pub fn Battle(comptime RNG: anytype) type {
49
61
  turn: u16 = 0,
50
62
  field: Field = .{},
51
63
 
52
- pub inline fn side(self: *Self, player: Player) *Side {
53
- return &self.sides[@enumToInt(player)];
64
+ _: [padding]u8 = .{0} ** padding,
65
+
66
+ pub fn side(self: anytype, player: Player) PointerType(@TypeOf(self), Side) {
67
+ assert(isPointerTo(self, Self));
68
+ return &self.sides[@intFromEnum(player)];
54
69
  }
55
70
 
56
- pub inline fn foe(self: *Self, player: Player) *Side {
57
- return &self.sides[@enumToInt(player.foe())];
71
+ pub fn foe(self: anytype, player: Player) PointerType(@TypeOf(self), Side) {
72
+ assert(isPointerTo(self, Self));
73
+ return &self.sides[@intFromEnum(player.foe())];
58
74
  }
59
75
 
60
- pub inline fn active(self: *Self, player: Player) ID {
61
- return player.ident(@intCast(u3, self.side(player).pokemon[0].position));
76
+ pub fn active(self: *const Self, player: Player) ID {
77
+ return player.ident(@intCast(self.side(player).pokemon[0].position));
62
78
  }
63
79
 
64
- pub fn update(self: *Self, c1: Choice, c2: Choice, log: anytype) !Result {
65
- return mechanics.update(self, c1, c2, log);
80
+ pub fn update(self: *Self, c1: Choice, c2: Choice, options: anytype) !Result {
81
+ return mechanics.update(self, c1, c2, options);
66
82
  }
67
83
 
68
84
  pub fn choices(self: *Self, player: Player, request: Choice.Type, out: []Choice) u8 {
@@ -71,35 +87,32 @@ pub fn Battle(comptime RNG: anytype) type {
71
87
  };
72
88
  }
73
89
 
74
- // TODO
75
90
  test Battle {
76
- try expectEqual(496, @sizeOf(Battle(PRNG)));
91
+ try expectEqual(512, @sizeOf(Battle(PRNG)));
77
92
  }
78
93
 
79
- const Field = packed struct {
94
+ pub const Field = packed struct(u8) {
80
95
  weather: Weather = .None,
81
96
  weather_duration: u4 = 0,
82
-
83
- comptime {
84
- assert(@sizeOf(Field) == 1);
85
- }
86
97
  };
87
98
 
88
- const Weather = enum(u4) {
99
+ pub const Weather = enum(u4) {
89
100
  None,
90
101
  Rain,
91
102
  Sun,
92
103
  Sandstorm,
93
104
  };
94
105
 
95
- const Side = extern struct {
106
+ pub const Side = extern struct {
96
107
  pokemon: [6]Pokemon = [_]Pokemon{.{}} ** 6,
97
- active: ActivePokemon = .{},
98
- conditions: Conditions,
108
+ active: ActivePokemon align(8) = .{},
109
+ conditions: Conditions = .{},
110
+ // NB: wLastPlayerCounterMove / wLastEnemyCounterMove (wLastPlayerMove / wLastEnemyMove)
99
111
  last_used_move: Move = .None,
100
- _: u8 = 0,
101
112
 
102
- const Conditions = packed struct {
113
+ _: [7]u8 = .{0} ** 7,
114
+
115
+ const Conditions = packed struct(u32) {
103
116
  Spikes: bool = false,
104
117
  Safeguard: bool = false,
105
118
  LightScreen: bool = false,
@@ -109,50 +122,69 @@ const Side = extern struct {
109
122
  light_screen: u4 = 0,
110
123
  reflect: u4 = 0,
111
124
 
112
- comptime {
113
- assert(@sizeOf(Conditions) == 2);
114
- }
125
+ future_sight: FutureSight = .{},
126
+
127
+ const FutureSight = packed struct(u16) {
128
+ damage: u12 = 0,
129
+ count: u4 = 0,
130
+ };
115
131
  };
116
132
 
117
133
  comptime {
118
- assert(@sizeOf(Side) == 240);
134
+ assert(@sizeOf(Side) == 248);
119
135
  }
120
136
 
121
- pub inline fn get(self: *const Side, slot: u8) *Pokemon {
137
+ pub fn get(self: anytype, slot: u8) PointerType(@TypeOf(self), Pokemon) {
138
+ assert(isPointerTo(self, Side));
122
139
  assert(slot > 0 and slot <= 6);
123
140
  const id = self.pokemon[slot - 1].position;
124
141
  assert(id > 0 and id <= 6);
125
142
  return &self.pokemon[id - 1];
126
143
  }
127
144
 
128
- pub inline fn stored(self: *Side) *Pokemon {
145
+ pub fn stored(self: anytype) PointerType(@TypeOf(self), Pokemon) {
146
+ assert(isPointerTo(self, Side));
129
147
  return self.get(1);
130
148
  }
149
+
150
+ pub fn lastMove(self: anytype, encore: bool) Move {
151
+ assert(self.last_used_move != .None or !self.active.volatiles.dirty);
152
+ if (encore) return self.last_used_move;
153
+ return if (self.active.volatiles.dirty) .None else self.last_used_move;
154
+ }
155
+
156
+ // TODO
157
+ // pub fn useMove(self: anytype) void {
158
+ // assert(side.last_selected_move != .None);
159
+ // self.last_used_move = side.last_selected_move;
160
+ // self.active.volatiles.dirty = false;
161
+ // }
131
162
  };
132
163
 
133
164
  // NOTE: DVs (Gender & Hidden Power) and Happiness are stored only in Pokemon
134
- const ActivePokemon = extern struct {
135
- volatiles: Volatile align(4) = .{},
165
+ pub const ActivePokemon = extern struct {
166
+ volatiles: Volatiles align(4) = .{},
136
167
  stats: Stats(u16) = .{},
137
168
  moves: [4]MoveSlot = [_]MoveSlot{.{}} ** 4,
138
169
  boosts: Boosts = .{},
170
+ types: Types = .{},
139
171
  species: Species = .None,
140
- item: Item = .None,
141
- last_move: Move = .None,
172
+
142
173
  _: u8 = 0,
143
174
 
144
175
  comptime {
145
176
  assert(@sizeOf(ActivePokemon) == 44);
146
177
  }
147
178
 
148
- pub inline fn move(self: *ActivePokemon, mslot: u8) *MoveSlot {
179
+ pub fn move(self: anytype, mslot: u8) PointerType(@TypeOf(self), MoveSlot) {
180
+ assert(isPointerTo(self, Pokemon));
149
181
  assert(mslot > 0 and mslot <= 4);
150
182
  assert(self.moves[mslot - 1].id != .None);
151
183
  return &self.moves[mslot - 1];
152
184
  }
153
185
  };
154
186
 
155
- const Pokemon = extern struct {
187
+ pub const Pokemon = extern struct {
156
188
  stats: Stats(u16) = .{},
157
189
  moves: [4]MoveSlot = [_]MoveSlot{.{}} ** 4,
158
190
  types: Types = .{},
@@ -169,7 +201,8 @@ const Pokemon = extern struct {
169
201
  assert(@sizeOf(Pokemon) == 32);
170
202
  }
171
203
 
172
- pub inline fn move(self: *Pokemon, mslot: u8) *MoveSlot {
204
+ pub fn move(self: anytype, mslot: u8) PointerType(@TypeOf(self), MoveSlot) {
205
+ assert(isPointerTo(self, Pokemon));
173
206
  assert(mslot > 0 and mslot <= 4);
174
207
  assert(self.moves[mslot - 1].id != .None);
175
208
  return &self.moves[mslot - 1];
@@ -182,7 +215,7 @@ pub const Gender = enum(u2) {
182
215
  Unknown,
183
216
  };
184
217
 
185
- const DVs = packed struct {
218
+ pub const DVs = packed struct(u16) {
186
219
  gender: Gender = .Male,
187
220
  pow: u6 = 40,
188
221
  type: Type = .Dark,
@@ -190,10 +223,10 @@ const DVs = packed struct {
190
223
  pub fn init(g: Gender, p: u6, t: Type) DVs {
191
224
  assert(p >= 1 and p <= 40);
192
225
  assert(t != .Normal and t != .@"???");
193
- return DVs{ .gender = g, .pow = p, .type = t };
226
+ return .{ .gender = g, .pow = p, .type = t };
194
227
  }
195
228
 
196
- pub inline fn power(dvs: DVs) u8 {
229
+ pub fn power(dvs: DVs) u8 {
197
230
  return @as(u8, dvs.pow) + 30;
198
231
  }
199
232
 
@@ -205,15 +238,10 @@ const DVs = packed struct {
205
238
  0xFF => .Unknown,
206
239
  else => if ((@as(u8, dvs.atk) << 4 | dvs.spe) < ratio) Gender.Female else Gender.Male,
207
240
  };
208
- const p = @intCast(u6, 1 + ((5 * @as(u8, (dvs.atk & 0b1000) | ((dvs.def & 0b1000)) >> 1 |
241
+ const p: u6 = @intCast(1 + ((5 * @as(u8, (dvs.atk & 0b1000) | ((dvs.def & 0b1000)) >> 1 |
209
242
  ((dvs.spe & 0b1000)) >> 2 | ((dvs.spc & 0b1000)) >> 3) + (dvs.spc & 0b0011)) >> 1));
210
- var t = @as(u8, dvs.def & 0b0011) + (@as(u8, dvs.atk & 0b0011) << 2) + 1;
211
- if (t >= @enumToInt(Type.@"???")) t = t + 1;
212
- return DVs{ .gender = g, .pow = p, .type = @intToEnum(Type, t) };
213
- }
214
-
215
- comptime {
216
- assert(@sizeOf(DVs) == 2);
243
+ const t = @as(u8, dvs.def & 0b0011) + (@as(u8, dvs.atk & 0b0011) << 2);
244
+ return .{ .gender = g, .pow = p, .type = Type.hiddenPower(t) };
217
245
  }
218
246
  };
219
247
 
@@ -238,10 +266,12 @@ test DVs {
238
266
  try expectEqual(Gender.Female, dvs.gender);
239
267
  }
240
268
 
241
- const MoveSlot = packed struct {
269
+ /// Representation of a Generation II Pokémon's move slot in a battle.
270
+ pub const MoveSlot = extern struct {
271
+ /// The identifier for the move.
242
272
  id: Move = .None,
243
- pp_ups: u2 = 3,
244
- pp: u6 = 0,
273
+ /// The remaining PP of the move.
274
+ pp: u8 = 0,
245
275
 
246
276
  comptime {
247
277
  assert(@sizeOf(MoveSlot) == 2);
@@ -250,14 +280,19 @@ const MoveSlot = packed struct {
250
280
 
251
281
  pub const Status = gen1.Status;
252
282
 
253
- const Volatile = packed struct {
283
+ /// TODO
284
+ pub const TriAttack = enum(u2) { PAR, FRZ, BRN };
285
+
286
+ pub const Volatiles = packed struct(u128) {
254
287
  Bide: bool = false,
255
288
  Thrashing: bool = false,
289
+ BeatUp: bool = false,
256
290
  Flinch: bool = false,
257
291
  Charging: bool = false,
258
292
  Underground: bool = false,
259
293
  Flying: bool = false,
260
294
  Confusion: bool = false,
295
+
261
296
  Mist: bool = false,
262
297
  FocusEnergy: bool = false,
263
298
  Substitute: bool = false,
@@ -268,52 +303,55 @@ const Volatile = packed struct {
268
303
  Transform: bool = false,
269
304
 
270
305
  Nightmare: bool = false,
271
- Cure: bool = false,
306
+ Curse: bool = false,
272
307
  Protect: bool = false,
273
308
  Foresight: bool = false,
274
309
  PerishSong: bool = false,
275
310
  Endure: bool = false,
276
311
  Rollout: bool = false,
277
312
  Attract: bool = false,
313
+
278
314
  DefenseCurl: bool = false,
279
315
  Encore: bool = false,
280
316
  LockOn: bool = false,
281
317
  DestinyBond: bool = false,
282
- BeatUp: bool = false,
318
+ Trapped: bool = false,
283
319
 
284
- trapped: bool = false,
285
320
  switched: bool = false,
321
+ // TODO: replace with simply looking at Choice on Battle
286
322
  switching: bool = false,
323
+ // TODO: simply store both last moves on side
324
+ dirty: bool = false,
287
325
 
288
- _: u5 = 0,
326
+ frozen: bool = false,
327
+ minimized: bool = false,
328
+ _: u10 = 0,
329
+ // TODO: is this needed for unmodified stats?
330
+ transform: u4 = 0,
289
331
 
290
- bind: u4 = 0,
291
- future_sight: FutureSight = .{},
292
332
  bide: u16 = 0,
293
- disabled: Disabled = .{},
333
+ bind: Bind = .{},
334
+ disable: Disable = .{},
294
335
  rage: u8 = 0,
295
336
  substitute: u8 = 0,
296
337
  toxic: u8 = 0,
297
338
  confusion: u4 = 0,
298
339
  encore: u4 = 0,
340
+ // TODO merge with attacks (ie rollout/thrashing)? need to be zeroed at same time
299
341
  fury_cutter: u4 = 0,
300
342
  perish_song: u4 = 0,
301
343
  protect: u4 = 0,
302
- rollout: u4 = 0,
344
+ attacks: u4 = 0, // bide/thrashing/rollout turns
303
345
 
304
- const Disabled = packed struct {
305
- move: u4 = 0,
346
+ const Bind = packed struct(u8) {
306
347
  duration: u4 = 0,
348
+ reason: u4 = 0,
307
349
  };
308
350
 
309
- const FutureSight = packed struct {
310
- damage: u12 = 0,
311
- count: u4 = 0,
351
+ const Disable = packed struct(u8) {
352
+ move: u4 = 0,
353
+ duration: u4 = 0,
312
354
  };
313
-
314
- comptime {
315
- assert(@sizeOf(Volatile) == 16);
316
- }
317
355
  };
318
356
 
319
357
  pub fn Stats(comptime T: type) type {
@@ -327,10 +365,11 @@ pub fn Stats(comptime T: type) type {
327
365
 
328
366
  pub fn calc(comptime stat: []const u8, base: T, dv: u4, exp: u16, level: u8) T {
329
367
  assert(level > 0 and level <= 100);
330
- const evs = @min(255, @floatToInt(u16, @ceil(@sqrt(@intToFloat(f32, exp)))));
368
+ const float: f32 = @floatFromInt(exp);
369
+ const evs: u16 = @min(255, @as(u16, @intFromFloat(@ceil(@sqrt(float)))));
331
370
  const core: u32 = (2 *% (@as(u32, base) +% dv)) +% (evs / 4);
332
371
  const factor: u32 = if (std.mem.eql(u8, stat, "hp")) level + 10 else 5;
333
- return @intCast(T, core *% @as(u32, level) / 100 +% factor);
372
+ return @intCast(core *% @as(u32, level) / 100 +% factor);
334
373
  }
335
374
  };
336
375
  }
@@ -347,7 +386,7 @@ test Stats {
347
386
  try expectEqual(@as(u16, 279), Stats(u16).calc("spe", base.spe, 15, 63001, 100));
348
387
  }
349
388
 
350
- pub const Boosts = packed struct {
389
+ pub const Boosts = packed struct(u32) {
351
390
  atk: i4 = 0,
352
391
  def: i4 = 0,
353
392
  spe: i4 = 0,
@@ -363,7 +402,7 @@ pub const Boosts = packed struct {
363
402
  };
364
403
 
365
404
  test Boosts {
366
- const boosts = Boosts{ .spd = -6 };
405
+ const boosts: Boosts = .{ .spd = -6 };
367
406
  try expectEqual(0, boosts.atk);
368
407
  try expectEqual(-6, boosts.spd);
369
408
  }
@@ -376,31 +415,31 @@ test Item {
376
415
  try expectEqual(Type.Normal, Item.boost(.PolkadotBow).?);
377
416
  try expectEqual(Type.Dark, Item.boost(.BlackGlasses).?);
378
417
 
379
- try expect(!Item.mail(.UpGrade));
380
- try expect(Item.mail(.FlowerMail));
381
- try expect(Item.mail(.MirageMail));
382
- try expect(!Item.mail(.TownMap));
383
-
384
- try expect(!Item.berry(.LightBall));
385
- try expect(Item.berry(.PSNCureBerry));
386
- try expect(Item.berry(.GoldBerry));
387
- try expect(!Item.berry(.MasterBall));
418
+ try expect(!Item.isMail(.UpGrade));
419
+ try expect(Item.isMail(.FlowerMail));
420
+ try expect(Item.isMail(.MirageMail));
421
+ try expect(!Item.isMail(.TownMap));
388
422
  }
389
423
 
390
424
  pub const Move = moves.Move;
391
425
 
392
426
  test Move {
393
- try expectEqual(251, @enumToInt(Move.BeatUp));
427
+ try expectEqual(251, @intFromEnum(Move.BeatUp));
394
428
  const move = Move.get(.DynamicPunch);
395
429
  try expectEqual(Move.Effect.ConfusionChance, move.effect);
396
- try expectEqual(@as(u8, 50), move.accuracy);
397
- try expectEqual(@as(u8, 5), move.pp);
430
+ try expectEqual(rng.Gen12.percent(50), move.accuracy);
431
+ try expectEqual(rng.Gen12.percent(100), move.chance);
432
+ try expectEqual(@as(u8, 5), Move.pp(.DynamicPunch));
433
+ try expectEqual(@as(i8, -1), Move.get(.Counter).priority);
434
+ try expect(!move.effect.isHighCritical());
435
+ try expect(Move.get(.KarateChop).effect.isHighCritical());
436
+ try expect(Move.get(.RazorWind).effect.isHighCritical());
398
437
  }
399
438
 
400
439
  pub const Species = species.Species;
401
440
 
402
441
  test Species {
403
- try expectEqual(152, @enumToInt(Species.Chikorita));
442
+ try expectEqual(152, @intFromEnum(Species.Chikorita));
404
443
  try expectEqual(@as(u8, 100), Species.get(.Celebi).stats.spd);
405
444
  }
406
445
 
@@ -409,7 +448,7 @@ pub const Types = types.Types;
409
448
  pub const Effectiveness = gen1.Effectiveness;
410
449
 
411
450
  test Types {
412
- try expectEqual(13, @enumToInt(Type.Electric));
451
+ try expectEqual(13, @intFromEnum(Type.Electric));
413
452
 
414
453
  try expect(!Type.Steel.special());
415
454
  try expect(Type.Dark.special());