@pkmn/engine 0.1.0-dev.90d6c14c → 0.1.0-dev.9257876b
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 +52 -21
- package/build/pkg/addon.js.map +1 -1
- package/build/pkg/data/ids.json +12 -12
- package/build/pkg/data/layout.json +2 -2
- 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 +2 -2
- 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 +125 -102
- package/package.json +43 -23
- package/src/bin/install-pkmn-engine +27 -19
- package/src/lib/common/data.zig +12 -24
- package/src/lib/common/optional.zig +9 -2
- package/src/lib/common/protocol.zig +805 -327
- package/src/lib/common/rational.zig +12 -8
- package/src/lib/common/rng.zig +26 -17
- package/src/lib/gen1/calc.zig +9 -10
- package/src/lib/gen1/chance.zig +83 -66
- 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 +7 -7
- package/src/lib/gen1/data.zig +60 -67
- package/src/lib/gen1/helpers.zig +261 -123
- package/src/lib/gen1/mechanics.zig +370 -403
- package/src/lib/gen2/calc.zig +143 -0
- package/src/lib/gen2/chance.zig +1315 -0
- package/src/lib/gen2/data/items.zig +12 -18
- package/src/lib/gen2/data/moves.zig +663 -569
- package/src/lib/gen2/data/species.zig +1 -1
- package/src/lib/gen2/data/types.zig +134 -31
- package/src/lib/gen2/data.zig +106 -79
- package/src/lib/gen2/generated.zig +806 -0
- package/src/lib/gen2/helpers.zig +8 -12
- package/src/lib/gen2/mechanics.zig +3587 -9
- package/src/lib/{binding/node.zig → node.zig} +10 -13
- package/src/lib/pkmn.zig +26 -3
- package/src/lib/{binding/wasm.zig → wasm.zig} +2 -1
- package/src/lib/gen1/README.md +0 -812
- package/src/lib/gen2/README.md +0 -308
package/src/lib/gen1/helpers.zig
CHANGED
|
@@ -266,7 +266,7 @@ pub const Rolls = struct {
|
|
|
266
266
|
const PLAYERS = [_]Optional(Player){ .P1, .P2 };
|
|
267
267
|
|
|
268
268
|
/// Returns a slice with the correct range of values for speed ties given the `action` state.
|
|
269
|
-
pub
|
|
269
|
+
pub fn speedTie(action: Action) []const Optional(Player) {
|
|
270
270
|
return if (@field(action, "speed_tie") == .None) &PLAYER_NONE else &PLAYERS;
|
|
271
271
|
}
|
|
272
272
|
|
|
@@ -275,14 +275,14 @@ pub const Rolls = struct {
|
|
|
275
275
|
|
|
276
276
|
/// Returns a slice with the correct range of values for hits given the `action` state
|
|
277
277
|
/// and the state of the `parent` (whether the player's Pokémon was fully paralyzed).
|
|
278
|
-
pub
|
|
278
|
+
pub fn hit(action: Action, parent: Optional(bool)) []const Optional(bool) {
|
|
279
279
|
if (parent == .true) return &BOOL_NONE;
|
|
280
280
|
return if (@field(action, "hit") == .None) &BOOL_NONE else &BOOLS;
|
|
281
281
|
}
|
|
282
282
|
|
|
283
283
|
/// Returns a slice with the correct range of values for critical hits given the `action` state
|
|
284
284
|
/// and the state of the `parent` (whether the player's Pokémon's move hit).
|
|
285
|
-
pub
|
|
285
|
+
pub fn criticalHit(
|
|
286
286
|
action: Action,
|
|
287
287
|
parent: Optional(bool),
|
|
288
288
|
) []const Optional(bool) {
|
|
@@ -292,7 +292,7 @@ pub const Rolls = struct {
|
|
|
292
292
|
|
|
293
293
|
/// Returns a slice with the correct range of values for secondary chances hits given the
|
|
294
294
|
/// `action` state and the state of the `parent` (whether the player's Pokémon's move hit).
|
|
295
|
-
pub
|
|
295
|
+
pub fn secondaryChance(
|
|
296
296
|
action: Action,
|
|
297
297
|
parent: Optional(bool),
|
|
298
298
|
) []const Optional(bool) {
|
|
@@ -305,7 +305,7 @@ pub const Rolls = struct {
|
|
|
305
305
|
|
|
306
306
|
/// Returns the range bounding damage rolls given the `action` state and the state of
|
|
307
307
|
/// the `parent` (whether the player's Pokémon's move hit).
|
|
308
|
-
pub
|
|
308
|
+
pub fn damage(action: Action, parent: Optional(bool)) Range {
|
|
309
309
|
return if (parent == .false or @field(action, "damage") == 0)
|
|
310
310
|
.{ .min = 0, .max = 1 }
|
|
311
311
|
else
|
|
@@ -314,7 +314,7 @@ pub const Rolls = struct {
|
|
|
314
314
|
|
|
315
315
|
/// Returns the max damage roll which will produce the same damage as `roll`
|
|
316
316
|
/// given the base damage in `summaries`.
|
|
317
|
-
pub
|
|
317
|
+
pub fn coalesce(player: Player, roll: u8, summaries: *calc.Summaries, cap: bool) !u8 {
|
|
318
318
|
if (roll == 0) return roll;
|
|
319
319
|
|
|
320
320
|
const dmg = summaries.get(player.foe()).damage;
|
|
@@ -326,13 +326,13 @@ pub const Rolls = struct {
|
|
|
326
326
|
|
|
327
327
|
/// Returns a slice with the correct range of values for confused given the `action` state
|
|
328
328
|
/// and the state of the `parent` (the player's Pokémon's remaining confusion turns).
|
|
329
|
-
pub
|
|
329
|
+
pub fn confused(action: Action, parent: u4) []const Optional(bool) {
|
|
330
330
|
return if (parent == 0 or @field(action, "confused") == .None) &BOOL_NONE else &BOOLS;
|
|
331
331
|
}
|
|
332
332
|
|
|
333
333
|
/// Returns a slice with the correct range of values for paralysis given the `action` state
|
|
334
334
|
/// and the state of the `parent` (whether the player's Pokémon was confused).
|
|
335
|
-
pub
|
|
335
|
+
pub fn paralyzed(action: Action, parent: Optional(bool)) []const Optional(bool) {
|
|
336
336
|
if (parent == .true) return &BOOL_NONE;
|
|
337
337
|
return if (@field(action, "paralyzed") == .None) &BOOL_NONE else &BOOLS;
|
|
338
338
|
}
|
|
@@ -342,7 +342,7 @@ pub const Rolls = struct {
|
|
|
342
342
|
|
|
343
343
|
/// Returns a slice with a range of values for duration given the `action` state
|
|
344
344
|
/// and the state of the `parent` (whether the player's Pokémon's move hit).
|
|
345
|
-
pub
|
|
345
|
+
pub fn duration(action: Action, parent: Optional(bool)) []const u1 {
|
|
346
346
|
if (parent == .false) return &DURATION_NONE;
|
|
347
347
|
return if (@field(action, "duration") == 0) &DURATION_NONE else &DURATION;
|
|
348
348
|
}
|
|
@@ -350,47 +350,65 @@ pub const Rolls = struct {
|
|
|
350
350
|
const U3_NONE = [_]u3{0};
|
|
351
351
|
const U3_FORCED = [_]u3{1};
|
|
352
352
|
|
|
353
|
-
/// Returns a slice with a range of values for sleep given the `action`
|
|
353
|
+
/// Returns a slice with a range of values for sleep given the `action` and `origin` states.
|
|
354
354
|
pub inline fn sleep(action: Action, origin: Action) []const u3 {
|
|
355
|
-
const
|
|
356
|
-
|
|
357
|
-
|
|
355
|
+
const a = @field(action.durations, "sleep");
|
|
356
|
+
const o = @field(origin.durations, "sleep");
|
|
357
|
+
if (o == a) return if (o == 0) &U3_NONE else &[_]u3{o};
|
|
358
|
+
assert(a == 0 or a == o + 1);
|
|
359
|
+
return if (o >= 7) &U3_NONE else &[_]u3{ 0, o + 1 };
|
|
358
360
|
}
|
|
359
361
|
|
|
360
362
|
const DISABLE_NONE = [_]u4{0};
|
|
361
363
|
|
|
362
|
-
/// Returns a slice with a range of values for disable given the `action`
|
|
364
|
+
/// Returns a slice with a range of values for disable given the `action` and `origin` states
|
|
363
365
|
/// and the state of the `parent` (the player's Pokémon's remaining sleep turns).
|
|
364
366
|
pub inline fn disable(action: Action, origin: Action, parent: u4) []const u4 {
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
367
|
+
if (parent > 0) return &DISABLE_NONE;
|
|
368
|
+
const a = @field(action.durations, "disable");
|
|
369
|
+
const o = @field(origin.durations, "disable");
|
|
370
|
+
if (o == a) return if (o == 0) &DISABLE_NONE else &[_]u4{o};
|
|
371
|
+
assert(a == 0 or a == o + 1);
|
|
372
|
+
return if (o >= 8) &DISABLE_NONE else &[_]u4{ 0, o + 1 };
|
|
368
373
|
}
|
|
369
374
|
|
|
370
|
-
/// Returns a slice with a range of values for confusion given the `action`
|
|
375
|
+
/// Returns a slice with a range of values for confusion given the `action` and `origin` states
|
|
371
376
|
/// and the state of the `parent` (the player's remaining sleep turns).
|
|
372
377
|
pub inline fn confusion(action: Action, origin: Action, parent: u4) []const u3 {
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
return if (
|
|
378
|
+
if (parent > 0) return &U3_NONE;
|
|
379
|
+
const a = @field(action.durations, "confusion");
|
|
380
|
+
const o = @field(origin.durations, "confusion");
|
|
381
|
+
if (o == a) return if (o == 0) &U3_NONE else &[_]u3{o};
|
|
382
|
+
assert(a == 0 or a == o + 1);
|
|
383
|
+
return if (o >= 5) &U3_NONE else if (o < 2)
|
|
384
|
+
if (a == 0) &U3_NONE else &U3_FORCED
|
|
385
|
+
else
|
|
386
|
+
&[_]u3{ 0, o + 1 };
|
|
377
387
|
}
|
|
378
388
|
|
|
379
|
-
/// Returns a slice with a range of values for attacking given the `action`
|
|
389
|
+
/// Returns a slice with a range of values for attacking given the `action` and `origin` states
|
|
380
390
|
/// and the state of the `parent` (whether the player's Pokémon was fully paralyzed).
|
|
381
391
|
pub inline fn attacking(action: Action, origin: Action, parent: Optional(bool)) []const u3 {
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
return if (
|
|
392
|
+
if (parent == .true) return &U3_NONE;
|
|
393
|
+
const a = @field(action.durations, "attacking");
|
|
394
|
+
const o = @field(origin.durations, "attacking");
|
|
395
|
+
if (o == a) return if (o == 0) &U3_NONE else &[_]u3{o};
|
|
396
|
+
assert(a == 0 or a == o + 1);
|
|
397
|
+
return if (o >= 3) &U3_NONE else if (o < 2)
|
|
398
|
+
if (a == 0) &U3_NONE else &U3_FORCED
|
|
399
|
+
else
|
|
400
|
+
&[_]u3{ 0, o + 1 };
|
|
386
401
|
}
|
|
387
402
|
|
|
388
|
-
/// Returns a slice with a range of values for binding given the `action`
|
|
403
|
+
/// Returns a slice with a range of values for binding given the `action` and `origin` states
|
|
389
404
|
/// and the state of the `parent` (whether the player's Pokémon was fully paralyzed).
|
|
390
405
|
pub inline fn binding(action: Action, origin: Action, parent: Optional(bool)) []const u3 {
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
406
|
+
if (parent == .true) return &U3_NONE;
|
|
407
|
+
const a = @field(action.durations, "binding");
|
|
408
|
+
const o = @field(origin.durations, "binding");
|
|
409
|
+
if (o == a) return if (o == 0) &U3_NONE else &[_]u3{o};
|
|
410
|
+
assert(a == 0 or a == o + 1);
|
|
411
|
+
return if (o >= 4) &U3_NONE else &[_]u3{ 0, o + 1 };
|
|
394
412
|
}
|
|
395
413
|
|
|
396
414
|
const SLOT_NONE = [_]u4{0};
|
|
@@ -400,7 +418,7 @@ pub const Rolls = struct {
|
|
|
400
418
|
/// and the state of the `parent` (whether the player's Pokémon's move hit).
|
|
401
419
|
///
|
|
402
420
|
/// These slots may or **may not be valid** as slots may be unset / have 0 PP.
|
|
403
|
-
pub
|
|
421
|
+
pub fn moveSlot(action: Action, parent: Optional(bool)) []const u4 {
|
|
404
422
|
if (parent == .false) return &SLOT_NONE;
|
|
405
423
|
return if (@field(action, "move_slot") == 0) &SLOT_NONE else &SLOT;
|
|
406
424
|
}
|
|
@@ -410,7 +428,7 @@ pub const Rolls = struct {
|
|
|
410
428
|
|
|
411
429
|
/// Returns a slice with the correct range of values for multi hit given the `action` state
|
|
412
430
|
/// and the state of the `parent` (whether the player's Pokémon's move hit).
|
|
413
|
-
pub
|
|
431
|
+
pub fn multiHit(action: Action, parent: Optional(bool)) []const u4 {
|
|
414
432
|
if (parent == .false) return &MULTI_NONE;
|
|
415
433
|
return if (@field(action, "multi_hit") == 0) &MULTI_NONE else &MULTI;
|
|
416
434
|
}
|
|
@@ -424,7 +442,7 @@ pub const Rolls = struct {
|
|
|
424
442
|
|
|
425
443
|
/// Returns a slice with the correct range of values for psywave given the `action` state,
|
|
426
444
|
/// the `side`, and the state of the `parent` (whether the player's Pokémon's move hit).
|
|
427
|
-
pub
|
|
445
|
+
pub fn psywave(
|
|
428
446
|
action: Action,
|
|
429
447
|
side: *data.Side,
|
|
430
448
|
parent: Optional(bool),
|
|
@@ -437,36 +455,21 @@ pub const Rolls = struct {
|
|
|
437
455
|
}
|
|
438
456
|
|
|
439
457
|
const MOVE_NONE = [_]Move{.None};
|
|
440
|
-
const MOVES = init: {
|
|
441
|
-
var moves: [Move.size - 2]Move = undefined;
|
|
442
|
-
var i: usize = 0;
|
|
443
|
-
for (@typeInfo(Move).Enum.fields) |f| {
|
|
444
|
-
if (!(std.mem.eql(u8, f.name, "None") or
|
|
445
|
-
std.mem.eql(u8, f.name, "Metronome") or
|
|
446
|
-
std.mem.eql(u8, f.name, "Struggle") or
|
|
447
|
-
std.mem.eql(u8, f.name, "SKIP_TURN")))
|
|
448
|
-
{
|
|
449
|
-
moves[i] = @field(Move, f.name);
|
|
450
|
-
i += 1;
|
|
451
|
-
}
|
|
452
|
-
}
|
|
453
|
-
break :init moves;
|
|
454
|
-
};
|
|
455
458
|
|
|
456
459
|
/// Returns a slice with the correct range of values for metronome given the `action` state.
|
|
457
|
-
pub
|
|
458
|
-
return if (@field(action, "metronome") == .None) &MOVE_NONE else &
|
|
460
|
+
pub fn metronome(action: Action) []const Move {
|
|
461
|
+
return if (@field(action, "metronome") == .None) &MOVE_NONE else &Move.METRONOME;
|
|
459
462
|
}
|
|
460
463
|
};
|
|
461
464
|
|
|
462
465
|
test "Rolls.speedTie" {
|
|
463
|
-
const actions =
|
|
466
|
+
const actions: Actions = .{ .p1 = .{ .speed_tie = .P2 } };
|
|
464
467
|
try expectEqualSlices(Optional(Player), &.{ .P1, .P2 }, Rolls.speedTie(actions.p1));
|
|
465
468
|
try expectEqualSlices(Optional(Player), &.{.None}, Rolls.speedTie(actions.p2));
|
|
466
469
|
}
|
|
467
470
|
|
|
468
471
|
test "Rolls.damage" {
|
|
469
|
-
const actions =
|
|
472
|
+
const actions: Actions = .{ .p2 = .{ .damage = 221 } };
|
|
470
473
|
try expectEqual(Rolls.Range{ .min = 0, .max = 1 }, Rolls.damage(actions.p1, .None));
|
|
471
474
|
try expectEqual(Rolls.Range{ .min = 217, .max = 256 }, Rolls.damage(actions.p2, .None));
|
|
472
475
|
try expectEqual(Rolls.Range{ .min = 0, .max = 1 }, Rolls.damage(actions.p2, .false));
|
|
@@ -475,16 +478,16 @@ test "Rolls.damage" {
|
|
|
475
478
|
test "Rolls.coalesce" {
|
|
476
479
|
var summaries =
|
|
477
480
|
calc.Summaries{ .p1 = .{ .damage = .{ .base = 74, .final = 69, .capped = true } } };
|
|
478
|
-
try expectEqual(
|
|
479
|
-
try expectEqual(
|
|
480
|
-
try expectEqual(
|
|
481
|
+
try expectEqual(0, try Rolls.coalesce(.P2, 0, &summaries, false));
|
|
482
|
+
try expectEqual(241, try Rolls.coalesce(.P2, 238, &summaries, false));
|
|
483
|
+
try expectEqual(255, try Rolls.coalesce(.P2, 238, &summaries, true));
|
|
481
484
|
summaries.p1.damage.final = 74;
|
|
482
|
-
try expectEqual(
|
|
483
|
-
try expectEqual(
|
|
485
|
+
try expectEqual(217, try Rolls.coalesce(.P2, 217, &summaries, false));
|
|
486
|
+
try expectEqual(255, try Rolls.coalesce(.P2, 217, &summaries, true));
|
|
484
487
|
}
|
|
485
488
|
|
|
486
489
|
test "Rolls.hit" {
|
|
487
|
-
const actions =
|
|
490
|
+
const actions: Actions = .{ .p2 = .{ .hit = .true } };
|
|
488
491
|
try expectEqualSlices(Optional(bool), &.{.None}, Rolls.hit(actions.p1, .None));
|
|
489
492
|
try expectEqualSlices(Optional(bool), &.{ .false, .true }, Rolls.hit(actions.p2, .None));
|
|
490
493
|
try expectEqualSlices(Optional(bool), &.{.None}, Rolls.hit(actions.p2, .true));
|
|
@@ -492,7 +495,7 @@ test "Rolls.hit" {
|
|
|
492
495
|
}
|
|
493
496
|
|
|
494
497
|
test "Rolls.secondaryChance" {
|
|
495
|
-
const actions =
|
|
498
|
+
const actions: Actions = .{ .p1 = .{ .secondary_chance = .true } };
|
|
496
499
|
try expectEqualSlices(
|
|
497
500
|
Optional(bool),
|
|
498
501
|
&.{ .false, .true },
|
|
@@ -503,7 +506,7 @@ test "Rolls.secondaryChance" {
|
|
|
503
506
|
}
|
|
504
507
|
|
|
505
508
|
test "Rolls.criticalHit" {
|
|
506
|
-
const actions =
|
|
509
|
+
const actions: Actions = .{ .p1 = .{ .critical_hit = .true } };
|
|
507
510
|
try expectEqualSlices(
|
|
508
511
|
Optional(bool),
|
|
509
512
|
&.{ .false, .true },
|
|
@@ -514,14 +517,14 @@ test "Rolls.criticalHit" {
|
|
|
514
517
|
}
|
|
515
518
|
|
|
516
519
|
test "Rolls.confused" {
|
|
517
|
-
const actions =
|
|
520
|
+
const actions: Actions = .{ .p2 = .{ .confused = .true } };
|
|
518
521
|
try expectEqualSlices(Optional(bool), &.{.None}, Rolls.confused(actions.p1, 1));
|
|
519
522
|
try expectEqualSlices(Optional(bool), &.{ .false, .true }, Rolls.confused(actions.p2, 1));
|
|
520
523
|
try expectEqualSlices(Optional(bool), &.{.None}, Rolls.confused(actions.p2, 0));
|
|
521
524
|
}
|
|
522
525
|
|
|
523
526
|
test "Rolls.paralyzed" {
|
|
524
|
-
const actions =
|
|
527
|
+
const actions: Actions = .{ .p2 = .{ .paralyzed = .true } };
|
|
525
528
|
try expectEqualSlices(Optional(bool), &.{.None}, Rolls.paralyzed(actions.p1, .None));
|
|
526
529
|
try expectEqualSlices(Optional(bool), &.{ .false, .true }, Rolls.paralyzed(actions.p2, .None));
|
|
527
530
|
try expectEqualSlices(Optional(bool), &.{ .false, .true }, Rolls.paralyzed(actions.p2, .false));
|
|
@@ -529,102 +532,237 @@ test "Rolls.paralyzed" {
|
|
|
529
532
|
}
|
|
530
533
|
|
|
531
534
|
test "Rolls.duration" {
|
|
532
|
-
const actions =
|
|
535
|
+
const actions: Actions = .{ .p2 = .{ .duration = 3 } };
|
|
533
536
|
try expectEqualSlices(u1, &.{0}, Rolls.duration(actions.p1, .None));
|
|
534
537
|
try expectEqualSlices(u1, &.{1}, Rolls.duration(actions.p2, .None));
|
|
535
538
|
try expectEqualSlices(u1, &.{0}, Rolls.duration(actions.p2, .false));
|
|
536
539
|
}
|
|
537
540
|
|
|
538
|
-
const FIXME: Action = .{};
|
|
539
|
-
|
|
540
541
|
test "Rolls.sleep" {
|
|
541
|
-
try expectEqualSlices(u3, &.{0}, Rolls.sleep(
|
|
542
|
-
|
|
543
|
-
|
|
542
|
+
try expectEqualSlices(u3, &.{0}, Rolls.sleep(
|
|
543
|
+
.{ .durations = .{ .sleep = 0 } },
|
|
544
|
+
.{ .durations = .{ .sleep = 0 } },
|
|
545
|
+
));
|
|
546
|
+
try expectEqualSlices(u3, &.{ 0, 1 }, Rolls.sleep(
|
|
547
|
+
.{ .durations = .{ .sleep = 1 } },
|
|
548
|
+
.{ .durations = .{ .sleep = 0 } },
|
|
549
|
+
));
|
|
550
|
+
try expectEqualSlices(u3, &.{ 0, 2 }, Rolls.sleep(
|
|
551
|
+
.{ .durations = .{ .sleep = 0 } },
|
|
552
|
+
.{ .durations = .{ .sleep = 1 } },
|
|
553
|
+
));
|
|
554
|
+
try expectEqualSlices(u3, &.{1}, Rolls.sleep(
|
|
555
|
+
.{ .durations = .{ .sleep = 1 } },
|
|
556
|
+
.{ .durations = .{ .sleep = 1 } },
|
|
557
|
+
));
|
|
558
|
+
try expectEqualSlices(u3, &.{ 0, 3 }, Rolls.sleep(
|
|
559
|
+
.{ .durations = .{ .sleep = 0 } },
|
|
560
|
+
.{ .durations = .{ .sleep = 2 } },
|
|
561
|
+
));
|
|
562
|
+
try expectEqualSlices(u3, &.{ 0, 7 }, Rolls.sleep(
|
|
563
|
+
.{ .durations = .{ .sleep = 7 } },
|
|
564
|
+
.{ .durations = .{ .sleep = 6 } },
|
|
565
|
+
));
|
|
566
|
+
try expectEqualSlices(u3, &.{0}, Rolls.sleep(
|
|
567
|
+
.{ .durations = .{ .sleep = 0 } },
|
|
568
|
+
.{ .durations = .{ .sleep = 7 } },
|
|
569
|
+
));
|
|
544
570
|
}
|
|
545
571
|
|
|
546
572
|
test "Rolls.disable" {
|
|
547
|
-
try expectEqualSlices(u4, &.{0}, Rolls.disable(
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
573
|
+
try expectEqualSlices(u4, &.{0}, Rolls.disable(
|
|
574
|
+
.{ .durations = .{ .disable = 0 } },
|
|
575
|
+
.{ .durations = .{ .disable = 0 } },
|
|
576
|
+
0,
|
|
577
|
+
));
|
|
578
|
+
try expectEqualSlices(u4, &.{ 0, 1 }, Rolls.disable(
|
|
579
|
+
.{ .durations = .{ .disable = 1 } },
|
|
580
|
+
.{ .durations = .{ .disable = 0 } },
|
|
581
|
+
0,
|
|
582
|
+
));
|
|
583
|
+
try expectEqualSlices(u4, &.{ 0, 2 }, Rolls.disable(
|
|
584
|
+
.{ .durations = .{ .disable = 0 } },
|
|
585
|
+
.{ .durations = .{ .disable = 1 } },
|
|
586
|
+
0,
|
|
587
|
+
));
|
|
588
|
+
try expectEqualSlices(u4, &.{1}, Rolls.disable(
|
|
589
|
+
.{ .durations = .{ .disable = 1 } },
|
|
590
|
+
.{ .durations = .{ .disable = 1 } },
|
|
591
|
+
0,
|
|
592
|
+
));
|
|
593
|
+
try expectEqualSlices(u4, &.{ 0, 3 }, Rolls.disable(
|
|
594
|
+
.{ .durations = .{ .disable = 0 } },
|
|
595
|
+
.{ .durations = .{ .disable = 2 } },
|
|
596
|
+
0,
|
|
597
|
+
));
|
|
598
|
+
try expectEqualSlices(u4, &.{0}, Rolls.disable(
|
|
599
|
+
.{ .durations = .{ .disable = 0 } },
|
|
600
|
+
.{ .durations = .{ .disable = 2 } },
|
|
601
|
+
1,
|
|
602
|
+
));
|
|
603
|
+
try expectEqualSlices(u4, &.{ 0, 8 }, Rolls.disable(
|
|
604
|
+
.{ .durations = .{ .disable = 8 } },
|
|
605
|
+
.{ .durations = .{ .disable = 7 } },
|
|
606
|
+
0,
|
|
607
|
+
));
|
|
608
|
+
try expectEqualSlices(u4, &.{0}, Rolls.disable(
|
|
609
|
+
.{ .durations = .{ .disable = 0 } },
|
|
610
|
+
.{ .durations = .{ .disable = 8 } },
|
|
611
|
+
0,
|
|
612
|
+
));
|
|
553
613
|
}
|
|
554
614
|
|
|
555
615
|
test "Rolls.confusion" {
|
|
556
|
-
try expectEqualSlices(u3, &.{0}, Rolls.confusion(
|
|
557
|
-
.durations = .{ .confusion = 0 },
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
.durations = .{ .confusion =
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
616
|
+
try expectEqualSlices(u3, &.{0}, Rolls.confusion(
|
|
617
|
+
.{ .durations = .{ .confusion = 0 } },
|
|
618
|
+
.{ .durations = .{ .confusion = 0 } },
|
|
619
|
+
0,
|
|
620
|
+
));
|
|
621
|
+
try expectEqualSlices(u3, &.{1}, Rolls.confusion(
|
|
622
|
+
.{ .durations = .{ .confusion = 1 } },
|
|
623
|
+
.{ .durations = .{ .confusion = 0 } },
|
|
624
|
+
0,
|
|
625
|
+
));
|
|
626
|
+
try expectEqualSlices(u3, &.{0}, Rolls.confusion(
|
|
627
|
+
.{ .durations = .{ .confusion = 0 } },
|
|
628
|
+
.{ .durations = .{ .confusion = 1 } },
|
|
629
|
+
0,
|
|
630
|
+
));
|
|
631
|
+
try expectEqualSlices(u3, &.{1}, Rolls.confusion(
|
|
632
|
+
.{ .durations = .{ .confusion = 1 } },
|
|
633
|
+
.{ .durations = .{ .confusion = 1 } },
|
|
634
|
+
0,
|
|
635
|
+
));
|
|
636
|
+
try expectEqualSlices(u3, &.{ 0, 3 }, Rolls.confusion(
|
|
637
|
+
.{ .durations = .{ .confusion = 0 } },
|
|
638
|
+
.{ .durations = .{ .confusion = 2 } },
|
|
639
|
+
0,
|
|
640
|
+
));
|
|
641
|
+
try expectEqualSlices(u3, &.{0}, Rolls.confusion(
|
|
642
|
+
.{ .durations = .{ .confusion = 0 } },
|
|
643
|
+
.{ .durations = .{ .confusion = 2 } },
|
|
644
|
+
1,
|
|
645
|
+
));
|
|
646
|
+
try expectEqualSlices(u3, &.{ 0, 5 }, Rolls.confusion(
|
|
647
|
+
.{ .durations = .{ .confusion = 5 } },
|
|
648
|
+
.{ .durations = .{ .confusion = 4 } },
|
|
649
|
+
0,
|
|
650
|
+
));
|
|
651
|
+
try expectEqualSlices(u3, &.{0}, Rolls.confusion(
|
|
652
|
+
.{ .durations = .{ .confusion = 0 } },
|
|
653
|
+
.{ .durations = .{ .confusion = 5 } },
|
|
654
|
+
0,
|
|
655
|
+
));
|
|
571
656
|
}
|
|
572
657
|
|
|
573
658
|
test "Rolls.attacking" {
|
|
574
|
-
try expectEqualSlices(u3, &.{0}, Rolls.attacking(
|
|
575
|
-
.durations = .{ .attacking = 0 },
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
.durations = .{ .attacking =
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
.
|
|
588
|
-
|
|
659
|
+
try expectEqualSlices(u3, &.{0}, Rolls.attacking(
|
|
660
|
+
.{ .durations = .{ .attacking = 0 } },
|
|
661
|
+
.{ .durations = .{ .attacking = 0 } },
|
|
662
|
+
.false,
|
|
663
|
+
));
|
|
664
|
+
try expectEqualSlices(u3, &.{1}, Rolls.attacking(
|
|
665
|
+
.{ .durations = .{ .attacking = 1 } },
|
|
666
|
+
.{ .durations = .{ .attacking = 0 } },
|
|
667
|
+
.false,
|
|
668
|
+
));
|
|
669
|
+
try expectEqualSlices(u3, &.{0}, Rolls.attacking(
|
|
670
|
+
.{ .durations = .{ .attacking = 0 } },
|
|
671
|
+
.{ .durations = .{ .attacking = 1 } },
|
|
672
|
+
.false,
|
|
673
|
+
));
|
|
674
|
+
try expectEqualSlices(u3, &.{1}, Rolls.attacking(
|
|
675
|
+
.{ .durations = .{ .attacking = 1 } },
|
|
676
|
+
.{ .durations = .{ .attacking = 1 } },
|
|
677
|
+
.false,
|
|
678
|
+
));
|
|
679
|
+
try expectEqualSlices(u3, &.{ 0, 3 }, Rolls.attacking(
|
|
680
|
+
.{ .durations = .{ .attacking = 0 } },
|
|
681
|
+
.{ .durations = .{ .attacking = 2 } },
|
|
682
|
+
.false,
|
|
683
|
+
));
|
|
684
|
+
try expectEqualSlices(u3, &.{0}, Rolls.attacking(
|
|
685
|
+
.{ .durations = .{ .attacking = 0 } },
|
|
686
|
+
.{ .durations = .{ .attacking = 2 } },
|
|
687
|
+
.true,
|
|
688
|
+
));
|
|
689
|
+
try expectEqualSlices(u3, &.{ 0, 3 }, Rolls.attacking(
|
|
690
|
+
.{ .durations = .{ .attacking = 3 } },
|
|
691
|
+
.{ .durations = .{ .attacking = 2 } },
|
|
692
|
+
.false,
|
|
693
|
+
));
|
|
694
|
+
try expectEqualSlices(u3, &.{0}, Rolls.attacking(
|
|
695
|
+
.{ .durations = .{ .attacking = 0 } },
|
|
696
|
+
.{ .durations = .{ .attacking = 3 } },
|
|
697
|
+
.false,
|
|
698
|
+
));
|
|
589
699
|
}
|
|
590
700
|
|
|
591
701
|
test "Rolls.binding" {
|
|
592
|
-
try expectEqualSlices(u3, &.{0}, Rolls.binding(
|
|
593
|
-
.durations = .{ .binding = 0 },
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
.durations = .{ .binding =
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
702
|
+
try expectEqualSlices(u3, &.{0}, Rolls.binding(
|
|
703
|
+
.{ .durations = .{ .binding = 0 } },
|
|
704
|
+
.{ .durations = .{ .binding = 0 } },
|
|
705
|
+
.false,
|
|
706
|
+
));
|
|
707
|
+
try expectEqualSlices(u3, &.{ 0, 1 }, Rolls.binding(
|
|
708
|
+
.{ .durations = .{ .binding = 1 } },
|
|
709
|
+
.{ .durations = .{ .binding = 0 } },
|
|
710
|
+
.false,
|
|
711
|
+
));
|
|
712
|
+
try expectEqualSlices(u3, &.{ 0, 2 }, Rolls.binding(
|
|
713
|
+
.{ .durations = .{ .binding = 0 } },
|
|
714
|
+
.{ .durations = .{ .binding = 1 } },
|
|
715
|
+
.false,
|
|
716
|
+
));
|
|
717
|
+
try expectEqualSlices(u3, &.{1}, Rolls.binding(
|
|
718
|
+
.{ .durations = .{ .binding = 1 } },
|
|
719
|
+
.{ .durations = .{ .binding = 1 } },
|
|
720
|
+
.false,
|
|
721
|
+
));
|
|
722
|
+
try expectEqualSlices(u3, &.{ 0, 3 }, Rolls.binding(
|
|
723
|
+
.{ .durations = .{ .binding = 0 } },
|
|
724
|
+
.{ .durations = .{ .binding = 2 } },
|
|
725
|
+
.false,
|
|
726
|
+
));
|
|
727
|
+
try expectEqualSlices(u3, &.{0}, Rolls.binding(
|
|
728
|
+
.{ .durations = .{ .binding = 0 } },
|
|
729
|
+
.{ .durations = .{ .binding = 2 } },
|
|
730
|
+
.true,
|
|
731
|
+
));
|
|
732
|
+
try expectEqualSlices(u3, &.{ 0, 4 }, Rolls.binding(
|
|
733
|
+
.{ .durations = .{ .binding = 4 } },
|
|
734
|
+
.{ .durations = .{ .binding = 3 } },
|
|
735
|
+
.false,
|
|
736
|
+
));
|
|
737
|
+
try expectEqualSlices(u3, &.{0}, Rolls.binding(
|
|
738
|
+
.{ .durations = .{ .binding = 0 } },
|
|
739
|
+
.{ .durations = .{ .binding = 4 } },
|
|
740
|
+
.false,
|
|
741
|
+
));
|
|
604
742
|
}
|
|
605
743
|
|
|
606
744
|
test "Rolls.moveSlot" {
|
|
607
|
-
const actions =
|
|
745
|
+
const actions: Actions = .{ .p2 = .{ .move_slot = 3 } };
|
|
608
746
|
try expectEqualSlices(u4, &.{0}, Rolls.moveSlot(actions.p1, .None));
|
|
609
747
|
try expectEqualSlices(u4, &.{ 1, 2, 3, 4 }, Rolls.moveSlot(actions.p2, .None));
|
|
610
748
|
try expectEqualSlices(u4, &.{0}, Rolls.moveSlot(actions.p2, .false));
|
|
611
749
|
}
|
|
612
750
|
|
|
613
751
|
test "Rolls.multiHit" {
|
|
614
|
-
const actions =
|
|
752
|
+
const actions: Actions = .{ .p2 = .{ .multi_hit = 3 } };
|
|
615
753
|
try expectEqualSlices(u4, &.{0}, Rolls.multiHit(actions.p1, .None));
|
|
616
754
|
try expectEqualSlices(u4, &.{ 2, 3, 4, 5 }, Rolls.multiHit(actions.p2, .None));
|
|
617
755
|
try expectEqualSlices(u4, &.{0}, Rolls.multiHit(actions.p2, .false));
|
|
618
756
|
}
|
|
619
757
|
|
|
620
758
|
test "Rolls.metronome" {
|
|
621
|
-
const actions =
|
|
759
|
+
const actions: Actions = .{ .p2 = .{ .metronome = .Surf } };
|
|
622
760
|
try expectEqualSlices(Move, &.{.None}, Rolls.metronome(actions.p1));
|
|
623
761
|
try expectEqual(@as(Move, @enumFromInt(24)), Rolls.metronome(actions.p2)[23]);
|
|
624
762
|
}
|
|
625
763
|
|
|
626
764
|
test "Rolls.psywave" {
|
|
627
|
-
const actions =
|
|
765
|
+
const actions: Actions = .{ .p2 = .{ .psywave = 79 } };
|
|
628
766
|
var side = Side.init(&[_]Pokemon{.{
|
|
629
767
|
.species = .Bulbasaur,
|
|
630
768
|
.level = 100,
|
|
@@ -633,9 +771,9 @@ test "Rolls.psywave" {
|
|
|
633
771
|
|
|
634
772
|
try expectEqualSlices(u8, &.{0}, Rolls.psywave(actions.p1, &side, .None));
|
|
635
773
|
var rolls = Rolls.psywave(actions.p2, &side, .None);
|
|
636
|
-
try expectEqual(
|
|
774
|
+
try expectEqual(150, rolls[rolls.len - 1]);
|
|
637
775
|
side.stored().level = 81;
|
|
638
776
|
rolls = Rolls.psywave(actions.p2, &side, .None);
|
|
639
|
-
try expectEqual(
|
|
777
|
+
try expectEqual(121, rolls[rolls.len - 1]);
|
|
640
778
|
try expectEqualSlices(u8, &.{0}, Rolls.psywave(actions.p2, &side, .false));
|
|
641
779
|
}
|