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