@pkmn/engine 0.1.0-dev.3393edb3 → 0.1.0-dev.36b5d56b
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/build/pkg/addon/browser.d.ts +1 -1
- package/build/pkg/addon/browser.js +2 -1
- package/build/pkg/addon/browser.js.map +1 -1
- package/build/pkg/addon/node.js +2 -1
- package/build/pkg/addon/node.js.map +1 -1
- 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 +20 -0
- package/build/pkg/addon.js.map +1 -1
- package/build/tools/debug.js +1 -1
- package/build/tools/debug.js.map +1 -1
- package/build/tools/display/index.js +17 -8
- package/build/tools/display/index.js.map +1 -1
- package/build.zig +89 -68
- package/package.json +19 -16
- package/src/lib/common/debug.zig +9 -4
- package/src/lib/common/options.zig +2 -0
- package/src/lib/common/protocol.zig +4 -8
- package/src/lib/common/rational.zig +7 -5
- package/src/lib/common/rng.zig +1 -3
- package/src/lib/gen1/calc.zig +82 -88
- package/src/lib/gen1/chance.zig +34 -18
- 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 +7 -11
- package/src/lib/gen1/helpers.zig +4 -11
- package/src/lib/gen1/mechanics.zig +68 -56
- package/src/lib/gen2/calc.zig +9 -17
- 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 +11 -15
- package/src/lib/gen2/generated.zig +18 -23
- package/src/lib/gen2/helpers.zig +5 -12
- package/src/lib/gen2/mechanics.zig +22 -30
- package/src/lib/node.zig +2 -4
- package/src/lib/pkmn.zig +4 -0
- package/src/lib/wasm.zig +1 -2
- package/src/tools/display/ui.css +8 -5
|
@@ -1,36 +1,28 @@
|
|
|
1
|
-
const
|
|
2
|
-
|
|
3
|
-
const pkmn = @import("../pkmn.zig");
|
|
1
|
+
const DEBUG = @import("../common/debug.zig").print;
|
|
4
2
|
|
|
3
|
+
const chance = @import("chance.zig");
|
|
5
4
|
const common = @import("../common/data.zig");
|
|
6
|
-
const
|
|
5
|
+
const data = @import("data.zig");
|
|
6
|
+
const pkmn = @import("../pkmn.zig");
|
|
7
7
|
const protocol = @import("../common/protocol.zig");
|
|
8
8
|
const rng = @import("../common/rng.zig");
|
|
9
|
-
|
|
10
|
-
const data = @import("data.zig");
|
|
11
|
-
const chance = @import("chance.zig");
|
|
9
|
+
const std = @import("std");
|
|
12
10
|
|
|
13
11
|
const assert = std.debug.assert;
|
|
14
|
-
|
|
15
|
-
const expectEqual = std.testing.expectEqual;
|
|
16
|
-
|
|
17
|
-
const showdown = pkmn.options.showdown;
|
|
18
|
-
|
|
19
|
-
const Choice = common.Choice;
|
|
20
|
-
const ID = common.ID;
|
|
21
|
-
const Player = common.Player;
|
|
22
|
-
const Result = common.Result;
|
|
23
|
-
|
|
24
12
|
const Boost = protocol.Boost;
|
|
13
|
+
const Choice = common.Choice;
|
|
25
14
|
const Damage = protocol.Damage;
|
|
15
|
+
const Effectiveness = data.Effectiveness;
|
|
16
|
+
const expectEqual = std.testing.expectEqual;
|
|
26
17
|
const Fail = protocol.Fail;
|
|
27
|
-
const Heal = protocol.Heal;
|
|
28
|
-
|
|
29
18
|
const Gen12 = rng.Gen12;
|
|
30
|
-
|
|
31
|
-
const
|
|
19
|
+
const Heal = protocol.Heal;
|
|
20
|
+
const ID = common.ID;
|
|
32
21
|
const Move = data.Move;
|
|
33
22
|
const MoveSlot = data.MoveSlot;
|
|
23
|
+
const Player = common.Player;
|
|
24
|
+
const Result = common.Result;
|
|
25
|
+
const showdown = pkmn.options.showdown;
|
|
34
26
|
const Side = data.Side;
|
|
35
27
|
const Species = data.Species;
|
|
36
28
|
const Stats = data.Stats;
|
|
@@ -173,7 +165,10 @@ fn selectMove(
|
|
|
173
165
|
if (foe_choice.type == .Switch) {
|
|
174
166
|
const last = side.active.move(battle.lastMove(player).index);
|
|
175
167
|
if (last.id == .Metronome) side.last_selected_move = last.id;
|
|
176
|
-
if (last.id == .MirrorMove)
|
|
168
|
+
if (last.id == .MirrorMove) {
|
|
169
|
+
if (!pkmn.options.mod) return Result.Error;
|
|
170
|
+
side.last_selected_move = last.id;
|
|
171
|
+
}
|
|
177
172
|
}
|
|
178
173
|
}
|
|
179
174
|
return null;
|
|
@@ -341,7 +336,6 @@ fn doTurn(
|
|
|
341
336
|
player_choice,
|
|
342
337
|
player_rewrap,
|
|
343
338
|
player_skip,
|
|
344
|
-
true,
|
|
345
339
|
&residual,
|
|
346
340
|
options,
|
|
347
341
|
)) |r| return r;
|
|
@@ -364,7 +358,6 @@ fn doTurn(
|
|
|
364
358
|
foe_choice,
|
|
365
359
|
foe_rewrap,
|
|
366
360
|
foe_skip,
|
|
367
|
-
false,
|
|
368
361
|
&residual,
|
|
369
362
|
options,
|
|
370
363
|
)) |r| return r;
|
|
@@ -392,7 +385,6 @@ fn executeMove(
|
|
|
392
385
|
choice: Choice,
|
|
393
386
|
rewrap: bool,
|
|
394
387
|
skip: bool,
|
|
395
|
-
first: bool,
|
|
396
388
|
residual: *bool,
|
|
397
389
|
options: anytype,
|
|
398
390
|
) !?Result {
|
|
@@ -427,7 +419,7 @@ fn executeMove(
|
|
|
427
419
|
mslot = @intCast(battle.lastMove(player).index);
|
|
428
420
|
const stored = side.stored();
|
|
429
421
|
// GLITCH: Struggle bypass PP underflow via Hyper Beam / Trapping-switch auto selection
|
|
430
|
-
auto = isForced(&side.active) or
|
|
422
|
+
auto = pkmn.options.mod or isForced(&side.active) or
|
|
431
423
|
side.active.volatiles.Binding or side.active.volatiles.Bide or
|
|
432
424
|
side.last_selected_move == .HyperBeam or
|
|
433
425
|
Status.is(stored.status, .FRZ) or Status.is(stored.status, .SLP);
|
|
@@ -452,7 +444,7 @@ fn executeMove(
|
|
|
452
444
|
|
|
453
445
|
var skip_can = false;
|
|
454
446
|
var skip_pp = false;
|
|
455
|
-
switch (try beforeMove(battle, player, skip,
|
|
447
|
+
switch (try beforeMove(battle, player, skip, residual, options)) {
|
|
456
448
|
.done => return null,
|
|
457
449
|
.skip_can => skip_can = true,
|
|
458
450
|
.skip_pp => skip_pp = true,
|
|
@@ -460,6 +452,25 @@ fn executeMove(
|
|
|
460
452
|
.err => return @as(?Result, Result.Error),
|
|
461
453
|
}
|
|
462
454
|
|
|
455
|
+
// Pokémon Showdown incorrectly implements PP deduction when handling the Hyper Beam automatic
|
|
456
|
+
// selection glitch - if the move was proced due to Metronome / Mirror Move it either subtracts
|
|
457
|
+
// from the Hyper Beam slot if present or skips PP deduction entirely...
|
|
458
|
+
if (showdown and !skip_pp and side.last_selected_move == .HyperBeam and
|
|
459
|
+
side.last_selected_move != side.active.move(battle.lastMove(player).index).id)
|
|
460
|
+
{
|
|
461
|
+
assert(mslot == 1);
|
|
462
|
+
const has_beam = has_beam: {
|
|
463
|
+
for (side.active.moves, 0..) |m, i| {
|
|
464
|
+
if (m.id == .HyperBeam) {
|
|
465
|
+
mslot = @intCast(i + 1);
|
|
466
|
+
break :has_beam true;
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
break :has_beam false;
|
|
470
|
+
};
|
|
471
|
+
if (!has_beam) skip_pp = true;
|
|
472
|
+
}
|
|
473
|
+
|
|
463
474
|
const can = skip_can or
|
|
464
475
|
try canMove(battle, player, mslot, auto, skip_pp, .None, residual, options);
|
|
465
476
|
if (!can) return null;
|
|
@@ -473,7 +484,6 @@ fn beforeMove(
|
|
|
473
484
|
battle: anytype,
|
|
474
485
|
player: Player,
|
|
475
486
|
skip: bool,
|
|
476
|
-
first: bool,
|
|
477
487
|
residual: *bool,
|
|
478
488
|
options: anytype,
|
|
479
489
|
) !BeforeMove {
|
|
@@ -558,24 +568,17 @@ fn beforeMove(
|
|
|
558
568
|
// This can only happen if a Pokémon started the battle frozen/sleeping and was thawed/woken
|
|
559
569
|
// before the side had a selected a move - we simply need to assume this leads to a desync
|
|
560
570
|
if (side.last_selected_move == .None) {
|
|
561
|
-
assert(!
|
|
571
|
+
assert(!pkmn.options.mod);
|
|
562
572
|
return .err;
|
|
563
573
|
}
|
|
564
574
|
|
|
565
575
|
if (volatiles.Confusion) {
|
|
566
576
|
assert(volatiles.confusion > 0);
|
|
567
577
|
if (options.calc.overridden(player, .confusion)) |obs| switch (obs) {
|
|
568
|
-
.started =>
|
|
569
|
-
if (!first or (options.calc.overridden(player, .confused) orelse .None) != .None) {
|
|
570
|
-
volatiles.confusion -= 1;
|
|
571
|
-
} else {
|
|
572
|
-
volatiles.confusion = 0;
|
|
573
|
-
}
|
|
574
|
-
},
|
|
578
|
+
.started, .ended => volatiles.confusion = 0,
|
|
575
579
|
.continuing => if (volatiles.confusion > 1) {
|
|
576
580
|
volatiles.confusion -= 1;
|
|
577
581
|
},
|
|
578
|
-
.ended => volatiles.confusion = 0,
|
|
579
582
|
.overwritten => {},
|
|
580
583
|
else => unreachable,
|
|
581
584
|
} else {
|
|
@@ -703,7 +706,7 @@ fn beforeMove(
|
|
|
703
706
|
try options.chance.attacking(player, if (volatiles.attacks == 0) .ended else .continuing);
|
|
704
707
|
|
|
705
708
|
if (volatiles.attacks == 0) {
|
|
706
|
-
const overwritten =
|
|
709
|
+
const overwritten = volatiles.Confusion;
|
|
707
710
|
|
|
708
711
|
volatiles.Thrashing = false;
|
|
709
712
|
volatiles.Confusion = true;
|
|
@@ -714,7 +717,11 @@ fn beforeMove(
|
|
|
714
717
|
// can be expected to recognize this pattern and pass the information only to the
|
|
715
718
|
// correct player)
|
|
716
719
|
try log.start(.{ battle.active(player), .ConfusionSilent });
|
|
717
|
-
options.chance.observe(.confusion, player, if (overwritten)
|
|
720
|
+
options.chance.observe(.confusion, player, if (overwritten)
|
|
721
|
+
if (pkmn.options.overwrite) .overwritten else .continuing
|
|
722
|
+
else
|
|
723
|
+
.started);
|
|
724
|
+
if (!overwritten) options.calc.confusion(player);
|
|
718
725
|
}
|
|
719
726
|
|
|
720
727
|
// This shouldn't actually set last_used_move, but Pokémon Showdown sets last
|
|
@@ -780,9 +787,14 @@ fn canMove(
|
|
|
780
787
|
|
|
781
788
|
if (move.effect == .Thrashing) {
|
|
782
789
|
Effects.thrashing(battle, player, options);
|
|
783
|
-
} else if (
|
|
784
|
-
// Pokémon Showdown handles this after hit/miss checks and damage calculation
|
|
785
|
-
|
|
790
|
+
} else if (move.effect == .Binding) {
|
|
791
|
+
// Pokémon Showdown handles this after hit/miss checks and damage calculation, though clears
|
|
792
|
+
// Recharging in onTryMove (required for the Hyper Beam automatic selection glitch)
|
|
793
|
+
if (showdown) {
|
|
794
|
+
battle.foe(player).active.volatiles.Recharging = false;
|
|
795
|
+
} else {
|
|
796
|
+
try Effects.binding(battle, player, false, options);
|
|
797
|
+
}
|
|
786
798
|
}
|
|
787
799
|
|
|
788
800
|
return true;
|
|
@@ -1136,7 +1148,7 @@ fn calcDamage(
|
|
|
1136
1148
|
if ((!showdown or !cfz) and (atk > 255 or def > 255)) {
|
|
1137
1149
|
atk = @max((atk / 4) & 255, 1);
|
|
1138
1150
|
// GLITCH: not adjusted to be a min of 1 on cartridge (can lead to division-by-zero freeze)
|
|
1139
|
-
def = @max((def / 4) & 255, if (
|
|
1151
|
+
def = @max((def / 4) & 255, if (pkmn.options.mod) 1 else 0);
|
|
1140
1152
|
}
|
|
1141
1153
|
|
|
1142
1154
|
const lvl: u32 = side.stored().level * @as(u2, if (crit) 2 else 1);
|
|
@@ -1157,7 +1169,7 @@ fn calcDamage(
|
|
|
1157
1169
|
// encountered so we need to make sure that in the event of a miss we commit the status of the
|
|
1158
1170
|
// crit roll. The alternative to doing this extra work is to *always* commit the crit roll but
|
|
1159
1171
|
// that results in counter intuitive probabilities in the common case
|
|
1160
|
-
if (pkmn.options.chance and !
|
|
1172
|
+
if (pkmn.options.chance and !pkmn.options.mod) {
|
|
1161
1173
|
atk = attack(side, !crit, special);
|
|
1162
1174
|
def = defense(target, !crit, special, false);
|
|
1163
1175
|
if ((atk > 255 or def > 255) and (def / 4) & 255 == 0) options.chance.glitch();
|
|
@@ -1242,13 +1254,13 @@ fn specialDamage(battle: anytype, player: Player, move: Move.Data, options: anyt
|
|
|
1242
1254
|
.Psywave => power: {
|
|
1243
1255
|
const max: u8 = @intCast(@as(u16, side.stored().level) * 3 / 2);
|
|
1244
1256
|
// GLITCH: Psywave infinite glitch loop
|
|
1245
|
-
if (!
|
|
1257
|
+
if (!pkmn.options.mod and max <= 1) return Result.Error;
|
|
1246
1258
|
break :power try Rolls.psywave(battle, player, max, options);
|
|
1247
1259
|
},
|
|
1248
1260
|
else => unreachable,
|
|
1249
1261
|
};
|
|
1250
1262
|
|
|
1251
|
-
if (battle.last_damage == 0) return if (
|
|
1263
|
+
if (battle.last_damage == 0) return if (pkmn.options.mod) null else Result.Error;
|
|
1252
1264
|
|
|
1253
1265
|
const sub = showdown and foe.active.volatiles.Substitute;
|
|
1254
1266
|
_ = try applyDamage(battle, player.foe(), player.foe(), .None, options);
|
|
@@ -1285,7 +1297,7 @@ fn counterDamage(battle: anytype, player: Player, move: Move.Data, options: anyt
|
|
|
1285
1297
|
|
|
1286
1298
|
if (!used or !selected) {
|
|
1287
1299
|
// GLITCH: Counter desync (covered by Desync Clause Mod on Pokémon Showdown)
|
|
1288
|
-
if (!
|
|
1300
|
+
if (!pkmn.options.mod) return Result.Error;
|
|
1289
1301
|
try options.log.fail(.{ battle.active(player), .None });
|
|
1290
1302
|
return null;
|
|
1291
1303
|
}
|
|
@@ -1532,7 +1544,7 @@ fn faint(battle: anytype, player: Player, done: bool, cap: bool, options: anytyp
|
|
|
1532
1544
|
assert(!foe_volatiles.MultiHit);
|
|
1533
1545
|
if (foe_volatiles.Bide) {
|
|
1534
1546
|
assert(!foe_volatiles.Thrashing and !foe_volatiles.Rage);
|
|
1535
|
-
foe_volatiles.state = if (
|
|
1547
|
+
foe_volatiles.state = if (pkmn.options.mod) 0 else foe_volatiles.state & 255;
|
|
1536
1548
|
if (foe_volatiles.state != 0) return Result.Error;
|
|
1537
1549
|
}
|
|
1538
1550
|
|
|
@@ -1623,12 +1635,12 @@ fn endTurn(battle: anytype, options: anytype) @TypeOf(options.log).Error!Result
|
|
|
1623
1635
|
|
|
1624
1636
|
battle.turn += 1;
|
|
1625
1637
|
|
|
1626
|
-
if (
|
|
1638
|
+
if (pkmn.options.mod and pkmn.options.ebc and checkEBC(battle)) {
|
|
1627
1639
|
try options.log.tie(.{});
|
|
1628
1640
|
return Result.Tie;
|
|
1629
1641
|
}
|
|
1630
1642
|
|
|
1631
|
-
if (
|
|
1643
|
+
if (pkmn.options.mod and battle.turn >= 1000) {
|
|
1632
1644
|
try options.log.tie(.{});
|
|
1633
1645
|
return Result.Tie;
|
|
1634
1646
|
} else if (battle.turn >= 65535) {
|
|
@@ -1877,6 +1889,7 @@ pub const Effects = struct {
|
|
|
1877
1889
|
|
|
1878
1890
|
foe.active.volatiles.confusion = Rolls.confusionDuration(battle, player, options);
|
|
1879
1891
|
options.chance.observe(.confusion, player.foe(), .started);
|
|
1892
|
+
options.calc.confusion(player.foe());
|
|
1880
1893
|
|
|
1881
1894
|
try options.log.start(.{ battle.active(player.foe()), .Confusion });
|
|
1882
1895
|
}
|
|
@@ -1922,12 +1935,11 @@ pub const Effects = struct {
|
|
|
1922
1935
|
|
|
1923
1936
|
// Technically this is still considered simply a "miss" on the cartridge,
|
|
1924
1937
|
// but diverging from Pokémon Showdown here would mostly just be pedantic
|
|
1925
|
-
if (n == 0) {
|
|
1938
|
+
if (n == 0 or (pkmn.options.mod and err)) {
|
|
1926
1939
|
try options.log.fail(.{ foe_ident, .None });
|
|
1927
1940
|
return null;
|
|
1928
1941
|
} else if (err) {
|
|
1929
1942
|
// GLITCH: Transform + Mirror Move / Metronome PP softlock
|
|
1930
|
-
assert(!showdown);
|
|
1931
1943
|
return Result.Error;
|
|
1932
1944
|
}
|
|
1933
1945
|
|
|
@@ -2005,7 +2017,7 @@ pub const Effects = struct {
|
|
|
2005
2017
|
if (foe.active.types.includes(move.type)) return;
|
|
2006
2018
|
if (!try Rolls.secondaryChance(battle, player, true, options)) return;
|
|
2007
2019
|
// Freeze Clause Mod
|
|
2008
|
-
if (
|
|
2020
|
+
if (pkmn.options.mod) for (foe.pokemon) |p| if (Status.is(p.status, .FRZ)) return;
|
|
2009
2021
|
|
|
2010
2022
|
foe_stored.status = Status.init(.FRZ);
|
|
2011
2023
|
// GLITCH: Hyper Beam recharging status is not cleared
|
|
@@ -2346,7 +2358,7 @@ pub const Effects = struct {
|
|
|
2346
2358
|
}
|
|
2347
2359
|
|
|
2348
2360
|
// Sleep Clause Mod
|
|
2349
|
-
if (
|
|
2361
|
+
if (pkmn.options.mod) {
|
|
2350
2362
|
for (foe.pokemon) |p| {
|
|
2351
2363
|
if (Status.is(p.status, .SLP) and !Status.is(p.status, .EXT)) return;
|
|
2352
2364
|
}
|
|
@@ -2452,7 +2464,7 @@ pub const Effects = struct {
|
|
|
2452
2464
|
if (side.active.volatiles.Binding) return;
|
|
2453
2465
|
side.active.volatiles.Binding = true;
|
|
2454
2466
|
// GLITCH: Hyper Beam automatic selection glitch if Recharging gets cleared on miss
|
|
2455
|
-
// (Pokémon Showdown
|
|
2467
|
+
// (Pokémon Showdown clears Recharging in onTryMove instead)
|
|
2456
2468
|
if (!showdown) {
|
|
2457
2469
|
foe.active.volatiles.Recharging = false;
|
|
2458
2470
|
} else if (foe.stored().hp == 0) return if (!rewrap) battle.rng.advance(1);
|
|
@@ -3218,7 +3230,7 @@ pub fn choices(battle: anytype, player: Player, request: Choice.Type, out: []Cho
|
|
|
3218
3230
|
// Struggle (Pokémon Showdown would use 'move 1' here)
|
|
3219
3231
|
if (n == before) {
|
|
3220
3232
|
// GLITCH: Transform + Mirror Move / Metronome PP softlock
|
|
3221
|
-
if (!
|
|
3233
|
+
if (!pkmn.options.mod) {
|
|
3222
3234
|
while (slot <= 4) : (slot += 1) {
|
|
3223
3235
|
if (active.moves[slot - 1].pp != 0) return n;
|
|
3224
3236
|
}
|
package/src/lib/gen2/calc.zig
CHANGED
|
@@ -1,27 +1,19 @@
|
|
|
1
|
-
const
|
|
2
|
-
|
|
3
|
-
const pkmn = @import("../pkmn.zig");
|
|
4
|
-
|
|
1
|
+
const chance = @import("chance.zig");
|
|
5
2
|
const common = @import("../common/data.zig");
|
|
6
|
-
const util = @import("../common/util.zig");
|
|
7
|
-
|
|
8
3
|
const Optional = @import("../common/optional.zig").Optional;
|
|
4
|
+
const pkmn = @import("../pkmn.zig");
|
|
5
|
+
const std = @import("std");
|
|
6
|
+
const util = @import("../common/util.zig");
|
|
9
7
|
|
|
10
|
-
const
|
|
11
|
-
|
|
8
|
+
const Action = chance.Action;
|
|
9
|
+
const Actions = chance.Actions;
|
|
12
10
|
const assert = std.debug.assert;
|
|
13
|
-
|
|
11
|
+
const Criticals = chance.Criticals;
|
|
12
|
+
const Damages = chance.Damages;
|
|
14
13
|
const enabled = pkmn.options.calc;
|
|
15
|
-
|
|
14
|
+
const isPointerTo = util.isPointerTo;
|
|
16
15
|
const Player = common.Player;
|
|
17
|
-
|
|
18
16
|
const PointerType = util.PointerType;
|
|
19
|
-
const isPointerTo = util.isPointerTo;
|
|
20
|
-
|
|
21
|
-
const Actions = chance.Actions;
|
|
22
|
-
const Action = chance.Action;
|
|
23
|
-
const Criticals = chance.Criticals;
|
|
24
|
-
const Damages = chance.Damages;
|
|
25
17
|
|
|
26
18
|
const Int = if (@hasField(std.builtin.Type, "int")) .int else .Int;
|
|
27
19
|
const Enum = if (@hasField(std.builtin.Type, "enum")) .@"enum" else .Enum;
|
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
//! Code generated by `tools/generate` - manual edits will be overwritten.
|
|
2
2
|
|
|
3
|
-
const std = @import("std");
|
|
4
|
-
|
|
5
3
|
const data = @import("../../gen2/data.zig");
|
|
4
|
+
const std = @import("std");
|
|
6
5
|
|
|
7
6
|
const assert = std.debug.assert;
|
|
8
|
-
|
|
9
7
|
const Type = data.Type;
|
|
10
8
|
|
|
11
9
|
/// Representation of a held item in Generation II Pokémon.
|
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
//! Code generated by `tools/generate` - manual edits will be overwritten.
|
|
2
2
|
|
|
3
|
-
const std = @import("std");
|
|
4
|
-
|
|
5
|
-
const rng = @import("../../common/rng.zig");
|
|
6
3
|
const gen2 = @import("../../gen2/data.zig");
|
|
4
|
+
const rng = @import("../../common/rng.zig");
|
|
5
|
+
const std = @import("std");
|
|
7
6
|
|
|
8
7
|
const assert = std.debug.assert;
|
|
9
|
-
|
|
10
8
|
const percent = rng.Gen12.percent;
|
|
11
9
|
const Type = gen2.Type;
|
|
12
10
|
|
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
//! Code generated by `tools/generate` - manual edits will be overwritten.
|
|
2
2
|
|
|
3
|
-
const std = @import("std");
|
|
4
|
-
|
|
5
3
|
const gen2 = @import("../../gen2/data.zig");
|
|
4
|
+
const std = @import("std");
|
|
6
5
|
|
|
7
6
|
const assert = std.debug.assert;
|
|
8
|
-
|
|
9
7
|
const Stats = gen2.Stats;
|
|
10
8
|
const Types = gen2.Types;
|
|
11
9
|
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
//! Code generated by `tools/generate` - manual edits will be overwritten.
|
|
2
2
|
|
|
3
|
-
const std = @import("std");
|
|
4
|
-
|
|
5
3
|
const gen1 = @import("../../gen1/data.zig");
|
|
4
|
+
const std = @import("std");
|
|
6
5
|
|
|
7
6
|
const assert = std.debug.assert;
|
|
8
7
|
const Effectiveness = gen1.Effectiveness;
|
package/src/lib/gen2/data.zig
CHANGED
|
@@ -1,24 +1,20 @@
|
|
|
1
|
-
const std = @import("std");
|
|
2
|
-
const builtin = @import("builtin");
|
|
3
|
-
|
|
4
|
-
const pkmn = @import("../pkmn.zig");
|
|
5
|
-
|
|
6
|
-
const data = @import("../common/data.zig");
|
|
7
1
|
const DEBUG = @import("../common/debug.zig").print;
|
|
8
|
-
const protocol = @import("../common/protocol.zig");
|
|
9
|
-
const rng = @import("../common/rng.zig");
|
|
10
|
-
const util = @import("../common/util.zig");
|
|
11
2
|
|
|
3
|
+
const builtin = @import("builtin");
|
|
4
|
+
const calc = @import("calc.zig");
|
|
5
|
+
const chance = @import("chance.zig");
|
|
6
|
+
const data = @import("../common/data.zig");
|
|
7
|
+
const gen1 = @import("../gen1/data.zig");
|
|
12
8
|
const items = @import("data/items.zig");
|
|
9
|
+
const mechanics = @import("mechanics.zig");
|
|
13
10
|
const moves = @import("data/moves.zig");
|
|
11
|
+
const pkmn = @import("../pkmn.zig");
|
|
12
|
+
const protocol = @import("../common/protocol.zig");
|
|
13
|
+
const rng = @import("../common/rng.zig");
|
|
14
14
|
const species = @import("data/species.zig");
|
|
15
|
+
const std = @import("std");
|
|
15
16
|
const types = @import("data/types.zig");
|
|
16
|
-
|
|
17
|
-
const gen1 = @import("../gen1/data.zig");
|
|
18
|
-
|
|
19
|
-
const calc = @import("calc.zig");
|
|
20
|
-
const chance = @import("chance.zig");
|
|
21
|
-
const mechanics = @import("mechanics.zig");
|
|
17
|
+
const util = @import("../common/util.zig");
|
|
22
18
|
|
|
23
19
|
const assert = std.debug.assert;
|
|
24
20
|
const expectEqual = std.testing.expectEqual;
|
|
@@ -1,37 +1,32 @@
|
|
|
1
1
|
//! Code generated by `tools/generate` - manual edits will be overwritten.
|
|
2
2
|
|
|
3
|
-
const std = @import("std");
|
|
4
|
-
|
|
5
3
|
const common = @import("../common/data.zig");
|
|
6
|
-
|
|
7
4
|
const data = @import("data.zig");
|
|
8
5
|
const mechanics = @import("mechanics.zig");
|
|
6
|
+
const std = @import("std");
|
|
9
7
|
|
|
10
|
-
const
|
|
11
|
-
const
|
|
12
|
-
|
|
13
|
-
const
|
|
14
|
-
const
|
|
15
|
-
|
|
16
|
-
const Effects = mechanics.Effects;
|
|
17
|
-
const State = mechanics.State;
|
|
18
|
-
|
|
19
|
-
const canMove = mechanics.canMove;
|
|
8
|
+
const adjustDamage = mechanics.adjustDamage;
|
|
9
|
+
const afterMove = mechanics.afterMove;
|
|
10
|
+
const applyDamage = mechanics.applyDamage;
|
|
11
|
+
const buildRage = mechanics.buildRage;
|
|
12
|
+
const calcDamage = mechanics.calcDamage;
|
|
20
13
|
const canCharge = mechanics.canCharge;
|
|
14
|
+
const canMove = mechanics.canMove;
|
|
15
|
+
const checkCriticalHit = mechanics.checkCriticalHit;
|
|
16
|
+
const checkHit = mechanics.checkHit;
|
|
21
17
|
const decrementPP = mechanics.decrementPP;
|
|
18
|
+
const destinyBond = mechanics.destinyBond;
|
|
22
19
|
const doMove = mechanics.doMove;
|
|
23
|
-
const checkHit = mechanics.checkHit;
|
|
24
|
-
const checkCriticalHit = mechanics.checkCriticalHit;
|
|
25
|
-
const calcDamage = mechanics.calcDamage;
|
|
26
|
-
const adjustDamage = mechanics.adjustDamage;
|
|
27
|
-
const randomizeDamage = mechanics.randomizeDamage;
|
|
28
|
-
const applyDamage = mechanics.applyDamage;
|
|
29
|
-
const reportOutcome = mechanics.reportOutcome;
|
|
30
20
|
const effectChance = mechanics.effectChance;
|
|
31
|
-
const
|
|
32
|
-
const
|
|
21
|
+
const Effectiveness = data.Effectiveness;
|
|
22
|
+
const Effects = mechanics.Effects;
|
|
33
23
|
const kingsRock = mechanics.kingsRock;
|
|
34
|
-
const
|
|
24
|
+
const Move = data.Move;
|
|
25
|
+
const Player = common.Player;
|
|
26
|
+
const randomizeDamage = mechanics.randomizeDamage;
|
|
27
|
+
const reportOutcome = mechanics.reportOutcome;
|
|
28
|
+
const Result = common.Result;
|
|
29
|
+
const State = mechanics.State;
|
|
35
30
|
|
|
36
31
|
const SECONDARY = true;
|
|
37
32
|
const KINGS = true;
|
package/src/lib/gen2/helpers.zig
CHANGED
|
@@ -1,25 +1,18 @@
|
|
|
1
|
-
const std = @import("std");
|
|
2
|
-
|
|
3
1
|
const common = @import("../common/data.zig");
|
|
2
|
+
const data = @import("data.zig");
|
|
3
|
+
const gen1 = @import("../gen1/data.zig");
|
|
4
4
|
const options = @import("../common/options.zig");
|
|
5
5
|
const rng = @import("../common/rng.zig");
|
|
6
|
-
|
|
7
|
-
const gen1 = @import("../gen1/data.zig");
|
|
8
|
-
|
|
9
|
-
const data = @import("data.zig");
|
|
6
|
+
const std = @import("std");
|
|
10
7
|
|
|
11
8
|
const assert = std.debug.assert;
|
|
12
|
-
|
|
13
9
|
const Choice = common.Choice;
|
|
14
|
-
|
|
15
|
-
const showdown = options.showdown;
|
|
16
|
-
|
|
17
|
-
const PSRNG = rng.PSRNG;
|
|
18
|
-
|
|
19
10
|
const DVs = data.DVs;
|
|
20
11
|
const Item = data.Item;
|
|
21
12
|
const Move = data.Move;
|
|
22
13
|
const MoveSlot = data.MoveSlot;
|
|
14
|
+
const PSRNG = rng.PSRNG;
|
|
15
|
+
const showdown = options.showdown;
|
|
23
16
|
const Species = data.Species;
|
|
24
17
|
const Stats = data.Stats;
|
|
25
18
|
|
|
@@ -1,44 +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
2
|
|
|
3
|
+
const common = @import("../common/data.zig");
|
|
10
4
|
const data = @import("data.zig");
|
|
11
5
|
const generated = @import("generated.zig");
|
|
12
|
-
|
|
13
|
-
const
|
|
14
|
-
|
|
15
|
-
const
|
|
16
|
-
const expectEqualSlices = std.testing.expectEqualSlices;
|
|
17
|
-
const expectEqualStrings = std.testing.expectEqualStrings;
|
|
18
|
-
|
|
19
|
-
const showdown = pkmn.options.showdown;
|
|
20
|
-
|
|
21
|
-
const Choice = common.Choice;
|
|
22
|
-
const ID = common.ID;
|
|
23
|
-
const Player = common.Player;
|
|
24
|
-
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");
|
|
25
10
|
|
|
26
11
|
const Activate = protocol.Activate;
|
|
12
|
+
const ActivePokemon = data.ActivePokemon;
|
|
13
|
+
const assert = std.debug.assert;
|
|
27
14
|
const Boost = protocol.Boost;
|
|
15
|
+
const Boosts = data.Boosts;
|
|
16
|
+
const Choice = common.Choice;
|
|
28
17
|
const Damage = protocol.Damage;
|
|
18
|
+
const Effectiveness = data.Effectiveness;
|
|
29
19
|
const End = protocol.End;
|
|
20
|
+
const expectEqual = std.testing.expectEqual;
|
|
21
|
+
const expectEqualSlices = std.testing.expectEqualSlices;
|
|
22
|
+
const expectEqualStrings = std.testing.expectEqualStrings;
|
|
30
23
|
const Fail = protocol.Fail;
|
|
31
|
-
const Heal = protocol.Heal;
|
|
32
|
-
const Start = protocol.Start;
|
|
33
|
-
|
|
34
24
|
const Gen12 = rng.Gen12;
|
|
35
|
-
|
|
36
|
-
const
|
|
37
|
-
const Boosts = data.Boosts;
|
|
38
|
-
const Effectiveness = data.Effectiveness;
|
|
25
|
+
const Heal = protocol.Heal;
|
|
26
|
+
const ID = common.ID;
|
|
39
27
|
const Item = data.Item;
|
|
40
28
|
const Move = data.Move;
|
|
29
|
+
const Player = common.Player;
|
|
30
|
+
const Result = common.Result;
|
|
31
|
+
const showdown = pkmn.options.showdown;
|
|
41
32
|
const Side = data.Side;
|
|
33
|
+
const Start = protocol.Start;
|
|
42
34
|
const Stats = data.Stats;
|
|
43
35
|
const Status = data.Status;
|
|
44
36
|
const TriAttack = data.TriAttack;
|
|
@@ -1200,7 +1192,7 @@ fn updateSideCondition(
|
|
|
1200
1192
|
fn endTurn(battle: anytype, options: anytype) @TypeOf(options.log).Error!Result {
|
|
1201
1193
|
battle.turn += 1;
|
|
1202
1194
|
|
|
1203
|
-
if (
|
|
1195
|
+
if (pkmn.options.mod and battle.turn >= 1000) {
|
|
1204
1196
|
try options.log.tie(.{});
|
|
1205
1197
|
return Result.Tie;
|
|
1206
1198
|
} else if (battle.turn >= 65535) {
|
|
@@ -1706,7 +1698,7 @@ pub const Effects = struct {
|
|
|
1706
1698
|
if (!state.proc) return;
|
|
1707
1699
|
if (foe.conditions.Safeguard) return;
|
|
1708
1700
|
// Freeze Clause Mod
|
|
1709
|
-
if (
|
|
1701
|
+
if (pkmn.options.mod) for (foe.pokemon) |p| if (Status.is(p.status, .FRZ)) return;
|
|
1710
1702
|
|
|
1711
1703
|
foe_stored.status = Status.init(.FRZ);
|
|
1712
1704
|
try options.log.status(.{ foe_ident, foe_stored.status, .None });
|
|
@@ -2384,7 +2376,7 @@ pub const Effects = struct {
|
|
|
2384
2376
|
}
|
|
2385
2377
|
|
|
2386
2378
|
// Sleep Clause Mod
|
|
2387
|
-
if (
|
|
2379
|
+
if (pkmn.options.mod) {
|
|
2388
2380
|
for (foe.pokemon) |p| {
|
|
2389
2381
|
if (Status.is(p.status, .SLP) and !Status.is(p.status, .EXT)) return;
|
|
2390
2382
|
}
|
package/src/lib/node.zig
CHANGED
package/src/lib/pkmn.zig
CHANGED
|
@@ -96,6 +96,10 @@ pub const gen1 = struct {
|
|
|
96
96
|
/// though damage calculator support should additionally be turned off
|
|
97
97
|
/// entirely via `options.calc`.
|
|
98
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;
|
|
99
103
|
};
|
|
100
104
|
/// Provides helpers for initializing Generation I Pokémon battles.
|
|
101
105
|
pub const helpers = @import("gen1/helpers.zig");
|