@pkmn/engine 0.1.0-dev.5570b5c5 → 0.1.0-dev.565de616
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +12 -8
- package/build/pkg/addon/browser.d.ts +3 -0
- package/build/pkg/addon/browser.js +44 -0
- package/build/pkg/addon/browser.js.map +1 -0
- package/build/pkg/addon/node.d.ts +3 -0
- package/build/pkg/addon/node.js +97 -0
- package/build/pkg/addon/node.js.map +1 -0
- package/build/pkg/addon/wasm.d.ts +2 -0
- package/build/pkg/addon/wasm.js +21 -0
- package/build/pkg/addon/wasm.js.map +1 -0
- package/build/pkg/addon.d.ts +22 -0
- package/build/pkg/addon.js +29 -51
- package/build/pkg/addon.js.map +1 -1
- package/build/pkg/data/layout.json +15 -2
- package/build/pkg/data/protocol.json +23 -9
- package/build/pkg/data.d.ts +23 -1
- package/build/pkg/data.js.map +1 -1
- package/build/pkg/gen1.d.ts +10 -13
- package/build/pkg/gen1.js +1 -1
- package/build/pkg/gen1.js.map +1 -1
- package/build/pkg/index.d.ts +53 -12
- package/build/pkg/index.js +15 -10
- package/build/pkg/index.js.map +1 -1
- package/build/pkg/protocol.d.ts +20 -1
- package/build/pkg/protocol.js +105 -103
- package/build/pkg/protocol.js.map +1 -1
- package/build/tools/debug.js +35 -68
- package/build/tools/debug.js.map +1 -1
- package/build/tools/display/debug.jsx +141 -0
- package/build/tools/display/debug.jsx.map +1 -0
- package/build/tools/display/index.js +141 -0
- package/build/tools/display/index.js.map +1 -0
- package/build/tools/display/ui.jsx +349 -0
- package/build/tools/display/ui.jsx.map +1 -0
- package/build/tools/display/util.js +18 -0
- package/build/tools/display/util.js.map +1 -0
- package/build.zig +230 -74
- package/package.json +51 -31
- package/src/bin/install-pkmn-engine +8 -6
- package/src/bin/pkmn-debug +1 -1
- package/src/lib/common/array.zig +77 -0
- package/src/lib/common/data.zig +8 -8
- package/src/lib/common/debug.zig +39 -8
- package/src/lib/common/js.zig +4 -2
- package/src/lib/common/optional.zig +13 -9
- package/src/lib/common/options.zig +6 -0
- package/src/lib/common/protocol.zig +45 -44
- package/src/lib/common/rational.zig +121 -29
- package/src/lib/common/rng.zig +5 -7
- package/src/lib/common/util.zig +50 -1
- package/src/lib/gen1/calc.zig +683 -156
- package/src/lib/gen1/chance.zig +415 -291
- package/src/lib/gen1/data/moves.zig +2 -4
- package/src/lib/gen1/data/species.zig +1 -3
- package/src/lib/gen1/data/types.zig +1 -2
- package/src/lib/gen1/data.zig +38 -41
- package/src/lib/gen1/helpers.zig +92 -548
- package/src/lib/gen1/mechanics.zig +325 -235
- package/src/lib/gen2/calc.zig +37 -27
- package/src/lib/gen2/chance.zig +90 -503
- package/src/lib/gen2/data/items.zig +1 -3
- package/src/lib/gen2/data/moves.zig +2 -4
- package/src/lib/gen2/data/species.zig +1 -3
- package/src/lib/gen2/data/types.zig +1 -2
- package/src/lib/gen2/data.zig +26 -29
- package/src/lib/gen2/generated.zig +18 -23
- package/src/lib/gen2/helpers.zig +46 -25
- package/src/lib/gen2/mechanics.zig +69 -107
- package/src/lib/node.zig +2 -4
- package/src/lib/pkmn.zig +14 -16
- package/src/lib/wasm.zig +1 -2
- package/src/tools/display/dom.ts +96 -0
- package/src/tools/display/ui.css +354 -0
- package/build/test/display.js +0 -400
- package/build/test/display.js.map +0 -1
- package/src/test/display/pkmn.html.tmpl +0 -368
|
@@ -1,50 +1,36 @@
|
|
|
1
|
-
const std = @import("std");
|
|
2
|
-
|
|
3
|
-
const pkmn = @import("../pkmn.zig");
|
|
4
|
-
|
|
5
|
-
const common = @import("../common/data.zig");
|
|
6
1
|
const DEBUG = @import("../common/debug.zig").print;
|
|
7
|
-
const protocol = @import("../common/protocol.zig");
|
|
8
|
-
const rng = @import("../common/rng.zig");
|
|
9
|
-
const util = @import("../common/util.zig");
|
|
10
2
|
|
|
3
|
+
const common = @import("../common/data.zig");
|
|
11
4
|
const data = @import("data.zig");
|
|
12
5
|
const generated = @import("generated.zig");
|
|
13
|
-
|
|
14
|
-
const
|
|
15
|
-
|
|
16
|
-
const
|
|
17
|
-
const expectEqualSlices = std.testing.expectEqualSlices;
|
|
18
|
-
const expectEqualStrings = std.testing.expectEqualStrings;
|
|
19
|
-
|
|
20
|
-
const showdown = pkmn.options.showdown;
|
|
21
|
-
|
|
22
|
-
const Choice = common.Choice;
|
|
23
|
-
const ID = common.ID;
|
|
24
|
-
const Player = common.Player;
|
|
25
|
-
const Result = common.Result;
|
|
6
|
+
const pkmn = @import("../pkmn.zig");
|
|
7
|
+
const protocol = @import("../common/protocol.zig");
|
|
8
|
+
const rng = @import("../common/rng.zig");
|
|
9
|
+
const std = @import("std");
|
|
26
10
|
|
|
27
11
|
const Activate = protocol.Activate;
|
|
12
|
+
const ActivePokemon = data.ActivePokemon;
|
|
13
|
+
const assert = std.debug.assert;
|
|
28
14
|
const Boost = protocol.Boost;
|
|
15
|
+
const Boosts = data.Boosts;
|
|
16
|
+
const Choice = common.Choice;
|
|
29
17
|
const Damage = protocol.Damage;
|
|
18
|
+
const Effectiveness = data.Effectiveness;
|
|
30
19
|
const End = protocol.End;
|
|
20
|
+
const expectEqual = std.testing.expectEqual;
|
|
21
|
+
const expectEqualSlices = std.testing.expectEqualSlices;
|
|
22
|
+
const expectEqualStrings = std.testing.expectEqualStrings;
|
|
31
23
|
const Fail = protocol.Fail;
|
|
32
|
-
const Heal = protocol.Heal;
|
|
33
|
-
const Start = protocol.Start;
|
|
34
|
-
|
|
35
24
|
const Gen12 = rng.Gen12;
|
|
36
|
-
|
|
37
|
-
const
|
|
38
|
-
|
|
39
|
-
const ActivePokemon = data.ActivePokemon;
|
|
40
|
-
const Boosts = data.Boosts;
|
|
41
|
-
const Effectiveness = data.Effectiveness;
|
|
25
|
+
const Heal = protocol.Heal;
|
|
26
|
+
const ID = common.ID;
|
|
42
27
|
const Item = data.Item;
|
|
43
28
|
const Move = data.Move;
|
|
44
|
-
const
|
|
45
|
-
const
|
|
29
|
+
const Player = common.Player;
|
|
30
|
+
const Result = common.Result;
|
|
31
|
+
const showdown = pkmn.options.showdown;
|
|
46
32
|
const Side = data.Side;
|
|
47
|
-
const
|
|
33
|
+
const Start = protocol.Start;
|
|
48
34
|
const Stats = data.Stats;
|
|
49
35
|
const Status = data.Status;
|
|
50
36
|
const TriAttack = data.TriAttack;
|
|
@@ -106,6 +92,7 @@ pub const State = struct {
|
|
|
106
92
|
type: Type, // BATTLE_VARS_MOVE_TYPE
|
|
107
93
|
accuracy: u8, // wEnemyMoveStruct + MOVE_ACC
|
|
108
94
|
move: Move, // wCurPlayerMove
|
|
95
|
+
hit: u3 = 0,
|
|
109
96
|
from: Move = .None,
|
|
110
97
|
mslot: u4, // wCurMoveNum
|
|
111
98
|
first: bool, // wEnemyGoesFirst
|
|
@@ -256,7 +243,6 @@ fn switchIn(battle: anytype, player: Player, slot: u8, kind: SwitchIn, options:
|
|
|
256
243
|
} else {
|
|
257
244
|
try options.log.switched(.{ battle.active(player), incoming });
|
|
258
245
|
}
|
|
259
|
-
options.chance.switched(player, side.pokemon[0].position, out);
|
|
260
246
|
|
|
261
247
|
if (side.conditions.Spikes and !active.types.includes(.Flying)) {
|
|
262
248
|
incoming.hp -|= @max(incoming.stats.hp / 8, 1);
|
|
@@ -442,18 +428,9 @@ fn beforeMove(battle: anytype, player: Player, move: Move, options: anytype) !bo
|
|
|
442
428
|
if (Status.is(stored.status, .SLP)) slp: {
|
|
443
429
|
const before = stored.status;
|
|
444
430
|
// Even if the EXT bit is set this will still correctly modify the sleep duration
|
|
445
|
-
// if (options.calc.modify(player, .sleep)) |extend| {
|
|
446
|
-
// if (!extend) stored.status = 0;
|
|
447
|
-
// } else {
|
|
448
431
|
stored.status -= 1;
|
|
449
|
-
// }
|
|
450
|
-
|
|
451
|
-
const duration = Status.duration(stored.status);
|
|
452
|
-
if (!Status.is(stored.status, .EXT)) {
|
|
453
|
-
try options.chance.sleep(player, duration);
|
|
454
|
-
}
|
|
455
432
|
|
|
456
|
-
if (duration == 0) {
|
|
433
|
+
if (Status.duration(stored.status) == 0) {
|
|
457
434
|
try log.curestatus(.{ ident, before, .Message });
|
|
458
435
|
stored.status = 0; // clears EXT if present
|
|
459
436
|
resetCant(volatiles);
|
|
@@ -483,12 +460,7 @@ fn beforeMove(battle: anytype, player: Player, move: Move, options: anytype) !bo
|
|
|
483
460
|
}
|
|
484
461
|
|
|
485
462
|
if (volatiles.disable.duration > 0) {
|
|
486
|
-
// if (options.calc.modify(player, .disable)) |extend| {
|
|
487
|
-
// if (!extend) volatiles.disable.duration = 0;
|
|
488
|
-
// } else {
|
|
489
463
|
volatiles.disable.duration -= 1;
|
|
490
|
-
// }
|
|
491
|
-
try options.chance.disable(player, volatiles.disable.duration);
|
|
492
464
|
|
|
493
465
|
if (volatiles.disable.duration == 0) {
|
|
494
466
|
volatiles.disable.move = 0;
|
|
@@ -498,13 +470,7 @@ fn beforeMove(battle: anytype, player: Player, move: Move, options: anytype) !bo
|
|
|
498
470
|
|
|
499
471
|
if (volatiles.Confusion) {
|
|
500
472
|
assert(volatiles.confusion > 0);
|
|
501
|
-
|
|
502
|
-
// if (options.calc.modify(player, .confusion)) |extend| {
|
|
503
|
-
// if (!extend) volatiles.confusion = 0;
|
|
504
|
-
// } else {
|
|
505
473
|
volatiles.confusion -= 1;
|
|
506
|
-
// }
|
|
507
|
-
try options.chance.confusion(player, volatiles.confusion);
|
|
508
474
|
|
|
509
475
|
if (volatiles.confusion == 0) {
|
|
510
476
|
volatiles.Confusion = false;
|
|
@@ -665,7 +631,7 @@ pub fn checkCriticalHit(battle: anytype, player: Player, state: *State, options:
|
|
|
665
631
|
}
|
|
666
632
|
assert(stage <= 4);
|
|
667
633
|
|
|
668
|
-
state.crit = try Rolls.criticalHit(battle, player, CRITICAL_HITS[stage], options);
|
|
634
|
+
state.crit = try Rolls.criticalHit(battle, player, state.hit, CRITICAL_HITS[stage], options);
|
|
669
635
|
}
|
|
670
636
|
|
|
671
637
|
pub fn calcDamage(
|
|
@@ -733,7 +699,7 @@ pub fn adjustDamage(battle: anytype, player: Player, state: *State, _: anytype)
|
|
|
733
699
|
|
|
734
700
|
pub fn randomizeDamage(battle: anytype, player: Player, state: *State, options: anytype) !void {
|
|
735
701
|
if (state.damage <= 1) return;
|
|
736
|
-
const random = try Rolls.damage(battle, player, options);
|
|
702
|
+
const random = try Rolls.damage(battle, player, state.hit, options);
|
|
737
703
|
options.calc.base(player.foe(), state.damage);
|
|
738
704
|
state.damage = @intCast(@as(u32, state.damage) *% random / 255);
|
|
739
705
|
options.calc.final(player.foe(), state.damage);
|
|
@@ -1226,7 +1192,7 @@ fn updateSideCondition(
|
|
|
1226
1192
|
fn endTurn(battle: anytype, options: anytype) @TypeOf(options.log).Error!Result {
|
|
1227
1193
|
battle.turn += 1;
|
|
1228
1194
|
|
|
1229
|
-
if (
|
|
1195
|
+
if (pkmn.options.mod and battle.turn >= 1000) {
|
|
1230
1196
|
try options.log.tie(.{});
|
|
1231
1197
|
return Result.Tie;
|
|
1232
1198
|
} else if (battle.turn >= 65535) {
|
|
@@ -1341,13 +1307,7 @@ pub const Effects = struct {
|
|
|
1341
1307
|
|
|
1342
1308
|
if (!volatiles.Bide) return;
|
|
1343
1309
|
|
|
1344
|
-
// if (options.calc.modify(player, .attacking)) |extend| {
|
|
1345
|
-
// if (!extend) volatiles.attacks = 0;
|
|
1346
|
-
// } else {
|
|
1347
1310
|
volatiles.attacks -= 1;
|
|
1348
|
-
// }
|
|
1349
|
-
try options.chance.attacking(player, volatiles.attacks);
|
|
1350
|
-
|
|
1351
1311
|
if (volatiles.attacks != 0) return options.log.activate(.{ ident, .Bide });
|
|
1352
1312
|
|
|
1353
1313
|
volatiles.Bide = false;
|
|
@@ -1738,7 +1698,7 @@ pub const Effects = struct {
|
|
|
1738
1698
|
if (!state.proc) return;
|
|
1739
1699
|
if (foe.conditions.Safeguard) return;
|
|
1740
1700
|
// Freeze Clause Mod
|
|
1741
|
-
if (
|
|
1701
|
+
if (pkmn.options.mod) for (foe.pokemon) |p| if (Status.is(p.status, .FRZ)) return;
|
|
1742
1702
|
|
|
1743
1703
|
foe_stored.status = Status.init(.FRZ);
|
|
1744
1704
|
try options.log.status(.{ foe_ident, foe_stored.status, .None });
|
|
@@ -2416,7 +2376,7 @@ pub const Effects = struct {
|
|
|
2416
2376
|
}
|
|
2417
2377
|
|
|
2418
2378
|
// Sleep Clause Mod
|
|
2419
|
-
if (
|
|
2379
|
+
if (pkmn.options.mod) {
|
|
2420
2380
|
for (foe.pokemon) |p| {
|
|
2421
2381
|
if (Status.is(p.status, .SLP) and !Status.is(p.status, .EXT)) return;
|
|
2422
2382
|
}
|
|
@@ -2876,7 +2836,7 @@ fn convertible(active: ActivePokemon, m: Move) bool {
|
|
|
2876
2836
|
|
|
2877
2837
|
pub const Rolls = struct {
|
|
2878
2838
|
fn speedTie(battle: anytype, options: anytype) !bool {
|
|
2879
|
-
const p1 = if (options.calc.overridden(.P1, .speed_tie)) |player|
|
|
2839
|
+
const p1 = if (options.calc.overridden(.P1, 0, .speed_tie)) |player|
|
|
2880
2840
|
player == .P1
|
|
2881
2841
|
else if (showdown)
|
|
2882
2842
|
battle.rng.range(u8, 0, 2) == 0
|
|
@@ -2888,7 +2848,7 @@ pub const Rolls = struct {
|
|
|
2888
2848
|
}
|
|
2889
2849
|
|
|
2890
2850
|
fn quickClaw(battle: anytype, player: Player, options: anytype) !bool {
|
|
2891
|
-
const qkc = if (options.calc.overridden(player, .quick_claw)) |val|
|
|
2851
|
+
const qkc = if (options.calc.overridden(player, 0, .quick_claw)) |val|
|
|
2892
2852
|
val == .true
|
|
2893
2853
|
else if (showdown)
|
|
2894
2854
|
battle.rng.chance(u8, 60, 256)
|
|
@@ -2900,7 +2860,7 @@ pub const Rolls = struct {
|
|
|
2900
2860
|
}
|
|
2901
2861
|
|
|
2902
2862
|
fn hit(battle: anytype, player: Player, accuracy: u8, options: anytype) !bool {
|
|
2903
|
-
const ok = if (options.calc.overridden(player, .hit)) |val|
|
|
2863
|
+
const ok = if (options.calc.overridden(player, 0, .hit)) |val|
|
|
2904
2864
|
val == .true
|
|
2905
2865
|
else if (showdown)
|
|
2906
2866
|
battle.rng.chance(u8, accuracy, 256)
|
|
@@ -2911,20 +2871,22 @@ pub const Rolls = struct {
|
|
|
2911
2871
|
return ok;
|
|
2912
2872
|
}
|
|
2913
2873
|
|
|
2914
|
-
fn criticalHit(battle: anytype, player: Player, rate: u8, options: anytype) !bool {
|
|
2915
|
-
|
|
2874
|
+
fn criticalHit(battle: anytype, player: Player, i: u3, rate: u8, options: anytype) !bool {
|
|
2875
|
+
_ = .{ player, options };
|
|
2876
|
+
const crit = if (options.calc.overridden(player, i, .critical_hits)) |val|
|
|
2916
2877
|
val == .true
|
|
2917
2878
|
else if (showdown)
|
|
2918
2879
|
battle.rng.chance(u8, rate, 256)
|
|
2919
2880
|
else
|
|
2920
2881
|
battle.rng.next() < rate;
|
|
2921
2882
|
|
|
2922
|
-
try options.chance.criticalHit(player, crit, rate);
|
|
2883
|
+
try options.chance.criticalHit(player, i, crit, rate);
|
|
2923
2884
|
return crit;
|
|
2924
2885
|
}
|
|
2925
2886
|
|
|
2926
|
-
fn damage(battle: anytype, player: Player, options: anytype) !u8 {
|
|
2927
|
-
|
|
2887
|
+
fn damage(battle: anytype, player: Player, i: u3, options: anytype) !u8 {
|
|
2888
|
+
_ = .{ player, options };
|
|
2889
|
+
const roll = if (options.calc.overridden(player, i, .damages)) |val|
|
|
2928
2890
|
val
|
|
2929
2891
|
else roll: {
|
|
2930
2892
|
if (showdown) break :roll battle.rng.range(u8, 217, 256);
|
|
@@ -2935,12 +2897,12 @@ pub const Rolls = struct {
|
|
|
2935
2897
|
};
|
|
2936
2898
|
|
|
2937
2899
|
assert(roll >= 217 and roll <= 255);
|
|
2938
|
-
try options.chance.damage(player, roll);
|
|
2900
|
+
try options.chance.damage(player, i, roll);
|
|
2939
2901
|
return roll;
|
|
2940
2902
|
}
|
|
2941
2903
|
|
|
2942
2904
|
fn confused(battle: anytype, player: Player, options: anytype) !bool {
|
|
2943
|
-
const cfz = if (options.calc.overridden(player, .confused)) |val|
|
|
2905
|
+
const cfz = if (options.calc.overridden(player, 0, .confused)) |val|
|
|
2944
2906
|
val == .true
|
|
2945
2907
|
else if (showdown)
|
|
2946
2908
|
!battle.rng.chance(u8, 128, 256)
|
|
@@ -2952,7 +2914,7 @@ pub const Rolls = struct {
|
|
|
2952
2914
|
}
|
|
2953
2915
|
|
|
2954
2916
|
fn attract(battle: anytype, player: Player, options: anytype) !bool {
|
|
2955
|
-
const cant = if (options.calc.overridden(player, .attract)) |val|
|
|
2917
|
+
const cant = if (options.calc.overridden(player, 0, .attract)) |val|
|
|
2956
2918
|
val == .true
|
|
2957
2919
|
else if (showdown)
|
|
2958
2920
|
battle.rng.chance(u8, 1, 2)
|
|
@@ -2964,7 +2926,7 @@ pub const Rolls = struct {
|
|
|
2964
2926
|
}
|
|
2965
2927
|
|
|
2966
2928
|
fn paralyzed(battle: anytype, player: Player, options: anytype) !bool {
|
|
2967
|
-
const par = if (options.calc.overridden(player, .paralyzed)) |val|
|
|
2929
|
+
const par = if (options.calc.overridden(player, 0, .paralyzed)) |val|
|
|
2968
2930
|
val == .true
|
|
2969
2931
|
else if (showdown)
|
|
2970
2932
|
battle.rng.chance(u8, 63, 256)
|
|
@@ -2976,7 +2938,7 @@ pub const Rolls = struct {
|
|
|
2976
2938
|
}
|
|
2977
2939
|
|
|
2978
2940
|
fn defrost(battle: anytype, player: Player, options: anytype) !bool {
|
|
2979
|
-
const thaw = if (options.calc.overridden(player, .defrost)) |val|
|
|
2941
|
+
const thaw = if (options.calc.overridden(player, 0, .defrost)) |val|
|
|
2980
2942
|
val == .true
|
|
2981
2943
|
else if (showdown)
|
|
2982
2944
|
battle.rng.chance(u8, 25, 256)
|
|
@@ -2989,7 +2951,7 @@ pub const Rolls = struct {
|
|
|
2989
2951
|
|
|
2990
2952
|
fn secondaryChance(battle: anytype, player: Player, rate: u8, options: anytype) !bool {
|
|
2991
2953
|
// GLITCH: 100% secondary chance will still fail 1/256 of the time
|
|
2992
|
-
const proc = if (options.calc.overridden(player, .secondary_chance)) |val|
|
|
2954
|
+
const proc = if (options.calc.overridden(player, 0, .secondary_chance)) |val|
|
|
2993
2955
|
val == .true
|
|
2994
2956
|
else if (showdown)
|
|
2995
2957
|
battle.rng.chance(u8, rate, 256)
|
|
@@ -3001,7 +2963,7 @@ pub const Rolls = struct {
|
|
|
3001
2963
|
}
|
|
3002
2964
|
|
|
3003
2965
|
fn item(battle: anytype, player: Player, options: anytype) !bool {
|
|
3004
|
-
const proc = if (options.calc.overridden(player, .item)) |val|
|
|
2966
|
+
const proc = if (options.calc.overridden(player, 0, .item)) |val|
|
|
3005
2967
|
val == .true
|
|
3006
2968
|
else if (showdown)
|
|
3007
2969
|
battle.rng.chance(u8, 30, 256)
|
|
@@ -3013,7 +2975,7 @@ pub const Rolls = struct {
|
|
|
3013
2975
|
}
|
|
3014
2976
|
|
|
3015
2977
|
fn triAttack(battle: anytype, player: Player, options: anytype) !TriAttack {
|
|
3016
|
-
const status: TriAttack = if (options.calc.overridden(player, .tri_attack)) |val|
|
|
2978
|
+
const status: TriAttack = if (options.calc.overridden(player, 0, .tri_attack)) |val|
|
|
3017
2979
|
@enumFromInt(@intFromEnum(val) - 1)
|
|
3018
2980
|
else if (showdown)
|
|
3019
2981
|
@enumFromInt(battle.rng.range(u2, 0, 2))
|
|
@@ -3029,7 +2991,7 @@ pub const Rolls = struct {
|
|
|
3029
2991
|
}
|
|
3030
2992
|
|
|
3031
2993
|
fn present(battle: anytype, player: Player, options: anytype) !u8 {
|
|
3032
|
-
const power = if (options.calc.overridden(player, .present)) |val|
|
|
2994
|
+
const power = if (options.calc.overridden(player, 0, .present)) |val|
|
|
3033
2995
|
(val - 1) * 40
|
|
3034
2996
|
else if (showdown) power: {
|
|
3035
2997
|
const r = battle.rng.range(u8, 0, 10);
|
|
@@ -3051,7 +3013,7 @@ pub const Rolls = struct {
|
|
|
3051
3013
|
}
|
|
3052
3014
|
|
|
3053
3015
|
fn magnitude(battle: anytype, player: Player, options: anytype) !u8 {
|
|
3054
|
-
const num: u8 = if (options.calc.overridden(player, .magnitude)) |val|
|
|
3016
|
+
const num: u8 = if (options.calc.overridden(player, 0, .magnitude)) |val|
|
|
3055
3017
|
val + 3
|
|
3056
3018
|
else if (showdown) num: {
|
|
3057
3019
|
const r = battle.rng.range(u8, 0, 100);
|
|
@@ -3079,7 +3041,7 @@ pub const Rolls = struct {
|
|
|
3079
3041
|
}
|
|
3080
3042
|
|
|
3081
3043
|
fn tripleKick(battle: anytype, player: Player, options: anytype) !u2 {
|
|
3082
|
-
const hits = if (options.calc.overridden(player, .triple_kick)) |val|
|
|
3044
|
+
const hits = if (options.calc.overridden(player, 0, .triple_kick)) |val|
|
|
3083
3045
|
val
|
|
3084
3046
|
else if (showdown)
|
|
3085
3047
|
battle.rng.range(u2, 1, 4)
|
|
@@ -3097,7 +3059,7 @@ pub const Rolls = struct {
|
|
|
3097
3059
|
|
|
3098
3060
|
fn spite(battle: anytype, player: Player, options: anytype) !u3 {
|
|
3099
3061
|
assert(!showdown);
|
|
3100
|
-
const pp: u3 = if (options.calc.overridden(player, .spite)) |val|
|
|
3062
|
+
const pp: u3 = if (options.calc.overridden(player, 0, .spite)) |val|
|
|
3101
3063
|
val + 1
|
|
3102
3064
|
else
|
|
3103
3065
|
@intCast((battle.rng.next() & 3) + 2);
|
|
@@ -3114,7 +3076,7 @@ pub const Rolls = struct {
|
|
|
3114
3076
|
var i: u8 = 0;
|
|
3115
3077
|
const neutral = @intFromEnum(Effectiveness.Neutral);
|
|
3116
3078
|
assert(mtype != .@"???");
|
|
3117
|
-
const ty: Type = if (options.calc.overridden(player, .conversion_2)) |val|
|
|
3079
|
+
const ty: Type = if (options.calc.overridden(player, 0, .conversion_2)) |val|
|
|
3118
3080
|
@enumFromInt(@intFromEnum(val) - 1)
|
|
3119
3081
|
else if (showdown) ty: {
|
|
3120
3082
|
for (Type.SHOWDOWN) |t| {
|
|
@@ -3148,7 +3110,7 @@ pub const Rolls = struct {
|
|
|
3148
3110
|
assert(count <= 8);
|
|
3149
3111
|
const num = if (count == 8) 0 else @as(u8, 255) >> @intCast(count);
|
|
3150
3112
|
|
|
3151
|
-
const ok = if (options.calc.overridden(player, .protect)) |val|
|
|
3113
|
+
const ok = if (options.calc.overridden(player, 0, .protect)) |val|
|
|
3152
3114
|
val == .true
|
|
3153
3115
|
else if (showdown)
|
|
3154
3116
|
battle.rng.chance(u8, num, 255)
|
|
@@ -3170,7 +3132,7 @@ pub const Rolls = struct {
|
|
|
3170
3132
|
const moves = active.moves;
|
|
3171
3133
|
|
|
3172
3134
|
// TODO: consider throwing error instead of rerolling?
|
|
3173
|
-
const overridden = if (options.calc.overridden(player, .move_slot)) |val|
|
|
3135
|
+
const overridden = if (options.calc.overridden(player, 0, .move_slot)) |val|
|
|
3174
3136
|
if (convertible(active, moves[val - 1].id)) val else null
|
|
3175
3137
|
else
|
|
3176
3138
|
null;
|
|
@@ -3207,7 +3169,7 @@ pub const Rolls = struct {
|
|
|
3207
3169
|
const moves = active.moves;
|
|
3208
3170
|
|
|
3209
3171
|
// TODO: consider throwing error instead of rerolling?
|
|
3210
|
-
const overridden = if (options.calc.overridden(player, .move_slot)) |val|
|
|
3172
|
+
const overridden = if (options.calc.overridden(player, 0, .move_slot)) |val|
|
|
3211
3173
|
if (val != mslot and Move.get(moves[val - 1].id).extra.sleep_talk) val else null
|
|
3212
3174
|
else
|
|
3213
3175
|
null;
|
|
@@ -3251,7 +3213,7 @@ pub const Rolls = struct {
|
|
|
3251
3213
|
assert(n > 0 and n <= 6);
|
|
3252
3214
|
|
|
3253
3215
|
// TODO: consider throwing error instead of rerolling?
|
|
3254
|
-
const overridden = if (options.calc.overridden(player, .force_switch)) |val| val: {
|
|
3216
|
+
const overridden = if (options.calc.overridden(player, 0, .force_switch)) |val| val: {
|
|
3255
3217
|
for (slots) |slot| if (slot == val) break :val if (foe.get(slot).hp > 0) val else null;
|
|
3256
3218
|
break :val null;
|
|
3257
3219
|
} else null;
|
|
@@ -3277,7 +3239,7 @@ pub const Rolls = struct {
|
|
|
3277
3239
|
const DISTRIBUTION = [_]u3{ 2, 2, 2, 3, 3, 3, 4, 5 };
|
|
3278
3240
|
|
|
3279
3241
|
fn multiHit(battle: anytype, player: Player, options: anytype) !u3 {
|
|
3280
|
-
const n: u3 = if (options.calc.overridden(player, .multi_hit)) |val|
|
|
3242
|
+
const n: u3 = if (options.calc.overridden(player, 0, .multi_hit)) |val|
|
|
3281
3243
|
@intCast(val)
|
|
3282
3244
|
else if (showdown)
|
|
3283
3245
|
DISTRIBUTION[battle.rng.range(u3, 0, DISTRIBUTION.len)]
|
|
@@ -3292,7 +3254,7 @@ pub const Rolls = struct {
|
|
|
3292
3254
|
}
|
|
3293
3255
|
|
|
3294
3256
|
fn psywave(battle: anytype, player: Player, max: u8, options: anytype) !u8 {
|
|
3295
|
-
const power = if (options.calc.overridden(player, .psywave)) |val|
|
|
3257
|
+
const power = if (options.calc.overridden(player, 0, .psywave)) |val|
|
|
3296
3258
|
val
|
|
3297
3259
|
else if (showdown)
|
|
3298
3260
|
battle.rng.range(u8, 1, max)
|
|
@@ -3318,7 +3280,7 @@ pub const Rolls = struct {
|
|
|
3318
3280
|
}
|
|
3319
3281
|
|
|
3320
3282
|
// TODO: consider throwing error instead of rerolling?
|
|
3321
|
-
const overridden = if (options.calc.overridden(player, .metronome)) |val| val: {
|
|
3283
|
+
const overridden = if (options.calc.overridden(player, 0, .metronome)) |val| val: {
|
|
3322
3284
|
for (moves) |m| if (m.id == val) break :val null;
|
|
3323
3285
|
break :val val;
|
|
3324
3286
|
} else null;
|
|
@@ -3350,7 +3312,7 @@ pub const Rolls = struct {
|
|
|
3350
3312
|
}
|
|
3351
3313
|
|
|
3352
3314
|
fn sleepDuration(battle: anytype, player: Player, options: anytype) u3 {
|
|
3353
|
-
const duration: u3 = if (options.calc.overridden(player, .duration)) |val|
|
|
3315
|
+
const duration: u3 = if (options.calc.overridden(player, 0, .duration)) |val|
|
|
3354
3316
|
@intCast(val)
|
|
3355
3317
|
else if (showdown)
|
|
3356
3318
|
battle.rng.range(u3, 1, 7)
|
|
@@ -3362,12 +3324,12 @@ pub const Rolls = struct {
|
|
|
3362
3324
|
};
|
|
3363
3325
|
|
|
3364
3326
|
assert(duration >= 1 and duration <= 6);
|
|
3365
|
-
options.chance.duration(
|
|
3327
|
+
options.chance.duration(player, duration);
|
|
3366
3328
|
return duration + 1;
|
|
3367
3329
|
}
|
|
3368
3330
|
|
|
3369
3331
|
fn confusionDuration(battle: anytype, player: Player, self: bool, options: anytype) u3 {
|
|
3370
|
-
const duration: u3 = if (options.calc.overridden(player, .duration)) |val|
|
|
3332
|
+
const duration: u3 = if (options.calc.overridden(player, 0, .duration)) |val|
|
|
3371
3333
|
@intCast(val)
|
|
3372
3334
|
else if (showdown)
|
|
3373
3335
|
// Pokémon Showdown incorrectly uses the same duration for self-confusion
|
|
@@ -3376,16 +3338,16 @@ pub const Rolls = struct {
|
|
|
3376
3338
|
@intCast((battle.rng.next() & if (self) 1 else 3) + 2);
|
|
3377
3339
|
|
|
3378
3340
|
assert(duration >= 2 and duration <= if (!showdown and self) 3 else 5);
|
|
3379
|
-
options.chance.duration(
|
|
3341
|
+
options.chance.duration(player, duration);
|
|
3380
3342
|
return duration;
|
|
3381
3343
|
}
|
|
3382
3344
|
|
|
3383
3345
|
fn disableDuration(battle: anytype, player: Player, options: anytype) u4 {
|
|
3384
|
-
const duration:
|
|
3346
|
+
const duration: u3 = if (options.calc.overridden(player, 0, .duration)) |val|
|
|
3385
3347
|
@intCast(val)
|
|
3386
3348
|
else if (showdown)
|
|
3387
3349
|
// Pokémon Showdown incorrectly inherits Generation III's Disable duration
|
|
3388
|
-
battle.rng.range(
|
|
3350
|
+
battle.rng.range(u3, 2, 6)
|
|
3389
3351
|
else duration: {
|
|
3390
3352
|
while (true) {
|
|
3391
3353
|
const r = battle.rng.next() & 7;
|
|
@@ -3394,12 +3356,12 @@ pub const Rolls = struct {
|
|
|
3394
3356
|
};
|
|
3395
3357
|
|
|
3396
3358
|
assert(duration >= 2 and duration <= (if (showdown) 5 else 7));
|
|
3397
|
-
options.chance.duration(
|
|
3359
|
+
options.chance.duration(player, duration);
|
|
3398
3360
|
return duration;
|
|
3399
3361
|
}
|
|
3400
3362
|
|
|
3401
3363
|
fn attackingDuration(battle: anytype, player: Player, options: anytype) u3 {
|
|
3402
|
-
const duration: u3 = if (options.calc.overridden(player, .duration)) |val|
|
|
3364
|
+
const duration: u3 = if (options.calc.overridden(player, 0, .duration)) |val|
|
|
3403
3365
|
@intCast(val)
|
|
3404
3366
|
else if (showdown)
|
|
3405
3367
|
battle.rng.range(u3, 2, 4)
|
|
@@ -3407,12 +3369,12 @@ pub const Rolls = struct {
|
|
|
3407
3369
|
@intCast((battle.rng.next() & 1) + 2); // BUG: thrash is + 1 not +2
|
|
3408
3370
|
|
|
3409
3371
|
assert(duration >= 2 and duration <= 3);
|
|
3410
|
-
options.chance.duration(
|
|
3372
|
+
options.chance.duration(player, duration);
|
|
3411
3373
|
return duration;
|
|
3412
3374
|
}
|
|
3413
3375
|
|
|
3414
3376
|
fn bindingDuration(battle: anytype, player: Player, options: anytype) u3 {
|
|
3415
|
-
const duration: u3 = (if (options.calc.overridden(player, .duration)) |val|
|
|
3377
|
+
const duration: u3 = (if (options.calc.overridden(player, 0, .duration)) |val|
|
|
3416
3378
|
@intCast(val)
|
|
3417
3379
|
else if (showdown)
|
|
3418
3380
|
// TODO: PS does range(3, 6) here which after subtracting 1 is actually 2-4 not 2-5!
|
|
@@ -3421,13 +3383,13 @@ pub const Rolls = struct {
|
|
|
3421
3383
|
@intCast(battle.rng.next() & 3 + 2));
|
|
3422
3384
|
|
|
3423
3385
|
assert(duration >= 2 and duration <= 5);
|
|
3424
|
-
options.chance.duration(
|
|
3386
|
+
options.chance.duration(player, duration);
|
|
3425
3387
|
return duration + 1;
|
|
3426
3388
|
}
|
|
3427
3389
|
|
|
3428
3390
|
// TODO: consider sharing implementation with bindingDuration
|
|
3429
3391
|
fn encoreDuration(battle: anytype, player: Player, options: anytype) u3 {
|
|
3430
|
-
const duration: u3 = (if (options.calc.overridden(player, .duration)) |val|
|
|
3392
|
+
const duration: u3 = (if (options.calc.overridden(player, 0, .duration)) |val|
|
|
3431
3393
|
@intCast(val)
|
|
3432
3394
|
else if (showdown)
|
|
3433
3395
|
battle.rng.range(u3, 2, 6)
|
|
@@ -3435,7 +3397,7 @@ pub const Rolls = struct {
|
|
|
3435
3397
|
@intCast(battle.rng.next() & 3 + 2));
|
|
3436
3398
|
|
|
3437
3399
|
assert(duration >= 2 and duration <= 5);
|
|
3438
|
-
options.chance.duration(
|
|
3400
|
+
options.chance.duration(player, duration);
|
|
3439
3401
|
return duration + 1;
|
|
3440
3402
|
}
|
|
3441
3403
|
};
|
package/src/lib/node.zig
CHANGED
package/src/lib/pkmn.zig
CHANGED
|
@@ -22,13 +22,16 @@ pub const Choice = @import("common/data.zig").Choice;
|
|
|
22
22
|
/// considered terminal.
|
|
23
23
|
pub const Result = @import("common/data.zig").Result;
|
|
24
24
|
|
|
25
|
+
// TODO
|
|
26
|
+
pub const Array = @import("common/array.zig").Array;
|
|
27
|
+
// TODO
|
|
28
|
+
pub const Optional = @import("common/optional.zig").Optional;
|
|
29
|
+
|
|
25
30
|
/// Pokémon Showdown's RNG (backed by a Generation V & VI RNG).
|
|
26
31
|
pub const PSRNG = @import("common/rng.zig").PSRNG;
|
|
27
32
|
|
|
28
33
|
/// Namespace for helpers related to protocol message logging.
|
|
29
|
-
pub const protocol = if (options.internal) struct {
|
|
30
|
-
pub usingnamespace @import("common/protocol.zig");
|
|
31
|
-
} else struct {
|
|
34
|
+
pub const protocol = if (options.internal) @import("common/protocol.zig") else struct {
|
|
32
35
|
/// Logs protocol information to its `Writer` during a battle update when
|
|
33
36
|
/// `options.log` is enabled.
|
|
34
37
|
pub const Log = @import("common/protocol.zig").Log;
|
|
@@ -82,11 +85,7 @@ pub const gen1 = struct {
|
|
|
82
85
|
/// via `overrides` and tracks `summaries` of information relevant to damage calculation.
|
|
83
86
|
pub const Calc = @import("gen1/calc.zig").Calc;
|
|
84
87
|
/// Namespace for types associated with supported Generation I Pokémon damage calc features.
|
|
85
|
-
pub const calc = if (options.internal) struct {
|
|
86
|
-
pub usingnamespace @import("gen1/calc.zig");
|
|
87
|
-
} else struct {
|
|
88
|
-
/// TODO
|
|
89
|
-
pub const Overrides = @import("gen1/calc.zig").Overrides;
|
|
88
|
+
pub const calc = if (options.internal) @import("gen1/calc.zig") else struct {
|
|
90
89
|
/// Information relevant to damage calculation that occured during a Generation I
|
|
91
90
|
/// battle `update`.
|
|
92
91
|
pub const Summaries = @import("gen1/calc.zig").Summaries;
|
|
@@ -97,6 +96,10 @@ pub const gen1 = struct {
|
|
|
97
96
|
/// though damage calculator support should additionally be turned off
|
|
98
97
|
/// entirely via `options.calc`.
|
|
99
98
|
pub const NULL = @import("gen1/calc.zig").NULL;
|
|
99
|
+
/// TODO
|
|
100
|
+
pub const MAX_FRONTIER = @import("gen1/calc.zig").MAX_FRONTIER;
|
|
101
|
+
/// TODO
|
|
102
|
+
pub const Rolls = @import("gen1/calc.zig").Rolls;
|
|
100
103
|
};
|
|
101
104
|
/// Provides helpers for initializing Generation I Pokémon battles.
|
|
102
105
|
pub const helpers = @import("gen1/helpers.zig");
|
|
@@ -114,10 +117,7 @@ pub const gen2 = struct {
|
|
|
114
117
|
pub const NULL = @import("gen2/chance.zig").NULL;
|
|
115
118
|
};
|
|
116
119
|
pub const Calc = @import("gen2/calc.zig").Calc;
|
|
117
|
-
pub const calc = if (options.internal) struct {
|
|
118
|
-
pub usingnamespace @import("gen2/calc.zig");
|
|
119
|
-
} else struct {
|
|
120
|
-
pub const Overrides = @import("gen2/calc.zig").Overrides;
|
|
120
|
+
pub const calc = if (options.internal) @import("gen2/calc.zig") else struct {
|
|
121
121
|
pub const Summaries = @import("gen2/calc.zig").Summaries;
|
|
122
122
|
pub const Summary = @import("gen2/calc.zig").Summary;
|
|
123
123
|
pub const NULL = @import("gen2/calc.zig").NULL;
|
|
@@ -127,10 +127,8 @@ pub const gen2 = struct {
|
|
|
127
127
|
|
|
128
128
|
// Internal APIs used by other pkmn libraries, not actually part of the public API.
|
|
129
129
|
// NOTE: `pub usingnamespace struct { ... }` here results in a (false?) dependency loop
|
|
130
|
-
pub const js = if (options.internal)
|
|
131
|
-
pub usingnamespace @import("common/js.zig");
|
|
132
|
-
} else struct {};
|
|
130
|
+
pub const js = if (options.internal) @import("common/js.zig") else {};
|
|
133
131
|
pub const bindings = if (options.internal) struct {
|
|
134
132
|
pub const node = @import("node.zig");
|
|
135
133
|
pub const wasm = @import("wasm.zig");
|
|
136
|
-
} else
|
|
134
|
+
} else {};
|