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