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