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