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