@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
@@ -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
 
@@ -216,14 +216,14 @@ pub const Item = enum(u8) {
216
216
  pub const size = 196;
217
217
 
218
218
  /// Returns a `Type` boosted by this item or `null` if the item is not a type-boosting item.
219
- pub inline fn boost(item: Item) ?Type {
219
+ pub fn boost(item: Item) ?Type {
220
220
  assert(item != .None);
221
221
  if (item == .PolkadotBow) return .Normal;
222
222
  return if (@intFromEnum(item) <= 18) @enumFromInt(@intFromEnum(item) - 1) else null;
223
223
  }
224
224
 
225
225
  /// Whether or not this item is Mail.
226
- pub inline fn isMail(item: Item) bool {
226
+ pub fn isMail(item: Item) bool {
227
227
  assert(item != .None);
228
228
  return @intFromEnum(item) > 60 and @intFromEnum(item) <= 70;
229
229
  }
@@ -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
 
@@ -938,7 +938,7 @@ pub const Move = enum(u8) {
938
938
  },
939
939
  // SolarBeam
940
940
  .{
941
- .effect = .Solarbeam,
941
+ .effect = .SolarBeam,
942
942
  .bp = 120,
943
943
  .type = .Grass,
944
944
  .accuracy = percent(100),
@@ -2529,7 +2529,7 @@ pub const Move = enum(u8) {
2529
2529
  Sleep,
2530
2530
  SleepTalk,
2531
2531
  Snore,
2532
- Solarbeam,
2532
+ SolarBeam,
2533
2533
  SpAtkUp1,
2534
2534
  SpDefDownChance,
2535
2535
  SpDefUp2,
@@ -2562,7 +2562,7 @@ pub const Move = enum(u8) {
2562
2562
  }
2563
2563
 
2564
2564
  /// Whether this effect has a high critical rate.
2565
- pub inline fn isHighCritical(effect: Effect) bool {
2565
+ pub fn isHighCritical(effect: Effect) bool {
2566
2566
  return effect == .HighCritical or effect == .RazorWind;
2567
2567
  }
2568
2568
  };
@@ -2865,7 +2865,7 @@ pub const Move = enum(u8) {
2865
2865
  };
2866
2866
 
2867
2867
  /// Returns the `Data` corresponding to the move.
2868
- pub inline fn get(id: Move) Data {
2868
+ pub fn get(id: Move) Data {
2869
2869
  assert(id != .None);
2870
2870
  return DATA[@intFromEnum(id) - 1];
2871
2871
  }
@@ -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
 
@@ -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
 
@@ -164,27 +164,27 @@ pub const Type = enum(u8) {
164
164
  pub const size = 18;
165
165
 
166
166
  /// Whether or not this type is considered to be special as opposed to physical.
167
- pub inline fn special(self: Type) bool {
167
+ pub fn special(self: Type) bool {
168
168
  return @intFromEnum(self) >= @intFromEnum(Type.Fire);
169
169
  }
170
170
 
171
171
  /// The `Effectiveness` of type `t2` vs. type `t1`.
172
- pub inline fn effectiveness(t1: Type, t2: Type) Effectiveness {
172
+ pub fn effectiveness(t1: Type, t2: Type) Effectiveness {
173
173
  return CHART[@intFromEnum(t1)][@intFromEnum(t2)];
174
174
  }
175
175
 
176
176
  /// The precedence order of Type `type`.
177
- pub inline fn precedence(self: Type) u8 {
177
+ pub fn precedence(self: Type) u8 {
178
178
  return PRECEDENCE[@intFromEnum(self)];
179
179
  }
180
180
 
181
181
  /// The internal index of this Type used by Present.
182
- pub inline fn present(self: Type) u8 {
182
+ pub fn present(self: Type) u8 {
183
183
  return INDEXES[@intFromEnum(self)];
184
184
  }
185
185
 
186
186
  /// The Type corresponding to a random roll of `num` for Conversion 2.
187
- pub inline fn conversion2(num: u8) Type {
187
+ pub fn conversion2(num: u8) Type {
188
188
  assert(num != 6);
189
189
  assert(num < 10 or num >= 20);
190
190
  assert(num <= 27);
@@ -192,7 +192,7 @@ pub const Type = enum(u8) {
192
192
  }
193
193
 
194
194
  /// The Type corresponding to a Hidden Power `index`.
195
- pub inline fn hiddenPower(index: u8) Type {
195
+ pub fn hiddenPower(index: u8) Type {
196
196
  return HIDDEN_POWER[index];
197
197
  }
198
198
  };
@@ -209,17 +209,17 @@ pub const Types = extern struct {
209
209
  }
210
210
 
211
211
  /// Whether this typing is immune to type `t`.
212
- pub inline fn immune(self: Types, t: Type) bool {
212
+ pub fn immune(self: Types, t: Type) bool {
213
213
  return t.effectiveness(self.type1) == I or t.effectiveness(self.type2) == I;
214
214
  }
215
215
 
216
216
  /// Whether this typing includes type `t`.
217
- pub inline fn includes(self: Types, t: Type) bool {
217
+ pub fn includes(self: Types, t: Type) bool {
218
218
  return self.type1 == t or self.type2 == t;
219
219
  }
220
220
 
221
221
  /// Whether this typing is immune to damage from Sandstorm.
222
- pub inline fn sandstormImmune(self: Types) bool {
222
+ pub fn sandstormImmune(self: Types) bool {
223
223
  return @intFromEnum(self.type1) <= @intFromEnum(Type.Steel) or
224
224
  @intFromEnum(self.type2) <= @intFromEnum(Type.Steel);
225
225
  }
@@ -62,17 +62,17 @@ pub fn Battle(comptime RNG: anytype) type {
62
62
 
63
63
  _: [padding]u8 = .{0} ** padding,
64
64
 
65
- pub inline fn side(self: anytype, player: Player) PointerType(@TypeOf(self), Side) {
65
+ pub fn side(self: anytype, player: Player) PointerType(@TypeOf(self), Side) {
66
66
  assert(@typeInfo(@TypeOf(self)).Pointer.child == Self);
67
67
  return &self.sides[@intFromEnum(player)];
68
68
  }
69
69
 
70
- pub inline fn foe(self: anytype, player: Player) PointerType(@TypeOf(self), Side) {
70
+ pub fn foe(self: anytype, player: Player) PointerType(@TypeOf(self), Side) {
71
71
  assert(@typeInfo(@TypeOf(self)).Pointer.child == Self);
72
72
  return &self.sides[@intFromEnum(player.foe())];
73
73
  }
74
74
 
75
- pub inline fn active(self: *const Self, player: Player) ID {
75
+ pub fn active(self: *const Self, player: Player) ID {
76
76
  return player.ident(@intCast(self.side(player).pokemon[0].position));
77
77
  }
78
78
 
@@ -133,7 +133,7 @@ pub const Side = extern struct {
133
133
  assert(@sizeOf(Side) == 248);
134
134
  }
135
135
 
136
- pub inline fn get(self: anytype, slot: u8) PointerType(@TypeOf(self), Pokemon) {
136
+ pub fn get(self: anytype, slot: u8) PointerType(@TypeOf(self), Pokemon) {
137
137
  assert(@typeInfo(@TypeOf(self)).Pointer.child == Side);
138
138
  assert(slot > 0 and slot <= 6);
139
139
  const id = self.pokemon[slot - 1].position;
@@ -141,19 +141,19 @@ pub const Side = extern struct {
141
141
  return &self.pokemon[id - 1];
142
142
  }
143
143
 
144
- pub inline fn stored(self: anytype) PointerType(@TypeOf(self), Pokemon) {
144
+ pub fn stored(self: anytype) PointerType(@TypeOf(self), Pokemon) {
145
145
  assert(@typeInfo(@TypeOf(self)).Pointer.child == Side);
146
146
  return self.get(1);
147
147
  }
148
148
 
149
- pub inline fn lastMove(self: anytype, encore: bool) Move {
149
+ pub fn lastMove(self: anytype, encore: bool) Move {
150
150
  assert(self.last_used_move != .None or !self.active.volatiles.dirty);
151
151
  if (encore) return self.last_used_move;
152
152
  return if (self.active.volatiles.dirty) .None else self.last_used_move;
153
153
  }
154
154
 
155
155
  // TODO
156
- // pub inline fn useMove(self: anytype) void {
156
+ // pub fn useMove(self: anytype) void {
157
157
  // assert(side.last_selected_move != .None);
158
158
  // self.last_used_move = side.last_selected_move;
159
159
  // self.active.volatiles.dirty = false;
@@ -175,7 +175,7 @@ pub const ActivePokemon = extern struct {
175
175
  assert(@sizeOf(ActivePokemon) == 44);
176
176
  }
177
177
 
178
- pub inline fn move(self: anytype, mslot: u8) PointerType(@TypeOf(self), MoveSlot) {
178
+ pub fn move(self: anytype, mslot: u8) PointerType(@TypeOf(self), MoveSlot) {
179
179
  assert(@typeInfo(@TypeOf(self)).Pointer.child == Pokemon);
180
180
  assert(mslot > 0 and mslot <= 4);
181
181
  assert(self.moves[mslot - 1].id != .None);
@@ -200,7 +200,7 @@ pub const Pokemon = extern struct {
200
200
  assert(@sizeOf(Pokemon) == 32);
201
201
  }
202
202
 
203
- pub inline fn move(self: anytype, mslot: u8) PointerType(@TypeOf(self), MoveSlot) {
203
+ pub fn move(self: anytype, mslot: u8) PointerType(@TypeOf(self), MoveSlot) {
204
204
  assert(@typeInfo(@TypeOf(self)).Pointer.child == Pokemon);
205
205
  assert(mslot > 0 and mslot <= 4);
206
206
  assert(self.moves[mslot - 1].id != .None);
@@ -225,7 +225,7 @@ pub const DVs = packed struct(u16) {
225
225
  return .{ .gender = g, .pow = p, .type = t };
226
226
  }
227
227
 
228
- pub inline fn power(dvs: DVs) u8 {
228
+ pub fn power(dvs: DVs) u8 {
229
229
  return @as(u8, dvs.pow) + 30;
230
230
  }
231
231
 
@@ -239,7 +239,7 @@ pub const DVs = packed struct(u16) {
239
239
  };
240
240
  const p: u6 = @intCast(1 + ((5 * @as(u8, (dvs.atk & 0b1000) | ((dvs.def & 0b1000)) >> 1 |
241
241
  ((dvs.spe & 0b1000)) >> 2 | ((dvs.spc & 0b1000)) >> 3) + (dvs.spc & 0b0011)) >> 1));
242
- var t = @as(u8, dvs.def & 0b0011) + (@as(u8, dvs.atk & 0b0011) << 2);
242
+ const t = @as(u8, dvs.def & 0b0011) + (@as(u8, dvs.atk & 0b0011) << 2);
243
243
  return .{ .gender = g, .pow = p, .type = Type.hiddenPower(t) };
244
244
  }
245
245
  };
@@ -248,12 +248,12 @@ test DVs {
248
248
  var dvs = DVs.from(.Mewtwo, .{ .def = 13 });
249
249
  try expectEqual(Gender.Unknown, dvs.gender);
250
250
  try expectEqual(Type.Ice, dvs.type);
251
- try expectEqual(@as(u8, 70), dvs.power());
251
+ try expectEqual(70, dvs.power());
252
252
 
253
253
  dvs = DVs.from(.Pikachu, .{ .spc = 14 });
254
254
  try expectEqual(Gender.Male, dvs.gender);
255
255
  try expectEqual(Type.Dark, dvs.type);
256
- try expectEqual(@as(u8, 69), dvs.power());
256
+ try expectEqual(69, dvs.power());
257
257
 
258
258
  dvs = DVs.from(.Cyndaquil, .{ .atk = 1, .def = 3, .spe = 10, .spc = 9 });
259
259
  try expectEqual(Gender.Female, dvs.gender);
@@ -280,22 +280,7 @@ pub const MoveSlot = extern struct {
280
280
  pub const Status = gen1.Status;
281
281
 
282
282
  /// TODO
283
- pub const TriAttack = enum(u2) {
284
- PAR,
285
- FRZ,
286
- BRN,
287
-
288
- /// TODO
289
- pub inline fn status(self: TriAttack) u8 {
290
- return Status.init(@enumFromInt(6 - @as(u8, @intFromEnum(self))));
291
- }
292
- };
293
-
294
- test TriAttack {
295
- try expectEqual(Status.init(.PAR), TriAttack.PAR.status());
296
- try expectEqual(Status.init(.FRZ), TriAttack.FRZ.status());
297
- try expectEqual(Status.init(.BRN), TriAttack.BRN.status());
298
- }
283
+ pub const TriAttack = enum(u2) { PAR, FRZ, BRN };
299
284
 
300
285
  pub const Volatiles = packed struct(u128) {
301
286
  Bide: bool = false,
@@ -329,14 +314,19 @@ pub const Volatiles = packed struct(u128) {
329
314
  Encore: bool = false,
330
315
  LockOn: bool = false,
331
316
  DestinyBond: bool = false,
317
+ Trapped: bool = false,
332
318
 
333
- trapped: bool = false,
334
319
  switched: bool = false,
320
+ // TODO: replace with simply looking at Choice on Battle
335
321
  switching: bool = false,
322
+ // TODO: simply store both last moves on side
336
323
  dirty: bool = false,
337
324
 
338
325
  frozen: bool = false,
339
- _: u15 = 0,
326
+ minimized: bool = false,
327
+ _: u10 = 0,
328
+ // TODO: is this needed for unmodified stats?
329
+ transform: u4 = 0,
340
330
 
341
331
  bide: u16 = 0,
342
332
  bind: Bind = .{},
@@ -390,9 +380,9 @@ test Stats {
390
380
  try expectEqual(0, stats.def);
391
381
 
392
382
  var base = Species.get(.Gyarados).stats;
393
- try expectEqual(@as(u16, 127), Stats(u16).calc("hp", base.hp, 0, 5120, 38));
383
+ try expectEqual(127, Stats(u16).calc("hp", base.hp, 0, 5120, 38));
394
384
  base = Species.get(.Pidgeot).stats;
395
- try expectEqual(@as(u16, 279), Stats(u16).calc("spe", base.spe, 15, 63001, 100));
385
+ try expectEqual(279, Stats(u16).calc("spe", base.spe, 15, 63001, 100));
396
386
  }
397
387
 
398
388
  pub const Boosts = packed struct(u32) {
@@ -438,8 +428,8 @@ test Move {
438
428
  try expectEqual(Move.Effect.ConfusionChance, move.effect);
439
429
  try expectEqual(rng.Gen12.percent(50), move.accuracy);
440
430
  try expectEqual(rng.Gen12.percent(100), move.chance);
441
- try expectEqual(@as(u8, 5), Move.pp(.DynamicPunch));
442
- try expectEqual(@as(i8, -1), Move.get(.Counter).priority);
431
+ try expectEqual(5, Move.pp(.DynamicPunch));
432
+ try expectEqual(-1, Move.get(.Counter).priority);
443
433
  try expect(!move.effect.isHighCritical());
444
434
  try expect(Move.get(.KarateChop).effect.isHighCritical());
445
435
  try expect(Move.get(.RazorWind).effect.isHighCritical());
@@ -449,7 +439,7 @@ pub const Species = species.Species;
449
439
 
450
440
  test Species {
451
441
  try expectEqual(152, @intFromEnum(Species.Chikorita));
452
- try expectEqual(@as(u8, 100), Species.get(.Celebi).stats.spd);
442
+ try expectEqual(100, Species.get(.Celebi).stats.spd);
453
443
  }
454
444
 
455
445
  pub const Type = types.Type;
@@ -462,7 +452,7 @@ test Types {
462
452
  try expect(!Type.Steel.special());
463
453
  try expect(Type.Dark.special());
464
454
 
465
- try expectEqual(@as(u8, 3), Type.Water.precedence());
455
+ try expectEqual(3, Type.Water.precedence());
466
456
  try expect(Type.Bug.precedence() > Type.Poison.precedence());
467
457
 
468
458
  try expectEqual(Effectiveness.Super, Type.effectiveness(.Ghost, .Psychic));