@pkmn/engine 0.1.0-dev.d3e796d5 → 0.1.0-dev.d56bdadd

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.
@@ -121,12 +121,19 @@ pub const Cant = enum(u8) {
121
121
  Disable,
122
122
  Recharge,
123
123
  PP,
124
+
125
+ Attract,
124
126
  };
125
127
 
126
128
  pub const Heal = enum(u8) {
127
129
  None,
128
130
  Silent,
129
131
  Drain,
132
+
133
+ Leftovers,
134
+ Berry,
135
+ BerryJuice,
136
+ GoldBerry,
130
137
  };
131
138
 
132
139
  pub const Damage = enum(u8) {
@@ -137,7 +144,16 @@ pub const Damage = enum(u8) {
137
144
  LeechSeed,
138
145
  RecoilOf,
139
146
 
147
+ Bind,
148
+ Wrap,
149
+ FireSpin,
150
+ Clamp,
151
+ Whirlpool,
140
152
  Spikes,
153
+
154
+ Nightmare,
155
+ Curse,
156
+ Sandstorm,
141
157
  };
142
158
 
143
159
  pub const Status = enum(u8) {
@@ -180,8 +196,25 @@ pub const Activate = enum(u8) {
180
196
  Haze,
181
197
  Mist,
182
198
  Struggle,
183
- Substitute,
199
+ Substitute, // FIXME SubstituteDamage
184
200
  Splash,
201
+
202
+ Rage, // TODO
203
+
204
+ Attract,
205
+ LockOn,
206
+ Bind,
207
+ Wrap,
208
+ FireSpin,
209
+ Clamp,
210
+ Whirlpool,
211
+ SubstituteBlock,
212
+
213
+ DestinyBond,
214
+
215
+ BeatUp, // FIXME of
216
+
217
+ Magnitude,
185
218
  };
186
219
 
187
220
  pub const Start = enum(u8) {
@@ -199,6 +232,19 @@ pub const Start = enum(u8) {
199
232
 
200
233
  Disable,
201
234
  Mimic,
235
+
236
+ Attract,
237
+ Nightmare,
238
+ Curse,
239
+ Foresight,
240
+ Encore,
241
+ FutureSight,
242
+
243
+ PerishSong0,
244
+ PerishSong1,
245
+ PerishSong2,
246
+ PerishSong3,
247
+ PerishSong3Silent,
202
248
  };
203
249
 
204
250
  pub const End = enum(u8) {
@@ -207,16 +253,30 @@ pub const End = enum(u8) {
207
253
  Bide,
208
254
  Substitute,
209
255
 
210
- // Silent
256
+ Nightmare,
257
+ Curse,
258
+ Foresight,
259
+ Encore,
260
+ FutureSight,
261
+ LeechSeed,
262
+
263
+ Bind,
264
+ Wrap,
265
+ FireSpin,
266
+ Clamp,
267
+ Whirlpool,
268
+
211
269
  DisableSilent,
212
270
  ConfusionSilent,
213
-
214
- Mist,
215
- FocusEnergy,
216
- LeechSeed,
217
- Toxic,
218
- LightScreen,
219
- Reflect,
271
+ MistSilent,
272
+ FocusEnergySilent,
273
+ LeechSeedSilent,
274
+ ToxicSilent,
275
+ LightScreenSilent,
276
+ ReflectSilent,
277
+ BideSilent,
278
+
279
+ LeechSeedFrom,
220
280
  };
221
281
 
222
282
  pub const Immune = enum(u8) {
@@ -224,6 +284,28 @@ pub const Immune = enum(u8) {
224
284
  OHKO,
225
285
  };
226
286
 
287
+ pub const EndItem = enum(u8) {
288
+ None,
289
+ Eat,
290
+ };
291
+
292
+ pub const SetHP = enum(u8) {
293
+ None,
294
+ Silent,
295
+ };
296
+
297
+ pub const Side = enum(u8) {
298
+ Safeguard,
299
+ Reflect,
300
+ LightScreen,
301
+ Spikes,
302
+ };
303
+
304
+ pub const Weather = enum(u8) {
305
+ None,
306
+ Upkeep,
307
+ };
308
+
227
309
  /// Null object pattern implementation of `Log` backed by a `std.io.null_writer`.
228
310
  /// Ignores anything sent to it, though protocol logging should additionally be turned off
229
311
  /// entirely with `options.log`.
@@ -238,7 +320,7 @@ pub fn Log(comptime Writer: type) type {
238
320
 
239
321
  pub const Error = Writer.Error;
240
322
 
241
- pub fn move(self: Self, source: ID, m: anytype, target: ID, from: anytype) Error!void {
323
+ pub fn move(self: Self, source: ID, m: anytype, target: ID) Error!void {
242
324
  if (!enabled) return;
243
325
 
244
326
  assert(m != .None);
@@ -247,25 +329,34 @@ pub fn Log(comptime Writer: type) type {
247
329
  @as(u8, @bitCast(source)),
248
330
  @intFromEnum(m),
249
331
  @as(u8, @bitCast(target)),
332
+ @intFromEnum(Move.None),
250
333
  });
251
- const none = &[_]u8{@intFromEnum(Move.None)};
252
- try self.writer.writeAll(switch (@typeInfo(@TypeOf(from))) {
253
- .Null => none,
254
- .Optional => if (from) |f| blk: {
255
- assert(@intFromEnum(f) != 0);
256
- break :blk &[_]u8{ @intFromEnum(Move.From), @intFromEnum(f) };
257
- } else none,
258
- else => blk: {
259
- assert(@intFromEnum(from) != 0);
260
- break :blk &[_]u8{ @intFromEnum(Move.From), @intFromEnum(from) };
261
- },
334
+ }
335
+
336
+ pub fn moveFrom(self: Self, source: ID, m: anytype, target: ID, from: anytype) Error!void {
337
+ if (!enabled) return;
338
+
339
+ assert(m != .None);
340
+ try self.writer.writeAll(&.{
341
+ @intFromEnum(ArgType.Move),
342
+ @as(u8, @bitCast(source)),
343
+ @intFromEnum(m),
344
+ @as(u8, @bitCast(target)),
262
345
  });
346
+ try self.writer.writeAll(if (@intFromEnum(from) == 0)
347
+ &.{@intFromEnum(Move.None)}
348
+ else
349
+ &.{ @intFromEnum(Move.From), @intFromEnum(from) });
263
350
  }
264
351
 
265
352
  pub fn switched(self: Self, ident: ID, pokemon: anytype) Error!void {
353
+ return switchDrag(self, .Switch, ident, pokemon);
354
+ }
355
+
356
+ fn switchDrag(self: Self, arg: ArgType, ident: ID, pokemon: anytype) Error!void {
266
357
  if (!enabled) return;
267
358
 
268
- try self.writer.writeAll(&.{ @intFromEnum(ArgType.Switch), @as(u8, @bitCast(ident)) });
359
+ try self.writer.writeAll(&.{ @intFromEnum(arg), @as(u8, @bitCast(ident)) });
269
360
  if (@hasField(@TypeOf(pokemon.*), "dvs")) {
270
361
  try self.writer.writeAll(&.{
271
362
  @intFromEnum(pokemon.species),
@@ -487,10 +578,34 @@ pub fn Log(comptime Writer: type) type {
487
578
  pub fn activate(self: Self, ident: ID, reason: Activate) Error!void {
488
579
  if (!enabled) return;
489
580
 
581
+ assert(reason != .SubstituteBlock); // TODO
582
+ try self.writer.writeAll(&.{
583
+ @intFromEnum(ArgType.Activate),
584
+ @as(u8, @bitCast(ident)),
585
+ @intFromEnum(reason),
586
+ });
587
+ }
588
+
589
+ pub fn activateMove(self: Self, ident: ID, reason: Activate, m: anytype) Error!void {
590
+ if (!enabled) return;
591
+
592
+ assert(reason == .SubstituteBlock); // TODO
490
593
  try self.writer.writeAll(&.{
491
594
  @intFromEnum(ArgType.Activate),
492
595
  @as(u8, @bitCast(ident)),
493
596
  @intFromEnum(reason),
597
+ @intFromEnum(m),
598
+ });
599
+ }
600
+
601
+ pub fn magnitude(self: Self, ident: ID, num: u8) Error!void {
602
+ if (!enabled) return;
603
+
604
+ try self.writer.writeAll(&.{
605
+ @intFromEnum(ArgType.Activate),
606
+ @as(u8, @bitCast(ident)),
607
+ @intFromEnum(Activate.Magnitude),
608
+ num,
494
609
  });
495
610
  }
496
611
 
@@ -595,6 +710,132 @@ pub fn Log(comptime Writer: type) type {
595
710
  });
596
711
  }
597
712
 
713
+ pub fn drag(self: Self, ident: ID, pokemon: anytype) Error!void {
714
+ return switchDrag(self, .Drag, ident, pokemon);
715
+ }
716
+
717
+ pub fn item(self: Self, target: ID, i: anytype, source: ID) Error!void {
718
+ if (!enabled) return;
719
+
720
+ try self.writer.writeAll(&.{
721
+ @intFromEnum(ArgType.Item),
722
+ @as(u8, @bitCast(target)),
723
+ @intFromEnum(i),
724
+ @as(u8, @bitCast(source)),
725
+ });
726
+ }
727
+
728
+ pub fn enditem(self: Self, ident: ID, i: anytype, reason: EndItem) Error!void {
729
+ if (!enabled) return;
730
+
731
+ try self.writer.writeAll(&.{
732
+ @intFromEnum(ArgType.EndItem),
733
+ @as(u8, @bitCast(ident)),
734
+ @intFromEnum(i),
735
+ @intFromEnum(reason),
736
+ });
737
+ }
738
+
739
+ pub fn cureteam(self: Self, source: ID) Error!void {
740
+ if (!enabled) return;
741
+
742
+ try self.writer.writeAll(&.{
743
+ @intFromEnum(ArgType.CureTeam),
744
+ @as(u8, @bitCast(source)),
745
+ });
746
+ }
747
+
748
+ pub fn sethp(self: Self, ident: ID, pokemon: anytype, reason: SetHP) Error!void {
749
+ if (!enabled) return;
750
+
751
+ try self.writer.writeAll(&.{ @intFromEnum(ArgType.SetHP), @as(u8, @bitCast(ident)) });
752
+ try self.writer.writeIntNative(u16, pokemon.hp);
753
+ try self.writer.writeIntNative(u16, pokemon.stats.hp);
754
+ try self.writer.writeAll(&.{pokemon.status});
755
+ try self.writer.writeByte(@intFromEnum(reason));
756
+ }
757
+
758
+ pub fn setboost(self: Self, ident: ID, num: i8) Error!void {
759
+ if (!enabled) return;
760
+
761
+ try self.writer.writeAll(&.{
762
+ @intFromEnum(ArgType.SetBoost),
763
+ @as(u8, @bitCast(ident)),
764
+ @as(u8, @intCast(num + 6)),
765
+ });
766
+ }
767
+
768
+ pub fn copyboost(self: Self, source: ID, target: ID) Error!void {
769
+ if (!enabled) return;
770
+
771
+ try self.writer.writeAll(&.{
772
+ @intFromEnum(ArgType.CopyBoost),
773
+ @as(u8, @bitCast(source)),
774
+ @as(u8, @bitCast(target)),
775
+ });
776
+ }
777
+
778
+ pub fn sidestart(self: Self, player: Player, reason: Side) Error!void {
779
+ if (!enabled) return;
780
+
781
+ try self.writer.writeAll(&.{
782
+ @intFromEnum(ArgType.SideStart),
783
+ @intFromEnum(player),
784
+ @intFromEnum(reason),
785
+ });
786
+ }
787
+
788
+ pub fn sideend(self: Self, player: Player, reason: Side) Error!void {
789
+ if (!enabled) return;
790
+
791
+ assert(@intFromEnum(reason) != @intFromEnum(Side.Spikes));
792
+ try self.writer.writeAll(&.{
793
+ @intFromEnum(ArgType.SideEnd),
794
+ @intFromEnum(player),
795
+ @intFromEnum(reason),
796
+ });
797
+ }
798
+
799
+ pub fn spikesend(self: Self, source: ID) Error!void {
800
+ if (!enabled) return;
801
+
802
+ try self.writer.writeAll(&.{
803
+ @intFromEnum(ArgType.SideEnd),
804
+ @intFromEnum(source.player),
805
+ @intFromEnum(Side.Spikes),
806
+ @as(u8, @bitCast(source)),
807
+ });
808
+ }
809
+
810
+ pub fn singlemove(self: Self, ident: ID, m: anytype) Error!void {
811
+ return single(self, .SingleMove, ident, m);
812
+ }
813
+
814
+ pub fn singleturn(self: Self, ident: ID, m: anytype) Error!void {
815
+ return single(self, .SingleTurn, ident, m);
816
+ }
817
+
818
+ fn single(self: Self, arg: ArgType, ident: ID, m: anytype) Error!void {
819
+ if (!enabled) return;
820
+
821
+ try self.writer.writeAll(&.{
822
+ @intFromEnum(arg),
823
+ @as(u8, @bitCast(ident)),
824
+ @intFromEnum(m),
825
+ });
826
+ }
827
+
828
+ pub fn weather(self: Self, w: anytype, reason: Weather) Error!void {
829
+ if (!enabled) return;
830
+
831
+ assert(!(w == .None and reason == .Upkeep));
832
+ try self.writer.writeAll(&.{
833
+ @intFromEnum(ArgType.Weather),
834
+ @intFromEnum(w),
835
+ @intFromEnum(reason),
836
+ });
837
+ }
838
+
598
839
  pub fn laststill(self: Self) Error!void {
599
840
  if (!enabled) return;
600
841
 
@@ -655,7 +896,7 @@ pub const ByteStream = struct {
655
896
  }
656
897
  };
657
898
 
658
- pub const Kind = enum { Move, Species, Type, Status };
899
+ pub const Kind = enum { Move, Species, Type, Status, Item, Weather };
659
900
 
660
901
  pub fn format(
661
902
  comptime gen: anytype,
@@ -700,6 +941,18 @@ pub fn format(
700
941
  .Resisted => "|-resisted|",
701
942
  .Immune => "|-immune|",
702
943
  .Transform => "|-transform|",
944
+ .Drag => "|drag|",
945
+ .Item => "|-item|",
946
+ .EndItem => "|-enditem|",
947
+ .CureTeam => "|-cureteam|",
948
+ .SetHP => "|-sethp|",
949
+ .SetBoost => "|-setboost|",
950
+ .CopyBoost => "|-copyboost|",
951
+ .SideStart => "|-sidestart|",
952
+ .SideEnd => "|-sideend|",
953
+ .SingleMove => "|-singlemove|",
954
+ .SingleTurn => "|-singleturn|",
955
+ .Weather => "|-weather|",
703
956
  else => unreachable,
704
957
  };
705
958
  printc("{s}", .{name}, a, b, &i, 1, color);
@@ -724,7 +977,7 @@ pub fn format(
724
977
  printc(" {s}", .{formatter(gen, .Move, a[i])}, a, b, &i, 1, color);
725
978
  }
726
979
  },
727
- .Switch => {
980
+ .Switch, .Drag => {
728
981
  const id = ID.from(@intCast(a[i]));
729
982
  printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
730
983
  printc(" {s}", .{formatter(gen, .Species, a[i])}, a, b, &i, 1, color);
@@ -768,6 +1021,7 @@ pub fn format(
768
1021
  .Crit,
769
1022
  .SuperEffective,
770
1023
  .Resisted,
1024
+ .CureTeam,
771
1025
  => {
772
1026
  const id = ID.from(@intCast(a[i]));
773
1027
  printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
@@ -844,12 +1098,12 @@ pub fn format(
844
1098
  printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
845
1099
  printc(" {s}", .{@tagName(@as(Fail, @enumFromInt(a[i])))}, a, b, &i, 1, color);
846
1100
  },
847
- .HitCount => {
1101
+ .HitCount, .SetBoost => {
848
1102
  const id = ID.from(@intCast(a[i]));
849
1103
  printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
850
1104
  printc(" {d}", .{a[i]}, a, b, &i, 1, color);
851
1105
  },
852
- .Prepare => {
1106
+ .Prepare, .SingleMove, .SingleTurn => {
853
1107
  const id = ID.from(@intCast(a[i]));
854
1108
  printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
855
1109
  printc(" {s}", .{formatter(gen, .Move, a[i])}, a, b, &i, 1, color);
@@ -885,12 +1139,64 @@ pub fn format(
885
1139
  printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
886
1140
  printc(" {s}", .{@tagName(@as(Immune, @enumFromInt(a[i])))}, a, b, &i, 1, color);
887
1141
  },
888
- .Transform => {
1142
+ .Transform, .CopyBoost => {
889
1143
  const source = ID.from(@intCast(a[i]));
890
1144
  printc(" {s}({d})", .{ @tagName(source.player), source.id }, a, b, &i, 1, color);
891
1145
  const target = ID.from(@intCast(a[i]));
892
1146
  printc(" {s}({d})", .{ @tagName(target.player), target.id }, a, b, &i, 1, color);
893
1147
  },
1148
+ .Item, .EndItem => {
1149
+ var id = ID.from(@intCast(a[i]));
1150
+ printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
1151
+ printc(" {s}", .{formatter(gen, .Item, a[i])}, a, b, &i, 1, color);
1152
+ if (arg == .Item) {
1153
+ id = ID.from(@intCast(a[i]));
1154
+ printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
1155
+ } else {
1156
+ const reason: EndItem = @enumFromInt(a[i]);
1157
+ printc(" {s}", .{@tagName(reason)}, a, b, &i, 1, color);
1158
+ }
1159
+ },
1160
+ .SetHP => {
1161
+ const id = ID.from(@intCast(a[i]));
1162
+ printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
1163
+ switch (endian) {
1164
+ .Big => {
1165
+ var hp = @as(u16, a[i]) << 8 | @as(u16, a[i + 1]);
1166
+ printc(" {d}", .{hp}, a, b, &i, 2, color);
1167
+ hp = @as(u16, a[i]) << 8 | @as(u16, a[i + 1]);
1168
+ printc("/{d}", .{hp}, a, b, &i, 2, color);
1169
+ },
1170
+ .Little => {
1171
+ var hp = @as(u16, a[i + 1]) << 8 | @as(u16, a[i]);
1172
+ printc(" {d}", .{hp}, a, b, &i, 2, color);
1173
+ hp = @as(u16, a[i + 1]) << 8 | @as(u16, a[i]);
1174
+ printc("/{d}", .{hp}, a, b, &i, 2, color);
1175
+ },
1176
+ }
1177
+ printc(" {s}", .{formatter(gen, .Status, a[i])}, a, b, &i, 1, color);
1178
+ printc(" {s}", .{@tagName(@as(SetHP, @enumFromInt(a[i])))}, a, b, &i, 1, color);
1179
+ },
1180
+ .SideStart => {
1181
+ const id = ID.from(@intCast(a[i]));
1182
+ printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
1183
+ printc(" {s}", .{@tagName(@as(Side, @enumFromInt(a[i])))}, a, b, &i, 1, color);
1184
+ },
1185
+ .SideEnd => {
1186
+ var id = ID.from(@intCast(a[i]));
1187
+ printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
1188
+ const reason: Side = @enumFromInt(a[i]);
1189
+ printc(" {s}", .{@tagName(reason)}, a, b, &i, 1, color);
1190
+ if (reason == .Spikes) {
1191
+ printc(" {s}", .{formatter(gen, .Move, a[i])}, a, b, &i, 1, color);
1192
+ id = ID.from(@intCast(a[i]));
1193
+ printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
1194
+ }
1195
+ },
1196
+ .Weather => {
1197
+ printc(" {s}", .{formatter(gen, .Weather, a[i])}, a, b, &i, 1, color);
1198
+ printc(" {s}", .{@tagName(@as(Weather, @enumFromInt(a[i])))}, a, b, &i, 1, color);
1199
+ },
894
1200
  else => unreachable,
895
1201
  }
896
1202
  print("\n", .{});
@@ -988,11 +1294,16 @@ const gen2 = struct {
988
1294
  };
989
1295
 
990
1296
  var buf: [gen1.LOGS_SIZE]u8 = undefined;
991
- var stream = ByteStream{ .buffer = &buf };
1297
+ var stream: ByteStream = .{ .buffer = &buf };
992
1298
  var log: FixedLog = .{ .writer = stream.writer() };
993
1299
 
994
- const M = gen1.Move;
995
- const S = gen1.Species;
1300
+ const M1 = gen1.Move;
1301
+ const S1 = gen1.Species;
1302
+
1303
+ const M2 = gen2.Move;
1304
+ const S2 = gen2.Species;
1305
+ const I2 = gen2.Item;
1306
+ const W2 = gen2.Weather;
996
1307
 
997
1308
  fn expectLog1(expected: []const u8, actual: []const u8) !void {
998
1309
  return expectLog(gen1, expected, actual, 0);
@@ -1008,32 +1319,39 @@ fn formatter(comptime gen: anytype, kind: Kind, byte: u8) []const u8 {
1008
1319
  .Species => @tagName(@as(gen.Species, @enumFromInt(byte))),
1009
1320
  .Type => @tagName(@as(gen.Type, @enumFromInt(byte))),
1010
1321
  .Status => gen.Status.name(byte),
1322
+ .Item => if (@hasDecl(gen, "Item"))
1323
+ @tagName(@as(gen.Item, @enumFromInt(byte)))
1324
+ else
1325
+ unreachable,
1326
+ .Weather => if (@hasDecl(gen, "Weather"))
1327
+ @tagName(@as(gen.Weather, @enumFromInt(byte)))
1328
+ else
1329
+ unreachable,
1011
1330
  };
1012
1331
  }
1013
1332
 
1014
1333
  test "|move|" {
1015
- try log.move(p2.ident(4), M.Thunderbolt, p1.ident(5), null);
1334
+ try log.move(p2.ident(4), M1.Thunderbolt, p1.ident(5));
1016
1335
  try expectLog1(
1017
- &.{ N(ArgType.Move), 0b1100, N(M.Thunderbolt), 0b0101, N(Move.None) },
1336
+ &.{ N(ArgType.Move), 0b1100, N(M1.Thunderbolt), 0b0101, N(Move.None) },
1018
1337
  buf[0..5],
1019
1338
  );
1020
1339
  stream.reset();
1021
1340
 
1022
- try log.move(p2.ident(4), M.Wrap, p1.ident(5), M.Wrap);
1023
- const wrap = N(M.Wrap);
1341
+ try log.moveFrom(p2.ident(4), M1.Pound, p1.ident(5), M1.Metronome);
1024
1342
  try expectLog1(
1025
- &.{ N(ArgType.Move), 0b1100, wrap, 0b0101, N(Move.From), wrap },
1343
+ &.{ N(ArgType.Move), 0b1100, N(M1.Pound), 0b0101, N(Move.From), N(M1.Metronome) },
1026
1344
  buf[0..6],
1027
1345
  );
1028
1346
  stream.reset();
1029
1347
 
1030
- try log.move(p2.ident(4), M.SkullBash, .{}, null);
1348
+ try log.move(p2.ident(4), M1.SkullBash, .{});
1031
1349
  try log.laststill();
1032
1350
  try expectLog1(
1033
1351
  &.{
1034
1352
  N(ArgType.Move),
1035
1353
  0b1100,
1036
- N(M.SkullBash),
1354
+ N(M1.SkullBash),
1037
1355
  0,
1038
1356
  N(Move.None),
1039
1357
  N(ArgType.LastStill),
@@ -1042,13 +1360,13 @@ test "|move|" {
1042
1360
  );
1043
1361
  stream.reset();
1044
1362
 
1045
- try log.move(p2.ident(4), M.Tackle, p1.ident(5), null);
1363
+ try log.move(p2.ident(4), M1.Tackle, p1.ident(5));
1046
1364
  try log.lastmiss();
1047
1365
  try expectLog1(
1048
1366
  &.{
1049
1367
  N(ArgType.Move),
1050
1368
  0b1100,
1051
- N(M.Tackle),
1369
+ N(M1.Tackle),
1052
1370
  0b0101,
1053
1371
  N(Move.None),
1054
1372
  N(ArgType.LastMiss),
@@ -1067,8 +1385,8 @@ test "|switch|" {
1067
1385
  try log.switched(p2.ident(3), &snorlax);
1068
1386
  const par = 0b1000000;
1069
1387
  var expected: []const u8 = switch (endian) {
1070
- .Big => &.{ N(ArgType.Switch), 0b1011, N(S.Snorlax), 91, 0, 200, 1, 144, par },
1071
- .Little => &.{ N(ArgType.Switch), 0b1011, N(S.Snorlax), 91, 200, 0, 144, 1, par },
1388
+ .Big => &.{ N(ArgType.Switch), 0b1011, N(S1.Snorlax), 91, 0, 200, 1, 144, par },
1389
+ .Little => &.{ N(ArgType.Switch), 0b1011, N(S1.Snorlax), 91, 200, 0, 144, 1, par },
1072
1390
  };
1073
1391
  try expectLog1(expected, buf[0..9]);
1074
1392
  stream.reset();
@@ -1078,8 +1396,8 @@ test "|switch|" {
1078
1396
  snorlax.status = 0;
1079
1397
  try log.switched(p2.ident(3), &snorlax);
1080
1398
  expected = switch (endian) {
1081
- .Big => &.{ N(ArgType.Switch), 0b1011, N(S.Snorlax), 100, 0, 0, 1, 144, 0 },
1082
- .Little => &.{ N(ArgType.Switch), 0b1011, N(S.Snorlax), 100, 0, 0, 144, 1, 0 },
1399
+ .Big => &.{ N(ArgType.Switch), 0b1011, N(S1.Snorlax), 100, 0, 0, 1, 144, 0 },
1400
+ .Little => &.{ N(ArgType.Switch), 0b1011, N(S1.Snorlax), 100, 0, 0, 144, 1, 0 },
1083
1401
  };
1084
1402
  try expectLog1(expected, buf[0..9]);
1085
1403
  stream.reset();
@@ -1087,8 +1405,8 @@ test "|switch|" {
1087
1405
  snorlax.hp = 400;
1088
1406
  try log.switched(p2.ident(3), &snorlax);
1089
1407
  expected = switch (endian) {
1090
- .Big => &.{ N(ArgType.Switch), 0b1011, N(S.Snorlax), 100, 1, 144, 1, 144, 0 },
1091
- .Little => &.{ N(ArgType.Switch), 0b1011, N(S.Snorlax), 100, 144, 1, 144, 1, 0 },
1408
+ .Big => &.{ N(ArgType.Switch), 0b1011, N(S1.Snorlax), 100, 1, 144, 1, 144, 0 },
1409
+ .Little => &.{ N(ArgType.Switch), 0b1011, N(S1.Snorlax), 100, 144, 1, 144, 1, 0 },
1092
1410
  };
1093
1411
  try expectLog1(expected, buf[0..9]);
1094
1412
  stream.reset();
@@ -1102,7 +1420,7 @@ test "|switch|" {
1102
1420
  expected = &(.{
1103
1421
  N(ArgType.Switch),
1104
1422
  0b1011,
1105
- N(gen2.Species.Blissey),
1423
+ N(S2.Blissey),
1106
1424
  N(gen2.Gender.Female),
1107
1425
  91,
1108
1426
  } ++ switch (endian) {
@@ -1118,8 +1436,8 @@ test "|cant|" {
1118
1436
  try expectLog1(&.{ N(ArgType.Cant), 0b1110, N(Cant.Bound) }, buf[0..3]);
1119
1437
  stream.reset();
1120
1438
 
1121
- try log.disabled(p1.ident(2), M.Earthquake);
1122
- try expectLog1(&.{ N(ArgType.Cant), 2, N(Cant.Disable), N(M.Earthquake) }, buf[0..4]);
1439
+ try log.disabled(p1.ident(2), M1.Earthquake);
1440
+ try expectLog1(&.{ N(ArgType.Cant), 2, N(Cant.Disable), N(M1.Earthquake) }, buf[0..4]);
1123
1441
  stream.reset();
1124
1442
  }
1125
1443
 
@@ -1229,9 +1547,9 @@ test "|-status|" {
1229
1547
  try expectLog1(&.{ N(ArgType.Status), 0b1010, 0b1000, N(Status.Silent) }, buf[0..4]);
1230
1548
  stream.reset();
1231
1549
 
1232
- try log.statusFrom(p1.ident(1), gen1.Status.init(.PAR), M.BodySlam);
1550
+ try log.statusFrom(p1.ident(1), gen1.Status.init(.PAR), M1.BodySlam);
1233
1551
  try expectLog1(
1234
- &.{ N(ArgType.Status), 0b0001, 0b1000000, N(Status.From), N(M.BodySlam) },
1552
+ &.{ N(ArgType.Status), 0b0001, 0b1000000, N(Status.From), N(M1.BodySlam) },
1235
1553
  buf[0..5],
1236
1554
  );
1237
1555
  stream.reset();
@@ -1302,8 +1620,8 @@ test "|-hitcount|" {
1302
1620
  }
1303
1621
 
1304
1622
  test "|-prepare|" {
1305
- try log.prepare(p2.ident(2), M.Dig);
1306
- try expectLog1(&.{ N(ArgType.Prepare), 0b1010, N(M.Dig) }, buf[0..3]);
1623
+ try log.prepare(p2.ident(2), M1.Dig);
1624
+ try expectLog1(&.{ N(ArgType.Prepare), 0b1010, N(M1.Dig) }, buf[0..3]);
1307
1625
  stream.reset();
1308
1626
  }
1309
1627
 
@@ -1329,6 +1647,12 @@ test "|-activate|" {
1329
1647
  try log.activate(p1.ident(2), .Splash);
1330
1648
  try expectLog1(&.{ N(ArgType.Activate), 0b0010, N(Activate.Splash) }, buf[0..3]);
1331
1649
  stream.reset();
1650
+
1651
+ // TODO activateMove
1652
+
1653
+ try log.magnitude(p1.ident(3), 5);
1654
+ try expectLog1(&.{ N(ArgType.Activate), 0b0011, N(Activate.Magnitude), 5 }, buf[0..4]);
1655
+ stream.reset();
1332
1656
  }
1333
1657
 
1334
1658
  test "|-fieldactivate|" {
@@ -1360,12 +1684,12 @@ test "|-start|" {
1360
1684
  );
1361
1685
  stream.reset();
1362
1686
 
1363
- try log.startEffect(p1.ident(2), .Disable, M.Surf);
1364
- try expectLog1(&.{ N(ArgType.Start), 0b0010, N(Start.Disable), N(M.Surf) }, buf[0..4]);
1687
+ try log.startEffect(p1.ident(2), .Disable, M1.Surf);
1688
+ try expectLog1(&.{ N(ArgType.Start), 0b0010, N(Start.Disable), N(M1.Surf) }, buf[0..4]);
1365
1689
  stream.reset();
1366
1690
 
1367
- try log.startEffect(p1.ident(2), .Mimic, M.Surf);
1368
- try expectLog1(&.{ N(ArgType.Start), 0b0010, N(Start.Mimic), N(M.Surf) }, buf[0..4]);
1691
+ try log.startEffect(p1.ident(2), .Mimic, M1.Surf);
1692
+ try expectLog1(&.{ N(ArgType.Start), 0b0010, N(Start.Mimic), N(M1.Surf) }, buf[0..4]);
1369
1693
  stream.reset();
1370
1694
  }
1371
1695
 
@@ -1384,21 +1708,25 @@ test "|-ohko|" {
1384
1708
  try expectLog1(&.{N(ArgType.OHKO)}, buf[0..1]);
1385
1709
  stream.reset();
1386
1710
  }
1711
+
1387
1712
  test "|-crit|" {
1388
1713
  try log.crit(p2.ident(5));
1389
1714
  try expectLog1(&.{ N(ArgType.Crit), 0b1101 }, buf[0..2]);
1390
1715
  stream.reset();
1391
1716
  }
1717
+
1392
1718
  test "|-supereffective|" {
1393
1719
  try log.supereffective(p1.ident(1));
1394
1720
  try expectLog1(&.{ N(ArgType.SuperEffective), 0b0001 }, buf[0..2]);
1395
1721
  stream.reset();
1396
1722
  }
1723
+
1397
1724
  test "|-resisted|" {
1398
1725
  try log.resisted(p2.ident(2));
1399
1726
  try expectLog1(&.{ N(ArgType.Resisted), 0b1010 }, buf[0..2]);
1400
1727
  stream.reset();
1401
1728
  }
1729
+
1402
1730
  test "|-immune|" {
1403
1731
  try log.immune(p1.ident(3), .None);
1404
1732
  try expectLog1(&.{ N(ArgType.Immune), 0b0011, N(Immune.None) }, buf[0..3]);
@@ -1408,8 +1736,124 @@ test "|-immune|" {
1408
1736
  try expectLog1(&.{ N(ArgType.Immune), 0b1010, N(Immune.OHKO) }, buf[0..3]);
1409
1737
  stream.reset();
1410
1738
  }
1739
+
1411
1740
  test "|-transform|" {
1412
1741
  try log.transform(p2.ident(4), p1.ident(5));
1413
1742
  try expectLog1(&.{ N(ArgType.Transform), 0b1100, 0b0101 }, buf[0..3]);
1414
1743
  stream.reset();
1415
1744
  }
1745
+
1746
+ test "|drag|" {
1747
+ var blissey = gen2.helpers.Pokemon.init(.{ .species = .Blissey, .moves = &.{.Splash} });
1748
+ blissey.level = 91;
1749
+ blissey.hp = 200;
1750
+ blissey.stats.hp = 400;
1751
+ blissey.status = gen2.Status.init(.PAR);
1752
+ try log.drag(p2.ident(3), &blissey);
1753
+ const par = 0b1000000;
1754
+ const expected = &(.{
1755
+ N(ArgType.Drag),
1756
+ 0b1011,
1757
+ N(S2.Blissey),
1758
+ N(gen2.Gender.Female),
1759
+ 91,
1760
+ } ++ switch (endian) {
1761
+ .Big => .{ 0, 200, 1, 144, par },
1762
+ .Little => .{ 200, 0, 144, 1, par },
1763
+ });
1764
+ try expectLog2(expected, buf[0..10]);
1765
+ stream.reset();
1766
+ }
1767
+
1768
+ test "|-item|" {
1769
+ try log.item(p2.ident(2), I2.GoldBerry, p1.ident(4));
1770
+ try expectLog2(&.{ N(ArgType.Item), 0b1010, N(I2.GoldBerry), 0b0100 }, buf[0..4]);
1771
+ stream.reset();
1772
+ }
1773
+
1774
+ test "|-enditem|" {
1775
+ try log.enditem(p1.ident(1), I2.BerserkGene, .None);
1776
+ try expectLog2(&.{ N(ArgType.EndItem), 0b0001, N(I2.BerserkGene), N(EndItem.None) }, buf[0..4]);
1777
+ stream.reset();
1778
+
1779
+ try log.enditem(p2.ident(4), I2.PRZCureBerry, .Eat);
1780
+ try expectLog2(&.{ N(ArgType.EndItem), 0b1100, N(I2.PRZCureBerry), N(EndItem.Eat) }, buf[0..4]);
1781
+ stream.reset();
1782
+ }
1783
+
1784
+ test "|-cureteam|" {
1785
+ try log.cureteam(p2.ident(5));
1786
+ try expectLog2(&.{ N(ArgType.CureTeam), 0b1101 }, buf[0..2]);
1787
+ stream.reset();
1788
+ }
1789
+
1790
+ test "|-sethp|" {
1791
+ var blissey = gen2.helpers.Pokemon.init(.{ .species = .Blissey, .moves = &.{.PainSplit} });
1792
+ blissey.hp = 612;
1793
+ try log.sethp(p2.ident(2), &blissey, .Silent);
1794
+ var expected: []const u8 = switch (endian) {
1795
+ .Big => &.{ N(ArgType.SetHP), 0b1010, 2, 100, 2, 201, 0, N(SetHP.Silent) },
1796
+ .Little => &.{ N(ArgType.SetHP), 0b1010, 100, 2, 201, 2, 0, N(SetHP.Silent) },
1797
+ };
1798
+ try expectLog2(expected, buf[0..8]);
1799
+ stream.reset();
1800
+ }
1801
+
1802
+ test "|-setboost|" {
1803
+ try log.setboost(p2.ident(6), 6);
1804
+ try expectLog2(&.{ N(ArgType.SetBoost), 0b1110, 12 }, buf[0..3]);
1805
+ stream.reset();
1806
+
1807
+ try log.setboost(p2.ident(3), 2);
1808
+ try expectLog2(&.{ N(ArgType.SetBoost), 0b1011, 8 }, buf[0..3]);
1809
+ stream.reset();
1810
+ }
1811
+
1812
+ test "|-copyboost|" {
1813
+ try log.copyboost(p2.ident(3), p1.ident(6));
1814
+ try expectLog2(&.{ N(ArgType.CopyBoost), 0b1011, 0b0110 }, buf[0..3]);
1815
+ stream.reset();
1816
+ }
1817
+
1818
+ test "|-sidestart|" {
1819
+ try log.sidestart(.P2, .Reflect);
1820
+ try expectLog2(&.{ N(ArgType.SideStart), 1, N(Side.Reflect) }, buf[0..3]);
1821
+ stream.reset();
1822
+ }
1823
+
1824
+ test "|-sideend|" {
1825
+ try log.sideend(.P2, .LightScreen);
1826
+ try expectLog2(&.{ N(ArgType.SideEnd), 1, N(Side.LightScreen) }, buf[0..3]);
1827
+ stream.reset();
1828
+
1829
+ try log.spikesend(p1.ident(3));
1830
+ try expectLog2(&.{
1831
+ N(ArgType.SideEnd),
1832
+ 0,
1833
+ N(Side.Spikes),
1834
+ 0b0011,
1835
+ }, buf[0..4]);
1836
+ stream.reset();
1837
+ }
1838
+
1839
+ test "|-singlemove|" {
1840
+ try log.singlemove(p2.ident(2), M2.DestinyBond);
1841
+ try expectLog2(&.{ N(ArgType.SingleMove), 0b1010, N(M2.DestinyBond) }, buf[0..3]);
1842
+ stream.reset();
1843
+ }
1844
+
1845
+ test "|-singleturn|" {
1846
+ try log.singleturn(p1.ident(3), M2.Protect);
1847
+ try expectLog2(&.{ N(ArgType.SingleTurn), 0b0011, N(M2.Protect) }, buf[0..3]);
1848
+ stream.reset();
1849
+ }
1850
+
1851
+ test "|-weather|" {
1852
+ try log.weather(W2.Rain, .Upkeep);
1853
+ try expectLog2(&.{ N(ArgType.Weather), N(W2.Rain), N(Weather.Upkeep) }, buf[0..3]);
1854
+ stream.reset();
1855
+
1856
+ try log.weather(W2.None, .None);
1857
+ try expectLog2(&.{ N(ArgType.Weather), N(W2.None), N(Weather.None) }, buf[0..3]);
1858
+ stream.reset();
1859
+ }