@pkmn/engine 0.1.0-dev.44b2e6ec → 0.1.0-dev.46850a3d
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 +5 -5
- package/build/pkg/addon.js +6 -7
- package/build/pkg/addon.js.map +1 -1
- package/build/pkg/data.d.ts +4 -5
- package/build/pkg/gen1.js.map +1 -1
- package/build/pkg/index.js.map +1 -1
- package/build/pkg/protocol.js +4 -4
- package/build/pkg/protocol.js.map +1 -1
- package/build/test/display.js +2 -2
- package/build/test/display.js.map +1 -1
- package/build/tools/debug.js +2 -3
- package/build/tools/debug.js.map +1 -1
- package/build.zig +57 -60
- package/package.json +29 -22
- package/src/bin/install-pkmn-engine +26 -18
- package/src/lib/common/data.zig +4 -4
- package/src/lib/common/optional.zig +1 -1
- package/src/lib/common/protocol.zig +15 -20
- package/src/lib/common/rng.zig +11 -11
- package/src/lib/gen1/chance.zig +27 -26
- package/src/lib/gen1/data/species.zig +1 -1
- package/src/lib/gen1/data.zig +18 -18
- package/src/lib/gen1/helpers.zig +7 -7
- package/src/lib/gen1/mechanics.zig +41 -5
- package/src/lib/gen2/chance.zig +38 -37
- package/src/lib/gen2/data.zig +8 -8
- package/src/lib/gen2/mechanics.zig +112 -27
- package/src/lib/{binding/node.zig → node.zig} +3 -2
- package/src/lib/pkmn.zig +26 -3
- package/src/lib/{binding/wasm.zig → wasm.zig} +2 -1
- package/src/lib/gen1/README.md +0 -894
- package/src/lib/gen2/README.md +0 -329
package/src/lib/gen1/chance.zig
CHANGED
|
@@ -14,7 +14,7 @@ const util = @import("../common/util.zig");
|
|
|
14
14
|
const Player = @import("../common/data.zig").Player;
|
|
15
15
|
const Optional = @import("../common/optional.zig").Optional;
|
|
16
16
|
|
|
17
|
-
const data = @import("
|
|
17
|
+
const data = @import("data.zig");
|
|
18
18
|
|
|
19
19
|
const enabled = options.chance;
|
|
20
20
|
const showdown = options.showdown;
|
|
@@ -92,13 +92,14 @@ pub const Actions = extern struct {
|
|
|
92
92
|
}
|
|
93
93
|
};
|
|
94
94
|
|
|
95
|
+
// TODO: ziglang/zig#19730
|
|
95
96
|
test Actions {
|
|
96
97
|
const a: Actions = .{ .p1 = .{ .hit = .true, .critical_hit = .false, .damage = 245 } };
|
|
97
98
|
const b: Actions = .{ .p1 = .{ .hit = .false, .critical_hit = .true, .damage = 246 } };
|
|
98
99
|
const c: Actions = .{ .p1 = .{ .hit = .true } };
|
|
99
|
-
const d: Actions = .{ .p2 = .{ .hit = .true, .durations = .{ .sleep = 2 } } };
|
|
100
|
-
const e: Actions = .{ .p2 = .{ .hit = .false, .durations = .{ .sleep = 4 } } };
|
|
101
|
-
const f: Actions = .{ .p1 = .{ .hit = .false, .durations = .{ .sleep = 4 } } };
|
|
100
|
+
// const d: Actions = .{ .p2 = .{ .hit = .true, .durations = .{ .sleep = 2 } } };
|
|
101
|
+
// const e: Actions = .{ .p2 = .{ .hit = .false, .durations = .{ .sleep = 4 } } };
|
|
102
|
+
// const f: Actions = .{ .p1 = .{ .hit = .false, .durations = .{ .sleep = 4 } } };
|
|
102
103
|
|
|
103
104
|
try expect(a.eql(a));
|
|
104
105
|
try expect(!a.eql(b));
|
|
@@ -111,8 +112,8 @@ test Actions {
|
|
|
111
112
|
try expect(b.matches(a));
|
|
112
113
|
try expect(!a.matches(c));
|
|
113
114
|
try expect(!c.matches(a));
|
|
114
|
-
try expect(d.matches(e));
|
|
115
|
-
try expect(!d.matches(f));
|
|
115
|
+
// try expect(d.matches(e));
|
|
116
|
+
// try expect(!d.matches(f));
|
|
116
117
|
}
|
|
117
118
|
|
|
118
119
|
/// Information about the RNG that was observed during a Generation I battle `update` for a
|
|
@@ -706,19 +707,19 @@ test "Chance.damage" {
|
|
|
706
707
|
|
|
707
708
|
try chance.damage(.P1, 217);
|
|
708
709
|
if (showdown) {
|
|
709
|
-
try expectValue(
|
|
710
|
+
try expectValue(217, chance.actions.p1.damage);
|
|
710
711
|
try expectProbability(&chance.probability, 1, 39);
|
|
711
712
|
} else {
|
|
712
713
|
try expectProbability(&chance.probability, 1, 1);
|
|
713
|
-
try expectValue(
|
|
714
|
+
try expectValue(0, chance.actions.p1.damage);
|
|
714
715
|
|
|
715
716
|
try chance.commit(.P1, .miss);
|
|
716
717
|
try expectProbability(&chance.probability, 1, 1);
|
|
717
|
-
try expectValue(
|
|
718
|
+
try expectValue(0, chance.actions.p1.damage);
|
|
718
719
|
|
|
719
720
|
try chance.commit(.P1, .hit);
|
|
720
721
|
try expectProbability(&chance.probability, 1, 39);
|
|
721
|
-
try expectValue(
|
|
722
|
+
try expectValue(217, chance.actions.p1.damage);
|
|
722
723
|
}
|
|
723
724
|
}
|
|
724
725
|
|
|
@@ -770,13 +771,13 @@ test "Chance.moveSlot" {
|
|
|
770
771
|
|
|
771
772
|
try chance.moveSlot(.P2, 2, &ms, 2);
|
|
772
773
|
try expectProbability(&chance.probability, 1, 2);
|
|
773
|
-
try expectValue(
|
|
774
|
+
try expectValue(2, chance.actions.p2.move_slot);
|
|
774
775
|
|
|
775
776
|
chance.reset();
|
|
776
777
|
|
|
777
778
|
try chance.moveSlot(.P1, 1, &ms, 0);
|
|
778
779
|
try expectProbability(&chance.probability, 1, 3);
|
|
779
|
-
try expectValue(
|
|
780
|
+
try expectValue(1, chance.actions.p1.move_slot);
|
|
780
781
|
}
|
|
781
782
|
|
|
782
783
|
test "Chance.multiHit" {
|
|
@@ -784,32 +785,32 @@ test "Chance.multiHit" {
|
|
|
784
785
|
|
|
785
786
|
try chance.multiHit(.P1, 3);
|
|
786
787
|
try expectProbability(&chance.probability, 3, 8);
|
|
787
|
-
try expectValue(
|
|
788
|
+
try expectValue(3, chance.actions.p1.multi_hit);
|
|
788
789
|
|
|
789
790
|
chance.reset();
|
|
790
791
|
|
|
791
792
|
try chance.multiHit(.P2, 5);
|
|
792
793
|
try expectProbability(&chance.probability, 1, 8);
|
|
793
|
-
try expectValue(
|
|
794
|
+
try expectValue(5, chance.actions.p2.multi_hit);
|
|
794
795
|
}
|
|
795
796
|
|
|
796
797
|
test "Chance.duration" {
|
|
797
798
|
var chance: Chance(rational.Rational(u64)) = .{ .probability = .{} };
|
|
798
799
|
|
|
799
800
|
chance.duration(.sleep, .P1, .P2, 2);
|
|
800
|
-
try expectValue(
|
|
801
|
-
try expectValue(
|
|
801
|
+
try expectValue(2, chance.actions.p1.duration);
|
|
802
|
+
try expectValue(1, chance.actions.p2.durations.sleep);
|
|
802
803
|
|
|
803
804
|
chance.reset();
|
|
804
805
|
|
|
805
806
|
chance.duration(.binding, .P2, .P2, 4);
|
|
806
807
|
if (!showdown) {
|
|
807
|
-
try expectValue(
|
|
808
|
-
try expectValue(
|
|
808
|
+
try expectValue(0, chance.actions.p2.duration);
|
|
809
|
+
try expectValue(0, chance.actions.p2.durations.binding);
|
|
809
810
|
try chance.commit(.P2, .hit);
|
|
810
811
|
}
|
|
811
|
-
try expectValue(
|
|
812
|
-
try expectValue(
|
|
812
|
+
try expectValue(4, chance.actions.p2.duration);
|
|
813
|
+
try expectValue(1, chance.actions.p2.durations.binding);
|
|
813
814
|
}
|
|
814
815
|
|
|
815
816
|
test "Chance.sleep" {
|
|
@@ -819,7 +820,7 @@ test "Chance.sleep" {
|
|
|
819
820
|
chance.actions.p1.durations.sleep = @intCast(i);
|
|
820
821
|
try chance.sleep(.P1, 0);
|
|
821
822
|
try expectProbability(&chance.probability, 1, d);
|
|
822
|
-
try expectValue(
|
|
823
|
+
try expectValue(0, chance.actions.p1.durations.sleep);
|
|
823
824
|
|
|
824
825
|
chance.reset();
|
|
825
826
|
|
|
@@ -842,7 +843,7 @@ test "Chance.confusion" {
|
|
|
842
843
|
chance.actions.p2.durations.confusion = @intCast(i);
|
|
843
844
|
try chance.confusion(.P2, 0);
|
|
844
845
|
try expectProbability(&chance.probability, 1, d);
|
|
845
|
-
try expectValue(
|
|
846
|
+
try expectValue(0, chance.actions.p2.durations.confusion);
|
|
846
847
|
|
|
847
848
|
chance.reset();
|
|
848
849
|
}
|
|
@@ -865,7 +866,7 @@ test "Chance.disable" {
|
|
|
865
866
|
chance.actions.p1.durations.disable = @intCast(i);
|
|
866
867
|
try chance.disable(.P1, 0);
|
|
867
868
|
try expectProbability(&chance.probability, 1, d);
|
|
868
|
-
try expectValue(
|
|
869
|
+
try expectValue(0, chance.actions.p1.durations.disable);
|
|
869
870
|
|
|
870
871
|
chance.reset();
|
|
871
872
|
|
|
@@ -888,7 +889,7 @@ test "Chance.attacking" {
|
|
|
888
889
|
chance.actions.p2.durations.attacking = @intCast(i);
|
|
889
890
|
try chance.attacking(.P2, 0);
|
|
890
891
|
try expectProbability(&chance.probability, 1, d);
|
|
891
|
-
try expectValue(
|
|
892
|
+
try expectValue(0, chance.actions.p2.durations.attacking);
|
|
892
893
|
|
|
893
894
|
chance.reset();
|
|
894
895
|
}
|
|
@@ -914,7 +915,7 @@ test "Chance.binding" {
|
|
|
914
915
|
chance.actions.p1.durations.binding = @intCast(i);
|
|
915
916
|
try chance.binding(.P1, 0);
|
|
916
917
|
try expectProbability(&chance.probability, p, q);
|
|
917
|
-
try expectValue(
|
|
918
|
+
try expectValue(0, chance.actions.p1.durations.binding);
|
|
918
919
|
|
|
919
920
|
chance.reset();
|
|
920
921
|
|
|
@@ -934,7 +935,7 @@ test "Chance.psywave" {
|
|
|
934
935
|
|
|
935
936
|
try chance.psywave(.P2, 100, 150);
|
|
936
937
|
try expectProbability(&chance.probability, 1, 150);
|
|
937
|
-
try expectValue(
|
|
938
|
+
try expectValue(101, chance.actions.p2.psywave);
|
|
938
939
|
}
|
|
939
940
|
|
|
940
941
|
test "Chance.metronome" {
|
|
@@ -1091,7 +1091,7 @@ pub const Species = enum(u8) {
|
|
|
1091
1091
|
/// The number of Pokémon species in this generation.
|
|
1092
1092
|
pub const size = 151;
|
|
1093
1093
|
|
|
1094
|
-
/// The Pokémon's critical hit
|
|
1094
|
+
/// The Pokémon's critical hit ratio out of 256.
|
|
1095
1095
|
pub fn chance(id: Species) u8 {
|
|
1096
1096
|
assert(id != .None);
|
|
1097
1097
|
return CHANCES[@intFromEnum(id) - 1];
|
package/src/lib/gen1/data.zig
CHANGED
|
@@ -112,7 +112,7 @@ pub fn Battle(comptime RNG: anytype) type {
|
|
|
112
112
|
/// make (i.e. on the cartridge a soft-lock occurs).
|
|
113
113
|
///
|
|
114
114
|
/// This function will always return choices > 0 if `pkmn.options.showdown` is true.
|
|
115
|
-
pub fn choices(self: *Self, player: Player, request: Choice.Type, out: []Choice) u8 {
|
|
115
|
+
pub fn choices(self: *const Self, player: Player, request: Choice.Type, out: []Choice) u8 {
|
|
116
116
|
return mechanics.choices(self, player, request, out);
|
|
117
117
|
}
|
|
118
118
|
};
|
|
@@ -316,12 +316,12 @@ test Status {
|
|
|
316
316
|
try expect(Status.is(Status.slp(5), .SLP));
|
|
317
317
|
try expect(!Status.is(Status.slp(5), .EXT));
|
|
318
318
|
try expect(!Status.is(Status.slp(7), .PSN));
|
|
319
|
-
try expectEqual(
|
|
319
|
+
try expectEqual(5, Status.duration(Status.slp(5)));
|
|
320
320
|
try expect(Status.is(Status.slf(2), .SLP));
|
|
321
321
|
try expect(Status.is(Status.slf(2), .EXT));
|
|
322
322
|
try expect(Status.is(Status.TOX, .PSN));
|
|
323
323
|
try expect(Status.is(Status.TOX, .EXT));
|
|
324
|
-
try expectEqual(
|
|
324
|
+
try expectEqual(1, Status.duration(Status.slp(1)));
|
|
325
325
|
}
|
|
326
326
|
|
|
327
327
|
/// Bitfield representation of volatile statuses and associated data in Generation I.
|
|
@@ -405,13 +405,13 @@ test Volatiles {
|
|
|
405
405
|
try expect(!volatiles.Transform);
|
|
406
406
|
try expect(!volatiles.MultiHit);
|
|
407
407
|
|
|
408
|
-
try expectEqual(
|
|
409
|
-
try expectEqual(
|
|
410
|
-
try expectEqual(
|
|
411
|
-
try expectEqual(
|
|
412
|
-
try expectEqual(
|
|
413
|
-
try expectEqual(
|
|
414
|
-
try expectEqual(
|
|
408
|
+
try expectEqual(235, volatiles.state);
|
|
409
|
+
try expectEqual(42, volatiles.substitute);
|
|
410
|
+
try expectEqual(2, volatiles.disable_move);
|
|
411
|
+
try expectEqual(4, volatiles.disable_duration);
|
|
412
|
+
try expectEqual(2, volatiles.confusion);
|
|
413
|
+
try expectEqual(4, volatiles.toxic);
|
|
414
|
+
try expectEqual(3, volatiles.attacks);
|
|
415
415
|
}
|
|
416
416
|
|
|
417
417
|
/// Representaiton of a Pokémon's stats in Generation I.
|
|
@@ -442,9 +442,9 @@ test Stats {
|
|
|
442
442
|
try expectEqual(0, stats.def);
|
|
443
443
|
|
|
444
444
|
var base = Species.get(.Gyarados).stats;
|
|
445
|
-
try expectEqual(
|
|
445
|
+
try expectEqual(127, Stats(u16).calc("hp", base.hp, 0, 5120, 38));
|
|
446
446
|
base = Species.get(.Pidgeot).stats;
|
|
447
|
-
try expectEqual(
|
|
447
|
+
try expectEqual(279, Stats(u16).calc("spe", base.spe, 15, 63001, 100));
|
|
448
448
|
}
|
|
449
449
|
|
|
450
450
|
/// Representation of a Pokémon's boosts in Generation I.
|
|
@@ -537,7 +537,7 @@ pub const Species = species.Species;
|
|
|
537
537
|
|
|
538
538
|
test Species {
|
|
539
539
|
try expectEqual(2, @intFromEnum(Species.Ivysaur));
|
|
540
|
-
try expectEqual(
|
|
540
|
+
try expectEqual(100, Species.get(.Mew).stats.def);
|
|
541
541
|
}
|
|
542
542
|
|
|
543
543
|
/// Representation of a Generation I type in Pokémon.
|
|
@@ -576,8 +576,8 @@ test Types {
|
|
|
576
576
|
try expectEqual(Effectiveness.Resisted, Type.effectiveness(.Fire, .Water));
|
|
577
577
|
try expectEqual(Effectiveness.Neutral, Type.effectiveness(.Normal, .Grass));
|
|
578
578
|
|
|
579
|
-
try expectEqual(
|
|
580
|
-
try expectEqual(
|
|
579
|
+
try expectEqual(3, Type.precedence(.Water, .Water));
|
|
580
|
+
try expectEqual(26, Type.precedence(.Bug, .Ghost));
|
|
581
581
|
try expect(Type.precedence(.Poison, .Bug) > Type.precedence(.Poison, .Poison));
|
|
582
582
|
|
|
583
583
|
const t: Types = .{ .type1 = .Rock, .type2 = .Ground };
|
|
@@ -617,18 +617,18 @@ pub const DVs = struct {
|
|
|
617
617
|
|
|
618
618
|
test DVs {
|
|
619
619
|
var dvs: DVs = .{ .spc = 15, .spe = 15 };
|
|
620
|
-
try expectEqual(
|
|
620
|
+
try expectEqual(15, dvs.hp());
|
|
621
621
|
dvs = .{
|
|
622
622
|
.atk = 5,
|
|
623
623
|
.def = 15,
|
|
624
624
|
.spe = 13,
|
|
625
625
|
.spc = 13,
|
|
626
626
|
};
|
|
627
|
-
try expectEqual(
|
|
627
|
+
try expectEqual(15, dvs.hp());
|
|
628
628
|
dvs = .{
|
|
629
629
|
.def = 3,
|
|
630
630
|
.spe = 10,
|
|
631
631
|
.spc = 11,
|
|
632
632
|
};
|
|
633
|
-
try expectEqual(
|
|
633
|
+
try expectEqual(13, dvs.hp());
|
|
634
634
|
}
|
package/src/lib/gen1/helpers.zig
CHANGED
|
@@ -478,12 +478,12 @@ test "Rolls.damage" {
|
|
|
478
478
|
test "Rolls.coalesce" {
|
|
479
479
|
var summaries =
|
|
480
480
|
calc.Summaries{ .p1 = .{ .damage = .{ .base = 74, .final = 69, .capped = true } } };
|
|
481
|
-
try expectEqual(
|
|
482
|
-
try expectEqual(
|
|
483
|
-
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));
|
|
484
484
|
summaries.p1.damage.final = 74;
|
|
485
|
-
try expectEqual(
|
|
486
|
-
try expectEqual(
|
|
485
|
+
try expectEqual(217, try Rolls.coalesce(.P2, 217, &summaries, false));
|
|
486
|
+
try expectEqual(255, try Rolls.coalesce(.P2, 217, &summaries, true));
|
|
487
487
|
}
|
|
488
488
|
|
|
489
489
|
test "Rolls.hit" {
|
|
@@ -771,9 +771,9 @@ test "Rolls.psywave" {
|
|
|
771
771
|
|
|
772
772
|
try expectEqualSlices(u8, &.{0}, Rolls.psywave(actions.p1, &side, .None));
|
|
773
773
|
var rolls = Rolls.psywave(actions.p2, &side, .None);
|
|
774
|
-
try expectEqual(
|
|
774
|
+
try expectEqual(150, rolls[rolls.len - 1]);
|
|
775
775
|
side.stored().level = 81;
|
|
776
776
|
rolls = Rolls.psywave(actions.p2, &side, .None);
|
|
777
|
-
try expectEqual(
|
|
777
|
+
try expectEqual(121, rolls[rolls.len - 1]);
|
|
778
778
|
try expectEqualSlices(u8, &.{0}, Rolls.psywave(actions.p2, &side, .false));
|
|
779
779
|
}
|
|
@@ -1053,7 +1053,7 @@ fn checkCriticalHit(battle: anytype, player: Player, move: Move.Data, options: a
|
|
|
1053
1053
|
const side = battle.side(player);
|
|
1054
1054
|
|
|
1055
1055
|
// Base speed is used for the critical hit calculation, even when Transform-ed
|
|
1056
|
-
var rate =
|
|
1056
|
+
var rate: u16 = Species.chance(side.stored().species);
|
|
1057
1057
|
// GLITCH: Focus Energy reduces critical hit rate instead of increasing it
|
|
1058
1058
|
rate = if (side.active.volatiles.FocusEnergy) rate / 2 else @min(rate * 2, 255);
|
|
1059
1059
|
rate = if (move.effect == .HighCritical) @min(rate * 4, 255) else rate / 2;
|
|
@@ -1110,9 +1110,9 @@ fn calcDamage(
|
|
|
1110
1110
|
def = @max((def / 4) & 255, if (showdown) 1 else 0);
|
|
1111
1111
|
}
|
|
1112
1112
|
|
|
1113
|
-
const lvl =
|
|
1113
|
+
const lvl: u32 = side.stored().level * @as(u2, if (crit) 2 else 1);
|
|
1114
1114
|
|
|
1115
|
-
def =
|
|
1115
|
+
def = if (move.effect == .Explode) @max(def / 2, 1) else def;
|
|
1116
1116
|
|
|
1117
1117
|
if (def == 0) return false;
|
|
1118
1118
|
|
|
@@ -1395,7 +1395,7 @@ fn moveHit(
|
|
|
1395
1395
|
const overwritten = overwrite and state > 0;
|
|
1396
1396
|
assert(!overwritten or (0 < state and state <= 255 and !side.active.volatiles.Bide));
|
|
1397
1397
|
|
|
1398
|
-
var accuracy = if (overwritten) state else
|
|
1398
|
+
var accuracy: u16 = if (overwritten) state else move.accuracy;
|
|
1399
1399
|
var boost = BOOSTS[@as(u4, @intCast(@as(i8, side.active.boosts.accuracy) + 6))];
|
|
1400
1400
|
accuracy = accuracy * boost[0] / boost[1];
|
|
1401
1401
|
boost = BOOSTS[@as(u4, @intCast(@as(i8, -foe.active.boosts.evasion) + 6))];
|
|
@@ -2689,6 +2689,8 @@ pub const Rolls = struct {
|
|
|
2689
2689
|
fn speedTie(battle: anytype, options: anytype) !bool {
|
|
2690
2690
|
const p1 = if (options.calc.overridden(.P1, .speed_tie)) |player|
|
|
2691
2691
|
player == .P1
|
|
2692
|
+
else if (@hasDecl(@TypeOf(battle.rng), "speedTie"))
|
|
2693
|
+
battle.rng.speedTie()
|
|
2692
2694
|
else if (showdown)
|
|
2693
2695
|
battle.rng.range(u8, 0, 2) == 0
|
|
2694
2696
|
else
|
|
@@ -2701,6 +2703,8 @@ pub const Rolls = struct {
|
|
|
2701
2703
|
fn criticalHit(battle: anytype, player: Player, rate: u8, options: anytype) !bool {
|
|
2702
2704
|
const crit = if (options.calc.overridden(player, .critical_hit)) |val|
|
|
2703
2705
|
val == .true
|
|
2706
|
+
else if (@hasDecl(@TypeOf(battle.rng), "criticalHit"))
|
|
2707
|
+
battle.rng.criticalHit(player, rate)
|
|
2704
2708
|
else if (showdown)
|
|
2705
2709
|
battle.rng.chance(u8, rate, 256)
|
|
2706
2710
|
else
|
|
@@ -2713,6 +2717,8 @@ pub const Rolls = struct {
|
|
|
2713
2717
|
fn damage(battle: anytype, player: Player, options: anytype) !u8 {
|
|
2714
2718
|
const roll = if (options.calc.overridden(player, .damage)) |val|
|
|
2715
2719
|
val
|
|
2720
|
+
else if (@hasDecl(@TypeOf(battle.rng), "damage"))
|
|
2721
|
+
battle.rng.damage(player)
|
|
2716
2722
|
else roll: {
|
|
2717
2723
|
if (showdown) break :roll battle.rng.range(u8, 217, 256);
|
|
2718
2724
|
while (true) {
|
|
@@ -2729,6 +2735,8 @@ pub const Rolls = struct {
|
|
|
2729
2735
|
fn hit(battle: anytype, player: Player, accuracy: u8, options: anytype) bool {
|
|
2730
2736
|
const ok = if (options.calc.overridden(player, .hit)) |val|
|
|
2731
2737
|
val == .true
|
|
2738
|
+
else if (@hasDecl(@TypeOf(battle.rng), "hit"))
|
|
2739
|
+
battle.rng.hit(player, accuracy)
|
|
2732
2740
|
else if (showdown)
|
|
2733
2741
|
battle.rng.chance(u8, accuracy, 256)
|
|
2734
2742
|
else
|
|
@@ -2741,6 +2749,8 @@ pub const Rolls = struct {
|
|
|
2741
2749
|
fn confused(battle: anytype, player: Player, options: anytype) !bool {
|
|
2742
2750
|
const cfz = if (options.calc.overridden(player, .confused)) |val|
|
|
2743
2751
|
val == .true
|
|
2752
|
+
else if (@hasDecl(@TypeOf(battle.rng), "confused"))
|
|
2753
|
+
battle.rng.confused(player)
|
|
2744
2754
|
else if (showdown)
|
|
2745
2755
|
!battle.rng.chance(u8, 128, 256)
|
|
2746
2756
|
else
|
|
@@ -2753,6 +2763,8 @@ pub const Rolls = struct {
|
|
|
2753
2763
|
fn paralyzed(battle: anytype, player: Player, options: anytype) !bool {
|
|
2754
2764
|
const par = if (options.calc.overridden(player, .paralyzed)) |val|
|
|
2755
2765
|
val == .true
|
|
2766
|
+
else if (@hasDecl(@TypeOf(battle.rng), "paralyzed"))
|
|
2767
|
+
battle.rng.paralyzed(player)
|
|
2756
2768
|
else if (showdown)
|
|
2757
2769
|
battle.rng.chance(u8, 63, 256)
|
|
2758
2770
|
else
|
|
@@ -2765,6 +2777,8 @@ pub const Rolls = struct {
|
|
|
2765
2777
|
fn confusionChance(battle: anytype, player: Player, options: anytype) !bool {
|
|
2766
2778
|
const proc = if (options.calc.overridden(player, .secondary_chance)) |val|
|
|
2767
2779
|
val == .true
|
|
2780
|
+
else if (@hasDecl(@TypeOf(battle.rng), "secondaryChance"))
|
|
2781
|
+
battle.rng.secondaryChance(player, 25)
|
|
2768
2782
|
else if (showdown)
|
|
2769
2783
|
battle.rng.chance(u8, 25, 256)
|
|
2770
2784
|
else
|
|
@@ -2779,6 +2793,8 @@ pub const Rolls = struct {
|
|
|
2779
2793
|
|
|
2780
2794
|
const proc = if (options.calc.overridden(player, .secondary_chance)) |val|
|
|
2781
2795
|
val == .true
|
|
2796
|
+
else if (@hasDecl(@TypeOf(battle.rng), "secondaryChance"))
|
|
2797
|
+
battle.rng.secondaryChance(player, rate)
|
|
2782
2798
|
else if (showdown)
|
|
2783
2799
|
battle.rng.chance(u8, rate, 256)
|
|
2784
2800
|
else
|
|
@@ -2793,6 +2809,8 @@ pub const Rolls = struct {
|
|
|
2793
2809
|
|
|
2794
2810
|
const proc = if (options.calc.overridden(player, .secondary_chance)) |val|
|
|
2795
2811
|
val == .true
|
|
2812
|
+
else if (@hasDecl(@TypeOf(battle.rng), "secondaryChance"))
|
|
2813
|
+
battle.rng.secondaryChance(player, rate)
|
|
2796
2814
|
else if (showdown)
|
|
2797
2815
|
battle.rng.chance(u8, rate, 256)
|
|
2798
2816
|
else
|
|
@@ -2805,6 +2823,8 @@ pub const Rolls = struct {
|
|
|
2805
2823
|
fn unboost(battle: anytype, player: Player, options: anytype) !bool {
|
|
2806
2824
|
const proc = if (options.calc.overridden(player, .secondary_chance)) |val|
|
|
2807
2825
|
val == .true
|
|
2826
|
+
else if (@hasDecl(@TypeOf(battle.rng), "secondaryChance"))
|
|
2827
|
+
battle.rng.secondaryChance(player, 85)
|
|
2808
2828
|
else if (showdown)
|
|
2809
2829
|
battle.rng.chance(u8, 85, 256)
|
|
2810
2830
|
else
|
|
@@ -2817,6 +2837,8 @@ pub const Rolls = struct {
|
|
|
2817
2837
|
fn metronome(battle: anytype, player: Player, options: anytype) !Move {
|
|
2818
2838
|
const move: Move = if (options.calc.overridden(player, .metronome)) |val|
|
|
2819
2839
|
val
|
|
2840
|
+
else if (@hasDecl(@TypeOf(battle.rng), "metronome"))
|
|
2841
|
+
battle.rng.metronome(player)
|
|
2820
2842
|
else if (showdown)
|
|
2821
2843
|
Move.METRONOME[battle.rng.range(u8, 0, Move.METRONOME.len)]
|
|
2822
2844
|
else move: {
|
|
@@ -2835,6 +2857,8 @@ pub const Rolls = struct {
|
|
|
2835
2857
|
fn psywave(battle: anytype, player: Player, max: u8, options: anytype) !u8 {
|
|
2836
2858
|
const power = if (options.calc.overridden(player, .psywave)) |val|
|
|
2837
2859
|
val - 1
|
|
2860
|
+
else if (@hasDecl(@TypeOf(battle.rng), "psywave"))
|
|
2861
|
+
battle.rng.psywave(player)
|
|
2838
2862
|
else if (showdown)
|
|
2839
2863
|
battle.rng.range(u8, 0, max)
|
|
2840
2864
|
else power: {
|
|
@@ -2852,6 +2876,8 @@ pub const Rolls = struct {
|
|
|
2852
2876
|
fn sleepDuration(battle: anytype, player: Player, options: anytype) u3 {
|
|
2853
2877
|
const duration: u3 = if (options.calc.overridden(player, .duration)) |val|
|
|
2854
2878
|
@intCast(val)
|
|
2879
|
+
else if (@hasDecl(@TypeOf(battle.rng), "sleepDuration"))
|
|
2880
|
+
battle.rng.sleepDuration(player)
|
|
2855
2881
|
else if (showdown)
|
|
2856
2882
|
battle.rng.range(u3, 1, 8)
|
|
2857
2883
|
else duration: {
|
|
@@ -2869,6 +2895,8 @@ pub const Rolls = struct {
|
|
|
2869
2895
|
fn disableDuration(battle: anytype, player: Player, options: anytype) u4 {
|
|
2870
2896
|
const duration: u4 = if (options.calc.overridden(player, .duration)) |val|
|
|
2871
2897
|
val
|
|
2898
|
+
else if (@hasDecl(@TypeOf(battle.rng), "disableDuration"))
|
|
2899
|
+
battle.rng.disableDuration(player)
|
|
2872
2900
|
else if (showdown)
|
|
2873
2901
|
battle.rng.range(u4, 1, 9)
|
|
2874
2902
|
else
|
|
@@ -2882,6 +2910,8 @@ pub const Rolls = struct {
|
|
|
2882
2910
|
fn confusionDuration(battle: anytype, player: Player, self: bool, options: anytype) u3 {
|
|
2883
2911
|
const duration: u3 = if (options.calc.overridden(player, .duration)) |val|
|
|
2884
2912
|
@intCast(val)
|
|
2913
|
+
else if (@hasDecl(@TypeOf(battle.rng), "confusionDuration"))
|
|
2914
|
+
battle.rng.confusionDuration(player, self)
|
|
2885
2915
|
else if (showdown)
|
|
2886
2916
|
battle.rng.range(u3, 2, 6)
|
|
2887
2917
|
else
|
|
@@ -2895,6 +2925,8 @@ pub const Rolls = struct {
|
|
|
2895
2925
|
fn attackingDuration(battle: anytype, player: Player, options: anytype) u3 {
|
|
2896
2926
|
const duration: u3 = if (options.calc.overridden(player, .duration)) |val|
|
|
2897
2927
|
@intCast(val)
|
|
2928
|
+
else if (@hasDecl(@TypeOf(battle.rng), "attackingDuration"))
|
|
2929
|
+
battle.rng.attackingDuration(player)
|
|
2898
2930
|
else if (showdown)
|
|
2899
2931
|
battle.rng.range(u3, 2, 4)
|
|
2900
2932
|
else
|
|
@@ -2916,6 +2948,8 @@ pub const Rolls = struct {
|
|
|
2916
2948
|
const roll = if (effect == .Binding) .duration else .multi_hit;
|
|
2917
2949
|
const n: u3 = if (options.calc.overridden(player, roll)) |val|
|
|
2918
2950
|
@intCast(val)
|
|
2951
|
+
else if (@hasDecl(@TypeOf(battle.rng), "distribution"))
|
|
2952
|
+
battle.rng.distribution(player)
|
|
2919
2953
|
else if (showdown)
|
|
2920
2954
|
DISTRIBUTION[battle.rng.range(u3, 0, DISTRIBUTION.len)]
|
|
2921
2955
|
else n: {
|
|
@@ -2948,7 +2982,9 @@ pub const Rolls = struct {
|
|
|
2948
2982
|
else
|
|
2949
2983
|
null;
|
|
2950
2984
|
|
|
2951
|
-
const slot: u4 = overridden orelse
|
|
2985
|
+
const slot: u4 = overridden orelse if (@hasDecl(@TypeOf(battle.rng), "moveSlot"))
|
|
2986
|
+
battle.rng.moveSlot(player, moves, check_pp)
|
|
2987
|
+
else slot: {
|
|
2952
2988
|
if (showdown) {
|
|
2953
2989
|
if (check_pp == 0) {
|
|
2954
2990
|
var i: usize = moves.len;
|