@pkmn/engine 0.1.0-dev.ce4c0b2a → 0.1.0-dev.d127cb34
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 -1
- package/README.md +23 -15
- package/build/pkg/addon/browser.d.ts +1 -1
- package/build/pkg/addon/browser.js +6 -2
- package/build/pkg/addon/browser.js.map +1 -1
- package/build/pkg/addon/node.js +22 -8
- package/build/pkg/addon/node.js.map +1 -1
- package/build/pkg/addon/wasm.d.ts +2 -0
- package/build/pkg/addon/wasm.js +53 -0
- package/build/pkg/addon/wasm.js.map +1 -0
- package/build/pkg/addon.d.ts +25 -5
- package/build/pkg/addon.js +8 -17
- 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.js.map +1 -1
- package/build/pkg/gen1.d.ts +15 -18
- package/build/pkg/gen1.js +28 -19
- package/build/pkg/gen1.js.map +1 -1
- package/build/pkg/index.d.ts +37 -100
- package/build/pkg/index.js +23 -75
- package/build/pkg/index.js.map +1 -1
- package/build/pkg/protocol.d.ts +11 -2
- package/build/pkg/protocol.js.map +1 -1
- package/build/tools/debug.js +56 -13
- package/build/tools/debug.js.map +1 -1
- package/build/tools/display/debug.jsx +19 -81
- package/build/tools/display/debug.jsx.map +1 -1
- package/build/tools/display/index.js +35 -15
- package/build/tools/display/index.js.map +1 -1
- package/build/tools/display/ui.jsx +27 -16
- package/build/tools/display/ui.jsx.map +1 -1
- package/build/tools/display/util.js +141 -2
- package/build/tools/display/util.js.map +1 -1
- package/build.zig +330 -245
- package/package.json +36 -128
- package/src/bin/install-pkmn-engine +25 -9
- package/src/lib/bindings/c.zig +201 -0
- package/src/lib/bindings/node.zig +117 -0
- package/src/lib/bindings/wasm.zig +51 -0
- package/src/lib/common/array.zig +5 -12
- package/src/lib/common/debug.zig +45 -34
- package/src/lib/common/js.zig +3 -9
- package/src/lib/common/optional.zig +26 -26
- package/src/lib/common/options.zig +2 -0
- package/src/lib/common/protocol.zig +228 -197
- package/src/lib/common/rational.zig +278 -285
- package/src/lib/common/rng.zig +1 -3
- package/src/lib/common/util.zig +34 -31
- package/src/lib/gen1/calc.zig +220 -195
- package/src/lib/gen1/chance.zig +184 -108
- 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 +3 -4
- package/src/lib/gen1/data.zig +12 -16
- package/src/lib/gen1/helpers.zig +35 -40
- package/src/lib/gen1/mechanics.zig +147 -127
- package/src/lib/gen2/calc.zig +12 -23
- package/src/lib/gen2/chance.zig +38 -26
- 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 +7 -5
- package/src/lib/gen2/data.zig +19 -22
- package/src/lib/gen2/generated.zig +18 -23
- package/src/lib/gen2/helpers.zig +32 -31
- package/src/lib/gen2/mechanics.zig +58 -55
- package/src/lib/napi.h +2 -0
- package/src/lib/node.zig +4 -121
- package/src/lib/pkmn.zig +98 -19
- package/src/lib/wasm.zig +9 -9
- package/src/tools/display/dom.ts +43 -31
- package/src/tools/display/ui.css +12 -9
package/src/lib/gen2/calc.zig
CHANGED
|
@@ -1,30 +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
|
-
|
|
26
|
-
const Int = if (@hasField(std.builtin.Type, "int")) .int else .Int;
|
|
27
|
-
const Enum = if (@hasField(std.builtin.Type, "enum")) .@"enum" else .Enum;
|
|
28
17
|
|
|
29
18
|
/// Information relevant to damage calculation that occured during a Generation II battle `update`.
|
|
30
19
|
pub const Summaries = extern struct {
|
|
@@ -99,8 +88,8 @@ pub const Calc = struct {
|
|
|
99
88
|
};
|
|
100
89
|
|
|
101
90
|
return if (switch (@typeInfo(@TypeOf(val))) {
|
|
102
|
-
|
|
103
|
-
|
|
91
|
+
.@"enum" => val != .None,
|
|
92
|
+
.int => val != 0,
|
|
104
93
|
else => unreachable,
|
|
105
94
|
}) val else null;
|
|
106
95
|
}
|
|
@@ -156,6 +145,6 @@ fn ReturnType(comptime field: Action.Field) type {
|
|
|
156
145
|
return ?(switch (field) {
|
|
157
146
|
.damages => u8,
|
|
158
147
|
.critical_hits => Optional(bool),
|
|
159
|
-
else =>
|
|
148
|
+
else => @FieldType(Action, @tagName(field)),
|
|
160
149
|
});
|
|
161
150
|
}
|
package/src/lib/gen2/chance.zig
CHANGED
|
@@ -27,10 +27,6 @@ const Type = data.Type;
|
|
|
27
27
|
const Effectiveness = data.Effectiveness;
|
|
28
28
|
const TriAttack = data.TriAttack;
|
|
29
29
|
|
|
30
|
-
const Int = if (@hasField(std.builtin.Type, "int")) .int else .Int;
|
|
31
|
-
const Enum = if (@hasField(std.builtin.Type, "enum")) .@"enum" else .Enum;
|
|
32
|
-
const Struct = if (@hasField(std.builtin.Type, "struct")) .@"struct" else .Struct;
|
|
33
|
-
|
|
34
30
|
/// Actions taken by a hypothetical "chance player" that convey information about which RNG events
|
|
35
31
|
/// were observed during a Generation II battle `update`. This can additionally be provided as input
|
|
36
32
|
/// to the `update` call to override the normal behavior of the RNG in order to force specific
|
|
@@ -57,15 +53,28 @@ pub const Actions = extern struct {
|
|
|
57
53
|
/// same shape if they have the same fields set (though those fields need not necessarily be
|
|
58
54
|
/// set to the same value).
|
|
59
55
|
pub fn matches(a: Actions, b: Actions) bool {
|
|
60
|
-
inline for (@
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
56
|
+
inline for (if (@hasField(@TypeOf(@typeInfo(Actions).@"struct"), "fields"))
|
|
57
|
+
@typeInfo(Actions).@"struct".fields
|
|
58
|
+
else
|
|
59
|
+
@typeInfo(Actions).@"struct".field_names) |player|
|
|
60
|
+
{
|
|
61
|
+
const player_name = if (@hasField(@TypeOf(player), "name"))
|
|
62
|
+
player.name
|
|
63
|
+
else
|
|
64
|
+
player;
|
|
65
|
+
inline for (if (@hasField(@TypeOf(@typeInfo(Action).@"struct"), "fields"))
|
|
66
|
+
@typeInfo(Action).@"struct".fields
|
|
67
|
+
else
|
|
68
|
+
@typeInfo(Action).@"struct".field_names) |field|
|
|
69
|
+
{
|
|
70
|
+
const field_name = if (@hasField(@TypeOf(field), "name")) field.name else field;
|
|
71
|
+
const a_val = @field(@field(a, player_name), field_name);
|
|
72
|
+
const b_val = @field(@field(b, player_name), field_name);
|
|
64
73
|
|
|
65
74
|
switch (@typeInfo(@TypeOf(a_val))) {
|
|
66
|
-
|
|
75
|
+
.@"enum" => if ((@intFromEnum(a_val) > 0) != (@intFromEnum(b_val) > 0))
|
|
67
76
|
return false,
|
|
68
|
-
|
|
77
|
+
.int => if ((a_val > 0) != (b_val > 0)) return false,
|
|
69
78
|
else => unreachable,
|
|
70
79
|
}
|
|
71
80
|
}
|
|
@@ -73,7 +82,7 @@ pub const Actions = extern struct {
|
|
|
73
82
|
return true;
|
|
74
83
|
}
|
|
75
84
|
|
|
76
|
-
pub fn fmt(self: Actions, writer:
|
|
85
|
+
pub fn fmt(self: Actions, writer: *std.Io.Writer, shape: bool) !void {
|
|
77
86
|
try writer.writeAll("<P1 = ");
|
|
78
87
|
try self.p1.fmt(writer, shape);
|
|
79
88
|
try writer.writeAll(", P2 = ");
|
|
@@ -81,8 +90,7 @@ pub const Actions = extern struct {
|
|
|
81
90
|
try writer.writeAll(">");
|
|
82
91
|
}
|
|
83
92
|
|
|
84
|
-
pub fn format(a: Actions,
|
|
85
|
-
_ = .{ f, o };
|
|
93
|
+
pub fn format(a: Actions, w: *std.Io.Writer) !void {
|
|
86
94
|
try fmt(a, w, false);
|
|
87
95
|
}
|
|
88
96
|
};
|
|
@@ -186,37 +194,41 @@ pub const Action = packed struct(u128) {
|
|
|
186
194
|
|
|
187
195
|
pub const Field = std.meta.FieldEnum(Action);
|
|
188
196
|
|
|
189
|
-
pub fn format(a: Action,
|
|
190
|
-
_ = .{ f, o };
|
|
197
|
+
pub fn format(a: Action, w: *std.Io.Writer) !void {
|
|
191
198
|
try fmt(a, w, false);
|
|
192
199
|
}
|
|
193
200
|
|
|
194
|
-
pub fn fmt(self: Action, writer:
|
|
201
|
+
pub fn fmt(self: Action, writer: *std.Io.Writer, shape: bool) !void {
|
|
195
202
|
try writer.writeByte('(');
|
|
196
203
|
var printed = false;
|
|
197
|
-
inline for (@
|
|
198
|
-
|
|
204
|
+
inline for (if (@hasField(@TypeOf(@typeInfo(Action).@"struct"), "fields"))
|
|
205
|
+
@typeInfo(Action).@"struct".fields
|
|
206
|
+
else
|
|
207
|
+
@typeInfo(Action).@"struct".field_names) |field|
|
|
208
|
+
{
|
|
209
|
+
const field_name = if (@hasField(@TypeOf(field), "name")) field.name else field;
|
|
210
|
+
const val = @field(self, field_name);
|
|
199
211
|
switch (@typeInfo(@TypeOf(val))) {
|
|
200
|
-
|
|
212
|
+
.@"enum" => if (val != .None) {
|
|
201
213
|
if (printed) try writer.writeAll(", ");
|
|
202
214
|
if (shape) {
|
|
203
|
-
try writer.print("{s}:?", .{
|
|
215
|
+
try writer.print("{s}:?", .{field_name});
|
|
204
216
|
} else if (@TypeOf(val) == Optional(bool)) {
|
|
205
217
|
try writer.print("{s}{s}", .{
|
|
206
218
|
if (val == .false) "!" else "",
|
|
207
|
-
|
|
219
|
+
field_name,
|
|
208
220
|
});
|
|
209
221
|
} else {
|
|
210
|
-
try writer.print("{s}:{s}", .{
|
|
222
|
+
try writer.print("{s}:{s}", .{ field_name, @tagName(val) });
|
|
211
223
|
}
|
|
212
224
|
printed = true;
|
|
213
225
|
},
|
|
214
|
-
|
|
226
|
+
.int => if (val != 0) {
|
|
215
227
|
if (printed) try writer.writeAll(", ");
|
|
216
228
|
if (shape) {
|
|
217
|
-
try writer.print("{s}:?", .{
|
|
229
|
+
try writer.print("{s}:?", .{field_name});
|
|
218
230
|
} else {
|
|
219
|
-
try writer.print("{s}:{d}", .{
|
|
231
|
+
try writer.print("{s}:{d}", .{ field_name, val });
|
|
220
232
|
}
|
|
221
233
|
printed = true;
|
|
222
234
|
},
|
|
@@ -786,7 +798,7 @@ pub fn expectProbability(r: anytype, p: u64, q: u64) !void {
|
|
|
786
798
|
|
|
787
799
|
r.reduce();
|
|
788
800
|
if (r.p != p or r.q != q) {
|
|
789
|
-
print("expected {d}/{d}, found {}\n", .{ p, q, r });
|
|
801
|
+
print("expected {d}/{d}, found {f}\n", .{ p, q, r });
|
|
790
802
|
return error.TestExpectedEqual;
|
|
791
803
|
}
|
|
792
804
|
}
|
|
@@ -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;
|
|
@@ -173,9 +172,12 @@ pub const Type = enum(u8) {
|
|
|
173
172
|
return CHART[@intFromEnum(t1)][@intFromEnum(t2)];
|
|
174
173
|
}
|
|
175
174
|
|
|
176
|
-
/// The precedence order of Type `
|
|
177
|
-
pub fn precedence(
|
|
178
|
-
return
|
|
175
|
+
/// The precedence order of Type `t1` vs. Type `t2`.
|
|
176
|
+
pub fn precedence(t1: Type, t2: Type) u8 {
|
|
177
|
+
// The Ice vs. Fire matchup is out of order - return a higher
|
|
178
|
+
// number than anything else so that it sorts last correctly
|
|
179
|
+
if (t1 == .Ice and t2 == .Fire) return 18;
|
|
180
|
+
return PRECEDENCE[@intFromEnum(t2)];
|
|
179
181
|
}
|
|
180
182
|
|
|
181
183
|
/// The internal index of this Type used by Present.
|
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;
|
|
@@ -61,7 +57,7 @@ pub fn Battle(comptime RNG: anytype) type {
|
|
|
61
57
|
turn: u16 = 0,
|
|
62
58
|
field: Field = .{},
|
|
63
59
|
|
|
64
|
-
_: [padding]u8 =
|
|
60
|
+
_: [padding]u8 = @splat(0),
|
|
65
61
|
|
|
66
62
|
pub fn side(self: anytype, player: Player) PointerType(@TypeOf(self), Side) {
|
|
67
63
|
assert(isPointerTo(self, Self));
|
|
@@ -104,13 +100,13 @@ pub const Weather = enum(u4) {
|
|
|
104
100
|
};
|
|
105
101
|
|
|
106
102
|
pub const Side = extern struct {
|
|
107
|
-
pokemon: [6]Pokemon =
|
|
103
|
+
pokemon: [6]Pokemon = @splat(.{}),
|
|
108
104
|
active: ActivePokemon align(8) = .{},
|
|
109
105
|
conditions: Conditions = .{},
|
|
110
106
|
// NB: wLastPlayerCounterMove / wLastEnemyCounterMove (wLastPlayerMove / wLastEnemyMove)
|
|
111
107
|
last_used_move: Move = .None,
|
|
112
108
|
|
|
113
|
-
_: [7]u8 =
|
|
109
|
+
_: [7]u8 = @splat(0),
|
|
114
110
|
|
|
115
111
|
const Conditions = packed struct(u32) {
|
|
116
112
|
Spikes: bool = false,
|
|
@@ -165,7 +161,7 @@ pub const Side = extern struct {
|
|
|
165
161
|
pub const ActivePokemon = extern struct {
|
|
166
162
|
volatiles: Volatiles align(4) = .{},
|
|
167
163
|
stats: Stats(u16) = .{},
|
|
168
|
-
moves: [4]MoveSlot =
|
|
164
|
+
moves: [4]MoveSlot = @splat(.{}),
|
|
169
165
|
boosts: Boosts = .{},
|
|
170
166
|
types: Types = .{},
|
|
171
167
|
species: Species = .None,
|
|
@@ -186,7 +182,7 @@ pub const ActivePokemon = extern struct {
|
|
|
186
182
|
|
|
187
183
|
pub const Pokemon = extern struct {
|
|
188
184
|
stats: Stats(u16) = .{},
|
|
189
|
-
moves: [4]MoveSlot =
|
|
185
|
+
moves: [4]MoveSlot = @splat(.{}),
|
|
190
186
|
types: Types = .{},
|
|
191
187
|
dvs: DVs = .{},
|
|
192
188
|
hp: u16 = 0,
|
|
@@ -453,8 +449,9 @@ test Types {
|
|
|
453
449
|
try expect(!Type.Steel.special());
|
|
454
450
|
try expect(Type.Dark.special());
|
|
455
451
|
|
|
456
|
-
try expectEqual(@as(u8, 3), Type.Water.
|
|
457
|
-
try expect(Type.
|
|
452
|
+
try expectEqual(@as(u8, 3), Type.precedence(.Water, .Water));
|
|
453
|
+
try expect(Type.precedence(.Poison, .Bug) > Type.precedence(.Poison, .Poison));
|
|
454
|
+
try expect(Type.precedence(.Ice, .Fire) > Type.precedence(.Ice, .Water));
|
|
458
455
|
|
|
459
456
|
try expectEqual(Effectiveness.Super, Type.effectiveness(.Ghost, .Psychic));
|
|
460
457
|
try expectEqual(Effectiveness.Super, Type.effectiveness(.Water, .Fire));
|
|
@@ -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,30 +1,21 @@
|
|
|
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
|
|
|
26
|
-
const Struct = if (@hasField(std.builtin.Type, "struct")) .@"struct" else .Struct;
|
|
27
|
-
|
|
28
19
|
pub const Options = struct {
|
|
29
20
|
cleric: bool = showdown,
|
|
30
21
|
};
|
|
@@ -81,7 +72,7 @@ pub fn prng(rand: *PSRNG) data.PRNG {
|
|
|
81
72
|
var carry: u8 = 0;
|
|
82
73
|
var div: u8 = 0;
|
|
83
74
|
|
|
84
|
-
var i:
|
|
75
|
+
var i: usize = 0;
|
|
85
76
|
while (i < seed.len) {
|
|
86
77
|
div = @intCast(timer >> 8);
|
|
87
78
|
// This is effectively @addWithOverflow but with three operands
|
|
@@ -149,15 +140,20 @@ pub const Pokemon = struct {
|
|
|
149
140
|
var pokemon = data.Pokemon{};
|
|
150
141
|
pokemon.species = p.species;
|
|
151
142
|
const species = Species.get(p.species);
|
|
152
|
-
inline for (@
|
|
153
|
-
|
|
143
|
+
inline for (if (@hasField(@TypeOf(@typeInfo(@TypeOf(pokemon.stats)).@"struct"), "fields"))
|
|
144
|
+
@typeInfo(@TypeOf(pokemon.stats)).@"struct".fields
|
|
145
|
+
else
|
|
146
|
+
@typeInfo(@TypeOf(pokemon.stats)).@"struct".field_names) |field|
|
|
147
|
+
{
|
|
148
|
+
const field_name = if (@hasField(@TypeOf(field), "name")) field.name else field;
|
|
149
|
+
const hp = comptime std.mem.eql(u8, field_name, "hp");
|
|
154
150
|
const spc =
|
|
155
|
-
comptime std.mem.eql(u8,
|
|
156
|
-
@field(pokemon.stats,
|
|
157
|
-
|
|
158
|
-
@field(species.stats,
|
|
159
|
-
if (hp) p.dvs.hp() else if (spc) p.dvs.spc else @field(p.dvs,
|
|
160
|
-
@field(p.stats,
|
|
151
|
+
comptime std.mem.eql(u8, field_name, "spa") or std.mem.eql(u8, field_name, "spd");
|
|
152
|
+
@field(pokemon.stats, field_name) = Stats(u16).calc(
|
|
153
|
+
field_name,
|
|
154
|
+
@field(species.stats, field_name),
|
|
155
|
+
if (hp) p.dvs.hp() else if (spc) p.dvs.spc else @field(p.dvs, field_name),
|
|
156
|
+
@field(p.stats, field_name),
|
|
161
157
|
p.level,
|
|
162
158
|
);
|
|
163
159
|
}
|
|
@@ -190,19 +186,24 @@ pub const Pokemon = struct {
|
|
|
190
186
|
|
|
191
187
|
var stats: Stats(u16) = .{};
|
|
192
188
|
const dvs = gen1.DVs.random(rand);
|
|
193
|
-
inline for (@
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
@
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
189
|
+
inline for (if (@hasField(@TypeOf(@typeInfo(@TypeOf(stats)).@"struct"), "fields"))
|
|
190
|
+
@typeInfo(@TypeOf(stats)).@"struct".fields
|
|
191
|
+
else
|
|
192
|
+
@typeInfo(@TypeOf(stats)).@"struct".field_names) |field|
|
|
193
|
+
{
|
|
194
|
+
const field_name = if (@hasField(@TypeOf(field), "name")) field.name else field;
|
|
195
|
+
const hp = std.mem.eql(u8, field_name, "hp");
|
|
196
|
+
const spc = std.mem.eql(u8, field_name, "spa") or std.mem.eql(u8, field_name, "spd");
|
|
197
|
+
@field(stats, field_name) = Stats(u16).calc(
|
|
198
|
+
field_name,
|
|
199
|
+
@field(species.stats, field_name),
|
|
200
|
+
if (hp) dvs.hp() else if (spc) dvs.spc else @field(dvs, field_name),
|
|
200
201
|
if (rand.chance(u8, 1, 20)) rand.range(u8, 0, 255 + 1) else 255,
|
|
201
202
|
lvl,
|
|
202
203
|
);
|
|
203
204
|
}
|
|
204
205
|
|
|
205
|
-
var ms
|
|
206
|
+
var ms: [4]MoveSlot = @splat(.{});
|
|
206
207
|
const n = if (rand.chance(u8, 1, 100)) rand.range(u4, 1, 3 + 1) else 4;
|
|
207
208
|
for (0..n) |i| {
|
|
208
209
|
var m: Move = .None;
|