@pkmn/engine 0.1.0-dev.b3f3e3a6 → 0.1.0-dev.bb8e286d
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 +3 -3
- package/build/pkg/addon.js.map +1 -1
- package/build/pkg/data.d.ts +1 -0
- package/build/pkg/data.js.map +1 -1
- 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 +1 -1
- package/build/pkg/protocol.js.map +1 -1
- package/build/test/display.js.map +1 -1
- package/build/tools/debug.js.map +1 -1
- package/build.zig +19 -8
- package/package.json +11 -10
- package/src/bin/install-pkmn-engine +1 -1
- package/src/lib/binding/node.zig +6 -10
- package/src/lib/common/protocol.zig +53 -52
- package/src/lib/common/rational.zig +7 -3
- package/src/lib/gen1/calc.zig +5 -5
- package/src/lib/gen1/mechanics.zig +16 -26
- package/src/lib/gen2/data.zig +1 -1
- package/src/lib/gen2/generated.zig +1 -3
- package/src/lib/gen2/mechanics.zig +20 -24
|
@@ -140,11 +140,11 @@ fn start(battle: anytype, options: anytype) !Result {
|
|
|
140
140
|
const p1 = battle.side(.P1);
|
|
141
141
|
const p2 = battle.side(.P2);
|
|
142
142
|
|
|
143
|
-
|
|
143
|
+
const p1_slot = findFirstAlive(p1);
|
|
144
144
|
assert(!showdown or p1_slot == 1);
|
|
145
145
|
if (p1_slot == 0) return if (findFirstAlive(p2) == 0) Result.Tie else Result.Lose;
|
|
146
146
|
|
|
147
|
-
|
|
147
|
+
const p2_slot = findFirstAlive(p2);
|
|
148
148
|
assert(!showdown or p2_slot == 1);
|
|
149
149
|
if (p2_slot == 0) return Result.Win;
|
|
150
150
|
|
|
@@ -403,7 +403,9 @@ fn executeMove(
|
|
|
403
403
|
|
|
404
404
|
assert(choice.type == .Move);
|
|
405
405
|
var mslot: u4 = @intCast(choice.data);
|
|
406
|
+
_ = &mslot;
|
|
406
407
|
var move = Move.Pound; // TODO
|
|
408
|
+
_ = &move;
|
|
407
409
|
|
|
408
410
|
if (!try beforeMove(battle, player, move, options)) return null;
|
|
409
411
|
|
|
@@ -565,7 +567,7 @@ fn resetCant(volatiles: *align(8) Volatiles) void {
|
|
|
565
567
|
|
|
566
568
|
pub fn canMove(battle: anytype, player: Player, state: *State, options: anytype) !bool {
|
|
567
569
|
var side = battle.side(player);
|
|
568
|
-
|
|
570
|
+
const volatiles = &side.active.volatiles;
|
|
569
571
|
|
|
570
572
|
// FIXME: pass in target to avoid lookup?
|
|
571
573
|
const target = if (Move.get(state.move).target == .Self) player else player.foe();
|
|
@@ -997,7 +999,6 @@ fn betweenTurns(battle: anytype, mslot: u4, options: anytype) !?Result {
|
|
|
997
999
|
|
|
998
1000
|
// Weather
|
|
999
1001
|
if (battle.field.weather != .None) {
|
|
1000
|
-
assert(battle.field.weather_duration > 0);
|
|
1001
1002
|
battle.field.weather_duration -= 1;
|
|
1002
1003
|
|
|
1003
1004
|
if (battle.field.weather_duration == 0) {
|
|
@@ -1056,7 +1057,6 @@ fn betweenTurns(battle: anytype, mslot: u4, options: anytype) !?Result {
|
|
|
1056
1057
|
var volatiles = &side.active.volatiles;
|
|
1057
1058
|
|
|
1058
1059
|
if (volatiles.PerishSong) {
|
|
1059
|
-
assert(volatiles.perish_song > 0);
|
|
1060
1060
|
volatiles.perish_song -= 1;
|
|
1061
1061
|
|
|
1062
1062
|
assert(volatiles.perish_song < 3);
|
|
@@ -1086,7 +1086,7 @@ fn betweenTurns(battle: anytype, mslot: u4, options: anytype) !?Result {
|
|
|
1086
1086
|
|
|
1087
1087
|
// Mystery Berry
|
|
1088
1088
|
inline for (players) |player| {
|
|
1089
|
-
|
|
1089
|
+
const stored = battle.side(player).stored();
|
|
1090
1090
|
|
|
1091
1091
|
if (stored.item == .MysteryBerry) {
|
|
1092
1092
|
// TODO stored and active moves, transform, etc
|
|
@@ -1193,7 +1193,6 @@ fn betweenTurns(battle: anytype, mslot: u4, options: anytype) !?Result {
|
|
|
1193
1193
|
var volatiles = &side.active.volatiles;
|
|
1194
1194
|
|
|
1195
1195
|
if (volatiles.Encore) {
|
|
1196
|
-
assert(volatiles.encore > 0);
|
|
1197
1196
|
volatiles.encore -= 1;
|
|
1198
1197
|
|
|
1199
1198
|
if (volatiles.encore == 0 or side.active.move(mslot).pp == 0) {
|
|
@@ -1215,7 +1214,6 @@ fn updateSideCondition(
|
|
|
1215
1214
|
) !void {
|
|
1216
1215
|
var side = battle.side(player);
|
|
1217
1216
|
if (@field(side.conditions, key)) {
|
|
1218
|
-
assert(@field(side.conditions, value) > 0);
|
|
1219
1217
|
@field(side.conditions, value) -= 1;
|
|
1220
1218
|
|
|
1221
1219
|
if (@field(side.conditions, value) == 0) {
|
|
@@ -1325,7 +1323,6 @@ pub const Effects = struct {
|
|
|
1325
1323
|
|
|
1326
1324
|
if (!volatiles.Bide) return;
|
|
1327
1325
|
|
|
1328
|
-
assert(volatiles.attacks > 0);
|
|
1329
1326
|
// if (options.calc.modify(player, .attacking)) |extend| {
|
|
1330
1327
|
// if (!extend) volatiles.attacks = 0;
|
|
1331
1328
|
// } else {
|
|
@@ -1478,8 +1475,8 @@ pub const Effects = struct {
|
|
|
1478
1475
|
side.stored().hp -= @max(side.stored().stats.hp / 2, 1);
|
|
1479
1476
|
try options.log.damage(.{ ident, side.stored(), .Curse });
|
|
1480
1477
|
} else {
|
|
1481
|
-
|
|
1482
|
-
|
|
1478
|
+
const stats = &side.active.stats;
|
|
1479
|
+
const boosts = &side.active.boosts;
|
|
1483
1480
|
|
|
1484
1481
|
const max_atk = boosts.atk == 6 or stats.atk == MAX_STAT_VALUE;
|
|
1485
1482
|
const max_def = boosts.def == 6 or stats.def == MAX_STAT_VALUE;
|
|
@@ -2185,11 +2182,10 @@ pub const Effects = struct {
|
|
|
2185
2182
|
}
|
|
2186
2183
|
|
|
2187
2184
|
pub fn damage(battle: anytype, player: Player, state: *State, _: anytype) !void {
|
|
2188
|
-
|
|
2189
|
-
var volatiles = &side.active.volatiles;
|
|
2185
|
+
const side = battle.side(player);
|
|
2190
2186
|
|
|
2191
|
-
assert(volatiles.Rage);
|
|
2192
|
-
state.damage *|= (volatiles.rage +| 1);
|
|
2187
|
+
assert(side.active.volatiles.Rage);
|
|
2188
|
+
state.damage *|= (side.active.volatiles.rage +| 1);
|
|
2193
2189
|
}
|
|
2194
2190
|
};
|
|
2195
2191
|
|
|
@@ -2541,8 +2537,8 @@ pub const Effects = struct {
|
|
|
2541
2537
|
pub fn allStatUpChance(battle: anytype, player: Player, state: *State, options: anytype) !void {
|
|
2542
2538
|
var side = battle.side(player);
|
|
2543
2539
|
|
|
2544
|
-
|
|
2545
|
-
|
|
2540
|
+
const stats = &side.active.stats;
|
|
2541
|
+
const boosts = &side.active.boosts;
|
|
2546
2542
|
|
|
2547
2543
|
if (!state.proc) return;
|
|
2548
2544
|
inline for (STATS, STAT_UP_REASONS) |s, r| {
|
|
@@ -2563,7 +2559,7 @@ pub const Effects = struct {
|
|
|
2563
2559
|
|
|
2564
2560
|
if (state.miss) return log.fail(.{ ident, .None });
|
|
2565
2561
|
|
|
2566
|
-
|
|
2562
|
+
const stats = &side.active.stats;
|
|
2567
2563
|
var boosts = &side.active.boosts;
|
|
2568
2564
|
|
|
2569
2565
|
const move = Move.get(state.move);
|
|
@@ -2634,7 +2630,7 @@ pub const Effects = struct {
|
|
|
2634
2630
|
|
|
2635
2631
|
const fail = foe.active.volatiles.Substitute or state.miss or !state.proc;
|
|
2636
2632
|
|
|
2637
|
-
|
|
2633
|
+
const stats = &foe.active.stats;
|
|
2638
2634
|
var boosts = &foe.active.boosts;
|
|
2639
2635
|
|
|
2640
2636
|
const move = Move.get(state.move);
|
|
@@ -2718,9 +2714,9 @@ fn unmodifiedStats(battle: anytype, side: *Side) *Stats(u16) {
|
|
|
2718
2714
|
}
|
|
2719
2715
|
|
|
2720
2716
|
fn recomputeStats(battle: anytype, side: *Side) void {
|
|
2721
|
-
|
|
2717
|
+
const stats = unmodifiedStats(battle, side);
|
|
2722
2718
|
inline for (STATS) |s| {
|
|
2723
|
-
|
|
2719
|
+
const mod = STAT_BOOSTS[@as(u4, @intCast(@as(i8, @field(side.active.boosts, s)) + 6))];
|
|
2724
2720
|
const val = @field(stats, s) * mod[0] / mod[1];
|
|
2725
2721
|
@field(side.active.stats, s) = @max(1, @min(MAX_STAT_VALUE, val));
|
|
2726
2722
|
}
|
|
@@ -2743,7 +2739,7 @@ fn boostStat(
|
|
|
2743
2739
|
n: u2,
|
|
2744
2740
|
) !void {
|
|
2745
2741
|
@field(boosts, s) = @intCast(@min(6, @as(i8, @field(boosts, s)) + n));
|
|
2746
|
-
|
|
2742
|
+
const mod = STAT_BOOSTS[@as(u4, @intCast(@as(i8, @field(boosts, s)) + 6))];
|
|
2747
2743
|
const stat = @field(unmodifiedStats(battle, side), s);
|
|
2748
2744
|
@field(stats, s) = @min(MAX_STAT_VALUE, stat * mod[0] / mod[1]);
|
|
2749
2745
|
if (comptime std.mem.eql(u8, s, "atk")) {
|
|
@@ -2766,7 +2762,7 @@ fn unboostStat(
|
|
|
2766
2762
|
n: u2,
|
|
2767
2763
|
) !void {
|
|
2768
2764
|
@field(boosts, s) = @intCast(@max(-6, @as(i8, @field(boosts, s)) - n));
|
|
2769
|
-
|
|
2765
|
+
const mod = STAT_BOOSTS[@as(u4, @intCast(@as(i8, @field(boosts, s)) + 6))];
|
|
2770
2766
|
const stat = @field(unmodifiedStats(battle, side), s);
|
|
2771
2767
|
@field(stats, s) = @max(1, stat * mod[0] / mod[1]);
|
|
2772
2768
|
if (comptime std.mem.eql(u8, s, "atk")) {
|
|
@@ -3467,7 +3463,7 @@ pub fn choices(battle: anytype, player: Player, request: Choice.Type, out: []Cho
|
|
|
3467
3463
|
.Move => {
|
|
3468
3464
|
const side = battle.side(player);
|
|
3469
3465
|
|
|
3470
|
-
|
|
3466
|
+
const active = &side.active;
|
|
3471
3467
|
const stored = side.stored();
|
|
3472
3468
|
|
|
3473
3469
|
// While players are not given any input options on the cartridge in these cases,
|