@pkmn/engine 0.1.0-dev.8b83af6b → 0.1.0-dev.900756a9
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 +53 -42
- 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 +26 -4
- package/build/pkg/data/protocol.json +69 -12
- package/build/pkg/data.d.ts +2 -2
- package/build/pkg/gen1.js +15 -18
- package/build/pkg/gen1.js.map +1 -1
- package/build/pkg/protocol.js +56 -37
- package/build/pkg/protocol.js.map +1 -1
- package/build/tools/debug.js +3 -1
- package/build/tools/debug.js.map +1 -1
- package/build.zig +96 -65
- package/package.json +40 -19
- package/src/bin/install-pkmn-engine +10 -5
- package/src/lib/binding/node.zig +40 -132
- package/src/lib/binding/wasm.zig +2 -0
- package/src/lib/common/battle.zig +17 -0
- package/src/lib/common/data.zig +8 -20
- 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 +635 -88
- package/src/lib/common/rational.zig +353 -0
- package/src/lib/common/rng.zig +19 -10
- package/src/lib/common/util.zig +12 -0
- package/src/lib/gen1/README.md +284 -204
- 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 +7 -7
- package/src/lib/gen1/data.zig +67 -58
- package/src/lib/gen1/helpers.zig +566 -10
- package/src/lib/gen1/mechanics.zig +800 -563
- 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 +12 -18
- package/src/lib/gen2/data/moves.zig +663 -569
- package/src/lib/gen2/data/species.zig +1 -1
- package/src/lib/gen2/data/types.zig +134 -31
- package/src/lib/gen2/data.zig +115 -78
- package/src/lib/gen2/generated.zig +808 -0
- package/src/lib/gen2/helpers.zig +11 -17
- package/src/lib/gen2/mechanics.zig +3492 -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
328
|
@intFromEnum(ArgType.Move),
|
|
237
329
|
@as(u8, @bitCast(source)),
|
|
238
330
|
@intFromEnum(m),
|
|
239
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(&.{ @intFromEnum(
|
|
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,6 +373,7 @@ 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
379
|
@intFromEnum(ArgType.Cant),
|
|
@@ -273,6 +384,7 @@ pub fn Log(comptime Writer: type) type {
|
|
|
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
389
|
@intFromEnum(ArgType.Cant),
|
|
278
390
|
@as(u8, @bitCast(ident)),
|
|
@@ -283,12 +395,14 @@ pub fn Log(comptime Writer: type) type {
|
|
|
283
395
|
|
|
284
396
|
pub fn faint(self: Self, ident: ID, done: bool) Error!void {
|
|
285
397
|
if (!enabled) return;
|
|
398
|
+
|
|
286
399
|
try self.writer.writeAll(&.{ @intFromEnum(ArgType.Faint), @as(u8, @bitCast(ident)) });
|
|
287
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;
|
|
405
|
+
|
|
292
406
|
try self.writer.writeByte(@intFromEnum(ArgType.Turn));
|
|
293
407
|
try self.writer.writeIntNative(u16, num);
|
|
294
408
|
try self.writer.writeByte(@intFromEnum(ArgType.None));
|
|
@@ -296,6 +410,7 @@ pub fn Log(comptime Writer: type) type {
|
|
|
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
415
|
@intFromEnum(ArgType.Win),
|
|
301
416
|
@intFromEnum(player),
|
|
@@ -305,11 +420,13 @@ pub fn Log(comptime Writer: type) type {
|
|
|
305
420
|
|
|
306
421
|
pub fn tie(self: Self) Error!void {
|
|
307
422
|
if (!enabled) return;
|
|
423
|
+
|
|
308
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;
|
|
429
|
+
|
|
313
430
|
assert(@intFromEnum(reason) <= @intFromEnum(Damage.LeechSeed));
|
|
314
431
|
try self.writer.writeAll(&.{ @intFromEnum(ArgType.Damage), @as(u8, @bitCast(ident)) });
|
|
315
432
|
try self.writer.writeIntNative(u16, pokemon.hp);
|
|
@@ -325,6 +442,7 @@ pub fn Log(comptime Writer: type) type {
|
|
|
325
442
|
source: ID,
|
|
326
443
|
) Error!void {
|
|
327
444
|
if (!enabled) return;
|
|
445
|
+
|
|
328
446
|
assert(@intFromEnum(reason) == @intFromEnum(Damage.RecoilOf));
|
|
329
447
|
try self.writer.writeAll(&.{ @intFromEnum(ArgType.Damage), @as(u8, @bitCast(ident)) });
|
|
330
448
|
try self.writer.writeIntNative(u16, pokemon.hp);
|
|
@@ -336,17 +454,20 @@ pub fn Log(comptime Writer: type) type {
|
|
|
336
454
|
});
|
|
337
455
|
}
|
|
338
456
|
|
|
339
|
-
|
|
457
|
+
// args: ident: ID, pokemon: anytype, reason: Heal
|
|
458
|
+
pub fn heal(self: Self, args: anytype) Error!void {
|
|
340
459
|
if (!enabled) return;
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
try self.writer.
|
|
344
|
-
try self.writer.writeIntNative(u16,
|
|
345
|
-
try self.writer.
|
|
460
|
+
|
|
461
|
+
assert(args[2] != .Drain);
|
|
462
|
+
try self.writer.writeAll(&.{ @intFromEnum(ArgType.Heal), @as(u8, @bitCast(args[0])) });
|
|
463
|
+
try self.writer.writeIntNative(u16, args[1].hp);
|
|
464
|
+
try self.writer.writeIntNative(u16, args[1].stats.hp);
|
|
465
|
+
try self.writer.writeAll(&.{ args[1].status, @intFromEnum(args[2]) });
|
|
346
466
|
}
|
|
347
467
|
|
|
348
468
|
pub fn drain(self: Self, source: ID, pokemon: anytype, target: ID) Error!void {
|
|
349
469
|
if (!enabled) return;
|
|
470
|
+
|
|
350
471
|
try self.writer.writeAll(&.{ @intFromEnum(ArgType.Heal), @as(u8, @bitCast(source)) });
|
|
351
472
|
try self.writer.writeIntNative(u16, pokemon.hp);
|
|
352
473
|
try self.writer.writeIntNative(u16, pokemon.stats.hp);
|
|
@@ -359,6 +480,7 @@ pub fn Log(comptime Writer: type) type {
|
|
|
359
480
|
|
|
360
481
|
pub fn status(self: Self, ident: ID, value: u8, reason: Status) Error!void {
|
|
361
482
|
if (!enabled) return;
|
|
483
|
+
|
|
362
484
|
assert(reason != .From);
|
|
363
485
|
try self.writer.writeAll(&.{
|
|
364
486
|
@intFromEnum(ArgType.Status),
|
|
@@ -370,6 +492,7 @@ pub fn Log(comptime Writer: type) type {
|
|
|
370
492
|
|
|
371
493
|
pub fn statusFrom(self: Self, ident: ID, value: u8, m: anytype) Error!void {
|
|
372
494
|
if (!enabled) return;
|
|
495
|
+
|
|
373
496
|
try self.writer.writeAll(&.{
|
|
374
497
|
@intFromEnum(ArgType.Status),
|
|
375
498
|
@as(u8, @bitCast(ident)),
|
|
@@ -381,6 +504,7 @@ pub fn Log(comptime Writer: type) type {
|
|
|
381
504
|
|
|
382
505
|
pub fn curestatus(self: Self, ident: ID, value: u8, reason: CureStatus) Error!void {
|
|
383
506
|
if (!enabled) return;
|
|
507
|
+
|
|
384
508
|
try self.writer.writeAll(&.{
|
|
385
509
|
@intFromEnum(ArgType.CureStatus),
|
|
386
510
|
@as(u8, @bitCast(ident)),
|
|
@@ -391,6 +515,7 @@ pub fn Log(comptime Writer: type) type {
|
|
|
391
515
|
|
|
392
516
|
pub fn boost(self: Self, ident: ID, reason: Boost, num: i8) Error!void {
|
|
393
517
|
if (!enabled) return;
|
|
518
|
+
|
|
394
519
|
assert(num != 0 and (reason != .Rage or num > 0));
|
|
395
520
|
try self.writer.writeAll(&.{
|
|
396
521
|
@intFromEnum(ArgType.Boost),
|
|
@@ -402,11 +527,13 @@ pub fn Log(comptime Writer: type) type {
|
|
|
402
527
|
|
|
403
528
|
pub fn clearallboost(self: Self) Error!void {
|
|
404
529
|
if (!enabled) return;
|
|
530
|
+
|
|
405
531
|
try self.writer.writeAll(&.{@intFromEnum(ArgType.ClearAllBoost)});
|
|
406
532
|
}
|
|
407
533
|
|
|
408
534
|
pub fn fail(self: Self, ident: ID, reason: Fail) Error!void {
|
|
409
535
|
if (!enabled) return;
|
|
536
|
+
|
|
410
537
|
try self.writer.writeAll(&.{
|
|
411
538
|
@intFromEnum(ArgType.Fail),
|
|
412
539
|
@as(u8, @bitCast(ident)),
|
|
@@ -416,11 +543,13 @@ pub fn Log(comptime Writer: type) type {
|
|
|
416
543
|
|
|
417
544
|
pub fn miss(self: Self, source: ID) Error!void {
|
|
418
545
|
if (!enabled) return;
|
|
546
|
+
|
|
419
547
|
try self.writer.writeAll(&.{ @intFromEnum(ArgType.Miss), @as(u8, @bitCast(source)) });
|
|
420
548
|
}
|
|
421
549
|
|
|
422
550
|
pub fn hitcount(self: Self, ident: ID, num: u8) Error!void {
|
|
423
551
|
if (!enabled) return;
|
|
552
|
+
|
|
424
553
|
try self.writer.writeAll(&.{
|
|
425
554
|
@intFromEnum(ArgType.HitCount),
|
|
426
555
|
@as(u8, @bitCast(ident)),
|
|
@@ -430,6 +559,7 @@ pub fn Log(comptime Writer: type) type {
|
|
|
430
559
|
|
|
431
560
|
pub fn prepare(self: Self, source: ID, m: anytype) Error!void {
|
|
432
561
|
if (!enabled) return;
|
|
562
|
+
|
|
433
563
|
try self.writer.writeAll(&.{
|
|
434
564
|
@intFromEnum(ArgType.Prepare),
|
|
435
565
|
@as(u8, @bitCast(source)),
|
|
@@ -439,6 +569,7 @@ pub fn Log(comptime Writer: type) type {
|
|
|
439
569
|
|
|
440
570
|
pub fn mustrecharge(self: Self, ident: ID) Error!void {
|
|
441
571
|
if (!enabled) return;
|
|
572
|
+
|
|
442
573
|
try self.writer.writeAll(&.{
|
|
443
574
|
@intFromEnum(ArgType.MustRecharge),
|
|
444
575
|
@as(u8, @bitCast(ident)),
|
|
@@ -447,20 +578,47 @@ pub fn Log(comptime Writer: type) type {
|
|
|
447
578
|
|
|
448
579
|
pub fn activate(self: Self, ident: ID, reason: Activate) Error!void {
|
|
449
580
|
if (!enabled) return;
|
|
581
|
+
|
|
582
|
+
assert(reason != .SubstituteBlock); // TODO
|
|
583
|
+
try self.writer.writeAll(&.{
|
|
584
|
+
@intFromEnum(ArgType.Activate),
|
|
585
|
+
@as(u8, @bitCast(ident)),
|
|
586
|
+
@intFromEnum(reason),
|
|
587
|
+
});
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
pub fn activateMove(self: Self, ident: ID, reason: Activate, m: anytype) Error!void {
|
|
591
|
+
if (!enabled) return;
|
|
592
|
+
|
|
593
|
+
assert(reason == .SubstituteBlock); // TODO
|
|
450
594
|
try self.writer.writeAll(&.{
|
|
451
595
|
@intFromEnum(ArgType.Activate),
|
|
452
596
|
@as(u8, @bitCast(ident)),
|
|
453
597
|
@intFromEnum(reason),
|
|
598
|
+
@intFromEnum(m),
|
|
599
|
+
});
|
|
600
|
+
}
|
|
601
|
+
|
|
602
|
+
pub fn magnitude(self: Self, ident: ID, num: u8) Error!void {
|
|
603
|
+
if (!enabled) return;
|
|
604
|
+
|
|
605
|
+
try self.writer.writeAll(&.{
|
|
606
|
+
@intFromEnum(ArgType.Activate),
|
|
607
|
+
@as(u8, @bitCast(ident)),
|
|
608
|
+
@intFromEnum(Activate.Magnitude),
|
|
609
|
+
num,
|
|
454
610
|
});
|
|
455
611
|
}
|
|
456
612
|
|
|
457
613
|
pub fn fieldactivate(self: Self) Error!void {
|
|
458
614
|
if (!enabled) return;
|
|
615
|
+
|
|
459
616
|
try self.writer.writeAll(&.{@intFromEnum(ArgType.FieldActivate)});
|
|
460
617
|
}
|
|
461
618
|
|
|
462
619
|
pub fn start(self: Self, ident: ID, reason: Start) Error!void {
|
|
463
620
|
if (!enabled) return;
|
|
621
|
+
|
|
464
622
|
assert(@intFromEnum(reason) < @intFromEnum(Start.TypeChange));
|
|
465
623
|
try self.writer.writeAll(&.{
|
|
466
624
|
@intFromEnum(ArgType.Start),
|
|
@@ -471,6 +629,7 @@ pub fn Log(comptime Writer: type) type {
|
|
|
471
629
|
|
|
472
630
|
pub fn typechange(self: Self, source: ID, types: anytype, target: ID) Error!void {
|
|
473
631
|
if (!enabled) return;
|
|
632
|
+
|
|
474
633
|
try self.writer.writeAll(&.{
|
|
475
634
|
@intFromEnum(ArgType.Start),
|
|
476
635
|
@as(u8, @bitCast(source)),
|
|
@@ -482,6 +641,7 @@ pub fn Log(comptime Writer: type) type {
|
|
|
482
641
|
|
|
483
642
|
pub fn startEffect(self: Self, ident: ID, reason: Start, m: anytype) Error!void {
|
|
484
643
|
if (!enabled) return;
|
|
644
|
+
|
|
485
645
|
assert(@intFromEnum(reason) > @intFromEnum(Start.TypeChange));
|
|
486
646
|
try self.writer.writeAll(&.{
|
|
487
647
|
@intFromEnum(ArgType.Start),
|
|
@@ -493,6 +653,7 @@ pub fn Log(comptime Writer: type) type {
|
|
|
493
653
|
|
|
494
654
|
pub fn end(self: Self, ident: ID, reason: End) Error!void {
|
|
495
655
|
if (!enabled) return;
|
|
656
|
+
|
|
496
657
|
try self.writer.writeAll(&.{
|
|
497
658
|
@intFromEnum(ArgType.End),
|
|
498
659
|
@as(u8, @bitCast(ident)),
|
|
@@ -502,16 +663,19 @@ pub fn Log(comptime Writer: type) type {
|
|
|
502
663
|
|
|
503
664
|
pub fn ohko(self: Self) Error!void {
|
|
504
665
|
if (!enabled) return;
|
|
666
|
+
|
|
505
667
|
try self.writer.writeAll(&.{@intFromEnum(ArgType.OHKO)});
|
|
506
668
|
}
|
|
507
669
|
|
|
508
670
|
pub fn crit(self: Self, ident: ID) Error!void {
|
|
509
671
|
if (!enabled) return;
|
|
672
|
+
|
|
510
673
|
try self.writer.writeAll(&.{ @intFromEnum(ArgType.Crit), @as(u8, @bitCast(ident)) });
|
|
511
674
|
}
|
|
512
675
|
|
|
513
676
|
pub fn supereffective(self: Self, ident: ID) Error!void {
|
|
514
677
|
if (!enabled) return;
|
|
678
|
+
|
|
515
679
|
try self.writer.writeAll(&.{
|
|
516
680
|
@intFromEnum(ArgType.SuperEffective),
|
|
517
681
|
@as(u8, @bitCast(ident)),
|
|
@@ -520,6 +684,7 @@ pub fn Log(comptime Writer: type) type {
|
|
|
520
684
|
|
|
521
685
|
pub fn resisted(self: Self, ident: ID) Error!void {
|
|
522
686
|
if (!enabled) return;
|
|
687
|
+
|
|
523
688
|
try self.writer.writeAll(&.{
|
|
524
689
|
@intFromEnum(ArgType.Resisted),
|
|
525
690
|
@as(u8, @bitCast(ident)),
|
|
@@ -528,6 +693,7 @@ pub fn Log(comptime Writer: type) type {
|
|
|
528
693
|
|
|
529
694
|
pub fn immune(self: Self, ident: ID, reason: Immune) Error!void {
|
|
530
695
|
if (!enabled) return;
|
|
696
|
+
|
|
531
697
|
try self.writer.writeAll(&.{
|
|
532
698
|
@intFromEnum(ArgType.Immune),
|
|
533
699
|
@as(u8, @bitCast(ident)),
|
|
@@ -537,6 +703,7 @@ pub fn Log(comptime Writer: type) type {
|
|
|
537
703
|
|
|
538
704
|
pub fn transform(self: Self, source: ID, target: ID) Error!void {
|
|
539
705
|
if (!enabled) return;
|
|
706
|
+
|
|
540
707
|
try self.writer.writeAll(&.{
|
|
541
708
|
@intFromEnum(ArgType.Transform),
|
|
542
709
|
@as(u8, @bitCast(source)),
|
|
@@ -544,20 +711,152 @@ pub fn Log(comptime Writer: type) type {
|
|
|
544
711
|
});
|
|
545
712
|
}
|
|
546
713
|
|
|
714
|
+
pub fn drag(self: Self, ident: ID, pokemon: anytype) Error!void {
|
|
715
|
+
return switchDrag(self, .Drag, ident, pokemon);
|
|
716
|
+
}
|
|
717
|
+
|
|
718
|
+
pub fn item(self: Self, target: ID, i: anytype, source: ID) Error!void {
|
|
719
|
+
if (!enabled) return;
|
|
720
|
+
|
|
721
|
+
try self.writer.writeAll(&.{
|
|
722
|
+
@intFromEnum(ArgType.Item),
|
|
723
|
+
@as(u8, @bitCast(target)),
|
|
724
|
+
@intFromEnum(i),
|
|
725
|
+
@as(u8, @bitCast(source)),
|
|
726
|
+
});
|
|
727
|
+
}
|
|
728
|
+
|
|
729
|
+
pub fn enditem(self: Self, ident: ID, i: anytype, reason: EndItem) Error!void {
|
|
730
|
+
if (!enabled) return;
|
|
731
|
+
|
|
732
|
+
try self.writer.writeAll(&.{
|
|
733
|
+
@intFromEnum(ArgType.EndItem),
|
|
734
|
+
@as(u8, @bitCast(ident)),
|
|
735
|
+
@intFromEnum(i),
|
|
736
|
+
@intFromEnum(reason),
|
|
737
|
+
});
|
|
738
|
+
}
|
|
739
|
+
|
|
740
|
+
pub fn cureteam(self: Self, source: ID) Error!void {
|
|
741
|
+
if (!enabled) return;
|
|
742
|
+
|
|
743
|
+
try self.writer.writeAll(&.{
|
|
744
|
+
@intFromEnum(ArgType.CureTeam),
|
|
745
|
+
@as(u8, @bitCast(source)),
|
|
746
|
+
});
|
|
747
|
+
}
|
|
748
|
+
|
|
749
|
+
pub fn sethp(self: Self, ident: ID, pokemon: anytype, reason: SetHP) Error!void {
|
|
750
|
+
if (!enabled) return;
|
|
751
|
+
|
|
752
|
+
try self.writer.writeAll(&.{ @intFromEnum(ArgType.SetHP), @as(u8, @bitCast(ident)) });
|
|
753
|
+
try self.writer.writeIntNative(u16, pokemon.hp);
|
|
754
|
+
try self.writer.writeIntNative(u16, pokemon.stats.hp);
|
|
755
|
+
try self.writer.writeAll(&.{pokemon.status});
|
|
756
|
+
try self.writer.writeByte(@intFromEnum(reason));
|
|
757
|
+
}
|
|
758
|
+
|
|
759
|
+
pub fn setboost(self: Self, ident: ID, num: i8) Error!void {
|
|
760
|
+
if (!enabled) return;
|
|
761
|
+
|
|
762
|
+
try self.writer.writeAll(&.{
|
|
763
|
+
@intFromEnum(ArgType.SetBoost),
|
|
764
|
+
@as(u8, @bitCast(ident)),
|
|
765
|
+
@as(u8, @intCast(num + 6)),
|
|
766
|
+
});
|
|
767
|
+
}
|
|
768
|
+
|
|
769
|
+
pub fn copyboost(self: Self, source: ID, target: ID) Error!void {
|
|
770
|
+
if (!enabled) return;
|
|
771
|
+
|
|
772
|
+
try self.writer.writeAll(&.{
|
|
773
|
+
@intFromEnum(ArgType.CopyBoost),
|
|
774
|
+
@as(u8, @bitCast(source)),
|
|
775
|
+
@as(u8, @bitCast(target)),
|
|
776
|
+
});
|
|
777
|
+
}
|
|
778
|
+
|
|
779
|
+
pub fn sidestart(self: Self, player: Player, reason: Side) Error!void {
|
|
780
|
+
if (!enabled) return;
|
|
781
|
+
|
|
782
|
+
try self.writer.writeAll(&.{
|
|
783
|
+
@intFromEnum(ArgType.SideStart),
|
|
784
|
+
@intFromEnum(player),
|
|
785
|
+
@intFromEnum(reason),
|
|
786
|
+
});
|
|
787
|
+
}
|
|
788
|
+
|
|
789
|
+
pub fn sideend(self: Self, player: Player, reason: Side) Error!void {
|
|
790
|
+
if (!enabled) return;
|
|
791
|
+
|
|
792
|
+
assert(@intFromEnum(reason) != @intFromEnum(Side.Spikes));
|
|
793
|
+
try self.writer.writeAll(&.{
|
|
794
|
+
@intFromEnum(ArgType.SideEnd),
|
|
795
|
+
@intFromEnum(player),
|
|
796
|
+
@intFromEnum(reason),
|
|
797
|
+
});
|
|
798
|
+
}
|
|
799
|
+
|
|
800
|
+
pub fn spikesend(self: Self, source: ID) Error!void {
|
|
801
|
+
if (!enabled) return;
|
|
802
|
+
|
|
803
|
+
try self.writer.writeAll(&.{
|
|
804
|
+
@intFromEnum(ArgType.SideEnd),
|
|
805
|
+
@intFromEnum(source.player),
|
|
806
|
+
@intFromEnum(Side.Spikes),
|
|
807
|
+
@as(u8, @bitCast(source)),
|
|
808
|
+
});
|
|
809
|
+
}
|
|
810
|
+
|
|
811
|
+
pub fn singlemove(self: Self, ident: ID, m: anytype) Error!void {
|
|
812
|
+
return single(self, .SingleMove, ident, m);
|
|
813
|
+
}
|
|
814
|
+
|
|
815
|
+
pub fn singleturn(self: Self, ident: ID, m: anytype) Error!void {
|
|
816
|
+
return single(self, .SingleTurn, ident, m);
|
|
817
|
+
}
|
|
818
|
+
|
|
819
|
+
fn single(self: Self, arg: ArgType, ident: ID, m: anytype) Error!void {
|
|
820
|
+
if (!enabled) return;
|
|
821
|
+
|
|
822
|
+
try self.writer.writeAll(&.{
|
|
823
|
+
@intFromEnum(arg),
|
|
824
|
+
@as(u8, @bitCast(ident)),
|
|
825
|
+
@intFromEnum(m),
|
|
826
|
+
});
|
|
827
|
+
}
|
|
828
|
+
|
|
829
|
+
pub fn weather(self: Self, w: anytype, reason: Weather) Error!void {
|
|
830
|
+
if (!enabled) return;
|
|
831
|
+
|
|
832
|
+
assert(!(w == .None and reason == .Upkeep));
|
|
833
|
+
try self.writer.writeAll(&.{
|
|
834
|
+
@intFromEnum(ArgType.Weather),
|
|
835
|
+
@intFromEnum(w),
|
|
836
|
+
@intFromEnum(reason),
|
|
837
|
+
});
|
|
838
|
+
}
|
|
839
|
+
|
|
547
840
|
pub fn laststill(self: Self) Error!void {
|
|
548
841
|
if (!enabled) return;
|
|
842
|
+
|
|
549
843
|
try self.writer.writeAll(&.{@intFromEnum(ArgType.LastStill)});
|
|
550
844
|
}
|
|
551
845
|
|
|
552
846
|
pub fn lastmiss(self: Self) Error!void {
|
|
553
847
|
if (!enabled) return;
|
|
848
|
+
|
|
554
849
|
try self.writer.writeAll(&.{@intFromEnum(ArgType.LastMiss)});
|
|
555
850
|
}
|
|
556
851
|
};
|
|
557
852
|
}
|
|
558
853
|
|
|
854
|
+
/// `Log` type backed by the optimized `ByteStream.Writer`.
|
|
559
855
|
pub const FixedLog = Log(ByteStream.Writer);
|
|
560
856
|
|
|
857
|
+
/// Stripped down version of `std.io.FixedBufferStream` optimized for efficiently writing the
|
|
858
|
+
/// individual protocol bytes. Note that the `ByteStream.Writer` is **not** a `std.io.Writer` and
|
|
859
|
+
/// should not be used for general purpose writing.
|
|
561
860
|
pub const ByteStream = struct {
|
|
562
861
|
buffer: []u8,
|
|
563
862
|
pos: usize = 0,
|
|
@@ -598,10 +897,14 @@ pub const ByteStream = struct {
|
|
|
598
897
|
}
|
|
599
898
|
};
|
|
600
899
|
|
|
601
|
-
pub const Kind = enum { Move, Species, Type, Status };
|
|
602
|
-
pub const Formatter = fn (Kind, u8) []const u8;
|
|
900
|
+
pub const Kind = enum { Move, Species, Type, Status, Item, Weather };
|
|
603
901
|
|
|
604
|
-
pub fn format(
|
|
902
|
+
pub fn format(
|
|
903
|
+
comptime gen: anytype,
|
|
904
|
+
a: []const u8,
|
|
905
|
+
b: ?[]const u8,
|
|
906
|
+
color: bool,
|
|
907
|
+
) void {
|
|
605
908
|
print("\n", .{});
|
|
606
909
|
|
|
607
910
|
var i: usize = 0;
|
|
@@ -639,6 +942,18 @@ pub fn format(comptime formatter: Formatter, a: []const u8, b: ?[]const u8, colo
|
|
|
639
942
|
.Resisted => "|-resisted|",
|
|
640
943
|
.Immune => "|-immune|",
|
|
641
944
|
.Transform => "|-transform|",
|
|
945
|
+
.Drag => "|drag|",
|
|
946
|
+
.Item => "|-item|",
|
|
947
|
+
.EndItem => "|-enditem|",
|
|
948
|
+
.CureTeam => "|-cureteam|",
|
|
949
|
+
.SetHP => "|-sethp|",
|
|
950
|
+
.SetBoost => "|-setboost|",
|
|
951
|
+
.CopyBoost => "|-copyboost|",
|
|
952
|
+
.SideStart => "|-sidestart|",
|
|
953
|
+
.SideEnd => "|-sideend|",
|
|
954
|
+
.SingleMove => "|-singlemove|",
|
|
955
|
+
.SingleTurn => "|-singleturn|",
|
|
956
|
+
.Weather => "|-weather|",
|
|
642
957
|
else => unreachable,
|
|
643
958
|
};
|
|
644
959
|
printc("{s}", .{name}, a, b, &i, 1, color);
|
|
@@ -654,17 +969,27 @@ pub fn format(comptime formatter: Formatter, a: []const u8, b: ?[]const u8, colo
|
|
|
654
969
|
.Move => {
|
|
655
970
|
const source = ID.from(@intCast(a[i]));
|
|
656
971
|
printc(" {s}({d})", .{ @tagName(source.player), source.id }, a, b, &i, 1, color);
|
|
657
|
-
printc(" {s}", .{formatter(.Move, a[i])}, a, b, &i, 1, color);
|
|
972
|
+
printc(" {s}", .{formatter(gen, .Move, a[i])}, a, b, &i, 1, color);
|
|
658
973
|
const target = ID.from(@intCast(a[i]));
|
|
659
974
|
printc(" {s}({d})", .{ @tagName(target.player), target.id }, a, b, &i, 1, color);
|
|
660
975
|
const reason: Move = @enumFromInt(a[i]);
|
|
661
976
|
printc(" {s}", .{@tagName(reason)}, a, b, &i, 1, color);
|
|
662
|
-
if (reason == .From)
|
|
977
|
+
if (reason == .From) {
|
|
978
|
+
printc(" {s}", .{formatter(gen, .Move, a[i])}, a, b, &i, 1, color);
|
|
979
|
+
}
|
|
663
980
|
},
|
|
664
|
-
.Switch => {
|
|
981
|
+
.Switch, .Drag => {
|
|
665
982
|
const id = ID.from(@intCast(a[i]));
|
|
666
983
|
printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
|
|
667
|
-
printc(" {s}", .{formatter(.Species, a[i])}, a, b, &i, 1, color);
|
|
984
|
+
printc(" {s}", .{formatter(gen, .Species, a[i])}, a, b, &i, 1, color);
|
|
985
|
+
if (@hasDecl(gen, "Gender")) {
|
|
986
|
+
if (a[i] == N(gen.Gender.Unknown)) {
|
|
987
|
+
i += 1;
|
|
988
|
+
} else {
|
|
989
|
+
var gender = if (a[i] == N(gen.Gender.Male)) "M" else "F";
|
|
990
|
+
printc(", {s}", .{gender}, a, b, &i, 1, color);
|
|
991
|
+
}
|
|
992
|
+
}
|
|
668
993
|
printc(" L{d}", .{a[i]}, a, b, &i, 1, color);
|
|
669
994
|
switch (endian) {
|
|
670
995
|
.Big => {
|
|
@@ -680,7 +1005,7 @@ pub fn format(comptime formatter: Formatter, a: []const u8, b: ?[]const u8, colo
|
|
|
680
1005
|
printc("/{d}", .{hp}, a, b, &i, 2, color);
|
|
681
1006
|
},
|
|
682
1007
|
}
|
|
683
|
-
printc(" {s}", .{formatter(.Status, a[i])}, a, b, &i, 1, color);
|
|
1008
|
+
printc(" {s}", .{formatter(gen, .Status, a[i])}, a, b, &i, 1, color);
|
|
684
1009
|
},
|
|
685
1010
|
.Cant => {
|
|
686
1011
|
const id = ID.from(@intCast(a[i]));
|
|
@@ -688,7 +1013,7 @@ pub fn format(comptime formatter: Formatter, a: []const u8, b: ?[]const u8, colo
|
|
|
688
1013
|
const reason: Cant = @enumFromInt(a[i]);
|
|
689
1014
|
printc(" {s}", .{@tagName(reason)}, a, b, &i, 1, color);
|
|
690
1015
|
if (reason == .Disable) {
|
|
691
|
-
printc(" {s}", .{formatter(.Move, a[i])}, a, b, &i, 1, color);
|
|
1016
|
+
printc(" {s}", .{formatter(gen, .Move, a[i])}, a, b, &i, 1, color);
|
|
692
1017
|
}
|
|
693
1018
|
},
|
|
694
1019
|
.Faint,
|
|
@@ -697,6 +1022,7 @@ pub fn format(comptime formatter: Formatter, a: []const u8, b: ?[]const u8, colo
|
|
|
697
1022
|
.Crit,
|
|
698
1023
|
.SuperEffective,
|
|
699
1024
|
.Resisted,
|
|
1025
|
+
.CureTeam,
|
|
700
1026
|
=> {
|
|
701
1027
|
const id = ID.from(@intCast(a[i]));
|
|
702
1028
|
printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
|
|
@@ -728,7 +1054,7 @@ pub fn format(comptime formatter: Formatter, a: []const u8, b: ?[]const u8, colo
|
|
|
728
1054
|
printc("/{d}", .{hp}, a, b, &i, 2, color);
|
|
729
1055
|
},
|
|
730
1056
|
}
|
|
731
|
-
printc(" {s}", .{formatter(.Status, a[i])}, a, b, &i, 1, color);
|
|
1057
|
+
printc(" {s}", .{formatter(gen, .Status, a[i])}, a, b, &i, 1, color);
|
|
732
1058
|
if (arg == .Damage) {
|
|
733
1059
|
const reason: Damage = @enumFromInt(a[i]);
|
|
734
1060
|
printc(" {s}", .{@tagName(reason)}, a, b, &i, 1, color);
|
|
@@ -748,15 +1074,17 @@ pub fn format(comptime formatter: Formatter, a: []const u8, b: ?[]const u8, colo
|
|
|
748
1074
|
.Status => {
|
|
749
1075
|
const id = ID.from(@intCast(a[i]));
|
|
750
1076
|
printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
|
|
751
|
-
printc(" {s}", .{formatter(.Status, a[i])}, a, b, &i, 1, color);
|
|
1077
|
+
printc(" {s}", .{formatter(gen, .Status, a[i])}, a, b, &i, 1, color);
|
|
752
1078
|
const reason: Status = @enumFromInt(a[i]);
|
|
753
1079
|
printc(" {s}", .{@tagName(reason)}, a, b, &i, 1, color);
|
|
754
|
-
if (reason == .From)
|
|
1080
|
+
if (reason == .From) {
|
|
1081
|
+
printc(" {s}", .{formatter(gen, .Move, a[i])}, a, b, &i, 1, color);
|
|
1082
|
+
}
|
|
755
1083
|
},
|
|
756
1084
|
.CureStatus => {
|
|
757
1085
|
const id = ID.from(@intCast(a[i]));
|
|
758
1086
|
printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
|
|
759
|
-
printc(" {s}", .{formatter(.Status, a[i])}, a, b, &i, 1, color);
|
|
1087
|
+
printc(" {s}", .{formatter(gen, .Status, a[i])}, a, b, &i, 1, color);
|
|
760
1088
|
const reason: CureStatus = @enumFromInt(a[i]);
|
|
761
1089
|
printc(" {s}", .{@tagName(reason)}, a, b, &i, 1, color);
|
|
762
1090
|
},
|
|
@@ -771,15 +1099,15 @@ pub fn format(comptime formatter: Formatter, a: []const u8, b: ?[]const u8, colo
|
|
|
771
1099
|
printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
|
|
772
1100
|
printc(" {s}", .{@tagName(@as(Fail, @enumFromInt(a[i])))}, a, b, &i, 1, color);
|
|
773
1101
|
},
|
|
774
|
-
.HitCount => {
|
|
1102
|
+
.HitCount, .SetBoost => {
|
|
775
1103
|
const id = ID.from(@intCast(a[i]));
|
|
776
1104
|
printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
|
|
777
1105
|
printc(" {d}", .{a[i]}, a, b, &i, 1, color);
|
|
778
1106
|
},
|
|
779
|
-
.Prepare => {
|
|
1107
|
+
.Prepare, .SingleMove, .SingleTurn => {
|
|
780
1108
|
const id = ID.from(@intCast(a[i]));
|
|
781
1109
|
printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
|
|
782
|
-
printc(" {s}", .{formatter(.Move, a[i])}, a, b, &i, 1, color);
|
|
1110
|
+
printc(" {s}", .{formatter(gen, .Move, a[i])}, a, b, &i, 1, color);
|
|
783
1111
|
},
|
|
784
1112
|
.Activate => {
|
|
785
1113
|
const id = ID.from(@intCast(a[i]));
|
|
@@ -794,12 +1122,12 @@ pub fn format(comptime formatter: Formatter, a: []const u8, b: ?[]const u8, colo
|
|
|
794
1122
|
if (@as(Start, @enumFromInt(reason)) == .TypeChange) {
|
|
795
1123
|
const types = @as(gen1.Types, @bitCast(a[i]));
|
|
796
1124
|
const args = .{
|
|
797
|
-
formatter(.Type, @intFromEnum(types.type1)),
|
|
798
|
-
formatter(.Type, @intFromEnum(types.type2)),
|
|
1125
|
+
formatter(gen, .Type, @intFromEnum(types.type1)),
|
|
1126
|
+
formatter(gen, .Type, @intFromEnum(types.type2)),
|
|
799
1127
|
};
|
|
800
1128
|
printc(" {s}/{s}", args, a, b, &i, 1, color);
|
|
801
1129
|
} else if (reason >= @intFromEnum(Start.Disable)) {
|
|
802
|
-
printc(" {s}", .{formatter(.Move, a[i])}, a, b, &i, 1, color);
|
|
1130
|
+
printc(" {s}", .{formatter(gen, .Move, a[i])}, a, b, &i, 1, color);
|
|
803
1131
|
}
|
|
804
1132
|
},
|
|
805
1133
|
.End => {
|
|
@@ -812,12 +1140,64 @@ pub fn format(comptime formatter: Formatter, a: []const u8, b: ?[]const u8, colo
|
|
|
812
1140
|
printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
|
|
813
1141
|
printc(" {s}", .{@tagName(@as(Immune, @enumFromInt(a[i])))}, a, b, &i, 1, color);
|
|
814
1142
|
},
|
|
815
|
-
.Transform => {
|
|
1143
|
+
.Transform, .CopyBoost => {
|
|
816
1144
|
const source = ID.from(@intCast(a[i]));
|
|
817
1145
|
printc(" {s}({d})", .{ @tagName(source.player), source.id }, a, b, &i, 1, color);
|
|
818
1146
|
const target = ID.from(@intCast(a[i]));
|
|
819
1147
|
printc(" {s}({d})", .{ @tagName(target.player), target.id }, a, b, &i, 1, color);
|
|
820
1148
|
},
|
|
1149
|
+
.Item, .EndItem => {
|
|
1150
|
+
var id = ID.from(@intCast(a[i]));
|
|
1151
|
+
printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
|
|
1152
|
+
printc(" {s}", .{formatter(gen, .Item, a[i])}, a, b, &i, 1, color);
|
|
1153
|
+
if (arg == .Item) {
|
|
1154
|
+
id = ID.from(@intCast(a[i]));
|
|
1155
|
+
printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
|
|
1156
|
+
} else {
|
|
1157
|
+
const reason: EndItem = @enumFromInt(a[i]);
|
|
1158
|
+
printc(" {s}", .{@tagName(reason)}, a, b, &i, 1, color);
|
|
1159
|
+
}
|
|
1160
|
+
},
|
|
1161
|
+
.SetHP => {
|
|
1162
|
+
const id = ID.from(@intCast(a[i]));
|
|
1163
|
+
printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
|
|
1164
|
+
switch (endian) {
|
|
1165
|
+
.Big => {
|
|
1166
|
+
var hp = @as(u16, a[i]) << 8 | @as(u16, a[i + 1]);
|
|
1167
|
+
printc(" {d}", .{hp}, a, b, &i, 2, color);
|
|
1168
|
+
hp = @as(u16, a[i]) << 8 | @as(u16, a[i + 1]);
|
|
1169
|
+
printc("/{d}", .{hp}, a, b, &i, 2, color);
|
|
1170
|
+
},
|
|
1171
|
+
.Little => {
|
|
1172
|
+
var hp = @as(u16, a[i + 1]) << 8 | @as(u16, a[i]);
|
|
1173
|
+
printc(" {d}", .{hp}, a, b, &i, 2, color);
|
|
1174
|
+
hp = @as(u16, a[i + 1]) << 8 | @as(u16, a[i]);
|
|
1175
|
+
printc("/{d}", .{hp}, a, b, &i, 2, color);
|
|
1176
|
+
},
|
|
1177
|
+
}
|
|
1178
|
+
printc(" {s}", .{formatter(gen, .Status, a[i])}, a, b, &i, 1, color);
|
|
1179
|
+
printc(" {s}", .{@tagName(@as(SetHP, @enumFromInt(a[i])))}, a, b, &i, 1, color);
|
|
1180
|
+
},
|
|
1181
|
+
.SideStart => {
|
|
1182
|
+
const id = ID.from(@intCast(a[i]));
|
|
1183
|
+
printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
|
|
1184
|
+
printc(" {s}", .{@tagName(@as(Side, @enumFromInt(a[i])))}, a, b, &i, 1, color);
|
|
1185
|
+
},
|
|
1186
|
+
.SideEnd => {
|
|
1187
|
+
var id = ID.from(@intCast(a[i]));
|
|
1188
|
+
printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
|
|
1189
|
+
const reason: Side = @enumFromInt(a[i]);
|
|
1190
|
+
printc(" {s}", .{@tagName(reason)}, a, b, &i, 1, color);
|
|
1191
|
+
if (reason == .Spikes) {
|
|
1192
|
+
printc(" {s}", .{formatter(gen, .Move, a[i])}, a, b, &i, 1, color);
|
|
1193
|
+
id = ID.from(@intCast(a[i]));
|
|
1194
|
+
printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
|
|
1195
|
+
}
|
|
1196
|
+
},
|
|
1197
|
+
.Weather => {
|
|
1198
|
+
printc(" {s}", .{formatter(gen, .Weather, a[i])}, a, b, &i, 1, color);
|
|
1199
|
+
printc(" {s}", .{@tagName(@as(Weather, @enumFromInt(a[i])))}, a, b, &i, 1, color);
|
|
1200
|
+
},
|
|
821
1201
|
else => unreachable,
|
|
822
1202
|
}
|
|
823
1203
|
print("\n", .{});
|
|
@@ -849,12 +1229,13 @@ fn printc(
|
|
|
849
1229
|
}
|
|
850
1230
|
|
|
851
1231
|
pub fn expectLog(
|
|
852
|
-
comptime
|
|
1232
|
+
comptime gen: anytype,
|
|
853
1233
|
expected: []const u8,
|
|
854
1234
|
actual: []const u8,
|
|
855
1235
|
offset: usize,
|
|
856
1236
|
) !void {
|
|
857
1237
|
if (!enabled) return;
|
|
1238
|
+
|
|
858
1239
|
const color = color: {
|
|
859
1240
|
if (std.process.hasEnvVarConstant("ZIG_DEBUG_COLOR")) {
|
|
860
1241
|
break :color true;
|
|
@@ -867,8 +1248,8 @@ pub fn expectLog(
|
|
|
867
1248
|
|
|
868
1249
|
expectEqualBytes(expected, actual, offset) catch |err| switch (err) {
|
|
869
1250
|
error.TestExpectedEqual => {
|
|
870
|
-
format(
|
|
871
|
-
format(
|
|
1251
|
+
format(gen, expected, null, color);
|
|
1252
|
+
format(gen, actual, expected, color);
|
|
872
1253
|
return err;
|
|
873
1254
|
},
|
|
874
1255
|
else => return err,
|
|
@@ -908,49 +1289,70 @@ const gen1 = struct {
|
|
|
908
1289
|
pub const helpers = @import("../gen1/helpers.zig");
|
|
909
1290
|
};
|
|
910
1291
|
|
|
1292
|
+
const gen2 = struct {
|
|
1293
|
+
pub usingnamespace @import("../gen2/data.zig");
|
|
1294
|
+
pub const helpers = @import("../gen2/helpers.zig");
|
|
1295
|
+
};
|
|
1296
|
+
|
|
911
1297
|
var buf: [gen1.LOGS_SIZE]u8 = undefined;
|
|
912
|
-
var stream =
|
|
1298
|
+
var stream: ByteStream = .{ .buffer = &buf };
|
|
913
1299
|
var log: FixedLog = .{ .writer = stream.writer() };
|
|
914
1300
|
|
|
915
|
-
const
|
|
916
|
-
const
|
|
1301
|
+
const M1 = gen1.Move;
|
|
1302
|
+
const S1 = gen1.Species;
|
|
1303
|
+
|
|
1304
|
+
const M2 = gen2.Move;
|
|
1305
|
+
const S2 = gen2.Species;
|
|
1306
|
+
const I2 = gen2.Item;
|
|
1307
|
+
const W2 = gen2.Weather;
|
|
917
1308
|
|
|
918
1309
|
fn expectLog1(expected: []const u8, actual: []const u8) !void {
|
|
919
|
-
return expectLog(
|
|
1310
|
+
return expectLog(gen1, expected, actual, 0);
|
|
920
1311
|
}
|
|
921
1312
|
|
|
922
|
-
fn
|
|
1313
|
+
fn expectLog2(expected: []const u8, actual: []const u8) !void {
|
|
1314
|
+
return expectLog(gen2, expected, actual, 0);
|
|
1315
|
+
}
|
|
1316
|
+
|
|
1317
|
+
fn formatter(comptime gen: anytype, kind: Kind, byte: u8) []const u8 {
|
|
923
1318
|
return switch (kind) {
|
|
924
|
-
.Move => @tagName(@as(
|
|
925
|
-
.Species => @tagName(@as(
|
|
926
|
-
.Type => @tagName(@as(
|
|
927
|
-
.Status =>
|
|
1319
|
+
.Move => @tagName(@as(gen.Move, @enumFromInt(byte))),
|
|
1320
|
+
.Species => @tagName(@as(gen.Species, @enumFromInt(byte))),
|
|
1321
|
+
.Type => @tagName(@as(gen.Type, @enumFromInt(byte))),
|
|
1322
|
+
.Status => gen.Status.name(byte),
|
|
1323
|
+
.Item => if (@hasDecl(gen, "Item"))
|
|
1324
|
+
@tagName(@as(gen.Item, @enumFromInt(byte)))
|
|
1325
|
+
else
|
|
1326
|
+
unreachable,
|
|
1327
|
+
.Weather => if (@hasDecl(gen, "Weather"))
|
|
1328
|
+
@tagName(@as(gen.Weather, @enumFromInt(byte)))
|
|
1329
|
+
else
|
|
1330
|
+
unreachable,
|
|
928
1331
|
};
|
|
929
1332
|
}
|
|
930
1333
|
|
|
931
1334
|
test "|move|" {
|
|
932
|
-
try log.move(p2.ident(4),
|
|
1335
|
+
try log.move(p2.ident(4), M1.Thunderbolt, p1.ident(5));
|
|
933
1336
|
try expectLog1(
|
|
934
|
-
&.{ N(ArgType.Move), 0b1100, N(
|
|
1337
|
+
&.{ N(ArgType.Move), 0b1100, N(M1.Thunderbolt), 0b0101, N(Move.None) },
|
|
935
1338
|
buf[0..5],
|
|
936
1339
|
);
|
|
937
1340
|
stream.reset();
|
|
938
1341
|
|
|
939
|
-
try log.
|
|
940
|
-
const wrap = N(M.Wrap);
|
|
1342
|
+
try log.moveFrom(p2.ident(4), M1.Pound, p1.ident(5), M1.Metronome);
|
|
941
1343
|
try expectLog1(
|
|
942
|
-
&.{ N(ArgType.Move), 0b1100,
|
|
1344
|
+
&.{ N(ArgType.Move), 0b1100, N(M1.Pound), 0b0101, N(Move.From), N(M1.Metronome) },
|
|
943
1345
|
buf[0..6],
|
|
944
1346
|
);
|
|
945
1347
|
stream.reset();
|
|
946
1348
|
|
|
947
|
-
try log.move(p2.ident(4),
|
|
1349
|
+
try log.move(p2.ident(4), M1.SkullBash, .{});
|
|
948
1350
|
try log.laststill();
|
|
949
1351
|
try expectLog1(
|
|
950
1352
|
&.{
|
|
951
1353
|
N(ArgType.Move),
|
|
952
1354
|
0b1100,
|
|
953
|
-
N(
|
|
1355
|
+
N(M1.SkullBash),
|
|
954
1356
|
0,
|
|
955
1357
|
N(Move.None),
|
|
956
1358
|
N(ArgType.LastStill),
|
|
@@ -959,13 +1361,13 @@ test "|move|" {
|
|
|
959
1361
|
);
|
|
960
1362
|
stream.reset();
|
|
961
1363
|
|
|
962
|
-
try log.move(p2.ident(4),
|
|
1364
|
+
try log.move(p2.ident(4), M1.Tackle, p1.ident(5));
|
|
963
1365
|
try log.lastmiss();
|
|
964
1366
|
try expectLog1(
|
|
965
1367
|
&.{
|
|
966
1368
|
N(ArgType.Move),
|
|
967
1369
|
0b1100,
|
|
968
|
-
N(
|
|
1370
|
+
N(M1.Tackle),
|
|
969
1371
|
0b0101,
|
|
970
1372
|
N(Move.None),
|
|
971
1373
|
N(ArgType.LastMiss),
|
|
@@ -984,8 +1386,8 @@ test "|switch|" {
|
|
|
984
1386
|
try log.switched(p2.ident(3), &snorlax);
|
|
985
1387
|
const par = 0b1000000;
|
|
986
1388
|
var expected: []const u8 = switch (endian) {
|
|
987
|
-
.Big => &.{ N(ArgType.Switch), 0b1011, N(
|
|
988
|
-
.Little => &.{ N(ArgType.Switch), 0b1011, N(
|
|
1389
|
+
.Big => &.{ N(ArgType.Switch), 0b1011, N(S1.Snorlax), 91, 0, 200, 1, 144, par },
|
|
1390
|
+
.Little => &.{ N(ArgType.Switch), 0b1011, N(S1.Snorlax), 91, 200, 0, 144, 1, par },
|
|
989
1391
|
};
|
|
990
1392
|
try expectLog1(expected, buf[0..9]);
|
|
991
1393
|
stream.reset();
|
|
@@ -995,8 +1397,8 @@ test "|switch|" {
|
|
|
995
1397
|
snorlax.status = 0;
|
|
996
1398
|
try log.switched(p2.ident(3), &snorlax);
|
|
997
1399
|
expected = switch (endian) {
|
|
998
|
-
.Big => &.{ N(ArgType.Switch), 0b1011, N(
|
|
999
|
-
.Little => &.{ N(ArgType.Switch), 0b1011, N(
|
|
1400
|
+
.Big => &.{ N(ArgType.Switch), 0b1011, N(S1.Snorlax), 100, 0, 0, 1, 144, 0 },
|
|
1401
|
+
.Little => &.{ N(ArgType.Switch), 0b1011, N(S1.Snorlax), 100, 0, 0, 144, 1, 0 },
|
|
1000
1402
|
};
|
|
1001
1403
|
try expectLog1(expected, buf[0..9]);
|
|
1002
1404
|
stream.reset();
|
|
@@ -1004,11 +1406,30 @@ test "|switch|" {
|
|
|
1004
1406
|
snorlax.hp = 400;
|
|
1005
1407
|
try log.switched(p2.ident(3), &snorlax);
|
|
1006
1408
|
expected = switch (endian) {
|
|
1007
|
-
.Big => &.{ N(ArgType.Switch), 0b1011, N(
|
|
1008
|
-
.Little => &.{ N(ArgType.Switch), 0b1011, N(
|
|
1409
|
+
.Big => &.{ N(ArgType.Switch), 0b1011, N(S1.Snorlax), 100, 1, 144, 1, 144, 0 },
|
|
1410
|
+
.Little => &.{ N(ArgType.Switch), 0b1011, N(S1.Snorlax), 100, 144, 1, 144, 1, 0 },
|
|
1009
1411
|
};
|
|
1010
1412
|
try expectLog1(expected, buf[0..9]);
|
|
1011
1413
|
stream.reset();
|
|
1414
|
+
|
|
1415
|
+
var blissey = gen2.helpers.Pokemon.init(.{ .species = .Blissey, .moves = &.{.Splash} });
|
|
1416
|
+
blissey.level = 91;
|
|
1417
|
+
blissey.hp = 200;
|
|
1418
|
+
blissey.stats.hp = 400;
|
|
1419
|
+
blissey.status = gen2.Status.init(.PAR);
|
|
1420
|
+
try log.switched(p2.ident(3), &blissey);
|
|
1421
|
+
expected = &(.{
|
|
1422
|
+
N(ArgType.Switch),
|
|
1423
|
+
0b1011,
|
|
1424
|
+
N(S2.Blissey),
|
|
1425
|
+
N(gen2.Gender.Female),
|
|
1426
|
+
91,
|
|
1427
|
+
} ++ switch (endian) {
|
|
1428
|
+
.Big => .{ 0, 200, 1, 144, par },
|
|
1429
|
+
.Little => .{ 200, 0, 144, 1, par },
|
|
1430
|
+
});
|
|
1431
|
+
try expectLog2(expected, buf[0..10]);
|
|
1432
|
+
stream.reset();
|
|
1012
1433
|
}
|
|
1013
1434
|
|
|
1014
1435
|
test "|cant|" {
|
|
@@ -1016,8 +1437,8 @@ test "|cant|" {
|
|
|
1016
1437
|
try expectLog1(&.{ N(ArgType.Cant), 0b1110, N(Cant.Bound) }, buf[0..3]);
|
|
1017
1438
|
stream.reset();
|
|
1018
1439
|
|
|
1019
|
-
try log.disabled(p1.ident(2),
|
|
1020
|
-
try expectLog1(&.{ N(ArgType.Cant), 2, N(Cant.Disable), N(
|
|
1440
|
+
try log.disabled(p1.ident(2), M1.Earthquake);
|
|
1441
|
+
try expectLog1(&.{ N(ArgType.Cant), 2, N(Cant.Disable), N(M1.Earthquake) }, buf[0..4]);
|
|
1021
1442
|
stream.reset();
|
|
1022
1443
|
}
|
|
1023
1444
|
|
|
@@ -1090,7 +1511,7 @@ test "|-heal|" {
|
|
|
1090
1511
|
var chansey = gen1.helpers.Pokemon.init(.{ .species = .Chansey, .moves = &.{.Splash} });
|
|
1091
1512
|
chansey.hp = 612;
|
|
1092
1513
|
chansey.status = gen1.Status.slp(1);
|
|
1093
|
-
try log.heal(p2.ident(2), &chansey, .None);
|
|
1514
|
+
try log.heal(.{ p2.ident(2), &chansey, Heal.None });
|
|
1094
1515
|
var expected: []const u8 = switch (endian) {
|
|
1095
1516
|
.Big => &.{ N(ArgType.Heal), 0b1010, 2, 100, 2, 191, 1, N(Heal.None) },
|
|
1096
1517
|
.Little => &.{ N(ArgType.Heal), 0b1010, 100, 2, 191, 2, 1, N(Heal.None) },
|
|
@@ -1101,7 +1522,7 @@ test "|-heal|" {
|
|
|
1101
1522
|
chansey.hp = 100;
|
|
1102
1523
|
chansey.stats.hp = 256;
|
|
1103
1524
|
chansey.status = 0;
|
|
1104
|
-
try log.heal(p2.ident(2), &chansey, .Silent);
|
|
1525
|
+
try log.heal(.{ p2.ident(2), &chansey, Heal.Silent });
|
|
1105
1526
|
expected = switch (endian) {
|
|
1106
1527
|
.Big => &.{ N(ArgType.Heal), 0b1010, 0, 100, 1, 0, 0, N(Heal.Silent) },
|
|
1107
1528
|
.Little => &.{ N(ArgType.Heal), 0b1010, 100, 0, 0, 1, 0, N(Heal.Silent) },
|
|
@@ -1127,9 +1548,9 @@ test "|-status|" {
|
|
|
1127
1548
|
try expectLog1(&.{ N(ArgType.Status), 0b1010, 0b1000, N(Status.Silent) }, buf[0..4]);
|
|
1128
1549
|
stream.reset();
|
|
1129
1550
|
|
|
1130
|
-
try log.statusFrom(p1.ident(1), gen1.Status.init(.PAR),
|
|
1551
|
+
try log.statusFrom(p1.ident(1), gen1.Status.init(.PAR), M1.BodySlam);
|
|
1131
1552
|
try expectLog1(
|
|
1132
|
-
&.{ N(ArgType.Status), 0b0001, 0b1000000, N(Status.From), N(
|
|
1553
|
+
&.{ N(ArgType.Status), 0b0001, 0b1000000, N(Status.From), N(M1.BodySlam) },
|
|
1133
1554
|
buf[0..5],
|
|
1134
1555
|
);
|
|
1135
1556
|
stream.reset();
|
|
@@ -1200,8 +1621,8 @@ test "|-hitcount|" {
|
|
|
1200
1621
|
}
|
|
1201
1622
|
|
|
1202
1623
|
test "|-prepare|" {
|
|
1203
|
-
try log.prepare(p2.ident(2),
|
|
1204
|
-
try expectLog1(&.{ N(ArgType.Prepare), 0b1010, N(
|
|
1624
|
+
try log.prepare(p2.ident(2), M1.Dig);
|
|
1625
|
+
try expectLog1(&.{ N(ArgType.Prepare), 0b1010, N(M1.Dig) }, buf[0..3]);
|
|
1205
1626
|
stream.reset();
|
|
1206
1627
|
}
|
|
1207
1628
|
|
|
@@ -1227,6 +1648,12 @@ test "|-activate|" {
|
|
|
1227
1648
|
try log.activate(p1.ident(2), .Splash);
|
|
1228
1649
|
try expectLog1(&.{ N(ArgType.Activate), 0b0010, N(Activate.Splash) }, buf[0..3]);
|
|
1229
1650
|
stream.reset();
|
|
1651
|
+
|
|
1652
|
+
// TODO activateMove
|
|
1653
|
+
|
|
1654
|
+
try log.magnitude(p1.ident(3), 5);
|
|
1655
|
+
try expectLog1(&.{ N(ArgType.Activate), 0b0011, N(Activate.Magnitude), 5 }, buf[0..4]);
|
|
1656
|
+
stream.reset();
|
|
1230
1657
|
}
|
|
1231
1658
|
|
|
1232
1659
|
test "|-fieldactivate|" {
|
|
@@ -1258,12 +1685,12 @@ test "|-start|" {
|
|
|
1258
1685
|
);
|
|
1259
1686
|
stream.reset();
|
|
1260
1687
|
|
|
1261
|
-
try log.startEffect(p1.ident(2), .Disable,
|
|
1262
|
-
try expectLog1(&.{ N(ArgType.Start), 0b0010, N(Start.Disable), N(
|
|
1688
|
+
try log.startEffect(p1.ident(2), .Disable, M1.Surf);
|
|
1689
|
+
try expectLog1(&.{ N(ArgType.Start), 0b0010, N(Start.Disable), N(M1.Surf) }, buf[0..4]);
|
|
1263
1690
|
stream.reset();
|
|
1264
1691
|
|
|
1265
|
-
try log.startEffect(p1.ident(2), .Mimic,
|
|
1266
|
-
try expectLog1(&.{ N(ArgType.Start), 0b0010, N(Start.Mimic), N(
|
|
1692
|
+
try log.startEffect(p1.ident(2), .Mimic, M1.Surf);
|
|
1693
|
+
try expectLog1(&.{ N(ArgType.Start), 0b0010, N(Start.Mimic), N(M1.Surf) }, buf[0..4]);
|
|
1267
1694
|
stream.reset();
|
|
1268
1695
|
}
|
|
1269
1696
|
|
|
@@ -1282,21 +1709,25 @@ test "|-ohko|" {
|
|
|
1282
1709
|
try expectLog1(&.{N(ArgType.OHKO)}, buf[0..1]);
|
|
1283
1710
|
stream.reset();
|
|
1284
1711
|
}
|
|
1712
|
+
|
|
1285
1713
|
test "|-crit|" {
|
|
1286
1714
|
try log.crit(p2.ident(5));
|
|
1287
1715
|
try expectLog1(&.{ N(ArgType.Crit), 0b1101 }, buf[0..2]);
|
|
1288
1716
|
stream.reset();
|
|
1289
1717
|
}
|
|
1718
|
+
|
|
1290
1719
|
test "|-supereffective|" {
|
|
1291
1720
|
try log.supereffective(p1.ident(1));
|
|
1292
1721
|
try expectLog1(&.{ N(ArgType.SuperEffective), 0b0001 }, buf[0..2]);
|
|
1293
1722
|
stream.reset();
|
|
1294
1723
|
}
|
|
1724
|
+
|
|
1295
1725
|
test "|-resisted|" {
|
|
1296
1726
|
try log.resisted(p2.ident(2));
|
|
1297
1727
|
try expectLog1(&.{ N(ArgType.Resisted), 0b1010 }, buf[0..2]);
|
|
1298
1728
|
stream.reset();
|
|
1299
1729
|
}
|
|
1730
|
+
|
|
1300
1731
|
test "|-immune|" {
|
|
1301
1732
|
try log.immune(p1.ident(3), .None);
|
|
1302
1733
|
try expectLog1(&.{ N(ArgType.Immune), 0b0011, N(Immune.None) }, buf[0..3]);
|
|
@@ -1306,8 +1737,124 @@ test "|-immune|" {
|
|
|
1306
1737
|
try expectLog1(&.{ N(ArgType.Immune), 0b1010, N(Immune.OHKO) }, buf[0..3]);
|
|
1307
1738
|
stream.reset();
|
|
1308
1739
|
}
|
|
1740
|
+
|
|
1309
1741
|
test "|-transform|" {
|
|
1310
1742
|
try log.transform(p2.ident(4), p1.ident(5));
|
|
1311
1743
|
try expectLog1(&.{ N(ArgType.Transform), 0b1100, 0b0101 }, buf[0..3]);
|
|
1312
1744
|
stream.reset();
|
|
1313
1745
|
}
|
|
1746
|
+
|
|
1747
|
+
test "|drag|" {
|
|
1748
|
+
var blissey = gen2.helpers.Pokemon.init(.{ .species = .Blissey, .moves = &.{.Splash} });
|
|
1749
|
+
blissey.level = 91;
|
|
1750
|
+
blissey.hp = 200;
|
|
1751
|
+
blissey.stats.hp = 400;
|
|
1752
|
+
blissey.status = gen2.Status.init(.PAR);
|
|
1753
|
+
try log.drag(p2.ident(3), &blissey);
|
|
1754
|
+
const par = 0b1000000;
|
|
1755
|
+
const expected = &(.{
|
|
1756
|
+
N(ArgType.Drag),
|
|
1757
|
+
0b1011,
|
|
1758
|
+
N(S2.Blissey),
|
|
1759
|
+
N(gen2.Gender.Female),
|
|
1760
|
+
91,
|
|
1761
|
+
} ++ switch (endian) {
|
|
1762
|
+
.Big => .{ 0, 200, 1, 144, par },
|
|
1763
|
+
.Little => .{ 200, 0, 144, 1, par },
|
|
1764
|
+
});
|
|
1765
|
+
try expectLog2(expected, buf[0..10]);
|
|
1766
|
+
stream.reset();
|
|
1767
|
+
}
|
|
1768
|
+
|
|
1769
|
+
test "|-item|" {
|
|
1770
|
+
try log.item(p2.ident(2), I2.GoldBerry, p1.ident(4));
|
|
1771
|
+
try expectLog2(&.{ N(ArgType.Item), 0b1010, N(I2.GoldBerry), 0b0100 }, buf[0..4]);
|
|
1772
|
+
stream.reset();
|
|
1773
|
+
}
|
|
1774
|
+
|
|
1775
|
+
test "|-enditem|" {
|
|
1776
|
+
try log.enditem(p1.ident(1), I2.BerserkGene, .None);
|
|
1777
|
+
try expectLog2(&.{ N(ArgType.EndItem), 0b0001, N(I2.BerserkGene), N(EndItem.None) }, buf[0..4]);
|
|
1778
|
+
stream.reset();
|
|
1779
|
+
|
|
1780
|
+
try log.enditem(p2.ident(4), I2.PRZCureBerry, .Eat);
|
|
1781
|
+
try expectLog2(&.{ N(ArgType.EndItem), 0b1100, N(I2.PRZCureBerry), N(EndItem.Eat) }, buf[0..4]);
|
|
1782
|
+
stream.reset();
|
|
1783
|
+
}
|
|
1784
|
+
|
|
1785
|
+
test "|-cureteam|" {
|
|
1786
|
+
try log.cureteam(p2.ident(5));
|
|
1787
|
+
try expectLog2(&.{ N(ArgType.CureTeam), 0b1101 }, buf[0..2]);
|
|
1788
|
+
stream.reset();
|
|
1789
|
+
}
|
|
1790
|
+
|
|
1791
|
+
test "|-sethp|" {
|
|
1792
|
+
var blissey = gen2.helpers.Pokemon.init(.{ .species = .Blissey, .moves = &.{.PainSplit} });
|
|
1793
|
+
blissey.hp = 612;
|
|
1794
|
+
try log.sethp(p2.ident(2), &blissey, .Silent);
|
|
1795
|
+
var expected: []const u8 = switch (endian) {
|
|
1796
|
+
.Big => &.{ N(ArgType.SetHP), 0b1010, 2, 100, 2, 201, 0, N(SetHP.Silent) },
|
|
1797
|
+
.Little => &.{ N(ArgType.SetHP), 0b1010, 100, 2, 201, 2, 0, N(SetHP.Silent) },
|
|
1798
|
+
};
|
|
1799
|
+
try expectLog2(expected, buf[0..8]);
|
|
1800
|
+
stream.reset();
|
|
1801
|
+
}
|
|
1802
|
+
|
|
1803
|
+
test "|-setboost|" {
|
|
1804
|
+
try log.setboost(p2.ident(6), 6);
|
|
1805
|
+
try expectLog2(&.{ N(ArgType.SetBoost), 0b1110, 12 }, buf[0..3]);
|
|
1806
|
+
stream.reset();
|
|
1807
|
+
|
|
1808
|
+
try log.setboost(p2.ident(3), 2);
|
|
1809
|
+
try expectLog2(&.{ N(ArgType.SetBoost), 0b1011, 8 }, buf[0..3]);
|
|
1810
|
+
stream.reset();
|
|
1811
|
+
}
|
|
1812
|
+
|
|
1813
|
+
test "|-copyboost|" {
|
|
1814
|
+
try log.copyboost(p2.ident(3), p1.ident(6));
|
|
1815
|
+
try expectLog2(&.{ N(ArgType.CopyBoost), 0b1011, 0b0110 }, buf[0..3]);
|
|
1816
|
+
stream.reset();
|
|
1817
|
+
}
|
|
1818
|
+
|
|
1819
|
+
test "|-sidestart|" {
|
|
1820
|
+
try log.sidestart(.P2, .Reflect);
|
|
1821
|
+
try expectLog2(&.{ N(ArgType.SideStart), 1, N(Side.Reflect) }, buf[0..3]);
|
|
1822
|
+
stream.reset();
|
|
1823
|
+
}
|
|
1824
|
+
|
|
1825
|
+
test "|-sideend|" {
|
|
1826
|
+
try log.sideend(.P2, .LightScreen);
|
|
1827
|
+
try expectLog2(&.{ N(ArgType.SideEnd), 1, N(Side.LightScreen) }, buf[0..3]);
|
|
1828
|
+
stream.reset();
|
|
1829
|
+
|
|
1830
|
+
try log.spikesend(p1.ident(3));
|
|
1831
|
+
try expectLog2(&.{
|
|
1832
|
+
N(ArgType.SideEnd),
|
|
1833
|
+
0,
|
|
1834
|
+
N(Side.Spikes),
|
|
1835
|
+
0b0011,
|
|
1836
|
+
}, buf[0..4]);
|
|
1837
|
+
stream.reset();
|
|
1838
|
+
}
|
|
1839
|
+
|
|
1840
|
+
test "|-singlemove|" {
|
|
1841
|
+
try log.singlemove(p2.ident(2), M2.DestinyBond);
|
|
1842
|
+
try expectLog2(&.{ N(ArgType.SingleMove), 0b1010, N(M2.DestinyBond) }, buf[0..3]);
|
|
1843
|
+
stream.reset();
|
|
1844
|
+
}
|
|
1845
|
+
|
|
1846
|
+
test "|-singleturn|" {
|
|
1847
|
+
try log.singleturn(p1.ident(3), M2.Protect);
|
|
1848
|
+
try expectLog2(&.{ N(ArgType.SingleTurn), 0b0011, N(M2.Protect) }, buf[0..3]);
|
|
1849
|
+
stream.reset();
|
|
1850
|
+
}
|
|
1851
|
+
|
|
1852
|
+
test "|-weather|" {
|
|
1853
|
+
try log.weather(W2.Rain, .Upkeep);
|
|
1854
|
+
try expectLog2(&.{ N(ArgType.Weather), N(W2.Rain), N(Weather.Upkeep) }, buf[0..3]);
|
|
1855
|
+
stream.reset();
|
|
1856
|
+
|
|
1857
|
+
try log.weather(W2.None, .None);
|
|
1858
|
+
try expectLog2(&.{ N(ArgType.Weather), N(W2.None), N(Weather.None) }, buf[0..3]);
|
|
1859
|
+
stream.reset();
|
|
1860
|
+
}
|