@pkmn/engine 0.1.0-dev.f3aaee39 → 0.1.0-dev.f3b63b86
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/LICENSE +1 -3
- package/README.md +77 -23
- package/build/pkg/addon/browser.d.ts +3 -0
- package/build/pkg/addon/browser.js +47 -0
- package/build/pkg/addon/browser.js.map +1 -0
- package/build/pkg/addon/node.d.ts +3 -0
- package/build/pkg/addon/node.js +110 -0
- package/build/pkg/addon/node.js.map +1 -0
- package/build/pkg/addon/wasm.d.ts +2 -0
- package/build/pkg/addon/wasm.js +53 -0
- package/build/pkg/addon/wasm.js.map +1 -0
- package/build/pkg/addon.d.ts +26 -4
- package/build/pkg/addon.js +39 -71
- package/build/pkg/addon.js.map +1 -1
- package/build/pkg/data/ids.json +12 -12
- package/build/pkg/data/layout.json +17 -4
- package/build/pkg/data/protocol.json +84 -13
- package/build/pkg/data.d.ts +27 -5
- package/build/pkg/data.js.map +1 -1
- package/build/pkg/gen1.d.ts +15 -18
- package/build/pkg/gen1.js +30 -21
- package/build/pkg/gen1.js.map +1 -1
- package/build/pkg/index.d.ts +42 -91
- package/build/pkg/index.js +23 -70
- package/build/pkg/index.js.map +1 -1
- package/build/pkg/protocol.d.ts +20 -1
- package/build/pkg/protocol.js +123 -102
- package/build/pkg/protocol.js.map +1 -1
- package/build/tools/debug.js +69 -74
- package/build/tools/debug.js.map +1 -1
- package/build/tools/display/debug.jsx +152 -0
- package/build/tools/display/debug.jsx.map +1 -0
- package/build/tools/display/index.js +152 -0
- package/build/tools/display/index.js.map +1 -0
- package/build/tools/display/ui.jsx +359 -0
- package/build/tools/display/ui.jsx.map +1 -0
- package/build/tools/display/util.js +33 -0
- package/build/tools/display/util.js.map +1 -0
- package/build.zig +273 -120
- package/package.json +64 -123
- package/src/bin/install-pkmn-engine +47 -21
- package/src/bin/pkmn-debug +1 -1
- package/src/lib/bindings/c.zig +200 -0
- package/src/lib/{binding → bindings}/node.zig +15 -32
- package/src/lib/bindings/wasm.zig +50 -0
- package/src/lib/common/array.zig +70 -0
- package/src/lib/common/data.zig +12 -24
- package/src/lib/common/debug.zig +32 -11
- package/src/lib/common/js.zig +3 -7
- package/src/lib/common/optional.zig +19 -18
- package/src/lib/common/options.zig +6 -0
- package/src/lib/common/protocol.zig +919 -430
- package/src/lib/common/rational.zig +341 -254
- package/src/lib/common/rng.zig +22 -15
- package/src/lib/common/util.zig +33 -1
- package/src/lib/gen1/calc.zig +706 -177
- package/src/lib/gen1/chance.zig +428 -302
- package/src/lib/gen1/data/moves.zig +193 -183
- package/src/lib/gen1/data/species.zig +4 -6
- package/src/lib/gen1/data/types.zig +9 -10
- package/src/lib/gen1/data.zig +60 -75
- package/src/lib/gen1/helpers.zig +90 -563
- package/src/lib/gen1/mechanics.zig +682 -600
- package/src/lib/gen2/calc.zig +150 -0
- package/src/lib/gen2/chance.zig +896 -0
- package/src/lib/gen2/data/items.zig +13 -21
- package/src/lib/gen2/data/moves.zig +664 -572
- package/src/lib/gen2/data/species.zig +2 -4
- package/src/lib/gen2/data/types.zig +139 -34
- package/src/lib/gen2/data.zig +121 -96
- package/src/lib/gen2/generated.zig +801 -0
- package/src/lib/gen2/helpers.zig +53 -38
- package/src/lib/gen2/mechanics.zig +3580 -29
- package/src/lib/napi.h +2 -0
- package/src/lib/node.zig +14 -0
- package/src/lib/pkmn.zig +125 -29
- package/src/lib/wasm.zig +13 -0
- package/src/tools/display/dom.ts +93 -0
- package/src/tools/display/ui.css +354 -0
- package/build/test/display.js +0 -400
- package/build/test/display.js.map +0 -1
- package/src/lib/binding/wasm.zig +0 -12
- package/src/lib/gen1/README.md +0 -892
- package/src/lib/gen2/README.md +0 -308
- package/src/test/display/pkmn.html.tmpl +0 -368
|
@@ -1,16 +1,17 @@
|
|
|
1
|
-
const std = @import("std");
|
|
2
1
|
const builtin = @import("builtin");
|
|
3
|
-
|
|
4
|
-
const
|
|
5
|
-
const
|
|
2
|
+
const data = @import("data.zig");
|
|
3
|
+
const options = @import("options.zig");
|
|
4
|
+
const pkmn = @import("../pkmn.zig");
|
|
5
|
+
const std = @import("std");
|
|
6
6
|
|
|
7
7
|
const assert = std.debug.assert;
|
|
8
|
-
const print = std.debug.print;
|
|
9
|
-
|
|
10
8
|
const enabled = options.log;
|
|
11
|
-
|
|
12
|
-
const Player = data.Player;
|
|
13
9
|
const ID = data.ID;
|
|
10
|
+
const Player = data.Player;
|
|
11
|
+
const print = std.debug.print;
|
|
12
|
+
|
|
13
|
+
const endian = builtin.cpu.arch.endian();
|
|
14
|
+
const Endian = std.builtin.Endian;
|
|
14
15
|
|
|
15
16
|
pub const ArgType = enum(u8) {
|
|
16
17
|
None,
|
|
@@ -69,7 +70,7 @@ pub const ArgType = enum(u8) {
|
|
|
69
70
|
EndAbility,
|
|
70
71
|
ClearNegativeBoost,
|
|
71
72
|
FormeChange,
|
|
72
|
-
|
|
73
|
+
LastNoTarget, // FIXME
|
|
73
74
|
|
|
74
75
|
// Gen 4
|
|
75
76
|
SwapBoost,
|
|
@@ -102,6 +103,7 @@ pub const ArgType = enum(u8) {
|
|
|
102
103
|
// Gen 8
|
|
103
104
|
CanDynamax,
|
|
104
105
|
SwapSideConditions,
|
|
106
|
+
UpdatePoke,
|
|
105
107
|
|
|
106
108
|
// Gen 9
|
|
107
109
|
Terastallize,
|
|
@@ -121,12 +123,19 @@ pub const Cant = enum(u8) {
|
|
|
121
123
|
Disable,
|
|
122
124
|
Recharge,
|
|
123
125
|
PP,
|
|
126
|
+
|
|
127
|
+
Attract,
|
|
124
128
|
};
|
|
125
129
|
|
|
126
130
|
pub const Heal = enum(u8) {
|
|
127
131
|
None,
|
|
128
132
|
Silent,
|
|
129
133
|
Drain,
|
|
134
|
+
|
|
135
|
+
Leftovers,
|
|
136
|
+
Berry,
|
|
137
|
+
BerryJuice,
|
|
138
|
+
GoldBerry,
|
|
130
139
|
};
|
|
131
140
|
|
|
132
141
|
pub const Damage = enum(u8) {
|
|
@@ -136,6 +145,17 @@ pub const Damage = enum(u8) {
|
|
|
136
145
|
Confusion,
|
|
137
146
|
LeechSeed,
|
|
138
147
|
RecoilOf,
|
|
148
|
+
|
|
149
|
+
Bind,
|
|
150
|
+
Wrap,
|
|
151
|
+
FireSpin,
|
|
152
|
+
Clamp,
|
|
153
|
+
Whirlpool,
|
|
154
|
+
Spikes,
|
|
155
|
+
|
|
156
|
+
Nightmare,
|
|
157
|
+
Curse,
|
|
158
|
+
Sandstorm,
|
|
139
159
|
};
|
|
140
160
|
|
|
141
161
|
pub const Status = enum(u8) {
|
|
@@ -178,8 +198,26 @@ pub const Activate = enum(u8) {
|
|
|
178
198
|
Haze,
|
|
179
199
|
Mist,
|
|
180
200
|
Struggle,
|
|
181
|
-
Substitute,
|
|
201
|
+
Substitute, // FIXME SubstituteDamage
|
|
182
202
|
Splash,
|
|
203
|
+
|
|
204
|
+
Rage, // TODO
|
|
205
|
+
|
|
206
|
+
Attract,
|
|
207
|
+
LockOn,
|
|
208
|
+
Bind,
|
|
209
|
+
Wrap,
|
|
210
|
+
FireSpin,
|
|
211
|
+
Clamp,
|
|
212
|
+
Whirlpool,
|
|
213
|
+
SubstituteBlock,
|
|
214
|
+
|
|
215
|
+
DestinyBond,
|
|
216
|
+
|
|
217
|
+
BeatUp, // FIXME of
|
|
218
|
+
|
|
219
|
+
Magnitude,
|
|
220
|
+
Spite,
|
|
183
221
|
};
|
|
184
222
|
|
|
185
223
|
pub const Start = enum(u8) {
|
|
@@ -197,6 +235,19 @@ pub const Start = enum(u8) {
|
|
|
197
235
|
|
|
198
236
|
Disable,
|
|
199
237
|
Mimic,
|
|
238
|
+
|
|
239
|
+
Attract,
|
|
240
|
+
Nightmare,
|
|
241
|
+
Curse,
|
|
242
|
+
Foresight,
|
|
243
|
+
Encore,
|
|
244
|
+
FutureSight,
|
|
245
|
+
|
|
246
|
+
PerishSong0,
|
|
247
|
+
PerishSong1,
|
|
248
|
+
PerishSong2,
|
|
249
|
+
PerishSong3,
|
|
250
|
+
PerishSong3Silent,
|
|
200
251
|
};
|
|
201
252
|
|
|
202
253
|
pub const End = enum(u8) {
|
|
@@ -205,16 +256,30 @@ pub const End = enum(u8) {
|
|
|
205
256
|
Bide,
|
|
206
257
|
Substitute,
|
|
207
258
|
|
|
208
|
-
|
|
259
|
+
Nightmare,
|
|
260
|
+
Curse,
|
|
261
|
+
Foresight,
|
|
262
|
+
Encore,
|
|
263
|
+
FutureSight,
|
|
264
|
+
LeechSeed,
|
|
265
|
+
|
|
266
|
+
Bind,
|
|
267
|
+
Wrap,
|
|
268
|
+
FireSpin,
|
|
269
|
+
Clamp,
|
|
270
|
+
Whirlpool,
|
|
271
|
+
|
|
209
272
|
DisableSilent,
|
|
210
273
|
ConfusionSilent,
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
274
|
+
MistSilent,
|
|
275
|
+
FocusEnergySilent,
|
|
276
|
+
LeechSeedSilent,
|
|
277
|
+
ToxicSilent,
|
|
278
|
+
LightScreenSilent,
|
|
279
|
+
ReflectSilent,
|
|
280
|
+
BideSilent,
|
|
281
|
+
|
|
282
|
+
LeechSeedFrom,
|
|
218
283
|
};
|
|
219
284
|
|
|
220
285
|
pub const Immune = enum(u8) {
|
|
@@ -222,376 +287,534 @@ pub const Immune = enum(u8) {
|
|
|
222
287
|
OHKO,
|
|
223
288
|
};
|
|
224
289
|
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
290
|
+
pub const EndItem = enum(u8) {
|
|
291
|
+
None,
|
|
292
|
+
Eat,
|
|
293
|
+
};
|
|
294
|
+
|
|
295
|
+
pub const SetHP = enum(u8) {
|
|
296
|
+
None,
|
|
297
|
+
Silent,
|
|
298
|
+
};
|
|
299
|
+
|
|
300
|
+
pub const Side = enum(u8) {
|
|
301
|
+
Safeguard,
|
|
302
|
+
Reflect,
|
|
303
|
+
LightScreen,
|
|
304
|
+
Spikes,
|
|
305
|
+
};
|
|
306
|
+
|
|
307
|
+
pub const Weather = enum(u8) {
|
|
308
|
+
None,
|
|
309
|
+
Upkeep,
|
|
310
|
+
};
|
|
229
311
|
|
|
230
|
-
/// Logs protocol information to its `
|
|
231
|
-
pub fn Log(comptime
|
|
312
|
+
/// Logs protocol information to its `WriterT` during a battle update when `options.log` is enabled.
|
|
313
|
+
pub fn Log(comptime WriterT: type) type {
|
|
232
314
|
return struct {
|
|
233
315
|
const Self = @This();
|
|
234
316
|
|
|
235
|
-
writer:
|
|
317
|
+
writer: WriterT,
|
|
236
318
|
|
|
237
|
-
pub const Error =
|
|
319
|
+
pub const Error = err(WriterT);
|
|
320
|
+
|
|
321
|
+
fn err(comptime T: type) type {
|
|
322
|
+
const msg = "Invalid Writer type " ++ @typeName(T) ++ "'";
|
|
323
|
+
return switch (@typeInfo(T)) {
|
|
324
|
+
.pointer => |ptr_info| switch (ptr_info.size) {
|
|
325
|
+
.one => switch (@typeInfo(ptr_info.child)) {
|
|
326
|
+
.@"struct" => err(ptr_info.child),
|
|
327
|
+
else => @compileError(msg),
|
|
328
|
+
},
|
|
329
|
+
else => @compileError(msg),
|
|
330
|
+
},
|
|
331
|
+
.@"struct" => if (@hasDecl(T, "Error")) T.Error else @compileError(msg),
|
|
332
|
+
else => @compileError(msg),
|
|
333
|
+
};
|
|
334
|
+
}
|
|
238
335
|
|
|
239
|
-
|
|
336
|
+
// source: ID, move: <Move>, target: ID, from?: <Move>
|
|
337
|
+
pub fn move(self: Self, args: anytype) Error!void {
|
|
240
338
|
if (!enabled) return;
|
|
241
339
|
|
|
242
|
-
assert(
|
|
340
|
+
assert(args[1] != .None);
|
|
243
341
|
try self.writer.writeAll(&.{
|
|
244
342
|
@intFromEnum(ArgType.Move),
|
|
245
|
-
@as(u8, @bitCast(
|
|
246
|
-
@intFromEnum(
|
|
247
|
-
@as(u8, @bitCast(
|
|
248
|
-
});
|
|
249
|
-
const none = &[_]u8{@intFromEnum(Move.None)};
|
|
250
|
-
try self.writer.writeAll(switch (@typeInfo(@TypeOf(from))) {
|
|
251
|
-
.Null => none,
|
|
252
|
-
.Optional => if (from) |f| blk: {
|
|
253
|
-
assert(@intFromEnum(f) != 0);
|
|
254
|
-
break :blk &[_]u8{ @intFromEnum(Move.From), @intFromEnum(f) };
|
|
255
|
-
} else none,
|
|
256
|
-
else => blk: {
|
|
257
|
-
assert(@intFromEnum(from) != 0);
|
|
258
|
-
break :blk &[_]u8{ @intFromEnum(Move.From), @intFromEnum(from) };
|
|
259
|
-
},
|
|
343
|
+
@as(u8, @bitCast(args[0])),
|
|
344
|
+
@intFromEnum(args[1]),
|
|
345
|
+
@as(u8, @bitCast(args[2])),
|
|
260
346
|
});
|
|
347
|
+
try self.writer.writeAll(if (args.len < 4 or @intFromEnum(args[3]) == 0)
|
|
348
|
+
&.{@intFromEnum(Move.None)}
|
|
349
|
+
else
|
|
350
|
+
&.{ @intFromEnum(Move.From), @intFromEnum(args[3]) });
|
|
261
351
|
}
|
|
262
352
|
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
try self.writer.writeAll(&.{ @intFromEnum(ArgType.Switch), @as(u8, @bitCast(ident)) });
|
|
267
|
-
try self.writer.writeAll(&.{ @intFromEnum(pokemon.species), pokemon.level });
|
|
268
|
-
try self.writer.writeIntNative(u16, pokemon.hp);
|
|
269
|
-
try self.writer.writeIntNative(u16, pokemon.stats.hp);
|
|
270
|
-
try self.writer.writeAll(&.{pokemon.status});
|
|
353
|
+
// ident: ID, pokemon: <Pokemon>
|
|
354
|
+
pub fn switched(self: Self, args: anytype) Error!void {
|
|
355
|
+
return switchDrag(self, .Switch, args);
|
|
271
356
|
}
|
|
272
357
|
|
|
273
|
-
|
|
358
|
+
// ident: ID, pokemon: <Pokemon>
|
|
359
|
+
fn switchDrag(self: Self, arg: ArgType, args: anytype) Error!void {
|
|
274
360
|
if (!enabled) return;
|
|
275
361
|
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
362
|
+
try self.writer.writeAll(&.{ @intFromEnum(arg), @as(u8, @bitCast(args[0])) });
|
|
363
|
+
if (@hasField(@TypeOf(args[1].*), "dvs")) {
|
|
364
|
+
try self.writer.writeAll(&.{
|
|
365
|
+
@intFromEnum(args[1].species),
|
|
366
|
+
@intFromEnum(args[1].dvs.gender),
|
|
367
|
+
args[1].level,
|
|
368
|
+
});
|
|
369
|
+
} else {
|
|
370
|
+
try self.writer.writeAll(&.{ @intFromEnum(args[1].species), args[1].level });
|
|
371
|
+
}
|
|
372
|
+
try self.writer.writeInt(u16, args[1].hp, endian);
|
|
373
|
+
try self.writer.writeInt(u16, args[1].stats.hp, endian);
|
|
374
|
+
try self.writer.writeAll(&.{args[1].status});
|
|
282
375
|
}
|
|
283
376
|
|
|
284
|
-
|
|
377
|
+
// ident: ID, reason: Cant
|
|
378
|
+
// ident: ID, reason: .Disable, move: <Move>
|
|
379
|
+
pub fn cant(self: Self, args: anytype) Error!void {
|
|
285
380
|
if (!enabled) return;
|
|
286
381
|
|
|
382
|
+
assert(args[1] != .Disable or args.len == 3);
|
|
287
383
|
try self.writer.writeAll(&.{
|
|
288
384
|
@intFromEnum(ArgType.Cant),
|
|
289
|
-
@as(u8, @bitCast(
|
|
290
|
-
@intFromEnum(Cant
|
|
291
|
-
@intFromEnum(m),
|
|
385
|
+
@as(u8, @bitCast(args[0])),
|
|
386
|
+
@intFromEnum(@as(Cant, args[1])),
|
|
292
387
|
});
|
|
388
|
+
if (args.len == 3) try self.writer.writeByte(@intFromEnum(args[2]));
|
|
293
389
|
}
|
|
294
390
|
|
|
295
|
-
|
|
391
|
+
// ident: ID, done: bool
|
|
392
|
+
pub fn faint(self: Self, args: anytype) Error!void {
|
|
296
393
|
if (!enabled) return;
|
|
297
394
|
|
|
298
|
-
try self.writer.writeAll(&.{ @intFromEnum(ArgType.Faint), @as(u8, @bitCast(
|
|
299
|
-
if (
|
|
395
|
+
try self.writer.writeAll(&.{ @intFromEnum(ArgType.Faint), @as(u8, @bitCast(args[0])) });
|
|
396
|
+
if (args[1]) try self.writer.writeByte(@intFromEnum(ArgType.None));
|
|
300
397
|
}
|
|
301
398
|
|
|
302
|
-
|
|
399
|
+
// num: u16
|
|
400
|
+
pub fn turn(self: Self, args: anytype) Error!void {
|
|
303
401
|
if (!enabled) return;
|
|
304
402
|
|
|
305
403
|
try self.writer.writeByte(@intFromEnum(ArgType.Turn));
|
|
306
|
-
try self.writer.
|
|
404
|
+
try self.writer.writeInt(u16, args[0], endian);
|
|
307
405
|
try self.writer.writeByte(@intFromEnum(ArgType.None));
|
|
308
406
|
}
|
|
309
407
|
|
|
310
|
-
|
|
408
|
+
// player: Player
|
|
409
|
+
pub fn win(self: Self, args: anytype) Error!void {
|
|
311
410
|
if (!enabled) return;
|
|
312
411
|
|
|
313
412
|
try self.writer.writeAll(&.{
|
|
314
413
|
@intFromEnum(ArgType.Win),
|
|
315
|
-
@intFromEnum(
|
|
414
|
+
@intFromEnum(@as(Player, args[0])),
|
|
316
415
|
@intFromEnum(ArgType.None),
|
|
317
416
|
});
|
|
318
417
|
}
|
|
319
418
|
|
|
320
|
-
|
|
419
|
+
// -
|
|
420
|
+
pub fn tie(self: Self, _: anytype) Error!void {
|
|
321
421
|
if (!enabled) return;
|
|
322
422
|
|
|
323
423
|
try self.writer.writeAll(&.{ @intFromEnum(ArgType.Tie), @intFromEnum(ArgType.None) });
|
|
324
424
|
}
|
|
325
425
|
|
|
326
|
-
|
|
426
|
+
// ident: ID, pokemon: <Pokemon>, reason: Damage
|
|
427
|
+
// ident: ID, pokemon: <Pokemon>, reason: .RecoilOf, source: ID
|
|
428
|
+
pub fn damage(self: Self, args: anytype) Error!void {
|
|
327
429
|
if (!enabled) return;
|
|
328
430
|
|
|
329
|
-
assert(
|
|
330
|
-
try self.writer.writeAll(&.{
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
431
|
+
assert(args[2] != .RecoilOf or args.len == 4);
|
|
432
|
+
try self.writer.writeAll(&.{
|
|
433
|
+
@intFromEnum(ArgType.Damage),
|
|
434
|
+
@as(u8, @bitCast(args[0])),
|
|
435
|
+
});
|
|
436
|
+
try self.writer.writeInt(u16, args[1].hp, endian);
|
|
437
|
+
try self.writer.writeInt(u16, args[1].stats.hp, endian);
|
|
438
|
+
try self.writer.writeAll(&.{ args[1].status, @intFromEnum(@as(Damage, args[2])) });
|
|
439
|
+
if (args.len == 4) try self.writer.writeByte(@as(u8, @bitCast(args[3])));
|
|
334
440
|
}
|
|
335
441
|
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
pokemon: anytype,
|
|
340
|
-
reason: Damage,
|
|
341
|
-
source: ID,
|
|
342
|
-
) Error!void {
|
|
442
|
+
// ident: ID, pokemon: <Pokemon>, reason: Heal
|
|
443
|
+
// ident: ID, pokemon: <Pokemon>, reason: .Drain, target: ID
|
|
444
|
+
pub fn heal(self: Self, args: anytype) Error!void {
|
|
343
445
|
if (!enabled) return;
|
|
344
446
|
|
|
345
|
-
assert(
|
|
346
|
-
try self.writer.writeAll(&.{ @intFromEnum(ArgType.
|
|
347
|
-
try self.writer.
|
|
348
|
-
try self.writer.
|
|
349
|
-
try self.writer.writeAll(&.{
|
|
350
|
-
|
|
351
|
-
@intFromEnum(reason),
|
|
352
|
-
@as(u8, @bitCast(source)),
|
|
353
|
-
});
|
|
447
|
+
assert(args[2] != .Drain or args.len == 4);
|
|
448
|
+
try self.writer.writeAll(&.{ @intFromEnum(ArgType.Heal), @as(u8, @bitCast(args[0])) });
|
|
449
|
+
try self.writer.writeInt(u16, args[1].hp, endian);
|
|
450
|
+
try self.writer.writeInt(u16, args[1].stats.hp, endian);
|
|
451
|
+
try self.writer.writeAll(&.{ args[1].status, @intFromEnum(@as(Heal, args[2])) });
|
|
452
|
+
if (args.len == 4) try self.writer.writeByte(@as(u8, @bitCast(args[3])));
|
|
354
453
|
}
|
|
355
454
|
|
|
356
|
-
|
|
455
|
+
// ident: ID, value: u8, reason: Status
|
|
456
|
+
// ident: ID, value: u8, reason: .From, m: <Move>
|
|
457
|
+
pub fn status(self: Self, args: anytype) Error!void {
|
|
357
458
|
if (!enabled) return;
|
|
358
459
|
|
|
359
|
-
assert(
|
|
360
|
-
try self.writer.writeAll(&.{
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
460
|
+
assert(args[2] != .From or args.len == 4);
|
|
461
|
+
try self.writer.writeAll(&.{
|
|
462
|
+
@intFromEnum(ArgType.Status),
|
|
463
|
+
@as(u8, @bitCast(args[0])),
|
|
464
|
+
args[1],
|
|
465
|
+
@intFromEnum(@as(Status, args[2])),
|
|
466
|
+
});
|
|
467
|
+
if (args.len == 4) try self.writer.writeByte(@intFromEnum(args[3]));
|
|
364
468
|
}
|
|
365
469
|
|
|
366
|
-
|
|
470
|
+
// ident: ID, value: u8, reason: CureStatus
|
|
471
|
+
pub fn curestatus(self: Self, args: anytype) Error!void {
|
|
367
472
|
if (!enabled) return;
|
|
368
473
|
|
|
369
|
-
try self.writer.writeAll(&.{ @intFromEnum(ArgType.Heal), @as(u8, @bitCast(source)) });
|
|
370
|
-
try self.writer.writeIntNative(u16, pokemon.hp);
|
|
371
|
-
try self.writer.writeIntNative(u16, pokemon.stats.hp);
|
|
372
474
|
try self.writer.writeAll(&.{
|
|
373
|
-
|
|
374
|
-
@
|
|
375
|
-
|
|
475
|
+
@intFromEnum(ArgType.CureStatus),
|
|
476
|
+
@as(u8, @bitCast(args[0])),
|
|
477
|
+
args[1],
|
|
478
|
+
@intFromEnum(@as(CureStatus, args[2])),
|
|
376
479
|
});
|
|
377
480
|
}
|
|
378
481
|
|
|
379
|
-
|
|
482
|
+
// ident: ID, reason: Boost, num: i8
|
|
483
|
+
pub fn boost(self: Self, args: anytype) Error!void {
|
|
380
484
|
if (!enabled) return;
|
|
381
485
|
|
|
382
|
-
assert(
|
|
486
|
+
assert(args[2] != 0 and (args[1] != .Rage or args[2] > 0));
|
|
383
487
|
try self.writer.writeAll(&.{
|
|
384
|
-
@intFromEnum(ArgType.
|
|
385
|
-
@as(u8, @bitCast(
|
|
386
|
-
|
|
387
|
-
@
|
|
488
|
+
@intFromEnum(ArgType.Boost),
|
|
489
|
+
@as(u8, @bitCast(args[0])),
|
|
490
|
+
@intFromEnum(@as(Boost, args[1])),
|
|
491
|
+
@as(u8, @intCast(@as(i8, args[2]) + 6)),
|
|
388
492
|
});
|
|
389
493
|
}
|
|
390
494
|
|
|
391
|
-
|
|
495
|
+
// -
|
|
496
|
+
pub fn clearallboost(self: Self, _: anytype) Error!void {
|
|
497
|
+
if (!enabled) return;
|
|
498
|
+
|
|
499
|
+
try self.writer.writeAll(&.{@intFromEnum(ArgType.ClearAllBoost)});
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
// ident: ID, reason: Fail
|
|
503
|
+
pub fn fail(self: Self, args: anytype) Error!void {
|
|
392
504
|
if (!enabled) return;
|
|
393
505
|
|
|
394
506
|
try self.writer.writeAll(&.{
|
|
395
|
-
@intFromEnum(ArgType.
|
|
396
|
-
@as(u8, @bitCast(
|
|
397
|
-
|
|
398
|
-
@intFromEnum(Status.From),
|
|
399
|
-
@intFromEnum(m),
|
|
507
|
+
@intFromEnum(ArgType.Fail),
|
|
508
|
+
@as(u8, @bitCast(args[0])),
|
|
509
|
+
@intFromEnum(@as(Fail, args[1])),
|
|
400
510
|
});
|
|
401
511
|
}
|
|
402
512
|
|
|
403
|
-
|
|
513
|
+
// source: ID
|
|
514
|
+
pub fn miss(self: Self, args: anytype) Error!void {
|
|
515
|
+
if (!enabled) return;
|
|
516
|
+
|
|
517
|
+
try self.writer.writeAll(&.{ @intFromEnum(ArgType.Miss), @as(u8, @bitCast(args[0])) });
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
// ident: ID, num: u8
|
|
521
|
+
pub fn hitcount(self: Self, args: anytype) Error!void {
|
|
404
522
|
if (!enabled) return;
|
|
405
523
|
|
|
406
524
|
try self.writer.writeAll(&.{
|
|
407
|
-
@intFromEnum(ArgType.
|
|
408
|
-
@as(u8, @bitCast(
|
|
409
|
-
|
|
410
|
-
@intFromEnum(reason),
|
|
525
|
+
@intFromEnum(ArgType.HitCount),
|
|
526
|
+
@as(u8, @bitCast(args[0])),
|
|
527
|
+
args[1],
|
|
411
528
|
});
|
|
412
529
|
}
|
|
413
530
|
|
|
414
|
-
|
|
531
|
+
// source: ID, m: <Move>
|
|
532
|
+
pub fn prepare(self: Self, args: anytype) Error!void {
|
|
415
533
|
if (!enabled) return;
|
|
416
534
|
|
|
417
|
-
assert(num != 0 and (reason != .Rage or num > 0));
|
|
418
535
|
try self.writer.writeAll(&.{
|
|
419
|
-
@intFromEnum(ArgType.
|
|
420
|
-
@as(u8, @bitCast(
|
|
421
|
-
@intFromEnum(
|
|
422
|
-
@as(u8, @intCast(num + 6)),
|
|
536
|
+
@intFromEnum(ArgType.Prepare),
|
|
537
|
+
@as(u8, @bitCast(args[0])),
|
|
538
|
+
@intFromEnum(args[1]),
|
|
423
539
|
});
|
|
424
540
|
}
|
|
425
541
|
|
|
426
|
-
|
|
542
|
+
// ident: ID
|
|
543
|
+
pub fn mustrecharge(self: Self, args: anytype) Error!void {
|
|
427
544
|
if (!enabled) return;
|
|
428
545
|
|
|
429
|
-
try self.writer.writeAll(&.{
|
|
546
|
+
try self.writer.writeAll(&.{
|
|
547
|
+
@intFromEnum(ArgType.MustRecharge),
|
|
548
|
+
@as(u8, @bitCast(args[0])),
|
|
549
|
+
});
|
|
430
550
|
}
|
|
431
551
|
|
|
432
|
-
|
|
552
|
+
// ident: ID, reason: Activate
|
|
553
|
+
// ident: ID, reason: .SubstituteBlock, m: <Move>
|
|
554
|
+
// ident: ID, reason: .Magnitude, num: u8
|
|
555
|
+
// ident: ID, reason: .Spite, m: <Move>, num: u8
|
|
556
|
+
pub fn activate(self: Self, args: anytype) Error!void {
|
|
433
557
|
if (!enabled) return;
|
|
434
558
|
|
|
559
|
+
assert(args.len <= 4);
|
|
560
|
+
const reason: Activate = args[1];
|
|
435
561
|
try self.writer.writeAll(&.{
|
|
436
|
-
@intFromEnum(ArgType.
|
|
437
|
-
@as(u8, @bitCast(
|
|
562
|
+
@intFromEnum(ArgType.Activate),
|
|
563
|
+
@as(u8, @bitCast(args[0])),
|
|
438
564
|
@intFromEnum(reason),
|
|
439
565
|
});
|
|
566
|
+
if (args.len == 3) {
|
|
567
|
+
if (reason == .SubstituteBlock) {
|
|
568
|
+
try self.writer.writeByte(@intFromEnum(args[2]));
|
|
569
|
+
} else {
|
|
570
|
+
assert(reason == .Magnitude);
|
|
571
|
+
try self.writer.writeByte(args[2]);
|
|
572
|
+
}
|
|
573
|
+
} else if (args.len == 4) {
|
|
574
|
+
assert(reason == .Spite);
|
|
575
|
+
try self.writer.writeAll(&.{ @intFromEnum(args[2]), args[3] });
|
|
576
|
+
}
|
|
440
577
|
}
|
|
441
578
|
|
|
442
|
-
|
|
579
|
+
// -
|
|
580
|
+
pub fn fieldactivate(self: Self, _: anytype) Error!void {
|
|
443
581
|
if (!enabled) return;
|
|
444
582
|
|
|
445
|
-
try self.writer.writeAll(&.{
|
|
583
|
+
try self.writer.writeAll(&.{@intFromEnum(ArgType.FieldActivate)});
|
|
446
584
|
}
|
|
447
585
|
|
|
448
|
-
|
|
586
|
+
// ident: ID, reason: Start
|
|
587
|
+
// ident: ID, reason: .Disable | .Mimic | .Encore, m: <Move>
|
|
588
|
+
// ident: ID, reason: .TypeChange, types: <Types>, target: ID
|
|
589
|
+
pub fn start(self: Self, args: anytype) Error!void {
|
|
449
590
|
if (!enabled) return;
|
|
450
591
|
|
|
592
|
+
assert(args.len <= 4);
|
|
593
|
+
const reason: Start = args[1];
|
|
451
594
|
try self.writer.writeAll(&.{
|
|
452
|
-
@intFromEnum(ArgType.
|
|
453
|
-
@as(u8, @bitCast(
|
|
454
|
-
|
|
595
|
+
@intFromEnum(ArgType.Start),
|
|
596
|
+
@as(u8, @bitCast(args[0])),
|
|
597
|
+
@intFromEnum(reason),
|
|
455
598
|
});
|
|
599
|
+
if (args.len == 3) {
|
|
600
|
+
assert(reason == .Disable or reason == .Mimic or reason == .Encore);
|
|
601
|
+
try self.writer.writeByte(@intFromEnum(args[2]));
|
|
602
|
+
} else if (args.len == 4) {
|
|
603
|
+
assert(reason == .TypeChange);
|
|
604
|
+
// FIXME: u16 types in Generation II
|
|
605
|
+
try self.writer.writeAll(&.{
|
|
606
|
+
@as(u8, @bitCast(args[2])),
|
|
607
|
+
@as(u8, @bitCast(args[3])),
|
|
608
|
+
});
|
|
609
|
+
}
|
|
456
610
|
}
|
|
457
611
|
|
|
458
|
-
|
|
612
|
+
// ident: ID, reason: End
|
|
613
|
+
pub fn end(self: Self, args: anytype) Error!void {
|
|
459
614
|
if (!enabled) return;
|
|
460
615
|
|
|
461
616
|
try self.writer.writeAll(&.{
|
|
462
|
-
@intFromEnum(ArgType.
|
|
463
|
-
@as(u8, @bitCast(
|
|
464
|
-
@intFromEnum(
|
|
617
|
+
@intFromEnum(ArgType.End),
|
|
618
|
+
@as(u8, @bitCast(args[0])),
|
|
619
|
+
@intFromEnum(@as(End, args[1])),
|
|
465
620
|
});
|
|
466
621
|
}
|
|
467
622
|
|
|
468
|
-
|
|
623
|
+
// -
|
|
624
|
+
pub fn ohko(self: Self, _: anytype) Error!void {
|
|
625
|
+
if (!enabled) return;
|
|
626
|
+
|
|
627
|
+
try self.writer.writeAll(&.{@intFromEnum(ArgType.OHKO)});
|
|
628
|
+
}
|
|
629
|
+
|
|
630
|
+
// ident: ID
|
|
631
|
+
pub fn crit(self: Self, args: anytype) Error!void {
|
|
632
|
+
if (!enabled) return;
|
|
633
|
+
|
|
634
|
+
try self.writer.writeAll(&.{ @intFromEnum(ArgType.Crit), @as(u8, @bitCast(args[0])) });
|
|
635
|
+
}
|
|
636
|
+
|
|
637
|
+
// ident: ID
|
|
638
|
+
pub fn supereffective(self: Self, args: anytype) Error!void {
|
|
469
639
|
if (!enabled) return;
|
|
470
640
|
|
|
471
641
|
try self.writer.writeAll(&.{
|
|
472
|
-
@intFromEnum(ArgType.
|
|
473
|
-
@as(u8, @bitCast(
|
|
642
|
+
@intFromEnum(ArgType.SuperEffective),
|
|
643
|
+
@as(u8, @bitCast(args[0])),
|
|
474
644
|
});
|
|
475
645
|
}
|
|
476
646
|
|
|
477
|
-
|
|
647
|
+
// ident: ID
|
|
648
|
+
pub fn resisted(self: Self, args: anytype) Error!void {
|
|
478
649
|
if (!enabled) return;
|
|
479
650
|
|
|
480
651
|
try self.writer.writeAll(&.{
|
|
481
|
-
@intFromEnum(ArgType.
|
|
482
|
-
@as(u8, @bitCast(
|
|
483
|
-
@intFromEnum(reason),
|
|
652
|
+
@intFromEnum(ArgType.Resisted),
|
|
653
|
+
@as(u8, @bitCast(args[0])),
|
|
484
654
|
});
|
|
485
655
|
}
|
|
486
656
|
|
|
487
|
-
|
|
657
|
+
// ident: ID, reason: Immune
|
|
658
|
+
pub fn immune(self: Self, args: anytype) Error!void {
|
|
488
659
|
if (!enabled) return;
|
|
489
660
|
|
|
490
|
-
try self.writer.writeAll(&.{
|
|
661
|
+
try self.writer.writeAll(&.{
|
|
662
|
+
@intFromEnum(ArgType.Immune),
|
|
663
|
+
@as(u8, @bitCast(args[0])),
|
|
664
|
+
@intFromEnum(@as(Immune, args[1])),
|
|
665
|
+
});
|
|
491
666
|
}
|
|
492
667
|
|
|
493
|
-
|
|
668
|
+
// source: ID, target: ID
|
|
669
|
+
pub fn transform(self: Self, args: anytype) Error!void {
|
|
494
670
|
if (!enabled) return;
|
|
495
671
|
|
|
496
|
-
assert(@intFromEnum(reason) < @intFromEnum(Start.TypeChange));
|
|
497
672
|
try self.writer.writeAll(&.{
|
|
498
|
-
@intFromEnum(ArgType.
|
|
499
|
-
@as(u8, @bitCast(
|
|
500
|
-
@
|
|
673
|
+
@intFromEnum(ArgType.Transform),
|
|
674
|
+
@as(u8, @bitCast(args[0])),
|
|
675
|
+
@as(u8, @bitCast(args[1])),
|
|
501
676
|
});
|
|
502
677
|
}
|
|
503
678
|
|
|
504
|
-
|
|
679
|
+
// ident: ID, pokemon: <Pokemon>
|
|
680
|
+
pub fn drag(self: Self, args: anytype) Error!void {
|
|
681
|
+
return switchDrag(self, .Drag, args);
|
|
682
|
+
}
|
|
683
|
+
|
|
684
|
+
// target: ID, item: <Item>, source: ID
|
|
685
|
+
pub fn item(self: Self, args: anytype) Error!void {
|
|
505
686
|
if (!enabled) return;
|
|
506
687
|
|
|
507
688
|
try self.writer.writeAll(&.{
|
|
508
|
-
@intFromEnum(ArgType.
|
|
509
|
-
@as(u8, @bitCast(
|
|
510
|
-
@intFromEnum(
|
|
511
|
-
@as(u8, @bitCast(
|
|
512
|
-
@as(u8, @bitCast(target)),
|
|
689
|
+
@intFromEnum(ArgType.Item),
|
|
690
|
+
@as(u8, @bitCast(args[0])),
|
|
691
|
+
@intFromEnum(args[1]),
|
|
692
|
+
@as(u8, @bitCast(args[2])),
|
|
513
693
|
});
|
|
514
694
|
}
|
|
515
695
|
|
|
516
|
-
|
|
696
|
+
// ident: ID, item: <Item>, reason: EndItem
|
|
697
|
+
pub fn enditem(self: Self, args: anytype) Error!void {
|
|
517
698
|
if (!enabled) return;
|
|
518
699
|
|
|
519
|
-
assert(@intFromEnum(reason) > @intFromEnum(Start.TypeChange));
|
|
520
700
|
try self.writer.writeAll(&.{
|
|
521
|
-
@intFromEnum(ArgType.
|
|
522
|
-
@as(u8, @bitCast(
|
|
523
|
-
@intFromEnum(
|
|
524
|
-
@intFromEnum(
|
|
701
|
+
@intFromEnum(ArgType.EndItem),
|
|
702
|
+
@as(u8, @bitCast(args[0])),
|
|
703
|
+
@intFromEnum(args[1]),
|
|
704
|
+
@intFromEnum(@as(EndItem, args[2])),
|
|
525
705
|
});
|
|
526
706
|
}
|
|
527
707
|
|
|
528
|
-
|
|
708
|
+
// source: ID
|
|
709
|
+
pub fn cureteam(self: Self, args: anytype) Error!void {
|
|
529
710
|
if (!enabled) return;
|
|
530
711
|
|
|
531
712
|
try self.writer.writeAll(&.{
|
|
532
|
-
@intFromEnum(ArgType.
|
|
533
|
-
@as(u8, @bitCast(
|
|
534
|
-
@intFromEnum(reason),
|
|
713
|
+
@intFromEnum(ArgType.CureTeam),
|
|
714
|
+
@as(u8, @bitCast(args[0])),
|
|
535
715
|
});
|
|
536
716
|
}
|
|
537
717
|
|
|
538
|
-
|
|
718
|
+
// ident: ID, pokemon: <Pokemon>, reason: SetHP
|
|
719
|
+
pub fn sethp(self: Self, args: anytype) Error!void {
|
|
539
720
|
if (!enabled) return;
|
|
540
721
|
|
|
541
|
-
try self.writer.writeAll(&.{@intFromEnum(ArgType.
|
|
722
|
+
try self.writer.writeAll(&.{ @intFromEnum(ArgType.SetHP), @as(u8, @bitCast(args[0])) });
|
|
723
|
+
try self.writer.writeInt(u16, args[1].hp, endian);
|
|
724
|
+
try self.writer.writeInt(u16, args[1].stats.hp, endian);
|
|
725
|
+
try self.writer.writeAll(&.{args[1].status});
|
|
726
|
+
try self.writer.writeByte(@intFromEnum(@as(SetHP, args[2])));
|
|
542
727
|
}
|
|
543
728
|
|
|
544
|
-
|
|
729
|
+
// ident: ID, num: i8
|
|
730
|
+
pub fn setboost(self: Self, args: anytype) Error!void {
|
|
545
731
|
if (!enabled) return;
|
|
546
732
|
|
|
547
|
-
try self.writer.writeAll(&.{
|
|
733
|
+
try self.writer.writeAll(&.{
|
|
734
|
+
@intFromEnum(ArgType.SetBoost),
|
|
735
|
+
@as(u8, @bitCast(args[0])),
|
|
736
|
+
@as(u8, @intCast(args[1] + 6)),
|
|
737
|
+
});
|
|
548
738
|
}
|
|
549
739
|
|
|
550
|
-
|
|
740
|
+
// source: ID, target: ID
|
|
741
|
+
pub fn copyboost(self: Self, args: anytype) Error!void {
|
|
551
742
|
if (!enabled) return;
|
|
552
743
|
|
|
553
744
|
try self.writer.writeAll(&.{
|
|
554
|
-
@intFromEnum(ArgType.
|
|
555
|
-
@as(u8, @bitCast(
|
|
745
|
+
@intFromEnum(ArgType.CopyBoost),
|
|
746
|
+
@as(u8, @bitCast(args[0])),
|
|
747
|
+
@as(u8, @bitCast(args[1])),
|
|
556
748
|
});
|
|
557
749
|
}
|
|
558
750
|
|
|
559
|
-
|
|
751
|
+
// player: Player, reason: Side
|
|
752
|
+
pub fn sidestart(self: Self, args: anytype) Error!void {
|
|
560
753
|
if (!enabled) return;
|
|
561
754
|
|
|
562
755
|
try self.writer.writeAll(&.{
|
|
563
|
-
@intFromEnum(ArgType.
|
|
564
|
-
@as(
|
|
756
|
+
@intFromEnum(ArgType.SideStart),
|
|
757
|
+
@intFromEnum(@as(Player, args[0])),
|
|
758
|
+
@intFromEnum(@as(Side, args[1])),
|
|
565
759
|
});
|
|
566
760
|
}
|
|
567
761
|
|
|
568
|
-
|
|
762
|
+
// player: Player, reason: Side
|
|
763
|
+
// player: Player, reason: .Spikes, source: ID
|
|
764
|
+
pub fn sideend(self: Self, args: anytype) Error!void {
|
|
569
765
|
if (!enabled) return;
|
|
570
766
|
|
|
767
|
+
assert(args[1] != .Spikes or args.len == 3);
|
|
571
768
|
try self.writer.writeAll(&.{
|
|
572
|
-
@intFromEnum(ArgType.
|
|
573
|
-
@as(
|
|
574
|
-
@intFromEnum(
|
|
769
|
+
@intFromEnum(ArgType.SideEnd),
|
|
770
|
+
@intFromEnum(@as(Player, args[0])),
|
|
771
|
+
@intFromEnum(@as(Side, args[1])),
|
|
575
772
|
});
|
|
773
|
+
if (args.len == 3) try self.writer.writeByte(@as(u8, @bitCast(args[2])));
|
|
576
774
|
}
|
|
577
775
|
|
|
578
|
-
|
|
776
|
+
// ident: ID, move: <Move>
|
|
777
|
+
pub fn singlemove(self: Self, args: anytype) Error!void {
|
|
778
|
+
return single(self, .SingleMove, args);
|
|
779
|
+
}
|
|
780
|
+
|
|
781
|
+
// ident: ID, move: <Move>
|
|
782
|
+
pub fn singleturn(self: Self, args: anytype) Error!void {
|
|
783
|
+
return single(self, .SingleTurn, args);
|
|
784
|
+
}
|
|
785
|
+
|
|
786
|
+
// ident: ID, move: <Move>
|
|
787
|
+
fn single(self: Self, arg: ArgType, args: anytype) Error!void {
|
|
579
788
|
if (!enabled) return;
|
|
580
789
|
|
|
581
790
|
try self.writer.writeAll(&.{
|
|
582
|
-
@intFromEnum(
|
|
583
|
-
@as(u8, @bitCast(
|
|
584
|
-
@
|
|
791
|
+
@intFromEnum(arg),
|
|
792
|
+
@as(u8, @bitCast(args[0])),
|
|
793
|
+
@intFromEnum(args[1]),
|
|
794
|
+
});
|
|
795
|
+
}
|
|
796
|
+
|
|
797
|
+
// weather: <Weather>, reason: Weather
|
|
798
|
+
pub fn weather(self: Self, args: anytype) Error!void {
|
|
799
|
+
if (!enabled) return;
|
|
800
|
+
|
|
801
|
+
assert(!(args[0] == .None and args[1] == .Upkeep));
|
|
802
|
+
try self.writer.writeAll(&.{
|
|
803
|
+
@intFromEnum(ArgType.Weather),
|
|
804
|
+
@intFromEnum(args[0]),
|
|
805
|
+
@intFromEnum(@as(Weather, args[1])),
|
|
585
806
|
});
|
|
586
807
|
}
|
|
587
808
|
|
|
588
|
-
|
|
809
|
+
// -
|
|
810
|
+
pub fn laststill(self: Self, _: anytype) Error!void {
|
|
589
811
|
if (!enabled) return;
|
|
590
812
|
|
|
591
813
|
try self.writer.writeAll(&.{@intFromEnum(ArgType.LastStill)});
|
|
592
814
|
}
|
|
593
815
|
|
|
594
|
-
|
|
816
|
+
// -
|
|
817
|
+
pub fn lastmiss(self: Self, _: anytype) Error!void {
|
|
595
818
|
if (!enabled) return;
|
|
596
819
|
|
|
597
820
|
try self.writer.writeAll(&.{@intFromEnum(ArgType.LastMiss)});
|
|
@@ -599,56 +822,72 @@ pub fn Log(comptime Writer: type) type {
|
|
|
599
822
|
};
|
|
600
823
|
}
|
|
601
824
|
|
|
602
|
-
/// `Log` type backed by the optimized `
|
|
603
|
-
pub const FixedLog = Log(
|
|
825
|
+
/// `Log` type backed by the optimized `Writer`.
|
|
826
|
+
pub const FixedLog = Log(*Writer);
|
|
604
827
|
|
|
605
|
-
///
|
|
606
|
-
///
|
|
607
|
-
///
|
|
608
|
-
pub const
|
|
828
|
+
/// Minimal logging helper optimized for efficiently writing the individual protocol bytes into a
|
|
829
|
+
/// fixed buffer. Note that this is **not** a `std.Io.Writer` and should not be used for general
|
|
830
|
+
/// purpose writing.
|
|
831
|
+
pub const Writer = struct {
|
|
609
832
|
buffer: []u8,
|
|
610
833
|
pos: usize = 0,
|
|
611
834
|
|
|
612
|
-
pub const
|
|
613
|
-
stream: *ByteStream,
|
|
835
|
+
pub const Error = error{NoSpaceLeft};
|
|
614
836
|
|
|
615
|
-
|
|
837
|
+
pub fn writeByte(self: *Writer, byte: u8) Error!void {
|
|
838
|
+
if (self.pos >= self.buffer.len) return error.NoSpaceLeft;
|
|
839
|
+
self.buffer[self.pos] = byte;
|
|
840
|
+
self.pos += 1;
|
|
841
|
+
}
|
|
616
842
|
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
843
|
+
pub fn writeAll(self: *Writer, bytes: []const u8) Error!void {
|
|
844
|
+
const npos = self.pos + bytes.len;
|
|
845
|
+
if (npos > self.buffer.len) return error.NoSpaceLeft;
|
|
846
|
+
@memcpy(self.buffer[self.pos..npos], bytes);
|
|
847
|
+
self.pos = npos;
|
|
848
|
+
}
|
|
620
849
|
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
850
|
+
pub fn writeInt(self: *Writer, comptime T: type, v: T, end: std.builtin.Endian) Error!void {
|
|
851
|
+
const bytes = @divExact(@typeInfo(T).int.bits, 8);
|
|
852
|
+
const npos = self.pos + bytes;
|
|
853
|
+
if (npos > self.buffer.len) return error.NoSpaceLeft;
|
|
854
|
+
std.mem.writeInt(T, self.buffer[self.pos..][0..bytes], v, end);
|
|
855
|
+
self.pos = npos;
|
|
856
|
+
}
|
|
624
857
|
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
return self.writeAll(&bytes);
|
|
630
|
-
}
|
|
631
|
-
};
|
|
858
|
+
pub fn reset(self: *Writer) void {
|
|
859
|
+
self.pos = 0;
|
|
860
|
+
}
|
|
861
|
+
};
|
|
632
862
|
|
|
633
|
-
|
|
634
|
-
|
|
863
|
+
/// Null object pattern implementation of `Log` backed by a null writer. Ignores anything sent to
|
|
864
|
+
/// it, though protocol logging should additionally be turned off entirely with `options.log`.
|
|
865
|
+
pub const NULL = Log(NullWriter){ .writer = .{} };
|
|
866
|
+
|
|
867
|
+
const NullWriter = struct {
|
|
868
|
+
pub const Error = error{};
|
|
869
|
+
|
|
870
|
+
pub fn writeByte(self: NullWriter, byte: u8) Error!void {
|
|
871
|
+
_ = .{ self, byte };
|
|
635
872
|
}
|
|
636
873
|
|
|
637
|
-
pub fn
|
|
638
|
-
|
|
639
|
-
self.buffer[self.pos] = byte;
|
|
640
|
-
self.pos += 1;
|
|
874
|
+
pub fn writeAll(self: NullWriter, bytes: []const u8) Error!void {
|
|
875
|
+
_ = .{ self, bytes };
|
|
641
876
|
}
|
|
642
877
|
|
|
643
|
-
pub fn
|
|
644
|
-
|
|
878
|
+
pub fn writeInt(self: NullWriter, comptime T: type, v: T, end: std.builtin.Endian) Error!void {
|
|
879
|
+
_ = .{ self, T, v, end };
|
|
645
880
|
}
|
|
646
881
|
};
|
|
647
882
|
|
|
648
|
-
pub const Kind = enum { Move, Species, Type, Status };
|
|
649
|
-
pub const Formatter = fn (Kind, u8) []const u8;
|
|
883
|
+
pub const Kind = enum { Move, Species, Type, Status, Item, Weather };
|
|
650
884
|
|
|
651
|
-
pub fn format(
|
|
885
|
+
pub fn format(
|
|
886
|
+
gen: anytype,
|
|
887
|
+
a: []const u8,
|
|
888
|
+
b: ?[]const u8,
|
|
889
|
+
color: bool,
|
|
890
|
+
) void {
|
|
652
891
|
print("\n", .{});
|
|
653
892
|
|
|
654
893
|
var i: usize = 0;
|
|
@@ -686,6 +925,18 @@ pub fn format(comptime formatter: Formatter, a: []const u8, b: ?[]const u8, colo
|
|
|
686
925
|
.Resisted => "|-resisted|",
|
|
687
926
|
.Immune => "|-immune|",
|
|
688
927
|
.Transform => "|-transform|",
|
|
928
|
+
.Drag => "|drag|",
|
|
929
|
+
.Item => "|-item|",
|
|
930
|
+
.EndItem => "|-enditem|",
|
|
931
|
+
.CureTeam => "|-cureteam|",
|
|
932
|
+
.SetHP => "|-sethp|",
|
|
933
|
+
.SetBoost => "|-setboost|",
|
|
934
|
+
.CopyBoost => "|-copyboost|",
|
|
935
|
+
.SideStart => "|-sidestart|",
|
|
936
|
+
.SideEnd => "|-sideend|",
|
|
937
|
+
.SingleMove => "|-singlemove|",
|
|
938
|
+
.SingleTurn => "|-singleturn|",
|
|
939
|
+
.Weather => "|-weather|",
|
|
689
940
|
else => unreachable,
|
|
690
941
|
};
|
|
691
942
|
printc("{s}", .{name}, a, b, &i, 1, color);
|
|
@@ -701,33 +952,43 @@ pub fn format(comptime formatter: Formatter, a: []const u8, b: ?[]const u8, colo
|
|
|
701
952
|
.Move => {
|
|
702
953
|
const source = ID.from(@intCast(a[i]));
|
|
703
954
|
printc(" {s}({d})", .{ @tagName(source.player), source.id }, a, b, &i, 1, color);
|
|
704
|
-
printc(" {s}", .{formatter(.Move, a[i])}, a, b, &i, 1, color);
|
|
955
|
+
printc(" {s}", .{formatter(gen, .Move, a[i])}, a, b, &i, 1, color);
|
|
705
956
|
const target = ID.from(@intCast(a[i]));
|
|
706
957
|
printc(" {s}({d})", .{ @tagName(target.player), target.id }, a, b, &i, 1, color);
|
|
707
958
|
const reason: Move = @enumFromInt(a[i]);
|
|
708
959
|
printc(" {s}", .{@tagName(reason)}, a, b, &i, 1, color);
|
|
709
|
-
if (reason == .From)
|
|
960
|
+
if (reason == .From) {
|
|
961
|
+
printc(" {s}", .{formatter(gen, .Move, a[i])}, a, b, &i, 1, color);
|
|
962
|
+
}
|
|
710
963
|
},
|
|
711
|
-
.Switch => {
|
|
964
|
+
.Switch, .Drag => {
|
|
712
965
|
const id = ID.from(@intCast(a[i]));
|
|
713
966
|
printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
|
|
714
|
-
printc(" {s}", .{formatter(.Species, a[i])}, a, b, &i, 1, color);
|
|
967
|
+
printc(" {s}", .{formatter(gen, .Species, a[i])}, a, b, &i, 1, color);
|
|
968
|
+
if (@hasDecl(gen, "Gender")) {
|
|
969
|
+
if (a[i] == N(gen.Gender.Unknown)) {
|
|
970
|
+
i += 1;
|
|
971
|
+
} else {
|
|
972
|
+
const gender = if (a[i] == N(gen.Gender.Male)) "M" else "F";
|
|
973
|
+
printc(", {s}", .{gender}, a, b, &i, 1, color);
|
|
974
|
+
}
|
|
975
|
+
}
|
|
715
976
|
printc(" L{d}", .{a[i]}, a, b, &i, 1, color);
|
|
716
977
|
switch (endian) {
|
|
717
|
-
.
|
|
978
|
+
.big => {
|
|
718
979
|
var hp = @as(u16, a[i]) << 8 | @as(u16, a[i + 1]);
|
|
719
980
|
printc(" {d}", .{hp}, a, b, &i, 2, color);
|
|
720
981
|
hp = @as(u16, a[i]) << 8 | @as(u16, a[i + 1]);
|
|
721
982
|
printc("/{d}", .{hp}, a, b, &i, 2, color);
|
|
722
983
|
},
|
|
723
|
-
.
|
|
984
|
+
.little => {
|
|
724
985
|
var hp = @as(u16, a[i + 1]) << 8 | @as(u16, a[i]);
|
|
725
986
|
printc(" {d}", .{hp}, a, b, &i, 2, color);
|
|
726
987
|
hp = @as(u16, a[i + 1]) << 8 | @as(u16, a[i]);
|
|
727
988
|
printc("/{d}", .{hp}, a, b, &i, 2, color);
|
|
728
989
|
},
|
|
729
990
|
}
|
|
730
|
-
printc(" {s}", .{formatter(.Status, a[i])}, a, b, &i, 1, color);
|
|
991
|
+
printc(" {s}", .{formatter(gen, .Status, a[i])}, a, b, &i, 1, color);
|
|
731
992
|
},
|
|
732
993
|
.Cant => {
|
|
733
994
|
const id = ID.from(@intCast(a[i]));
|
|
@@ -735,7 +996,7 @@ pub fn format(comptime formatter: Formatter, a: []const u8, b: ?[]const u8, colo
|
|
|
735
996
|
const reason: Cant = @enumFromInt(a[i]);
|
|
736
997
|
printc(" {s}", .{@tagName(reason)}, a, b, &i, 1, color);
|
|
737
998
|
if (reason == .Disable) {
|
|
738
|
-
printc(" {s}", .{formatter(.Move, a[i])}, a, b, &i, 1, color);
|
|
999
|
+
printc(" {s}", .{formatter(gen, .Move, a[i])}, a, b, &i, 1, color);
|
|
739
1000
|
}
|
|
740
1001
|
},
|
|
741
1002
|
.Faint,
|
|
@@ -744,14 +1005,15 @@ pub fn format(comptime formatter: Formatter, a: []const u8, b: ?[]const u8, colo
|
|
|
744
1005
|
.Crit,
|
|
745
1006
|
.SuperEffective,
|
|
746
1007
|
.Resisted,
|
|
1008
|
+
.CureTeam,
|
|
747
1009
|
=> {
|
|
748
1010
|
const id = ID.from(@intCast(a[i]));
|
|
749
1011
|
printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
|
|
750
1012
|
},
|
|
751
1013
|
.Turn => {
|
|
752
1014
|
const turn = switch (endian) {
|
|
753
|
-
.
|
|
754
|
-
.
|
|
1015
|
+
.big => @as(u16, a[i]) << 8 | @as(u16, a[i + 1]),
|
|
1016
|
+
.little => @as(u16, a[i + 1]) << 8 | @as(u16, a[i]),
|
|
755
1017
|
};
|
|
756
1018
|
printc(" {d}", .{turn}, a, b, &i, 2, color);
|
|
757
1019
|
},
|
|
@@ -762,20 +1024,20 @@ pub fn format(comptime formatter: Formatter, a: []const u8, b: ?[]const u8, colo
|
|
|
762
1024
|
var id = ID.from(@intCast(a[i]));
|
|
763
1025
|
printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
|
|
764
1026
|
switch (endian) {
|
|
765
|
-
.
|
|
1027
|
+
.big => {
|
|
766
1028
|
var hp = @as(u16, a[i]) << 8 | @as(u16, a[i + 1]);
|
|
767
1029
|
printc(" {d}", .{hp}, a, b, &i, 2, color);
|
|
768
1030
|
hp = @as(u16, a[i]) << 8 | @as(u16, a[i + 1]);
|
|
769
1031
|
printc("/{d}", .{hp}, a, b, &i, 2, color);
|
|
770
1032
|
},
|
|
771
|
-
.
|
|
1033
|
+
.little => {
|
|
772
1034
|
var hp = @as(u16, a[i + 1]) << 8 | @as(u16, a[i]);
|
|
773
1035
|
printc(" {d}", .{hp}, a, b, &i, 2, color);
|
|
774
1036
|
hp = @as(u16, a[i + 1]) << 8 | @as(u16, a[i]);
|
|
775
1037
|
printc("/{d}", .{hp}, a, b, &i, 2, color);
|
|
776
1038
|
},
|
|
777
1039
|
}
|
|
778
|
-
printc(" {s}", .{formatter(.Status, a[i])}, a, b, &i, 1, color);
|
|
1040
|
+
printc(" {s}", .{formatter(gen, .Status, a[i])}, a, b, &i, 1, color);
|
|
779
1041
|
if (arg == .Damage) {
|
|
780
1042
|
const reason: Damage = @enumFromInt(a[i]);
|
|
781
1043
|
printc(" {s}", .{@tagName(reason)}, a, b, &i, 1, color);
|
|
@@ -795,15 +1057,17 @@ pub fn format(comptime formatter: Formatter, a: []const u8, b: ?[]const u8, colo
|
|
|
795
1057
|
.Status => {
|
|
796
1058
|
const id = ID.from(@intCast(a[i]));
|
|
797
1059
|
printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
|
|
798
|
-
printc(" {s}", .{formatter(.Status, a[i])}, a, b, &i, 1, color);
|
|
1060
|
+
printc(" {s}", .{formatter(gen, .Status, a[i])}, a, b, &i, 1, color);
|
|
799
1061
|
const reason: Status = @enumFromInt(a[i]);
|
|
800
1062
|
printc(" {s}", .{@tagName(reason)}, a, b, &i, 1, color);
|
|
801
|
-
if (reason == .From)
|
|
1063
|
+
if (reason == .From) {
|
|
1064
|
+
printc(" {s}", .{formatter(gen, .Move, a[i])}, a, b, &i, 1, color);
|
|
1065
|
+
}
|
|
802
1066
|
},
|
|
803
1067
|
.CureStatus => {
|
|
804
1068
|
const id = ID.from(@intCast(a[i]));
|
|
805
1069
|
printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
|
|
806
|
-
printc(" {s}", .{formatter(.Status, a[i])}, a, b, &i, 1, color);
|
|
1070
|
+
printc(" {s}", .{formatter(gen, .Status, a[i])}, a, b, &i, 1, color);
|
|
807
1071
|
const reason: CureStatus = @enumFromInt(a[i]);
|
|
808
1072
|
printc(" {s}", .{@tagName(reason)}, a, b, &i, 1, color);
|
|
809
1073
|
},
|
|
@@ -818,20 +1082,26 @@ pub fn format(comptime formatter: Formatter, a: []const u8, b: ?[]const u8, colo
|
|
|
818
1082
|
printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
|
|
819
1083
|
printc(" {s}", .{@tagName(@as(Fail, @enumFromInt(a[i])))}, a, b, &i, 1, color);
|
|
820
1084
|
},
|
|
821
|
-
.HitCount => {
|
|
1085
|
+
.HitCount, .SetBoost => {
|
|
822
1086
|
const id = ID.from(@intCast(a[i]));
|
|
823
1087
|
printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
|
|
824
1088
|
printc(" {d}", .{a[i]}, a, b, &i, 1, color);
|
|
825
1089
|
},
|
|
826
|
-
.Prepare => {
|
|
1090
|
+
.Prepare, .SingleMove, .SingleTurn => {
|
|
827
1091
|
const id = ID.from(@intCast(a[i]));
|
|
828
1092
|
printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
|
|
829
|
-
printc(" {s}", .{formatter(.Move, a[i])}, a, b, &i, 1, color);
|
|
1093
|
+
printc(" {s}", .{formatter(gen, .Move, a[i])}, a, b, &i, 1, color);
|
|
830
1094
|
},
|
|
831
1095
|
.Activate => {
|
|
832
1096
|
const id = ID.from(@intCast(a[i]));
|
|
833
1097
|
printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
|
|
834
|
-
|
|
1098
|
+
const reason: Activate = @enumFromInt(a[i]);
|
|
1099
|
+
printc(" {s}", .{@tagName(reason)}, a, b, &i, 1, color);
|
|
1100
|
+
if (reason == .SubstituteBlock) {
|
|
1101
|
+
printc(" {s}", .{formatter(gen, .Move, a[i])}, a, b, &i, 1, color);
|
|
1102
|
+
} else if (reason == .Magnitude) {
|
|
1103
|
+
printc(" {d}", .{a[i]}, a, b, &i, 1, color);
|
|
1104
|
+
}
|
|
835
1105
|
},
|
|
836
1106
|
.Start => {
|
|
837
1107
|
const id = ID.from(@intCast(a[i]));
|
|
@@ -839,14 +1109,15 @@ pub fn format(comptime formatter: Formatter, a: []const u8, b: ?[]const u8, colo
|
|
|
839
1109
|
const reason = a[i];
|
|
840
1110
|
printc(" {s}", .{@tagName(@as(Start, @enumFromInt(reason)))}, a, b, &i, 1, color);
|
|
841
1111
|
if (@as(Start, @enumFromInt(reason)) == .TypeChange) {
|
|
1112
|
+
// FIXME
|
|
842
1113
|
const types = @as(gen1.Types, @bitCast(a[i]));
|
|
843
1114
|
const args = .{
|
|
844
|
-
formatter(.Type, @intFromEnum(types.type1)),
|
|
845
|
-
formatter(.Type, @intFromEnum(types.type2)),
|
|
1115
|
+
formatter(gen, .Type, @intFromEnum(types.type1)),
|
|
1116
|
+
formatter(gen, .Type, @intFromEnum(types.type2)),
|
|
846
1117
|
};
|
|
847
1118
|
printc(" {s}/{s}", args, a, b, &i, 1, color);
|
|
848
1119
|
} else if (reason >= @intFromEnum(Start.Disable)) {
|
|
849
|
-
printc(" {s}", .{formatter(.Move, a[i])}, a, b, &i, 1, color);
|
|
1120
|
+
printc(" {s}", .{formatter(gen, .Move, a[i])}, a, b, &i, 1, color);
|
|
850
1121
|
}
|
|
851
1122
|
},
|
|
852
1123
|
.End => {
|
|
@@ -859,12 +1130,64 @@ pub fn format(comptime formatter: Formatter, a: []const u8, b: ?[]const u8, colo
|
|
|
859
1130
|
printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
|
|
860
1131
|
printc(" {s}", .{@tagName(@as(Immune, @enumFromInt(a[i])))}, a, b, &i, 1, color);
|
|
861
1132
|
},
|
|
862
|
-
.Transform => {
|
|
1133
|
+
.Transform, .CopyBoost => {
|
|
863
1134
|
const source = ID.from(@intCast(a[i]));
|
|
864
1135
|
printc(" {s}({d})", .{ @tagName(source.player), source.id }, a, b, &i, 1, color);
|
|
865
1136
|
const target = ID.from(@intCast(a[i]));
|
|
866
1137
|
printc(" {s}({d})", .{ @tagName(target.player), target.id }, a, b, &i, 1, color);
|
|
867
1138
|
},
|
|
1139
|
+
.Item, .EndItem => {
|
|
1140
|
+
var id = ID.from(@intCast(a[i]));
|
|
1141
|
+
printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
|
|
1142
|
+
printc(" {s}", .{formatter(gen, .Item, a[i])}, a, b, &i, 1, color);
|
|
1143
|
+
if (arg == .Item) {
|
|
1144
|
+
id = ID.from(@intCast(a[i]));
|
|
1145
|
+
printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
|
|
1146
|
+
} else {
|
|
1147
|
+
const reason: EndItem = @enumFromInt(a[i]);
|
|
1148
|
+
printc(" {s}", .{@tagName(reason)}, a, b, &i, 1, color);
|
|
1149
|
+
}
|
|
1150
|
+
},
|
|
1151
|
+
.SetHP => {
|
|
1152
|
+
const id = ID.from(@intCast(a[i]));
|
|
1153
|
+
printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
|
|
1154
|
+
switch (endian) {
|
|
1155
|
+
.big => {
|
|
1156
|
+
var hp = @as(u16, a[i]) << 8 | @as(u16, a[i + 1]);
|
|
1157
|
+
printc(" {d}", .{hp}, a, b, &i, 2, color);
|
|
1158
|
+
hp = @as(u16, a[i]) << 8 | @as(u16, a[i + 1]);
|
|
1159
|
+
printc("/{d}", .{hp}, a, b, &i, 2, color);
|
|
1160
|
+
},
|
|
1161
|
+
.little => {
|
|
1162
|
+
var hp = @as(u16, a[i + 1]) << 8 | @as(u16, a[i]);
|
|
1163
|
+
printc(" {d}", .{hp}, a, b, &i, 2, color);
|
|
1164
|
+
hp = @as(u16, a[i + 1]) << 8 | @as(u16, a[i]);
|
|
1165
|
+
printc("/{d}", .{hp}, a, b, &i, 2, color);
|
|
1166
|
+
},
|
|
1167
|
+
}
|
|
1168
|
+
printc(" {s}", .{formatter(gen, .Status, a[i])}, a, b, &i, 1, color);
|
|
1169
|
+
printc(" {s}", .{@tagName(@as(SetHP, @enumFromInt(a[i])))}, a, b, &i, 1, color);
|
|
1170
|
+
},
|
|
1171
|
+
.SideStart => {
|
|
1172
|
+
const id = ID.from(@intCast(a[i]));
|
|
1173
|
+
printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
|
|
1174
|
+
printc(" {s}", .{@tagName(@as(Side, @enumFromInt(a[i])))}, a, b, &i, 1, color);
|
|
1175
|
+
},
|
|
1176
|
+
.SideEnd => {
|
|
1177
|
+
var id = ID.from(@intCast(a[i]));
|
|
1178
|
+
printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
|
|
1179
|
+
const reason: Side = @enumFromInt(a[i]);
|
|
1180
|
+
printc(" {s}", .{@tagName(reason)}, a, b, &i, 1, color);
|
|
1181
|
+
if (reason == .Spikes) {
|
|
1182
|
+
printc(" {s}", .{formatter(gen, .Move, a[i])}, a, b, &i, 1, color);
|
|
1183
|
+
id = ID.from(@intCast(a[i]));
|
|
1184
|
+
printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
|
|
1185
|
+
}
|
|
1186
|
+
},
|
|
1187
|
+
.Weather => {
|
|
1188
|
+
printc(" {s}", .{formatter(gen, .Weather, a[i])}, a, b, &i, 1, color);
|
|
1189
|
+
printc(" {s}", .{@tagName(@as(Weather, @enumFromInt(a[i])))}, a, b, &i, 1, color);
|
|
1190
|
+
},
|
|
868
1191
|
else => unreachable,
|
|
869
1192
|
}
|
|
870
1193
|
print("\n", .{});
|
|
@@ -896,30 +1219,22 @@ fn printc(
|
|
|
896
1219
|
}
|
|
897
1220
|
|
|
898
1221
|
pub fn expectLog(
|
|
899
|
-
comptime
|
|
1222
|
+
comptime gen: anytype,
|
|
900
1223
|
expected: []const u8,
|
|
901
1224
|
actual: []const u8,
|
|
902
1225
|
offset: usize,
|
|
903
1226
|
) !void {
|
|
904
1227
|
if (!enabled) return;
|
|
905
1228
|
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
break :color true;
|
|
909
|
-
} else if (std.process.hasEnvVarConstant("NO_COLOR")) {
|
|
910
|
-
break :color false;
|
|
911
|
-
} else {
|
|
912
|
-
break :color std.io.getStdErr().supportsAnsiEscapeCodes();
|
|
913
|
-
}
|
|
914
|
-
};
|
|
1229
|
+
// TODO: ziglang/zig#30833 - read from environment
|
|
1230
|
+
const color = true;
|
|
915
1231
|
|
|
916
1232
|
expectEqualBytes(expected, actual, offset) catch |err| switch (err) {
|
|
917
1233
|
error.TestExpectedEqual => {
|
|
918
|
-
format(
|
|
919
|
-
format(
|
|
1234
|
+
format(gen, expected, null, color);
|
|
1235
|
+
format(gen, actual, expected, color);
|
|
920
1236
|
return err;
|
|
921
1237
|
},
|
|
922
|
-
else => return err,
|
|
923
1238
|
};
|
|
924
1239
|
}
|
|
925
1240
|
|
|
@@ -927,7 +1242,7 @@ fn expectEqualBytes(expected: []const u8, actual: []const u8, offset: usize) !vo
|
|
|
927
1242
|
for (offset..@min(expected.len, actual.len)) |i| {
|
|
928
1243
|
if (expected[i] != actual[i]) {
|
|
929
1244
|
print(
|
|
930
|
-
"index {} incorrect. expected 0x{X:0>2}, found 0x{X:0>2}\n",
|
|
1245
|
+
"index {d} incorrect. expected 0x{X:0>2}, found 0x{X:0>2}\n",
|
|
931
1246
|
.{ i, expected[i], actual[i] },
|
|
932
1247
|
);
|
|
933
1248
|
return error.TestExpectedEqual;
|
|
@@ -942,8 +1257,6 @@ fn expectEqualBytes(expected: []const u8, actual: []const u8, offset: usize) !vo
|
|
|
942
1257
|
}
|
|
943
1258
|
}
|
|
944
1259
|
|
|
945
|
-
const endian = builtin.target.cpu.arch.endian();
|
|
946
|
-
|
|
947
1260
|
fn N(e: anytype) u8 {
|
|
948
1261
|
return @intFromEnum(e);
|
|
949
1262
|
}
|
|
@@ -951,76 +1264,90 @@ fn N(e: anytype) u8 {
|
|
|
951
1264
|
const p1 = Player.P1;
|
|
952
1265
|
const p2 = Player.P2;
|
|
953
1266
|
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
1267
|
+
var buf: [pkmn.LOGS_SIZE]u8 = undefined;
|
|
1268
|
+
var writer: Writer = .{ .buffer = &buf };
|
|
1269
|
+
var log: FixedLog = .{ .writer = &writer };
|
|
1270
|
+
|
|
1271
|
+
const gen1 = pkmn.gen1;
|
|
1272
|
+
const gen2 = pkmn.gen2;
|
|
958
1273
|
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
var log: FixedLog = .{ .writer = stream.writer() };
|
|
1274
|
+
const M1 = gen1.Move;
|
|
1275
|
+
const S1 = gen1.Species;
|
|
962
1276
|
|
|
963
|
-
const
|
|
964
|
-
const
|
|
1277
|
+
const M2 = gen2.Move;
|
|
1278
|
+
const S2 = gen2.Species;
|
|
1279
|
+
const I2 = gen2.Item;
|
|
1280
|
+
const W2 = gen2.Weather;
|
|
965
1281
|
|
|
966
1282
|
fn expectLog1(expected: []const u8, actual: []const u8) !void {
|
|
967
|
-
return expectLog(
|
|
1283
|
+
return expectLog(gen1, expected, actual, 0);
|
|
968
1284
|
}
|
|
969
1285
|
|
|
970
|
-
fn
|
|
1286
|
+
fn expectLog2(expected: []const u8, actual: []const u8) !void {
|
|
1287
|
+
return expectLog(gen2, expected, actual, 0);
|
|
1288
|
+
}
|
|
1289
|
+
|
|
1290
|
+
fn formatter(comptime gen: anytype, kind: Kind, byte: u8) []const u8 {
|
|
971
1291
|
return switch (kind) {
|
|
972
|
-
.Move => @tagName(@as(
|
|
973
|
-
.Species => @tagName(@as(
|
|
974
|
-
.Type => @tagName(@as(
|
|
975
|
-
.Status =>
|
|
1292
|
+
.Move => @tagName(@as(gen.Move, @enumFromInt(byte))),
|
|
1293
|
+
.Species => @tagName(@as(gen.Species, @enumFromInt(byte))),
|
|
1294
|
+
.Type => @tagName(@as(gen.Type, @enumFromInt(byte))),
|
|
1295
|
+
.Status => gen.Status.name(byte),
|
|
1296
|
+
.Item => if (@hasDecl(gen, "Item"))
|
|
1297
|
+
@tagName(@as(gen.Item, @enumFromInt(byte)))
|
|
1298
|
+
else
|
|
1299
|
+
unreachable,
|
|
1300
|
+
.Weather => if (@hasDecl(gen, "Weather"))
|
|
1301
|
+
@tagName(@as(gen.Weather, @enumFromInt(byte)))
|
|
1302
|
+
else
|
|
1303
|
+
unreachable,
|
|
976
1304
|
};
|
|
977
1305
|
}
|
|
978
1306
|
|
|
979
1307
|
test "|move|" {
|
|
980
|
-
try log.move(p2.ident(4),
|
|
1308
|
+
try log.move(.{ p2.ident(4), M1.Thunderbolt, p1.ident(5) });
|
|
981
1309
|
try expectLog1(
|
|
982
|
-
&.{ N(ArgType.Move), 0b1100, N(
|
|
1310
|
+
&.{ N(ArgType.Move), 0b1100, N(M1.Thunderbolt), 0b0101, N(Move.None) },
|
|
983
1311
|
buf[0..5],
|
|
984
1312
|
);
|
|
985
|
-
|
|
1313
|
+
writer.reset();
|
|
986
1314
|
|
|
987
|
-
try log.move(p2.ident(4),
|
|
988
|
-
const wrap = N(M.Wrap);
|
|
1315
|
+
try log.move(.{ p2.ident(4), M1.Pound, p1.ident(5), M1.Metronome });
|
|
989
1316
|
try expectLog1(
|
|
990
|
-
&.{ N(ArgType.Move), 0b1100,
|
|
1317
|
+
&.{ N(ArgType.Move), 0b1100, N(M1.Pound), 0b0101, N(Move.From), N(M1.Metronome) },
|
|
991
1318
|
buf[0..6],
|
|
992
1319
|
);
|
|
993
|
-
|
|
1320
|
+
writer.reset();
|
|
994
1321
|
|
|
995
|
-
try log.move(p2.ident(4),
|
|
996
|
-
try log.laststill();
|
|
1322
|
+
try log.move(.{ p2.ident(4), M1.SkullBash, ID{} });
|
|
1323
|
+
try log.laststill(.{});
|
|
997
1324
|
try expectLog1(
|
|
998
1325
|
&.{
|
|
999
1326
|
N(ArgType.Move),
|
|
1000
1327
|
0b1100,
|
|
1001
|
-
N(
|
|
1328
|
+
N(M1.SkullBash),
|
|
1002
1329
|
0,
|
|
1003
1330
|
N(Move.None),
|
|
1004
1331
|
N(ArgType.LastStill),
|
|
1005
1332
|
},
|
|
1006
1333
|
buf[0..6],
|
|
1007
1334
|
);
|
|
1008
|
-
|
|
1335
|
+
writer.reset();
|
|
1009
1336
|
|
|
1010
|
-
try log.move(p2.ident(4),
|
|
1011
|
-
try log.lastmiss();
|
|
1337
|
+
try log.move(.{ p2.ident(4), M1.Tackle, p1.ident(5) });
|
|
1338
|
+
try log.lastmiss(.{});
|
|
1012
1339
|
try expectLog1(
|
|
1013
1340
|
&.{
|
|
1014
1341
|
N(ArgType.Move),
|
|
1015
1342
|
0b1100,
|
|
1016
|
-
N(
|
|
1343
|
+
N(M1.Tackle),
|
|
1017
1344
|
0b0101,
|
|
1018
1345
|
N(Move.None),
|
|
1019
1346
|
N(ArgType.LastMiss),
|
|
1020
1347
|
},
|
|
1021
1348
|
buf[0..6],
|
|
1022
1349
|
);
|
|
1023
|
-
|
|
1350
|
+
writer.reset();
|
|
1024
1351
|
}
|
|
1025
1352
|
|
|
1026
1353
|
test "|switch|" {
|
|
@@ -1029,333 +1356,495 @@ test "|switch|" {
|
|
|
1029
1356
|
snorlax.hp = 200;
|
|
1030
1357
|
snorlax.stats.hp = 400;
|
|
1031
1358
|
snorlax.status = gen1.Status.init(.PAR);
|
|
1032
|
-
try log.switched(p2.ident(3), &snorlax);
|
|
1359
|
+
try log.switched(.{ p2.ident(3), &snorlax });
|
|
1033
1360
|
const par = 0b1000000;
|
|
1034
1361
|
var expected: []const u8 = switch (endian) {
|
|
1035
|
-
.
|
|
1036
|
-
.
|
|
1362
|
+
.big => &.{ N(ArgType.Switch), 0b1011, N(S1.Snorlax), 91, 0, 200, 1, 144, par },
|
|
1363
|
+
.little => &.{ N(ArgType.Switch), 0b1011, N(S1.Snorlax), 91, 200, 0, 144, 1, par },
|
|
1037
1364
|
};
|
|
1038
1365
|
try expectLog1(expected, buf[0..9]);
|
|
1039
|
-
|
|
1366
|
+
writer.reset();
|
|
1040
1367
|
|
|
1041
1368
|
snorlax.level = 100;
|
|
1042
1369
|
snorlax.hp = 0;
|
|
1043
1370
|
snorlax.status = 0;
|
|
1044
|
-
try log.switched(p2.ident(3), &snorlax);
|
|
1371
|
+
try log.switched(.{ p2.ident(3), &snorlax });
|
|
1045
1372
|
expected = switch (endian) {
|
|
1046
|
-
.
|
|
1047
|
-
.
|
|
1373
|
+
.big => &.{ N(ArgType.Switch), 0b1011, N(S1.Snorlax), 100, 0, 0, 1, 144, 0 },
|
|
1374
|
+
.little => &.{ N(ArgType.Switch), 0b1011, N(S1.Snorlax), 100, 0, 0, 144, 1, 0 },
|
|
1048
1375
|
};
|
|
1049
1376
|
try expectLog1(expected, buf[0..9]);
|
|
1050
|
-
|
|
1377
|
+
writer.reset();
|
|
1051
1378
|
|
|
1052
1379
|
snorlax.hp = 400;
|
|
1053
|
-
try log.switched(p2.ident(3), &snorlax);
|
|
1380
|
+
try log.switched(.{ p2.ident(3), &snorlax });
|
|
1054
1381
|
expected = switch (endian) {
|
|
1055
|
-
.
|
|
1056
|
-
.
|
|
1382
|
+
.big => &.{ N(ArgType.Switch), 0b1011, N(S1.Snorlax), 100, 1, 144, 1, 144, 0 },
|
|
1383
|
+
.little => &.{ N(ArgType.Switch), 0b1011, N(S1.Snorlax), 100, 144, 1, 144, 1, 0 },
|
|
1057
1384
|
};
|
|
1058
1385
|
try expectLog1(expected, buf[0..9]);
|
|
1059
|
-
|
|
1386
|
+
writer.reset();
|
|
1387
|
+
|
|
1388
|
+
var blissey = gen2.helpers.Pokemon.init(.{ .species = .Blissey, .moves = &.{.Splash} });
|
|
1389
|
+
blissey.level = 91;
|
|
1390
|
+
blissey.hp = 200;
|
|
1391
|
+
blissey.stats.hp = 400;
|
|
1392
|
+
blissey.status = gen2.Status.init(.PAR);
|
|
1393
|
+
try log.switched(.{ p2.ident(3), &blissey });
|
|
1394
|
+
expected = &(.{
|
|
1395
|
+
N(ArgType.Switch),
|
|
1396
|
+
0b1011,
|
|
1397
|
+
N(S2.Blissey),
|
|
1398
|
+
N(gen2.Gender.Female),
|
|
1399
|
+
91,
|
|
1400
|
+
} ++ switch (endian) {
|
|
1401
|
+
.big => .{ 0, 200, 1, 144, par },
|
|
1402
|
+
.little => .{ 200, 0, 144, 1, par },
|
|
1403
|
+
});
|
|
1404
|
+
try expectLog2(expected, buf[0..10]);
|
|
1405
|
+
writer.reset();
|
|
1060
1406
|
}
|
|
1061
1407
|
|
|
1062
1408
|
test "|cant|" {
|
|
1063
|
-
try log.cant(p2.ident(6), .Bound);
|
|
1409
|
+
try log.cant(.{ p2.ident(6), .Bound });
|
|
1064
1410
|
try expectLog1(&.{ N(ArgType.Cant), 0b1110, N(Cant.Bound) }, buf[0..3]);
|
|
1065
|
-
|
|
1411
|
+
writer.reset();
|
|
1066
1412
|
|
|
1067
|
-
try log.
|
|
1068
|
-
try expectLog1(&.{ N(ArgType.Cant), 2, N(Cant.Disable), N(
|
|
1069
|
-
|
|
1413
|
+
try log.cant(.{ p1.ident(2), .Disable, M1.Earthquake });
|
|
1414
|
+
try expectLog1(&.{ N(ArgType.Cant), 2, N(Cant.Disable), N(M1.Earthquake) }, buf[0..4]);
|
|
1415
|
+
writer.reset();
|
|
1070
1416
|
}
|
|
1071
1417
|
|
|
1072
1418
|
test "|faint|" {
|
|
1073
|
-
try log.faint(p2.ident(2), false);
|
|
1419
|
+
try log.faint(.{ p2.ident(2), false });
|
|
1074
1420
|
try expectLog1(&.{ N(ArgType.Faint), 0b1010 }, buf[0..2]);
|
|
1075
|
-
|
|
1421
|
+
writer.reset();
|
|
1076
1422
|
|
|
1077
|
-
try log.faint(p2.ident(2), true);
|
|
1423
|
+
try log.faint(.{ p2.ident(2), true });
|
|
1078
1424
|
try expectLog1(&.{ N(ArgType.Faint), 0b1010, N(ArgType.None) }, buf[0..3]);
|
|
1079
|
-
|
|
1425
|
+
writer.reset();
|
|
1080
1426
|
}
|
|
1081
1427
|
|
|
1082
1428
|
test "|turn|" {
|
|
1083
|
-
try log.turn(42);
|
|
1084
|
-
|
|
1085
|
-
.
|
|
1086
|
-
.
|
|
1429
|
+
try log.turn(.{42});
|
|
1430
|
+
const expected = switch (endian) {
|
|
1431
|
+
.big => &.{ N(ArgType.Turn), 0, 42, N(ArgType.None) },
|
|
1432
|
+
.little => &.{ N(ArgType.Turn), 42, 0, N(ArgType.None) },
|
|
1087
1433
|
};
|
|
1088
1434
|
try expectLog1(expected, buf[0..4]);
|
|
1089
|
-
|
|
1435
|
+
writer.reset();
|
|
1090
1436
|
}
|
|
1091
1437
|
|
|
1092
1438
|
test "|win|" {
|
|
1093
|
-
try log.win(.P2);
|
|
1439
|
+
try log.win(.{.P2});
|
|
1094
1440
|
try expectLog1(&.{ N(ArgType.Win), 1, N(ArgType.None) }, buf[0..3]);
|
|
1095
|
-
|
|
1441
|
+
writer.reset();
|
|
1096
1442
|
}
|
|
1097
1443
|
|
|
1098
1444
|
test "|tie|" {
|
|
1099
|
-
try log.tie();
|
|
1445
|
+
try log.tie(.{});
|
|
1100
1446
|
try expectLog1(&.{ N(ArgType.Tie), N(ArgType.None) }, buf[0..2]);
|
|
1101
|
-
|
|
1447
|
+
writer.reset();
|
|
1102
1448
|
}
|
|
1103
1449
|
|
|
1104
1450
|
test "|-damage|" {
|
|
1105
1451
|
var chansey = gen1.helpers.Pokemon.init(.{ .species = .Chansey, .moves = &.{.Splash} });
|
|
1106
1452
|
chansey.hp = 612;
|
|
1107
1453
|
chansey.status = gen1.Status.slp(1);
|
|
1108
|
-
try log.damage(p2.ident(2), &chansey, .None);
|
|
1454
|
+
try log.damage(.{ p2.ident(2), &chansey, .None });
|
|
1109
1455
|
var expected: []const u8 = switch (endian) {
|
|
1110
|
-
.
|
|
1111
|
-
.
|
|
1456
|
+
.big => &.{ N(ArgType.Damage), 0b1010, 2, 100, 2, 191, 1, N(Damage.None) },
|
|
1457
|
+
.little => &.{ N(ArgType.Damage), 0b1010, 100, 2, 191, 2, 1, N(Damage.None) },
|
|
1112
1458
|
};
|
|
1113
1459
|
try expectLog1(expected, buf[0..8]);
|
|
1114
|
-
|
|
1460
|
+
writer.reset();
|
|
1115
1461
|
|
|
1116
1462
|
chansey.hp = 100;
|
|
1117
1463
|
chansey.stats.hp = 256;
|
|
1118
1464
|
chansey.status = 0;
|
|
1119
|
-
try log.damage(p2.ident(2), &chansey, .Confusion);
|
|
1465
|
+
try log.damage(.{ p2.ident(2), &chansey, .Confusion });
|
|
1120
1466
|
expected = switch (endian) {
|
|
1121
|
-
.
|
|
1122
|
-
.
|
|
1467
|
+
.big => &.{ N(ArgType.Damage), 0b1010, 0, 100, 1, 0, 0, N(Damage.Confusion) },
|
|
1468
|
+
.little => &.{ N(ArgType.Damage), 0b1010, 100, 0, 0, 1, 0, N(Damage.Confusion) },
|
|
1123
1469
|
};
|
|
1124
1470
|
try expectLog1(expected, buf[0..8]);
|
|
1125
|
-
|
|
1471
|
+
writer.reset();
|
|
1126
1472
|
|
|
1127
1473
|
chansey.status = gen1.Status.init(.PSN);
|
|
1128
|
-
try log.
|
|
1474
|
+
try log.damage(.{ p2.ident(2), &chansey, .RecoilOf, p1.ident(1) });
|
|
1129
1475
|
expected = switch (endian) {
|
|
1130
|
-
.
|
|
1131
|
-
.
|
|
1476
|
+
.big => &.{ N(ArgType.Damage), 0b1010, 0, 100, 1, 0, 0b1000, N(Damage.RecoilOf), 1 },
|
|
1477
|
+
.little => &.{ N(ArgType.Damage), 0b1010, 100, 0, 0, 1, 0b1000, N(Damage.RecoilOf), 1 },
|
|
1132
1478
|
};
|
|
1133
1479
|
try expectLog1(expected, buf[0..9]);
|
|
1134
|
-
|
|
1480
|
+
writer.reset();
|
|
1135
1481
|
}
|
|
1136
1482
|
|
|
1137
1483
|
test "|-heal|" {
|
|
1138
1484
|
var chansey = gen1.helpers.Pokemon.init(.{ .species = .Chansey, .moves = &.{.Splash} });
|
|
1139
1485
|
chansey.hp = 612;
|
|
1140
1486
|
chansey.status = gen1.Status.slp(1);
|
|
1141
|
-
try log.heal(p2.ident(2), &chansey, .None);
|
|
1487
|
+
try log.heal(.{ p2.ident(2), &chansey, .None });
|
|
1142
1488
|
var expected: []const u8 = switch (endian) {
|
|
1143
|
-
.
|
|
1144
|
-
.
|
|
1489
|
+
.big => &.{ N(ArgType.Heal), 0b1010, 2, 100, 2, 191, 1, N(Heal.None) },
|
|
1490
|
+
.little => &.{ N(ArgType.Heal), 0b1010, 100, 2, 191, 2, 1, N(Heal.None) },
|
|
1145
1491
|
};
|
|
1146
1492
|
try expectLog1(expected, buf[0..8]);
|
|
1147
|
-
|
|
1493
|
+
writer.reset();
|
|
1148
1494
|
|
|
1149
1495
|
chansey.hp = 100;
|
|
1150
1496
|
chansey.stats.hp = 256;
|
|
1151
1497
|
chansey.status = 0;
|
|
1152
|
-
try log.heal(p2.ident(2), &chansey, .Silent);
|
|
1498
|
+
try log.heal(.{ p2.ident(2), &chansey, .Silent });
|
|
1153
1499
|
expected = switch (endian) {
|
|
1154
|
-
.
|
|
1155
|
-
.
|
|
1500
|
+
.big => &.{ N(ArgType.Heal), 0b1010, 0, 100, 1, 0, 0, N(Heal.Silent) },
|
|
1501
|
+
.little => &.{ N(ArgType.Heal), 0b1010, 100, 0, 0, 1, 0, N(Heal.Silent) },
|
|
1156
1502
|
};
|
|
1157
1503
|
try expectLog1(expected, buf[0..8]);
|
|
1158
|
-
|
|
1504
|
+
writer.reset();
|
|
1159
1505
|
|
|
1160
|
-
try log.
|
|
1506
|
+
try log.heal(.{ p2.ident(2), &chansey, .Drain, p1.ident(1) });
|
|
1161
1507
|
expected = switch (endian) {
|
|
1162
|
-
.
|
|
1163
|
-
.
|
|
1508
|
+
.big => &.{ N(ArgType.Heal), 0b1010, 0, 100, 1, 0, 0, N(Heal.Drain), 1 },
|
|
1509
|
+
.little => &.{ N(ArgType.Heal), 0b1010, 100, 0, 0, 1, 0, N(Heal.Drain), 1 },
|
|
1164
1510
|
};
|
|
1165
1511
|
try expectLog1(expected, buf[0..9]);
|
|
1166
|
-
|
|
1512
|
+
writer.reset();
|
|
1167
1513
|
}
|
|
1168
1514
|
|
|
1169
1515
|
test "|-status|" {
|
|
1170
|
-
try log.status(p2.ident(6), gen1.Status.init(.BRN), .None);
|
|
1516
|
+
try log.status(.{ p2.ident(6), gen1.Status.init(.BRN), .None });
|
|
1171
1517
|
try expectLog1(&.{ N(ArgType.Status), 0b1110, 0b10000, N(Status.None) }, buf[0..4]);
|
|
1172
|
-
|
|
1518
|
+
writer.reset();
|
|
1173
1519
|
|
|
1174
|
-
try log.status(p2.ident(2), gen1.Status.init(.PSN), .Silent);
|
|
1520
|
+
try log.status(.{ p2.ident(2), gen1.Status.init(.PSN), .Silent });
|
|
1175
1521
|
try expectLog1(&.{ N(ArgType.Status), 0b1010, 0b1000, N(Status.Silent) }, buf[0..4]);
|
|
1176
|
-
|
|
1522
|
+
writer.reset();
|
|
1177
1523
|
|
|
1178
|
-
try log.
|
|
1524
|
+
try log.status(.{ p1.ident(1), gen1.Status.init(.PAR), .From, M1.BodySlam });
|
|
1179
1525
|
try expectLog1(
|
|
1180
|
-
&.{ N(ArgType.Status), 0b0001, 0b1000000, N(Status.From), N(
|
|
1526
|
+
&.{ N(ArgType.Status), 0b0001, 0b1000000, N(Status.From), N(M1.BodySlam) },
|
|
1181
1527
|
buf[0..5],
|
|
1182
1528
|
);
|
|
1183
|
-
|
|
1529
|
+
writer.reset();
|
|
1184
1530
|
}
|
|
1185
1531
|
|
|
1186
1532
|
test "|-curestatus|" {
|
|
1187
|
-
try log.curestatus(p2.ident(6), gen1.Status.slp(7), .Message);
|
|
1533
|
+
try log.curestatus(.{ p2.ident(6), gen1.Status.slp(7), .Message });
|
|
1188
1534
|
try expectLog1(&.{ N(ArgType.CureStatus), 0b1110, 0b111, N(CureStatus.Message) }, buf[0..4]);
|
|
1189
|
-
|
|
1535
|
+
writer.reset();
|
|
1190
1536
|
|
|
1191
|
-
try log.curestatus(p1.ident(2), gen1.Status.TOX, .Silent);
|
|
1537
|
+
try log.curestatus(.{ p1.ident(2), gen1.Status.TOX, .Silent });
|
|
1192
1538
|
try expectLog1(&.{
|
|
1193
1539
|
N(ArgType.CureStatus),
|
|
1194
1540
|
0b0010,
|
|
1195
1541
|
0b10001000,
|
|
1196
1542
|
N(CureStatus.Silent),
|
|
1197
1543
|
}, buf[0..4]);
|
|
1198
|
-
|
|
1544
|
+
writer.reset();
|
|
1199
1545
|
}
|
|
1200
1546
|
|
|
1201
1547
|
test "|-boost|" {
|
|
1202
|
-
try log.boost(p2.ident(6), .Speed, 2);
|
|
1548
|
+
try log.boost(.{ p2.ident(6), .Speed, 2 });
|
|
1203
1549
|
try expectLog1(&.{ N(ArgType.Boost), 0b1110, N(Boost.Speed), 8 }, buf[0..4]);
|
|
1204
|
-
|
|
1550
|
+
writer.reset();
|
|
1205
1551
|
|
|
1206
|
-
try log.boost(p1.ident(2), .Rage, 1);
|
|
1552
|
+
try log.boost(.{ p1.ident(2), .Rage, 1 });
|
|
1207
1553
|
try expectLog1(&.{ N(ArgType.Boost), 0b0010, N(Boost.Rage), 7 }, buf[0..4]);
|
|
1208
|
-
|
|
1554
|
+
writer.reset();
|
|
1209
1555
|
|
|
1210
|
-
try log.boost(p2.ident(3), .Defense, -2);
|
|
1556
|
+
try log.boost(.{ p2.ident(3), .Defense, -2 });
|
|
1211
1557
|
try expectLog1(&.{ N(ArgType.Boost), 0b1011, N(Boost.Defense), 4 }, buf[0..4]);
|
|
1212
|
-
|
|
1558
|
+
writer.reset();
|
|
1213
1559
|
}
|
|
1214
1560
|
|
|
1215
1561
|
test "|-clearallboost|" {
|
|
1216
|
-
try log.clearallboost();
|
|
1562
|
+
try log.clearallboost(.{});
|
|
1217
1563
|
try expectLog1(&.{N(ArgType.ClearAllBoost)}, buf[0..1]);
|
|
1218
|
-
|
|
1564
|
+
writer.reset();
|
|
1219
1565
|
}
|
|
1220
1566
|
|
|
1221
1567
|
test "|-fail|" {
|
|
1222
|
-
try log.fail(p2.ident(6), .None);
|
|
1568
|
+
try log.fail(.{ p2.ident(6), .None });
|
|
1223
1569
|
try expectLog1(&.{ N(ArgType.Fail), 0b1110, N(Fail.None) }, buf[0..3]);
|
|
1224
|
-
|
|
1570
|
+
writer.reset();
|
|
1225
1571
|
|
|
1226
|
-
try log.fail(p2.ident(6), .Sleep);
|
|
1572
|
+
try log.fail(.{ p2.ident(6), .Sleep });
|
|
1227
1573
|
try expectLog1(&.{ N(ArgType.Fail), 0b1110, N(Fail.Sleep) }, buf[0..3]);
|
|
1228
|
-
|
|
1574
|
+
writer.reset();
|
|
1229
1575
|
|
|
1230
|
-
try log.fail(p2.ident(6), .Substitute);
|
|
1576
|
+
try log.fail(.{ p2.ident(6), .Substitute });
|
|
1231
1577
|
try expectLog1(&.{ N(ArgType.Fail), 0b1110, N(Fail.Substitute) }, buf[0..3]);
|
|
1232
|
-
|
|
1578
|
+
writer.reset();
|
|
1233
1579
|
|
|
1234
|
-
try log.fail(p2.ident(6), .Weak);
|
|
1580
|
+
try log.fail(.{ p2.ident(6), .Weak });
|
|
1235
1581
|
try expectLog1(&.{ N(ArgType.Fail), 0b1110, N(Fail.Weak) }, buf[0..3]);
|
|
1236
|
-
|
|
1582
|
+
writer.reset();
|
|
1237
1583
|
}
|
|
1238
1584
|
|
|
1239
1585
|
test "|-miss|" {
|
|
1240
|
-
try log.miss(p2.ident(4));
|
|
1586
|
+
try log.miss(.{p2.ident(4)});
|
|
1241
1587
|
try expectLog1(&.{ N(ArgType.Miss), 0b1100 }, buf[0..2]);
|
|
1242
|
-
|
|
1588
|
+
writer.reset();
|
|
1243
1589
|
}
|
|
1244
1590
|
test "|-hitcount|" {
|
|
1245
|
-
try log.hitcount(p2.ident(1), 5);
|
|
1591
|
+
try log.hitcount(.{ p2.ident(1), 5 });
|
|
1246
1592
|
try expectLog1(&.{ N(ArgType.HitCount), 0b1001, 5 }, buf[0..3]);
|
|
1247
|
-
|
|
1593
|
+
writer.reset();
|
|
1248
1594
|
}
|
|
1249
1595
|
|
|
1250
1596
|
test "|-prepare|" {
|
|
1251
|
-
try log.prepare(p2.ident(2),
|
|
1252
|
-
try expectLog1(&.{ N(ArgType.Prepare), 0b1010, N(
|
|
1253
|
-
|
|
1597
|
+
try log.prepare(.{ p2.ident(2), M1.Dig });
|
|
1598
|
+
try expectLog1(&.{ N(ArgType.Prepare), 0b1010, N(M1.Dig) }, buf[0..3]);
|
|
1599
|
+
writer.reset();
|
|
1254
1600
|
}
|
|
1255
1601
|
|
|
1256
1602
|
test "|-mustrecharge|" {
|
|
1257
|
-
try log.mustrecharge(p1.ident(6));
|
|
1603
|
+
try log.mustrecharge(.{p1.ident(6)});
|
|
1258
1604
|
try expectLog1(&.{ N(ArgType.MustRecharge), 0b0110 }, buf[0..2]);
|
|
1259
|
-
|
|
1605
|
+
writer.reset();
|
|
1260
1606
|
}
|
|
1261
1607
|
|
|
1262
1608
|
test "|-activate|" {
|
|
1263
|
-
try log.activate(p1.ident(2), .Struggle);
|
|
1609
|
+
try log.activate(.{ p1.ident(2), .Struggle });
|
|
1264
1610
|
try expectLog1(&.{ N(ArgType.Activate), 0b0010, N(Activate.Struggle) }, buf[0..3]);
|
|
1265
|
-
|
|
1611
|
+
writer.reset();
|
|
1266
1612
|
|
|
1267
|
-
try log.activate(p2.ident(4), .Mist);
|
|
1613
|
+
try log.activate(.{ p2.ident(4), .Mist });
|
|
1268
1614
|
try expectLog1(&.{ N(ArgType.Activate), 0b1100, N(Activate.Mist) }, buf[0..3]);
|
|
1269
|
-
|
|
1615
|
+
writer.reset();
|
|
1270
1616
|
|
|
1271
|
-
try log.activate(p2.ident(6), .Substitute);
|
|
1617
|
+
try log.activate(.{ p2.ident(6), .Substitute });
|
|
1272
1618
|
try expectLog1(&.{ N(ArgType.Activate), 0b1110, N(Activate.Substitute) }, buf[0..3]);
|
|
1273
|
-
|
|
1619
|
+
writer.reset();
|
|
1274
1620
|
|
|
1275
|
-
try log.activate(p1.ident(2), .Splash);
|
|
1621
|
+
try log.activate(.{ p1.ident(2), .Splash });
|
|
1276
1622
|
try expectLog1(&.{ N(ArgType.Activate), 0b0010, N(Activate.Splash) }, buf[0..3]);
|
|
1277
|
-
|
|
1623
|
+
writer.reset();
|
|
1624
|
+
|
|
1625
|
+
try log.activate(.{ p1.ident(4), .SubstituteBlock, M2.Spite });
|
|
1626
|
+
try expectLog1(&.{
|
|
1627
|
+
N(ArgType.Activate),
|
|
1628
|
+
0b0100,
|
|
1629
|
+
N(Activate.SubstituteBlock),
|
|
1630
|
+
N(M2.Spite),
|
|
1631
|
+
}, buf[0..4]);
|
|
1632
|
+
writer.reset();
|
|
1633
|
+
|
|
1634
|
+
try log.activate(.{ p1.ident(3), .Magnitude, 5 });
|
|
1635
|
+
try expectLog1(&.{ N(ArgType.Activate), 0b0011, N(Activate.Magnitude), 5 }, buf[0..4]);
|
|
1636
|
+
writer.reset();
|
|
1278
1637
|
}
|
|
1279
1638
|
|
|
1280
1639
|
test "|-fieldactivate|" {
|
|
1281
|
-
try log.fieldactivate();
|
|
1640
|
+
try log.fieldactivate(.{});
|
|
1282
1641
|
try expectLog1(&.{N(ArgType.FieldActivate)}, buf[0..1]);
|
|
1283
|
-
|
|
1642
|
+
writer.reset();
|
|
1284
1643
|
}
|
|
1285
1644
|
|
|
1286
1645
|
test "|-start|" {
|
|
1287
|
-
try log.start(p2.ident(6), .Bide);
|
|
1646
|
+
try log.start(.{ p2.ident(6), .Bide });
|
|
1288
1647
|
try expectLog1(&.{ N(ArgType.Start), 0b1110, N(Start.Bide) }, buf[0..3]);
|
|
1289
|
-
|
|
1648
|
+
writer.reset();
|
|
1290
1649
|
|
|
1291
|
-
try log.start(p1.ident(2), .ConfusionSilent);
|
|
1650
|
+
try log.start(.{ p1.ident(2), .ConfusionSilent });
|
|
1292
1651
|
try expectLog1(&.{ N(ArgType.Start), 0b0010, N(Start.ConfusionSilent) }, buf[0..3]);
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
try log.
|
|
1652
|
+
writer.reset();
|
|
1653
|
+
|
|
1654
|
+
try log.start(.{
|
|
1655
|
+
p2.ident(6),
|
|
1656
|
+
.TypeChange,
|
|
1657
|
+
gen1.Types{ .type1 = .Fire, .type2 = .Fire },
|
|
1658
|
+
p2.ident(5),
|
|
1659
|
+
});
|
|
1296
1660
|
try expectLog1(
|
|
1297
1661
|
&.{ N(ArgType.Start), 0b1110, N(Start.TypeChange), 0b1000_1000, 0b1101 },
|
|
1298
1662
|
buf[0..5],
|
|
1299
1663
|
);
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
try log.
|
|
1664
|
+
writer.reset();
|
|
1665
|
+
|
|
1666
|
+
try log.start(.{
|
|
1667
|
+
p1.ident(2),
|
|
1668
|
+
.TypeChange,
|
|
1669
|
+
gen1.Types{ .type1 = .Bug, .type2 = .Poison },
|
|
1670
|
+
p2.ident(4),
|
|
1671
|
+
});
|
|
1303
1672
|
try expectLog1(
|
|
1304
1673
|
&.{ N(ArgType.Start), 0b0010, N(Start.TypeChange), 0b0011_0110, 0b1100 },
|
|
1305
1674
|
buf[0..5],
|
|
1306
1675
|
);
|
|
1307
|
-
|
|
1676
|
+
writer.reset();
|
|
1308
1677
|
|
|
1309
|
-
try log.
|
|
1310
|
-
try expectLog1(&.{ N(ArgType.Start), 0b0010, N(Start.Disable), N(
|
|
1311
|
-
|
|
1678
|
+
try log.start(.{ p1.ident(2), .Disable, M1.Surf });
|
|
1679
|
+
try expectLog1(&.{ N(ArgType.Start), 0b0010, N(Start.Disable), N(M1.Surf) }, buf[0..4]);
|
|
1680
|
+
writer.reset();
|
|
1312
1681
|
|
|
1313
|
-
try log.
|
|
1314
|
-
try expectLog1(&.{ N(ArgType.Start), 0b0010, N(Start.Mimic), N(
|
|
1315
|
-
|
|
1682
|
+
try log.start(.{ p1.ident(2), .Mimic, M1.Surf });
|
|
1683
|
+
try expectLog1(&.{ N(ArgType.Start), 0b0010, N(Start.Mimic), N(M1.Surf) }, buf[0..4]);
|
|
1684
|
+
writer.reset();
|
|
1316
1685
|
}
|
|
1317
1686
|
|
|
1318
1687
|
test "|-end|" {
|
|
1319
|
-
try log.end(p2.ident(6), .Bide);
|
|
1688
|
+
try log.end(.{ p2.ident(6), .Bide });
|
|
1320
1689
|
try expectLog1(&.{ N(ArgType.End), 0b1110, N(End.Bide) }, buf[0..3]);
|
|
1321
|
-
|
|
1690
|
+
writer.reset();
|
|
1322
1691
|
|
|
1323
|
-
try log.end(p1.ident(2), .ConfusionSilent);
|
|
1692
|
+
try log.end(.{ p1.ident(2), .ConfusionSilent });
|
|
1324
1693
|
try expectLog1(&.{ N(ArgType.End), 0b0010, N(End.ConfusionSilent) }, buf[0..3]);
|
|
1325
|
-
|
|
1694
|
+
writer.reset();
|
|
1326
1695
|
}
|
|
1327
1696
|
|
|
1328
1697
|
test "|-ohko|" {
|
|
1329
|
-
try log.ohko();
|
|
1698
|
+
try log.ohko(.{});
|
|
1330
1699
|
try expectLog1(&.{N(ArgType.OHKO)}, buf[0..1]);
|
|
1331
|
-
|
|
1700
|
+
writer.reset();
|
|
1332
1701
|
}
|
|
1702
|
+
|
|
1333
1703
|
test "|-crit|" {
|
|
1334
|
-
try log.crit(p2.ident(5));
|
|
1704
|
+
try log.crit(.{p2.ident(5)});
|
|
1335
1705
|
try expectLog1(&.{ N(ArgType.Crit), 0b1101 }, buf[0..2]);
|
|
1336
|
-
|
|
1706
|
+
writer.reset();
|
|
1337
1707
|
}
|
|
1708
|
+
|
|
1338
1709
|
test "|-supereffective|" {
|
|
1339
|
-
try log.supereffective(p1.ident(1));
|
|
1710
|
+
try log.supereffective(.{p1.ident(1)});
|
|
1340
1711
|
try expectLog1(&.{ N(ArgType.SuperEffective), 0b0001 }, buf[0..2]);
|
|
1341
|
-
|
|
1712
|
+
writer.reset();
|
|
1342
1713
|
}
|
|
1714
|
+
|
|
1343
1715
|
test "|-resisted|" {
|
|
1344
|
-
try log.resisted(p2.ident(2));
|
|
1716
|
+
try log.resisted(.{p2.ident(2)});
|
|
1345
1717
|
try expectLog1(&.{ N(ArgType.Resisted), 0b1010 }, buf[0..2]);
|
|
1346
|
-
|
|
1718
|
+
writer.reset();
|
|
1347
1719
|
}
|
|
1720
|
+
|
|
1348
1721
|
test "|-immune|" {
|
|
1349
|
-
try log.immune(p1.ident(3), .None);
|
|
1722
|
+
try log.immune(.{ p1.ident(3), .None });
|
|
1350
1723
|
try expectLog1(&.{ N(ArgType.Immune), 0b0011, N(Immune.None) }, buf[0..3]);
|
|
1351
|
-
|
|
1724
|
+
writer.reset();
|
|
1352
1725
|
|
|
1353
|
-
try log.immune(p2.ident(2), .OHKO);
|
|
1726
|
+
try log.immune(.{ p2.ident(2), .OHKO });
|
|
1354
1727
|
try expectLog1(&.{ N(ArgType.Immune), 0b1010, N(Immune.OHKO) }, buf[0..3]);
|
|
1355
|
-
|
|
1728
|
+
writer.reset();
|
|
1356
1729
|
}
|
|
1730
|
+
|
|
1357
1731
|
test "|-transform|" {
|
|
1358
|
-
try log.transform(p2.ident(4), p1.ident(5));
|
|
1732
|
+
try log.transform(.{ p2.ident(4), p1.ident(5) });
|
|
1359
1733
|
try expectLog1(&.{ N(ArgType.Transform), 0b1100, 0b0101 }, buf[0..3]);
|
|
1360
|
-
|
|
1734
|
+
writer.reset();
|
|
1735
|
+
}
|
|
1736
|
+
|
|
1737
|
+
test "|drag|" {
|
|
1738
|
+
var blissey = gen2.helpers.Pokemon.init(.{ .species = .Blissey, .moves = &.{.Splash} });
|
|
1739
|
+
blissey.level = 91;
|
|
1740
|
+
blissey.hp = 200;
|
|
1741
|
+
blissey.stats.hp = 400;
|
|
1742
|
+
blissey.status = gen2.Status.init(.PAR);
|
|
1743
|
+
try log.drag(.{ p2.ident(3), &blissey });
|
|
1744
|
+
const par = 0b1000000;
|
|
1745
|
+
const expected = &(.{
|
|
1746
|
+
N(ArgType.Drag),
|
|
1747
|
+
0b1011,
|
|
1748
|
+
N(S2.Blissey),
|
|
1749
|
+
N(gen2.Gender.Female),
|
|
1750
|
+
91,
|
|
1751
|
+
} ++ switch (endian) {
|
|
1752
|
+
.big => .{ 0, 200, 1, 144, par },
|
|
1753
|
+
.little => .{ 200, 0, 144, 1, par },
|
|
1754
|
+
});
|
|
1755
|
+
try expectLog2(expected, buf[0..10]);
|
|
1756
|
+
writer.reset();
|
|
1757
|
+
}
|
|
1758
|
+
|
|
1759
|
+
test "|-item|" {
|
|
1760
|
+
try log.item(.{ p2.ident(2), I2.GoldBerry, p1.ident(4) });
|
|
1761
|
+
try expectLog2(&.{ N(ArgType.Item), 0b1010, N(I2.GoldBerry), 0b0100 }, buf[0..4]);
|
|
1762
|
+
writer.reset();
|
|
1763
|
+
}
|
|
1764
|
+
|
|
1765
|
+
test "|-enditem|" {
|
|
1766
|
+
try log.enditem(.{ p1.ident(1), I2.BerserkGene, .None });
|
|
1767
|
+
try expectLog2(&.{ N(ArgType.EndItem), 0b0001, N(I2.BerserkGene), N(EndItem.None) }, buf[0..4]);
|
|
1768
|
+
writer.reset();
|
|
1769
|
+
|
|
1770
|
+
try log.enditem(.{ p2.ident(4), I2.PRZCureBerry, .Eat });
|
|
1771
|
+
try expectLog2(&.{ N(ArgType.EndItem), 0b1100, N(I2.PRZCureBerry), N(EndItem.Eat) }, buf[0..4]);
|
|
1772
|
+
writer.reset();
|
|
1773
|
+
}
|
|
1774
|
+
|
|
1775
|
+
test "|-cureteam|" {
|
|
1776
|
+
try log.cureteam(.{p2.ident(5)});
|
|
1777
|
+
try expectLog2(&.{ N(ArgType.CureTeam), 0b1101 }, buf[0..2]);
|
|
1778
|
+
writer.reset();
|
|
1779
|
+
}
|
|
1780
|
+
|
|
1781
|
+
test "|-sethp|" {
|
|
1782
|
+
var blissey = gen2.helpers.Pokemon.init(.{ .species = .Blissey, .moves = &.{.PainSplit} });
|
|
1783
|
+
blissey.hp = 612;
|
|
1784
|
+
try log.sethp(.{ p2.ident(2), &blissey, .Silent });
|
|
1785
|
+
const expected: []const u8 = switch (endian) {
|
|
1786
|
+
.big => &.{ N(ArgType.SetHP), 0b1010, 2, 100, 2, 201, 0, N(SetHP.Silent) },
|
|
1787
|
+
.little => &.{ N(ArgType.SetHP), 0b1010, 100, 2, 201, 2, 0, N(SetHP.Silent) },
|
|
1788
|
+
};
|
|
1789
|
+
try expectLog2(expected, buf[0..8]);
|
|
1790
|
+
writer.reset();
|
|
1791
|
+
}
|
|
1792
|
+
|
|
1793
|
+
test "|-setboost|" {
|
|
1794
|
+
try log.setboost(.{ p2.ident(6), 6 });
|
|
1795
|
+
try expectLog2(&.{ N(ArgType.SetBoost), 0b1110, 12 }, buf[0..3]);
|
|
1796
|
+
writer.reset();
|
|
1797
|
+
|
|
1798
|
+
try log.setboost(.{ p2.ident(3), 2 });
|
|
1799
|
+
try expectLog2(&.{ N(ArgType.SetBoost), 0b1011, 8 }, buf[0..3]);
|
|
1800
|
+
writer.reset();
|
|
1801
|
+
}
|
|
1802
|
+
|
|
1803
|
+
test "|-copyboost|" {
|
|
1804
|
+
try log.copyboost(.{ p2.ident(3), p1.ident(6) });
|
|
1805
|
+
try expectLog2(&.{ N(ArgType.CopyBoost), 0b1011, 0b0110 }, buf[0..3]);
|
|
1806
|
+
writer.reset();
|
|
1807
|
+
}
|
|
1808
|
+
|
|
1809
|
+
test "|-sidestart|" {
|
|
1810
|
+
try log.sidestart(.{ .P2, .Reflect });
|
|
1811
|
+
try expectLog2(&.{ N(ArgType.SideStart), 1, N(Side.Reflect) }, buf[0..3]);
|
|
1812
|
+
writer.reset();
|
|
1813
|
+
}
|
|
1814
|
+
|
|
1815
|
+
test "|-sideend|" {
|
|
1816
|
+
try log.sideend(.{ .P2, .LightScreen });
|
|
1817
|
+
try expectLog2(&.{ N(ArgType.SideEnd), 1, N(Side.LightScreen) }, buf[0..3]);
|
|
1818
|
+
writer.reset();
|
|
1819
|
+
|
|
1820
|
+
try log.sideend(.{ .P1, .Spikes, p1.ident(3) });
|
|
1821
|
+
try expectLog2(&.{
|
|
1822
|
+
N(ArgType.SideEnd),
|
|
1823
|
+
0,
|
|
1824
|
+
N(Side.Spikes),
|
|
1825
|
+
0b0011,
|
|
1826
|
+
}, buf[0..4]);
|
|
1827
|
+
writer.reset();
|
|
1828
|
+
}
|
|
1829
|
+
|
|
1830
|
+
test "|-singlemove|" {
|
|
1831
|
+
try log.singlemove(.{ p2.ident(2), M2.DestinyBond });
|
|
1832
|
+
try expectLog2(&.{ N(ArgType.SingleMove), 0b1010, N(M2.DestinyBond) }, buf[0..3]);
|
|
1833
|
+
writer.reset();
|
|
1834
|
+
}
|
|
1835
|
+
|
|
1836
|
+
test "|-singleturn|" {
|
|
1837
|
+
try log.singleturn(.{ p1.ident(3), M2.Protect });
|
|
1838
|
+
try expectLog2(&.{ N(ArgType.SingleTurn), 0b0011, N(M2.Protect) }, buf[0..3]);
|
|
1839
|
+
writer.reset();
|
|
1840
|
+
}
|
|
1841
|
+
|
|
1842
|
+
test "|-weather|" {
|
|
1843
|
+
try log.weather(.{ W2.Rain, .Upkeep });
|
|
1844
|
+
try expectLog2(&.{ N(ArgType.Weather), N(W2.Rain), N(Weather.Upkeep) }, buf[0..3]);
|
|
1845
|
+
writer.reset();
|
|
1846
|
+
|
|
1847
|
+
try log.weather(.{ W2.None, .None });
|
|
1848
|
+
try expectLog2(&.{ N(ArgType.Weather), N(W2.None), N(Weather.None) }, buf[0..3]);
|
|
1849
|
+
writer.reset();
|
|
1361
1850
|
}
|