@pkmn/engine 0.1.0-dev.a93847b2 → 0.1.0-dev.ac652f4e
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 +344 -101
- 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 +8 -8
- 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 +400 -402
- package/src/lib/common/rational.zig +328 -159
- package/src/lib/common/rng.zig +16 -9
- package/src/lib/common/util.zig +60 -1
- package/src/lib/gen1/calc.zig +697 -161
- package/src/lib/gen1/chance.zig +406 -281
- package/src/lib/gen1/data/moves.zig +11 -13
- package/src/lib/gen1/data/species.zig +3 -5
- package/src/lib/gen1/data/types.zig +5 -6
- package/src/lib/gen1/data.zig +38 -41
- package/src/lib/gen1/helpers.zig +92 -548
- package/src/lib/gen1/mechanics.zig +593 -483
- package/src/lib/gen2/calc.zig +38 -28
- package/src/lib/gen2/chance.zig +85 -497
- package/src/lib/gen2/data/items.zig +3 -5
- package/src/lib/gen2/data/moves.zig +4 -6
- package/src/lib/gen2/data/species.zig +1 -3
- package/src/lib/gen2/data/types.zig +10 -11
- package/src/lib/gen2/data.zig +33 -34
- package/src/lib/gen2/generated.zig +45 -101
- package/src/lib/gen2/helpers.zig +46 -25
- package/src/lib/gen2/mechanics.zig +1121 -555
- 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.
|
|
@@ -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
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
|
|
|
@@ -2562,7 +2560,7 @@ pub const Move = enum(u8) {
|
|
|
2562
2560
|
}
|
|
2563
2561
|
|
|
2564
2562
|
/// Whether this effect has a high critical rate.
|
|
2565
|
-
pub
|
|
2563
|
+
pub fn isHighCritical(effect: Effect) bool {
|
|
2566
2564
|
return effect == .HighCritical or effect == .RazorWind;
|
|
2567
2565
|
}
|
|
2568
2566
|
};
|
|
@@ -2865,7 +2863,7 @@ pub const Move = enum(u8) {
|
|
|
2865
2863
|
};
|
|
2866
2864
|
|
|
2867
2865
|
/// Returns the `Data` corresponding to the move.
|
|
2868
|
-
pub
|
|
2866
|
+
pub fn get(id: Move) Data {
|
|
2869
2867
|
assert(id != .None);
|
|
2870
2868
|
return DATA[@intFromEnum(id) - 1];
|
|
2871
2869
|
}
|
|
@@ -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;
|
|
@@ -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,17 @@ 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
|
|
221
|
+
pub fn sandstormImmune(self: Types) bool {
|
|
223
222
|
return @intFromEnum(self.type1) <= @intFromEnum(Type.Steel) or
|
|
224
223
|
@intFromEnum(self.type2) <= @intFromEnum(Type.Steel);
|
|
225
224
|
}
|
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
|
};
|
|
@@ -314,16 +311,18 @@ 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,
|
|
325
324
|
_: u10 = 0,
|
|
326
|
-
// TODO?
|
|
325
|
+
// TODO: is this needed for unmodified stats?
|
|
327
326
|
transform: u4 = 0,
|
|
328
327
|
|
|
329
328
|
bide: u16 = 0,
|
|
@@ -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());
|
|
@@ -97,17 +90,8 @@ pub fn runMove(battle: anytype, player: Player, state: *State, options: anytype)
|
|
|
97
90
|
},
|
|
98
91
|
.OHKO => {
|
|
99
92
|
if (!try canMove(battle, player, state, options)) return;
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
assert(move.type == .Normal or move.type == .Ground);
|
|
103
|
-
const foe = battle.foe(player);
|
|
104
|
-
const immune = if (move.type == .Normal)
|
|
105
|
-
foe.active.types.includes(.Ghost) and !foe.active.volatiles.Foresight
|
|
106
|
-
else
|
|
107
|
-
foe.active.types.includes(.Ghost);
|
|
108
|
-
state.effectiveness = if (immune) 0 else Effectiveness.neutral;
|
|
109
|
-
|
|
110
|
-
try Effects.ohko(battle, player, state, options);
|
|
93
|
+
try Effects.ohko.immune(battle, player, state, options);
|
|
94
|
+
try Effects.ohko.damage(battle, player, state, options);
|
|
111
95
|
try applyDamage(battle, player, state, options);
|
|
112
96
|
try reportOutcome(battle, player, state, options);
|
|
113
97
|
_ = try afterMove(!KINGS, battle, player, state, options);
|
|
@@ -118,9 +102,7 @@ pub fn runMove(battle: anytype, player: Player, state: *State, options: anytype)
|
|
|
118
102
|
try calcDamage(battle, player, state, options);
|
|
119
103
|
try adjustDamage(battle, player, state, options);
|
|
120
104
|
try randomizeDamage(battle, player, state, options);
|
|
121
|
-
|
|
122
|
-
if (battle.foe(player).active.volatiles.Flying) state.damage *|= 2;
|
|
123
|
-
|
|
105
|
+
try Effects.double.flying(battle, player, state, options);
|
|
124
106
|
try checkHit(battle, player, state, options);
|
|
125
107
|
try applyDamage(battle, player, state, options);
|
|
126
108
|
try reportOutcome(battle, player, state, options);
|
|
@@ -157,9 +139,7 @@ pub fn runMove(battle: anytype, player: Player, state: *State, options: anytype)
|
|
|
157
139
|
try calcDamage(battle, player, state, options);
|
|
158
140
|
try adjustDamage(battle, player, state, options);
|
|
159
141
|
try randomizeDamage(battle, player, state, options);
|
|
160
|
-
|
|
161
|
-
if (battle.foe(player).active.volatiles.minimized) state.damage *|= 2;
|
|
162
|
-
|
|
142
|
+
try Effects.double.minimize(battle, player, state, options);
|
|
163
143
|
try checkHit(battle, player, state, options);
|
|
164
144
|
try effectChance(battle, player, state, options);
|
|
165
145
|
try applyDamage(battle, player, state, options);
|
|
@@ -188,7 +168,7 @@ pub fn runMove(battle: anytype, player: Player, state: *State, options: anytype)
|
|
|
188
168
|
if (!skip_pp) _ = decrementPP(side, state.move, state.mslot); // TODO if no pp return
|
|
189
169
|
// TODO rampage
|
|
190
170
|
// usedmovetext
|
|
191
|
-
try log.move(ident, state.move, foe_ident); // FIXME self? from?
|
|
171
|
+
try log.move(.{ ident, state.move, foe_ident }); // FIXME self? from?
|
|
192
172
|
try checkHit(battle, player, state, options);
|
|
193
173
|
try checkCriticalHit(battle, player, state, options);
|
|
194
174
|
try calcDamage(battle, player, state, options);
|
|
@@ -273,7 +253,7 @@ pub fn runMove(battle: anytype, player: Player, state: *State, options: anytype)
|
|
|
273
253
|
try Effects.hyperBeam(battle, player, state, options);
|
|
274
254
|
_ = try afterMove(!KINGS, battle, player, state, options);
|
|
275
255
|
},
|
|
276
|
-
.Counter => {
|
|
256
|
+
.MirrorCoat, .Counter => {
|
|
277
257
|
if (!try canMove(battle, player, state, options)) return;
|
|
278
258
|
try Effects.counter(battle, player, state, options);
|
|
279
259
|
try applyDamage(battle, player, state, options);
|
|
@@ -308,7 +288,6 @@ pub fn runMove(battle: anytype, player: Player, state: *State, options: anytype)
|
|
|
308
288
|
if (!try canMove(battle, player, state, options)) return;
|
|
309
289
|
try checkCriticalHit(battle, player, state, options);
|
|
310
290
|
try calcDamage(battle, player, state, options);
|
|
311
|
-
// TODO thunderaccuracy
|
|
312
291
|
try checkHit(battle, player, state, options);
|
|
313
292
|
try effectChance(battle, player, state, options);
|
|
314
293
|
try adjustDamage(battle, player, state, options);
|
|
@@ -324,9 +303,7 @@ pub fn runMove(battle: anytype, player: Player, state: *State, options: anytype)
|
|
|
324
303
|
try calcDamage(battle, player, state, options);
|
|
325
304
|
try adjustDamage(battle, player, state, options);
|
|
326
305
|
try randomizeDamage(battle, player, state, options);
|
|
327
|
-
|
|
328
|
-
if (battle.foe(player).active.volatiles.Underground) state.damage *|= 2;
|
|
329
|
-
|
|
306
|
+
try Effects.double.underground(battle, player, state, options);
|
|
330
307
|
try checkHit(battle, player, state, options);
|
|
331
308
|
try effectChance(battle, player, state, options);
|
|
332
309
|
try applyDamage(battle, player, state, options);
|
|
@@ -339,13 +316,10 @@ pub fn runMove(battle: anytype, player: Player, state: *State, options: anytype)
|
|
|
339
316
|
try calcDamage(battle, player, state, options);
|
|
340
317
|
try adjustDamage(battle, player, state, options);
|
|
341
318
|
try checkHit(battle, player, state, options);
|
|
342
|
-
|
|
343
|
-
assert(volatiles.Rage);
|
|
344
|
-
state.damage *|= (volatiles.rage +| 1);
|
|
345
|
-
|
|
319
|
+
try Effects.rage.damage(battle, player, state, options);
|
|
346
320
|
try randomizeDamage(battle, player, state, options);
|
|
347
321
|
// TODO failuretext
|
|
348
|
-
try Effects.rage(battle, player, state, options);
|
|
322
|
+
try Effects.rage.start(battle, player, state, options);
|
|
349
323
|
try applyDamage(battle, player, state, options);
|
|
350
324
|
try reportOutcome(battle, player, state, options);
|
|
351
325
|
_ = try afterMove(KINGS, battle, player, state, options);
|
|
@@ -363,47 +337,32 @@ pub fn runMove(battle: anytype, player: Player, state: *State, options: anytype)
|
|
|
363
337
|
if (!try canMove(battle, player, state, options)) return;
|
|
364
338
|
try Effects.heal(battle, player, state, options);
|
|
365
339
|
},
|
|
340
|
+
.LightScreen => {
|
|
341
|
+
if (!try canMove(battle, player, state, options)) return;
|
|
342
|
+
try Effects.lightScreen(battle, player, state, options);
|
|
343
|
+
},
|
|
366
344
|
.Haze => {
|
|
367
345
|
if (!try canMove(battle, player, state, options)) return;
|
|
368
346
|
try Effects.haze(battle, player, state, options);
|
|
369
347
|
},
|
|
370
|
-
.
|
|
348
|
+
.Reflect => {
|
|
371
349
|
if (!try canMove(battle, player, state, options)) return;
|
|
372
|
-
try Effects.
|
|
350
|
+
try Effects.reflect(battle, player, state, options);
|
|
373
351
|
},
|
|
374
352
|
.FocusEnergy => {
|
|
375
353
|
if (!try canMove(battle, player, state, options)) return;
|
|
376
354
|
try Effects.focusEnergy(battle, player, state, options);
|
|
377
355
|
},
|
|
378
356
|
.Bide => {
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
assert(volatiles.attacks > 0);
|
|
382
|
-
// if (options.calc.modify(player, .attacking)) |extend| {
|
|
383
|
-
// if (!extend) volatiles.attacks = 0;
|
|
384
|
-
// } else {
|
|
385
|
-
volatiles.attacks -= 1;
|
|
386
|
-
// }
|
|
387
|
-
try options.chance.attacking(player, volatiles.attacks);
|
|
388
|
-
|
|
389
|
-
if (volatiles.attacks != 0) return try options.log.activate(ident, .Bide);
|
|
390
|
-
|
|
391
|
-
volatiles.Bide = false;
|
|
392
|
-
try options.log.end(ident, .Bide);
|
|
393
|
-
|
|
394
|
-
state.damage = volatiles.bide *% 2;
|
|
395
|
-
volatiles.bide = 0;
|
|
396
|
-
|
|
397
|
-
if (state.damage == 0) state.miss = true;
|
|
398
|
-
|
|
357
|
+
try Effects.bide.store(battle, player, state, options);
|
|
399
358
|
// doturn
|
|
400
359
|
const charging = false; // TODO
|
|
401
360
|
const skip_pp = charging or state.move == .Struggle or
|
|
402
361
|
(volatiles.BeatUp or volatiles.Thrashing or volatiles.Bide);
|
|
403
362
|
if (!skip_pp) _ = decrementPP(side, state.move, state.mslot); // TODO if no pp return
|
|
404
363
|
// usedmovetext
|
|
405
|
-
try log.move(ident, state.move, foe_ident); // FIXME self? from?
|
|
406
|
-
|
|
364
|
+
try log.move(.{ ident, state.move, foe_ident }); // FIXME self? from?
|
|
365
|
+
try Effects.bide.unleash(battle, player, state, options);
|
|
407
366
|
|
|
408
367
|
if (state.immune()) {
|
|
409
368
|
state.damage = 0;
|
|
@@ -522,7 +481,7 @@ pub fn runMove(battle: anytype, player: Player, state: *State, options: anytype)
|
|
|
522
481
|
try randomizeDamage(battle, player, state, options);
|
|
523
482
|
try checkHit(battle, player, state, options);
|
|
524
483
|
try effectChance(battle, player, state, options);
|
|
525
|
-
try Effects.snore(battle, player, state, options);
|
|
484
|
+
if (!try Effects.snore(battle, player, state, options)) return;
|
|
526
485
|
try applyDamage(battle, player, state, options);
|
|
527
486
|
try reportOutcome(battle, player, state, options);
|
|
528
487
|
if (!try afterMove(!KINGS, battle, player, state, options)) return;
|
|
@@ -582,19 +541,19 @@ pub fn runMove(battle: anytype, player: Player, state: *State, options: anytype)
|
|
|
582
541
|
try Effects.sandstorm(battle, player, state, options);
|
|
583
542
|
},
|
|
584
543
|
.Rollout => {
|
|
585
|
-
|
|
544
|
+
try Effects.rollout.check(battle, player, state, options);
|
|
586
545
|
// doturn
|
|
587
546
|
const charging = false; // TODO
|
|
588
547
|
const skip_pp = charging or state.move == .Struggle or
|
|
589
548
|
(volatiles.BeatUp or volatiles.Thrashing or volatiles.Bide);
|
|
590
549
|
if (!skip_pp) _ = decrementPP(side, state.move, state.mslot); // TODO if no pp return
|
|
591
550
|
// usedmovetext
|
|
592
|
-
try log.move(ident, state.move, foe_ident); // FIXME self? from?
|
|
551
|
+
try log.move(.{ ident, state.move, foe_ident }); // FIXME self? from?
|
|
593
552
|
try checkCriticalHit(battle, player, state, options);
|
|
594
553
|
try calcDamage(battle, player, state, options);
|
|
595
554
|
try adjustDamage(battle, player, state, options);
|
|
596
555
|
try checkHit(battle, player, state, options);
|
|
597
|
-
|
|
556
|
+
try Effects.rollout.power(battle, player, state, options);
|
|
598
557
|
try randomizeDamage(battle, player, state, options);
|
|
599
558
|
try applyDamage(battle, player, state, options);
|
|
600
559
|
try reportOutcome(battle, player, state, options);
|
|
@@ -615,12 +574,7 @@ pub fn runMove(battle: anytype, player: Player, state: *State, options: anytype)
|
|
|
615
574
|
.Swagger => {
|
|
616
575
|
if (!try canMove(battle, player, state, options)) return;
|
|
617
576
|
try checkHit(battle, player, state, options);
|
|
618
|
-
|
|
619
|
-
// TODO attackup2
|
|
620
|
-
// TODO switchturn
|
|
621
|
-
// TODO failuretext
|
|
622
|
-
// TODO switchturn
|
|
623
|
-
// TODO switchturn
|
|
577
|
+
try Effects.boost(battle, player.foe(), state, options);
|
|
624
578
|
try Effects.confusionChance(battle, player, state, options);
|
|
625
579
|
},
|
|
626
580
|
.FuryCutter => {
|
|
@@ -694,14 +648,12 @@ pub fn runMove(battle: anytype, player: Player, state: *State, options: anytype)
|
|
|
694
648
|
.Magnitude => {
|
|
695
649
|
if (!try canMove(battle, player, state, options)) return;
|
|
696
650
|
try checkCriticalHit(battle, player, state, options);
|
|
697
|
-
|
|
651
|
+
try Effects.magnitude(battle, player, state, options);
|
|
698
652
|
try calcDamage(battle, player, state, options);
|
|
699
653
|
try adjustDamage(battle, player, state, options);
|
|
700
654
|
try randomizeDamage(battle, player, state, options);
|
|
701
655
|
try checkHit(battle, player, state, options);
|
|
702
|
-
|
|
703
|
-
if (battle.foe(player).active.volatiles.Underground) state.damage *|= 2;
|
|
704
|
-
|
|
656
|
+
try Effects.double.underground(battle, player, state, options);
|
|
705
657
|
try applyDamage(battle, player, state, options);
|
|
706
658
|
try reportOutcome(battle, player, state, options);
|
|
707
659
|
_ = try afterMove(KINGS, battle, player, state, options);
|
|
@@ -755,9 +707,7 @@ pub fn runMove(battle: anytype, player: Player, state: *State, options: anytype)
|
|
|
755
707
|
try calcDamage(battle, player, state, options);
|
|
756
708
|
try adjustDamage(battle, player, state, options);
|
|
757
709
|
try randomizeDamage(battle, player, state, options);
|
|
758
|
-
|
|
759
|
-
if (battle.foe(player).active.volatiles.Flying) state.damage *|= 2;
|
|
760
|
-
|
|
710
|
+
try Effects.double.flying(battle, player, state, options);
|
|
761
711
|
try checkHit(battle, player, state, options);
|
|
762
712
|
try effectChance(battle, player, state, options);
|
|
763
713
|
try applyDamage(battle, player, state, options);
|
|
@@ -773,12 +723,6 @@ pub fn runMove(battle: anytype, player: Player, state: *State, options: anytype)
|
|
|
773
723
|
if (!try canMove(battle, player, state, options)) return;
|
|
774
724
|
try Effects.sunnyDay(battle, player, state, options);
|
|
775
725
|
},
|
|
776
|
-
.MirrorCoat => {
|
|
777
|
-
if (!try canMove(battle, player, state, options)) return;
|
|
778
|
-
try Effects.mirrorCoat(battle, player, state, options);
|
|
779
|
-
try applyDamage(battle, player, state, options);
|
|
780
|
-
_ = try afterMove(KINGS, battle, player, state, options);
|
|
781
|
-
},
|
|
782
726
|
.PsychUp => {
|
|
783
727
|
if (!try canMove(battle, player, state, options)) return;
|
|
784
728
|
try Effects.psychUp(battle, player, state, options);
|