@pkmn/engine 0.1.0-dev.bcb16a6c → 0.1.0-dev.bce6e8a5
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 +47 -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 +110 -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/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 +15 -18
- package/build/pkg/gen1.js +30 -21
- package/build/pkg/gen1.js.map +1 -1
- package/build/pkg/index.d.ts +42 -91
- package/build/pkg/index.js +23 -70
- 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 +53 -76
- package/build/tools/debug.js.map +1 -1
- package/build/tools/display/debug.jsx +152 -0
- package/build/tools/display/debug.jsx.map +1 -0
- package/build/tools/display/index.js +152 -0
- package/build/tools/display/index.js.map +1 -0
- package/build/tools/display/ui.jsx +359 -0
- package/build/tools/display/ui.jsx.map +1 -0
- package/build/tools/display/util.js +33 -0
- package/build/tools/display/util.js.map +1 -0
- package/build.zig +344 -101
- package/package.json +62 -132
- package/src/bin/install-pkmn-engine +31 -20
- package/src/bin/pkmn-debug +1 -1
- package/src/lib/bindings/c.zig +255 -0
- package/src/lib/{binding → bindings}/node.zig +8 -21
- package/src/lib/bindings/wasm.zig +59 -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 +17 -15
- package/src/lib/common/options.zig +6 -0
- package/src/lib/common/protocol.zig +414 -389
- 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 +430 -303
- 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 +6 -7
- package/src/lib/gen1/data.zig +44 -47
- package/src/lib/gen1/helpers.zig +91 -562
- package/src/lib/gen1/mechanics.zig +642 -565
- package/src/lib/gen2/calc.zig +153 -0
- package/src/lib/gen2/chance.zig +902 -0
- package/src/lib/gen2/data/items.zig +4 -6
- package/src/lib/gen2/data/moves.zig +34 -19
- package/src/lib/gen2/data/species.zig +2 -4
- package/src/lib/gen2/data/types.zig +13 -13
- package/src/lib/gen2/data.zig +45 -54
- package/src/lib/gen2/generated.zig +801 -0
- package/src/lib/gen2/helpers.zig +46 -25
- package/src/lib/gen2/mechanics.zig +2483 -452
- 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 +93 -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 -330
- package/src/test/display/pkmn.html.tmpl +0 -368
|
@@ -1,11 +1,9 @@
|
|
|
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 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.
|
|
@@ -216,14 +214,14 @@ pub const Item = enum(u8) {
|
|
|
216
214
|
pub const size = 196;
|
|
217
215
|
|
|
218
216
|
/// Returns a `Type` boosted by this item or `null` if the item is not a type-boosting item.
|
|
219
|
-
pub
|
|
217
|
+
pub fn boost(item: Item) ?Type {
|
|
220
218
|
assert(item != .None);
|
|
221
219
|
if (item == .PolkadotBow) return .Normal;
|
|
222
220
|
return if (@intFromEnum(item) <= 18) @enumFromInt(@intFromEnum(item) - 1) else null;
|
|
223
221
|
}
|
|
224
222
|
|
|
225
223
|
/// Whether or not this item is Mail.
|
|
226
|
-
pub
|
|
224
|
+
pub fn isMail(item: Item) bool {
|
|
227
225
|
assert(item != .None);
|
|
228
226
|
return @intFromEnum(item) > 60 and @intFromEnum(item) <= 70;
|
|
229
227
|
}
|
|
@@ -1,12 +1,10 @@
|
|
|
1
|
-
//! Code generated by `tools/generate` - manual edits will be overwritten
|
|
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
|
|
|
@@ -288,6 +286,8 @@ pub const Move = enum(u8) {
|
|
|
288
286
|
const Extra = packed struct(u8) {
|
|
289
287
|
/// Whether this move can be called via Metronome.
|
|
290
288
|
metronome: bool = true,
|
|
289
|
+
/// Whether this move can be called via Sleep Talk.
|
|
290
|
+
sleep_talk: bool = true,
|
|
291
291
|
/// Whether this move is considered to be "continuous".
|
|
292
292
|
continuous: bool = false,
|
|
293
293
|
/// Whether this move can hit a flying target.
|
|
@@ -295,7 +295,7 @@ pub const Move = enum(u8) {
|
|
|
295
295
|
/// Whether this move can hit an underground target.
|
|
296
296
|
underground: bool = false,
|
|
297
297
|
/// Protocol reason offset associated with this move.
|
|
298
|
-
protocol:
|
|
298
|
+
protocol: u3 = 0,
|
|
299
299
|
};
|
|
300
300
|
|
|
301
301
|
comptime {
|
|
@@ -410,7 +410,7 @@ pub const Move = enum(u8) {
|
|
|
410
410
|
.type = .Normal,
|
|
411
411
|
.accuracy = percent(75),
|
|
412
412
|
.target = .Foes,
|
|
413
|
-
.extra = .{ .continuous = true },
|
|
413
|
+
.extra = .{ .sleep_talk = false, .continuous = true },
|
|
414
414
|
},
|
|
415
415
|
// SwordsDance
|
|
416
416
|
.{
|
|
@@ -457,12 +457,12 @@ pub const Move = enum(u8) {
|
|
|
457
457
|
},
|
|
458
458
|
// Fly
|
|
459
459
|
.{
|
|
460
|
-
.effect = .
|
|
460
|
+
.effect = .FlyDig,
|
|
461
461
|
.bp = 70,
|
|
462
462
|
.type = .Flying,
|
|
463
463
|
.accuracy = percent(95),
|
|
464
464
|
.target = .Any,
|
|
465
|
-
.extra = .{ .continuous = true },
|
|
465
|
+
.extra = .{ .sleep_talk = false, .continuous = true },
|
|
466
466
|
},
|
|
467
467
|
// Bind
|
|
468
468
|
.{
|
|
@@ -936,12 +936,12 @@ pub const Move = enum(u8) {
|
|
|
936
936
|
},
|
|
937
937
|
// SolarBeam
|
|
938
938
|
.{
|
|
939
|
-
.effect = .
|
|
939
|
+
.effect = .SolarBeam,
|
|
940
940
|
.bp = 120,
|
|
941
941
|
.type = .Grass,
|
|
942
942
|
.accuracy = percent(100),
|
|
943
943
|
.target = .Other,
|
|
944
|
-
.extra = .{ .continuous = true },
|
|
944
|
+
.extra = .{ .sleep_talk = false, .continuous = true },
|
|
945
945
|
},
|
|
946
946
|
// PoisonPowder
|
|
947
947
|
.{
|
|
@@ -1065,11 +1065,12 @@ pub const Move = enum(u8) {
|
|
|
1065
1065
|
},
|
|
1066
1066
|
// Dig
|
|
1067
1067
|
.{
|
|
1068
|
-
.effect = .
|
|
1068
|
+
.effect = .FlyDig,
|
|
1069
1069
|
.bp = 60,
|
|
1070
1070
|
.type = .Ground,
|
|
1071
1071
|
.accuracy = percent(100),
|
|
1072
1072
|
.target = .Other,
|
|
1073
|
+
.extra = .{ .sleep_talk = false },
|
|
1073
1074
|
},
|
|
1074
1075
|
// Toxic
|
|
1075
1076
|
.{
|
|
@@ -1282,7 +1283,7 @@ pub const Move = enum(u8) {
|
|
|
1282
1283
|
.type = .Normal,
|
|
1283
1284
|
.accuracy = percent(100),
|
|
1284
1285
|
.target = .Self,
|
|
1285
|
-
.extra = .{ .continuous = true },
|
|
1286
|
+
.extra = .{ .sleep_talk = false, .continuous = true },
|
|
1286
1287
|
},
|
|
1287
1288
|
// Metronome
|
|
1288
1289
|
.{
|
|
@@ -1394,7 +1395,7 @@ pub const Move = enum(u8) {
|
|
|
1394
1395
|
.type = .Normal,
|
|
1395
1396
|
.accuracy = percent(100),
|
|
1396
1397
|
.target = .Other,
|
|
1397
|
-
.extra = .{ .continuous = true },
|
|
1398
|
+
.extra = .{ .sleep_talk = false, .continuous = true },
|
|
1398
1399
|
},
|
|
1399
1400
|
// SpikeCannon
|
|
1400
1401
|
.{
|
|
@@ -1500,7 +1501,7 @@ pub const Move = enum(u8) {
|
|
|
1500
1501
|
.type = .Flying,
|
|
1501
1502
|
.accuracy = percent(90),
|
|
1502
1503
|
.target = .Any,
|
|
1503
|
-
.extra = .{ .continuous = true },
|
|
1504
|
+
.extra = .{ .sleep_talk = false, .continuous = true },
|
|
1504
1505
|
},
|
|
1505
1506
|
// Transform
|
|
1506
1507
|
.{
|
|
@@ -2463,7 +2464,7 @@ pub const Move = enum(u8) {
|
|
|
2463
2464
|
FixedDamage,
|
|
2464
2465
|
FlameWheel,
|
|
2465
2466
|
FlinchChance,
|
|
2466
|
-
|
|
2467
|
+
FlyDig,
|
|
2467
2468
|
FocusEnergy,
|
|
2468
2469
|
ForceSwitch,
|
|
2469
2470
|
Foresight,
|
|
@@ -2526,7 +2527,7 @@ pub const Move = enum(u8) {
|
|
|
2526
2527
|
Sleep,
|
|
2527
2528
|
SleepTalk,
|
|
2528
2529
|
Snore,
|
|
2529
|
-
|
|
2530
|
+
SolarBeam,
|
|
2530
2531
|
SpAtkUp1,
|
|
2531
2532
|
SpDefDownChance,
|
|
2532
2533
|
SpDefUp2,
|
|
@@ -2559,7 +2560,7 @@ pub const Move = enum(u8) {
|
|
|
2559
2560
|
}
|
|
2560
2561
|
|
|
2561
2562
|
/// Whether this effect has a high critical rate.
|
|
2562
|
-
pub
|
|
2563
|
+
pub fn isHighCritical(effect: Effect) bool {
|
|
2563
2564
|
return effect == .HighCritical or effect == .RazorWind;
|
|
2564
2565
|
}
|
|
2565
2566
|
};
|
|
@@ -2847,8 +2848,22 @@ pub const Move = enum(u8) {
|
|
|
2847
2848
|
/// The number of Pokémon moves in this generation.
|
|
2848
2849
|
pub const size = 251;
|
|
2849
2850
|
|
|
2851
|
+
/// Pokémon moves that can be called by Metronome in this generation.
|
|
2852
|
+
pub const METRONOME = init: {
|
|
2853
|
+
var num = 0;
|
|
2854
|
+
var moves: [239]Move = undefined;
|
|
2855
|
+
for (1..Move.size + 1) |i| {
|
|
2856
|
+
if (Move.get(@enumFromInt(i)).extra.metronome) {
|
|
2857
|
+
moves[num] = @enumFromInt(i);
|
|
2858
|
+
num += 1;
|
|
2859
|
+
}
|
|
2860
|
+
}
|
|
2861
|
+
assert(num == moves.len);
|
|
2862
|
+
break :init moves;
|
|
2863
|
+
};
|
|
2864
|
+
|
|
2850
2865
|
/// Returns the `Data` corresponding to the move.
|
|
2851
|
-
pub
|
|
2866
|
+
pub fn get(id: Move) Data {
|
|
2852
2867
|
assert(id != .None);
|
|
2853
2868
|
return DATA[@intFromEnum(id) - 1];
|
|
2854
2869
|
}
|
|
@@ -1,11 +1,9 @@
|
|
|
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 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
|
-
//! 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;
|
|
@@ -164,27 +163,27 @@ pub const Type = enum(u8) {
|
|
|
164
163
|
pub const size = 18;
|
|
165
164
|
|
|
166
165
|
/// Whether or not this type is considered to be special as opposed to physical.
|
|
167
|
-
pub
|
|
166
|
+
pub fn special(self: Type) bool {
|
|
168
167
|
return @intFromEnum(self) >= @intFromEnum(Type.Fire);
|
|
169
168
|
}
|
|
170
169
|
|
|
171
170
|
/// The `Effectiveness` of type `t2` vs. type `t1`.
|
|
172
|
-
pub
|
|
171
|
+
pub fn effectiveness(t1: Type, t2: Type) Effectiveness {
|
|
173
172
|
return CHART[@intFromEnum(t1)][@intFromEnum(t2)];
|
|
174
173
|
}
|
|
175
174
|
|
|
176
175
|
/// The precedence order of Type `type`.
|
|
177
|
-
pub
|
|
176
|
+
pub fn precedence(self: Type) u8 {
|
|
178
177
|
return PRECEDENCE[@intFromEnum(self)];
|
|
179
178
|
}
|
|
180
179
|
|
|
181
180
|
/// The internal index of this Type used by Present.
|
|
182
|
-
pub
|
|
181
|
+
pub fn present(self: Type) u8 {
|
|
183
182
|
return INDEXES[@intFromEnum(self)];
|
|
184
183
|
}
|
|
185
184
|
|
|
186
185
|
/// The Type corresponding to a random roll of `num` for Conversion 2.
|
|
187
|
-
pub
|
|
186
|
+
pub fn conversion2(num: u8) Type {
|
|
188
187
|
assert(num != 6);
|
|
189
188
|
assert(num < 10 or num >= 20);
|
|
190
189
|
assert(num <= 27);
|
|
@@ -192,7 +191,7 @@ pub const Type = enum(u8) {
|
|
|
192
191
|
}
|
|
193
192
|
|
|
194
193
|
/// The Type corresponding to a Hidden Power `index`.
|
|
195
|
-
pub
|
|
194
|
+
pub fn hiddenPower(index: u8) Type {
|
|
196
195
|
return HIDDEN_POWER[index];
|
|
197
196
|
}
|
|
198
197
|
};
|
|
@@ -209,17 +208,18 @@ pub const Types = extern struct {
|
|
|
209
208
|
}
|
|
210
209
|
|
|
211
210
|
/// Whether this typing is immune to type `t`.
|
|
212
|
-
pub
|
|
211
|
+
pub fn immune(self: Types, t: Type) bool {
|
|
213
212
|
return t.effectiveness(self.type1) == I or t.effectiveness(self.type2) == I;
|
|
214
213
|
}
|
|
215
214
|
|
|
216
215
|
/// Whether this typing includes type `t`.
|
|
217
|
-
pub
|
|
216
|
+
pub fn includes(self: Types, t: Type) bool {
|
|
218
217
|
return self.type1 == t or self.type2 == t;
|
|
219
218
|
}
|
|
220
219
|
|
|
221
220
|
/// Whether this typing is immune to damage from Sandstorm.
|
|
222
|
-
pub
|
|
223
|
-
return self.type1 <= @intFromEnum(Type.Steel) or
|
|
221
|
+
pub fn sandstormImmune(self: Types) bool {
|
|
222
|
+
return @intFromEnum(self.type1) <= @intFromEnum(Type.Steel) or
|
|
223
|
+
@intFromEnum(self.type2) <= @intFromEnum(Type.Steel);
|
|
224
224
|
}
|
|
225
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,6 +41,7 @@ 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
|
|
|
@@ -62,17 +59,17 @@ pub fn Battle(comptime RNG: anytype) type {
|
|
|
62
59
|
|
|
63
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
|
|
|
@@ -133,27 +130,27 @@ pub const Side = extern struct {
|
|
|
133
130
|
assert(@sizeOf(Side) == 248);
|
|
134
131
|
}
|
|
135
132
|
|
|
136
|
-
pub
|
|
137
|
-
assert(
|
|
133
|
+
pub fn get(self: anytype, slot: u8) PointerType(@TypeOf(self), Pokemon) {
|
|
134
|
+
assert(isPointerTo(self, Side));
|
|
138
135
|
assert(slot > 0 and slot <= 6);
|
|
139
136
|
const id = self.pokemon[slot - 1].position;
|
|
140
137
|
assert(id > 0 and id <= 6);
|
|
141
138
|
return &self.pokemon[id - 1];
|
|
142
139
|
}
|
|
143
140
|
|
|
144
|
-
pub
|
|
145
|
-
assert(
|
|
141
|
+
pub fn stored(self: anytype) PointerType(@TypeOf(self), Pokemon) {
|
|
142
|
+
assert(isPointerTo(self, Side));
|
|
146
143
|
return self.get(1);
|
|
147
144
|
}
|
|
148
145
|
|
|
149
|
-
pub
|
|
146
|
+
pub fn lastMove(self: anytype, encore: bool) Move {
|
|
150
147
|
assert(self.last_used_move != .None or !self.active.volatiles.dirty);
|
|
151
148
|
if (encore) return self.last_used_move;
|
|
152
149
|
return if (self.active.volatiles.dirty) .None else self.last_used_move;
|
|
153
150
|
}
|
|
154
151
|
|
|
155
152
|
// TODO
|
|
156
|
-
// pub
|
|
153
|
+
// pub fn useMove(self: anytype) void {
|
|
157
154
|
// assert(side.last_selected_move != .None);
|
|
158
155
|
// self.last_used_move = side.last_selected_move;
|
|
159
156
|
// self.active.volatiles.dirty = false;
|
|
@@ -175,8 +172,8 @@ pub const ActivePokemon = extern struct {
|
|
|
175
172
|
assert(@sizeOf(ActivePokemon) == 44);
|
|
176
173
|
}
|
|
177
174
|
|
|
178
|
-
pub
|
|
179
|
-
assert(
|
|
175
|
+
pub fn move(self: anytype, mslot: u8) PointerType(@TypeOf(self), MoveSlot) {
|
|
176
|
+
assert(isPointerTo(self, Pokemon));
|
|
180
177
|
assert(mslot > 0 and mslot <= 4);
|
|
181
178
|
assert(self.moves[mslot - 1].id != .None);
|
|
182
179
|
return &self.moves[mslot - 1];
|
|
@@ -200,8 +197,8 @@ pub const Pokemon = extern struct {
|
|
|
200
197
|
assert(@sizeOf(Pokemon) == 32);
|
|
201
198
|
}
|
|
202
199
|
|
|
203
|
-
pub
|
|
204
|
-
assert(
|
|
200
|
+
pub fn move(self: anytype, mslot: u8) PointerType(@TypeOf(self), MoveSlot) {
|
|
201
|
+
assert(isPointerTo(self, Pokemon));
|
|
205
202
|
assert(mslot > 0 and mslot <= 4);
|
|
206
203
|
assert(self.moves[mslot - 1].id != .None);
|
|
207
204
|
return &self.moves[mslot - 1];
|
|
@@ -225,7 +222,7 @@ pub const DVs = packed struct(u16) {
|
|
|
225
222
|
return .{ .gender = g, .pow = p, .type = t };
|
|
226
223
|
}
|
|
227
224
|
|
|
228
|
-
pub
|
|
225
|
+
pub fn power(dvs: DVs) u8 {
|
|
229
226
|
return @as(u8, dvs.pow) + 30;
|
|
230
227
|
}
|
|
231
228
|
|
|
@@ -239,7 +236,7 @@ pub const DVs = packed struct(u16) {
|
|
|
239
236
|
};
|
|
240
237
|
const p: u6 = @intCast(1 + ((5 * @as(u8, (dvs.atk & 0b1000) | ((dvs.def & 0b1000)) >> 1 |
|
|
241
238
|
((dvs.spe & 0b1000)) >> 2 | ((dvs.spc & 0b1000)) >> 3) + (dvs.spc & 0b0011)) >> 1));
|
|
242
|
-
|
|
239
|
+
const t = @as(u8, dvs.def & 0b0011) + (@as(u8, dvs.atk & 0b0011) << 2);
|
|
243
240
|
return .{ .gender = g, .pow = p, .type = Type.hiddenPower(t) };
|
|
244
241
|
}
|
|
245
242
|
};
|
|
@@ -280,22 +277,7 @@ pub const MoveSlot = extern struct {
|
|
|
280
277
|
pub const Status = gen1.Status;
|
|
281
278
|
|
|
282
279
|
/// TODO
|
|
283
|
-
pub const TriAttack = enum(u2) {
|
|
284
|
-
PAR,
|
|
285
|
-
FRZ,
|
|
286
|
-
BRN,
|
|
287
|
-
|
|
288
|
-
/// TODO
|
|
289
|
-
pub inline fn status(self: TriAttack) u8 {
|
|
290
|
-
return Status.init(@enumFromInt(6 - @as(u8, @intFromEnum(self))));
|
|
291
|
-
}
|
|
292
|
-
};
|
|
293
|
-
|
|
294
|
-
test TriAttack {
|
|
295
|
-
try expectEqual(Status.init(.PAR), TriAttack.PAR.status());
|
|
296
|
-
try expectEqual(Status.init(.FRZ), TriAttack.FRZ.status());
|
|
297
|
-
try expectEqual(Status.init(.BRN), TriAttack.BRN.status());
|
|
298
|
-
}
|
|
280
|
+
pub const TriAttack = enum(u2) { PAR, FRZ, BRN };
|
|
299
281
|
|
|
300
282
|
pub const Volatiles = packed struct(u128) {
|
|
301
283
|
Bide: bool = false,
|
|
@@ -329,19 +311,23 @@ pub const Volatiles = packed struct(u128) {
|
|
|
329
311
|
Encore: bool = false,
|
|
330
312
|
LockOn: bool = false,
|
|
331
313
|
DestinyBond: bool = false,
|
|
314
|
+
Trapped: bool = false,
|
|
332
315
|
|
|
333
|
-
trapped: bool = false,
|
|
334
316
|
switched: bool = false,
|
|
317
|
+
// TODO: replace with simply looking at Choice on Battle
|
|
335
318
|
switching: bool = false,
|
|
319
|
+
// TODO: simply store both last moves on side
|
|
336
320
|
dirty: bool = false,
|
|
337
321
|
|
|
338
322
|
frozen: bool = false,
|
|
339
|
-
|
|
323
|
+
minimized: bool = false,
|
|
324
|
+
_: u10 = 0,
|
|
325
|
+
// TODO: is this needed for unmodified stats?
|
|
326
|
+
transform: u4 = 0,
|
|
340
327
|
|
|
341
|
-
bind_reason: u4 = 0,
|
|
342
|
-
bind: u4 = 0,
|
|
343
328
|
bide: u16 = 0,
|
|
344
|
-
|
|
329
|
+
bind: Bind = .{},
|
|
330
|
+
disable: Disable = .{},
|
|
345
331
|
rage: u8 = 0,
|
|
346
332
|
substitute: u8 = 0,
|
|
347
333
|
toxic: u8 = 0,
|
|
@@ -353,7 +339,12 @@ pub const Volatiles = packed struct(u128) {
|
|
|
353
339
|
protect: u4 = 0,
|
|
354
340
|
attacks: u4 = 0, // bide/thrashing/rollout turns
|
|
355
341
|
|
|
356
|
-
const
|
|
342
|
+
const Bind = packed struct(u8) {
|
|
343
|
+
duration: u4 = 0,
|
|
344
|
+
reason: u4 = 0,
|
|
345
|
+
};
|
|
346
|
+
|
|
347
|
+
const Disable = packed struct(u8) {
|
|
357
348
|
move: u4 = 0,
|
|
358
349
|
duration: u4 = 0,
|
|
359
350
|
};
|