@pkmn/engine 0.1.0-dev.47feedd9 → 0.1.0-dev.49f6bf26
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.
- package/LICENSE +1 -3
- package/README.md +87 -53
- package/build/pkg/addon.js +3 -2
- package/build/pkg/addon.js.map +1 -1
- package/build/pkg/data/ids.json +12 -12
- package/build/pkg/data/layout.json +27 -5
- package/build/pkg/data/protocol.json +69 -12
- package/build/pkg/data.d.ts +3 -2
- package/build/pkg/data.js.map +1 -1
- package/build/pkg/gen1.d.ts +2 -1
- package/build/pkg/gen1.js +38 -20
- package/build/pkg/gen1.js.map +1 -1
- package/build/pkg/index.d.ts +6 -3
- package/build/pkg/index.js.map +1 -1
- package/build/pkg/protocol.d.ts +4 -2
- package/build/pkg/protocol.js +61 -40
- package/build/pkg/protocol.js.map +1 -1
- package/build/test/display.js +7 -3
- package/build/test/display.js.map +1 -1
- package/build/tools/debug.js +3 -1
- package/build/tools/debug.js.map +1 -1
- package/build.zig +151 -111
- package/package.json +53 -23
- package/src/bin/install-pkmn-engine +23 -18
- package/src/lib/common/battle.zig +17 -0
- package/src/lib/common/data.zig +19 -31
- package/src/lib/common/debug.zig +20 -11
- package/src/lib/common/js.zig +118 -0
- package/src/lib/common/optional.zig +67 -0
- package/src/lib/common/options.zig +9 -0
- package/src/lib/common/protocol.zig +896 -359
- package/src/lib/common/rational.zig +357 -0
- package/src/lib/common/rng.zig +29 -20
- package/src/lib/common/util.zig +12 -0
- package/src/lib/gen1/README.md +277 -180
- package/src/lib/gen1/calc.zig +426 -0
- package/src/lib/gen1/chance.zig +1060 -0
- package/src/lib/gen1/data/moves.zig +202 -190
- package/src/lib/gen1/data/species.zig +4 -4
- package/src/lib/gen1/data/types.zig +10 -10
- package/src/lib/gen1/data.zig +101 -87
- package/src/lib/gen1/helpers.zig +577 -35
- package/src/lib/gen1/mechanics.zig +975 -710
- package/src/lib/gen2/README.md +105 -85
- package/src/lib/gen2/calc.zig +143 -0
- package/src/lib/gen2/chance.zig +1314 -0
- package/src/lib/gen2/data/items.zig +14 -20
- package/src/lib/gen2/data/moves.zig +664 -570
- package/src/lib/gen2/data/species.zig +2 -2
- package/src/lib/gen2/data/types.zig +137 -34
- package/src/lib/gen2/data.zig +130 -92
- package/src/lib/gen2/generated.zig +806 -0
- package/src/lib/gen2/helpers.zig +16 -22
- package/src/lib/gen2/mechanics.zig +3506 -12
- package/src/lib/node.zig +131 -0
- package/src/lib/pkmn.zig +84 -2
- package/src/lib/wasm.zig +13 -0
- package/src/lib/binding/node.zig +0 -229
- package/src/lib/binding/wasm.zig +0 -10
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
const std = @import("std");
|
|
2
2
|
const builtin = @import("builtin");
|
|
3
3
|
|
|
4
|
-
const
|
|
5
|
-
|
|
4
|
+
const pkmn = @import("../pkmn.zig");
|
|
5
|
+
|
|
6
|
+
const data = @import("data.zig");
|
|
7
|
+
const options = @import("options.zig");
|
|
6
8
|
|
|
7
9
|
const assert = std.debug.assert;
|
|
8
10
|
const print = std.debug.print;
|
|
@@ -12,6 +14,8 @@ const enabled = options.log;
|
|
|
12
14
|
const Player = data.Player;
|
|
13
15
|
const ID = data.ID;
|
|
14
16
|
|
|
17
|
+
const endian = builtin.cpu.arch.endian();
|
|
18
|
+
|
|
15
19
|
pub const ArgType = enum(u8) {
|
|
16
20
|
None,
|
|
17
21
|
|
|
@@ -69,7 +73,7 @@ pub const ArgType = enum(u8) {
|
|
|
69
73
|
EndAbility,
|
|
70
74
|
ClearNegativeBoost,
|
|
71
75
|
FormeChange,
|
|
72
|
-
|
|
76
|
+
LastNoTarget, // FIXME
|
|
73
77
|
|
|
74
78
|
// Gen 4
|
|
75
79
|
SwapBoost,
|
|
@@ -102,6 +106,10 @@ pub const ArgType = enum(u8) {
|
|
|
102
106
|
// Gen 8
|
|
103
107
|
CanDynamax,
|
|
104
108
|
SwapSideConditions,
|
|
109
|
+
UpdatePoke,
|
|
110
|
+
|
|
111
|
+
// Gen 9
|
|
112
|
+
Terastallize,
|
|
105
113
|
};
|
|
106
114
|
|
|
107
115
|
pub const Move = enum(u8) {
|
|
@@ -118,12 +126,19 @@ pub const Cant = enum(u8) {
|
|
|
118
126
|
Disable,
|
|
119
127
|
Recharge,
|
|
120
128
|
PP,
|
|
129
|
+
|
|
130
|
+
Attract,
|
|
121
131
|
};
|
|
122
132
|
|
|
123
133
|
pub const Heal = enum(u8) {
|
|
124
134
|
None,
|
|
125
135
|
Silent,
|
|
126
136
|
Drain,
|
|
137
|
+
|
|
138
|
+
Leftovers,
|
|
139
|
+
Berry,
|
|
140
|
+
BerryJuice,
|
|
141
|
+
GoldBerry,
|
|
127
142
|
};
|
|
128
143
|
|
|
129
144
|
pub const Damage = enum(u8) {
|
|
@@ -133,6 +148,17 @@ pub const Damage = enum(u8) {
|
|
|
133
148
|
Confusion,
|
|
134
149
|
LeechSeed,
|
|
135
150
|
RecoilOf,
|
|
151
|
+
|
|
152
|
+
Bind,
|
|
153
|
+
Wrap,
|
|
154
|
+
FireSpin,
|
|
155
|
+
Clamp,
|
|
156
|
+
Whirlpool,
|
|
157
|
+
Spikes,
|
|
158
|
+
|
|
159
|
+
Nightmare,
|
|
160
|
+
Curse,
|
|
161
|
+
Sandstorm,
|
|
136
162
|
};
|
|
137
163
|
|
|
138
164
|
pub const Status = enum(u8) {
|
|
@@ -175,8 +201,25 @@ pub const Activate = enum(u8) {
|
|
|
175
201
|
Haze,
|
|
176
202
|
Mist,
|
|
177
203
|
Struggle,
|
|
178
|
-
Substitute,
|
|
204
|
+
Substitute, // FIXME SubstituteDamage
|
|
179
205
|
Splash,
|
|
206
|
+
|
|
207
|
+
Rage, // TODO
|
|
208
|
+
|
|
209
|
+
Attract,
|
|
210
|
+
LockOn,
|
|
211
|
+
Bind,
|
|
212
|
+
Wrap,
|
|
213
|
+
FireSpin,
|
|
214
|
+
Clamp,
|
|
215
|
+
Whirlpool,
|
|
216
|
+
SubstituteBlock,
|
|
217
|
+
|
|
218
|
+
DestinyBond,
|
|
219
|
+
|
|
220
|
+
BeatUp, // FIXME of
|
|
221
|
+
|
|
222
|
+
Magnitude,
|
|
180
223
|
};
|
|
181
224
|
|
|
182
225
|
pub const Start = enum(u8) {
|
|
@@ -194,6 +237,19 @@ pub const Start = enum(u8) {
|
|
|
194
237
|
|
|
195
238
|
Disable,
|
|
196
239
|
Mimic,
|
|
240
|
+
|
|
241
|
+
Attract,
|
|
242
|
+
Nightmare,
|
|
243
|
+
Curse,
|
|
244
|
+
Foresight,
|
|
245
|
+
Encore,
|
|
246
|
+
FutureSight,
|
|
247
|
+
|
|
248
|
+
PerishSong0,
|
|
249
|
+
PerishSong1,
|
|
250
|
+
PerishSong2,
|
|
251
|
+
PerishSong3,
|
|
252
|
+
PerishSong3Silent,
|
|
197
253
|
};
|
|
198
254
|
|
|
199
255
|
pub const End = enum(u8) {
|
|
@@ -202,16 +258,30 @@ pub const End = enum(u8) {
|
|
|
202
258
|
Bide,
|
|
203
259
|
Substitute,
|
|
204
260
|
|
|
205
|
-
|
|
261
|
+
Nightmare,
|
|
262
|
+
Curse,
|
|
263
|
+
Foresight,
|
|
264
|
+
Encore,
|
|
265
|
+
FutureSight,
|
|
266
|
+
LeechSeed,
|
|
267
|
+
|
|
268
|
+
Bind,
|
|
269
|
+
Wrap,
|
|
270
|
+
FireSpin,
|
|
271
|
+
Clamp,
|
|
272
|
+
Whirlpool,
|
|
273
|
+
|
|
206
274
|
DisableSilent,
|
|
207
275
|
ConfusionSilent,
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
276
|
+
MistSilent,
|
|
277
|
+
FocusEnergySilent,
|
|
278
|
+
LeechSeedSilent,
|
|
279
|
+
ToxicSilent,
|
|
280
|
+
LightScreenSilent,
|
|
281
|
+
ReflectSilent,
|
|
282
|
+
BideSilent,
|
|
283
|
+
|
|
284
|
+
LeechSeedFrom,
|
|
215
285
|
};
|
|
216
286
|
|
|
217
287
|
pub const Immune = enum(u8) {
|
|
@@ -219,8 +289,34 @@ pub const Immune = enum(u8) {
|
|
|
219
289
|
OHKO,
|
|
220
290
|
};
|
|
221
291
|
|
|
292
|
+
pub const EndItem = enum(u8) {
|
|
293
|
+
None,
|
|
294
|
+
Eat,
|
|
295
|
+
};
|
|
296
|
+
|
|
297
|
+
pub const SetHP = enum(u8) {
|
|
298
|
+
None,
|
|
299
|
+
Silent,
|
|
300
|
+
};
|
|
301
|
+
|
|
302
|
+
pub const Side = enum(u8) {
|
|
303
|
+
Safeguard,
|
|
304
|
+
Reflect,
|
|
305
|
+
LightScreen,
|
|
306
|
+
Spikes,
|
|
307
|
+
};
|
|
308
|
+
|
|
309
|
+
pub const Weather = enum(u8) {
|
|
310
|
+
None,
|
|
311
|
+
Upkeep,
|
|
312
|
+
};
|
|
313
|
+
|
|
314
|
+
/// Null object pattern implementation of `Log` backed by a `std.io.null_writer`.
|
|
315
|
+
/// Ignores anything sent to it, though protocol logging should additionally be turned off
|
|
316
|
+
/// entirely with `options.log`.
|
|
222
317
|
pub const NULL = Log(@TypeOf(std.io.null_writer)){ .writer = std.io.null_writer };
|
|
223
318
|
|
|
319
|
+
/// Logs protocol information to its `Writer` during a battle update when `options.log` is enabled.
|
|
224
320
|
pub fn Log(comptime Writer: type) type {
|
|
225
321
|
return struct {
|
|
226
322
|
const Self = @This();
|
|
@@ -229,322 +325,497 @@ pub fn Log(comptime Writer: type) type {
|
|
|
229
325
|
|
|
230
326
|
pub const Error = Writer.Error;
|
|
231
327
|
|
|
232
|
-
|
|
328
|
+
// source: ID, move: <Move>, target: ID, from?: <Move>
|
|
329
|
+
pub fn move(self: Self, args: anytype) Error!void {
|
|
233
330
|
if (!enabled) return;
|
|
234
|
-
|
|
331
|
+
|
|
332
|
+
assert(args[1] != .None);
|
|
235
333
|
try self.writer.writeAll(&.{
|
|
236
|
-
@
|
|
237
|
-
@
|
|
238
|
-
@
|
|
239
|
-
@
|
|
334
|
+
@intFromEnum(ArgType.Move),
|
|
335
|
+
@as(u8, @bitCast(args[0])),
|
|
336
|
+
@intFromEnum(args[1]),
|
|
337
|
+
@as(u8, @bitCast(args[2])),
|
|
240
338
|
});
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
.
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
339
|
+
try self.writer.writeAll(if (args.len < 4 or @intFromEnum(args[3]) == 0)
|
|
340
|
+
&.{@intFromEnum(Move.None)}
|
|
341
|
+
else
|
|
342
|
+
&.{ @intFromEnum(Move.From), @intFromEnum(args[3]) });
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
// ident: ID, pokemon: <Pokemon>
|
|
346
|
+
pub fn switched(self: Self, args: anytype) Error!void {
|
|
347
|
+
return switchDrag(self, .Switch, args);
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
// ident: ID, pokemon: <Pokemon>
|
|
351
|
+
fn switchDrag(self: Self, arg: ArgType, args: anytype) Error!void {
|
|
352
|
+
if (!enabled) return;
|
|
353
|
+
|
|
354
|
+
try self.writer.writeAll(&.{ @intFromEnum(arg), @as(u8, @bitCast(args[0])) });
|
|
355
|
+
if (@hasField(@TypeOf(args[1].*), "dvs")) {
|
|
356
|
+
try self.writer.writeAll(&.{
|
|
357
|
+
@intFromEnum(args[1].species),
|
|
358
|
+
@intFromEnum(args[1].dvs.gender),
|
|
359
|
+
args[1].level,
|
|
360
|
+
});
|
|
361
|
+
} else {
|
|
362
|
+
try self.writer.writeAll(&.{ @intFromEnum(args[1].species), args[1].level });
|
|
363
|
+
}
|
|
364
|
+
try self.writer.writeInt(u16, args[1].hp, endian);
|
|
365
|
+
try self.writer.writeInt(u16, args[1].stats.hp, endian);
|
|
366
|
+
try self.writer.writeAll(&.{args[1].status});
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
// ident: ID, reason: Cant
|
|
370
|
+
// ident: ID, reason: .Disable, move: <Move>
|
|
371
|
+
pub fn cant(self: Self, args: anytype) Error!void {
|
|
372
|
+
if (!enabled) return;
|
|
373
|
+
|
|
374
|
+
assert(args[1] != .Disable or args.len == 3);
|
|
375
|
+
try self.writer.writeAll(&.{
|
|
376
|
+
@intFromEnum(ArgType.Cant),
|
|
377
|
+
@as(u8, @bitCast(args[0])),
|
|
378
|
+
@intFromEnum(@as(Cant, args[1])),
|
|
252
379
|
});
|
|
380
|
+
if (args.len == 3) try self.writer.writeByte(@intFromEnum(args[2]));
|
|
253
381
|
}
|
|
254
382
|
|
|
255
|
-
|
|
383
|
+
// ident: ID, done: bool
|
|
384
|
+
pub fn faint(self: Self, args: anytype) Error!void {
|
|
256
385
|
if (!enabled) return;
|
|
257
|
-
|
|
258
|
-
try self.writer.writeAll(&.{ @
|
|
259
|
-
try self.writer.
|
|
260
|
-
try self.writer.writeIntNative(u16, pokemon.stats.hp);
|
|
261
|
-
try self.writer.writeAll(&.{pokemon.status});
|
|
386
|
+
|
|
387
|
+
try self.writer.writeAll(&.{ @intFromEnum(ArgType.Faint), @as(u8, @bitCast(args[0])) });
|
|
388
|
+
if (args[1]) try self.writer.writeByte(@intFromEnum(ArgType.None));
|
|
262
389
|
}
|
|
263
390
|
|
|
264
|
-
|
|
391
|
+
// num: u16
|
|
392
|
+
pub fn turn(self: Self, args: anytype) Error!void {
|
|
265
393
|
if (!enabled) return;
|
|
266
|
-
|
|
394
|
+
|
|
395
|
+
try self.writer.writeByte(@intFromEnum(ArgType.Turn));
|
|
396
|
+
try self.writer.writeInt(u16, args[0], endian);
|
|
397
|
+
try self.writer.writeByte(@intFromEnum(ArgType.None));
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
// player: Player
|
|
401
|
+
pub fn win(self: Self, args: anytype) Error!void {
|
|
402
|
+
if (!enabled) return;
|
|
403
|
+
|
|
267
404
|
try self.writer.writeAll(&.{
|
|
268
|
-
@
|
|
269
|
-
@
|
|
270
|
-
@
|
|
405
|
+
@intFromEnum(ArgType.Win),
|
|
406
|
+
@intFromEnum(@as(Player, args[0])),
|
|
407
|
+
@intFromEnum(ArgType.None),
|
|
271
408
|
});
|
|
272
409
|
}
|
|
273
410
|
|
|
274
|
-
|
|
411
|
+
// -
|
|
412
|
+
pub fn tie(self: Self, _: anytype) Error!void {
|
|
413
|
+
if (!enabled) return;
|
|
414
|
+
|
|
415
|
+
try self.writer.writeAll(&.{ @intFromEnum(ArgType.Tie), @intFromEnum(ArgType.None) });
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
// ident: ID, pokemon: <Pokemon>, reason: Damage
|
|
419
|
+
// ident: ID, pokemon: <Pokemon>, reason: .RecoilOf, source: ID
|
|
420
|
+
pub fn damage(self: Self, args: anytype) Error!void {
|
|
275
421
|
if (!enabled) return;
|
|
422
|
+
|
|
423
|
+
assert(args[2] != .RecoilOf or args.len == 4);
|
|
276
424
|
try self.writer.writeAll(&.{
|
|
277
|
-
@
|
|
278
|
-
@
|
|
279
|
-
@enumToInt(Cant.Disable),
|
|
280
|
-
@enumToInt(m),
|
|
425
|
+
@intFromEnum(ArgType.Damage),
|
|
426
|
+
@as(u8, @bitCast(args[0])),
|
|
281
427
|
});
|
|
428
|
+
try self.writer.writeInt(u16, args[1].hp, endian);
|
|
429
|
+
try self.writer.writeInt(u16, args[1].stats.hp, endian);
|
|
430
|
+
try self.writer.writeAll(&.{ args[1].status, @intFromEnum(@as(Damage, args[2])) });
|
|
431
|
+
if (args.len == 4) try self.writer.writeByte(@as(u8, @bitCast(args[3])));
|
|
282
432
|
}
|
|
283
433
|
|
|
284
|
-
|
|
434
|
+
// ident: ID, pokemon: <Pokemon>, reason: Heal
|
|
435
|
+
// ident: ID, pokemon: <Pokemon>, reason: .Drain, target: ID
|
|
436
|
+
pub fn heal(self: Self, args: anytype) Error!void {
|
|
285
437
|
if (!enabled) return;
|
|
286
|
-
|
|
287
|
-
|
|
438
|
+
|
|
439
|
+
assert(args[2] != .Drain or args.len == 4);
|
|
440
|
+
try self.writer.writeAll(&.{ @intFromEnum(ArgType.Heal), @as(u8, @bitCast(args[0])) });
|
|
441
|
+
try self.writer.writeInt(u16, args[1].hp, endian);
|
|
442
|
+
try self.writer.writeInt(u16, args[1].stats.hp, endian);
|
|
443
|
+
try self.writer.writeAll(&.{ args[1].status, @intFromEnum(@as(Heal, args[2])) });
|
|
444
|
+
if (args.len == 4) try self.writer.writeByte(@as(u8, @bitCast(args[3])));
|
|
288
445
|
}
|
|
289
446
|
|
|
290
|
-
|
|
447
|
+
// ident: ID, value: u8, reason: Status
|
|
448
|
+
// ident: ID, value: u8, reason: .From, m: <Move>
|
|
449
|
+
pub fn status(self: Self, args: anytype) Error!void {
|
|
291
450
|
if (!enabled) return;
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
try self.writer.
|
|
451
|
+
|
|
452
|
+
assert(args[2] != .From or args.len == 4);
|
|
453
|
+
try self.writer.writeAll(&.{
|
|
454
|
+
@intFromEnum(ArgType.Status),
|
|
455
|
+
@as(u8, @bitCast(args[0])),
|
|
456
|
+
args[1],
|
|
457
|
+
@intFromEnum(@as(Status, args[2])),
|
|
458
|
+
});
|
|
459
|
+
if (args.len == 4) try self.writer.writeByte(@intFromEnum(args[3]));
|
|
295
460
|
}
|
|
296
461
|
|
|
297
|
-
|
|
462
|
+
// ident: ID, value: u8, reason: CureStatus
|
|
463
|
+
pub fn curestatus(self: Self, args: anytype) Error!void {
|
|
298
464
|
if (!enabled) return;
|
|
465
|
+
|
|
299
466
|
try self.writer.writeAll(&.{
|
|
300
|
-
@
|
|
301
|
-
@
|
|
302
|
-
|
|
467
|
+
@intFromEnum(ArgType.CureStatus),
|
|
468
|
+
@as(u8, @bitCast(args[0])),
|
|
469
|
+
args[1],
|
|
470
|
+
@intFromEnum(@as(CureStatus, args[2])),
|
|
303
471
|
});
|
|
304
472
|
}
|
|
305
473
|
|
|
306
|
-
|
|
474
|
+
// ident: ID, reason: Boost, num: i8
|
|
475
|
+
pub fn boost(self: Self, args: anytype) Error!void {
|
|
307
476
|
if (!enabled) return;
|
|
308
|
-
|
|
477
|
+
|
|
478
|
+
assert(args[2] != 0 and (args[1] != .Rage or args[2] > 0));
|
|
479
|
+
try self.writer.writeAll(&.{
|
|
480
|
+
@intFromEnum(ArgType.Boost),
|
|
481
|
+
@as(u8, @bitCast(args[0])),
|
|
482
|
+
@intFromEnum(@as(Boost, args[1])),
|
|
483
|
+
@as(u8, @intCast(@as(i8, args[2]) + 6)),
|
|
484
|
+
});
|
|
309
485
|
}
|
|
310
486
|
|
|
311
|
-
|
|
487
|
+
// -
|
|
488
|
+
pub fn clearallboost(self: Self, _: anytype) Error!void {
|
|
312
489
|
if (!enabled) return;
|
|
313
|
-
|
|
314
|
-
try self.writer.writeAll(&.{
|
|
315
|
-
try self.writer.writeIntNative(u16, pokemon.hp);
|
|
316
|
-
try self.writer.writeIntNative(u16, pokemon.stats.hp);
|
|
317
|
-
try self.writer.writeAll(&.{ pokemon.status, @enumToInt(reason) });
|
|
490
|
+
|
|
491
|
+
try self.writer.writeAll(&.{@intFromEnum(ArgType.ClearAllBoost)});
|
|
318
492
|
}
|
|
319
493
|
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
ident: ID,
|
|
323
|
-
pokemon: anytype,
|
|
324
|
-
reason: Damage,
|
|
325
|
-
source: ID,
|
|
326
|
-
) Error!void {
|
|
494
|
+
// ident: ID, reason: Fail
|
|
495
|
+
pub fn fail(self: Self, args: anytype) Error!void {
|
|
327
496
|
if (!enabled) return;
|
|
328
|
-
|
|
329
|
-
try self.writer.writeAll(&.{ @enumToInt(ArgType.Damage), @bitCast(u8, ident) });
|
|
330
|
-
try self.writer.writeIntNative(u16, pokemon.hp);
|
|
331
|
-
try self.writer.writeIntNative(u16, pokemon.stats.hp);
|
|
497
|
+
|
|
332
498
|
try self.writer.writeAll(&.{
|
|
333
|
-
|
|
334
|
-
@
|
|
335
|
-
@
|
|
499
|
+
@intFromEnum(ArgType.Fail),
|
|
500
|
+
@as(u8, @bitCast(args[0])),
|
|
501
|
+
@intFromEnum(@as(Fail, args[1])),
|
|
336
502
|
});
|
|
337
503
|
}
|
|
338
504
|
|
|
339
|
-
|
|
505
|
+
// source: ID
|
|
506
|
+
pub fn miss(self: Self, args: anytype) Error!void {
|
|
340
507
|
if (!enabled) return;
|
|
341
|
-
|
|
342
|
-
try self.writer.writeAll(&.{ @
|
|
343
|
-
try self.writer.writeIntNative(u16, pokemon.hp);
|
|
344
|
-
try self.writer.writeIntNative(u16, pokemon.stats.hp);
|
|
345
|
-
try self.writer.writeAll(&.{ pokemon.status, @enumToInt(reason) });
|
|
508
|
+
|
|
509
|
+
try self.writer.writeAll(&.{ @intFromEnum(ArgType.Miss), @as(u8, @bitCast(args[0])) });
|
|
346
510
|
}
|
|
347
511
|
|
|
348
|
-
|
|
512
|
+
// ident: ID, num: u8
|
|
513
|
+
pub fn hitcount(self: Self, args: anytype) Error!void {
|
|
349
514
|
if (!enabled) return;
|
|
350
|
-
|
|
351
|
-
try self.writer.writeIntNative(u16, pokemon.hp);
|
|
352
|
-
try self.writer.writeIntNative(u16, pokemon.stats.hp);
|
|
515
|
+
|
|
353
516
|
try self.writer.writeAll(&.{
|
|
354
|
-
|
|
355
|
-
@
|
|
356
|
-
|
|
517
|
+
@intFromEnum(ArgType.HitCount),
|
|
518
|
+
@as(u8, @bitCast(args[0])),
|
|
519
|
+
args[1],
|
|
357
520
|
});
|
|
358
521
|
}
|
|
359
522
|
|
|
360
|
-
|
|
523
|
+
// source: ID, m: <Move>
|
|
524
|
+
pub fn prepare(self: Self, args: anytype) Error!void {
|
|
361
525
|
if (!enabled) return;
|
|
362
|
-
|
|
526
|
+
|
|
363
527
|
try self.writer.writeAll(&.{
|
|
364
|
-
@
|
|
365
|
-
@
|
|
366
|
-
|
|
367
|
-
@enumToInt(reason),
|
|
528
|
+
@intFromEnum(ArgType.Prepare),
|
|
529
|
+
@as(u8, @bitCast(args[0])),
|
|
530
|
+
@intFromEnum(args[1]),
|
|
368
531
|
});
|
|
369
532
|
}
|
|
370
533
|
|
|
371
|
-
|
|
534
|
+
// ident: ID
|
|
535
|
+
pub fn mustrecharge(self: Self, args: anytype) Error!void {
|
|
372
536
|
if (!enabled) return;
|
|
537
|
+
|
|
373
538
|
try self.writer.writeAll(&.{
|
|
374
|
-
@
|
|
375
|
-
@
|
|
376
|
-
value,
|
|
377
|
-
@enumToInt(Status.From),
|
|
378
|
-
@enumToInt(m),
|
|
539
|
+
@intFromEnum(ArgType.MustRecharge),
|
|
540
|
+
@as(u8, @bitCast(args[0])),
|
|
379
541
|
});
|
|
380
542
|
}
|
|
381
543
|
|
|
382
|
-
|
|
544
|
+
// ident: ID, reason: Activate
|
|
545
|
+
// ident: ID, reason: .SubstituteBlock, m: <Move>
|
|
546
|
+
// ident: ID, reason: .Magnitude, num: u8
|
|
547
|
+
pub fn activate(self: Self, args: anytype) Error!void {
|
|
383
548
|
if (!enabled) return;
|
|
549
|
+
|
|
550
|
+
assert(args.len <= 4);
|
|
551
|
+
const reason: Activate = args[1];
|
|
384
552
|
try self.writer.writeAll(&.{
|
|
385
|
-
@
|
|
386
|
-
@
|
|
387
|
-
|
|
388
|
-
@enumToInt(reason),
|
|
553
|
+
@intFromEnum(ArgType.Activate),
|
|
554
|
+
@as(u8, @bitCast(args[0])),
|
|
555
|
+
@intFromEnum(reason),
|
|
389
556
|
});
|
|
557
|
+
if (args.len == 3) {
|
|
558
|
+
if (reason == .SubstituteBlock) {
|
|
559
|
+
try self.writer.writeByte(@intFromEnum(args[2]));
|
|
560
|
+
} else {
|
|
561
|
+
assert(reason == .Magnitude);
|
|
562
|
+
try self.writer.writeByte(args[2]);
|
|
563
|
+
}
|
|
564
|
+
}
|
|
390
565
|
}
|
|
391
566
|
|
|
392
|
-
|
|
567
|
+
// -
|
|
568
|
+
pub fn fieldactivate(self: Self, _: anytype) Error!void {
|
|
393
569
|
if (!enabled) return;
|
|
394
|
-
|
|
395
|
-
try self.writer.writeAll(&.{
|
|
396
|
-
@enumToInt(ArgType.Boost),
|
|
397
|
-
@bitCast(u8, ident),
|
|
398
|
-
@enumToInt(reason),
|
|
399
|
-
@intCast(u8, num + 6),
|
|
400
|
-
});
|
|
570
|
+
|
|
571
|
+
try self.writer.writeAll(&.{@intFromEnum(ArgType.FieldActivate)});
|
|
401
572
|
}
|
|
402
573
|
|
|
403
|
-
|
|
574
|
+
// ident: ID, reason: Start
|
|
575
|
+
// ident: ID, reason: .Disable | .Mimic | .Encore, m: <Move>
|
|
576
|
+
// ident: ID, reason: .TypeChange, types: <Types>, target: ID
|
|
577
|
+
pub fn start(self: Self, args: anytype) Error!void {
|
|
404
578
|
if (!enabled) return;
|
|
405
|
-
|
|
579
|
+
|
|
580
|
+
assert(args.len <= 4);
|
|
581
|
+
const reason: Start = args[1];
|
|
582
|
+
try self.writer.writeAll(&.{
|
|
583
|
+
@intFromEnum(ArgType.Start),
|
|
584
|
+
@as(u8, @bitCast(args[0])),
|
|
585
|
+
@intFromEnum(reason),
|
|
586
|
+
});
|
|
587
|
+
if (args.len == 3) {
|
|
588
|
+
assert(reason == .Disable or reason == .Mimic or reason == .Encore);
|
|
589
|
+
try self.writer.writeByte(@intFromEnum(args[2]));
|
|
590
|
+
} else if (args.len == 4) {
|
|
591
|
+
assert(reason == .TypeChange);
|
|
592
|
+
// FIXME: u16 types in Generation II
|
|
593
|
+
try self.writer.writeAll(&.{
|
|
594
|
+
@as(u8, @bitCast(args[2])),
|
|
595
|
+
@as(u8, @bitCast(args[3])),
|
|
596
|
+
});
|
|
597
|
+
}
|
|
406
598
|
}
|
|
407
599
|
|
|
408
|
-
|
|
600
|
+
// ident: ID, reason: End
|
|
601
|
+
pub fn end(self: Self, args: anytype) Error!void {
|
|
409
602
|
if (!enabled) return;
|
|
603
|
+
|
|
410
604
|
try self.writer.writeAll(&.{
|
|
411
|
-
@
|
|
412
|
-
@
|
|
413
|
-
@
|
|
605
|
+
@intFromEnum(ArgType.End),
|
|
606
|
+
@as(u8, @bitCast(args[0])),
|
|
607
|
+
@intFromEnum(@as(End, args[1])),
|
|
414
608
|
});
|
|
415
609
|
}
|
|
416
610
|
|
|
417
|
-
|
|
611
|
+
// -
|
|
612
|
+
pub fn ohko(self: Self, _: anytype) Error!void {
|
|
418
613
|
if (!enabled) return;
|
|
419
|
-
|
|
614
|
+
|
|
615
|
+
try self.writer.writeAll(&.{@intFromEnum(ArgType.OHKO)});
|
|
420
616
|
}
|
|
421
617
|
|
|
422
|
-
|
|
618
|
+
// ident: ID
|
|
619
|
+
pub fn crit(self: Self, args: anytype) Error!void {
|
|
423
620
|
if (!enabled) return;
|
|
424
|
-
|
|
621
|
+
|
|
622
|
+
try self.writer.writeAll(&.{ @intFromEnum(ArgType.Crit), @as(u8, @bitCast(args[0])) });
|
|
425
623
|
}
|
|
426
624
|
|
|
427
|
-
|
|
625
|
+
// ident: ID
|
|
626
|
+
pub fn supereffective(self: Self, args: anytype) Error!void {
|
|
428
627
|
if (!enabled) return;
|
|
628
|
+
|
|
429
629
|
try self.writer.writeAll(&.{
|
|
430
|
-
@
|
|
431
|
-
@
|
|
432
|
-
@enumToInt(m),
|
|
630
|
+
@intFromEnum(ArgType.SuperEffective),
|
|
631
|
+
@as(u8, @bitCast(args[0])),
|
|
433
632
|
});
|
|
434
633
|
}
|
|
435
634
|
|
|
436
|
-
|
|
635
|
+
// ident: ID
|
|
636
|
+
pub fn resisted(self: Self, args: anytype) Error!void {
|
|
437
637
|
if (!enabled) return;
|
|
438
|
-
|
|
638
|
+
|
|
639
|
+
try self.writer.writeAll(&.{
|
|
640
|
+
@intFromEnum(ArgType.Resisted),
|
|
641
|
+
@as(u8, @bitCast(args[0])),
|
|
642
|
+
});
|
|
439
643
|
}
|
|
440
644
|
|
|
441
|
-
|
|
645
|
+
// ident: ID, reason: Immune
|
|
646
|
+
pub fn immune(self: Self, args: anytype) Error!void {
|
|
442
647
|
if (!enabled) return;
|
|
648
|
+
|
|
443
649
|
try self.writer.writeAll(&.{
|
|
444
|
-
@
|
|
445
|
-
@
|
|
446
|
-
@
|
|
650
|
+
@intFromEnum(ArgType.Immune),
|
|
651
|
+
@as(u8, @bitCast(args[0])),
|
|
652
|
+
@intFromEnum(@as(Immune, args[1])),
|
|
447
653
|
});
|
|
448
654
|
}
|
|
449
655
|
|
|
450
|
-
|
|
656
|
+
// source: ID, target: ID
|
|
657
|
+
pub fn transform(self: Self, args: anytype) Error!void {
|
|
451
658
|
if (!enabled) return;
|
|
452
|
-
|
|
659
|
+
|
|
660
|
+
try self.writer.writeAll(&.{
|
|
661
|
+
@intFromEnum(ArgType.Transform),
|
|
662
|
+
@as(u8, @bitCast(args[0])),
|
|
663
|
+
@as(u8, @bitCast(args[1])),
|
|
664
|
+
});
|
|
665
|
+
}
|
|
666
|
+
|
|
667
|
+
// ident: ID, pokemon: <Pokemon>
|
|
668
|
+
pub fn drag(self: Self, args: anytype) Error!void {
|
|
669
|
+
return switchDrag(self, .Drag, args);
|
|
453
670
|
}
|
|
454
671
|
|
|
455
|
-
|
|
672
|
+
// target: ID, item: <Item>, source: ID
|
|
673
|
+
pub fn item(self: Self, args: anytype) Error!void {
|
|
456
674
|
if (!enabled) return;
|
|
457
|
-
|
|
675
|
+
|
|
458
676
|
try self.writer.writeAll(&.{
|
|
459
|
-
@
|
|
460
|
-
@
|
|
461
|
-
@
|
|
677
|
+
@intFromEnum(ArgType.Item),
|
|
678
|
+
@as(u8, @bitCast(args[0])),
|
|
679
|
+
@intFromEnum(args[1]),
|
|
680
|
+
@as(u8, @bitCast(args[2])),
|
|
462
681
|
});
|
|
463
682
|
}
|
|
464
683
|
|
|
465
|
-
|
|
684
|
+
// ident: ID, item: <Item>, reason: EndItem
|
|
685
|
+
pub fn enditem(self: Self, args: anytype) Error!void {
|
|
466
686
|
if (!enabled) return;
|
|
687
|
+
|
|
467
688
|
try self.writer.writeAll(&.{
|
|
468
|
-
@
|
|
469
|
-
@
|
|
470
|
-
@
|
|
471
|
-
@
|
|
472
|
-
@bitCast(u8, target),
|
|
689
|
+
@intFromEnum(ArgType.EndItem),
|
|
690
|
+
@as(u8, @bitCast(args[0])),
|
|
691
|
+
@intFromEnum(args[1]),
|
|
692
|
+
@intFromEnum(@as(EndItem, args[2])),
|
|
473
693
|
});
|
|
474
694
|
}
|
|
475
695
|
|
|
476
|
-
|
|
696
|
+
// source: ID
|
|
697
|
+
pub fn cureteam(self: Self, args: anytype) Error!void {
|
|
477
698
|
if (!enabled) return;
|
|
478
|
-
|
|
699
|
+
|
|
479
700
|
try self.writer.writeAll(&.{
|
|
480
|
-
@
|
|
481
|
-
@
|
|
482
|
-
@enumToInt(reason),
|
|
483
|
-
@enumToInt(m),
|
|
701
|
+
@intFromEnum(ArgType.CureTeam),
|
|
702
|
+
@as(u8, @bitCast(args[0])),
|
|
484
703
|
});
|
|
485
704
|
}
|
|
486
705
|
|
|
487
|
-
|
|
706
|
+
// ident: ID, pokemon: <Pokemon>, reason: SetHP
|
|
707
|
+
pub fn sethp(self: Self, args: anytype) Error!void {
|
|
488
708
|
if (!enabled) return;
|
|
709
|
+
|
|
710
|
+
try self.writer.writeAll(&.{ @intFromEnum(ArgType.SetHP), @as(u8, @bitCast(args[0])) });
|
|
711
|
+
try self.writer.writeInt(u16, args[1].hp, endian);
|
|
712
|
+
try self.writer.writeInt(u16, args[1].stats.hp, endian);
|
|
713
|
+
try self.writer.writeAll(&.{args[1].status});
|
|
714
|
+
try self.writer.writeByte(@intFromEnum(@as(SetHP, args[2])));
|
|
715
|
+
}
|
|
716
|
+
|
|
717
|
+
// ident: ID, num: i8
|
|
718
|
+
pub fn setboost(self: Self, args: anytype) Error!void {
|
|
719
|
+
if (!enabled) return;
|
|
720
|
+
|
|
489
721
|
try self.writer.writeAll(&.{
|
|
490
|
-
@
|
|
491
|
-
@
|
|
492
|
-
@
|
|
722
|
+
@intFromEnum(ArgType.SetBoost),
|
|
723
|
+
@as(u8, @bitCast(args[0])),
|
|
724
|
+
@as(u8, @intCast(args[1] + 6)),
|
|
493
725
|
});
|
|
494
726
|
}
|
|
495
727
|
|
|
496
|
-
|
|
728
|
+
// source: ID, target: ID
|
|
729
|
+
pub fn copyboost(self: Self, args: anytype) Error!void {
|
|
497
730
|
if (!enabled) return;
|
|
498
|
-
|
|
731
|
+
|
|
732
|
+
try self.writer.writeAll(&.{
|
|
733
|
+
@intFromEnum(ArgType.CopyBoost),
|
|
734
|
+
@as(u8, @bitCast(args[0])),
|
|
735
|
+
@as(u8, @bitCast(args[1])),
|
|
736
|
+
});
|
|
499
737
|
}
|
|
500
738
|
|
|
501
|
-
|
|
739
|
+
// player: Player, reason: Side
|
|
740
|
+
pub fn sidestart(self: Self, args: anytype) Error!void {
|
|
502
741
|
if (!enabled) return;
|
|
503
|
-
|
|
742
|
+
|
|
743
|
+
try self.writer.writeAll(&.{
|
|
744
|
+
@intFromEnum(ArgType.SideStart),
|
|
745
|
+
@intFromEnum(@as(Player, args[0])),
|
|
746
|
+
@intFromEnum(@as(Side, args[1])),
|
|
747
|
+
});
|
|
504
748
|
}
|
|
505
749
|
|
|
506
|
-
|
|
750
|
+
// player: Player, reason: Side
|
|
751
|
+
// player: Player, reason: .Spikes, source: ID
|
|
752
|
+
pub fn sideend(self: Self, args: anytype) Error!void {
|
|
507
753
|
if (!enabled) return;
|
|
508
|
-
|
|
754
|
+
|
|
755
|
+
assert(args[1] != .Spikes or args.len == 3);
|
|
756
|
+
try self.writer.writeAll(&.{
|
|
757
|
+
@intFromEnum(ArgType.SideEnd),
|
|
758
|
+
@intFromEnum(@as(Player, args[0])),
|
|
759
|
+
@intFromEnum(@as(Side, args[1])),
|
|
760
|
+
});
|
|
761
|
+
if (args.len == 3) try self.writer.writeByte(@as(u8, @bitCast(args[2])));
|
|
509
762
|
}
|
|
510
763
|
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
764
|
+
// ident: ID, move: <Move>
|
|
765
|
+
pub fn singlemove(self: Self, args: anytype) Error!void {
|
|
766
|
+
return single(self, .SingleMove, args);
|
|
767
|
+
}
|
|
768
|
+
|
|
769
|
+
// ident: ID, move: <Move>
|
|
770
|
+
pub fn singleturn(self: Self, args: anytype) Error!void {
|
|
771
|
+
return single(self, .SingleTurn, args);
|
|
514
772
|
}
|
|
515
773
|
|
|
516
|
-
|
|
774
|
+
// ident: ID, move: <Move>
|
|
775
|
+
fn single(self: Self, arg: ArgType, args: anytype) Error!void {
|
|
517
776
|
if (!enabled) return;
|
|
777
|
+
|
|
518
778
|
try self.writer.writeAll(&.{
|
|
519
|
-
@
|
|
520
|
-
@
|
|
521
|
-
@
|
|
779
|
+
@intFromEnum(arg),
|
|
780
|
+
@as(u8, @bitCast(args[0])),
|
|
781
|
+
@intFromEnum(args[1]),
|
|
522
782
|
});
|
|
523
783
|
}
|
|
524
784
|
|
|
525
|
-
|
|
785
|
+
// weather: <Weather>, reason: Weather
|
|
786
|
+
pub fn weather(self: Self, args: anytype) Error!void {
|
|
526
787
|
if (!enabled) return;
|
|
788
|
+
|
|
789
|
+
assert(!(args[0] == .None and args[1] == .Upkeep));
|
|
527
790
|
try self.writer.writeAll(&.{
|
|
528
|
-
@
|
|
529
|
-
@
|
|
530
|
-
@
|
|
791
|
+
@intFromEnum(ArgType.Weather),
|
|
792
|
+
@intFromEnum(args[0]),
|
|
793
|
+
@intFromEnum(@as(Weather, args[1])),
|
|
531
794
|
});
|
|
532
795
|
}
|
|
533
796
|
|
|
534
|
-
|
|
797
|
+
// -
|
|
798
|
+
pub fn laststill(self: Self, _: anytype) Error!void {
|
|
535
799
|
if (!enabled) return;
|
|
536
|
-
|
|
800
|
+
|
|
801
|
+
try self.writer.writeAll(&.{@intFromEnum(ArgType.LastStill)});
|
|
537
802
|
}
|
|
538
803
|
|
|
539
|
-
|
|
804
|
+
// -
|
|
805
|
+
pub fn lastmiss(self: Self, _: anytype) Error!void {
|
|
540
806
|
if (!enabled) return;
|
|
541
|
-
|
|
807
|
+
|
|
808
|
+
try self.writer.writeAll(&.{@intFromEnum(ArgType.LastMiss)});
|
|
542
809
|
}
|
|
543
810
|
};
|
|
544
811
|
}
|
|
545
812
|
|
|
813
|
+
/// `Log` type backed by the optimized `ByteStream.Writer`.
|
|
546
814
|
pub const FixedLog = Log(ByteStream.Writer);
|
|
547
815
|
|
|
816
|
+
/// Stripped down version of `std.io.FixedBufferStream` optimized for efficiently writing the
|
|
817
|
+
/// individual protocol bytes. Note that the `ByteStream.Writer` is **not** a `std.io.Writer` and
|
|
818
|
+
/// should not be used for general purpose writing.
|
|
548
819
|
pub const ByteStream = struct {
|
|
549
820
|
buffer: []u8,
|
|
550
821
|
pos: usize = 0,
|
|
@@ -562,10 +833,10 @@ pub const ByteStream = struct {
|
|
|
562
833
|
try self.stream.writeByte(byte);
|
|
563
834
|
}
|
|
564
835
|
|
|
565
|
-
pub fn
|
|
836
|
+
pub fn writeInt(self: Writer, comptime T: type, v: T, end: std.builtin.Endian) Error!void {
|
|
566
837
|
// TODO: rework this to write directly to the buffer?
|
|
567
|
-
var bytes: [(@typeInfo(T).Int.bits
|
|
568
|
-
std.mem.
|
|
838
|
+
var bytes: [@divExact(@typeInfo(T).Int.bits, 8)]u8 = undefined;
|
|
839
|
+
std.mem.writeInt(std.math.ByteAlignedInt(@TypeOf(v)), &bytes, v, end);
|
|
569
840
|
return self.writeAll(&bytes);
|
|
570
841
|
}
|
|
571
842
|
};
|
|
@@ -585,15 +856,19 @@ pub const ByteStream = struct {
|
|
|
585
856
|
}
|
|
586
857
|
};
|
|
587
858
|
|
|
588
|
-
pub const Kind = enum { Move, Species, Type, Status };
|
|
589
|
-
pub const Formatter = fn (Kind, u8) []const u8;
|
|
859
|
+
pub const Kind = enum { Move, Species, Type, Status, Item, Weather };
|
|
590
860
|
|
|
591
|
-
pub fn format(
|
|
861
|
+
pub fn format(
|
|
862
|
+
comptime gen: anytype,
|
|
863
|
+
a: []const u8,
|
|
864
|
+
b: ?[]const u8,
|
|
865
|
+
color: bool,
|
|
866
|
+
) void {
|
|
592
867
|
print("\n", .{});
|
|
593
868
|
|
|
594
869
|
var i: usize = 0;
|
|
595
870
|
while (i < a.len) {
|
|
596
|
-
const arg = @
|
|
871
|
+
const arg: ArgType = @enumFromInt(a[i]);
|
|
597
872
|
const name = switch (arg) {
|
|
598
873
|
.None => if (color) "\x1b[2m-\x1b[0m" else "-",
|
|
599
874
|
.LastStill => "|[still]",
|
|
@@ -626,6 +901,18 @@ pub fn format(comptime formatter: Formatter, a: []const u8, b: ?[]const u8, colo
|
|
|
626
901
|
.Resisted => "|-resisted|",
|
|
627
902
|
.Immune => "|-immune|",
|
|
628
903
|
.Transform => "|-transform|",
|
|
904
|
+
.Drag => "|drag|",
|
|
905
|
+
.Item => "|-item|",
|
|
906
|
+
.EndItem => "|-enditem|",
|
|
907
|
+
.CureTeam => "|-cureteam|",
|
|
908
|
+
.SetHP => "|-sethp|",
|
|
909
|
+
.SetBoost => "|-setboost|",
|
|
910
|
+
.CopyBoost => "|-copyboost|",
|
|
911
|
+
.SideStart => "|-sidestart|",
|
|
912
|
+
.SideEnd => "|-sideend|",
|
|
913
|
+
.SingleMove => "|-singlemove|",
|
|
914
|
+
.SingleTurn => "|-singleturn|",
|
|
915
|
+
.Weather => "|-weather|",
|
|
629
916
|
else => unreachable,
|
|
630
917
|
};
|
|
631
918
|
printc("{s}", .{name}, a, b, &i, 1, color);
|
|
@@ -639,43 +926,53 @@ pub fn format(comptime formatter: Formatter, a: []const u8, b: ?[]const u8, colo
|
|
|
639
926
|
.OHKO,
|
|
640
927
|
=> {},
|
|
641
928
|
.Move => {
|
|
642
|
-
const source = ID.from(@intCast(
|
|
929
|
+
const source = ID.from(@intCast(a[i]));
|
|
643
930
|
printc(" {s}({d})", .{ @tagName(source.player), source.id }, a, b, &i, 1, color);
|
|
644
|
-
printc(" {s}", .{formatter(.Move, a[i])}, a, b, &i, 1, color);
|
|
645
|
-
const target = ID.from(@intCast(
|
|
931
|
+
printc(" {s}", .{formatter(gen, .Move, a[i])}, a, b, &i, 1, color);
|
|
932
|
+
const target = ID.from(@intCast(a[i]));
|
|
646
933
|
printc(" {s}({d})", .{ @tagName(target.player), target.id }, a, b, &i, 1, color);
|
|
647
|
-
const reason = @
|
|
934
|
+
const reason: Move = @enumFromInt(a[i]);
|
|
648
935
|
printc(" {s}", .{@tagName(reason)}, a, b, &i, 1, color);
|
|
649
|
-
if (reason == .From)
|
|
936
|
+
if (reason == .From) {
|
|
937
|
+
printc(" {s}", .{formatter(gen, .Move, a[i])}, a, b, &i, 1, color);
|
|
938
|
+
}
|
|
650
939
|
},
|
|
651
|
-
.Switch => {
|
|
652
|
-
const id = ID.from(@intCast(
|
|
940
|
+
.Switch, .Drag => {
|
|
941
|
+
const id = ID.from(@intCast(a[i]));
|
|
653
942
|
printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
|
|
654
|
-
printc(" {s}", .{formatter(.Species, a[i])}, a, b, &i, 1, color);
|
|
943
|
+
printc(" {s}", .{formatter(gen, .Species, a[i])}, a, b, &i, 1, color);
|
|
944
|
+
if (@hasDecl(gen, "Gender")) {
|
|
945
|
+
if (a[i] == N(gen.Gender.Unknown)) {
|
|
946
|
+
i += 1;
|
|
947
|
+
} else {
|
|
948
|
+
const gender = if (a[i] == N(gen.Gender.Male)) "M" else "F";
|
|
949
|
+
printc(", {s}", .{gender}, a, b, &i, 1, color);
|
|
950
|
+
}
|
|
951
|
+
}
|
|
655
952
|
printc(" L{d}", .{a[i]}, a, b, &i, 1, color);
|
|
656
953
|
switch (endian) {
|
|
657
|
-
.
|
|
954
|
+
.big => {
|
|
658
955
|
var hp = @as(u16, a[i]) << 8 | @as(u16, a[i + 1]);
|
|
659
956
|
printc(" {d}", .{hp}, a, b, &i, 2, color);
|
|
660
957
|
hp = @as(u16, a[i]) << 8 | @as(u16, a[i + 1]);
|
|
661
958
|
printc("/{d}", .{hp}, a, b, &i, 2, color);
|
|
662
959
|
},
|
|
663
|
-
.
|
|
960
|
+
.little => {
|
|
664
961
|
var hp = @as(u16, a[i + 1]) << 8 | @as(u16, a[i]);
|
|
665
962
|
printc(" {d}", .{hp}, a, b, &i, 2, color);
|
|
666
963
|
hp = @as(u16, a[i + 1]) << 8 | @as(u16, a[i]);
|
|
667
964
|
printc("/{d}", .{hp}, a, b, &i, 2, color);
|
|
668
965
|
},
|
|
669
966
|
}
|
|
670
|
-
printc(" {s}", .{formatter(.Status, a[i])}, a, b, &i, 1, color);
|
|
967
|
+
printc(" {s}", .{formatter(gen, .Status, a[i])}, a, b, &i, 1, color);
|
|
671
968
|
},
|
|
672
969
|
.Cant => {
|
|
673
|
-
const id = ID.from(@intCast(
|
|
970
|
+
const id = ID.from(@intCast(a[i]));
|
|
674
971
|
printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
|
|
675
|
-
const reason = @
|
|
972
|
+
const reason: Cant = @enumFromInt(a[i]);
|
|
676
973
|
printc(" {s}", .{@tagName(reason)}, a, b, &i, 1, color);
|
|
677
974
|
if (reason == .Disable) {
|
|
678
|
-
printc(" {s}", .{formatter(.Move, a[i])}, a, b, &i, 1, color);
|
|
975
|
+
printc(" {s}", .{formatter(gen, .Move, a[i])}, a, b, &i, 1, color);
|
|
679
976
|
}
|
|
680
977
|
},
|
|
681
978
|
.Faint,
|
|
@@ -684,124 +981,189 @@ pub fn format(comptime formatter: Formatter, a: []const u8, b: ?[]const u8, colo
|
|
|
684
981
|
.Crit,
|
|
685
982
|
.SuperEffective,
|
|
686
983
|
.Resisted,
|
|
984
|
+
.CureTeam,
|
|
687
985
|
=> {
|
|
688
|
-
const id = ID.from(@intCast(
|
|
986
|
+
const id = ID.from(@intCast(a[i]));
|
|
689
987
|
printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
|
|
690
988
|
},
|
|
691
989
|
.Turn => {
|
|
692
990
|
const turn = switch (endian) {
|
|
693
|
-
.
|
|
694
|
-
.
|
|
991
|
+
.big => @as(u16, a[i]) << 8 | @as(u16, a[i + 1]),
|
|
992
|
+
.little => @as(u16, a[i + 1]) << 8 | @as(u16, a[i]),
|
|
695
993
|
};
|
|
696
994
|
printc(" {d}", .{turn}, a, b, &i, 2, color);
|
|
697
995
|
},
|
|
698
|
-
.Win =>
|
|
996
|
+
.Win => {
|
|
997
|
+
printc(" {s}", .{@tagName(@as(Player, @enumFromInt(a[i])))}, a, b, &i, 1, color);
|
|
998
|
+
},
|
|
699
999
|
.Damage, .Heal => {
|
|
700
|
-
var id = ID.from(@intCast(
|
|
1000
|
+
var id = ID.from(@intCast(a[i]));
|
|
701
1001
|
printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
|
|
702
1002
|
switch (endian) {
|
|
703
|
-
.
|
|
1003
|
+
.big => {
|
|
704
1004
|
var hp = @as(u16, a[i]) << 8 | @as(u16, a[i + 1]);
|
|
705
1005
|
printc(" {d}", .{hp}, a, b, &i, 2, color);
|
|
706
1006
|
hp = @as(u16, a[i]) << 8 | @as(u16, a[i + 1]);
|
|
707
1007
|
printc("/{d}", .{hp}, a, b, &i, 2, color);
|
|
708
1008
|
},
|
|
709
|
-
.
|
|
1009
|
+
.little => {
|
|
710
1010
|
var hp = @as(u16, a[i + 1]) << 8 | @as(u16, a[i]);
|
|
711
1011
|
printc(" {d}", .{hp}, a, b, &i, 2, color);
|
|
712
1012
|
hp = @as(u16, a[i + 1]) << 8 | @as(u16, a[i]);
|
|
713
1013
|
printc("/{d}", .{hp}, a, b, &i, 2, color);
|
|
714
1014
|
},
|
|
715
1015
|
}
|
|
716
|
-
printc(" {s}", .{formatter(.Status, a[i])}, a, b, &i, 1, color);
|
|
1016
|
+
printc(" {s}", .{formatter(gen, .Status, a[i])}, a, b, &i, 1, color);
|
|
717
1017
|
if (arg == .Damage) {
|
|
718
|
-
const reason = a[i];
|
|
719
|
-
printc(" {s}", .{@tagName(
|
|
720
|
-
if (reason ==
|
|
721
|
-
id = ID.from(@intCast(
|
|
1018
|
+
const reason: Damage = @enumFromInt(a[i]);
|
|
1019
|
+
printc(" {s}", .{@tagName(reason)}, a, b, &i, 1, color);
|
|
1020
|
+
if (reason == .RecoilOf) {
|
|
1021
|
+
id = ID.from(@intCast(a[i]));
|
|
722
1022
|
printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
|
|
723
1023
|
}
|
|
724
1024
|
} else {
|
|
725
|
-
const reason = @
|
|
1025
|
+
const reason: Heal = @enumFromInt(a[i]);
|
|
726
1026
|
printc(" {s}", .{@tagName(reason)}, a, b, &i, 1, color);
|
|
727
1027
|
if (reason == .Drain) {
|
|
728
|
-
id = ID.from(@intCast(
|
|
1028
|
+
id = ID.from(@intCast(a[i]));
|
|
729
1029
|
printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
|
|
730
1030
|
}
|
|
731
1031
|
}
|
|
732
1032
|
},
|
|
733
1033
|
.Status => {
|
|
734
|
-
const id = ID.from(@intCast(
|
|
1034
|
+
const id = ID.from(@intCast(a[i]));
|
|
735
1035
|
printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
|
|
736
|
-
printc(" {s}", .{formatter(.Status, a[i])}, a, b, &i, 1, color);
|
|
737
|
-
const reason = @
|
|
1036
|
+
printc(" {s}", .{formatter(gen, .Status, a[i])}, a, b, &i, 1, color);
|
|
1037
|
+
const reason: Status = @enumFromInt(a[i]);
|
|
738
1038
|
printc(" {s}", .{@tagName(reason)}, a, b, &i, 1, color);
|
|
739
|
-
if (reason == .From)
|
|
1039
|
+
if (reason == .From) {
|
|
1040
|
+
printc(" {s}", .{formatter(gen, .Move, a[i])}, a, b, &i, 1, color);
|
|
1041
|
+
}
|
|
740
1042
|
},
|
|
741
1043
|
.CureStatus => {
|
|
742
|
-
const id = ID.from(@intCast(
|
|
1044
|
+
const id = ID.from(@intCast(a[i]));
|
|
743
1045
|
printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
|
|
744
|
-
printc(" {s}", .{formatter(.Status, a[i])}, a, b, &i, 1, color);
|
|
745
|
-
|
|
1046
|
+
printc(" {s}", .{formatter(gen, .Status, a[i])}, a, b, &i, 1, color);
|
|
1047
|
+
const reason: CureStatus = @enumFromInt(a[i]);
|
|
1048
|
+
printc(" {s}", .{@tagName(reason)}, a, b, &i, 1, color);
|
|
746
1049
|
},
|
|
747
1050
|
.Boost => {
|
|
748
|
-
const id = ID.from(@intCast(
|
|
1051
|
+
const id = ID.from(@intCast(a[i]));
|
|
749
1052
|
printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
|
|
750
|
-
printc(" {s}", .{@tagName(@
|
|
1053
|
+
printc(" {s}", .{@tagName(@as(Boost, @enumFromInt(a[i])))}, a, b, &i, 1, color);
|
|
751
1054
|
printc(" {d}", .{a[i]}, a, b, &i, 1, color);
|
|
752
1055
|
},
|
|
753
1056
|
.Fail => {
|
|
754
|
-
const id = ID.from(@intCast(
|
|
1057
|
+
const id = ID.from(@intCast(a[i]));
|
|
755
1058
|
printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
|
|
756
|
-
printc(" {s}", .{@tagName(@
|
|
1059
|
+
printc(" {s}", .{@tagName(@as(Fail, @enumFromInt(a[i])))}, a, b, &i, 1, color);
|
|
757
1060
|
},
|
|
758
|
-
.HitCount => {
|
|
759
|
-
const id = ID.from(@intCast(
|
|
1061
|
+
.HitCount, .SetBoost => {
|
|
1062
|
+
const id = ID.from(@intCast(a[i]));
|
|
760
1063
|
printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
|
|
761
1064
|
printc(" {d}", .{a[i]}, a, b, &i, 1, color);
|
|
762
1065
|
},
|
|
763
|
-
.Prepare => {
|
|
764
|
-
const id = ID.from(@intCast(
|
|
1066
|
+
.Prepare, .SingleMove, .SingleTurn => {
|
|
1067
|
+
const id = ID.from(@intCast(a[i]));
|
|
765
1068
|
printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
|
|
766
|
-
printc(" {s}", .{formatter(.Move, a[i])}, a, b, &i, 1, color);
|
|
1069
|
+
printc(" {s}", .{formatter(gen, .Move, a[i])}, a, b, &i, 1, color);
|
|
767
1070
|
},
|
|
768
1071
|
.Activate => {
|
|
769
|
-
const id = ID.from(@intCast(
|
|
1072
|
+
const id = ID.from(@intCast(a[i]));
|
|
770
1073
|
printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
|
|
771
|
-
|
|
1074
|
+
const reason: Activate = @enumFromInt(a[i]);
|
|
1075
|
+
printc(" {s}", .{@tagName(reason)}, a, b, &i, 1, color);
|
|
1076
|
+
if (reason == .SubstituteBlock) {
|
|
1077
|
+
printc(" {s}", .{formatter(gen, .Move, a[i])}, a, b, &i, 1, color);
|
|
1078
|
+
} else if (reason == .Magnitude) {
|
|
1079
|
+
printc(" {d}", .{a[i]}, a, b, &i, 1, color);
|
|
1080
|
+
}
|
|
772
1081
|
},
|
|
773
1082
|
.Start => {
|
|
774
|
-
const id = ID.from(@intCast(
|
|
1083
|
+
const id = ID.from(@intCast(a[i]));
|
|
775
1084
|
printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
|
|
776
1085
|
const reason = a[i];
|
|
777
|
-
printc(" {s}", .{@tagName(@
|
|
778
|
-
if (@
|
|
779
|
-
|
|
1086
|
+
printc(" {s}", .{@tagName(@as(Start, @enumFromInt(reason)))}, a, b, &i, 1, color);
|
|
1087
|
+
if (@as(Start, @enumFromInt(reason)) == .TypeChange) {
|
|
1088
|
+
// FIXME
|
|
1089
|
+
const types = @as(gen1.Types, @bitCast(a[i]));
|
|
780
1090
|
const args = .{
|
|
781
|
-
formatter(.Type, @
|
|
782
|
-
formatter(.Type, @
|
|
1091
|
+
formatter(gen, .Type, @intFromEnum(types.type1)),
|
|
1092
|
+
formatter(gen, .Type, @intFromEnum(types.type2)),
|
|
783
1093
|
};
|
|
784
1094
|
printc(" {s}/{s}", args, a, b, &i, 1, color);
|
|
785
|
-
} else if (reason >= @
|
|
786
|
-
printc(" {s}", .{formatter(.Move, a[i])}, a, b, &i, 1, color);
|
|
1095
|
+
} else if (reason >= @intFromEnum(Start.Disable)) {
|
|
1096
|
+
printc(" {s}", .{formatter(gen, .Move, a[i])}, a, b, &i, 1, color);
|
|
787
1097
|
}
|
|
788
1098
|
},
|
|
789
1099
|
.End => {
|
|
790
|
-
const id = ID.from(@intCast(
|
|
1100
|
+
const id = ID.from(@intCast(a[i]));
|
|
791
1101
|
printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
|
|
792
|
-
printc(" {s}", .{@tagName(@
|
|
1102
|
+
printc(" {s}", .{@tagName(@as(End, @enumFromInt(a[i])))}, a, b, &i, 1, color);
|
|
793
1103
|
},
|
|
794
1104
|
.Immune => {
|
|
795
|
-
const id = ID.from(@intCast(
|
|
1105
|
+
const id = ID.from(@intCast(a[i]));
|
|
796
1106
|
printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
|
|
797
|
-
printc(" {s}", .{@tagName(@
|
|
1107
|
+
printc(" {s}", .{@tagName(@as(Immune, @enumFromInt(a[i])))}, a, b, &i, 1, color);
|
|
798
1108
|
},
|
|
799
|
-
.Transform => {
|
|
800
|
-
const source = ID.from(@intCast(
|
|
1109
|
+
.Transform, .CopyBoost => {
|
|
1110
|
+
const source = ID.from(@intCast(a[i]));
|
|
801
1111
|
printc(" {s}({d})", .{ @tagName(source.player), source.id }, a, b, &i, 1, color);
|
|
802
|
-
const target = ID.from(@intCast(
|
|
1112
|
+
const target = ID.from(@intCast(a[i]));
|
|
803
1113
|
printc(" {s}({d})", .{ @tagName(target.player), target.id }, a, b, &i, 1, color);
|
|
804
1114
|
},
|
|
1115
|
+
.Item, .EndItem => {
|
|
1116
|
+
var id = ID.from(@intCast(a[i]));
|
|
1117
|
+
printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
|
|
1118
|
+
printc(" {s}", .{formatter(gen, .Item, a[i])}, a, b, &i, 1, color);
|
|
1119
|
+
if (arg == .Item) {
|
|
1120
|
+
id = ID.from(@intCast(a[i]));
|
|
1121
|
+
printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
|
|
1122
|
+
} else {
|
|
1123
|
+
const reason: EndItem = @enumFromInt(a[i]);
|
|
1124
|
+
printc(" {s}", .{@tagName(reason)}, a, b, &i, 1, color);
|
|
1125
|
+
}
|
|
1126
|
+
},
|
|
1127
|
+
.SetHP => {
|
|
1128
|
+
const id = ID.from(@intCast(a[i]));
|
|
1129
|
+
printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
|
|
1130
|
+
switch (endian) {
|
|
1131
|
+
.big => {
|
|
1132
|
+
var hp = @as(u16, a[i]) << 8 | @as(u16, a[i + 1]);
|
|
1133
|
+
printc(" {d}", .{hp}, a, b, &i, 2, color);
|
|
1134
|
+
hp = @as(u16, a[i]) << 8 | @as(u16, a[i + 1]);
|
|
1135
|
+
printc("/{d}", .{hp}, a, b, &i, 2, color);
|
|
1136
|
+
},
|
|
1137
|
+
.little => {
|
|
1138
|
+
var hp = @as(u16, a[i + 1]) << 8 | @as(u16, a[i]);
|
|
1139
|
+
printc(" {d}", .{hp}, a, b, &i, 2, color);
|
|
1140
|
+
hp = @as(u16, a[i + 1]) << 8 | @as(u16, a[i]);
|
|
1141
|
+
printc("/{d}", .{hp}, a, b, &i, 2, color);
|
|
1142
|
+
},
|
|
1143
|
+
}
|
|
1144
|
+
printc(" {s}", .{formatter(gen, .Status, a[i])}, a, b, &i, 1, color);
|
|
1145
|
+
printc(" {s}", .{@tagName(@as(SetHP, @enumFromInt(a[i])))}, a, b, &i, 1, color);
|
|
1146
|
+
},
|
|
1147
|
+
.SideStart => {
|
|
1148
|
+
const id = ID.from(@intCast(a[i]));
|
|
1149
|
+
printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
|
|
1150
|
+
printc(" {s}", .{@tagName(@as(Side, @enumFromInt(a[i])))}, a, b, &i, 1, color);
|
|
1151
|
+
},
|
|
1152
|
+
.SideEnd => {
|
|
1153
|
+
var id = ID.from(@intCast(a[i]));
|
|
1154
|
+
printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
|
|
1155
|
+
const reason: Side = @enumFromInt(a[i]);
|
|
1156
|
+
printc(" {s}", .{@tagName(reason)}, a, b, &i, 1, color);
|
|
1157
|
+
if (reason == .Spikes) {
|
|
1158
|
+
printc(" {s}", .{formatter(gen, .Move, a[i])}, a, b, &i, 1, color);
|
|
1159
|
+
id = ID.from(@intCast(a[i]));
|
|
1160
|
+
printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
|
|
1161
|
+
}
|
|
1162
|
+
},
|
|
1163
|
+
.Weather => {
|
|
1164
|
+
printc(" {s}", .{formatter(gen, .Weather, a[i])}, a, b, &i, 1, color);
|
|
1165
|
+
printc(" {s}", .{@tagName(@as(Weather, @enumFromInt(a[i])))}, a, b, &i, 1, color);
|
|
1166
|
+
},
|
|
805
1167
|
else => unreachable,
|
|
806
1168
|
}
|
|
807
1169
|
print("\n", .{});
|
|
@@ -833,12 +1195,13 @@ fn printc(
|
|
|
833
1195
|
}
|
|
834
1196
|
|
|
835
1197
|
pub fn expectLog(
|
|
836
|
-
comptime
|
|
1198
|
+
comptime gen: anytype,
|
|
837
1199
|
expected: []const u8,
|
|
838
1200
|
actual: []const u8,
|
|
839
1201
|
offset: usize,
|
|
840
1202
|
) !void {
|
|
841
1203
|
if (!enabled) return;
|
|
1204
|
+
|
|
842
1205
|
const color = color: {
|
|
843
1206
|
if (std.process.hasEnvVarConstant("ZIG_DEBUG_COLOR")) {
|
|
844
1207
|
break :color true;
|
|
@@ -851,8 +1214,8 @@ pub fn expectLog(
|
|
|
851
1214
|
|
|
852
1215
|
expectEqualBytes(expected, actual, offset) catch |err| switch (err) {
|
|
853
1216
|
error.TestExpectedEqual => {
|
|
854
|
-
format(
|
|
855
|
-
format(
|
|
1217
|
+
format(gen, expected, null, color);
|
|
1218
|
+
format(gen, actual, expected, color);
|
|
856
1219
|
return err;
|
|
857
1220
|
},
|
|
858
1221
|
else => return err,
|
|
@@ -878,63 +1241,75 @@ fn expectEqualBytes(expected: []const u8, actual: []const u8, offset: usize) !vo
|
|
|
878
1241
|
}
|
|
879
1242
|
}
|
|
880
1243
|
|
|
881
|
-
const endian = builtin.target.cpu.arch.endian();
|
|
882
|
-
|
|
883
1244
|
fn N(e: anytype) u8 {
|
|
884
|
-
return @
|
|
1245
|
+
return @intFromEnum(e);
|
|
885
1246
|
}
|
|
886
1247
|
|
|
887
1248
|
const p1 = Player.P1;
|
|
888
1249
|
const p2 = Player.P2;
|
|
889
1250
|
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
pub const helpers = @import("../gen1/helpers.zig");
|
|
893
|
-
};
|
|
894
|
-
|
|
895
|
-
var buf: [gen1.LOGS_SIZE]u8 = undefined;
|
|
896
|
-
var stream = ByteStream{ .buffer = &buf };
|
|
1251
|
+
var buf: [pkmn.LOGS_SIZE]u8 = undefined;
|
|
1252
|
+
var stream: ByteStream = .{ .buffer = &buf };
|
|
897
1253
|
var log: FixedLog = .{ .writer = stream.writer() };
|
|
898
1254
|
|
|
899
|
-
const
|
|
900
|
-
const
|
|
1255
|
+
const gen1 = pkmn.gen1;
|
|
1256
|
+
const gen2 = pkmn.gen2;
|
|
1257
|
+
|
|
1258
|
+
const M1 = gen1.Move;
|
|
1259
|
+
const S1 = gen1.Species;
|
|
1260
|
+
|
|
1261
|
+
const M2 = gen2.Move;
|
|
1262
|
+
const S2 = gen2.Species;
|
|
1263
|
+
const I2 = gen2.Item;
|
|
1264
|
+
const W2 = gen2.Weather;
|
|
901
1265
|
|
|
902
1266
|
fn expectLog1(expected: []const u8, actual: []const u8) !void {
|
|
903
|
-
return expectLog(
|
|
1267
|
+
return expectLog(gen1, expected, actual, 0);
|
|
1268
|
+
}
|
|
1269
|
+
|
|
1270
|
+
fn expectLog2(expected: []const u8, actual: []const u8) !void {
|
|
1271
|
+
return expectLog(gen2, expected, actual, 0);
|
|
904
1272
|
}
|
|
905
1273
|
|
|
906
|
-
fn
|
|
1274
|
+
fn formatter(comptime gen: anytype, kind: Kind, byte: u8) []const u8 {
|
|
907
1275
|
return switch (kind) {
|
|
908
|
-
.Move => @tagName(@
|
|
909
|
-
.Species => @tagName(@
|
|
910
|
-
.Type => @tagName(@
|
|
911
|
-
.Status =>
|
|
1276
|
+
.Move => @tagName(@as(gen.Move, @enumFromInt(byte))),
|
|
1277
|
+
.Species => @tagName(@as(gen.Species, @enumFromInt(byte))),
|
|
1278
|
+
.Type => @tagName(@as(gen.Type, @enumFromInt(byte))),
|
|
1279
|
+
.Status => gen.Status.name(byte),
|
|
1280
|
+
.Item => if (@hasDecl(gen, "Item"))
|
|
1281
|
+
@tagName(@as(gen.Item, @enumFromInt(byte)))
|
|
1282
|
+
else
|
|
1283
|
+
unreachable,
|
|
1284
|
+
.Weather => if (@hasDecl(gen, "Weather"))
|
|
1285
|
+
@tagName(@as(gen.Weather, @enumFromInt(byte)))
|
|
1286
|
+
else
|
|
1287
|
+
unreachable,
|
|
912
1288
|
};
|
|
913
1289
|
}
|
|
914
1290
|
|
|
915
1291
|
test "|move|" {
|
|
916
|
-
try log.move(p2.ident(4),
|
|
1292
|
+
try log.move(.{ p2.ident(4), M1.Thunderbolt, p1.ident(5) });
|
|
917
1293
|
try expectLog1(
|
|
918
|
-
&.{ N(ArgType.Move), 0b1100, N(
|
|
1294
|
+
&.{ N(ArgType.Move), 0b1100, N(M1.Thunderbolt), 0b0101, N(Move.None) },
|
|
919
1295
|
buf[0..5],
|
|
920
1296
|
);
|
|
921
1297
|
stream.reset();
|
|
922
1298
|
|
|
923
|
-
try log.move(p2.ident(4),
|
|
924
|
-
const wrap = N(M.Wrap);
|
|
1299
|
+
try log.move(.{ p2.ident(4), M1.Pound, p1.ident(5), M1.Metronome });
|
|
925
1300
|
try expectLog1(
|
|
926
|
-
&.{ N(ArgType.Move), 0b1100,
|
|
1301
|
+
&.{ N(ArgType.Move), 0b1100, N(M1.Pound), 0b0101, N(Move.From), N(M1.Metronome) },
|
|
927
1302
|
buf[0..6],
|
|
928
1303
|
);
|
|
929
1304
|
stream.reset();
|
|
930
1305
|
|
|
931
|
-
try log.move(p2.ident(4),
|
|
932
|
-
try log.laststill();
|
|
1306
|
+
try log.move(.{ p2.ident(4), M1.SkullBash, ID{} });
|
|
1307
|
+
try log.laststill(.{});
|
|
933
1308
|
try expectLog1(
|
|
934
1309
|
&.{
|
|
935
1310
|
N(ArgType.Move),
|
|
936
1311
|
0b1100,
|
|
937
|
-
N(
|
|
1312
|
+
N(M1.SkullBash),
|
|
938
1313
|
0,
|
|
939
1314
|
N(Move.None),
|
|
940
1315
|
N(ArgType.LastStill),
|
|
@@ -943,13 +1318,13 @@ test "|move|" {
|
|
|
943
1318
|
);
|
|
944
1319
|
stream.reset();
|
|
945
1320
|
|
|
946
|
-
try log.move(p2.ident(4),
|
|
947
|
-
try log.lastmiss();
|
|
1321
|
+
try log.move(.{ p2.ident(4), M1.Tackle, p1.ident(5) });
|
|
1322
|
+
try log.lastmiss(.{});
|
|
948
1323
|
try expectLog1(
|
|
949
1324
|
&.{
|
|
950
1325
|
N(ArgType.Move),
|
|
951
1326
|
0b1100,
|
|
952
|
-
N(
|
|
1327
|
+
N(M1.Tackle),
|
|
953
1328
|
0b0101,
|
|
954
1329
|
N(Move.None),
|
|
955
1330
|
N(ArgType.LastMiss),
|
|
@@ -965,11 +1340,11 @@ test "|switch|" {
|
|
|
965
1340
|
snorlax.hp = 200;
|
|
966
1341
|
snorlax.stats.hp = 400;
|
|
967
1342
|
snorlax.status = gen1.Status.init(.PAR);
|
|
968
|
-
try log.switched(p2.ident(3), &snorlax);
|
|
1343
|
+
try log.switched(.{ p2.ident(3), &snorlax });
|
|
969
1344
|
const par = 0b1000000;
|
|
970
1345
|
var expected: []const u8 = switch (endian) {
|
|
971
|
-
.
|
|
972
|
-
.
|
|
1346
|
+
.big => &.{ N(ArgType.Switch), 0b1011, N(S1.Snorlax), 91, 0, 200, 1, 144, par },
|
|
1347
|
+
.little => &.{ N(ArgType.Switch), 0b1011, N(S1.Snorlax), 91, 200, 0, 144, 1, par },
|
|
973
1348
|
};
|
|
974
1349
|
try expectLog1(expected, buf[0..9]);
|
|
975
1350
|
stream.reset();
|
|
@@ -977,62 +1352,81 @@ test "|switch|" {
|
|
|
977
1352
|
snorlax.level = 100;
|
|
978
1353
|
snorlax.hp = 0;
|
|
979
1354
|
snorlax.status = 0;
|
|
980
|
-
try log.switched(p2.ident(3), &snorlax);
|
|
1355
|
+
try log.switched(.{ p2.ident(3), &snorlax });
|
|
981
1356
|
expected = switch (endian) {
|
|
982
|
-
.
|
|
983
|
-
.
|
|
1357
|
+
.big => &.{ N(ArgType.Switch), 0b1011, N(S1.Snorlax), 100, 0, 0, 1, 144, 0 },
|
|
1358
|
+
.little => &.{ N(ArgType.Switch), 0b1011, N(S1.Snorlax), 100, 0, 0, 144, 1, 0 },
|
|
984
1359
|
};
|
|
985
1360
|
try expectLog1(expected, buf[0..9]);
|
|
986
1361
|
stream.reset();
|
|
987
1362
|
|
|
988
1363
|
snorlax.hp = 400;
|
|
989
|
-
try log.switched(p2.ident(3), &snorlax);
|
|
1364
|
+
try log.switched(.{ p2.ident(3), &snorlax });
|
|
990
1365
|
expected = switch (endian) {
|
|
991
|
-
.
|
|
992
|
-
.
|
|
1366
|
+
.big => &.{ N(ArgType.Switch), 0b1011, N(S1.Snorlax), 100, 1, 144, 1, 144, 0 },
|
|
1367
|
+
.little => &.{ N(ArgType.Switch), 0b1011, N(S1.Snorlax), 100, 144, 1, 144, 1, 0 },
|
|
993
1368
|
};
|
|
994
1369
|
try expectLog1(expected, buf[0..9]);
|
|
995
1370
|
stream.reset();
|
|
1371
|
+
|
|
1372
|
+
var blissey = gen2.helpers.Pokemon.init(.{ .species = .Blissey, .moves = &.{.Splash} });
|
|
1373
|
+
blissey.level = 91;
|
|
1374
|
+
blissey.hp = 200;
|
|
1375
|
+
blissey.stats.hp = 400;
|
|
1376
|
+
blissey.status = gen2.Status.init(.PAR);
|
|
1377
|
+
try log.switched(.{ p2.ident(3), &blissey });
|
|
1378
|
+
expected = &(.{
|
|
1379
|
+
N(ArgType.Switch),
|
|
1380
|
+
0b1011,
|
|
1381
|
+
N(S2.Blissey),
|
|
1382
|
+
N(gen2.Gender.Female),
|
|
1383
|
+
91,
|
|
1384
|
+
} ++ switch (endian) {
|
|
1385
|
+
.big => .{ 0, 200, 1, 144, par },
|
|
1386
|
+
.little => .{ 200, 0, 144, 1, par },
|
|
1387
|
+
});
|
|
1388
|
+
try expectLog2(expected, buf[0..10]);
|
|
1389
|
+
stream.reset();
|
|
996
1390
|
}
|
|
997
1391
|
|
|
998
1392
|
test "|cant|" {
|
|
999
|
-
try log.cant(p2.ident(6), .Bound);
|
|
1393
|
+
try log.cant(.{ p2.ident(6), .Bound });
|
|
1000
1394
|
try expectLog1(&.{ N(ArgType.Cant), 0b1110, N(Cant.Bound) }, buf[0..3]);
|
|
1001
1395
|
stream.reset();
|
|
1002
1396
|
|
|
1003
|
-
try log.
|
|
1004
|
-
try expectLog1(&.{ N(ArgType.Cant), 2, N(Cant.Disable), N(
|
|
1397
|
+
try log.cant(.{ p1.ident(2), .Disable, M1.Earthquake });
|
|
1398
|
+
try expectLog1(&.{ N(ArgType.Cant), 2, N(Cant.Disable), N(M1.Earthquake) }, buf[0..4]);
|
|
1005
1399
|
stream.reset();
|
|
1006
1400
|
}
|
|
1007
1401
|
|
|
1008
1402
|
test "|faint|" {
|
|
1009
|
-
try log.faint(p2.ident(2), false);
|
|
1403
|
+
try log.faint(.{ p2.ident(2), false });
|
|
1010
1404
|
try expectLog1(&.{ N(ArgType.Faint), 0b1010 }, buf[0..2]);
|
|
1011
1405
|
stream.reset();
|
|
1012
1406
|
|
|
1013
|
-
try log.faint(p2.ident(2), true);
|
|
1407
|
+
try log.faint(.{ p2.ident(2), true });
|
|
1014
1408
|
try expectLog1(&.{ N(ArgType.Faint), 0b1010, N(ArgType.None) }, buf[0..3]);
|
|
1015
1409
|
stream.reset();
|
|
1016
1410
|
}
|
|
1017
1411
|
|
|
1018
1412
|
test "|turn|" {
|
|
1019
|
-
try log.turn(42);
|
|
1020
|
-
|
|
1021
|
-
.
|
|
1022
|
-
.
|
|
1413
|
+
try log.turn(.{42});
|
|
1414
|
+
const expected = switch (endian) {
|
|
1415
|
+
.big => &.{ N(ArgType.Turn), 0, 42, N(ArgType.None) },
|
|
1416
|
+
.little => &.{ N(ArgType.Turn), 42, 0, N(ArgType.None) },
|
|
1023
1417
|
};
|
|
1024
1418
|
try expectLog1(expected, buf[0..4]);
|
|
1025
1419
|
stream.reset();
|
|
1026
1420
|
}
|
|
1027
1421
|
|
|
1028
1422
|
test "|win|" {
|
|
1029
|
-
try log.win(.P2);
|
|
1423
|
+
try log.win(.{.P2});
|
|
1030
1424
|
try expectLog1(&.{ N(ArgType.Win), 1, N(ArgType.None) }, buf[0..3]);
|
|
1031
1425
|
stream.reset();
|
|
1032
1426
|
}
|
|
1033
1427
|
|
|
1034
1428
|
test "|tie|" {
|
|
1035
|
-
try log.tie();
|
|
1429
|
+
try log.tie(.{});
|
|
1036
1430
|
try expectLog1(&.{ N(ArgType.Tie), N(ArgType.None) }, buf[0..2]);
|
|
1037
1431
|
stream.reset();
|
|
1038
1432
|
}
|
|
@@ -1041,10 +1435,10 @@ test "|-damage|" {
|
|
|
1041
1435
|
var chansey = gen1.helpers.Pokemon.init(.{ .species = .Chansey, .moves = &.{.Splash} });
|
|
1042
1436
|
chansey.hp = 612;
|
|
1043
1437
|
chansey.status = gen1.Status.slp(1);
|
|
1044
|
-
try log.damage(p2.ident(2), &chansey, .None);
|
|
1438
|
+
try log.damage(.{ p2.ident(2), &chansey, .None });
|
|
1045
1439
|
var expected: []const u8 = switch (endian) {
|
|
1046
|
-
.
|
|
1047
|
-
.
|
|
1440
|
+
.big => &.{ N(ArgType.Damage), 0b1010, 2, 100, 2, 191, 1, N(Damage.None) },
|
|
1441
|
+
.little => &.{ N(ArgType.Damage), 0b1010, 100, 2, 191, 2, 1, N(Damage.None) },
|
|
1048
1442
|
};
|
|
1049
1443
|
try expectLog1(expected, buf[0..8]);
|
|
1050
1444
|
stream.reset();
|
|
@@ -1052,19 +1446,19 @@ test "|-damage|" {
|
|
|
1052
1446
|
chansey.hp = 100;
|
|
1053
1447
|
chansey.stats.hp = 256;
|
|
1054
1448
|
chansey.status = 0;
|
|
1055
|
-
try log.damage(p2.ident(2), &chansey, .Confusion);
|
|
1449
|
+
try log.damage(.{ p2.ident(2), &chansey, .Confusion });
|
|
1056
1450
|
expected = switch (endian) {
|
|
1057
|
-
.
|
|
1058
|
-
.
|
|
1451
|
+
.big => &.{ N(ArgType.Damage), 0b1010, 0, 100, 1, 0, 0, N(Damage.Confusion) },
|
|
1452
|
+
.little => &.{ N(ArgType.Damage), 0b1010, 100, 0, 0, 1, 0, N(Damage.Confusion) },
|
|
1059
1453
|
};
|
|
1060
1454
|
try expectLog1(expected, buf[0..8]);
|
|
1061
1455
|
stream.reset();
|
|
1062
1456
|
|
|
1063
1457
|
chansey.status = gen1.Status.init(.PSN);
|
|
1064
|
-
try log.
|
|
1458
|
+
try log.damage(.{ p2.ident(2), &chansey, .RecoilOf, p1.ident(1) });
|
|
1065
1459
|
expected = switch (endian) {
|
|
1066
|
-
.
|
|
1067
|
-
.
|
|
1460
|
+
.big => &.{ N(ArgType.Damage), 0b1010, 0, 100, 1, 0, 0b1000, N(Damage.RecoilOf), 1 },
|
|
1461
|
+
.little => &.{ N(ArgType.Damage), 0b1010, 100, 0, 0, 1, 0b1000, N(Damage.RecoilOf), 1 },
|
|
1068
1462
|
};
|
|
1069
1463
|
try expectLog1(expected, buf[0..9]);
|
|
1070
1464
|
stream.reset();
|
|
@@ -1074,10 +1468,10 @@ test "|-heal|" {
|
|
|
1074
1468
|
var chansey = gen1.helpers.Pokemon.init(.{ .species = .Chansey, .moves = &.{.Splash} });
|
|
1075
1469
|
chansey.hp = 612;
|
|
1076
1470
|
chansey.status = gen1.Status.slp(1);
|
|
1077
|
-
try log.heal(p2.ident(2), &chansey, .None);
|
|
1471
|
+
try log.heal(.{ p2.ident(2), &chansey, .None });
|
|
1078
1472
|
var expected: []const u8 = switch (endian) {
|
|
1079
|
-
.
|
|
1080
|
-
.
|
|
1473
|
+
.big => &.{ N(ArgType.Heal), 0b1010, 2, 100, 2, 191, 1, N(Heal.None) },
|
|
1474
|
+
.little => &.{ N(ArgType.Heal), 0b1010, 100, 2, 191, 2, 1, N(Heal.None) },
|
|
1081
1475
|
};
|
|
1082
1476
|
try expectLog1(expected, buf[0..8]);
|
|
1083
1477
|
stream.reset();
|
|
@@ -1085,46 +1479,46 @@ test "|-heal|" {
|
|
|
1085
1479
|
chansey.hp = 100;
|
|
1086
1480
|
chansey.stats.hp = 256;
|
|
1087
1481
|
chansey.status = 0;
|
|
1088
|
-
try log.heal(p2.ident(2), &chansey, .Silent);
|
|
1482
|
+
try log.heal(.{ p2.ident(2), &chansey, .Silent });
|
|
1089
1483
|
expected = switch (endian) {
|
|
1090
|
-
.
|
|
1091
|
-
.
|
|
1484
|
+
.big => &.{ N(ArgType.Heal), 0b1010, 0, 100, 1, 0, 0, N(Heal.Silent) },
|
|
1485
|
+
.little => &.{ N(ArgType.Heal), 0b1010, 100, 0, 0, 1, 0, N(Heal.Silent) },
|
|
1092
1486
|
};
|
|
1093
1487
|
try expectLog1(expected, buf[0..8]);
|
|
1094
1488
|
stream.reset();
|
|
1095
1489
|
|
|
1096
|
-
try log.
|
|
1490
|
+
try log.heal(.{ p2.ident(2), &chansey, .Drain, p1.ident(1) });
|
|
1097
1491
|
expected = switch (endian) {
|
|
1098
|
-
.
|
|
1099
|
-
.
|
|
1492
|
+
.big => &.{ N(ArgType.Heal), 0b1010, 0, 100, 1, 0, 0, N(Heal.Drain), 1 },
|
|
1493
|
+
.little => &.{ N(ArgType.Heal), 0b1010, 100, 0, 0, 1, 0, N(Heal.Drain), 1 },
|
|
1100
1494
|
};
|
|
1101
1495
|
try expectLog1(expected, buf[0..9]);
|
|
1102
1496
|
stream.reset();
|
|
1103
1497
|
}
|
|
1104
1498
|
|
|
1105
1499
|
test "|-status|" {
|
|
1106
|
-
try log.status(p2.ident(6), gen1.Status.init(.BRN), .None);
|
|
1500
|
+
try log.status(.{ p2.ident(6), gen1.Status.init(.BRN), .None });
|
|
1107
1501
|
try expectLog1(&.{ N(ArgType.Status), 0b1110, 0b10000, N(Status.None) }, buf[0..4]);
|
|
1108
1502
|
stream.reset();
|
|
1109
1503
|
|
|
1110
|
-
try log.status(p2.ident(2), gen1.Status.init(.PSN), .Silent);
|
|
1504
|
+
try log.status(.{ p2.ident(2), gen1.Status.init(.PSN), .Silent });
|
|
1111
1505
|
try expectLog1(&.{ N(ArgType.Status), 0b1010, 0b1000, N(Status.Silent) }, buf[0..4]);
|
|
1112
1506
|
stream.reset();
|
|
1113
1507
|
|
|
1114
|
-
try log.
|
|
1508
|
+
try log.status(.{ p1.ident(1), gen1.Status.init(.PAR), .From, M1.BodySlam });
|
|
1115
1509
|
try expectLog1(
|
|
1116
|
-
&.{ N(ArgType.Status), 0b0001, 0b1000000, N(Status.From), N(
|
|
1510
|
+
&.{ N(ArgType.Status), 0b0001, 0b1000000, N(Status.From), N(M1.BodySlam) },
|
|
1117
1511
|
buf[0..5],
|
|
1118
1512
|
);
|
|
1119
1513
|
stream.reset();
|
|
1120
1514
|
}
|
|
1121
1515
|
|
|
1122
1516
|
test "|-curestatus|" {
|
|
1123
|
-
try log.curestatus(p2.ident(6), gen1.Status.slp(7), .Message);
|
|
1517
|
+
try log.curestatus(.{ p2.ident(6), gen1.Status.slp(7), .Message });
|
|
1124
1518
|
try expectLog1(&.{ N(ArgType.CureStatus), 0b1110, 0b111, N(CureStatus.Message) }, buf[0..4]);
|
|
1125
1519
|
stream.reset();
|
|
1126
1520
|
|
|
1127
|
-
try log.curestatus(p1.ident(2), gen1.Status.TOX, .Silent);
|
|
1521
|
+
try log.curestatus(.{ p1.ident(2), gen1.Status.TOX, .Silent });
|
|
1128
1522
|
try expectLog1(&.{
|
|
1129
1523
|
N(ArgType.CureStatus),
|
|
1130
1524
|
0b0010,
|
|
@@ -1135,163 +1529,306 @@ test "|-curestatus|" {
|
|
|
1135
1529
|
}
|
|
1136
1530
|
|
|
1137
1531
|
test "|-boost|" {
|
|
1138
|
-
try log.boost(p2.ident(6), .Speed, 2);
|
|
1532
|
+
try log.boost(.{ p2.ident(6), .Speed, 2 });
|
|
1139
1533
|
try expectLog1(&.{ N(ArgType.Boost), 0b1110, N(Boost.Speed), 8 }, buf[0..4]);
|
|
1140
1534
|
stream.reset();
|
|
1141
1535
|
|
|
1142
|
-
try log.boost(p1.ident(2), .Rage, 1);
|
|
1536
|
+
try log.boost(.{ p1.ident(2), .Rage, 1 });
|
|
1143
1537
|
try expectLog1(&.{ N(ArgType.Boost), 0b0010, N(Boost.Rage), 7 }, buf[0..4]);
|
|
1144
1538
|
stream.reset();
|
|
1145
1539
|
|
|
1146
|
-
try log.boost(p2.ident(3), .Defense, -2);
|
|
1540
|
+
try log.boost(.{ p2.ident(3), .Defense, -2 });
|
|
1147
1541
|
try expectLog1(&.{ N(ArgType.Boost), 0b1011, N(Boost.Defense), 4 }, buf[0..4]);
|
|
1148
1542
|
stream.reset();
|
|
1149
1543
|
}
|
|
1150
1544
|
|
|
1151
1545
|
test "|-clearallboost|" {
|
|
1152
|
-
try log.clearallboost();
|
|
1546
|
+
try log.clearallboost(.{});
|
|
1153
1547
|
try expectLog1(&.{N(ArgType.ClearAllBoost)}, buf[0..1]);
|
|
1154
1548
|
stream.reset();
|
|
1155
1549
|
}
|
|
1156
1550
|
|
|
1157
1551
|
test "|-fail|" {
|
|
1158
|
-
try log.fail(p2.ident(6), .None);
|
|
1552
|
+
try log.fail(.{ p2.ident(6), .None });
|
|
1159
1553
|
try expectLog1(&.{ N(ArgType.Fail), 0b1110, N(Fail.None) }, buf[0..3]);
|
|
1160
1554
|
stream.reset();
|
|
1161
1555
|
|
|
1162
|
-
try log.fail(p2.ident(6), .Sleep);
|
|
1556
|
+
try log.fail(.{ p2.ident(6), .Sleep });
|
|
1163
1557
|
try expectLog1(&.{ N(ArgType.Fail), 0b1110, N(Fail.Sleep) }, buf[0..3]);
|
|
1164
1558
|
stream.reset();
|
|
1165
1559
|
|
|
1166
|
-
try log.fail(p2.ident(6), .Substitute);
|
|
1560
|
+
try log.fail(.{ p2.ident(6), .Substitute });
|
|
1167
1561
|
try expectLog1(&.{ N(ArgType.Fail), 0b1110, N(Fail.Substitute) }, buf[0..3]);
|
|
1168
1562
|
stream.reset();
|
|
1169
1563
|
|
|
1170
|
-
try log.fail(p2.ident(6), .Weak);
|
|
1564
|
+
try log.fail(.{ p2.ident(6), .Weak });
|
|
1171
1565
|
try expectLog1(&.{ N(ArgType.Fail), 0b1110, N(Fail.Weak) }, buf[0..3]);
|
|
1172
1566
|
stream.reset();
|
|
1173
1567
|
}
|
|
1174
1568
|
|
|
1175
1569
|
test "|-miss|" {
|
|
1176
|
-
try log.miss(p2.ident(4));
|
|
1570
|
+
try log.miss(.{p2.ident(4)});
|
|
1177
1571
|
try expectLog1(&.{ N(ArgType.Miss), 0b1100 }, buf[0..2]);
|
|
1178
1572
|
stream.reset();
|
|
1179
1573
|
}
|
|
1180
1574
|
test "|-hitcount|" {
|
|
1181
|
-
try log.hitcount(p2.ident(1), 5);
|
|
1575
|
+
try log.hitcount(.{ p2.ident(1), 5 });
|
|
1182
1576
|
try expectLog1(&.{ N(ArgType.HitCount), 0b1001, 5 }, buf[0..3]);
|
|
1183
1577
|
stream.reset();
|
|
1184
1578
|
}
|
|
1185
1579
|
|
|
1186
1580
|
test "|-prepare|" {
|
|
1187
|
-
try log.prepare(p2.ident(2),
|
|
1188
|
-
try expectLog1(&.{ N(ArgType.Prepare), 0b1010, N(
|
|
1581
|
+
try log.prepare(.{ p2.ident(2), M1.Dig });
|
|
1582
|
+
try expectLog1(&.{ N(ArgType.Prepare), 0b1010, N(M1.Dig) }, buf[0..3]);
|
|
1189
1583
|
stream.reset();
|
|
1190
1584
|
}
|
|
1191
1585
|
|
|
1192
1586
|
test "|-mustrecharge|" {
|
|
1193
|
-
try log.mustrecharge(p1.ident(6));
|
|
1587
|
+
try log.mustrecharge(.{p1.ident(6)});
|
|
1194
1588
|
try expectLog1(&.{ N(ArgType.MustRecharge), 0b0110 }, buf[0..2]);
|
|
1195
1589
|
stream.reset();
|
|
1196
1590
|
}
|
|
1197
1591
|
|
|
1198
1592
|
test "|-activate|" {
|
|
1199
|
-
try log.activate(p1.ident(2), .Struggle);
|
|
1593
|
+
try log.activate(.{ p1.ident(2), .Struggle });
|
|
1200
1594
|
try expectLog1(&.{ N(ArgType.Activate), 0b0010, N(Activate.Struggle) }, buf[0..3]);
|
|
1201
1595
|
stream.reset();
|
|
1202
1596
|
|
|
1203
|
-
try log.activate(p2.ident(4), .Mist);
|
|
1597
|
+
try log.activate(.{ p2.ident(4), .Mist });
|
|
1204
1598
|
try expectLog1(&.{ N(ArgType.Activate), 0b1100, N(Activate.Mist) }, buf[0..3]);
|
|
1205
1599
|
stream.reset();
|
|
1206
1600
|
|
|
1207
|
-
try log.activate(p2.ident(6), .Substitute);
|
|
1601
|
+
try log.activate(.{ p2.ident(6), .Substitute });
|
|
1208
1602
|
try expectLog1(&.{ N(ArgType.Activate), 0b1110, N(Activate.Substitute) }, buf[0..3]);
|
|
1209
1603
|
stream.reset();
|
|
1210
1604
|
|
|
1211
|
-
try log.activate(p1.ident(2), .Splash);
|
|
1605
|
+
try log.activate(.{ p1.ident(2), .Splash });
|
|
1212
1606
|
try expectLog1(&.{ N(ArgType.Activate), 0b0010, N(Activate.Splash) }, buf[0..3]);
|
|
1213
1607
|
stream.reset();
|
|
1608
|
+
|
|
1609
|
+
try log.activate(.{ p1.ident(4), .SubstituteBlock, M2.Spite });
|
|
1610
|
+
try expectLog1(&.{
|
|
1611
|
+
N(ArgType.Activate),
|
|
1612
|
+
0b0100,
|
|
1613
|
+
N(Activate.SubstituteBlock),
|
|
1614
|
+
N(M2.Spite),
|
|
1615
|
+
}, buf[0..4]);
|
|
1616
|
+
stream.reset();
|
|
1617
|
+
|
|
1618
|
+
try log.activate(.{ p1.ident(3), .Magnitude, 5 });
|
|
1619
|
+
try expectLog1(&.{ N(ArgType.Activate), 0b0011, N(Activate.Magnitude), 5 }, buf[0..4]);
|
|
1620
|
+
stream.reset();
|
|
1214
1621
|
}
|
|
1215
1622
|
|
|
1216
1623
|
test "|-fieldactivate|" {
|
|
1217
|
-
try log.fieldactivate();
|
|
1624
|
+
try log.fieldactivate(.{});
|
|
1218
1625
|
try expectLog1(&.{N(ArgType.FieldActivate)}, buf[0..1]);
|
|
1219
1626
|
stream.reset();
|
|
1220
1627
|
}
|
|
1221
1628
|
|
|
1222
1629
|
test "|-start|" {
|
|
1223
|
-
try log.start(p2.ident(6), .Bide);
|
|
1630
|
+
try log.start(.{ p2.ident(6), .Bide });
|
|
1224
1631
|
try expectLog1(&.{ N(ArgType.Start), 0b1110, N(Start.Bide) }, buf[0..3]);
|
|
1225
1632
|
stream.reset();
|
|
1226
1633
|
|
|
1227
|
-
try log.start(p1.ident(2), .ConfusionSilent);
|
|
1634
|
+
try log.start(.{ p1.ident(2), .ConfusionSilent });
|
|
1228
1635
|
try expectLog1(&.{ N(ArgType.Start), 0b0010, N(Start.ConfusionSilent) }, buf[0..3]);
|
|
1229
1636
|
stream.reset();
|
|
1230
1637
|
|
|
1231
|
-
try log.
|
|
1638
|
+
try log.start(.{
|
|
1639
|
+
p2.ident(6),
|
|
1640
|
+
.TypeChange,
|
|
1641
|
+
gen1.Types{ .type1 = .Fire, .type2 = .Fire },
|
|
1642
|
+
p2.ident(5),
|
|
1643
|
+
});
|
|
1232
1644
|
try expectLog1(
|
|
1233
1645
|
&.{ N(ArgType.Start), 0b1110, N(Start.TypeChange), 0b1000_1000, 0b1101 },
|
|
1234
1646
|
buf[0..5],
|
|
1235
1647
|
);
|
|
1236
1648
|
stream.reset();
|
|
1237
1649
|
|
|
1238
|
-
try log.
|
|
1650
|
+
try log.start(.{
|
|
1651
|
+
p1.ident(2),
|
|
1652
|
+
.TypeChange,
|
|
1653
|
+
gen1.Types{ .type1 = .Bug, .type2 = .Poison },
|
|
1654
|
+
p2.ident(4),
|
|
1655
|
+
});
|
|
1239
1656
|
try expectLog1(
|
|
1240
1657
|
&.{ N(ArgType.Start), 0b0010, N(Start.TypeChange), 0b0011_0110, 0b1100 },
|
|
1241
1658
|
buf[0..5],
|
|
1242
1659
|
);
|
|
1243
1660
|
stream.reset();
|
|
1244
1661
|
|
|
1245
|
-
try log.
|
|
1246
|
-
try expectLog1(&.{ N(ArgType.Start), 0b0010, N(Start.Disable), N(
|
|
1662
|
+
try log.start(.{ p1.ident(2), .Disable, M1.Surf });
|
|
1663
|
+
try expectLog1(&.{ N(ArgType.Start), 0b0010, N(Start.Disable), N(M1.Surf) }, buf[0..4]);
|
|
1247
1664
|
stream.reset();
|
|
1248
1665
|
|
|
1249
|
-
try log.
|
|
1250
|
-
try expectLog1(&.{ N(ArgType.Start), 0b0010, N(Start.Mimic), N(
|
|
1666
|
+
try log.start(.{ p1.ident(2), .Mimic, M1.Surf });
|
|
1667
|
+
try expectLog1(&.{ N(ArgType.Start), 0b0010, N(Start.Mimic), N(M1.Surf) }, buf[0..4]);
|
|
1251
1668
|
stream.reset();
|
|
1252
1669
|
}
|
|
1253
1670
|
|
|
1254
1671
|
test "|-end|" {
|
|
1255
|
-
try log.end(p2.ident(6), .Bide);
|
|
1672
|
+
try log.end(.{ p2.ident(6), .Bide });
|
|
1256
1673
|
try expectLog1(&.{ N(ArgType.End), 0b1110, N(End.Bide) }, buf[0..3]);
|
|
1257
1674
|
stream.reset();
|
|
1258
1675
|
|
|
1259
|
-
try log.end(p1.ident(2), .ConfusionSilent);
|
|
1676
|
+
try log.end(.{ p1.ident(2), .ConfusionSilent });
|
|
1260
1677
|
try expectLog1(&.{ N(ArgType.End), 0b0010, N(End.ConfusionSilent) }, buf[0..3]);
|
|
1261
1678
|
stream.reset();
|
|
1262
1679
|
}
|
|
1263
1680
|
|
|
1264
1681
|
test "|-ohko|" {
|
|
1265
|
-
try log.ohko();
|
|
1682
|
+
try log.ohko(.{});
|
|
1266
1683
|
try expectLog1(&.{N(ArgType.OHKO)}, buf[0..1]);
|
|
1267
1684
|
stream.reset();
|
|
1268
1685
|
}
|
|
1686
|
+
|
|
1269
1687
|
test "|-crit|" {
|
|
1270
|
-
try log.crit(p2.ident(5));
|
|
1688
|
+
try log.crit(.{p2.ident(5)});
|
|
1271
1689
|
try expectLog1(&.{ N(ArgType.Crit), 0b1101 }, buf[0..2]);
|
|
1272
1690
|
stream.reset();
|
|
1273
1691
|
}
|
|
1692
|
+
|
|
1274
1693
|
test "|-supereffective|" {
|
|
1275
|
-
try log.supereffective(p1.ident(1));
|
|
1694
|
+
try log.supereffective(.{p1.ident(1)});
|
|
1276
1695
|
try expectLog1(&.{ N(ArgType.SuperEffective), 0b0001 }, buf[0..2]);
|
|
1277
1696
|
stream.reset();
|
|
1278
1697
|
}
|
|
1698
|
+
|
|
1279
1699
|
test "|-resisted|" {
|
|
1280
|
-
try log.resisted(p2.ident(2));
|
|
1700
|
+
try log.resisted(.{p2.ident(2)});
|
|
1281
1701
|
try expectLog1(&.{ N(ArgType.Resisted), 0b1010 }, buf[0..2]);
|
|
1282
1702
|
stream.reset();
|
|
1283
1703
|
}
|
|
1704
|
+
|
|
1284
1705
|
test "|-immune|" {
|
|
1285
|
-
try log.immune(p1.ident(3), .None);
|
|
1706
|
+
try log.immune(.{ p1.ident(3), .None });
|
|
1286
1707
|
try expectLog1(&.{ N(ArgType.Immune), 0b0011, N(Immune.None) }, buf[0..3]);
|
|
1287
1708
|
stream.reset();
|
|
1288
1709
|
|
|
1289
|
-
try log.immune(p2.ident(2), .OHKO);
|
|
1710
|
+
try log.immune(.{ p2.ident(2), .OHKO });
|
|
1290
1711
|
try expectLog1(&.{ N(ArgType.Immune), 0b1010, N(Immune.OHKO) }, buf[0..3]);
|
|
1291
1712
|
stream.reset();
|
|
1292
1713
|
}
|
|
1714
|
+
|
|
1293
1715
|
test "|-transform|" {
|
|
1294
|
-
try log.transform(p2.ident(4), p1.ident(5));
|
|
1716
|
+
try log.transform(.{ p2.ident(4), p1.ident(5) });
|
|
1295
1717
|
try expectLog1(&.{ N(ArgType.Transform), 0b1100, 0b0101 }, buf[0..3]);
|
|
1296
1718
|
stream.reset();
|
|
1297
1719
|
}
|
|
1720
|
+
|
|
1721
|
+
test "|drag|" {
|
|
1722
|
+
var blissey = gen2.helpers.Pokemon.init(.{ .species = .Blissey, .moves = &.{.Splash} });
|
|
1723
|
+
blissey.level = 91;
|
|
1724
|
+
blissey.hp = 200;
|
|
1725
|
+
blissey.stats.hp = 400;
|
|
1726
|
+
blissey.status = gen2.Status.init(.PAR);
|
|
1727
|
+
try log.drag(.{ p2.ident(3), &blissey });
|
|
1728
|
+
const par = 0b1000000;
|
|
1729
|
+
const expected = &(.{
|
|
1730
|
+
N(ArgType.Drag),
|
|
1731
|
+
0b1011,
|
|
1732
|
+
N(S2.Blissey),
|
|
1733
|
+
N(gen2.Gender.Female),
|
|
1734
|
+
91,
|
|
1735
|
+
} ++ switch (endian) {
|
|
1736
|
+
.big => .{ 0, 200, 1, 144, par },
|
|
1737
|
+
.little => .{ 200, 0, 144, 1, par },
|
|
1738
|
+
});
|
|
1739
|
+
try expectLog2(expected, buf[0..10]);
|
|
1740
|
+
stream.reset();
|
|
1741
|
+
}
|
|
1742
|
+
|
|
1743
|
+
test "|-item|" {
|
|
1744
|
+
try log.item(.{ p2.ident(2), I2.GoldBerry, p1.ident(4) });
|
|
1745
|
+
try expectLog2(&.{ N(ArgType.Item), 0b1010, N(I2.GoldBerry), 0b0100 }, buf[0..4]);
|
|
1746
|
+
stream.reset();
|
|
1747
|
+
}
|
|
1748
|
+
|
|
1749
|
+
test "|-enditem|" {
|
|
1750
|
+
try log.enditem(.{ p1.ident(1), I2.BerserkGene, .None });
|
|
1751
|
+
try expectLog2(&.{ N(ArgType.EndItem), 0b0001, N(I2.BerserkGene), N(EndItem.None) }, buf[0..4]);
|
|
1752
|
+
stream.reset();
|
|
1753
|
+
|
|
1754
|
+
try log.enditem(.{ p2.ident(4), I2.PRZCureBerry, .Eat });
|
|
1755
|
+
try expectLog2(&.{ N(ArgType.EndItem), 0b1100, N(I2.PRZCureBerry), N(EndItem.Eat) }, buf[0..4]);
|
|
1756
|
+
stream.reset();
|
|
1757
|
+
}
|
|
1758
|
+
|
|
1759
|
+
test "|-cureteam|" {
|
|
1760
|
+
try log.cureteam(.{p2.ident(5)});
|
|
1761
|
+
try expectLog2(&.{ N(ArgType.CureTeam), 0b1101 }, buf[0..2]);
|
|
1762
|
+
stream.reset();
|
|
1763
|
+
}
|
|
1764
|
+
|
|
1765
|
+
test "|-sethp|" {
|
|
1766
|
+
var blissey = gen2.helpers.Pokemon.init(.{ .species = .Blissey, .moves = &.{.PainSplit} });
|
|
1767
|
+
blissey.hp = 612;
|
|
1768
|
+
try log.sethp(.{ p2.ident(2), &blissey, .Silent });
|
|
1769
|
+
const expected: []const u8 = switch (endian) {
|
|
1770
|
+
.big => &.{ N(ArgType.SetHP), 0b1010, 2, 100, 2, 201, 0, N(SetHP.Silent) },
|
|
1771
|
+
.little => &.{ N(ArgType.SetHP), 0b1010, 100, 2, 201, 2, 0, N(SetHP.Silent) },
|
|
1772
|
+
};
|
|
1773
|
+
try expectLog2(expected, buf[0..8]);
|
|
1774
|
+
stream.reset();
|
|
1775
|
+
}
|
|
1776
|
+
|
|
1777
|
+
test "|-setboost|" {
|
|
1778
|
+
try log.setboost(.{ p2.ident(6), 6 });
|
|
1779
|
+
try expectLog2(&.{ N(ArgType.SetBoost), 0b1110, 12 }, buf[0..3]);
|
|
1780
|
+
stream.reset();
|
|
1781
|
+
|
|
1782
|
+
try log.setboost(.{ p2.ident(3), 2 });
|
|
1783
|
+
try expectLog2(&.{ N(ArgType.SetBoost), 0b1011, 8 }, buf[0..3]);
|
|
1784
|
+
stream.reset();
|
|
1785
|
+
}
|
|
1786
|
+
|
|
1787
|
+
test "|-copyboost|" {
|
|
1788
|
+
try log.copyboost(.{ p2.ident(3), p1.ident(6) });
|
|
1789
|
+
try expectLog2(&.{ N(ArgType.CopyBoost), 0b1011, 0b0110 }, buf[0..3]);
|
|
1790
|
+
stream.reset();
|
|
1791
|
+
}
|
|
1792
|
+
|
|
1793
|
+
test "|-sidestart|" {
|
|
1794
|
+
try log.sidestart(.{ .P2, .Reflect });
|
|
1795
|
+
try expectLog2(&.{ N(ArgType.SideStart), 1, N(Side.Reflect) }, buf[0..3]);
|
|
1796
|
+
stream.reset();
|
|
1797
|
+
}
|
|
1798
|
+
|
|
1799
|
+
test "|-sideend|" {
|
|
1800
|
+
try log.sideend(.{ .P2, .LightScreen });
|
|
1801
|
+
try expectLog2(&.{ N(ArgType.SideEnd), 1, N(Side.LightScreen) }, buf[0..3]);
|
|
1802
|
+
stream.reset();
|
|
1803
|
+
|
|
1804
|
+
try log.sideend(.{ .P1, .Spikes, p1.ident(3) });
|
|
1805
|
+
try expectLog2(&.{
|
|
1806
|
+
N(ArgType.SideEnd),
|
|
1807
|
+
0,
|
|
1808
|
+
N(Side.Spikes),
|
|
1809
|
+
0b0011,
|
|
1810
|
+
}, buf[0..4]);
|
|
1811
|
+
stream.reset();
|
|
1812
|
+
}
|
|
1813
|
+
|
|
1814
|
+
test "|-singlemove|" {
|
|
1815
|
+
try log.singlemove(.{ p2.ident(2), M2.DestinyBond });
|
|
1816
|
+
try expectLog2(&.{ N(ArgType.SingleMove), 0b1010, N(M2.DestinyBond) }, buf[0..3]);
|
|
1817
|
+
stream.reset();
|
|
1818
|
+
}
|
|
1819
|
+
|
|
1820
|
+
test "|-singleturn|" {
|
|
1821
|
+
try log.singleturn(.{ p1.ident(3), M2.Protect });
|
|
1822
|
+
try expectLog2(&.{ N(ArgType.SingleTurn), 0b0011, N(M2.Protect) }, buf[0..3]);
|
|
1823
|
+
stream.reset();
|
|
1824
|
+
}
|
|
1825
|
+
|
|
1826
|
+
test "|-weather|" {
|
|
1827
|
+
try log.weather(.{ W2.Rain, .Upkeep });
|
|
1828
|
+
try expectLog2(&.{ N(ArgType.Weather), N(W2.Rain), N(Weather.Upkeep) }, buf[0..3]);
|
|
1829
|
+
stream.reset();
|
|
1830
|
+
|
|
1831
|
+
try log.weather(.{ W2.None, .None });
|
|
1832
|
+
try expectLog2(&.{ N(ArgType.Weather), N(W2.None), N(Weather.None) }, buf[0..3]);
|
|
1833
|
+
stream.reset();
|
|
1834
|
+
}
|