@pkmn/engine 0.1.0-dev.645b4750 → 0.1.0-dev.6ba42cd5

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.
@@ -15,9 +15,6 @@ const isPointerTo = util.isPointerTo;
15
15
  const Player = common.Player;
16
16
  const PointerType = util.PointerType;
17
17
 
18
- const Int = if (@hasField(std.builtin.Type, "int")) .int else .Int;
19
- const Enum = if (@hasField(std.builtin.Type, "enum")) .@"enum" else .Enum;
20
-
21
18
  /// Information relevant to damage calculation that occured during a Generation II battle `update`.
22
19
  pub const Summaries = extern struct {
23
20
  /// Relevant information for Player 1.
@@ -91,8 +88,8 @@ pub const Calc = struct {
91
88
  };
92
89
 
93
90
  return if (switch (@typeInfo(@TypeOf(val))) {
94
- Enum => val != .None,
95
- Int => val != 0,
91
+ .@"enum" => val != .None,
92
+ .int => val != 0,
96
93
  else => unreachable,
97
94
  }) val else null;
98
95
  }
@@ -148,6 +145,6 @@ fn ReturnType(comptime field: Action.Field) type {
148
145
  return ?(switch (field) {
149
146
  .damages => u8,
150
147
  .critical_hits => Optional(bool),
151
- else => util.FieldType(Action, field),
148
+ else => @FieldType(Action, @tagName(field)),
152
149
  });
153
150
  }
@@ -27,10 +27,6 @@ const Type = data.Type;
27
27
  const Effectiveness = data.Effectiveness;
28
28
  const TriAttack = data.TriAttack;
29
29
 
30
- const Int = if (@hasField(std.builtin.Type, "int")) .int else .Int;
31
- const Enum = if (@hasField(std.builtin.Type, "enum")) .@"enum" else .Enum;
32
- const Struct = if (@hasField(std.builtin.Type, "struct")) .@"struct" else .Struct;
33
-
34
30
  /// Actions taken by a hypothetical "chance player" that convey information about which RNG events
35
31
  /// were observed during a Generation II battle `update`. This can additionally be provided as input
36
32
  /// to the `update` call to override the normal behavior of the RNG in order to force specific
@@ -57,15 +53,15 @@ pub const Actions = extern struct {
57
53
  /// same shape if they have the same fields set (though those fields need not necessarily be
58
54
  /// set to the same value).
59
55
  pub fn matches(a: Actions, b: Actions) bool {
60
- inline for (@field(@typeInfo(Actions), @tagName(Struct)).fields) |player| {
61
- inline for (@field(@typeInfo(Action), @tagName(Struct)).fields) |field| {
56
+ inline for (@typeInfo(Actions).@"struct".fields) |player| {
57
+ inline for (@typeInfo(Action).@"struct".fields) |field| {
62
58
  const a_val = @field(@field(a, player.name), field.name);
63
59
  const b_val = @field(@field(b, player.name), field.name);
64
60
 
65
61
  switch (@typeInfo(@TypeOf(a_val))) {
66
- Enum => if ((@intFromEnum(a_val) > 0) != (@intFromEnum(b_val) > 0))
62
+ .@"enum" => if ((@intFromEnum(a_val) > 0) != (@intFromEnum(b_val) > 0))
67
63
  return false,
68
- Int => if ((a_val > 0) != (b_val > 0)) return false,
64
+ .int => if ((a_val > 0) != (b_val > 0)) return false,
69
65
  else => unreachable,
70
66
  }
71
67
  }
@@ -73,7 +69,7 @@ pub const Actions = extern struct {
73
69
  return true;
74
70
  }
75
71
 
76
- pub fn fmt(self: Actions, writer: anytype, shape: bool) !void {
72
+ pub fn fmt(self: Actions, writer: *std.Io.Writer, shape: bool) !void {
77
73
  try writer.writeAll("<P1 = ");
78
74
  try self.p1.fmt(writer, shape);
79
75
  try writer.writeAll(", P2 = ");
@@ -81,8 +77,7 @@ pub const Actions = extern struct {
81
77
  try writer.writeAll(">");
82
78
  }
83
79
 
84
- pub fn format(a: Actions, comptime f: []const u8, o: std.fmt.FormatOptions, w: anytype) !void {
85
- _ = .{ f, o };
80
+ pub fn format(a: Actions, w: *std.Io.Writer) !void {
86
81
  try fmt(a, w, false);
87
82
  }
88
83
  };
@@ -186,18 +181,17 @@ pub const Action = packed struct(u128) {
186
181
 
187
182
  pub const Field = std.meta.FieldEnum(Action);
188
183
 
189
- pub fn format(a: Action, comptime f: []const u8, o: std.fmt.FormatOptions, w: anytype) !void {
190
- _ = .{ f, o };
184
+ pub fn format(a: Action, w: *std.Io.Writer) !void {
191
185
  try fmt(a, w, false);
192
186
  }
193
187
 
194
- pub fn fmt(self: Action, writer: anytype, shape: bool) !void {
188
+ pub fn fmt(self: Action, writer: *std.Io.Writer, shape: bool) !void {
195
189
  try writer.writeByte('(');
196
190
  var printed = false;
197
- inline for (@field(@typeInfo(Action), @tagName(Struct)).fields) |field| {
191
+ inline for (@typeInfo(Action).@"struct".fields) |field| {
198
192
  const val = @field(self, field.name);
199
193
  switch (@typeInfo(@TypeOf(val))) {
200
- Enum => if (val != .None) {
194
+ .@"enum" => if (val != .None) {
201
195
  if (printed) try writer.writeAll(", ");
202
196
  if (shape) {
203
197
  try writer.print("{s}:?", .{field.name});
@@ -211,7 +205,7 @@ pub const Action = packed struct(u128) {
211
205
  }
212
206
  printed = true;
213
207
  },
214
- Int => if (val != 0) {
208
+ .int => if (val != 0) {
215
209
  if (printed) try writer.writeAll(", ");
216
210
  if (shape) {
217
211
  try writer.print("{s}:?", .{field.name});
@@ -786,7 +780,7 @@ pub fn expectProbability(r: anytype, p: u64, q: u64) !void {
786
780
 
787
781
  r.reduce();
788
782
  if (r.p != p or r.q != q) {
789
- print("expected {d}/{d}, found {}\n", .{ p, q, r });
783
+ print("expected {d}/{d}, found {f}\n", .{ p, q, r });
790
784
  return error.TestExpectedEqual;
791
785
  }
792
786
  }
@@ -172,9 +172,12 @@ pub const Type = enum(u8) {
172
172
  return CHART[@intFromEnum(t1)][@intFromEnum(t2)];
173
173
  }
174
174
 
175
- /// The precedence order of Type `type`.
176
- pub fn precedence(self: Type) u8 {
177
- return PRECEDENCE[@intFromEnum(self)];
175
+ /// The precedence order of Type `t1` vs. Type `t2`.
176
+ pub fn precedence(t1: Type, t2: Type) u8 {
177
+ // The Ice vs. Fire matchup is out of order - return a higher
178
+ // number than anything else so that it sorts last correctly
179
+ if (t1 == .Ice and t2 == .Fire) return 18;
180
+ return PRECEDENCE[@intFromEnum(t2)];
178
181
  }
179
182
 
180
183
  /// The internal index of this Type used by Present.
@@ -57,7 +57,7 @@ pub fn Battle(comptime RNG: anytype) type {
57
57
  turn: u16 = 0,
58
58
  field: Field = .{},
59
59
 
60
- _: [padding]u8 = .{0} ** padding,
60
+ _: [padding]u8 = @splat(0),
61
61
 
62
62
  pub fn side(self: anytype, player: Player) PointerType(@TypeOf(self), Side) {
63
63
  assert(isPointerTo(self, Self));
@@ -100,13 +100,13 @@ pub const Weather = enum(u4) {
100
100
  };
101
101
 
102
102
  pub const Side = extern struct {
103
- pokemon: [6]Pokemon = [_]Pokemon{.{}} ** 6,
103
+ pokemon: [6]Pokemon = @splat(.{}),
104
104
  active: ActivePokemon align(8) = .{},
105
105
  conditions: Conditions = .{},
106
106
  // NB: wLastPlayerCounterMove / wLastEnemyCounterMove (wLastPlayerMove / wLastEnemyMove)
107
107
  last_used_move: Move = .None,
108
108
 
109
- _: [7]u8 = .{0} ** 7,
109
+ _: [7]u8 = @splat(0),
110
110
 
111
111
  const Conditions = packed struct(u32) {
112
112
  Spikes: bool = false,
@@ -161,7 +161,7 @@ pub const Side = extern struct {
161
161
  pub const ActivePokemon = extern struct {
162
162
  volatiles: Volatiles align(4) = .{},
163
163
  stats: Stats(u16) = .{},
164
- moves: [4]MoveSlot = [_]MoveSlot{.{}} ** 4,
164
+ moves: [4]MoveSlot = @splat(.{}),
165
165
  boosts: Boosts = .{},
166
166
  types: Types = .{},
167
167
  species: Species = .None,
@@ -182,7 +182,7 @@ pub const ActivePokemon = extern struct {
182
182
 
183
183
  pub const Pokemon = extern struct {
184
184
  stats: Stats(u16) = .{},
185
- moves: [4]MoveSlot = [_]MoveSlot{.{}} ** 4,
185
+ moves: [4]MoveSlot = @splat(.{}),
186
186
  types: Types = .{},
187
187
  dvs: DVs = .{},
188
188
  hp: u16 = 0,
@@ -449,8 +449,9 @@ test Types {
449
449
  try expect(!Type.Steel.special());
450
450
  try expect(Type.Dark.special());
451
451
 
452
- try expectEqual(@as(u8, 3), Type.Water.precedence());
453
- try expect(Type.Bug.precedence() > Type.Poison.precedence());
452
+ try expectEqual(@as(u8, 3), Type.precedence(.Water, .Water));
453
+ try expect(Type.precedence(.Poison, .Bug) > Type.precedence(.Poison, .Poison));
454
+ try expect(Type.precedence(.Ice, .Fire) > Type.precedence(.Ice, .Water));
454
455
 
455
456
  try expectEqual(Effectiveness.Super, Type.effectiveness(.Ghost, .Psychic));
456
457
  try expectEqual(Effectiveness.Super, Type.effectiveness(.Water, .Fire));
@@ -16,8 +16,6 @@ const showdown = options.showdown;
16
16
  const Species = data.Species;
17
17
  const Stats = data.Stats;
18
18
 
19
- const Struct = if (@hasField(std.builtin.Type, "struct")) .@"struct" else .Struct;
20
-
21
19
  pub const Options = struct {
22
20
  cleric: bool = showdown,
23
21
  };
@@ -74,7 +72,7 @@ pub fn prng(rand: *PSRNG) data.PRNG {
74
72
  var carry: u8 = 0;
75
73
  var div: u8 = 0;
76
74
 
77
- var i: u8 = 0;
75
+ var i: usize = 0;
78
76
  while (i < seed.len) {
79
77
  div = @intCast(timer >> 8);
80
78
  // This is effectively @addWithOverflow but with three operands
@@ -142,7 +140,7 @@ pub const Pokemon = struct {
142
140
  var pokemon = data.Pokemon{};
143
141
  pokemon.species = p.species;
144
142
  const species = Species.get(p.species);
145
- inline for (@field(@typeInfo(@TypeOf(pokemon.stats)), @tagName(Struct)).fields) |field| {
143
+ inline for (@typeInfo(@TypeOf(pokemon.stats)).@"struct".fields) |field| {
146
144
  const hp = comptime std.mem.eql(u8, field.name, "hp");
147
145
  const spc =
148
146
  comptime std.mem.eql(u8, field.name, "spa") or std.mem.eql(u8, field.name, "spd");
@@ -183,7 +181,7 @@ pub const Pokemon = struct {
183
181
 
184
182
  var stats: Stats(u16) = .{};
185
183
  const dvs = gen1.DVs.random(rand);
186
- inline for (@field(@typeInfo(@TypeOf(stats)), @tagName(Struct)).fields) |field| {
184
+ inline for (@typeInfo(@TypeOf(stats)).@"struct".fields) |field| {
187
185
  const hp = std.mem.eql(u8, field.name, "hp");
188
186
  const spc = std.mem.eql(u8, field.name, "spa") or std.mem.eql(u8, field.name, "spd");
189
187
  @field(stats, field.name) = Stats(u16).calc(
@@ -195,7 +193,7 @@ pub const Pokemon = struct {
195
193
  );
196
194
  }
197
195
 
198
- var ms = [_]MoveSlot{.{}} ** 4;
196
+ var ms: [4]MoveSlot = @splat(.{});
199
197
  const n = if (rand.chance(u8, 1, 100)) rand.range(u4, 1, 3 + 1) else 4;
200
198
  for (0..n) |i| {
201
199
  var m: Move = .None;
@@ -682,7 +682,7 @@ pub fn adjustDamage(battle: anytype, player: Player, state: *State, _: anytype)
682
682
 
683
683
  // Type effectiveness matchup precedence only matters with (NVE, SE)
684
684
  if (!showdown and (eff1 + eff2) == Effectiveness.mismatch and
685
- types.type1.precedence() > types.type2.precedence())
685
+ Type.precedence(state.type, types.type1) > Type.precedence(state.type, types.type2))
686
686
  {
687
687
  assert(eff2 != neutral);
688
688
  d = d *% eff2 / 10;
@@ -1558,7 +1558,7 @@ pub const Effects = struct {
1558
1558
  const last = battle.foe(player).lastMove(true);
1559
1559
  const failed = volatiles.Encore or
1560
1560
  (last == .None or last == .Struggle or
1561
- last == .Encore or .last == .MirrorMove);
1561
+ last == .Encore or .last == .MirrorMove);
1562
1562
  if (failed) return options.log.fail(.{ foe_ident, .None });
1563
1563
 
1564
1564
  var slot: u3 = 0;
@@ -3081,7 +3081,7 @@ pub const Rolls = struct {
3081
3081
  }
3082
3082
 
3083
3083
  // Conversion 2 can at most choose between 7 types (vs. a Grass-type attack)
3084
- var CONVERSION_2: [7]Type = [_]Type{.@"???"} ** 7;
3084
+ var CONVERSION_2: [7]Type = @splat(.@"???");
3085
3085
 
3086
3086
  fn conversion2(battle: anytype, player: Player, mtype: Type, options: anytype) !Type {
3087
3087
  var i: u8 = 0;
@@ -3506,11 +3506,11 @@ pub fn choices(battle: anytype, player: Player, request: Choice.Type, out: []Cho
3506
3506
  },
3507
3507
  .Switch => {
3508
3508
  const side = battle.side(player);
3509
- var slot: u4 = 2;
3509
+ var slot: usize = 2;
3510
3510
  while (slot <= 6) : (slot += 1) {
3511
3511
  const id = side.order[slot - 1];
3512
3512
  if (id == 0 or side.pokemon[id - 1].hp == 0) continue;
3513
- out[n] = .{ .type = .Switch, .data = slot };
3513
+ out[n] = .{ .type = .Switch, .data = @intCast(slot) };
3514
3514
  n += 1;
3515
3515
  }
3516
3516
  if (n == 0) {
@@ -3540,11 +3540,11 @@ pub fn choices(battle: anytype, player: Player, request: Choice.Type, out: []Cho
3540
3540
  return n;
3541
3541
  }
3542
3542
 
3543
- var slot: u4 = 2;
3543
+ var slot: usize = 2;
3544
3544
  while (!active.volatiles.Trapped and slot <= 6) : (slot += 1) {
3545
3545
  const id = side.order[slot - 1];
3546
3546
  if (id == 0 or side.pokemon[id - 1].hp == 0) continue;
3547
- out[n] = .{ .type = .Switch, .data = slot };
3547
+ out[n] = .{ .type = .Switch, .data = @intCast(slot) };
3548
3548
  n += 1;
3549
3549
  }
3550
3550
 
@@ -3577,7 +3577,7 @@ pub fn choices(battle: anytype, player: Player, request: Choice.Type, out: []Cho
3577
3577
  const struggle =
3578
3578
  m.id == .Bide and (m.pp == 0 or active.volatiles.disable.move == slot);
3579
3579
  const s = if (struggle) 0 else slot;
3580
- out[n] = .{ .type = .Move, .data = s };
3580
+ out[n] = .{ .type = .Move, .data = @intCast(s) };
3581
3581
  n += 1;
3582
3582
  return n;
3583
3583
  }
@@ -3591,7 +3591,7 @@ pub fn choices(battle: anytype, player: Player, request: Choice.Type, out: []Cho
3591
3591
  if (m.id == .None) break;
3592
3592
  if (m.pp == 0) continue;
3593
3593
  if (active.volatiles.disable.move == slot) continue;
3594
- out[n] = .{ .type = .Move, .data = slot };
3594
+ out[n] = .{ .type = .Move, .data = @intCast(slot) };
3595
3595
  n += 1;
3596
3596
  }
3597
3597
  // Struggle (Pokémon Showdown would use 'move 1' here)
package/src/lib/napi.h ADDED
@@ -0,0 +1,2 @@
1
+ #define NAPI_VERSION 8
2
+ #include <node_api.h>
package/src/lib/node.zig CHANGED
@@ -1,14 +1,10 @@
1
+ const c = @import("napi");
1
2
  const js = @import("common/js.zig");
2
3
  const node = @import("bindings/node.zig");
3
4
  const std = @import("std");
4
5
 
5
6
  const assert = std.debug.assert;
6
7
 
7
- const c = @cImport({
8
- @cDefine("NAPI_VERSION", "8");
9
- @cInclude("node_api.h");
10
- });
11
-
12
8
  export fn napi_register_module_v1(env: c.napi_env, exports: c.napi_value) c.napi_value {
13
9
  const properties = [_]c.napi_property_descriptor{
14
10
  js.Property.init("engine", .{ .value = node.register(env) }),
package/src/lib/pkmn.zig CHANGED
@@ -22,9 +22,9 @@ pub const Choice = @import("common/data.zig").Choice;
22
22
  /// considered terminal.
23
23
  pub const Result = @import("common/data.zig").Result;
24
24
 
25
- // TODO
25
+ /// Helpers for working with bit-packed arrays of non-powers-of-2 types.
26
26
  pub const Array = @import("common/array.zig").Array;
27
- // TODO
27
+ /// Optimized optional representation which stores the empty None value as a sentinel.
28
28
  pub const Optional = @import("common/optional.zig").Optional;
29
29
 
30
30
  /// Pokémon Showdown's RNG (backed by a Generation V & VI RNG).
@@ -32,31 +32,78 @@ pub const PSRNG = @import("common/rng.zig").PSRNG;
32
32
 
33
33
  /// Namespace for helpers related to protocol message logging.
34
34
  pub const protocol = if (options.internal) @import("common/protocol.zig") else struct {
35
- /// Logs protocol information to its `Writer` during a battle update when
35
+ /// Logs protocol information to its `WriterT` during a battle update when
36
36
  /// `options.log` is enabled.
37
37
  pub const Log = @import("common/protocol.zig").Log;
38
- /// Stripped down version of `std.io.FixedBufferStream` optimized for
39
- /// efficiently writing the individual protocol bytes. Note that the
40
- /// `ByteStream.Writer` is **not** a `std.io.Writer` and should not be
41
- /// used for general purpose writing.
42
- pub const ByteStream = @import("common/protocol.zig").ByteStream;
43
- /// `Log` type backed by the optimized `ByteStream.Writer`. Intended to be
44
- /// intialized with a `LOGS_SIZE`-sized buffer.
38
+ /// `Log` type backed by the optimized `Writer`. Intended to be intialized with
39
+ /// a `LOGS_SIZE`-sized buffer.
45
40
  pub const FixedLog = @import("common/protocol.zig").FixedLog;
46
- /// Null object pattern implementation of `Log` backed by a
47
- /// `std.io.null_writer`. Ignores anything sent to it, though protocol
48
- /// logging should additionally be turned off entirely with `options.log`.
41
+ /// Minimal logging helper optimized for efficiently writing the individual
42
+ /// protocol bytes into a fixed buffer. Note that this is **not** a
43
+ /// `std.Io.Writer` and should not be used for general purpose writing.
44
+ pub const Writer = @import("common/protocol.zig").Writer;
45
+ /// Null object pattern implementation of `Log` backed by a null writer.
46
+ /// Ignores anything sent to it, though protocol logging should additionally
47
+ /// be turned off entirely with `options.log`.
49
48
  pub const NULL = @import("common/protocol.zig").NULL;
50
49
  };
51
50
 
52
- pub usingnamespace @import("common/rational.zig");
51
+ /// Specialization of a rational number used by the engine to compute probabilties.
52
+ pub const Rational = @import("common/rational.zig").Rational;
53
53
 
54
54
  /// Namespace for cross-generation battle-related types.
55
55
  pub const battle = @import("common/battle.zig");
56
56
 
57
57
  /// Namespace for Generation I Pokémon.
58
58
  pub const gen1 = struct {
59
- pub usingnamespace @import("gen1/data.zig");
59
+ const data = @import("gen1/data.zig");
60
+ /// The minimum size in bytes required to hold all Generation I choice options.
61
+ pub const MAX_CHOICES = data.MAX_CHOICES;
62
+ /// The maximum number of bytes possibly logged by a single Generation I update.
63
+ pub const MAX_LOGS = data.MAX_LOGS;
64
+ /// The optimal size in bytes required to hold all Generation I choice options.
65
+ /// At least as large as MAX_CHOICES.
66
+ pub const CHOICES_SIZE = data.CHOICES_SIZE;
67
+ /// The optimal size in bytes required to hold the largest amount of log data possible from a
68
+ /// single Generation I update. At least as large as MAX_LOGS.
69
+ pub const LOGS_SIZE = data.LOGS_SIZE;
70
+ /// Null object pattern implementation of pkmn.battle.Options for Generation I.
71
+ pub const NULL = data.NULL;
72
+ /// The pseudo random number generator used by Generation I.
73
+ pub const PRNG = data.PRNG;
74
+ /// Representation of a Generation I battle.
75
+ pub const Battle = data.Battle;
76
+ /// Representation of one side of a Generation I Pokémon battle.
77
+ pub const Side = data.Side;
78
+ /// Representation of the state for single Generation I Pokémon while active in battle.
79
+ pub const ActivePokemon = data.ActivePokemon;
80
+ /// Representation of the state for single Generation I Pokémon while inactive in the party.
81
+ pub const Pokemon = data.Pokemon;
82
+ /// Representation of a Generation I Pokémon's move slot in a battle.
83
+ pub const MoveSlot = data.MoveSlot;
84
+ /// Details required to detect desyncs based on the move last selected/executed by players.
85
+ pub const MoveDetails = data.MoveDetails;
86
+ /// Bitfield representation of a Generation I & II Pokémon's major status condition.
87
+ pub const Status = data.Status;
88
+ /// Bitfield representation of volatile statuses and associated data in Generation I.
89
+ pub const Volatiles = data.Volatiles;
90
+ /// Representation of a Pokémon's stats in Generation I.
91
+ pub const Stats = data.Stats;
92
+ /// Representation of a Pokémon's boosts in Generation I.
93
+ pub const Boosts = data.Boosts;
94
+ /// Representation of a Generation I Pokémon move.
95
+ pub const Move = data.Move;
96
+ /// Representation of a Generation I Pokémon species.
97
+ pub const Species = data.Species;
98
+ /// Representation of a Generation I type in Pokémon.
99
+ pub const Type = data.Type;
100
+ /// Representation of a Generation I Pokémon's typing.
101
+ pub const Types = data.Types;
102
+ /// Modifiers for the effectiveness of a type vs. another type in Pokémon.
103
+ pub const Effectiveness = data.Effectiveness;
104
+ /// Representation of a Generation I Pokémon's determinant values.
105
+ pub const DVs = data.DVs;
106
+
60
107
  /// Tracks chance actions and their associated probability during a
61
108
  /// Generation I battle update when `options.chance` is enabled.
62
109
  pub const Chance = @import("gen1/chance.zig").Chance;
@@ -107,7 +154,34 @@ pub const gen1 = struct {
107
154
 
108
155
  /// TODO
109
156
  pub const gen2 = struct {
110
- pub usingnamespace @import("gen2/data.zig");
157
+ const data = @import("gen2/data.zig");
158
+ pub const MAX_CHOICES = data.MAX_CHOICES;
159
+ pub const MAX_LOGS = data.MAX_LOGS;
160
+ pub const CHOICES_SIZE = data.CHOICES_SIZE;
161
+ pub const LOGS_SIZE = data.LOGS_SIZE;
162
+ pub const NULL = data.NULL;
163
+ pub const PRNG = data.PRNG;
164
+ pub const Battle = data.Battle;
165
+ pub const Field = data.Field;
166
+ pub const Weather = data.Weather;
167
+ pub const Side = data.Side;
168
+ pub const ActivePokemon = data.ActivePokemon;
169
+ pub const Pokemon = data.Pokemon;
170
+ pub const Gender = data.Gender;
171
+ pub const DVs = data.DVs;
172
+ pub const MoveSlot = data.MoveSlot;
173
+ pub const Status = data.Status;
174
+ pub const TriAttack = data.TriAttack;
175
+ pub const Volatiles = data.Volatiles;
176
+ pub const Stats = data.Stats;
177
+ pub const Boosts = data.Boosts;
178
+ pub const Item = data.Item;
179
+ pub const Move = data.Move;
180
+ pub const Species = data.Species;
181
+ pub const Type = data.Type;
182
+ pub const Types = data.Types;
183
+ pub const Effectiveness = data.Effectiveness;
184
+
111
185
  pub const Chance = @import("gen2/chance.zig").Chance;
112
186
  pub const chance = struct {
113
187
  pub const Actions = @import("gen2/chance.zig").Actions;
@@ -126,8 +200,8 @@ pub const gen2 = struct {
126
200
  };
127
201
 
128
202
  // Internal APIs used by other pkmn libraries, not actually part of the public API.
129
- // NOTE: `pub usingnamespace struct { ... }` here results in a (false?) dependency loop
130
203
  pub const js = if (options.internal) @import("common/js.zig") else {};
204
+ pub const util = if (options.internal) @import("common/util.zig") else {};
131
205
  pub const bindings = if (options.internal) struct {
132
206
  pub const c = @import("bindings/c.zig");
133
207
  pub const node = @import("bindings/node.zig");
package/src/lib/wasm.zig CHANGED
@@ -9,9 +9,5 @@ export const CALC = wasm.options.calc;
9
9
  export const GEN1_CHOICES_SIZE = wasm.gen(1).CHOICES_SIZE;
10
10
  export const GEN1_LOGS_SIZE = wasm.gen(1).LOGS_SIZE;
11
11
 
12
- const exportable = @hasDecl(std.zig, "Zir") and !@hasField(std.zig.Zir.Inst.Tag, "export_value");
13
-
14
- usingnamespace if (exportable) struct {
15
- export const GEN1_update = wasm.gen(1).update;
16
- export const GEN1_choices = wasm.gen(1).choices;
17
- } else wasm.exports();
12
+ export const GEN1_update = wasm.gen(1).update;
13
+ export const GEN1_choices = wasm.gen(1).choices;