@pkmn/engine 0.1.0-dev.d97c6e03 → 0.1.0-dev.dc33f678
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/README.md +67 -56
- package/build/pkg/addon.d.ts +1 -1
- package/build/pkg/addon.js +7 -6
- 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 +2 -2
- 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 +15 -12
- package/build/pkg/index.js.map +1 -1
- package/build/pkg/protocol.d.ts +4 -2
- package/build/pkg/protocol.js +60 -39
- package/build/pkg/protocol.js.map +1 -1
- package/build/test/display.js +29 -12
- package/build/test/display.js.map +1 -1
- package/build.zig +92 -68
- package/package.json +40 -21
- package/src/bin/install-pkmn-engine +11 -6
- package/src/lib/binding/node.zig +46 -141
- package/src/lib/binding/wasm.zig +5 -3
- package/src/lib/common/battle.zig +17 -0
- package/src/lib/common/data.zig +15 -27
- 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 +771 -245
- package/src/lib/common/rational.zig +353 -0
- package/src/lib/common/rng.zig +15 -15
- package/src/lib/common/util.zig +12 -0
- package/src/lib/gen1/README.md +285 -182
- package/src/lib/gen1/calc.zig +426 -0
- package/src/lib/gen1/chance.zig +1060 -0
- package/src/lib/gen1/data/moves.zig +192 -180
- package/src/lib/gen1/data/species.zig +2 -2
- package/src/lib/gen1/data/types.zig +5 -5
- package/src/lib/gen1/data.zig +79 -65
- package/src/lib/gen1/helpers.zig +577 -32
- package/src/lib/gen1/mechanics.zig +940 -614
- package/src/lib/gen2/README.md +106 -85
- package/src/lib/gen2/data/items.zig +12 -18
- package/src/lib/gen2/data/moves.zig +660 -566
- package/src/lib/gen2/data/species.zig +1 -1
- package/src/lib/gen2/data/types.zig +131 -28
- package/src/lib/gen2/data.zig +132 -84
- package/src/lib/gen2/helpers.zig +16 -22
- package/src/lib/gen2/mechanics.zig +2426 -12
- package/src/lib/pkmn.zig +65 -6
|
@@ -7,7 +7,7 @@ const options = @import("./options.zig");
|
|
|
7
7
|
const assert = std.debug.assert;
|
|
8
8
|
const print = std.debug.print;
|
|
9
9
|
|
|
10
|
-
const
|
|
10
|
+
const enabled = options.log;
|
|
11
11
|
|
|
12
12
|
const Player = data.Player;
|
|
13
13
|
const ID = data.ID;
|
|
@@ -102,6 +102,9 @@ pub const ArgType = enum(u8) {
|
|
|
102
102
|
// Gen 8
|
|
103
103
|
CanDynamax,
|
|
104
104
|
SwapSideConditions,
|
|
105
|
+
|
|
106
|
+
// Gen 9
|
|
107
|
+
Terastallize,
|
|
105
108
|
};
|
|
106
109
|
|
|
107
110
|
pub const Move = enum(u8) {
|
|
@@ -118,12 +121,19 @@ pub const Cant = enum(u8) {
|
|
|
118
121
|
Disable,
|
|
119
122
|
Recharge,
|
|
120
123
|
PP,
|
|
124
|
+
|
|
125
|
+
Attract,
|
|
121
126
|
};
|
|
122
127
|
|
|
123
128
|
pub const Heal = enum(u8) {
|
|
124
129
|
None,
|
|
125
130
|
Silent,
|
|
126
131
|
Drain,
|
|
132
|
+
|
|
133
|
+
Leftovers,
|
|
134
|
+
Berry,
|
|
135
|
+
BerryJuice,
|
|
136
|
+
GoldBerry,
|
|
127
137
|
};
|
|
128
138
|
|
|
129
139
|
pub const Damage = enum(u8) {
|
|
@@ -133,6 +143,17 @@ pub const Damage = enum(u8) {
|
|
|
133
143
|
Confusion,
|
|
134
144
|
LeechSeed,
|
|
135
145
|
RecoilOf,
|
|
146
|
+
|
|
147
|
+
Bind,
|
|
148
|
+
Wrap,
|
|
149
|
+
FireSpin,
|
|
150
|
+
Clamp,
|
|
151
|
+
Whirlpool,
|
|
152
|
+
Spikes,
|
|
153
|
+
|
|
154
|
+
Nightmare,
|
|
155
|
+
Curse,
|
|
156
|
+
Sandstorm,
|
|
136
157
|
};
|
|
137
158
|
|
|
138
159
|
pub const Status = enum(u8) {
|
|
@@ -177,6 +198,18 @@ pub const Activate = enum(u8) {
|
|
|
177
198
|
Struggle,
|
|
178
199
|
Substitute,
|
|
179
200
|
Splash,
|
|
201
|
+
|
|
202
|
+
Rage, // TODO
|
|
203
|
+
|
|
204
|
+
Attract,
|
|
205
|
+
LockOn,
|
|
206
|
+
Bind,
|
|
207
|
+
Wrap,
|
|
208
|
+
FireSpin,
|
|
209
|
+
Clamp,
|
|
210
|
+
Whirlpool,
|
|
211
|
+
|
|
212
|
+
BeatUp, // FIXME of
|
|
180
213
|
};
|
|
181
214
|
|
|
182
215
|
pub const Start = enum(u8) {
|
|
@@ -194,6 +227,19 @@ pub const Start = enum(u8) {
|
|
|
194
227
|
|
|
195
228
|
Disable,
|
|
196
229
|
Mimic,
|
|
230
|
+
|
|
231
|
+
Attract,
|
|
232
|
+
Nightmare,
|
|
233
|
+
Curse,
|
|
234
|
+
Foresight,
|
|
235
|
+
Encore,
|
|
236
|
+
FutureSight,
|
|
237
|
+
|
|
238
|
+
PerishSong0,
|
|
239
|
+
PerishSong1,
|
|
240
|
+
PerishSong2,
|
|
241
|
+
PerishSong3,
|
|
242
|
+
PerishSong3Silent,
|
|
197
243
|
};
|
|
198
244
|
|
|
199
245
|
pub const End = enum(u8) {
|
|
@@ -202,16 +248,27 @@ pub const End = enum(u8) {
|
|
|
202
248
|
Bide,
|
|
203
249
|
Substitute,
|
|
204
250
|
|
|
205
|
-
|
|
251
|
+
Nightmare,
|
|
252
|
+
Curse,
|
|
253
|
+
Foresight,
|
|
254
|
+
Encore,
|
|
255
|
+
FutureSight,
|
|
256
|
+
LeechSeed,
|
|
257
|
+
Bind,
|
|
258
|
+
Wrap,
|
|
259
|
+
FireSpin,
|
|
260
|
+
Clamp,
|
|
261
|
+
Whirlpool,
|
|
262
|
+
|
|
206
263
|
DisableSilent,
|
|
207
264
|
ConfusionSilent,
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
265
|
+
MistSilent,
|
|
266
|
+
FocusEnergySilent,
|
|
267
|
+
LeechSeedSilent,
|
|
268
|
+
ToxicSilent,
|
|
269
|
+
LightScreenSilent,
|
|
270
|
+
ReflectSilent,
|
|
271
|
+
BideSilent,
|
|
215
272
|
};
|
|
216
273
|
|
|
217
274
|
pub const Immune = enum(u8) {
|
|
@@ -219,8 +276,34 @@ pub const Immune = enum(u8) {
|
|
|
219
276
|
OHKO,
|
|
220
277
|
};
|
|
221
278
|
|
|
279
|
+
pub const EndItem = enum(u8) {
|
|
280
|
+
None,
|
|
281
|
+
Eat,
|
|
282
|
+
};
|
|
283
|
+
|
|
284
|
+
pub const SetHP = enum(u8) {
|
|
285
|
+
None,
|
|
286
|
+
Silent,
|
|
287
|
+
};
|
|
288
|
+
|
|
289
|
+
pub const Side = enum(u8) {
|
|
290
|
+
Safeguard,
|
|
291
|
+
Reflect,
|
|
292
|
+
LightScreen,
|
|
293
|
+
Spikes,
|
|
294
|
+
};
|
|
295
|
+
|
|
296
|
+
pub const Weather = enum(u8) {
|
|
297
|
+
None,
|
|
298
|
+
Upkeep,
|
|
299
|
+
};
|
|
300
|
+
|
|
301
|
+
/// Null object pattern implementation of `Log` backed by a `std.io.null_writer`.
|
|
302
|
+
/// Ignores anything sent to it, though protocol logging should additionally be turned off
|
|
303
|
+
/// entirely with `options.log`.
|
|
222
304
|
pub const NULL = Log(@TypeOf(std.io.null_writer)){ .writer = std.io.null_writer };
|
|
223
305
|
|
|
306
|
+
/// Logs protocol information to its `Writer` during a battle update when `options.log` is enabled.
|
|
224
307
|
pub fn Log(comptime Writer: type) type {
|
|
225
308
|
return struct {
|
|
226
309
|
const Self = @This();
|
|
@@ -229,92 +312,118 @@ pub fn Log(comptime Writer: type) type {
|
|
|
229
312
|
|
|
230
313
|
pub const Error = Writer.Error;
|
|
231
314
|
|
|
232
|
-
pub fn move(self: Self, source: ID, m: anytype, target: ID
|
|
233
|
-
if (!
|
|
315
|
+
pub fn move(self: Self, source: ID, m: anytype, target: ID) Error!void {
|
|
316
|
+
if (!enabled) return;
|
|
317
|
+
|
|
234
318
|
assert(m != .None);
|
|
235
319
|
try self.writer.writeAll(&.{
|
|
236
|
-
@
|
|
237
|
-
@
|
|
238
|
-
@
|
|
239
|
-
@
|
|
320
|
+
@intFromEnum(ArgType.Move),
|
|
321
|
+
@as(u8, @bitCast(source)),
|
|
322
|
+
@intFromEnum(m),
|
|
323
|
+
@as(u8, @bitCast(target)),
|
|
324
|
+
@intFromEnum(Move.None),
|
|
240
325
|
});
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
pub fn moveFrom(self: Self, source: ID, m: anytype, target: ID, from: anytype) Error!void {
|
|
329
|
+
if (!enabled) return;
|
|
330
|
+
|
|
331
|
+
assert(m != .None);
|
|
332
|
+
try self.writer.writeAll(&.{
|
|
333
|
+
@intFromEnum(ArgType.Move),
|
|
334
|
+
@as(u8, @bitCast(source)),
|
|
335
|
+
@intFromEnum(m),
|
|
336
|
+
@as(u8, @bitCast(target)),
|
|
252
337
|
});
|
|
338
|
+
try self.writer.writeAll(if (@intFromEnum(from) == 0)
|
|
339
|
+
&.{@intFromEnum(Move.None)}
|
|
340
|
+
else
|
|
341
|
+
&.{ @intFromEnum(Move.From), @intFromEnum(from) });
|
|
253
342
|
}
|
|
254
343
|
|
|
255
344
|
pub fn switched(self: Self, ident: ID, pokemon: anytype) Error!void {
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
345
|
+
return switchDrag(self, .Switch, ident, pokemon);
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
fn switchDrag(self: Self, arg: ArgType, ident: ID, pokemon: anytype) Error!void {
|
|
349
|
+
if (!enabled) return;
|
|
350
|
+
|
|
351
|
+
try self.writer.writeAll(&.{ @intFromEnum(arg), @as(u8, @bitCast(ident)) });
|
|
352
|
+
if (@hasField(@TypeOf(pokemon.*), "dvs")) {
|
|
353
|
+
try self.writer.writeAll(&.{
|
|
354
|
+
@intFromEnum(pokemon.species),
|
|
355
|
+
@intFromEnum(pokemon.dvs.gender),
|
|
356
|
+
pokemon.level,
|
|
357
|
+
});
|
|
358
|
+
} else {
|
|
359
|
+
try self.writer.writeAll(&.{ @intFromEnum(pokemon.species), pokemon.level });
|
|
360
|
+
}
|
|
259
361
|
try self.writer.writeIntNative(u16, pokemon.hp);
|
|
260
362
|
try self.writer.writeIntNative(u16, pokemon.stats.hp);
|
|
261
363
|
try self.writer.writeAll(&.{pokemon.status});
|
|
262
364
|
}
|
|
263
365
|
|
|
264
366
|
pub fn cant(self: Self, ident: ID, reason: Cant) Error!void {
|
|
265
|
-
if (!
|
|
367
|
+
if (!enabled) return;
|
|
368
|
+
|
|
266
369
|
assert(reason != .Disable);
|
|
267
370
|
try self.writer.writeAll(&.{
|
|
268
|
-
@
|
|
269
|
-
@
|
|
270
|
-
@
|
|
371
|
+
@intFromEnum(ArgType.Cant),
|
|
372
|
+
@as(u8, @bitCast(ident)),
|
|
373
|
+
@intFromEnum(reason),
|
|
271
374
|
});
|
|
272
375
|
}
|
|
273
376
|
|
|
274
377
|
pub fn disabled(self: Self, ident: ID, m: anytype) Error!void {
|
|
275
|
-
if (!
|
|
378
|
+
if (!enabled) return;
|
|
379
|
+
|
|
276
380
|
try self.writer.writeAll(&.{
|
|
277
|
-
@
|
|
278
|
-
@
|
|
279
|
-
@
|
|
280
|
-
@
|
|
381
|
+
@intFromEnum(ArgType.Cant),
|
|
382
|
+
@as(u8, @bitCast(ident)),
|
|
383
|
+
@intFromEnum(Cant.Disable),
|
|
384
|
+
@intFromEnum(m),
|
|
281
385
|
});
|
|
282
386
|
}
|
|
283
387
|
|
|
284
388
|
pub fn faint(self: Self, ident: ID, done: bool) Error!void {
|
|
285
|
-
if (!
|
|
286
|
-
|
|
287
|
-
|
|
389
|
+
if (!enabled) return;
|
|
390
|
+
|
|
391
|
+
try self.writer.writeAll(&.{ @intFromEnum(ArgType.Faint), @as(u8, @bitCast(ident)) });
|
|
392
|
+
if (done) try self.writer.writeByte(@intFromEnum(ArgType.None));
|
|
288
393
|
}
|
|
289
394
|
|
|
290
395
|
pub fn turn(self: Self, num: u16) Error!void {
|
|
291
|
-
if (!
|
|
292
|
-
|
|
396
|
+
if (!enabled) return;
|
|
397
|
+
|
|
398
|
+
try self.writer.writeByte(@intFromEnum(ArgType.Turn));
|
|
293
399
|
try self.writer.writeIntNative(u16, num);
|
|
294
|
-
try self.writer.writeByte(@
|
|
400
|
+
try self.writer.writeByte(@intFromEnum(ArgType.None));
|
|
295
401
|
}
|
|
296
402
|
|
|
297
403
|
pub fn win(self: Self, player: Player) Error!void {
|
|
298
|
-
if (!
|
|
404
|
+
if (!enabled) return;
|
|
405
|
+
|
|
299
406
|
try self.writer.writeAll(&.{
|
|
300
|
-
@
|
|
301
|
-
@
|
|
302
|
-
@
|
|
407
|
+
@intFromEnum(ArgType.Win),
|
|
408
|
+
@intFromEnum(player),
|
|
409
|
+
@intFromEnum(ArgType.None),
|
|
303
410
|
});
|
|
304
411
|
}
|
|
305
412
|
|
|
306
413
|
pub fn tie(self: Self) Error!void {
|
|
307
|
-
if (!
|
|
308
|
-
|
|
414
|
+
if (!enabled) return;
|
|
415
|
+
|
|
416
|
+
try self.writer.writeAll(&.{ @intFromEnum(ArgType.Tie), @intFromEnum(ArgType.None) });
|
|
309
417
|
}
|
|
310
418
|
|
|
311
419
|
pub fn damage(self: Self, ident: ID, pokemon: anytype, reason: Damage) Error!void {
|
|
312
|
-
if (!
|
|
313
|
-
|
|
314
|
-
|
|
420
|
+
if (!enabled) return;
|
|
421
|
+
|
|
422
|
+
assert(@intFromEnum(reason) <= @intFromEnum(Damage.LeechSeed));
|
|
423
|
+
try self.writer.writeAll(&.{ @intFromEnum(ArgType.Damage), @as(u8, @bitCast(ident)) });
|
|
315
424
|
try self.writer.writeIntNative(u16, pokemon.hp);
|
|
316
425
|
try self.writer.writeIntNative(u16, pokemon.stats.hp);
|
|
317
|
-
try self.writer.writeAll(&.{ pokemon.status, @
|
|
426
|
+
try self.writer.writeAll(&.{ pokemon.status, @intFromEnum(reason) });
|
|
318
427
|
}
|
|
319
428
|
|
|
320
429
|
pub fn damageOf(
|
|
@@ -324,227 +433,398 @@ pub fn Log(comptime Writer: type) type {
|
|
|
324
433
|
reason: Damage,
|
|
325
434
|
source: ID,
|
|
326
435
|
) Error!void {
|
|
327
|
-
if (!
|
|
328
|
-
|
|
329
|
-
|
|
436
|
+
if (!enabled) return;
|
|
437
|
+
|
|
438
|
+
assert(@intFromEnum(reason) == @intFromEnum(Damage.RecoilOf));
|
|
439
|
+
try self.writer.writeAll(&.{ @intFromEnum(ArgType.Damage), @as(u8, @bitCast(ident)) });
|
|
330
440
|
try self.writer.writeIntNative(u16, pokemon.hp);
|
|
331
441
|
try self.writer.writeIntNative(u16, pokemon.stats.hp);
|
|
332
442
|
try self.writer.writeAll(&.{
|
|
333
443
|
pokemon.status,
|
|
334
|
-
@
|
|
335
|
-
@
|
|
444
|
+
@intFromEnum(reason),
|
|
445
|
+
@as(u8, @bitCast(source)),
|
|
336
446
|
});
|
|
337
447
|
}
|
|
338
448
|
|
|
339
449
|
pub fn heal(self: Self, ident: ID, pokemon: anytype, reason: Heal) Error!void {
|
|
340
|
-
if (!
|
|
450
|
+
if (!enabled) return;
|
|
451
|
+
|
|
341
452
|
assert(reason != .Drain);
|
|
342
|
-
try self.writer.writeAll(&.{ @
|
|
453
|
+
try self.writer.writeAll(&.{ @intFromEnum(ArgType.Heal), @as(u8, @bitCast(ident)) });
|
|
343
454
|
try self.writer.writeIntNative(u16, pokemon.hp);
|
|
344
455
|
try self.writer.writeIntNative(u16, pokemon.stats.hp);
|
|
345
|
-
try self.writer.writeAll(&.{ pokemon.status, @
|
|
456
|
+
try self.writer.writeAll(&.{ pokemon.status, @intFromEnum(reason) });
|
|
346
457
|
}
|
|
347
458
|
|
|
348
459
|
pub fn drain(self: Self, source: ID, pokemon: anytype, target: ID) Error!void {
|
|
349
|
-
if (!
|
|
350
|
-
|
|
460
|
+
if (!enabled) return;
|
|
461
|
+
|
|
462
|
+
try self.writer.writeAll(&.{ @intFromEnum(ArgType.Heal), @as(u8, @bitCast(source)) });
|
|
351
463
|
try self.writer.writeIntNative(u16, pokemon.hp);
|
|
352
464
|
try self.writer.writeIntNative(u16, pokemon.stats.hp);
|
|
353
465
|
try self.writer.writeAll(&.{
|
|
354
466
|
pokemon.status,
|
|
355
|
-
@
|
|
356
|
-
@
|
|
467
|
+
@intFromEnum(Heal.Drain),
|
|
468
|
+
@as(u8, @bitCast(target)),
|
|
357
469
|
});
|
|
358
470
|
}
|
|
359
471
|
|
|
360
472
|
pub fn status(self: Self, ident: ID, value: u8, reason: Status) Error!void {
|
|
361
|
-
if (!
|
|
473
|
+
if (!enabled) return;
|
|
474
|
+
|
|
362
475
|
assert(reason != .From);
|
|
363
476
|
try self.writer.writeAll(&.{
|
|
364
|
-
@
|
|
365
|
-
@
|
|
477
|
+
@intFromEnum(ArgType.Status),
|
|
478
|
+
@as(u8, @bitCast(ident)),
|
|
366
479
|
value,
|
|
367
|
-
@
|
|
480
|
+
@intFromEnum(reason),
|
|
368
481
|
});
|
|
369
482
|
}
|
|
370
483
|
|
|
371
484
|
pub fn statusFrom(self: Self, ident: ID, value: u8, m: anytype) Error!void {
|
|
372
|
-
if (!
|
|
485
|
+
if (!enabled) return;
|
|
486
|
+
|
|
373
487
|
try self.writer.writeAll(&.{
|
|
374
|
-
@
|
|
375
|
-
@
|
|
488
|
+
@intFromEnum(ArgType.Status),
|
|
489
|
+
@as(u8, @bitCast(ident)),
|
|
376
490
|
value,
|
|
377
|
-
@
|
|
378
|
-
@
|
|
491
|
+
@intFromEnum(Status.From),
|
|
492
|
+
@intFromEnum(m),
|
|
379
493
|
});
|
|
380
494
|
}
|
|
381
495
|
|
|
382
496
|
pub fn curestatus(self: Self, ident: ID, value: u8, reason: CureStatus) Error!void {
|
|
383
|
-
if (!
|
|
497
|
+
if (!enabled) return;
|
|
498
|
+
|
|
384
499
|
try self.writer.writeAll(&.{
|
|
385
|
-
@
|
|
386
|
-
@
|
|
500
|
+
@intFromEnum(ArgType.CureStatus),
|
|
501
|
+
@as(u8, @bitCast(ident)),
|
|
387
502
|
value,
|
|
388
|
-
@
|
|
503
|
+
@intFromEnum(reason),
|
|
389
504
|
});
|
|
390
505
|
}
|
|
391
506
|
|
|
392
507
|
pub fn boost(self: Self, ident: ID, reason: Boost, num: i8) Error!void {
|
|
393
|
-
if (!
|
|
508
|
+
if (!enabled) return;
|
|
509
|
+
|
|
394
510
|
assert(num != 0 and (reason != .Rage or num > 0));
|
|
395
511
|
try self.writer.writeAll(&.{
|
|
396
|
-
@
|
|
397
|
-
@
|
|
398
|
-
@
|
|
399
|
-
@
|
|
512
|
+
@intFromEnum(ArgType.Boost),
|
|
513
|
+
@as(u8, @bitCast(ident)),
|
|
514
|
+
@intFromEnum(reason),
|
|
515
|
+
@as(u8, @intCast(num + 6)),
|
|
400
516
|
});
|
|
401
517
|
}
|
|
402
518
|
|
|
403
519
|
pub fn clearallboost(self: Self) Error!void {
|
|
404
|
-
if (!
|
|
405
|
-
|
|
520
|
+
if (!enabled) return;
|
|
521
|
+
|
|
522
|
+
try self.writer.writeAll(&.{@intFromEnum(ArgType.ClearAllBoost)});
|
|
406
523
|
}
|
|
407
524
|
|
|
408
525
|
pub fn fail(self: Self, ident: ID, reason: Fail) Error!void {
|
|
409
|
-
if (!
|
|
526
|
+
if (!enabled) return;
|
|
527
|
+
|
|
410
528
|
try self.writer.writeAll(&.{
|
|
411
|
-
@
|
|
412
|
-
@
|
|
413
|
-
@
|
|
529
|
+
@intFromEnum(ArgType.Fail),
|
|
530
|
+
@as(u8, @bitCast(ident)),
|
|
531
|
+
@intFromEnum(reason),
|
|
414
532
|
});
|
|
415
533
|
}
|
|
416
534
|
|
|
417
535
|
pub fn miss(self: Self, source: ID) Error!void {
|
|
418
|
-
if (!
|
|
419
|
-
|
|
536
|
+
if (!enabled) return;
|
|
537
|
+
|
|
538
|
+
try self.writer.writeAll(&.{ @intFromEnum(ArgType.Miss), @as(u8, @bitCast(source)) });
|
|
420
539
|
}
|
|
421
540
|
|
|
422
541
|
pub fn hitcount(self: Self, ident: ID, num: u8) Error!void {
|
|
423
|
-
if (!
|
|
424
|
-
|
|
542
|
+
if (!enabled) return;
|
|
543
|
+
|
|
544
|
+
try self.writer.writeAll(&.{
|
|
545
|
+
@intFromEnum(ArgType.HitCount),
|
|
546
|
+
@as(u8, @bitCast(ident)),
|
|
547
|
+
num,
|
|
548
|
+
});
|
|
425
549
|
}
|
|
426
550
|
|
|
427
551
|
pub fn prepare(self: Self, source: ID, m: anytype) Error!void {
|
|
428
|
-
if (!
|
|
552
|
+
if (!enabled) return;
|
|
553
|
+
|
|
429
554
|
try self.writer.writeAll(&.{
|
|
430
|
-
@
|
|
431
|
-
@
|
|
432
|
-
@
|
|
555
|
+
@intFromEnum(ArgType.Prepare),
|
|
556
|
+
@as(u8, @bitCast(source)),
|
|
557
|
+
@intFromEnum(m),
|
|
433
558
|
});
|
|
434
559
|
}
|
|
435
560
|
|
|
436
561
|
pub fn mustrecharge(self: Self, ident: ID) Error!void {
|
|
437
|
-
if (!
|
|
438
|
-
|
|
562
|
+
if (!enabled) return;
|
|
563
|
+
|
|
564
|
+
try self.writer.writeAll(&.{
|
|
565
|
+
@intFromEnum(ArgType.MustRecharge),
|
|
566
|
+
@as(u8, @bitCast(ident)),
|
|
567
|
+
});
|
|
439
568
|
}
|
|
440
569
|
|
|
441
570
|
pub fn activate(self: Self, ident: ID, reason: Activate) Error!void {
|
|
442
|
-
if (!
|
|
571
|
+
if (!enabled) return;
|
|
572
|
+
|
|
443
573
|
try self.writer.writeAll(&.{
|
|
444
|
-
@
|
|
445
|
-
@
|
|
446
|
-
@
|
|
574
|
+
@intFromEnum(ArgType.Activate),
|
|
575
|
+
@as(u8, @bitCast(ident)),
|
|
576
|
+
@intFromEnum(reason),
|
|
447
577
|
});
|
|
448
578
|
}
|
|
449
579
|
|
|
450
580
|
pub fn fieldactivate(self: Self) Error!void {
|
|
451
|
-
if (!
|
|
452
|
-
|
|
581
|
+
if (!enabled) return;
|
|
582
|
+
|
|
583
|
+
try self.writer.writeAll(&.{@intFromEnum(ArgType.FieldActivate)});
|
|
453
584
|
}
|
|
454
585
|
|
|
455
586
|
pub fn start(self: Self, ident: ID, reason: Start) Error!void {
|
|
456
|
-
if (!
|
|
457
|
-
|
|
587
|
+
if (!enabled) return;
|
|
588
|
+
|
|
589
|
+
assert(@intFromEnum(reason) < @intFromEnum(Start.TypeChange));
|
|
458
590
|
try self.writer.writeAll(&.{
|
|
459
|
-
@
|
|
460
|
-
@
|
|
461
|
-
@
|
|
591
|
+
@intFromEnum(ArgType.Start),
|
|
592
|
+
@as(u8, @bitCast(ident)),
|
|
593
|
+
@intFromEnum(reason),
|
|
462
594
|
});
|
|
463
595
|
}
|
|
464
596
|
|
|
465
597
|
pub fn typechange(self: Self, source: ID, types: anytype, target: ID) Error!void {
|
|
466
|
-
if (!
|
|
598
|
+
if (!enabled) return;
|
|
599
|
+
|
|
467
600
|
try self.writer.writeAll(&.{
|
|
468
|
-
@
|
|
469
|
-
@
|
|
470
|
-
@
|
|
471
|
-
@
|
|
472
|
-
@
|
|
601
|
+
@intFromEnum(ArgType.Start),
|
|
602
|
+
@as(u8, @bitCast(source)),
|
|
603
|
+
@intFromEnum(Start.TypeChange),
|
|
604
|
+
@as(u8, @bitCast(types)),
|
|
605
|
+
@as(u8, @bitCast(target)),
|
|
473
606
|
});
|
|
474
607
|
}
|
|
475
608
|
|
|
476
609
|
pub fn startEffect(self: Self, ident: ID, reason: Start, m: anytype) Error!void {
|
|
477
|
-
if (!
|
|
478
|
-
|
|
610
|
+
if (!enabled) return;
|
|
611
|
+
|
|
612
|
+
assert(@intFromEnum(reason) > @intFromEnum(Start.TypeChange));
|
|
479
613
|
try self.writer.writeAll(&.{
|
|
480
|
-
@
|
|
481
|
-
@
|
|
482
|
-
@
|
|
483
|
-
@
|
|
614
|
+
@intFromEnum(ArgType.Start),
|
|
615
|
+
@as(u8, @bitCast(ident)),
|
|
616
|
+
@intFromEnum(reason),
|
|
617
|
+
@intFromEnum(m),
|
|
484
618
|
});
|
|
485
619
|
}
|
|
486
620
|
|
|
487
621
|
pub fn end(self: Self, ident: ID, reason: End) Error!void {
|
|
488
|
-
if (!
|
|
622
|
+
if (!enabled) return;
|
|
623
|
+
|
|
489
624
|
try self.writer.writeAll(&.{
|
|
490
|
-
@
|
|
491
|
-
@
|
|
492
|
-
@
|
|
625
|
+
@intFromEnum(ArgType.End),
|
|
626
|
+
@as(u8, @bitCast(ident)),
|
|
627
|
+
@intFromEnum(reason),
|
|
493
628
|
});
|
|
494
629
|
}
|
|
495
630
|
|
|
496
631
|
pub fn ohko(self: Self) Error!void {
|
|
497
|
-
if (!
|
|
498
|
-
|
|
632
|
+
if (!enabled) return;
|
|
633
|
+
|
|
634
|
+
try self.writer.writeAll(&.{@intFromEnum(ArgType.OHKO)});
|
|
499
635
|
}
|
|
500
636
|
|
|
501
637
|
pub fn crit(self: Self, ident: ID) Error!void {
|
|
502
|
-
if (!
|
|
503
|
-
|
|
638
|
+
if (!enabled) return;
|
|
639
|
+
|
|
640
|
+
try self.writer.writeAll(&.{ @intFromEnum(ArgType.Crit), @as(u8, @bitCast(ident)) });
|
|
504
641
|
}
|
|
505
642
|
|
|
506
643
|
pub fn supereffective(self: Self, ident: ID) Error!void {
|
|
507
|
-
if (!
|
|
508
|
-
|
|
644
|
+
if (!enabled) return;
|
|
645
|
+
|
|
646
|
+
try self.writer.writeAll(&.{
|
|
647
|
+
@intFromEnum(ArgType.SuperEffective),
|
|
648
|
+
@as(u8, @bitCast(ident)),
|
|
649
|
+
});
|
|
509
650
|
}
|
|
510
651
|
|
|
511
652
|
pub fn resisted(self: Self, ident: ID) Error!void {
|
|
512
|
-
if (!
|
|
513
|
-
|
|
653
|
+
if (!enabled) return;
|
|
654
|
+
|
|
655
|
+
try self.writer.writeAll(&.{
|
|
656
|
+
@intFromEnum(ArgType.Resisted),
|
|
657
|
+
@as(u8, @bitCast(ident)),
|
|
658
|
+
});
|
|
514
659
|
}
|
|
515
660
|
|
|
516
661
|
pub fn immune(self: Self, ident: ID, reason: Immune) Error!void {
|
|
517
|
-
if (!
|
|
662
|
+
if (!enabled) return;
|
|
663
|
+
|
|
518
664
|
try self.writer.writeAll(&.{
|
|
519
|
-
@
|
|
520
|
-
@
|
|
521
|
-
@
|
|
665
|
+
@intFromEnum(ArgType.Immune),
|
|
666
|
+
@as(u8, @bitCast(ident)),
|
|
667
|
+
@intFromEnum(reason),
|
|
522
668
|
});
|
|
523
669
|
}
|
|
524
670
|
|
|
525
671
|
pub fn transform(self: Self, source: ID, target: ID) Error!void {
|
|
526
|
-
if (!
|
|
672
|
+
if (!enabled) return;
|
|
673
|
+
|
|
674
|
+
try self.writer.writeAll(&.{
|
|
675
|
+
@intFromEnum(ArgType.Transform),
|
|
676
|
+
@as(u8, @bitCast(source)),
|
|
677
|
+
@as(u8, @bitCast(target)),
|
|
678
|
+
});
|
|
679
|
+
}
|
|
680
|
+
|
|
681
|
+
pub fn drag(self: Self, ident: ID, pokemon: anytype) Error!void {
|
|
682
|
+
return switchDrag(self, .Drag, ident, pokemon);
|
|
683
|
+
}
|
|
684
|
+
|
|
685
|
+
pub fn item(self: Self, target: ID, i: anytype, source: ID) Error!void {
|
|
686
|
+
if (!enabled) return;
|
|
687
|
+
|
|
688
|
+
try self.writer.writeAll(&.{
|
|
689
|
+
@intFromEnum(ArgType.Item),
|
|
690
|
+
@as(u8, @bitCast(target)),
|
|
691
|
+
@intFromEnum(i),
|
|
692
|
+
@as(u8, @bitCast(source)),
|
|
693
|
+
});
|
|
694
|
+
}
|
|
695
|
+
|
|
696
|
+
pub fn enditem(self: Self, ident: ID, i: anytype, reason: EndItem) Error!void {
|
|
697
|
+
if (!enabled) return;
|
|
698
|
+
|
|
527
699
|
try self.writer.writeAll(&.{
|
|
528
|
-
@
|
|
529
|
-
@
|
|
530
|
-
@
|
|
700
|
+
@intFromEnum(ArgType.EndItem),
|
|
701
|
+
@as(u8, @bitCast(ident)),
|
|
702
|
+
@intFromEnum(i),
|
|
703
|
+
@intFromEnum(reason),
|
|
704
|
+
});
|
|
705
|
+
}
|
|
706
|
+
|
|
707
|
+
pub fn cureteam(self: Self, source: ID) Error!void {
|
|
708
|
+
if (!enabled) return;
|
|
709
|
+
|
|
710
|
+
try self.writer.writeAll(&.{
|
|
711
|
+
@intFromEnum(ArgType.CureTeam),
|
|
712
|
+
@as(u8, @bitCast(source)),
|
|
713
|
+
});
|
|
714
|
+
}
|
|
715
|
+
|
|
716
|
+
pub fn sethp(self: Self, ident: ID, pokemon: anytype, reason: SetHP) Error!void {
|
|
717
|
+
if (!enabled) return;
|
|
718
|
+
|
|
719
|
+
try self.writer.writeAll(&.{ @intFromEnum(ArgType.SetHP), @as(u8, @bitCast(ident)) });
|
|
720
|
+
try self.writer.writeIntNative(u16, pokemon.hp);
|
|
721
|
+
try self.writer.writeIntNative(u16, pokemon.stats.hp);
|
|
722
|
+
try self.writer.writeAll(&.{pokemon.status});
|
|
723
|
+
try self.writer.writeByte(@intFromEnum(reason));
|
|
724
|
+
}
|
|
725
|
+
|
|
726
|
+
pub fn setboost(self: Self, ident: ID, num: i8) Error!void {
|
|
727
|
+
if (!enabled) return;
|
|
728
|
+
|
|
729
|
+
try self.writer.writeAll(&.{
|
|
730
|
+
@intFromEnum(ArgType.SetBoost),
|
|
731
|
+
@as(u8, @bitCast(ident)),
|
|
732
|
+
@as(u8, @intCast(num + 6)),
|
|
733
|
+
});
|
|
734
|
+
}
|
|
735
|
+
|
|
736
|
+
pub fn copyboost(self: Self, source: ID, target: ID) Error!void {
|
|
737
|
+
if (!enabled) return;
|
|
738
|
+
|
|
739
|
+
try self.writer.writeAll(&.{
|
|
740
|
+
@intFromEnum(ArgType.CopyBoost),
|
|
741
|
+
@as(u8, @bitCast(source)),
|
|
742
|
+
@as(u8, @bitCast(target)),
|
|
743
|
+
});
|
|
744
|
+
}
|
|
745
|
+
|
|
746
|
+
pub fn sidestart(self: Self, player: Player, reason: Side) Error!void {
|
|
747
|
+
if (!enabled) return;
|
|
748
|
+
|
|
749
|
+
try self.writer.writeAll(&.{
|
|
750
|
+
@intFromEnum(ArgType.SideStart),
|
|
751
|
+
@intFromEnum(player),
|
|
752
|
+
@intFromEnum(reason),
|
|
753
|
+
});
|
|
754
|
+
}
|
|
755
|
+
|
|
756
|
+
pub fn sideend(self: Self, player: Player, reason: Side) Error!void {
|
|
757
|
+
if (!enabled) return;
|
|
758
|
+
|
|
759
|
+
assert(@intFromEnum(reason) != @intFromEnum(Side.Spikes));
|
|
760
|
+
try self.writer.writeAll(&.{
|
|
761
|
+
@intFromEnum(ArgType.SideEnd),
|
|
762
|
+
@intFromEnum(player),
|
|
763
|
+
@intFromEnum(reason),
|
|
764
|
+
});
|
|
765
|
+
}
|
|
766
|
+
|
|
767
|
+
pub fn spikesend(self: Self, player: Player, m: anytype, source: ID) Error!void {
|
|
768
|
+
if (!enabled) return;
|
|
769
|
+
|
|
770
|
+
try self.writer.writeAll(&.{
|
|
771
|
+
@intFromEnum(ArgType.SideEnd),
|
|
772
|
+
@intFromEnum(player),
|
|
773
|
+
@intFromEnum(Side.Spikes),
|
|
774
|
+
@intFromEnum(m),
|
|
775
|
+
@as(u8, @bitCast(source)),
|
|
776
|
+
});
|
|
777
|
+
}
|
|
778
|
+
|
|
779
|
+
pub fn singlemove(self: Self, ident: ID, m: anytype) Error!void {
|
|
780
|
+
return single(self, .SingleMove, ident, m);
|
|
781
|
+
}
|
|
782
|
+
|
|
783
|
+
pub fn singleturn(self: Self, ident: ID, m: anytype) Error!void {
|
|
784
|
+
return single(self, .SingleTurn, ident, m);
|
|
785
|
+
}
|
|
786
|
+
|
|
787
|
+
fn single(self: Self, arg: ArgType, ident: ID, m: anytype) Error!void {
|
|
788
|
+
if (!enabled) return;
|
|
789
|
+
|
|
790
|
+
try self.writer.writeAll(&.{
|
|
791
|
+
@intFromEnum(arg),
|
|
792
|
+
@as(u8, @bitCast(ident)),
|
|
793
|
+
@intFromEnum(m),
|
|
794
|
+
});
|
|
795
|
+
}
|
|
796
|
+
|
|
797
|
+
pub fn weather(self: Self, w: anytype, reason: Weather) Error!void {
|
|
798
|
+
if (!enabled) return;
|
|
799
|
+
|
|
800
|
+
assert(!(w == .None and reason == .Upkeep));
|
|
801
|
+
try self.writer.writeAll(&.{
|
|
802
|
+
@intFromEnum(ArgType.Weather),
|
|
803
|
+
@intFromEnum(w),
|
|
804
|
+
@intFromEnum(reason),
|
|
531
805
|
});
|
|
532
806
|
}
|
|
533
807
|
|
|
534
808
|
pub fn laststill(self: Self) Error!void {
|
|
535
|
-
if (!
|
|
536
|
-
|
|
809
|
+
if (!enabled) return;
|
|
810
|
+
|
|
811
|
+
try self.writer.writeAll(&.{@intFromEnum(ArgType.LastStill)});
|
|
537
812
|
}
|
|
538
813
|
|
|
539
814
|
pub fn lastmiss(self: Self) Error!void {
|
|
540
|
-
if (!
|
|
541
|
-
|
|
815
|
+
if (!enabled) return;
|
|
816
|
+
|
|
817
|
+
try self.writer.writeAll(&.{@intFromEnum(ArgType.LastMiss)});
|
|
542
818
|
}
|
|
543
819
|
};
|
|
544
820
|
}
|
|
545
821
|
|
|
822
|
+
/// `Log` type backed by the optimized `ByteStream.Writer`.
|
|
546
823
|
pub const FixedLog = Log(ByteStream.Writer);
|
|
547
824
|
|
|
825
|
+
/// Stripped down version of `std.io.FixedBufferStream` optimized for efficiently writing the
|
|
826
|
+
/// individual protocol bytes. Note that the `ByteStream.Writer` is **not** a `std.io.Writer` and
|
|
827
|
+
/// should not be used for general purpose writing.
|
|
548
828
|
pub const ByteStream = struct {
|
|
549
829
|
buffer: []u8,
|
|
550
830
|
pos: usize = 0,
|
|
@@ -585,15 +865,19 @@ pub const ByteStream = struct {
|
|
|
585
865
|
}
|
|
586
866
|
};
|
|
587
867
|
|
|
588
|
-
pub const Kind = enum { Move, Species, Type, Status };
|
|
589
|
-
pub const Formatter = fn (Kind, u8) []const u8;
|
|
868
|
+
pub const Kind = enum { Move, Species, Type, Status, Item, Weather };
|
|
590
869
|
|
|
591
|
-
pub fn format(
|
|
870
|
+
pub fn format(
|
|
871
|
+
comptime gen: anytype,
|
|
872
|
+
a: []const u8,
|
|
873
|
+
b: ?[]const u8,
|
|
874
|
+
color: bool,
|
|
875
|
+
) void {
|
|
592
876
|
print("\n", .{});
|
|
593
877
|
|
|
594
878
|
var i: usize = 0;
|
|
595
879
|
while (i < a.len) {
|
|
596
|
-
const arg = @
|
|
880
|
+
const arg: ArgType = @enumFromInt(a[i]);
|
|
597
881
|
const name = switch (arg) {
|
|
598
882
|
.None => if (color) "\x1b[2m-\x1b[0m" else "-",
|
|
599
883
|
.LastStill => "|[still]",
|
|
@@ -626,6 +910,18 @@ pub fn format(comptime formatter: Formatter, a: []const u8, b: ?[]const u8, colo
|
|
|
626
910
|
.Resisted => "|-resisted|",
|
|
627
911
|
.Immune => "|-immune|",
|
|
628
912
|
.Transform => "|-transform|",
|
|
913
|
+
.Drag => "|drag|",
|
|
914
|
+
.Item => "|-item|",
|
|
915
|
+
.EndItem => "|-enditem|",
|
|
916
|
+
.CureTeam => "|-cureteam|",
|
|
917
|
+
.SetHP => "|-sethp|",
|
|
918
|
+
.SetBoost => "|-setboost|",
|
|
919
|
+
.CopyBoost => "|-copyboost|",
|
|
920
|
+
.SideStart => "|-sidestart|",
|
|
921
|
+
.SideEnd => "|-sideend|",
|
|
922
|
+
.SingleMove => "|-singlemove|",
|
|
923
|
+
.SingleTurn => "|-singleturn|",
|
|
924
|
+
.Weather => "|-weather|",
|
|
629
925
|
else => unreachable,
|
|
630
926
|
};
|
|
631
927
|
printc("{s}", .{name}, a, b, &i, 1, color);
|
|
@@ -639,19 +935,29 @@ pub fn format(comptime formatter: Formatter, a: []const u8, b: ?[]const u8, colo
|
|
|
639
935
|
.OHKO,
|
|
640
936
|
=> {},
|
|
641
937
|
.Move => {
|
|
642
|
-
const source = ID.from(@intCast(
|
|
938
|
+
const source = ID.from(@intCast(a[i]));
|
|
643
939
|
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(
|
|
940
|
+
printc(" {s}", .{formatter(gen, .Move, a[i])}, a, b, &i, 1, color);
|
|
941
|
+
const target = ID.from(@intCast(a[i]));
|
|
646
942
|
printc(" {s}({d})", .{ @tagName(target.player), target.id }, a, b, &i, 1, color);
|
|
647
|
-
const reason = @
|
|
943
|
+
const reason: Move = @enumFromInt(a[i]);
|
|
648
944
|
printc(" {s}", .{@tagName(reason)}, a, b, &i, 1, color);
|
|
649
|
-
if (reason == .From)
|
|
945
|
+
if (reason == .From) {
|
|
946
|
+
printc(" {s}", .{formatter(gen, .Move, a[i])}, a, b, &i, 1, color);
|
|
947
|
+
}
|
|
650
948
|
},
|
|
651
|
-
.Switch => {
|
|
652
|
-
const id = ID.from(@intCast(
|
|
949
|
+
.Switch, .Drag => {
|
|
950
|
+
const id = ID.from(@intCast(a[i]));
|
|
653
951
|
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);
|
|
952
|
+
printc(" {s}", .{formatter(gen, .Species, a[i])}, a, b, &i, 1, color);
|
|
953
|
+
if (@hasDecl(gen, "Gender")) {
|
|
954
|
+
if (a[i] == N(gen.Gender.Unknown)) {
|
|
955
|
+
i += 1;
|
|
956
|
+
} else {
|
|
957
|
+
var gender = if (a[i] == N(gen.Gender.Male)) "M" else "F";
|
|
958
|
+
printc(", {s}", .{gender}, a, b, &i, 1, color);
|
|
959
|
+
}
|
|
960
|
+
}
|
|
655
961
|
printc(" L{d}", .{a[i]}, a, b, &i, 1, color);
|
|
656
962
|
switch (endian) {
|
|
657
963
|
.Big => {
|
|
@@ -667,15 +973,15 @@ pub fn format(comptime formatter: Formatter, a: []const u8, b: ?[]const u8, colo
|
|
|
667
973
|
printc("/{d}", .{hp}, a, b, &i, 2, color);
|
|
668
974
|
},
|
|
669
975
|
}
|
|
670
|
-
printc(" {s}", .{formatter(.Status, a[i])}, a, b, &i, 1, color);
|
|
976
|
+
printc(" {s}", .{formatter(gen, .Status, a[i])}, a, b, &i, 1, color);
|
|
671
977
|
},
|
|
672
978
|
.Cant => {
|
|
673
|
-
const id = ID.from(@intCast(
|
|
979
|
+
const id = ID.from(@intCast(a[i]));
|
|
674
980
|
printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
|
|
675
|
-
const reason = @
|
|
981
|
+
const reason: Cant = @enumFromInt(a[i]);
|
|
676
982
|
printc(" {s}", .{@tagName(reason)}, a, b, &i, 1, color);
|
|
677
983
|
if (reason == .Disable) {
|
|
678
|
-
printc(" {s}", .{formatter(.Move, a[i])}, a, b, &i, 1, color);
|
|
984
|
+
printc(" {s}", .{formatter(gen, .Move, a[i])}, a, b, &i, 1, color);
|
|
679
985
|
}
|
|
680
986
|
},
|
|
681
987
|
.Faint,
|
|
@@ -684,8 +990,9 @@ pub fn format(comptime formatter: Formatter, a: []const u8, b: ?[]const u8, colo
|
|
|
684
990
|
.Crit,
|
|
685
991
|
.SuperEffective,
|
|
686
992
|
.Resisted,
|
|
993
|
+
.CureTeam,
|
|
687
994
|
=> {
|
|
688
|
-
const id = ID.from(@intCast(
|
|
995
|
+
const id = ID.from(@intCast(a[i]));
|
|
689
996
|
printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
|
|
690
997
|
},
|
|
691
998
|
.Turn => {
|
|
@@ -695,9 +1002,11 @@ pub fn format(comptime formatter: Formatter, a: []const u8, b: ?[]const u8, colo
|
|
|
695
1002
|
};
|
|
696
1003
|
printc(" {d}", .{turn}, a, b, &i, 2, color);
|
|
697
1004
|
},
|
|
698
|
-
.Win =>
|
|
1005
|
+
.Win => {
|
|
1006
|
+
printc(" {s}", .{@tagName(@as(Player, @enumFromInt(a[i])))}, a, b, &i, 1, color);
|
|
1007
|
+
},
|
|
699
1008
|
.Damage, .Heal => {
|
|
700
|
-
var id = ID.from(@intCast(
|
|
1009
|
+
var id = ID.from(@intCast(a[i]));
|
|
701
1010
|
printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
|
|
702
1011
|
switch (endian) {
|
|
703
1012
|
.Big => {
|
|
@@ -713,95 +1022,150 @@ pub fn format(comptime formatter: Formatter, a: []const u8, b: ?[]const u8, colo
|
|
|
713
1022
|
printc("/{d}", .{hp}, a, b, &i, 2, color);
|
|
714
1023
|
},
|
|
715
1024
|
}
|
|
716
|
-
printc(" {s}", .{formatter(.Status, a[i])}, a, b, &i, 1, color);
|
|
1025
|
+
printc(" {s}", .{formatter(gen, .Status, a[i])}, a, b, &i, 1, color);
|
|
717
1026
|
if (arg == .Damage) {
|
|
718
|
-
const reason = a[i];
|
|
719
|
-
printc(" {s}", .{@tagName(
|
|
720
|
-
if (reason ==
|
|
721
|
-
id = ID.from(@intCast(
|
|
1027
|
+
const reason: Damage = @enumFromInt(a[i]);
|
|
1028
|
+
printc(" {s}", .{@tagName(reason)}, a, b, &i, 1, color);
|
|
1029
|
+
if (reason == .RecoilOf) {
|
|
1030
|
+
id = ID.from(@intCast(a[i]));
|
|
722
1031
|
printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
|
|
723
1032
|
}
|
|
724
1033
|
} else {
|
|
725
|
-
const reason = @
|
|
1034
|
+
const reason: Heal = @enumFromInt(a[i]);
|
|
726
1035
|
printc(" {s}", .{@tagName(reason)}, a, b, &i, 1, color);
|
|
727
1036
|
if (reason == .Drain) {
|
|
728
|
-
id = ID.from(@intCast(
|
|
1037
|
+
id = ID.from(@intCast(a[i]));
|
|
729
1038
|
printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
|
|
730
1039
|
}
|
|
731
1040
|
}
|
|
732
1041
|
},
|
|
733
1042
|
.Status => {
|
|
734
|
-
const id = ID.from(@intCast(
|
|
1043
|
+
const id = ID.from(@intCast(a[i]));
|
|
735
1044
|
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 = @
|
|
1045
|
+
printc(" {s}", .{formatter(gen, .Status, a[i])}, a, b, &i, 1, color);
|
|
1046
|
+
const reason: Status = @enumFromInt(a[i]);
|
|
738
1047
|
printc(" {s}", .{@tagName(reason)}, a, b, &i, 1, color);
|
|
739
|
-
if (reason == .From)
|
|
1048
|
+
if (reason == .From) {
|
|
1049
|
+
printc(" {s}", .{formatter(gen, .Move, a[i])}, a, b, &i, 1, color);
|
|
1050
|
+
}
|
|
740
1051
|
},
|
|
741
1052
|
.CureStatus => {
|
|
742
|
-
const id = ID.from(@intCast(
|
|
1053
|
+
const id = ID.from(@intCast(a[i]));
|
|
743
1054
|
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
|
-
|
|
1055
|
+
printc(" {s}", .{formatter(gen, .Status, a[i])}, a, b, &i, 1, color);
|
|
1056
|
+
const reason: CureStatus = @enumFromInt(a[i]);
|
|
1057
|
+
printc(" {s}", .{@tagName(reason)}, a, b, &i, 1, color);
|
|
746
1058
|
},
|
|
747
1059
|
.Boost => {
|
|
748
|
-
const id = ID.from(@intCast(
|
|
1060
|
+
const id = ID.from(@intCast(a[i]));
|
|
749
1061
|
printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
|
|
750
|
-
printc(" {s}", .{@tagName(@
|
|
1062
|
+
printc(" {s}", .{@tagName(@as(Boost, @enumFromInt(a[i])))}, a, b, &i, 1, color);
|
|
751
1063
|
printc(" {d}", .{a[i]}, a, b, &i, 1, color);
|
|
752
1064
|
},
|
|
753
1065
|
.Fail => {
|
|
754
|
-
const id = ID.from(@intCast(
|
|
1066
|
+
const id = ID.from(@intCast(a[i]));
|
|
755
1067
|
printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
|
|
756
|
-
printc(" {s}", .{@tagName(@
|
|
1068
|
+
printc(" {s}", .{@tagName(@as(Fail, @enumFromInt(a[i])))}, a, b, &i, 1, color);
|
|
757
1069
|
},
|
|
758
|
-
.HitCount => {
|
|
759
|
-
const id = ID.from(@intCast(
|
|
1070
|
+
.HitCount, .SetBoost => {
|
|
1071
|
+
const id = ID.from(@intCast(a[i]));
|
|
760
1072
|
printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
|
|
761
1073
|
printc(" {d}", .{a[i]}, a, b, &i, 1, color);
|
|
762
1074
|
},
|
|
763
|
-
.Prepare => {
|
|
764
|
-
const id = ID.from(@intCast(
|
|
1075
|
+
.Prepare, .SingleMove, .SingleTurn => {
|
|
1076
|
+
const id = ID.from(@intCast(a[i]));
|
|
765
1077
|
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);
|
|
1078
|
+
printc(" {s}", .{formatter(gen, .Move, a[i])}, a, b, &i, 1, color);
|
|
767
1079
|
},
|
|
768
1080
|
.Activate => {
|
|
769
|
-
const id = ID.from(@intCast(
|
|
1081
|
+
const id = ID.from(@intCast(a[i]));
|
|
770
1082
|
printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
|
|
771
|
-
printc(" {s}", .{@tagName(@
|
|
1083
|
+
printc(" {s}", .{@tagName(@as(Activate, @enumFromInt(a[i])))}, a, b, &i, 1, color);
|
|
772
1084
|
},
|
|
773
1085
|
.Start => {
|
|
774
|
-
const id = ID.from(@intCast(
|
|
1086
|
+
const id = ID.from(@intCast(a[i]));
|
|
775
1087
|
printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
|
|
776
1088
|
const reason = a[i];
|
|
777
|
-
printc(" {s}", .{@tagName(@
|
|
778
|
-
if (@
|
|
779
|
-
const types = @
|
|
1089
|
+
printc(" {s}", .{@tagName(@as(Start, @enumFromInt(reason)))}, a, b, &i, 1, color);
|
|
1090
|
+
if (@as(Start, @enumFromInt(reason)) == .TypeChange) {
|
|
1091
|
+
const types = @as(gen1.Types, @bitCast(a[i]));
|
|
780
1092
|
const args = .{
|
|
781
|
-
formatter(.Type, @
|
|
782
|
-
formatter(.Type, @
|
|
1093
|
+
formatter(gen, .Type, @intFromEnum(types.type1)),
|
|
1094
|
+
formatter(gen, .Type, @intFromEnum(types.type2)),
|
|
783
1095
|
};
|
|
784
1096
|
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);
|
|
1097
|
+
} else if (reason >= @intFromEnum(Start.Disable)) {
|
|
1098
|
+
printc(" {s}", .{formatter(gen, .Move, a[i])}, a, b, &i, 1, color);
|
|
787
1099
|
}
|
|
788
1100
|
},
|
|
789
1101
|
.End => {
|
|
790
|
-
const id = ID.from(@intCast(
|
|
1102
|
+
const id = ID.from(@intCast(a[i]));
|
|
791
1103
|
printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
|
|
792
|
-
printc(" {s}", .{@tagName(@
|
|
1104
|
+
printc(" {s}", .{@tagName(@as(End, @enumFromInt(a[i])))}, a, b, &i, 1, color);
|
|
793
1105
|
},
|
|
794
1106
|
.Immune => {
|
|
795
|
-
const id = ID.from(@intCast(
|
|
1107
|
+
const id = ID.from(@intCast(a[i]));
|
|
796
1108
|
printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
|
|
797
|
-
printc(" {s}", .{@tagName(@
|
|
1109
|
+
printc(" {s}", .{@tagName(@as(Immune, @enumFromInt(a[i])))}, a, b, &i, 1, color);
|
|
798
1110
|
},
|
|
799
|
-
.Transform => {
|
|
800
|
-
const source = ID.from(@intCast(
|
|
1111
|
+
.Transform, .CopyBoost => {
|
|
1112
|
+
const source = ID.from(@intCast(a[i]));
|
|
801
1113
|
printc(" {s}({d})", .{ @tagName(source.player), source.id }, a, b, &i, 1, color);
|
|
802
|
-
const target = ID.from(@intCast(
|
|
1114
|
+
const target = ID.from(@intCast(a[i]));
|
|
803
1115
|
printc(" {s}({d})", .{ @tagName(target.player), target.id }, a, b, &i, 1, color);
|
|
804
1116
|
},
|
|
1117
|
+
.Item, .EndItem => {
|
|
1118
|
+
var id = ID.from(@intCast(a[i]));
|
|
1119
|
+
printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
|
|
1120
|
+
printc(" {s}", .{formatter(gen, .Item, a[i])}, a, b, &i, 1, color);
|
|
1121
|
+
if (arg == .Item) {
|
|
1122
|
+
id = ID.from(@intCast(a[i]));
|
|
1123
|
+
printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
|
|
1124
|
+
} else {
|
|
1125
|
+
const reason: EndItem = @enumFromInt(a[i]);
|
|
1126
|
+
printc(" {s}", .{@tagName(reason)}, a, b, &i, 1, color);
|
|
1127
|
+
}
|
|
1128
|
+
},
|
|
1129
|
+
.SetHP => {
|
|
1130
|
+
const id = ID.from(@intCast(a[i]));
|
|
1131
|
+
printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
|
|
1132
|
+
switch (endian) {
|
|
1133
|
+
.Big => {
|
|
1134
|
+
var hp = @as(u16, a[i]) << 8 | @as(u16, a[i + 1]);
|
|
1135
|
+
printc(" {d}", .{hp}, a, b, &i, 2, color);
|
|
1136
|
+
hp = @as(u16, a[i]) << 8 | @as(u16, a[i + 1]);
|
|
1137
|
+
printc("/{d}", .{hp}, a, b, &i, 2, color);
|
|
1138
|
+
},
|
|
1139
|
+
.Little => {
|
|
1140
|
+
var hp = @as(u16, a[i + 1]) << 8 | @as(u16, a[i]);
|
|
1141
|
+
printc(" {d}", .{hp}, a, b, &i, 2, color);
|
|
1142
|
+
hp = @as(u16, a[i + 1]) << 8 | @as(u16, a[i]);
|
|
1143
|
+
printc("/{d}", .{hp}, a, b, &i, 2, color);
|
|
1144
|
+
},
|
|
1145
|
+
}
|
|
1146
|
+
printc(" {s}", .{formatter(gen, .Status, a[i])}, a, b, &i, 1, color);
|
|
1147
|
+
printc(" {s}", .{@tagName(@as(SetHP, @enumFromInt(a[i])))}, a, b, &i, 1, color);
|
|
1148
|
+
},
|
|
1149
|
+
.SideStart => {
|
|
1150
|
+
const id = ID.from(@intCast(a[i]));
|
|
1151
|
+
printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
|
|
1152
|
+
printc(" {s}", .{@tagName(@as(Side, @enumFromInt(a[i])))}, a, b, &i, 1, color);
|
|
1153
|
+
},
|
|
1154
|
+
.SideEnd => {
|
|
1155
|
+
var id = ID.from(@intCast(a[i]));
|
|
1156
|
+
printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
|
|
1157
|
+
const reason: Side = @enumFromInt(a[i]);
|
|
1158
|
+
printc(" {s}", .{@tagName(reason)}, a, b, &i, 1, color);
|
|
1159
|
+
if (reason == .Spikes) {
|
|
1160
|
+
printc(" {s}", .{formatter(gen, .Move, a[i])}, a, b, &i, 1, color);
|
|
1161
|
+
id = ID.from(@intCast(a[i]));
|
|
1162
|
+
printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
|
|
1163
|
+
}
|
|
1164
|
+
},
|
|
1165
|
+
.Weather => {
|
|
1166
|
+
printc(" {s}", .{formatter(gen, .Weather, a[i])}, a, b, &i, 1, color);
|
|
1167
|
+
printc(" {s}", .{@tagName(@as(Weather, @enumFromInt(a[i])))}, a, b, &i, 1, color);
|
|
1168
|
+
},
|
|
805
1169
|
else => unreachable,
|
|
806
1170
|
}
|
|
807
1171
|
print("\n", .{});
|
|
@@ -833,12 +1197,13 @@ fn printc(
|
|
|
833
1197
|
}
|
|
834
1198
|
|
|
835
1199
|
pub fn expectLog(
|
|
836
|
-
comptime
|
|
1200
|
+
comptime gen: anytype,
|
|
837
1201
|
expected: []const u8,
|
|
838
1202
|
actual: []const u8,
|
|
839
1203
|
offset: usize,
|
|
840
1204
|
) !void {
|
|
841
|
-
if (!
|
|
1205
|
+
if (!enabled) return;
|
|
1206
|
+
|
|
842
1207
|
const color = color: {
|
|
843
1208
|
if (std.process.hasEnvVarConstant("ZIG_DEBUG_COLOR")) {
|
|
844
1209
|
break :color true;
|
|
@@ -851,8 +1216,8 @@ pub fn expectLog(
|
|
|
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,
|
|
@@ -881,7 +1246,7 @@ fn expectEqualBytes(expected: []const u8, actual: []const u8, offset: usize) !vo
|
|
|
881
1246
|
const endian = builtin.target.cpu.arch.endian();
|
|
882
1247
|
|
|
883
1248
|
fn N(e: anytype) u8 {
|
|
884
|
-
return @
|
|
1249
|
+
return @intFromEnum(e);
|
|
885
1250
|
}
|
|
886
1251
|
|
|
887
1252
|
const p1 = Player.P1;
|
|
@@ -892,49 +1257,70 @@ const gen1 = struct {
|
|
|
892
1257
|
pub const helpers = @import("../gen1/helpers.zig");
|
|
893
1258
|
};
|
|
894
1259
|
|
|
1260
|
+
const gen2 = struct {
|
|
1261
|
+
pub usingnamespace @import("../gen2/data.zig");
|
|
1262
|
+
pub const helpers = @import("../gen2/helpers.zig");
|
|
1263
|
+
};
|
|
1264
|
+
|
|
895
1265
|
var buf: [gen1.LOGS_SIZE]u8 = undefined;
|
|
896
|
-
var stream =
|
|
1266
|
+
var stream: ByteStream = .{ .buffer = &buf };
|
|
897
1267
|
var log: FixedLog = .{ .writer = stream.writer() };
|
|
898
1268
|
|
|
899
|
-
const
|
|
900
|
-
const
|
|
1269
|
+
const M1 = gen1.Move;
|
|
1270
|
+
const S1 = gen1.Species;
|
|
1271
|
+
|
|
1272
|
+
const M2 = gen2.Move;
|
|
1273
|
+
const S2 = gen2.Species;
|
|
1274
|
+
const I2 = gen2.Item;
|
|
1275
|
+
const W2 = gen2.Weather;
|
|
901
1276
|
|
|
902
1277
|
fn expectLog1(expected: []const u8, actual: []const u8) !void {
|
|
903
|
-
return expectLog(
|
|
1278
|
+
return expectLog(gen1, expected, actual, 0);
|
|
904
1279
|
}
|
|
905
1280
|
|
|
906
|
-
fn
|
|
1281
|
+
fn expectLog2(expected: []const u8, actual: []const u8) !void {
|
|
1282
|
+
return expectLog(gen2, expected, actual, 0);
|
|
1283
|
+
}
|
|
1284
|
+
|
|
1285
|
+
fn formatter(comptime gen: anytype, kind: Kind, byte: u8) []const u8 {
|
|
907
1286
|
return switch (kind) {
|
|
908
|
-
.Move => @tagName(@
|
|
909
|
-
.Species => @tagName(@
|
|
910
|
-
.Type => @tagName(@
|
|
911
|
-
.Status =>
|
|
1287
|
+
.Move => @tagName(@as(gen.Move, @enumFromInt(byte))),
|
|
1288
|
+
.Species => @tagName(@as(gen.Species, @enumFromInt(byte))),
|
|
1289
|
+
.Type => @tagName(@as(gen.Type, @enumFromInt(byte))),
|
|
1290
|
+
.Status => gen.Status.name(byte),
|
|
1291
|
+
.Item => if (@hasDecl(gen, "Item"))
|
|
1292
|
+
@tagName(@as(gen.Item, @enumFromInt(byte)))
|
|
1293
|
+
else
|
|
1294
|
+
unreachable,
|
|
1295
|
+
.Weather => if (@hasDecl(gen, "Weather"))
|
|
1296
|
+
@tagName(@as(gen.Weather, @enumFromInt(byte)))
|
|
1297
|
+
else
|
|
1298
|
+
unreachable,
|
|
912
1299
|
};
|
|
913
1300
|
}
|
|
914
1301
|
|
|
915
1302
|
test "|move|" {
|
|
916
|
-
try log.move(p2.ident(4),
|
|
1303
|
+
try log.move(p2.ident(4), M1.Thunderbolt, p1.ident(5));
|
|
917
1304
|
try expectLog1(
|
|
918
|
-
&.{ N(ArgType.Move), 0b1100, N(
|
|
1305
|
+
&.{ N(ArgType.Move), 0b1100, N(M1.Thunderbolt), 0b0101, N(Move.None) },
|
|
919
1306
|
buf[0..5],
|
|
920
1307
|
);
|
|
921
1308
|
stream.reset();
|
|
922
1309
|
|
|
923
|
-
try log.
|
|
924
|
-
const wrap = N(M.Wrap);
|
|
1310
|
+
try log.moveFrom(p2.ident(4), M1.Pound, p1.ident(5), M1.Metronome);
|
|
925
1311
|
try expectLog1(
|
|
926
|
-
&.{ N(ArgType.Move), 0b1100,
|
|
1312
|
+
&.{ N(ArgType.Move), 0b1100, N(M1.Pound), 0b0101, N(Move.From), N(M1.Metronome) },
|
|
927
1313
|
buf[0..6],
|
|
928
1314
|
);
|
|
929
1315
|
stream.reset();
|
|
930
1316
|
|
|
931
|
-
try log.move(p2.ident(4),
|
|
1317
|
+
try log.move(p2.ident(4), M1.SkullBash, .{});
|
|
932
1318
|
try log.laststill();
|
|
933
1319
|
try expectLog1(
|
|
934
1320
|
&.{
|
|
935
1321
|
N(ArgType.Move),
|
|
936
1322
|
0b1100,
|
|
937
|
-
N(
|
|
1323
|
+
N(M1.SkullBash),
|
|
938
1324
|
0,
|
|
939
1325
|
N(Move.None),
|
|
940
1326
|
N(ArgType.LastStill),
|
|
@@ -943,13 +1329,13 @@ test "|move|" {
|
|
|
943
1329
|
);
|
|
944
1330
|
stream.reset();
|
|
945
1331
|
|
|
946
|
-
try log.move(p2.ident(4),
|
|
1332
|
+
try log.move(p2.ident(4), M1.Tackle, p1.ident(5));
|
|
947
1333
|
try log.lastmiss();
|
|
948
1334
|
try expectLog1(
|
|
949
1335
|
&.{
|
|
950
1336
|
N(ArgType.Move),
|
|
951
1337
|
0b1100,
|
|
952
|
-
N(
|
|
1338
|
+
N(M1.Tackle),
|
|
953
1339
|
0b0101,
|
|
954
1340
|
N(Move.None),
|
|
955
1341
|
N(ArgType.LastMiss),
|
|
@@ -968,8 +1354,8 @@ test "|switch|" {
|
|
|
968
1354
|
try log.switched(p2.ident(3), &snorlax);
|
|
969
1355
|
const par = 0b1000000;
|
|
970
1356
|
var expected: []const u8 = switch (endian) {
|
|
971
|
-
.Big => &.{ N(ArgType.Switch), 0b1011, N(
|
|
972
|
-
.Little => &.{ N(ArgType.Switch), 0b1011, N(
|
|
1357
|
+
.Big => &.{ N(ArgType.Switch), 0b1011, N(S1.Snorlax), 91, 0, 200, 1, 144, par },
|
|
1358
|
+
.Little => &.{ N(ArgType.Switch), 0b1011, N(S1.Snorlax), 91, 200, 0, 144, 1, par },
|
|
973
1359
|
};
|
|
974
1360
|
try expectLog1(expected, buf[0..9]);
|
|
975
1361
|
stream.reset();
|
|
@@ -979,8 +1365,8 @@ test "|switch|" {
|
|
|
979
1365
|
snorlax.status = 0;
|
|
980
1366
|
try log.switched(p2.ident(3), &snorlax);
|
|
981
1367
|
expected = switch (endian) {
|
|
982
|
-
.Big => &.{ N(ArgType.Switch), 0b1011, N(
|
|
983
|
-
.Little => &.{ N(ArgType.Switch), 0b1011, N(
|
|
1368
|
+
.Big => &.{ N(ArgType.Switch), 0b1011, N(S1.Snorlax), 100, 0, 0, 1, 144, 0 },
|
|
1369
|
+
.Little => &.{ N(ArgType.Switch), 0b1011, N(S1.Snorlax), 100, 0, 0, 144, 1, 0 },
|
|
984
1370
|
};
|
|
985
1371
|
try expectLog1(expected, buf[0..9]);
|
|
986
1372
|
stream.reset();
|
|
@@ -988,11 +1374,30 @@ test "|switch|" {
|
|
|
988
1374
|
snorlax.hp = 400;
|
|
989
1375
|
try log.switched(p2.ident(3), &snorlax);
|
|
990
1376
|
expected = switch (endian) {
|
|
991
|
-
.Big => &.{ N(ArgType.Switch), 0b1011, N(
|
|
992
|
-
.Little => &.{ N(ArgType.Switch), 0b1011, N(
|
|
1377
|
+
.Big => &.{ N(ArgType.Switch), 0b1011, N(S1.Snorlax), 100, 1, 144, 1, 144, 0 },
|
|
1378
|
+
.Little => &.{ N(ArgType.Switch), 0b1011, N(S1.Snorlax), 100, 144, 1, 144, 1, 0 },
|
|
993
1379
|
};
|
|
994
1380
|
try expectLog1(expected, buf[0..9]);
|
|
995
1381
|
stream.reset();
|
|
1382
|
+
|
|
1383
|
+
var blissey = gen2.helpers.Pokemon.init(.{ .species = .Blissey, .moves = &.{.Splash} });
|
|
1384
|
+
blissey.level = 91;
|
|
1385
|
+
blissey.hp = 200;
|
|
1386
|
+
blissey.stats.hp = 400;
|
|
1387
|
+
blissey.status = gen2.Status.init(.PAR);
|
|
1388
|
+
try log.switched(p2.ident(3), &blissey);
|
|
1389
|
+
expected = &(.{
|
|
1390
|
+
N(ArgType.Switch),
|
|
1391
|
+
0b1011,
|
|
1392
|
+
N(S2.Blissey),
|
|
1393
|
+
N(gen2.Gender.Female),
|
|
1394
|
+
91,
|
|
1395
|
+
} ++ switch (endian) {
|
|
1396
|
+
.Big => .{ 0, 200, 1, 144, par },
|
|
1397
|
+
.Little => .{ 200, 0, 144, 1, par },
|
|
1398
|
+
});
|
|
1399
|
+
try expectLog2(expected, buf[0..10]);
|
|
1400
|
+
stream.reset();
|
|
996
1401
|
}
|
|
997
1402
|
|
|
998
1403
|
test "|cant|" {
|
|
@@ -1000,8 +1405,8 @@ test "|cant|" {
|
|
|
1000
1405
|
try expectLog1(&.{ N(ArgType.Cant), 0b1110, N(Cant.Bound) }, buf[0..3]);
|
|
1001
1406
|
stream.reset();
|
|
1002
1407
|
|
|
1003
|
-
try log.disabled(p1.ident(2),
|
|
1004
|
-
try expectLog1(&.{ N(ArgType.Cant), 2, N(Cant.Disable), N(
|
|
1408
|
+
try log.disabled(p1.ident(2), M1.Earthquake);
|
|
1409
|
+
try expectLog1(&.{ N(ArgType.Cant), 2, N(Cant.Disable), N(M1.Earthquake) }, buf[0..4]);
|
|
1005
1410
|
stream.reset();
|
|
1006
1411
|
}
|
|
1007
1412
|
|
|
@@ -1111,9 +1516,9 @@ test "|-status|" {
|
|
|
1111
1516
|
try expectLog1(&.{ N(ArgType.Status), 0b1010, 0b1000, N(Status.Silent) }, buf[0..4]);
|
|
1112
1517
|
stream.reset();
|
|
1113
1518
|
|
|
1114
|
-
try log.statusFrom(p1.ident(1), gen1.Status.init(.PAR),
|
|
1519
|
+
try log.statusFrom(p1.ident(1), gen1.Status.init(.PAR), M1.BodySlam);
|
|
1115
1520
|
try expectLog1(
|
|
1116
|
-
&.{ N(ArgType.Status), 0b0001, 0b1000000, N(Status.From), N(
|
|
1521
|
+
&.{ N(ArgType.Status), 0b0001, 0b1000000, N(Status.From), N(M1.BodySlam) },
|
|
1117
1522
|
buf[0..5],
|
|
1118
1523
|
);
|
|
1119
1524
|
stream.reset();
|
|
@@ -1184,8 +1589,8 @@ test "|-hitcount|" {
|
|
|
1184
1589
|
}
|
|
1185
1590
|
|
|
1186
1591
|
test "|-prepare|" {
|
|
1187
|
-
try log.prepare(p2.ident(2),
|
|
1188
|
-
try expectLog1(&.{ N(ArgType.Prepare), 0b1010, N(
|
|
1592
|
+
try log.prepare(p2.ident(2), M1.Dig);
|
|
1593
|
+
try expectLog1(&.{ N(ArgType.Prepare), 0b1010, N(M1.Dig) }, buf[0..3]);
|
|
1189
1594
|
stream.reset();
|
|
1190
1595
|
}
|
|
1191
1596
|
|
|
@@ -1242,12 +1647,12 @@ test "|-start|" {
|
|
|
1242
1647
|
);
|
|
1243
1648
|
stream.reset();
|
|
1244
1649
|
|
|
1245
|
-
try log.startEffect(p1.ident(2), .Disable,
|
|
1246
|
-
try expectLog1(&.{ N(ArgType.Start), 0b0010, N(Start.Disable), N(
|
|
1650
|
+
try log.startEffect(p1.ident(2), .Disable, M1.Surf);
|
|
1651
|
+
try expectLog1(&.{ N(ArgType.Start), 0b0010, N(Start.Disable), N(M1.Surf) }, buf[0..4]);
|
|
1247
1652
|
stream.reset();
|
|
1248
1653
|
|
|
1249
|
-
try log.startEffect(p1.ident(2), .Mimic,
|
|
1250
|
-
try expectLog1(&.{ N(ArgType.Start), 0b0010, N(Start.Mimic), N(
|
|
1654
|
+
try log.startEffect(p1.ident(2), .Mimic, M1.Surf);
|
|
1655
|
+
try expectLog1(&.{ N(ArgType.Start), 0b0010, N(Start.Mimic), N(M1.Surf) }, buf[0..4]);
|
|
1251
1656
|
stream.reset();
|
|
1252
1657
|
}
|
|
1253
1658
|
|
|
@@ -1266,21 +1671,25 @@ test "|-ohko|" {
|
|
|
1266
1671
|
try expectLog1(&.{N(ArgType.OHKO)}, buf[0..1]);
|
|
1267
1672
|
stream.reset();
|
|
1268
1673
|
}
|
|
1674
|
+
|
|
1269
1675
|
test "|-crit|" {
|
|
1270
1676
|
try log.crit(p2.ident(5));
|
|
1271
1677
|
try expectLog1(&.{ N(ArgType.Crit), 0b1101 }, buf[0..2]);
|
|
1272
1678
|
stream.reset();
|
|
1273
1679
|
}
|
|
1680
|
+
|
|
1274
1681
|
test "|-supereffective|" {
|
|
1275
1682
|
try log.supereffective(p1.ident(1));
|
|
1276
1683
|
try expectLog1(&.{ N(ArgType.SuperEffective), 0b0001 }, buf[0..2]);
|
|
1277
1684
|
stream.reset();
|
|
1278
1685
|
}
|
|
1686
|
+
|
|
1279
1687
|
test "|-resisted|" {
|
|
1280
1688
|
try log.resisted(p2.ident(2));
|
|
1281
1689
|
try expectLog1(&.{ N(ArgType.Resisted), 0b1010 }, buf[0..2]);
|
|
1282
1690
|
stream.reset();
|
|
1283
1691
|
}
|
|
1692
|
+
|
|
1284
1693
|
test "|-immune|" {
|
|
1285
1694
|
try log.immune(p1.ident(3), .None);
|
|
1286
1695
|
try expectLog1(&.{ N(ArgType.Immune), 0b0011, N(Immune.None) }, buf[0..3]);
|
|
@@ -1290,8 +1699,125 @@ test "|-immune|" {
|
|
|
1290
1699
|
try expectLog1(&.{ N(ArgType.Immune), 0b1010, N(Immune.OHKO) }, buf[0..3]);
|
|
1291
1700
|
stream.reset();
|
|
1292
1701
|
}
|
|
1702
|
+
|
|
1293
1703
|
test "|-transform|" {
|
|
1294
1704
|
try log.transform(p2.ident(4), p1.ident(5));
|
|
1295
1705
|
try expectLog1(&.{ N(ArgType.Transform), 0b1100, 0b0101 }, buf[0..3]);
|
|
1296
1706
|
stream.reset();
|
|
1297
1707
|
}
|
|
1708
|
+
|
|
1709
|
+
test "|drag|" {
|
|
1710
|
+
var blissey = gen2.helpers.Pokemon.init(.{ .species = .Blissey, .moves = &.{.Splash} });
|
|
1711
|
+
blissey.level = 91;
|
|
1712
|
+
blissey.hp = 200;
|
|
1713
|
+
blissey.stats.hp = 400;
|
|
1714
|
+
blissey.status = gen2.Status.init(.PAR);
|
|
1715
|
+
try log.drag(p2.ident(3), &blissey);
|
|
1716
|
+
const par = 0b1000000;
|
|
1717
|
+
const expected = &(.{
|
|
1718
|
+
N(ArgType.Drag),
|
|
1719
|
+
0b1011,
|
|
1720
|
+
N(S2.Blissey),
|
|
1721
|
+
N(gen2.Gender.Female),
|
|
1722
|
+
91,
|
|
1723
|
+
} ++ switch (endian) {
|
|
1724
|
+
.Big => .{ 0, 200, 1, 144, par },
|
|
1725
|
+
.Little => .{ 200, 0, 144, 1, par },
|
|
1726
|
+
});
|
|
1727
|
+
try expectLog2(expected, buf[0..10]);
|
|
1728
|
+
stream.reset();
|
|
1729
|
+
}
|
|
1730
|
+
|
|
1731
|
+
test "|-item|" {
|
|
1732
|
+
try log.item(p2.ident(2), I2.GoldBerry, p1.ident(4));
|
|
1733
|
+
try expectLog2(&.{ N(ArgType.Item), 0b1010, N(I2.GoldBerry), 0b0100 }, buf[0..4]);
|
|
1734
|
+
stream.reset();
|
|
1735
|
+
}
|
|
1736
|
+
|
|
1737
|
+
test "|-enditem|" {
|
|
1738
|
+
try log.enditem(p1.ident(1), I2.BerserkGene, .None);
|
|
1739
|
+
try expectLog2(&.{ N(ArgType.EndItem), 0b0001, N(I2.BerserkGene), N(EndItem.None) }, buf[0..4]);
|
|
1740
|
+
stream.reset();
|
|
1741
|
+
|
|
1742
|
+
try log.enditem(p2.ident(4), I2.PRZCureBerry, .Eat);
|
|
1743
|
+
try expectLog2(&.{ N(ArgType.EndItem), 0b1100, N(I2.PRZCureBerry), N(EndItem.Eat) }, buf[0..4]);
|
|
1744
|
+
stream.reset();
|
|
1745
|
+
}
|
|
1746
|
+
|
|
1747
|
+
test "|-cureteam|" {
|
|
1748
|
+
try log.cureteam(p2.ident(5));
|
|
1749
|
+
try expectLog2(&.{ N(ArgType.CureTeam), 0b1101 }, buf[0..2]);
|
|
1750
|
+
stream.reset();
|
|
1751
|
+
}
|
|
1752
|
+
|
|
1753
|
+
test "|-sethp|" {
|
|
1754
|
+
var blissey = gen2.helpers.Pokemon.init(.{ .species = .Blissey, .moves = &.{.PainSplit} });
|
|
1755
|
+
blissey.hp = 612;
|
|
1756
|
+
try log.sethp(p2.ident(2), &blissey, .Silent);
|
|
1757
|
+
var expected: []const u8 = switch (endian) {
|
|
1758
|
+
.Big => &.{ N(ArgType.SetHP), 0b1010, 2, 100, 2, 201, 0, N(SetHP.Silent) },
|
|
1759
|
+
.Little => &.{ N(ArgType.SetHP), 0b1010, 100, 2, 201, 2, 0, N(SetHP.Silent) },
|
|
1760
|
+
};
|
|
1761
|
+
try expectLog2(expected, buf[0..8]);
|
|
1762
|
+
stream.reset();
|
|
1763
|
+
}
|
|
1764
|
+
|
|
1765
|
+
test "|-setboost|" {
|
|
1766
|
+
try log.setboost(p2.ident(6), 6);
|
|
1767
|
+
try expectLog2(&.{ N(ArgType.SetBoost), 0b1110, 12 }, buf[0..3]);
|
|
1768
|
+
stream.reset();
|
|
1769
|
+
|
|
1770
|
+
try log.setboost(p2.ident(3), 2);
|
|
1771
|
+
try expectLog2(&.{ N(ArgType.SetBoost), 0b1011, 8 }, buf[0..3]);
|
|
1772
|
+
stream.reset();
|
|
1773
|
+
}
|
|
1774
|
+
|
|
1775
|
+
test "|-copyboost|" {
|
|
1776
|
+
try log.copyboost(p2.ident(3), p1.ident(6));
|
|
1777
|
+
try expectLog2(&.{ N(ArgType.CopyBoost), 0b1011, 0b0110 }, buf[0..3]);
|
|
1778
|
+
stream.reset();
|
|
1779
|
+
}
|
|
1780
|
+
|
|
1781
|
+
test "|-sidestart|" {
|
|
1782
|
+
try log.sidestart(.P2, .Reflect);
|
|
1783
|
+
try expectLog2(&.{ N(ArgType.SideStart), 1, N(Side.Reflect) }, buf[0..3]);
|
|
1784
|
+
stream.reset();
|
|
1785
|
+
}
|
|
1786
|
+
|
|
1787
|
+
test "|-sideend|" {
|
|
1788
|
+
try log.sideend(.P2, .LightScreen);
|
|
1789
|
+
try expectLog2(&.{ N(ArgType.SideEnd), 1, N(Side.LightScreen) }, buf[0..3]);
|
|
1790
|
+
stream.reset();
|
|
1791
|
+
|
|
1792
|
+
try log.spikesend(.P1, M2.RapidSpin, p1.ident(3));
|
|
1793
|
+
try expectLog2(&.{
|
|
1794
|
+
N(ArgType.SideEnd),
|
|
1795
|
+
0,
|
|
1796
|
+
N(Side.Spikes),
|
|
1797
|
+
N(M2.RapidSpin),
|
|
1798
|
+
0b0011,
|
|
1799
|
+
}, buf[0..5]);
|
|
1800
|
+
stream.reset();
|
|
1801
|
+
}
|
|
1802
|
+
|
|
1803
|
+
test "|-singlemove|" {
|
|
1804
|
+
try log.singlemove(p2.ident(2), M2.DestinyBond);
|
|
1805
|
+
try expectLog2(&.{ N(ArgType.SingleMove), 0b1010, N(M2.DestinyBond) }, buf[0..3]);
|
|
1806
|
+
stream.reset();
|
|
1807
|
+
}
|
|
1808
|
+
|
|
1809
|
+
test "|-singleturn|" {
|
|
1810
|
+
try log.singleturn(p1.ident(3), M2.Protect);
|
|
1811
|
+
try expectLog2(&.{ N(ArgType.SingleTurn), 0b0011, N(M2.Protect) }, buf[0..3]);
|
|
1812
|
+
stream.reset();
|
|
1813
|
+
}
|
|
1814
|
+
|
|
1815
|
+
test "|-weather|" {
|
|
1816
|
+
try log.weather(W2.Rain, .Upkeep);
|
|
1817
|
+
try expectLog2(&.{ N(ArgType.Weather), N(W2.Rain), N(Weather.Upkeep) }, buf[0..3]);
|
|
1818
|
+
stream.reset();
|
|
1819
|
+
|
|
1820
|
+
try log.weather(W2.None, .None);
|
|
1821
|
+
try expectLog2(&.{ N(ArgType.Weather), N(W2.None), N(Weather.None) }, buf[0..3]);
|
|
1822
|
+
stream.reset();
|
|
1823
|
+
}
|