@pkmn/engine 0.1.0-dev.dfd46bbb → 0.1.0-dev.e0a786f8
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 +15 -2
- 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 +28 -19
- 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 +330 -93
- package/package.json +59 -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 +4 -4
- package/src/lib/common/debug.zig +39 -8
- package/src/lib/common/js.zig +4 -2
- package/src/lib/common/optional.zig +14 -10
- package/src/lib/common/options.zig +6 -0
- package/src/lib/common/protocol.zig +396 -399
- package/src/lib/common/rational.zig +327 -158
- package/src/lib/common/rng.zig +7 -9
- package/src/lib/common/util.zig +60 -1
- package/src/lib/gen1/calc.zig +696 -160
- package/src/lib/gen1/chance.zig +405 -280
- package/src/lib/gen1/data/moves.zig +2 -4
- package/src/lib/gen1/data/species.zig +2 -4
- package/src/lib/gen1/data/types.zig +1 -2
- package/src/lib/gen1/data.zig +24 -27
- package/src/lib/gen1/helpers.zig +92 -548
- package/src/lib/gen1/mechanics.zig +575 -461
- package/src/lib/gen2/calc.zig +37 -27
- package/src/lib/gen2/chance.zig +84 -496
- 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 +20 -23
- package/src/lib/gen2/generated.zig +24 -37
- package/src/lib/gen2/helpers.zig +46 -25
- package/src/lib/gen2/mechanics.zig +721 -453
- 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
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;
|
|
@@ -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
|
|
|
@@ -63,12 +60,12 @@ pub fn Battle(comptime RNG: anytype) type {
|
|
|
63
60
|
_: [padding]u8 = .{0} ** padding,
|
|
64
61
|
|
|
65
62
|
pub fn side(self: anytype, player: Player) PointerType(@TypeOf(self), Side) {
|
|
66
|
-
assert(
|
|
63
|
+
assert(isPointerTo(self, Self));
|
|
67
64
|
return &self.sides[@intFromEnum(player)];
|
|
68
65
|
}
|
|
69
66
|
|
|
70
67
|
pub fn foe(self: anytype, player: Player) PointerType(@TypeOf(self), Side) {
|
|
71
|
-
assert(
|
|
68
|
+
assert(isPointerTo(self, Self));
|
|
72
69
|
return &self.sides[@intFromEnum(player.foe())];
|
|
73
70
|
}
|
|
74
71
|
|
|
@@ -134,7 +131,7 @@ pub const Side = extern struct {
|
|
|
134
131
|
}
|
|
135
132
|
|
|
136
133
|
pub fn get(self: anytype, slot: u8) PointerType(@TypeOf(self), Pokemon) {
|
|
137
|
-
assert(
|
|
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);
|
|
@@ -142,7 +139,7 @@ pub const Side = extern struct {
|
|
|
142
139
|
}
|
|
143
140
|
|
|
144
141
|
pub fn stored(self: anytype) PointerType(@TypeOf(self), Pokemon) {
|
|
145
|
-
assert(
|
|
142
|
+
assert(isPointerTo(self, Side));
|
|
146
143
|
return self.get(1);
|
|
147
144
|
}
|
|
148
145
|
|
|
@@ -176,7 +173,7 @@ pub const ActivePokemon = extern struct {
|
|
|
176
173
|
}
|
|
177
174
|
|
|
178
175
|
pub fn move(self: anytype, mslot: u8) PointerType(@TypeOf(self), MoveSlot) {
|
|
179
|
-
assert(
|
|
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];
|
|
@@ -201,7 +198,7 @@ pub const Pokemon = extern struct {
|
|
|
201
198
|
}
|
|
202
199
|
|
|
203
200
|
pub fn move(self: anytype, mslot: u8) PointerType(@TypeOf(self), MoveSlot) {
|
|
204
|
-
assert(
|
|
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];
|
|
@@ -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
|
};
|
|
@@ -314,8 +311,8 @@ 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,
|
|
320
317
|
// TODO: replace with simply looking at Choice on Battle
|
|
321
318
|
switching: bool = false,
|
|
@@ -1,39 +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
|
-
|
|
12
|
-
const
|
|
13
|
-
const
|
|
14
|
-
|
|
15
|
-
const Effectiveness = data.Effectiveness;
|
|
16
|
-
const Move = data.Move;
|
|
17
|
-
|
|
18
|
-
const Effects = mechanics.Effects;
|
|
19
|
-
const State = mechanics.State;
|
|
20
|
-
|
|
21
|
-
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;
|
|
22
13
|
const canCharge = mechanics.canCharge;
|
|
14
|
+
const canMove = mechanics.canMove;
|
|
15
|
+
const checkCriticalHit = mechanics.checkCriticalHit;
|
|
16
|
+
const checkHit = mechanics.checkHit;
|
|
23
17
|
const decrementPP = mechanics.decrementPP;
|
|
18
|
+
const destinyBond = mechanics.destinyBond;
|
|
24
19
|
const doMove = mechanics.doMove;
|
|
25
|
-
const checkHit = mechanics.checkHit;
|
|
26
|
-
const checkCriticalHit = mechanics.checkCriticalHit;
|
|
27
|
-
const calcDamage = mechanics.calcDamage;
|
|
28
|
-
const adjustDamage = mechanics.adjustDamage;
|
|
29
|
-
const randomizeDamage = mechanics.randomizeDamage;
|
|
30
|
-
const applyDamage = mechanics.applyDamage;
|
|
31
|
-
const reportOutcome = mechanics.reportOutcome;
|
|
32
20
|
const effectChance = mechanics.effectChance;
|
|
33
|
-
const
|
|
34
|
-
const
|
|
21
|
+
const Effectiveness = data.Effectiveness;
|
|
22
|
+
const Effects = mechanics.Effects;
|
|
35
23
|
const kingsRock = mechanics.kingsRock;
|
|
36
|
-
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;
|
|
37
30
|
|
|
38
31
|
const SECONDARY = true;
|
|
39
32
|
const KINGS = true;
|
|
@@ -42,7 +35,7 @@ pub fn runMove(battle: anytype, player: Player, state: *State, options: anytype)
|
|
|
42
35
|
var log = options.log;
|
|
43
36
|
|
|
44
37
|
var side = battle.side(player);
|
|
45
|
-
|
|
38
|
+
const volatiles = &side.active.volatiles;
|
|
46
39
|
|
|
47
40
|
const ident = battle.active(player);
|
|
48
41
|
const foe_ident = battle.active(player.foe());
|
|
@@ -175,7 +168,7 @@ pub fn runMove(battle: anytype, player: Player, state: *State, options: anytype)
|
|
|
175
168
|
if (!skip_pp) _ = decrementPP(side, state.move, state.mslot); // TODO if no pp return
|
|
176
169
|
// TODO rampage
|
|
177
170
|
// usedmovetext
|
|
178
|
-
try log.move(ident, state.move, foe_ident); // FIXME self? from?
|
|
171
|
+
try log.move(.{ ident, state.move, foe_ident }); // FIXME self? from?
|
|
179
172
|
try checkHit(battle, player, state, options);
|
|
180
173
|
try checkCriticalHit(battle, player, state, options);
|
|
181
174
|
try calcDamage(battle, player, state, options);
|
|
@@ -260,7 +253,7 @@ pub fn runMove(battle: anytype, player: Player, state: *State, options: anytype)
|
|
|
260
253
|
try Effects.hyperBeam(battle, player, state, options);
|
|
261
254
|
_ = try afterMove(!KINGS, battle, player, state, options);
|
|
262
255
|
},
|
|
263
|
-
.Counter => {
|
|
256
|
+
.MirrorCoat, .Counter => {
|
|
264
257
|
if (!try canMove(battle, player, state, options)) return;
|
|
265
258
|
try Effects.counter(battle, player, state, options);
|
|
266
259
|
try applyDamage(battle, player, state, options);
|
|
@@ -368,7 +361,7 @@ pub fn runMove(battle: anytype, player: Player, state: *State, options: anytype)
|
|
|
368
361
|
(volatiles.BeatUp or volatiles.Thrashing or volatiles.Bide);
|
|
369
362
|
if (!skip_pp) _ = decrementPP(side, state.move, state.mslot); // TODO if no pp return
|
|
370
363
|
// usedmovetext
|
|
371
|
-
try log.move(ident, state.move, foe_ident); // FIXME self? from?
|
|
364
|
+
try log.move(.{ ident, state.move, foe_ident }); // FIXME self? from?
|
|
372
365
|
try Effects.bide.unleash(battle, player, state, options);
|
|
373
366
|
|
|
374
367
|
if (state.immune()) {
|
|
@@ -555,7 +548,7 @@ pub fn runMove(battle: anytype, player: Player, state: *State, options: anytype)
|
|
|
555
548
|
(volatiles.BeatUp or volatiles.Thrashing or volatiles.Bide);
|
|
556
549
|
if (!skip_pp) _ = decrementPP(side, state.move, state.mslot); // TODO if no pp return
|
|
557
550
|
// usedmovetext
|
|
558
|
-
try log.move(ident, state.move, foe_ident); // FIXME self? from?
|
|
551
|
+
try log.move(.{ ident, state.move, foe_ident }); // FIXME self? from?
|
|
559
552
|
try checkCriticalHit(battle, player, state, options);
|
|
560
553
|
try calcDamage(battle, player, state, options);
|
|
561
554
|
try adjustDamage(battle, player, state, options);
|
|
@@ -655,7 +648,7 @@ pub fn runMove(battle: anytype, player: Player, state: *State, options: anytype)
|
|
|
655
648
|
.Magnitude => {
|
|
656
649
|
if (!try canMove(battle, player, state, options)) return;
|
|
657
650
|
try checkCriticalHit(battle, player, state, options);
|
|
658
|
-
|
|
651
|
+
try Effects.magnitude(battle, player, state, options);
|
|
659
652
|
try calcDamage(battle, player, state, options);
|
|
660
653
|
try adjustDamage(battle, player, state, options);
|
|
661
654
|
try randomizeDamage(battle, player, state, options);
|
|
@@ -730,12 +723,6 @@ pub fn runMove(battle: anytype, player: Player, state: *State, options: anytype)
|
|
|
730
723
|
if (!try canMove(battle, player, state, options)) return;
|
|
731
724
|
try Effects.sunnyDay(battle, player, state, options);
|
|
732
725
|
},
|
|
733
|
-
.MirrorCoat => {
|
|
734
|
-
if (!try canMove(battle, player, state, options)) return;
|
|
735
|
-
try Effects.mirrorCoat(battle, player, state, options);
|
|
736
|
-
try applyDamage(battle, player, state, options);
|
|
737
|
-
_ = try afterMove(KINGS, battle, player, state, options);
|
|
738
|
-
},
|
|
739
726
|
.PsychUp => {
|
|
740
727
|
if (!try canMove(battle, player, state, options)) return;
|
|
741
728
|
try Effects.psychUp(battle, player, state, options);
|
package/src/lib/gen2/helpers.zig
CHANGED
|
@@ -1,31 +1,22 @@
|
|
|
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
|
-
const protocol = @import("../common/protocol.zig");
|
|
6
5
|
const rng = @import("../common/rng.zig");
|
|
7
|
-
|
|
8
|
-
const gen1 = @import("../gen1/data.zig");
|
|
9
|
-
|
|
10
|
-
const data = @import("data.zig");
|
|
6
|
+
const std = @import("std");
|
|
11
7
|
|
|
12
8
|
const assert = std.debug.assert;
|
|
13
|
-
|
|
14
|
-
const expectEqual = std.testing.expectEqual;
|
|
15
|
-
|
|
16
9
|
const Choice = common.Choice;
|
|
17
|
-
|
|
18
|
-
const showdown = options.showdown;
|
|
19
|
-
|
|
20
|
-
const PSRNG = rng.PSRNG;
|
|
21
|
-
|
|
22
10
|
const DVs = data.DVs;
|
|
23
11
|
const Item = data.Item;
|
|
24
12
|
const Move = data.Move;
|
|
25
13
|
const MoveSlot = data.MoveSlot;
|
|
14
|
+
const PSRNG = rng.PSRNG;
|
|
15
|
+
const showdown = options.showdown;
|
|
26
16
|
const Species = data.Species;
|
|
27
17
|
const Stats = data.Stats;
|
|
28
|
-
|
|
18
|
+
|
|
19
|
+
const Struct = if (@hasField(std.builtin.Type, "struct")) .@"struct" else .Struct;
|
|
29
20
|
|
|
30
21
|
pub const Options = struct {
|
|
31
22
|
cleric: bool = showdown,
|
|
@@ -65,17 +56,47 @@ pub const Battle = struct {
|
|
|
65
56
|
};
|
|
66
57
|
|
|
67
58
|
pub fn prng(rand: *PSRNG) data.PRNG {
|
|
68
|
-
// FIXME: what is max range in gen2?
|
|
69
59
|
return .{
|
|
70
60
|
.src = .{
|
|
71
61
|
.seed = if (showdown)
|
|
72
62
|
rand.newSeed()
|
|
73
|
-
else
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
63
|
+
else seed: {
|
|
64
|
+
// GLITCH: The initial RNG seed in Gen II link battles is heavily constrained
|
|
65
|
+
// https://www.smogon.com/forums/threads/rng-in-rby-link-battles.3746779
|
|
66
|
+
var seed = [_]u8{ 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
|
67
|
+
|
|
68
|
+
// Bytes in seed can only range from 0-252, not 0-255
|
|
69
|
+
const max: u8 = 253;
|
|
70
|
+
// Instructions take multiples of 4 cycles to execute
|
|
71
|
+
var timer: u16 = 4 * rand.range(u16, 0, 16384);
|
|
72
|
+
var add: u8 = rand.range(u8, 0, 256);
|
|
73
|
+
var sub: u8 = rand.range(u8, 0, 256);
|
|
74
|
+
var carry: u8 = 0;
|
|
75
|
+
var div: u8 = 0;
|
|
76
|
+
|
|
77
|
+
var i: u8 = 0;
|
|
78
|
+
while (i < seed.len) {
|
|
79
|
+
div = @intCast(timer >> 8);
|
|
80
|
+
// This is effectively @addWithOverflow but with three operands
|
|
81
|
+
const result = @as(u16, add) + @as(u16, div) + @as(u16, carry);
|
|
82
|
+
add = @intCast(result & 255);
|
|
83
|
+
carry = @intFromBool(result > 255);
|
|
84
|
+
timer +%= 44;
|
|
85
|
+
div = @intCast(timer >> 8);
|
|
86
|
+
sub -%= div +% carry;
|
|
87
|
+
|
|
88
|
+
if (sub < max) {
|
|
89
|
+
seed[i] = sub;
|
|
90
|
+
i += 1;
|
|
91
|
+
timer +%= 152;
|
|
92
|
+
carry = 1;
|
|
93
|
+
} else {
|
|
94
|
+
timer +%= 132;
|
|
95
|
+
carry = 0;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
break :seed seed;
|
|
99
|
+
},
|
|
79
100
|
},
|
|
80
101
|
};
|
|
81
102
|
}
|
|
@@ -121,7 +142,7 @@ pub const Pokemon = struct {
|
|
|
121
142
|
var pokemon = data.Pokemon{};
|
|
122
143
|
pokemon.species = p.species;
|
|
123
144
|
const species = Species.get(p.species);
|
|
124
|
-
inline for (@typeInfo(@TypeOf(pokemon.stats))
|
|
145
|
+
inline for (@field(@typeInfo(@TypeOf(pokemon.stats)), @tagName(Struct)).fields) |field| {
|
|
125
146
|
const hp = comptime std.mem.eql(u8, field.name, "hp");
|
|
126
147
|
const spc =
|
|
127
148
|
comptime std.mem.eql(u8, field.name, "spa") or std.mem.eql(u8, field.name, "spd");
|
|
@@ -162,7 +183,7 @@ pub const Pokemon = struct {
|
|
|
162
183
|
|
|
163
184
|
var stats: Stats(u16) = .{};
|
|
164
185
|
const dvs = gen1.DVs.random(rand);
|
|
165
|
-
inline for (@typeInfo(@TypeOf(stats))
|
|
186
|
+
inline for (@field(@typeInfo(@TypeOf(stats)), @tagName(Struct)).fields) |field| {
|
|
166
187
|
const hp = std.mem.eql(u8, field.name, "hp");
|
|
167
188
|
const spc = std.mem.eql(u8, field.name, "spa") or std.mem.eql(u8, field.name, "spd");
|
|
168
189
|
@field(stats, field.name) = Stats(u16).calc(
|