@pkmn/engine 0.1.0-dev.f918c3bd → 0.1.0-dev.fb6653d6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +1 -3
- package/README.md +51 -23
- 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 +53 -0
- package/build/pkg/addon/wasm.js.map +1 -0
- package/build/pkg/addon.d.ts +25 -3
- package/build/pkg/addon.js +39 -71
- package/build/pkg/addon.js.map +1 -1
- package/build/pkg/data/ids.json +12 -12
- package/build/pkg/data/layout.json +17 -4
- package/build/pkg/data/protocol.json +23 -9
- package/build/pkg/data.d.ts +27 -5
- package/build/pkg/data.js.map +1 -1
- package/build/pkg/gen1.d.ts +13 -17
- package/build/pkg/gen1.js +8 -12
- package/build/pkg/gen1.js.map +1 -1
- package/build/pkg/index.d.ts +40 -91
- package/build/pkg/index.js +6 -63
- package/build/pkg/index.js.map +1 -1
- package/build/pkg/protocol.d.ts +20 -1
- package/build/pkg/protocol.js +109 -107
- package/build/pkg/protocol.js.map +1 -1
- package/build/tools/debug.js +36 -69
- 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 +142 -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 +303 -101
- package/package.json +61 -132
- package/src/bin/install-pkmn-engine +30 -20
- package/src/bin/pkmn-debug +1 -1
- package/src/lib/{binding → bindings}/node.zig +8 -21
- package/src/lib/bindings/wasm.zig +58 -0
- 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 +21 -10
- package/src/lib/common/options.zig +6 -0
- package/src/lib/common/protocol.zig +421 -393
- package/src/lib/common/rational.zig +131 -35
- package/src/lib/common/rng.zig +16 -9
- package/src/lib/common/util.zig +50 -1
- package/src/lib/gen1/calc.zig +687 -160
- package/src/lib/gen1/chance.zig +434 -307
- package/src/lib/gen1/data/moves.zig +26 -14
- package/src/lib/gen1/data/species.zig +4 -6
- package/src/lib/gen1/data/types.zig +7 -8
- package/src/lib/gen1/data.zig +44 -47
- package/src/lib/gen1/helpers.zig +91 -562
- package/src/lib/gen1/mechanics.zig +641 -557
- package/src/lib/gen2/calc.zig +153 -0
- package/src/lib/gen2/chance.zig +902 -0
- package/src/lib/gen2/data/items.zig +13 -21
- package/src/lib/gen2/data/moves.zig +67 -47
- package/src/lib/gen2/data/species.zig +2 -4
- package/src/lib/gen2/data/types.zig +134 -32
- package/src/lib/gen2/data.zig +56 -54
- package/src/lib/gen2/generated.zig +801 -0
- package/src/lib/gen2/helpers.zig +46 -25
- package/src/lib/gen2/mechanics.zig +2778 -362
- package/src/lib/node.zig +18 -0
- package/src/lib/pkmn.zig +37 -15
- package/src/lib/wasm.zig +17 -0
- 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/lib/binding/wasm.zig +0 -12
- package/src/lib/gen1/README.md +0 -894
- package/src/lib/gen2/README.md +0 -328
- package/src/test/display/pkmn.html.tmpl +0 -368
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
//! Code generated by `tools/generate` - manual edits will be overwritten
|
|
2
|
-
|
|
3
|
-
const std = @import("std");
|
|
1
|
+
//! Code generated by `tools/generate` - manual edits will be overwritten.
|
|
4
2
|
|
|
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;
|
|
@@ -14,15 +13,15 @@ const I = Effectiveness.Immune;
|
|
|
14
13
|
|
|
15
14
|
/// Representation of a Generation II type in Pokémon.
|
|
16
15
|
pub const Type = enum(u8) {
|
|
16
|
+
Ground,
|
|
17
|
+
Rock,
|
|
18
|
+
Steel,
|
|
17
19
|
Normal,
|
|
18
20
|
Fighting,
|
|
19
21
|
Flying,
|
|
20
22
|
Poison,
|
|
21
|
-
Ground,
|
|
22
|
-
Rock,
|
|
23
23
|
Bug,
|
|
24
24
|
Ghost,
|
|
25
|
-
Steel,
|
|
26
25
|
@"???",
|
|
27
26
|
Fire,
|
|
28
27
|
Water,
|
|
@@ -34,36 +33,36 @@ pub const Type = enum(u8) {
|
|
|
34
33
|
Dark,
|
|
35
34
|
|
|
36
35
|
const CHART: [18][18]Effectiveness = .{
|
|
37
|
-
[_]Effectiveness{ N,
|
|
38
|
-
[_]Effectiveness{
|
|
39
|
-
[_]Effectiveness{ N, S,
|
|
40
|
-
[_]Effectiveness{ N,
|
|
41
|
-
[_]Effectiveness{ N,
|
|
42
|
-
[_]Effectiveness{ N, R,
|
|
43
|
-
[_]Effectiveness{
|
|
44
|
-
[_]Effectiveness{
|
|
45
|
-
[_]Effectiveness{ N, N,
|
|
36
|
+
[_]Effectiveness{ N, S, S, N, N, I, S, R, N, N, S, N, R, S, N, N, N, N }, // Ground
|
|
37
|
+
[_]Effectiveness{ R, N, R, N, R, S, N, S, N, N, S, N, N, N, N, S, N, N }, // Rock
|
|
38
|
+
[_]Effectiveness{ N, S, R, N, N, N, N, N, N, N, R, R, N, R, N, S, N, N }, // Steel
|
|
39
|
+
[_]Effectiveness{ N, R, R, N, N, N, N, N, I, N, N, N, N, N, N, N, N, N }, // Normal
|
|
40
|
+
[_]Effectiveness{ N, S, S, S, N, R, R, R, I, N, N, N, N, N, R, S, N, S }, // Fighting
|
|
41
|
+
[_]Effectiveness{ N, R, R, N, S, N, N, S, N, N, N, N, S, R, N, N, N, N }, // Flying
|
|
42
|
+
[_]Effectiveness{ R, R, I, N, N, N, R, N, R, N, N, N, S, N, N, N, N, N }, // Poison
|
|
43
|
+
[_]Effectiveness{ N, N, R, N, R, R, R, N, R, N, R, N, S, N, S, N, N, S }, // Bug
|
|
44
|
+
[_]Effectiveness{ N, N, R, I, N, N, N, N, S, N, N, N, N, N, S, N, N, R }, // Ghost
|
|
46
45
|
[_]Effectiveness{ N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N }, // ???
|
|
47
|
-
[_]Effectiveness{ N,
|
|
48
|
-
[_]Effectiveness{
|
|
49
|
-
[_]Effectiveness{
|
|
50
|
-
[_]Effectiveness{
|
|
51
|
-
[_]Effectiveness{ N,
|
|
52
|
-
[_]Effectiveness{
|
|
53
|
-
[_]Effectiveness{ N, N,
|
|
54
|
-
[_]Effectiveness{ N, R, N,
|
|
46
|
+
[_]Effectiveness{ N, R, S, N, N, N, N, S, N, N, R, R, S, N, N, S, R, N }, // Fire
|
|
47
|
+
[_]Effectiveness{ S, S, N, N, N, N, N, N, N, N, S, R, R, N, N, N, R, N }, // Water
|
|
48
|
+
[_]Effectiveness{ S, S, R, N, N, R, R, R, N, N, R, S, R, N, N, N, R, N }, // Grass
|
|
49
|
+
[_]Effectiveness{ I, N, N, N, N, S, N, N, N, N, N, S, R, R, N, N, R, N }, // Electric
|
|
50
|
+
[_]Effectiveness{ N, N, R, N, S, N, S, N, N, N, N, N, N, N, R, N, N, I }, // Psychic
|
|
51
|
+
[_]Effectiveness{ S, N, R, N, N, S, N, N, N, N, R, R, S, N, N, R, S, N }, // Ice
|
|
52
|
+
[_]Effectiveness{ N, N, R, N, N, N, N, N, N, N, N, N, N, N, N, N, S, N }, // Dragon
|
|
53
|
+
[_]Effectiveness{ N, N, R, N, R, N, N, N, S, N, N, N, N, N, S, N, N, R }, // Dark
|
|
55
54
|
};
|
|
56
55
|
|
|
57
56
|
const PRECEDENCE = [_]u8{
|
|
57
|
+
9, // Ground
|
|
58
|
+
13, // Rock
|
|
59
|
+
17, // Steel
|
|
58
60
|
1, // Normal
|
|
59
61
|
7, // Fighting
|
|
60
62
|
10, // Flying
|
|
61
63
|
8, // Poison
|
|
62
|
-
9, // Ground
|
|
63
|
-
13, // Rock
|
|
64
64
|
12, // Bug
|
|
65
65
|
14, // Ghost
|
|
66
|
-
17, // Steel
|
|
67
66
|
0, // ???
|
|
68
67
|
2, // Fire
|
|
69
68
|
3, // Water
|
|
@@ -75,29 +74,126 @@ pub const Type = enum(u8) {
|
|
|
75
74
|
16, // Dark
|
|
76
75
|
};
|
|
77
76
|
|
|
77
|
+
const INDEXES = [_]u8{
|
|
78
|
+
4, // Ground
|
|
79
|
+
5, // Rock
|
|
80
|
+
9, // Steel
|
|
81
|
+
0, // Normal
|
|
82
|
+
1, // Fighting
|
|
83
|
+
2, // Flying
|
|
84
|
+
3, // Poison
|
|
85
|
+
7, // Bug
|
|
86
|
+
8, // Ghost
|
|
87
|
+
19, // ???
|
|
88
|
+
20, // Fire
|
|
89
|
+
21, // Water
|
|
90
|
+
22, // Grass
|
|
91
|
+
23, // Electric
|
|
92
|
+
24, // Psychic
|
|
93
|
+
25, // Ice
|
|
94
|
+
26, // Dragon
|
|
95
|
+
27, // Dark
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
const CONVERSION_2 = [_]Type{
|
|
99
|
+
.Normal,
|
|
100
|
+
.Fighting,
|
|
101
|
+
.Flying,
|
|
102
|
+
.Poison,
|
|
103
|
+
.Ground,
|
|
104
|
+
.Rock,
|
|
105
|
+
.@"???", // placeholder
|
|
106
|
+
.Bug,
|
|
107
|
+
.Ghost,
|
|
108
|
+
.Steel,
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
const HIDDEN_POWER = [_]Type{
|
|
112
|
+
.Fighting,
|
|
113
|
+
.Flying,
|
|
114
|
+
.Poison,
|
|
115
|
+
.Ground,
|
|
116
|
+
.Rock,
|
|
117
|
+
.Bug,
|
|
118
|
+
.Ghost,
|
|
119
|
+
.Steel,
|
|
120
|
+
.Fire,
|
|
121
|
+
.Water,
|
|
122
|
+
.Grass,
|
|
123
|
+
.Electric,
|
|
124
|
+
.Psychic,
|
|
125
|
+
.Ice,
|
|
126
|
+
.Dragon,
|
|
127
|
+
.Dark,
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
/// Order of Pokémon Showdown's types.
|
|
131
|
+
pub const SHOWDOWN = [_]Type{
|
|
132
|
+
.Fire,
|
|
133
|
+
.Ice,
|
|
134
|
+
.Steel,
|
|
135
|
+
.Electric,
|
|
136
|
+
.Ghost,
|
|
137
|
+
.Grass,
|
|
138
|
+
.Dark,
|
|
139
|
+
.Bug,
|
|
140
|
+
.Dragon,
|
|
141
|
+
.Fighting,
|
|
142
|
+
.Flying,
|
|
143
|
+
.Ground,
|
|
144
|
+
.Normal,
|
|
145
|
+
.Poison,
|
|
146
|
+
.Psychic,
|
|
147
|
+
.Rock,
|
|
148
|
+
.Water,
|
|
149
|
+
.@"???",
|
|
150
|
+
};
|
|
151
|
+
|
|
78
152
|
comptime {
|
|
79
153
|
assert(@bitSizeOf(Type) == 8);
|
|
80
154
|
assert(@sizeOf(@TypeOf(CHART)) == 324);
|
|
81
155
|
assert(@sizeOf(@TypeOf(PRECEDENCE)) == 18);
|
|
156
|
+
assert(@sizeOf(@TypeOf(INDEXES)) == 18);
|
|
157
|
+
assert(@sizeOf(@TypeOf(CONVERSION_2)) == 10);
|
|
158
|
+
assert(@sizeOf(@TypeOf(HIDDEN_POWER)) == 16);
|
|
159
|
+
assert(@sizeOf(@TypeOf(SHOWDOWN)) == 18);
|
|
82
160
|
}
|
|
83
161
|
|
|
84
162
|
/// The number of types in this generation.
|
|
85
163
|
pub const size = 18;
|
|
86
164
|
|
|
87
165
|
/// Whether or not this type is considered to be special as opposed to physical.
|
|
88
|
-
pub
|
|
166
|
+
pub fn special(self: Type) bool {
|
|
89
167
|
return @intFromEnum(self) >= @intFromEnum(Type.Fire);
|
|
90
168
|
}
|
|
91
169
|
|
|
92
170
|
/// The `Effectiveness` of type `t2` vs. type `t1`.
|
|
93
|
-
pub
|
|
171
|
+
pub fn effectiveness(t1: Type, t2: Type) Effectiveness {
|
|
94
172
|
return CHART[@intFromEnum(t1)][@intFromEnum(t2)];
|
|
95
173
|
}
|
|
96
174
|
|
|
97
|
-
/// The precedence order of
|
|
98
|
-
pub
|
|
175
|
+
/// The precedence order of Type `type`.
|
|
176
|
+
pub fn precedence(self: Type) u8 {
|
|
99
177
|
return PRECEDENCE[@intFromEnum(self)];
|
|
100
178
|
}
|
|
179
|
+
|
|
180
|
+
/// The internal index of this Type used by Present.
|
|
181
|
+
pub fn present(self: Type) u8 {
|
|
182
|
+
return INDEXES[@intFromEnum(self)];
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/// The Type corresponding to a random roll of `num` for Conversion 2.
|
|
186
|
+
pub fn conversion2(num: u8) Type {
|
|
187
|
+
assert(num != 6);
|
|
188
|
+
assert(num < 10 or num >= 20);
|
|
189
|
+
assert(num <= 27);
|
|
190
|
+
return if (num < 10) CONVERSION_2[num] else @enumFromInt(num - 10);
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
/// The Type corresponding to a Hidden Power `index`.
|
|
194
|
+
pub fn hiddenPower(index: u8) Type {
|
|
195
|
+
return HIDDEN_POWER[index];
|
|
196
|
+
}
|
|
101
197
|
};
|
|
102
198
|
|
|
103
199
|
/// Representation of a Pokémon's typing.
|
|
@@ -112,12 +208,18 @@ pub const Types = extern struct {
|
|
|
112
208
|
}
|
|
113
209
|
|
|
114
210
|
/// Whether this typing is immune to type `t`.
|
|
115
|
-
pub
|
|
211
|
+
pub fn immune(self: Types, t: Type) bool {
|
|
116
212
|
return t.effectiveness(self.type1) == I or t.effectiveness(self.type2) == I;
|
|
117
213
|
}
|
|
118
214
|
|
|
119
215
|
/// Whether this typing includes type `t`.
|
|
120
|
-
pub
|
|
216
|
+
pub fn includes(self: Types, t: Type) bool {
|
|
121
217
|
return self.type1 == t or self.type2 == t;
|
|
122
218
|
}
|
|
219
|
+
|
|
220
|
+
/// Whether this typing is immune to damage from Sandstorm.
|
|
221
|
+
pub fn sandstormImmune(self: Types) bool {
|
|
222
|
+
return @intFromEnum(self.type1) <= @intFromEnum(Type.Steel) or
|
|
223
|
+
@intFromEnum(self.type2) <= @intFromEnum(Type.Steel);
|
|
224
|
+
}
|
|
123
225
|
};
|
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;
|
|
@@ -45,12 +41,14 @@ const Player = data.Player;
|
|
|
45
41
|
const Result = data.Result;
|
|
46
42
|
|
|
47
43
|
const PointerType = util.PointerType;
|
|
44
|
+
const isPointerTo = util.isPointerTo;
|
|
48
45
|
|
|
49
46
|
const showdown = pkmn.options.showdown;
|
|
50
47
|
|
|
51
48
|
pub const PRNG = rng.PRNG(2);
|
|
52
49
|
|
|
53
50
|
pub fn Battle(comptime RNG: anytype) type {
|
|
51
|
+
const padding = if (!showdown) 3 else 5;
|
|
54
52
|
return extern struct {
|
|
55
53
|
const Self = @This();
|
|
56
54
|
|
|
@@ -59,20 +57,19 @@ pub fn Battle(comptime RNG: anytype) type {
|
|
|
59
57
|
turn: u16 = 0,
|
|
60
58
|
field: Field = .{},
|
|
61
59
|
|
|
62
|
-
|
|
63
|
-
_2: if (!showdown) u16 else u32 = 0,
|
|
60
|
+
_: [padding]u8 = .{0} ** padding,
|
|
64
61
|
|
|
65
|
-
pub
|
|
66
|
-
assert(
|
|
62
|
+
pub fn side(self: anytype, player: Player) PointerType(@TypeOf(self), Side) {
|
|
63
|
+
assert(isPointerTo(self, Self));
|
|
67
64
|
return &self.sides[@intFromEnum(player)];
|
|
68
65
|
}
|
|
69
66
|
|
|
70
|
-
pub
|
|
71
|
-
assert(
|
|
67
|
+
pub fn foe(self: anytype, player: Player) PointerType(@TypeOf(self), Side) {
|
|
68
|
+
assert(isPointerTo(self, Self));
|
|
72
69
|
return &self.sides[@intFromEnum(player.foe())];
|
|
73
70
|
}
|
|
74
71
|
|
|
75
|
-
pub
|
|
72
|
+
pub fn active(self: *const Self, player: Player) ID {
|
|
76
73
|
return player.ident(@intCast(self.side(player).pokemon[0].position));
|
|
77
74
|
}
|
|
78
75
|
|
|
@@ -106,13 +103,11 @@ pub const Side = extern struct {
|
|
|
106
103
|
pokemon: [6]Pokemon = [_]Pokemon{.{}} ** 6,
|
|
107
104
|
active: ActivePokemon align(8) = .{},
|
|
108
105
|
conditions: Conditions = .{},
|
|
109
|
-
_1: u32 = 0,
|
|
110
|
-
_2: u16 = 0,
|
|
111
|
-
// NB: wCurPlayerMove / wCurEnemyMove (?)
|
|
112
|
-
_3: u8 = 0,
|
|
113
106
|
// NB: wLastPlayerCounterMove / wLastEnemyCounterMove (wLastPlayerMove / wLastEnemyMove)
|
|
114
107
|
last_used_move: Move = .None,
|
|
115
108
|
|
|
109
|
+
_: [7]u8 = .{0} ** 7,
|
|
110
|
+
|
|
116
111
|
const Conditions = packed struct(u32) {
|
|
117
112
|
Spikes: bool = false,
|
|
118
113
|
Safeguard: bool = false,
|
|
@@ -135,27 +130,27 @@ pub const Side = extern struct {
|
|
|
135
130
|
assert(@sizeOf(Side) == 248);
|
|
136
131
|
}
|
|
137
132
|
|
|
138
|
-
pub
|
|
139
|
-
assert(
|
|
133
|
+
pub fn get(self: anytype, slot: u8) PointerType(@TypeOf(self), Pokemon) {
|
|
134
|
+
assert(isPointerTo(self, Side));
|
|
140
135
|
assert(slot > 0 and slot <= 6);
|
|
141
136
|
const id = self.pokemon[slot - 1].position;
|
|
142
137
|
assert(id > 0 and id <= 6);
|
|
143
138
|
return &self.pokemon[id - 1];
|
|
144
139
|
}
|
|
145
140
|
|
|
146
|
-
pub
|
|
147
|
-
assert(
|
|
141
|
+
pub fn stored(self: anytype) PointerType(@TypeOf(self), Pokemon) {
|
|
142
|
+
assert(isPointerTo(self, Side));
|
|
148
143
|
return self.get(1);
|
|
149
144
|
}
|
|
150
145
|
|
|
151
|
-
pub
|
|
146
|
+
pub fn lastMove(self: anytype, encore: bool) Move {
|
|
152
147
|
assert(self.last_used_move != .None or !self.active.volatiles.dirty);
|
|
153
148
|
if (encore) return self.last_used_move;
|
|
154
149
|
return if (self.active.volatiles.dirty) .None else self.last_used_move;
|
|
155
150
|
}
|
|
156
151
|
|
|
157
152
|
// TODO
|
|
158
|
-
// pub
|
|
153
|
+
// pub fn useMove(self: anytype) void {
|
|
159
154
|
// assert(side.last_selected_move != .None);
|
|
160
155
|
// self.last_used_move = side.last_selected_move;
|
|
161
156
|
// self.active.volatiles.dirty = false;
|
|
@@ -177,8 +172,8 @@ pub const ActivePokemon = extern struct {
|
|
|
177
172
|
assert(@sizeOf(ActivePokemon) == 44);
|
|
178
173
|
}
|
|
179
174
|
|
|
180
|
-
pub
|
|
181
|
-
assert(
|
|
175
|
+
pub fn move(self: anytype, mslot: u8) PointerType(@TypeOf(self), MoveSlot) {
|
|
176
|
+
assert(isPointerTo(self, Pokemon));
|
|
182
177
|
assert(mslot > 0 and mslot <= 4);
|
|
183
178
|
assert(self.moves[mslot - 1].id != .None);
|
|
184
179
|
return &self.moves[mslot - 1];
|
|
@@ -202,8 +197,8 @@ pub const Pokemon = extern struct {
|
|
|
202
197
|
assert(@sizeOf(Pokemon) == 32);
|
|
203
198
|
}
|
|
204
199
|
|
|
205
|
-
pub
|
|
206
|
-
assert(
|
|
200
|
+
pub fn move(self: anytype, mslot: u8) PointerType(@TypeOf(self), MoveSlot) {
|
|
201
|
+
assert(isPointerTo(self, Pokemon));
|
|
207
202
|
assert(mslot > 0 and mslot <= 4);
|
|
208
203
|
assert(self.moves[mslot - 1].id != .None);
|
|
209
204
|
return &self.moves[mslot - 1];
|
|
@@ -227,7 +222,7 @@ pub const DVs = packed struct(u16) {
|
|
|
227
222
|
return .{ .gender = g, .pow = p, .type = t };
|
|
228
223
|
}
|
|
229
224
|
|
|
230
|
-
pub
|
|
225
|
+
pub fn power(dvs: DVs) u8 {
|
|
231
226
|
return @as(u8, dvs.pow) + 30;
|
|
232
227
|
}
|
|
233
228
|
|
|
@@ -241,9 +236,8 @@ pub const DVs = packed struct(u16) {
|
|
|
241
236
|
};
|
|
242
237
|
const p: u6 = @intCast(1 + ((5 * @as(u8, (dvs.atk & 0b1000) | ((dvs.def & 0b1000)) >> 1 |
|
|
243
238
|
((dvs.spe & 0b1000)) >> 2 | ((dvs.spc & 0b1000)) >> 3) + (dvs.spc & 0b0011)) >> 1));
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
return .{ .gender = g, .pow = p, .type = @enumFromInt(t) };
|
|
239
|
+
const t = @as(u8, dvs.def & 0b0011) + (@as(u8, dvs.atk & 0b0011) << 2);
|
|
240
|
+
return .{ .gender = g, .pow = p, .type = Type.hiddenPower(t) };
|
|
247
241
|
}
|
|
248
242
|
};
|
|
249
243
|
|
|
@@ -282,6 +276,9 @@ pub const MoveSlot = extern struct {
|
|
|
282
276
|
|
|
283
277
|
pub const Status = gen1.Status;
|
|
284
278
|
|
|
279
|
+
/// TODO
|
|
280
|
+
pub const TriAttack = enum(u2) { PAR, FRZ, BRN };
|
|
281
|
+
|
|
285
282
|
pub const Volatiles = packed struct(u128) {
|
|
286
283
|
Bide: bool = false,
|
|
287
284
|
Thrashing: bool = false,
|
|
@@ -314,18 +311,23 @@ pub const Volatiles = packed struct(u128) {
|
|
|
314
311
|
Encore: bool = false,
|
|
315
312
|
LockOn: bool = false,
|
|
316
313
|
DestinyBond: bool = false,
|
|
314
|
+
Trapped: bool = false,
|
|
317
315
|
|
|
318
|
-
trapped: bool = false,
|
|
319
316
|
switched: bool = false,
|
|
317
|
+
// TODO: replace with simply looking at Choice on Battle
|
|
320
318
|
switching: bool = false,
|
|
319
|
+
// TODO: simply store both last moves on side
|
|
321
320
|
dirty: bool = false,
|
|
322
321
|
|
|
323
322
|
frozen: bool = false,
|
|
324
|
-
|
|
323
|
+
minimized: bool = false,
|
|
324
|
+
_: u10 = 0,
|
|
325
|
+
// TODO: is this needed for unmodified stats?
|
|
326
|
+
transform: u4 = 0,
|
|
325
327
|
|
|
326
|
-
bind: u4 = 0,
|
|
327
328
|
bide: u16 = 0,
|
|
328
|
-
|
|
329
|
+
bind: Bind = .{},
|
|
330
|
+
disable: Disable = .{},
|
|
329
331
|
rage: u8 = 0,
|
|
330
332
|
substitute: u8 = 0,
|
|
331
333
|
toxic: u8 = 0,
|
|
@@ -337,7 +339,12 @@ pub const Volatiles = packed struct(u128) {
|
|
|
337
339
|
protect: u4 = 0,
|
|
338
340
|
attacks: u4 = 0, // bide/thrashing/rollout turns
|
|
339
341
|
|
|
340
|
-
const
|
|
342
|
+
const Bind = packed struct(u8) {
|
|
343
|
+
duration: u4 = 0,
|
|
344
|
+
reason: u4 = 0,
|
|
345
|
+
};
|
|
346
|
+
|
|
347
|
+
const Disable = packed struct(u8) {
|
|
341
348
|
move: u4 = 0,
|
|
342
349
|
duration: u4 = 0,
|
|
343
350
|
};
|
|
@@ -404,15 +411,10 @@ test Item {
|
|
|
404
411
|
try expectEqual(Type.Normal, Item.boost(.PolkadotBow).?);
|
|
405
412
|
try expectEqual(Type.Dark, Item.boost(.BlackGlasses).?);
|
|
406
413
|
|
|
407
|
-
try expect(!Item.
|
|
408
|
-
try expect(Item.
|
|
409
|
-
try expect(Item.
|
|
410
|
-
try expect(!Item.
|
|
411
|
-
|
|
412
|
-
try expect(!Item.berry(.LightBall));
|
|
413
|
-
try expect(Item.berry(.PSNCureBerry));
|
|
414
|
-
try expect(Item.berry(.GoldBerry));
|
|
415
|
-
try expect(!Item.berry(.MasterBall));
|
|
414
|
+
try expect(!Item.isMail(.UpGrade));
|
|
415
|
+
try expect(Item.isMail(.FlowerMail));
|
|
416
|
+
try expect(Item.isMail(.MirageMail));
|
|
417
|
+
try expect(!Item.isMail(.TownMap));
|
|
416
418
|
}
|
|
417
419
|
|
|
418
420
|
pub const Move = moves.Move;
|