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