From 8b83af6b872a6891e0040f1694f81ce1c1af1192 Mon Sep 17 00:00:00 2001 From: Kirk Scheibelhut Date: Tue, 27 Jun 2023 13:38:57 -0300 Subject: [PATCH] update zig to v0.11.0-dev.3859+88284c124 --- README.md | 2 +- src/bin/install-pkmn-engine | 2 +- src/lib/binding/c.zig | 23 ++--- src/lib/binding/node.zig | 37 +++---- src/lib/binding/wasm.zig | 4 +- src/lib/common/data.zig | 22 ++-- src/lib/common/data/items.zig.tmpl | 2 +- src/lib/common/protocol.zig | 161 +++++++++++++++-------------- src/lib/common/rng.zig | 10 +- src/lib/gen1/data.zig | 13 +-- src/lib/gen1/data/types.zig | 2 +- src/lib/gen1/helpers.zig | 14 +-- src/lib/gen1/mechanics.zig | 120 ++++++++++----------- src/lib/gen1/test.zig | 6 +- src/lib/gen2/data.zig | 11 +- src/lib/gen2/data/items.zig | 2 +- src/lib/gen2/helpers.zig | 10 +- src/lib/gen2/test.zig | 6 +- src/tools/generate.ts | 2 +- 19 files changed, 225 insertions(+), 224 deletions(-) diff --git a/README.md b/README.md index d6dd7822..64f92a9b 100644 --- a/README.md +++ b/README.md @@ -50,7 +50,7 @@ $ zig build --prefix /usr/local -Doptimize=ReleaseFast The Zig website has [installation instructions](https://ziglang.org/learn/getting-started/) which walk through how to install Zig on each platform - the engine code should work on Zig v0.11.0 dev -build 3737 or greater, though tracks Zig's master branch so this may change in the future if +build 3859 or greater, though tracks Zig's master branch so this may change in the future if breaking language changes are introduced: `libpkmn` can be built with `-Dshowdown` to instead produce the Pokémon Showdown compatible diff --git a/src/bin/install-pkmn-engine b/src/bin/install-pkmn-engine index e3a71490..80f4cdea 100755 --- a/src/bin/install-pkmn-engine +++ b/src/bin/install-pkmn-engine @@ -10,7 +10,7 @@ const path = require('path'); const {pipeline} = require('stream/promises'); const tty = require('tty'); -const ZIG_VERSION = {major: 0, minor: 11, patch: 0, dev: 3737}; +const ZIG_VERSION = {major: 0, minor: 11, patch: 0, dev: 3859}; const DEV = ZIG_VERSION.dev ? `-dev.${ZIG_VERSION.dev}` : ''; const VERSION = `${ZIG_VERSION.major}.${ZIG_VERSION.minor}.${ZIG_VERSION.patch}${DEV}`; const INDEX = 'https://ziglang.org/download/index.json'; diff --git a/src/lib/binding/c.zig b/src/lib/binding/c.zig index c08a2e0b..fbc11c9b 100644 --- a/src/lib/binding/c.zig +++ b/src/lib/binding/c.zig @@ -18,32 +18,29 @@ export const PKMN_LOGS_SIZE = pkmn.LOGS_SIZE; export fn pkmn_choice_init(choice: u8, data: u8) u8 { assert(choice <= @typeInfo(pkmn.Choice.Type).Enum.fields.len); assert(data <= 6); - return @bitCast(u8, pkmn.Choice{ - .type = @enumFromInt(pkmn.Choice.Type, choice), - .data = @intCast(u4, data), - }); + return @bitCast(pkmn.Choice{ .type = @enumFromInt(choice), .data = @intCast(data) }); } export fn pkmn_choice_type(choice: u8) u8 { - return @as(u8, @intFromEnum(@bitCast(pkmn.Choice, choice).type)); + return @intFromEnum(@as(pkmn.Choice, @bitCast(choice)).type); } export fn pkmn_choice_data(choice: u8) u8 { - return @as(u8, @bitCast(pkmn.Choice, choice).data); + return @as(u8, @as(pkmn.Choice, @bitCast(choice)).data); } export fn pkmn_result_type(result: u8) u8 { - return @intFromEnum(@bitCast(pkmn.Result, result).type); + return @intFromEnum(@as(pkmn.Result, @bitCast(result)).type); } export fn pkmn_result_p1(result: u8) u8 { assert(!pkmn_error(result)); - return @intFromEnum(@bitCast(pkmn.Result, result).p1); + return @intFromEnum(@as(pkmn.Result, @bitCast(result)).p1); } export fn pkmn_result_p2(result: u8) u8 { assert(!pkmn_error(result)); - return @intFromEnum(@bitCast(pkmn.Result, result).p2); + return @intFromEnum(@as(pkmn.Result, @bitCast(result)).p2); } export fn pkmn_error(result: u8) bool { @@ -74,7 +71,7 @@ export fn pkmn_gen1_battle_update( if (buf) |b| { var stream = pkmn.protocol.ByteStream{ .buffer = b[0..len] }; var log = pkmn.protocol.FixedLog{ .writer = stream.writer() }; - return battle.update(c1, c2, log) catch return @bitCast(pkmn.Result, ERROR); + return battle.update(c1, c2, log) catch return @bitCast(ERROR); } } return battle.update(c1, c2, pkmn.protocol.NULL) catch unreachable; @@ -90,9 +87,5 @@ export fn pkmn_gen1_battle_choices( assert(player <= @typeInfo(pkmn.Player).Enum.fields.len); assert(request <= @typeInfo(pkmn.Choice.Type).Enum.fields.len); assert(!pkmn.options.showdown or len > 0); - return battle.choices( - @enumFromInt(pkmn.Player, player), - @enumFromInt(pkmn.Choice.Type, request), - @ptrCast([]pkmn.Choice, out[0..len]), - ); + return battle.choices(@enumFromInt(player), @enumFromInt(request), @ptrCast(out[0..len])); } diff --git a/src/lib/binding/node.zig b/src/lib/binding/node.zig index 3128da6d..4c85adc7 100644 --- a/src/lib/binding/node.zig +++ b/src/lib/binding/node.zig @@ -34,8 +34,8 @@ fn bindings(env: c.napi_env) c.napi_value { } fn bind(env: c.napi_env, gen: anytype) c.napi_value { - const choices_size = @intCast(u32, gen.CHOICES_SIZE); - const logs_size = @intCast(u32, gen.LOGS_SIZE); + const choices_size: u32 = @intCast(gen.CHOICES_SIZE); + const logs_size: u32 = @intCast(gen.LOGS_SIZE); var object = Object.init(env); const properties = [_]c.napi_property_descriptor{ Property.init("CHOICES_SIZE", .{ .value = Number.init(env, choices_size) }), @@ -61,10 +61,9 @@ fn update(gen: anytype) c.napi_callback { assert(len == @sizeOf(gen.Battle(gen.PRNG))); assert(data != null); - var aligned = @alignCast(@alignOf(*gen.Battle(gen.PRNG)), data.?); - var battle = @ptrCast(*gen.Battle(gen.PRNG), aligned); - const c1 = @bitCast(pkmn.Choice, Number.get(env, argv[1], u8)); - const c2 = @bitCast(pkmn.Choice, Number.get(env, argv[2], u8)); + var battle: *gen.Battle(gen.PRNG) = @alignCast(@ptrCast(data.?)); + const c1: pkmn.Choice = @bitCast(Number.get(env, argv[1], u8)); + const c2: pkmn.Choice = @bitCast(Number.get(env, argv[2], u8)); var vtype: c.napi_valuetype = undefined; assert(c.napi_typeof(env, argv[3], &vtype) == c.napi_ok); @@ -75,14 +74,14 @@ fn update(gen: anytype) c.napi_callback { assert(len == gen.LOGS_SIZE); assert(data != null); - var buf = @ptrCast([*]u8, data.?)[0..gen.LOGS_SIZE]; + var buf = @as([*]u8, @ptrCast(data.?))[0..gen.LOGS_SIZE]; var stream = pkmn.protocol.ByteStream{ .buffer = buf }; var log = pkmn.protocol.FixedLog{ .writer = stream.writer() }; break :result battle.update(c1, c2, log); }, } catch unreachable; - return Number.init(env, @bitCast(u8, result)); + return Number.init(env, @as(u8, @bitCast(result))); } }.call; } @@ -101,19 +100,17 @@ fn choices(gen: anytype) c.napi_callback { assert(len == @sizeOf(gen.Battle(gen.PRNG))); assert(data != null); - var aligned = @alignCast(@alignOf(*gen.Battle(gen.PRNG)), data.?); - var battle = @ptrCast(*gen.Battle(gen.PRNG), aligned); - - const player = @enumFromInt(pkmn.Player, Number.get(env, argv[1], u8)); - const request = @enumFromInt(pkmn.Choice.Type, Number.get(env, argv[2], u8)); + var battle: *gen.Battle(gen.PRNG) = @alignCast(@ptrCast(data.?)); + const player: pkmn.Player = @enumFromInt(Number.get(env, argv[1], u8)); + const request: pkmn.Choice.Type = @enumFromInt(Number.get(env, argv[2], u8)); assert(c.napi_get_arraybuffer_info(env, argv[3], &data, &len) == c.napi_ok); assert(len == gen.CHOICES_SIZE); assert(data != null); - var out = @ptrCast([*]pkmn.Choice, data.?)[0..gen.CHOICES_SIZE]; + var out = @as([*]pkmn.Choice, @ptrCast(data.?))[0..gen.CHOICES_SIZE]; const n = battle.choices(player, request, out); - return Number.init(env, @bitCast(u8, n)); + return Number.init(env, @as(u8, @bitCast(n))); } }.call; } @@ -166,25 +163,25 @@ const Number = struct { .signed => { var result: i32 = undefined; assert(c.napi_get_value_int32(env, value, &result) == c.napi_ok); - return if (info.bits == 32) result else @intCast(T, result); + return if (info.bits == 32) result else @intCast(result); }, .unsigned => { var result: u32 = undefined; assert(c.napi_get_value_uint32(env, value, &result) == c.napi_ok); - return if (info.bits == 32) result else @intCast(T, result); + return if (info.bits == 32) result else @intCast(result); }, }, 33...63 => { var result: i64 = undefined; assert(c.napi_get_value_int64(env, value, &result) == c.napi_ok); - return @intCast(T, result); + return @intCast(result); }, else => { var result: i64 = undefined; assert(c.napi_get_value_int64(env, value, &result) == c.napi_ok); return switch (info.signedness) { - .signed => @as(T, value), - .unsigned => if (0 <= value) @intCast(T, value) else unreachable, + .signed => value, + .unsigned => if (0 <= value) @intCast(value) else unreachable, }; }, }, diff --git a/src/lib/binding/wasm.zig b/src/lib/binding/wasm.zig index 30144f9e..95be6b1b 100644 --- a/src/lib/binding/wasm.zig +++ b/src/lib/binding/wasm.zig @@ -5,6 +5,6 @@ export const SHOWDOWN = pkmn.options.showdown; export const LOG = pkmn.options.log; export const GEN1_CHOICES_SIZE = - std.math.ceilPowerOfTwo(u32, @intCast(u32, pkmn.gen1.CHOICES_SIZE)) catch unreachable; + std.math.ceilPowerOfTwo(u32, @as(u32, @intCast(pkmn.gen1.CHOICES_SIZE))) catch unreachable; export const GEN1_LOGS_SIZE = - std.math.ceilPowerOfTwo(u32, @intCast(u32, pkmn.gen1.LOGS_SIZE)) catch unreachable; + std.math.ceilPowerOfTwo(u32, @as(u32, @intCast(pkmn.gen1.LOGS_SIZE))) catch unreachable; diff --git a/src/lib/common/data.zig b/src/lib/common/data.zig index ba37bd31..4f4844fa 100644 --- a/src/lib/common/data.zig +++ b/src/lib/common/data.zig @@ -10,7 +10,7 @@ pub const Player = enum(u1) { /// Returns a player's opponent. pub inline fn foe(self: Player) Player { - return @enumFromInt(Player, ~@intFromEnum(self)); + return @enumFromInt(~@intFromEnum(self)); } /// Return's an identifier for the player's Pokémon at the one-indexed `id`. @@ -22,8 +22,8 @@ pub const Player = enum(u1) { test Player { try expectEqual(Player.P2, Player.P1.foe()); - try expectEqual(@as(u8, 0b0001), @bitCast(u8, Player.P1.ident(1))); - try expectEqual(@as(u8, 0b1101), @bitCast(u8, Player.P2.ident(5))); + try expectEqual(@as(u8, 0b0001), @as(u8, @bitCast(Player.P1.ident(1)))); + try expectEqual(@as(u8, 0b1101), @as(u8, @bitCast(Player.P2.ident(5)))); } /// An identifier for a specific Pokémon in battle. @@ -40,18 +40,18 @@ pub const ID = packed struct { /// Converts the identifier into a number. pub inline fn int(self: ID) u4 { - return @intCast(u4, @bitCast(u8, self)); + return @intCast(@as(u8, @bitCast(self))); } /// Decodes the identifier from a number. pub inline fn from(id: u4) ID { - return @bitCast(ID, @as(u8, id)); + return @bitCast(@as(u8, id)); } }; test ID { - try expectEqual(@as(u8, 0b0001), @bitCast(u8, ID{ .player = .P1, .id = 1 })); - try expectEqual(@as(u8, 0b1101), @bitCast(u8, ID{ .player = .P2, .id = 5 })); + try expectEqual(@as(u8, 0b0001), @as(u8, @bitCast(ID{ .player = .P1, .id = 1 }))); + try expectEqual(@as(u8, 0b1101), @as(u8, @bitCast(ID{ .player = .P2, .id = 5 }))); const id = ID{ .player = .P2, .id = 4 }; try expectEqual(id, ID.from(id.int())); } @@ -84,8 +84,8 @@ test Choice { const p2: Choice = .{ .type = .Switch, .data = 5 }; try expectEqual(5, p2.data); try expectEqual(Choice.Type.Move, p1.type); - try expectEqual(0b0001_0001, @bitCast(u8, p1)); - try expectEqual(0b0001_0110, @bitCast(u8, p2)); + try expectEqual(0b0001_0001, @as(u8, @bitCast(p1))); + try expectEqual(0b0001_0110, @as(u8, @bitCast(p2))); } /// The result of the battle - all results other than 'None' should be considered terminal. @@ -124,6 +124,6 @@ pub const Result = packed struct { }; test Result { - try expectEqual(0b0101_0000, @bitCast(u8, Result.Default)); - try expectEqual(0b1000_0000, @bitCast(u8, Result{ .p2 = .Switch })); + try expectEqual(0b0101_0000, @as(u8, @bitCast(Result.Default))); + try expectEqual(0b1000_0000, @as(u8, @bitCast(Result{ .p2 = .Switch }))); } diff --git a/src/lib/common/data/items.zig.tmpl b/src/lib/common/data/items.zig.tmpl index ab7bf729..cee19254 100644 --- a/src/lib/common/data/items.zig.tmpl +++ b/src/lib/common/data/items.zig.tmpl @@ -24,7 +24,7 @@ pub const Item = enum({{{ Item.type }}}) { pub inline fn boost(item: Item) ?Type { assert(item != .None); if (item == .PolkadotBow) return .Normal; - return if (@intFromEnum(item) <= {{{ Item.boosts }}}) @enumFromInt(Type, @intFromEnum(item) - 1) else null; + return if (@intFromEnum(item) <= {{{ Item.boosts }}}) @enumFromInt(@intFromEnum(item) - 1) else null; } /// Whether or not this item is a Berry. diff --git a/src/lib/common/protocol.zig b/src/lib/common/protocol.zig index b0e425ff..4a74da1e 100644 --- a/src/lib/common/protocol.zig +++ b/src/lib/common/protocol.zig @@ -234,9 +234,9 @@ pub fn Log(comptime Writer: type) type { assert(m != .None); try self.writer.writeAll(&.{ @intFromEnum(ArgType.Move), - @bitCast(u8, source), + @as(u8, @bitCast(source)), @intFromEnum(m), - @bitCast(u8, target), + @as(u8, @bitCast(target)), }); const none = &[_]u8{@intFromEnum(Move.None)}; try self.writer.writeAll(switch (@typeInfo(@TypeOf(from))) { @@ -254,7 +254,7 @@ pub fn Log(comptime Writer: type) type { pub fn switched(self: Self, ident: ID, pokemon: anytype) Error!void { if (!enabled) return; - try self.writer.writeAll(&.{ @intFromEnum(ArgType.Switch), @bitCast(u8, ident) }); + try self.writer.writeAll(&.{ @intFromEnum(ArgType.Switch), @as(u8, @bitCast(ident)) }); try self.writer.writeAll(&.{ @intFromEnum(pokemon.species), pokemon.level }); try self.writer.writeIntNative(u16, pokemon.hp); try self.writer.writeIntNative(u16, pokemon.stats.hp); @@ -266,7 +266,7 @@ pub fn Log(comptime Writer: type) type { assert(reason != .Disable); try self.writer.writeAll(&.{ @intFromEnum(ArgType.Cant), - @bitCast(u8, ident), + @as(u8, @bitCast(ident)), @intFromEnum(reason), }); } @@ -275,7 +275,7 @@ pub fn Log(comptime Writer: type) type { if (!enabled) return; try self.writer.writeAll(&.{ @intFromEnum(ArgType.Cant), - @bitCast(u8, ident), + @as(u8, @bitCast(ident)), @intFromEnum(Cant.Disable), @intFromEnum(m), }); @@ -283,7 +283,7 @@ pub fn Log(comptime Writer: type) type { pub fn faint(self: Self, ident: ID, done: bool) Error!void { if (!enabled) return; - try self.writer.writeAll(&.{ @intFromEnum(ArgType.Faint), @bitCast(u8, ident) }); + try self.writer.writeAll(&.{ @intFromEnum(ArgType.Faint), @as(u8, @bitCast(ident)) }); if (done) try self.writer.writeByte(@intFromEnum(ArgType.None)); } @@ -311,7 +311,7 @@ pub fn Log(comptime Writer: type) type { pub fn damage(self: Self, ident: ID, pokemon: anytype, reason: Damage) Error!void { if (!enabled) return; assert(@intFromEnum(reason) <= @intFromEnum(Damage.LeechSeed)); - try self.writer.writeAll(&.{ @intFromEnum(ArgType.Damage), @bitCast(u8, ident) }); + try self.writer.writeAll(&.{ @intFromEnum(ArgType.Damage), @as(u8, @bitCast(ident)) }); try self.writer.writeIntNative(u16, pokemon.hp); try self.writer.writeIntNative(u16, pokemon.stats.hp); try self.writer.writeAll(&.{ pokemon.status, @intFromEnum(reason) }); @@ -326,20 +326,20 @@ pub fn Log(comptime Writer: type) type { ) Error!void { if (!enabled) return; assert(@intFromEnum(reason) == @intFromEnum(Damage.RecoilOf)); - try self.writer.writeAll(&.{ @intFromEnum(ArgType.Damage), @bitCast(u8, ident) }); + try self.writer.writeAll(&.{ @intFromEnum(ArgType.Damage), @as(u8, @bitCast(ident)) }); try self.writer.writeIntNative(u16, pokemon.hp); try self.writer.writeIntNative(u16, pokemon.stats.hp); try self.writer.writeAll(&.{ pokemon.status, @intFromEnum(reason), - @bitCast(u8, source), + @as(u8, @bitCast(source)), }); } pub fn heal(self: Self, ident: ID, pokemon: anytype, reason: Heal) Error!void { if (!enabled) return; assert(reason != .Drain); - try self.writer.writeAll(&.{ @intFromEnum(ArgType.Heal), @bitCast(u8, ident) }); + try self.writer.writeAll(&.{ @intFromEnum(ArgType.Heal), @as(u8, @bitCast(ident)) }); try self.writer.writeIntNative(u16, pokemon.hp); try self.writer.writeIntNative(u16, pokemon.stats.hp); try self.writer.writeAll(&.{ pokemon.status, @intFromEnum(reason) }); @@ -347,13 +347,13 @@ pub fn Log(comptime Writer: type) type { pub fn drain(self: Self, source: ID, pokemon: anytype, target: ID) Error!void { if (!enabled) return; - try self.writer.writeAll(&.{ @intFromEnum(ArgType.Heal), @bitCast(u8, source) }); + try self.writer.writeAll(&.{ @intFromEnum(ArgType.Heal), @as(u8, @bitCast(source)) }); try self.writer.writeIntNative(u16, pokemon.hp); try self.writer.writeIntNative(u16, pokemon.stats.hp); try self.writer.writeAll(&.{ pokemon.status, @intFromEnum(Heal.Drain), - @bitCast(u8, target), + @as(u8, @bitCast(target)), }); } @@ -362,7 +362,7 @@ pub fn Log(comptime Writer: type) type { assert(reason != .From); try self.writer.writeAll(&.{ @intFromEnum(ArgType.Status), - @bitCast(u8, ident), + @as(u8, @bitCast(ident)), value, @intFromEnum(reason), }); @@ -372,7 +372,7 @@ pub fn Log(comptime Writer: type) type { if (!enabled) return; try self.writer.writeAll(&.{ @intFromEnum(ArgType.Status), - @bitCast(u8, ident), + @as(u8, @bitCast(ident)), value, @intFromEnum(Status.From), @intFromEnum(m), @@ -383,7 +383,7 @@ pub fn Log(comptime Writer: type) type { if (!enabled) return; try self.writer.writeAll(&.{ @intFromEnum(ArgType.CureStatus), - @bitCast(u8, ident), + @as(u8, @bitCast(ident)), value, @intFromEnum(reason), }); @@ -394,9 +394,9 @@ pub fn Log(comptime Writer: type) type { assert(num != 0 and (reason != .Rage or num > 0)); try self.writer.writeAll(&.{ @intFromEnum(ArgType.Boost), - @bitCast(u8, ident), + @as(u8, @bitCast(ident)), @intFromEnum(reason), - @intCast(u8, num + 6), + @as(u8, @intCast(num + 6)), }); } @@ -409,21 +409,21 @@ pub fn Log(comptime Writer: type) type { if (!enabled) return; try self.writer.writeAll(&.{ @intFromEnum(ArgType.Fail), - @bitCast(u8, ident), + @as(u8, @bitCast(ident)), @intFromEnum(reason), }); } pub fn miss(self: Self, source: ID) Error!void { if (!enabled) return; - try self.writer.writeAll(&.{ @intFromEnum(ArgType.Miss), @bitCast(u8, source) }); + try self.writer.writeAll(&.{ @intFromEnum(ArgType.Miss), @as(u8, @bitCast(source)) }); } pub fn hitcount(self: Self, ident: ID, num: u8) Error!void { if (!enabled) return; try self.writer.writeAll(&.{ @intFromEnum(ArgType.HitCount), - @bitCast(u8, ident), + @as(u8, @bitCast(ident)), num, }); } @@ -432,21 +432,24 @@ pub fn Log(comptime Writer: type) type { if (!enabled) return; try self.writer.writeAll(&.{ @intFromEnum(ArgType.Prepare), - @bitCast(u8, source), + @as(u8, @bitCast(source)), @intFromEnum(m), }); } pub fn mustrecharge(self: Self, ident: ID) Error!void { if (!enabled) return; - try self.writer.writeAll(&.{ @intFromEnum(ArgType.MustRecharge), @bitCast(u8, ident) }); + try self.writer.writeAll(&.{ + @intFromEnum(ArgType.MustRecharge), + @as(u8, @bitCast(ident)), + }); } pub fn activate(self: Self, ident: ID, reason: Activate) Error!void { if (!enabled) return; try self.writer.writeAll(&.{ @intFromEnum(ArgType.Activate), - @bitCast(u8, ident), + @as(u8, @bitCast(ident)), @intFromEnum(reason), }); } @@ -461,7 +464,7 @@ pub fn Log(comptime Writer: type) type { assert(@intFromEnum(reason) < @intFromEnum(Start.TypeChange)); try self.writer.writeAll(&.{ @intFromEnum(ArgType.Start), - @bitCast(u8, ident), + @as(u8, @bitCast(ident)), @intFromEnum(reason), }); } @@ -470,10 +473,10 @@ pub fn Log(comptime Writer: type) type { if (!enabled) return; try self.writer.writeAll(&.{ @intFromEnum(ArgType.Start), - @bitCast(u8, source), + @as(u8, @bitCast(source)), @intFromEnum(Start.TypeChange), - @bitCast(u8, types), - @bitCast(u8, target), + @as(u8, @bitCast(types)), + @as(u8, @bitCast(target)), }); } @@ -482,7 +485,7 @@ pub fn Log(comptime Writer: type) type { assert(@intFromEnum(reason) > @intFromEnum(Start.TypeChange)); try self.writer.writeAll(&.{ @intFromEnum(ArgType.Start), - @bitCast(u8, ident), + @as(u8, @bitCast(ident)), @intFromEnum(reason), @intFromEnum(m), }); @@ -492,7 +495,7 @@ pub fn Log(comptime Writer: type) type { if (!enabled) return; try self.writer.writeAll(&.{ @intFromEnum(ArgType.End), - @bitCast(u8, ident), + @as(u8, @bitCast(ident)), @intFromEnum(reason), }); } @@ -504,27 +507,30 @@ pub fn Log(comptime Writer: type) type { pub fn crit(self: Self, ident: ID) Error!void { if (!enabled) return; - try self.writer.writeAll(&.{ @intFromEnum(ArgType.Crit), @bitCast(u8, ident) }); + try self.writer.writeAll(&.{ @intFromEnum(ArgType.Crit), @as(u8, @bitCast(ident)) }); } pub fn supereffective(self: Self, ident: ID) Error!void { if (!enabled) return; try self.writer.writeAll(&.{ @intFromEnum(ArgType.SuperEffective), - @bitCast(u8, ident), + @as(u8, @bitCast(ident)), }); } pub fn resisted(self: Self, ident: ID) Error!void { if (!enabled) return; - try self.writer.writeAll(&.{ @intFromEnum(ArgType.Resisted), @bitCast(u8, ident) }); + try self.writer.writeAll(&.{ + @intFromEnum(ArgType.Resisted), + @as(u8, @bitCast(ident)), + }); } pub fn immune(self: Self, ident: ID, reason: Immune) Error!void { if (!enabled) return; try self.writer.writeAll(&.{ @intFromEnum(ArgType.Immune), - @bitCast(u8, ident), + @as(u8, @bitCast(ident)), @intFromEnum(reason), }); } @@ -533,8 +539,8 @@ pub fn Log(comptime Writer: type) type { if (!enabled) return; try self.writer.writeAll(&.{ @intFromEnum(ArgType.Transform), - @bitCast(u8, source), - @bitCast(u8, target), + @as(u8, @bitCast(source)), + @as(u8, @bitCast(target)), }); } @@ -600,7 +606,7 @@ pub fn format(comptime formatter: Formatter, a: []const u8, b: ?[]const u8, colo var i: usize = 0; while (i < a.len) { - const arg = @enumFromInt(ArgType, a[i]); + const arg: ArgType = @enumFromInt(a[i]); const name = switch (arg) { .None => if (color) "\x1b[2m-\x1b[0m" else "-", .LastStill => "|[still]", @@ -646,17 +652,17 @@ pub fn format(comptime formatter: Formatter, a: []const u8, b: ?[]const u8, colo .OHKO, => {}, .Move => { - const source = ID.from(@intCast(u4, a[i])); + const source = ID.from(@intCast(a[i])); printc(" {s}({d})", .{ @tagName(source.player), source.id }, a, b, &i, 1, color); printc(" {s}", .{formatter(.Move, a[i])}, a, b, &i, 1, color); - const target = ID.from(@intCast(u4, a[i])); + const target = ID.from(@intCast(a[i])); printc(" {s}({d})", .{ @tagName(target.player), target.id }, a, b, &i, 1, color); - const reason = @enumFromInt(Move, a[i]); + const reason: Move = @enumFromInt(a[i]); printc(" {s}", .{@tagName(reason)}, a, b, &i, 1, color); if (reason == .From) printc(" {s}", .{formatter(.Move, a[i])}, a, b, &i, 1, color); }, .Switch => { - const id = ID.from(@intCast(u4, a[i])); + const id = ID.from(@intCast(a[i])); printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color); printc(" {s}", .{formatter(.Species, a[i])}, a, b, &i, 1, color); printc(" L{d}", .{a[i]}, a, b, &i, 1, color); @@ -677,9 +683,9 @@ pub fn format(comptime formatter: Formatter, a: []const u8, b: ?[]const u8, colo printc(" {s}", .{formatter(.Status, a[i])}, a, b, &i, 1, color); }, .Cant => { - const id = ID.from(@intCast(u4, a[i])); + const id = ID.from(@intCast(a[i])); printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color); - const reason = @enumFromInt(Cant, a[i]); + const reason: Cant = @enumFromInt(a[i]); printc(" {s}", .{@tagName(reason)}, a, b, &i, 1, color); if (reason == .Disable) { printc(" {s}", .{formatter(.Move, a[i])}, a, b, &i, 1, color); @@ -692,7 +698,7 @@ pub fn format(comptime formatter: Formatter, a: []const u8, b: ?[]const u8, colo .SuperEffective, .Resisted, => { - const id = ID.from(@intCast(u4, a[i])); + const id = ID.from(@intCast(a[i])); printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color); }, .Turn => { @@ -702,9 +708,11 @@ pub fn format(comptime formatter: Formatter, a: []const u8, b: ?[]const u8, colo }; printc(" {d}", .{turn}, a, b, &i, 2, color); }, - .Win => printc(" {s}", .{@tagName(@enumFromInt(Player, a[i]))}, a, b, &i, 1, color), + .Win => { + printc(" {s}", .{@tagName(@as(Player, @enumFromInt(a[i])))}, a, b, &i, 1, color); + }, .Damage, .Heal => { - var id = ID.from(@intCast(u4, a[i])); + var id = ID.from(@intCast(a[i])); printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color); switch (endian) { .Big => { @@ -722,68 +730,69 @@ pub fn format(comptime formatter: Formatter, a: []const u8, b: ?[]const u8, colo } printc(" {s}", .{formatter(.Status, a[i])}, a, b, &i, 1, color); if (arg == .Damage) { - const reason = a[i]; - printc(" {s}", .{@tagName(@enumFromInt(Damage, reason))}, a, b, &i, 1, color); - if (reason == @intFromEnum(Damage.RecoilOf)) { - id = ID.from(@intCast(u4, a[i])); + const reason: Damage = @enumFromInt(a[i]); + printc(" {s}", .{@tagName(reason)}, a, b, &i, 1, color); + if (reason == .RecoilOf) { + id = ID.from(@intCast(a[i])); printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color); } } else { - const reason = @enumFromInt(Heal, a[i]); + const reason: Heal = @enumFromInt(a[i]); printc(" {s}", .{@tagName(reason)}, a, b, &i, 1, color); if (reason == .Drain) { - id = ID.from(@intCast(u4, a[i])); + id = ID.from(@intCast(a[i])); printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color); } } }, .Status => { - const id = ID.from(@intCast(u4, a[i])); + const id = ID.from(@intCast(a[i])); printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color); printc(" {s}", .{formatter(.Status, a[i])}, a, b, &i, 1, color); - const reason = @enumFromInt(Status, a[i]); + const reason: Status = @enumFromInt(a[i]); printc(" {s}", .{@tagName(reason)}, a, b, &i, 1, color); if (reason == .From) printc(" {s}", .{formatter(.Move, a[i])}, a, b, &i, 1, color); }, .CureStatus => { - const id = ID.from(@intCast(u4, a[i])); + const id = ID.from(@intCast(a[i])); printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color); printc(" {s}", .{formatter(.Status, a[i])}, a, b, &i, 1, color); - printc(" {s}", .{@tagName(@enumFromInt(CureStatus, a[i]))}, a, b, &i, 1, color); + const reason: CureStatus = @enumFromInt(a[i]); + printc(" {s}", .{@tagName(reason)}, a, b, &i, 1, color); }, .Boost => { - const id = ID.from(@intCast(u4, a[i])); + const id = ID.from(@intCast(a[i])); printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color); - printc(" {s}", .{@tagName(@enumFromInt(Boost, a[i]))}, a, b, &i, 1, color); + printc(" {s}", .{@tagName(@as(Boost, @enumFromInt(a[i])))}, a, b, &i, 1, color); printc(" {d}", .{a[i]}, a, b, &i, 1, color); }, .Fail => { - const id = ID.from(@intCast(u4, a[i])); + const id = ID.from(@intCast(a[i])); printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color); - printc(" {s}", .{@tagName(@enumFromInt(Fail, a[i]))}, a, b, &i, 1, color); + printc(" {s}", .{@tagName(@as(Fail, @enumFromInt(a[i])))}, a, b, &i, 1, color); }, .HitCount => { - const id = ID.from(@intCast(u4, a[i])); + const id = ID.from(@intCast(a[i])); printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color); printc(" {d}", .{a[i]}, a, b, &i, 1, color); }, .Prepare => { - const id = ID.from(@intCast(u4, a[i])); + const id = ID.from(@intCast(a[i])); printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color); printc(" {s}", .{formatter(.Move, a[i])}, a, b, &i, 1, color); }, .Activate => { - const id = ID.from(@intCast(u4, a[i])); + const id = ID.from(@intCast(a[i])); printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color); - printc(" {s}", .{@tagName(@enumFromInt(Activate, a[i]))}, a, b, &i, 1, color); + printc(" {s}", .{@tagName(@as(Activate, @enumFromInt(a[i])))}, a, b, &i, 1, color); }, .Start => { - const id = ID.from(@intCast(u4, a[i])); + const id = ID.from(@intCast(a[i])); printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color); const reason = a[i]; - printc(" {s}", .{@tagName(@enumFromInt(Start, reason))}, a, b, &i, 1, color); - if (@enumFromInt(Start, reason) == .TypeChange) { - const types = @bitCast(gen1.Types, a[i]); + printc(" {s}", .{@tagName(@as(Start, @enumFromInt(reason)))}, a, b, &i, 1, color); + if (@as(Start, @enumFromInt(reason)) == .TypeChange) { + const types = @as(gen1.Types, @bitCast(a[i])); const args = .{ formatter(.Type, @intFromEnum(types.type1)), formatter(.Type, @intFromEnum(types.type2)), @@ -794,19 +803,19 @@ pub fn format(comptime formatter: Formatter, a: []const u8, b: ?[]const u8, colo } }, .End => { - const id = ID.from(@intCast(u4, a[i])); + const id = ID.from(@intCast(a[i])); printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color); - printc(" {s}", .{@tagName(@enumFromInt(End, a[i]))}, a, b, &i, 1, color); + printc(" {s}", .{@tagName(@as(End, @enumFromInt(a[i])))}, a, b, &i, 1, color); }, .Immune => { - const id = ID.from(@intCast(u4, a[i])); + const id = ID.from(@intCast(a[i])); printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color); - printc(" {s}", .{@tagName(@enumFromInt(Immune, a[i]))}, a, b, &i, 1, color); + printc(" {s}", .{@tagName(@as(Immune, @enumFromInt(a[i])))}, a, b, &i, 1, color); }, .Transform => { - const source = ID.from(@intCast(u4, a[i])); + const source = ID.from(@intCast(a[i])); printc(" {s}({d})", .{ @tagName(source.player), source.id }, a, b, &i, 1, color); - const target = ID.from(@intCast(u4, a[i])); + const target = ID.from(@intCast(a[i])); printc(" {s}({d})", .{ @tagName(target.player), target.id }, a, b, &i, 1, color); }, else => unreachable, @@ -912,9 +921,9 @@ fn expectLog1(expected: []const u8, actual: []const u8) !void { fn gen1Formatter(kind: Kind, byte: u8) []const u8 { return switch (kind) { - .Move => @tagName(@enumFromInt(M, byte)), - .Species => @tagName(@enumFromInt(S, byte)), - .Type => @tagName(@enumFromInt(gen1.Type, byte)), + .Move => @tagName(@as(M, @enumFromInt(byte))), + .Species => @tagName(@as(S, @enumFromInt(byte))), + .Type => @tagName(@as(gen1.Type, @enumFromInt(byte))), .Status => gen1.Status.name(byte), }; } diff --git a/src/lib/common/rng.zig b/src/lib/common/rng.zig index 2dbeea24..99d811d5 100644 --- a/src/lib/common/rng.zig +++ b/src/lib/common/rng.zig @@ -47,7 +47,7 @@ pub const PSRNG = extern struct { } pub fn range(self: *PSRNG, comptime T: type, from: T, to: Bound(T)) T { - return @intCast(T, @as(u64, self.src.next()) * (to - from) / divisor + from); + return @intCast(@as(u64, self.src.next()) * (to - from) / divisor + from); } pub fn chance(self: *PSRNG, comptime T: type, numerator: T, denominator: Bound(T)) bool { @@ -80,7 +80,7 @@ pub const Gen12 = extern struct { } pub fn percent(p: u8) u8 { - return @intCast(u8, (@as(u16, p) * 0xFF) / 100); + return @intCast((@as(u16, p) * 0xFF) / 100); } pub fn next(self: *Gen12) u8 { @@ -114,7 +114,7 @@ pub const Gen34 = extern struct { pub fn next(self: *Gen34) u16 { self.advance(); - return @intCast(u16, self.seed >> 16); + return @intCast(self.seed >> 16); } pub fn advance(self: *Gen34) void { @@ -144,7 +144,7 @@ pub const Gen56 = extern struct { pub fn next(self: *Gen56) u32 { self.advance(); - return @intCast(u32, self.seed >> 32); + return @intCast(self.seed >> 32); } pub fn advance(self: *Gen56) void { @@ -190,7 +190,7 @@ pub fn FixedRNG(comptime gen: comptime_int, comptime len: usize) type { pub fn range(self: *Self, comptime T: type, from: T, to: Bound(T)) T { assert(showdown); - return @intCast(T, @as(u64, self.next()) * (to - from) / divisor + from); + return @intCast(@as(u64, self.next()) * (to - from) / divisor + from); } pub fn chance( diff --git a/src/lib/gen1/data.zig b/src/lib/gen1/data.zig index 6281bd1b..c2045f44 100644 --- a/src/lib/gen1/data.zig +++ b/src/lib/gen1/data.zig @@ -72,7 +72,7 @@ pub fn Battle(comptime RNG: anytype) type { /// Returns an identifier for the active Pokémon of `player`. pub inline fn active(self: *Self, player: Player) ID { - return player.ident(@intCast(u3, self.side(player).order[0])); + return player.ident(@intCast(self.side(player).order[0])); } /// Returns the result of applying Player 1's choice `c1` and Player 2's choice `c2` to the @@ -243,13 +243,13 @@ pub const Status = enum(u8) { /// Whether or not the status `num` is the same as `status`. pub inline fn is(num: u8, status: Status) bool { if (status == .SLP) return Status.duration(num) > 0; - return ((num >> @intCast(u3, @intFromEnum(status))) & 1) != 0; + return ((num >> @intCast(@intFromEnum(status))) & 1) != 0; } /// Initializes a non-sleep `status`. Use `slp` or `slf` to initialize a sleep status. pub inline fn init(status: Status) u8 { assert(status != .SLP and status != .EXT); - return @as(u8, 1) << @intCast(u3, @intFromEnum(status)); + return @as(u8, 1) << @intCast(@intFromEnum(status)); } /// Initializes a non self-inflicted sleep status with duration `dur`. @@ -266,7 +266,7 @@ pub const Status = enum(u8) { /// Returns the duration of a sleep status. pub inline fn duration(num: u8) u3 { - return @intCast(u3, num & SLP); + return @intCast(num & SLP); } /// Returns whether `num` reflects any status. @@ -413,10 +413,11 @@ pub fn Stats(comptime T: type) type { /// Computes the value of `stat` given a `base`, `dv`, stat `exp` and `level`. pub fn calc(comptime stat: []const u8, base: T, dv: u4, exp: u16, level: u8) T { assert(level > 0 and level <= 100); - const evs = @min(255, @intFromFloat(u16, @ceil(@sqrt(@floatFromInt(f32, exp))))); + const float: f32 = @floatFromInt(exp); + const evs = @min(255, @as(u16, @intFromFloat(@ceil(@sqrt(float))))); const core: u32 = (2 *% (@as(u32, base) +% dv)) +% (evs / 4); const factor: u32 = if (std.mem.eql(u8, stat, "hp")) level + 10 else 5; - return @intCast(T, core *% @as(u32, level) / 100 +% factor); + return @intCast(core *% @as(u32, level) / 100 +% factor); } }; } diff --git a/src/lib/gen1/data/types.zig b/src/lib/gen1/data/types.zig index 81e43d8f..f946433e 100644 --- a/src/lib/gen1/data/types.zig +++ b/src/lib/gen1/data/types.zig @@ -102,7 +102,7 @@ pub const Type = enum(u4) { /// The precedence order of type `t2` vs. type `t1`. pub fn precedence(t1: Type, t2: Type) u8 { for (PRECEDENCE, 0..) |matchup, i| { - if (matchup.type1 == t1 and matchup.type2 == t2) return @intCast(u8, i); + if (matchup.type1 == t1 and matchup.type2 == t2) return @intCast(i); } unreachable; } diff --git a/src/lib/gen1/helpers.zig b/src/lib/gen1/helpers.zig index b98ec17b..1fbfb5ff 100644 --- a/src/lib/gen1/helpers.zig +++ b/src/lib/gen1/helpers.zig @@ -90,7 +90,7 @@ pub const Side = struct { for (0..ps.len) |i| { side.pokemon[i] = Pokemon.init(ps[i]); - side.order[i] = @intCast(u4, i) + 1; + side.order[i] = @as(u4, @intCast(i)) + 1; } return side; } @@ -101,7 +101,7 @@ pub const Side = struct { for (0..n) |i| { side.pokemon[i] = Pokemon.random(rand, opt); - side.order[i] = @intCast(u4, i) + 1; + side.order[i] = @as(u4, @intCast(i)) + 1; } return side; @@ -139,7 +139,7 @@ pub const Pokemon = struct { for (p.moves, 0..) |m, j| { pokemon.moves[j].id = m; // NB: PP can be at most 61 legally (though can overflow to 63) - pokemon.moves[j].pp = @intCast(u8, @min(Move.pp(m) / 5 * 8, 61)); + pokemon.moves[j].pp = @intCast(@min(Move.pp(m) / 5 * 8, 61)); } if (p.hp) |hp| { pokemon.hp = hp; @@ -153,7 +153,7 @@ pub const Pokemon = struct { } pub fn random(rand: *PSRNG, opt: Options) data.Pokemon { - const s = @enumFromInt(Species, rand.range(u8, 1, Species.size + 1)); + const s: Species = @enumFromInt(rand.range(u8, 1, Species.size + 1)); const species = Species.get(s); const lvl = if (rand.chance(u8, 1, 20)) rand.range(u8, 1, 99 + 1) else 100; var stats: Stats(u16) = .{}; @@ -176,15 +176,15 @@ pub const Pokemon = struct { for (0..n) |i| { var m: Move = .None; sample: while (true) { - m = @enumFromInt(Move, rand.range(u8, 1, Move.size - 1 + 1)); + m = @enumFromInt(rand.range(u8, 1, Move.size - 1 + 1)); if (opt.block and blocked(m)) continue :sample; for (0..i) |j| if (ms[j].id == m) continue :sample; break; } - const pp_ups = + const pp_ups: u8 = if (!opt.cleric and rand.chance(u8, 1, 10)) rand.range(u2, 0, 2 + 1) else 3; // NB: PP can be at most 61 legally (though can overflow to 63) - const max_pp = @intCast(u8, Move.pp(m) + @as(u8, pp_ups) * @min(Move.pp(m) / 5, 7)); + const max_pp: u8 = @intCast(Move.pp(m) + pp_ups * @min(Move.pp(m) / 5, 7)); ms[i] = .{ .id = m, .pp = if (opt.cleric) max_pp else rand.range(u8, 0, max_pp + 1), diff --git a/src/lib/gen1/mechanics.zig b/src/lib/gen1/mechanics.zig index 99654506..ab358de0 100644 --- a/src/lib/gen1/mechanics.zig +++ b/src/lib/gen1/mechanics.zig @@ -183,7 +183,7 @@ fn selectMove( battle.last_moves.p1_index else battle.last_moves.p2_index; - const last = side.active.move(@intCast(u4, slot)); + const last = side.active.move(slot); if (last.id == .Metronome) side.last_selected_move = last.id; if (last.id == .MirrorMove) return Result.Error; } @@ -237,9 +237,9 @@ fn saveMove(battle: anytype, player: Player, choice: ?Choice) void { side.last_selected_move = move.id; if (player == .P1) { - battle.last_moves.p1_index = @intCast(u3, c.data); + battle.last_moves.p1_index = @intCast(c.data); } else { - battle.last_moves.p2_index = @intCast(u3, c.data); + battle.last_moves.p2_index = @intCast(c.data); } } } @@ -420,7 +420,7 @@ fn executeMove( var side = battle.side(player); if (choice.type == .Switch) { - try switchIn(battle, player, @intCast(u4, choice.data), false, log); + try switchIn(battle, player, choice.data, false, log); return null; } @@ -436,7 +436,7 @@ fn executeMove( } assert(choice.type == .Move); - var mslot = @intCast(u4, choice.data); + var mslot: u4 = @intCast(choice.data); // Sadly, we can't even check `Move.get(side.last_selected_move).effect == .Binding` here // because Pokémon Showdown's Mirror Move implementation clobbers side.last_selected_move var auto = showdown and side.last_selected_move != .None; @@ -445,7 +445,7 @@ fn executeMove( if (mslot == 0 and side.last_selected_move != .None and side.last_selected_move != .Struggle) { // choice.data == 0 only happens with Struggle on Pokémon Showdown assert(!showdown); - mslot = @intCast(u4, if (player == .P1) + mslot = @intCast(if (player == .P1) battle.last_moves.p1_index else battle.last_moves.p2_index); @@ -469,7 +469,7 @@ fn executeMove( } else if (showdown and side.active.volatiles.Charging) { // Incorrect mslot with Pokémon Showdown choice semantics so we need to recover from index assert(mslot == 1); - mslot = @intCast(u4, if (player == .P1) + mslot = @intCast(if (player == .P1) battle.last_moves.p1_index else battle.last_moves.p2_index); @@ -796,11 +796,11 @@ fn decrementPP(side: *Side, mslot: u4, auto: bool) void { if (volatiles.Bide) return; assert(active.move(mslot).pp > 0 or auto); - active.move(mslot).pp = @intCast(u6, active.move(mslot).pp) -% 1; + active.move(mslot).pp = @as(u6, @intCast(active.move(mslot).pp)) -% 1; if (volatiles.Transform) return; assert(side.stored().move(mslot).pp > 0 or auto); - side.stored().move(mslot).pp = @intCast(u6, side.stored().move(mslot).pp) -% 1; + side.stored().move(mslot).pp = @as(u6, @intCast(side.stored().move(mslot).pp)) -% 1; assert(active.move(mslot).pp == side.stored().move(mslot).pp); } @@ -808,12 +808,12 @@ fn incrementPP(side: *Side, mslot: u4) void { var active = &side.active; const volatiles = &active.volatiles; - active.move(mslot).pp = @intCast(u6, active.move(mslot).pp) +% 1; + active.move(mslot).pp = @as(u6, @intCast(active.move(mslot).pp)) +% 1; // GLITCH: No check for Transform means an empty/incorrect stored slot can get incremented if (showdown and volatiles.Transform) return; assert(mslot > 0 and mslot <= 4); - side.stored().moves[mslot - 1].pp = @intCast(u6, side.stored().moves[mslot - 1].pp) +% 1; + side.stored().moves[mslot - 1].pp = @as(u6, @intCast(side.stored().moves[mslot - 1].pp)) +% 1; } // Pokémon Showdown does hit/multi/crit/damage instead of crit/damage/hit/multi @@ -1123,7 +1123,7 @@ fn calcDamage( d = @min(997, d); d += 2; - battle.last_damage = @intCast(u16, d); + battle.last_damage = @intCast(d); return true; } @@ -1162,7 +1162,7 @@ fn adjustDamage(battle: anytype, player: Player) u16 { fn randomizeDamage(battle: anytype) void { if (battle.last_damage <= 1) return; const random = Rolls.damage(battle); - battle.last_damage = @intCast(u16, @as(u32, battle.last_damage) *% random / 255); + battle.last_damage = @intCast(@as(u32, battle.last_damage) *% random / 255); } fn specialDamage(battle: anytype, player: Player, move: Move.Data, log: anytype) !?Result { @@ -1178,7 +1178,7 @@ fn specialDamage(battle: anytype, player: Player, move: Move.Data, log: anytype) .DragonRage => 40, // GLITCH: if power = 0 then a desync occurs (or a miss on Pokémon Showdown) .Psywave => power: { - const max = @intCast(u8, @as(u16, side.stored().level) * 3 / 2); + const max: u8 = @intCast(@as(u16, side.stored().level) * 3 / 2); // GLITCH: Psywave infinite glitch loop if (!showdown and max <= 1) return Result.Error; break :power Rolls.psywave(battle, max); @@ -1267,7 +1267,7 @@ fn applyDamage( return true; } else { // Safe to truncate since less than subbed.volatiles.substitute which is a u8 - subbed.active.volatiles.substitute -= @intCast(u8, battle.last_damage); + subbed.active.volatiles.substitute -= @intCast(battle.last_damage); try log.activate(battle.active(sub_player), .Substitute); return false; } @@ -1379,9 +1379,9 @@ fn moveHit(battle: anytype, player: Player, move: Move.Data, immune: *bool, mist assert(!overwritten or (0 < state and state <= 255 and !side.active.volatiles.Bide)); var accuracy = if (overwritten) state else @as(u16, Gen12.percent(move.accuracy)); - var boost = BOOSTS[@intCast(u4, @as(i8, side.active.boosts.accuracy) + 6)]; + var boost = BOOSTS[@intCast(@as(i8, side.active.boosts.accuracy) + 6)]; accuracy = accuracy * boost[0] / boost[1]; - boost = BOOSTS[@intCast(u4, @as(i8, -foe.active.boosts.evasion) + 6)]; + boost = BOOSTS[@intCast(@as(i8, -foe.active.boosts.evasion) + 6)]; accuracy = accuracy * boost[0] / boost[1]; accuracy = @min(255, @max(1, accuracy)); @@ -1561,7 +1561,7 @@ fn endTurn(battle: anytype, log: anytype) @TypeOf(log).Error!Result { fn checkEBC(battle: anytype) bool { for (battle.sides, 0..) |side, i| { - const foe = battle.sides[~@intCast(u1, i)]; + const foe = battle.sides[~@as(u1, @intCast(i))]; var foe_all_ghosts = true; var foe_all_transform = true; @@ -1855,7 +1855,7 @@ pub const Effects = struct { return Result.Error; } - volatiles.disabled_move = @intCast(u3, Rolls.moveSlot(battle, &foe.active.moves, n)); + volatiles.disabled_move = @intCast(Rolls.moveSlot(battle, &foe.active.moves, n)); volatiles.disabled_duration = Rolls.disableDuration(battle); try log.startEffect(foe_ident, .Disable, foe.active.move(volatiles.disabled_move).id); @@ -1954,7 +1954,7 @@ pub const Effects = struct { // Pokémon Showdown clears P1 then P2 instead of status -> side -> foe if (showdown) { for (&battle.sides, 0..) |*s, i| { - const p = @enumFromInt(Player, i); + const p: Player = @enumFromInt(i); // Pokémon Showdown incorrectly does not prevent sleep/freeze from moving if (p != player and Status.any(s.stored().status)) { try log.curestatus(foe_ident, foe_stored.status, .Silent); @@ -2055,7 +2055,7 @@ pub const Effects = struct { const has_mimic = has_mimic: { for (side.active.moves, 0..) |m, i| { if (m.id == .Mimic) { - oslot = @intCast(u8, i + 1); + oslot = @intCast(i + 1); break :has_mimic true; } } @@ -2204,9 +2204,9 @@ pub const Effects = struct { assert(showdown or battle.last_damage > 0); if (showdown and battle.last_damage == 0) return; - const damage = @intCast(i16, @max(battle.last_damage / + const damage: i16 = @intCast(@max(battle.last_damage / @as(u8, if (side.last_selected_move == .Struggle) 2 else 4), 1)); - stored.hp = @intCast(u16, @max(@intCast(i16, stored.hp) - damage, 0)); + stored.hp = @intCast(@max(@as(i16, @intCast(stored.hp)) - damage, 0)); try log.damageOf(battle.active(player), stored, .RecoilOf, battle.active(player.foe())); if (showdown and stored.hp == 0) residual.* = false; @@ -2266,7 +2266,7 @@ pub const Effects = struct { assert(side.stored().stats.hp <= 1023); // Will be 0 if HP is <= 3 meaning that the user gets a 1 HP Substitute for "free" - const hp = @intCast(u8, side.stored().stats.hp / 4); + const hp: u8 = @intCast(side.stored().stats.hp / 4); // Pokénon Showdown incorrectly checks for 1/4 HP based on `target.maxhp / 4` which returns // a floating point value and thus only correctly implements the Substitute 1/4 glitch when // the target's HP is exactly divisible by 4 (here we're using an inlined divCeil routine to @@ -2361,7 +2361,7 @@ pub const Effects = struct { assert(boosts.atk >= -6 and boosts.atk <= 6); if (boosts.atk == 6) return try log.fail(ident, .None); const n: u2 = if (move.effect == .AttackUp2) 2 else 1; - boosts.atk = @intCast(i4, @min(6, @as(i8, boosts.atk) + n)); + boosts.atk = @intCast(@min(6, @as(i8, boosts.atk) + n)); const reason = if (move.effect == .Rage) Boost.Rage else Boost.Attack; if (stats.atk == MAX_STAT_VALUE) { boosts.atk -= 1; @@ -2372,7 +2372,7 @@ pub const Effects = struct { } return try log.fail(ident, .None); } - var mod = BOOSTS[@intCast(u4, @as(i8, boosts.atk) + 6)]; + var mod = BOOSTS[@intCast(@as(i8, boosts.atk) + 6)]; const stat = unmodifiedStats(battle, side).atk; stats.atk = @min(MAX_STAT_VALUE, stat * mod[0] / mod[1]); try log.boost(ident, reason, n); @@ -2383,7 +2383,7 @@ pub const Effects = struct { assert(boosts.def >= -6 and boosts.def <= 6); if (boosts.def == 6) return try log.fail(ident, .None); const n: u2 = if (move.effect == .DefenseUp2) 2 else 1; - boosts.def = @intCast(i4, @min(6, @as(i8, boosts.def) + n)); + boosts.def = @intCast(@min(6, @as(i8, boosts.def) + n)); if (stats.def == MAX_STAT_VALUE) { boosts.def -= 1; if (showdown) { @@ -2392,7 +2392,7 @@ pub const Effects = struct { } return try log.fail(ident, .None); } - var mod = BOOSTS[@intCast(u4, @as(i8, boosts.def) + 6)]; + var mod = BOOSTS[@intCast(@as(i8, boosts.def) + 6)]; const stat = unmodifiedStats(battle, side).def; stats.def = @min(MAX_STAT_VALUE, stat * mod[0] / mod[1]); try log.boost(ident, .Defense, n); @@ -2400,7 +2400,7 @@ pub const Effects = struct { .SpeedUp2 => { assert(boosts.spe >= -6 and boosts.spe <= 6); if (boosts.spe == 6) return try log.fail(ident, .None); - boosts.spe = @intCast(i4, @min(6, @as(i8, boosts.spe) + 2)); + boosts.spe = @intCast(@min(6, @as(i8, boosts.spe) + 2)); if (stats.spe == MAX_STAT_VALUE) { boosts.spe -= 1; if (showdown) { @@ -2409,7 +2409,7 @@ pub const Effects = struct { } return try log.fail(ident, .None); } - var mod = BOOSTS[@intCast(u4, @as(i8, boosts.spe) + 6)]; + var mod = BOOSTS[@intCast(@as(i8, boosts.spe) + 6)]; const stat = unmodifiedStats(battle, side).spe; stats.spe = @min(MAX_STAT_VALUE, stat * mod[0] / mod[1]); try log.boost(ident, .Speed, 2); @@ -2418,7 +2418,7 @@ pub const Effects = struct { assert(boosts.spc >= -6 and boosts.spc <= 6); if (boosts.spc == 6) return try log.fail(ident, .None); const n: u2 = if (move.effect == .SpecialUp2) 2 else 1; - boosts.spc = @intCast(i4, @min(6, @as(i8, boosts.spc) + n)); + boosts.spc = @intCast(@min(6, @as(i8, boosts.spc) + n)); if (stats.spc == MAX_STAT_VALUE) { boosts.spc -= 1; if (showdown) { @@ -2429,7 +2429,7 @@ pub const Effects = struct { } return try log.fail(ident, .None); } - var mod = BOOSTS[@intCast(u4, @as(i8, boosts.spc) + 6)]; + var mod = BOOSTS[@intCast(@as(i8, boosts.spc) + 6)]; const stat = unmodifiedStats(battle, side).spc; stats.spc = @min(MAX_STAT_VALUE, stat * mod[0] / mod[1]); try log.boost(ident, .SpecialAttack, n); @@ -2438,7 +2438,7 @@ pub const Effects = struct { .EvasionUp1 => { assert(boosts.evasion >= -6 and boosts.evasion <= 6); if (boosts.evasion == 6) return try log.fail(ident, .None); - boosts.evasion = @intCast(i4, @min(6, @as(i8, boosts.evasion) + 1)); + boosts.evasion = @intCast(@min(6, @as(i8, boosts.evasion) + 1)); try log.boost(ident, .Evasion, 1); }, else => unreachable, @@ -2469,7 +2469,7 @@ pub const Effects = struct { .AttackDown1, .AttackDownChance => { assert(boosts.atk >= -6 and boosts.atk <= 6); if (boosts.atk == -6) return if (fail) try log.fail(foe_ident, .None); - boosts.atk = @intCast(i4, @max(-6, @as(i8, boosts.atk) - 1)); + boosts.atk = @intCast(@max(-6, @as(i8, boosts.atk) - 1)); if (stats.atk == 1) { boosts.atk += 1; if (showdown) { @@ -2478,7 +2478,7 @@ pub const Effects = struct { } return try log.fail(foe_ident, .None); } - var mod = BOOSTS[@intCast(u4, @as(i8, boosts.atk) + 6)]; + var mod = BOOSTS[@intCast(@as(i8, boosts.atk) + 6)]; const stat = unmodifiedStats(battle, foe).atk; stats.atk = @max(1, stat * mod[0] / mod[1]); try log.boost(foe_ident, .Attack, -1); @@ -2487,7 +2487,7 @@ pub const Effects = struct { assert(boosts.def >= -6 and boosts.def <= 6); if (boosts.def == -6) return if (fail) try log.fail(foe_ident, .None); const n: u2 = if (move.effect == .DefenseDown2) 2 else 1; - boosts.def = @intCast(i4, @max(-6, @as(i8, boosts.def) - n)); + boosts.def = @intCast(@max(-6, @as(i8, boosts.def) - n)); if (stats.def == 1) { boosts.def += 1; if (showdown) { @@ -2496,7 +2496,7 @@ pub const Effects = struct { } return try log.fail(foe_ident, .None); } - var mod = BOOSTS[@intCast(u4, @as(i8, boosts.def) + 6)]; + var mod = BOOSTS[@intCast(@as(i8, boosts.def) + 6)]; const stat = unmodifiedStats(battle, foe).def; stats.def = @max(1, stat * mod[0] / mod[1]); try log.boost(foe_ident, .Defense, -@as(i8, n)); @@ -2504,7 +2504,7 @@ pub const Effects = struct { .SpeedDown1, .SpeedDownChance => { assert(boosts.spe >= -6 and boosts.spe <= 6); if (boosts.spe == -6) return if (fail) try log.fail(foe_ident, .None); - boosts.spe = @intCast(i4, @max(-6, @as(i8, boosts.spe) - 1)); + boosts.spe = @intCast(@max(-6, @as(i8, boosts.spe) - 1)); if (stats.spe == 1) { boosts.spe += 1; if (showdown) { @@ -2513,7 +2513,7 @@ pub const Effects = struct { } return try log.fail(foe_ident, .None); } - var mod = BOOSTS[@intCast(u4, @as(i8, boosts.spe) + 6)]; + var mod = BOOSTS[@intCast(@as(i8, boosts.spe) + 6)]; const stat = unmodifiedStats(battle, foe).spe; stats.spe = @max(1, stat * mod[0] / mod[1]); try log.boost(foe_ident, .Speed, -1); @@ -2522,7 +2522,7 @@ pub const Effects = struct { .SpecialDownChance => { assert(boosts.spc >= -6 and boosts.spc <= 6); if (boosts.spc == -6) return if (fail) try log.fail(foe_ident, .None); - boosts.spc = @intCast(i4, @max(-6, @as(i8, boosts.spc) - 1)); + boosts.spc = @intCast(@max(-6, @as(i8, boosts.spc) - 1)); if (stats.spc == 1) { boosts.spc += 1; if (showdown) { @@ -2533,7 +2533,7 @@ pub const Effects = struct { } return try log.fail(foe_ident, .None); } - var mod = BOOSTS[@intCast(u4, @as(i8, boosts.spc) + 6)]; + var mod = BOOSTS[@intCast(@as(i8, boosts.spc) + 6)]; const stat = unmodifiedStats(battle, foe).spc; stats.spc = @max(1, stat * mod[0] / mod[1]); try log.boost(foe_ident, .SpecialAttack, -1); @@ -2542,7 +2542,7 @@ pub const Effects = struct { .AccuracyDown1 => { assert(boosts.accuracy >= -6 and boosts.accuracy <= 6); if (boosts.accuracy == -6) return if (fail) try log.fail(foe_ident, .None); - boosts.accuracy = @intCast(i4, @max(-6, @as(i8, boosts.accuracy) - 1)); + boosts.accuracy = @intCast(@max(-6, @as(i8, boosts.accuracy) - 1)); try log.boost(foe_ident, .Accuracy, -1); }, else => unreachable, @@ -2626,7 +2626,7 @@ pub const Rolls = struct { } inline fn criticalHit(battle: anytype, chance: u16) bool { - if (showdown) return battle.rng.chance(u8, @intCast(u8, chance), 256); + if (showdown) return battle.rng.chance(u8, @as(u8, @intCast(chance)), 256); return std.math.rotl(u8, battle.rng.next(), 3) < chance; } @@ -2639,13 +2639,13 @@ pub const Rolls = struct { } inline fn hit(battle: anytype, accuracy: u16) bool { - if (showdown) return battle.rng.chance(u8, @intCast(u8, accuracy), 256); + if (showdown) return battle.rng.chance(u8, @as(u8, @intCast(accuracy)), 256); return battle.rng.next() < accuracy; } inline fn confusionDuration(battle: anytype) u3 { - if (showdown) return @intCast(u3, battle.rng.range(u8, 2, 6)); - return @intCast(u3, (battle.rng.next() & 3) + 2); + if (showdown) return @intCast(battle.rng.range(u8, 2, 6)); + return @intCast((battle.rng.next() & 3) + 2); } inline fn confused(battle: anytype) bool { @@ -2674,16 +2674,16 @@ pub const Rolls = struct { } inline fn sleepDuration(battle: anytype) u3 { - if (showdown) return @intCast(u3, battle.rng.range(u8, 1, 8)); + if (showdown) return @intCast(battle.rng.range(u8, 1, 8)); while (true) { const r = battle.rng.next() & 7; - if (r != 0) return @intCast(u3, r); + if (r != 0) return @intCast(r); } } inline fn bideThrashDuration(battle: anytype) u3 { - if (showdown) return @intCast(u3, battle.rng.range(u4, 2, 4)); - return @intCast(u3, (battle.rng.next() & 1) + 2); + if (showdown) return @intCast(battle.rng.range(u4, 2, 4)); + return @intCast((battle.rng.next() & 1) + 2); } fn moveSlot(battle: anytype, moves: []MoveSlot, check_pp: u4) u4 { @@ -2693,11 +2693,11 @@ pub const Rolls = struct { while (i > 0) { i -= 1; if (moves[i].id != .None) { - return battle.rng.range(u4, 0, @intCast(u4, i + 1)) + 1; + return battle.rng.range(u4, 0, @as(u4, @intCast(i + 1))) + 1; } } } else { - var r = battle.rng.range(u4, 0, @intCast(u4, check_pp)) + 1; + var r = battle.rng.range(u4, 0, check_pp) + 1; var i: usize = 0; while (i < moves.len and r > 0) : (i += 1) { if (moves[i].pp > 0) { @@ -2705,32 +2705,32 @@ pub const Rolls = struct { if (r == 0) break; } } - return @intCast(u4, i + 1); + return @intCast(i + 1); } } while (true) { - const r = @intCast(u4, battle.rng.next() & 3); + const r: u4 = @intCast(battle.rng.next() & 3); if (moves[r].id != .None and (check_pp == 0 or moves[r].pp > 0)) return r + 1; } } inline fn disableDuration(battle: anytype) u4 { - if (showdown) return @intCast(u4, battle.rng.range(u8, 1, 9)); - return @intCast(u4, (battle.rng.next() & 7) + 1); + if (showdown) return @intCast(battle.rng.range(u8, 1, 9)); + return @intCast((battle.rng.next() & 7) + 1); } inline fn metronome(battle: anytype) Move { if (showdown) { const r = battle.rng.range(u8, 0, @intFromEnum(Move.Struggle) - 2); const mod = @as(u2, (if (r < @intFromEnum(Move.Metronome) - 1) 1 else 2)); - return @enumFromInt(Move, r + mod); + return @enumFromInt(r + mod); } while (true) { const r = battle.rng.next(); if (r == 0 or r == @intFromEnum(Move.Metronome)) continue; if (r >= @intFromEnum(Move.Struggle)) continue; - return @enumFromInt(Move, r); + return @enumFromInt(r); } } @@ -2745,7 +2745,7 @@ pub const Rolls = struct { inline fn distribution(battle: anytype) u3 { if (showdown) return DISTRIBUTION[battle.rng.range(u8, 0, DISTRIBUTION.len)]; const r = (battle.rng.next() & 3); - return @intCast(u3, (if (r < 2) r else battle.rng.next() & 3) + 2); + return @intCast((if (r < 2) r else battle.rng.next() & 3) + 2); } inline fn unboost(battle: anytype) bool { @@ -2758,7 +2758,7 @@ test "RNG agreement" { if (!showdown) return; var expected: [256]u32 = undefined; for (0..expected.len) |i| { - expected[i] = @intCast(u32, i * 0x1000000); + expected[i] = @intCast(i * 0x1000000); } var spe = rng.FixedRNG(1, expected.len){ .rolls = expected }; diff --git a/src/lib/gen1/test.zig b/src/lib/gen1/test.zig index c4b29fef..074f3dc4 100644 --- a/src/lib/gen1/test.zig +++ b/src/lib/gen1/test.zig @@ -9445,9 +9445,9 @@ fn expectLog(expected: []const u8, actual: []const u8) !void { fn formatter(kind: protocol.Kind, byte: u8) []const u8 { return switch (kind) { - .Move => @tagName(@enumFromInt(Move, byte)), - .Species => @tagName(@enumFromInt(Species, byte)), - .Type => @tagName(@enumFromInt(Type, byte)), + .Move => @tagName(@as(Move, @enumFromInt(byte))), + .Species => @tagName(@as(Species, @enumFromInt(byte))), + .Type => @tagName(@as(Type, @enumFromInt(byte))), .Status => Status.name(byte), }; } diff --git a/src/lib/gen2/data.zig b/src/lib/gen2/data.zig index 25563d69..30cf4ce4 100644 --- a/src/lib/gen2/data.zig +++ b/src/lib/gen2/data.zig @@ -58,7 +58,7 @@ pub fn Battle(comptime RNG: anytype) type { } pub inline fn active(self: *Self, player: Player) ID { - return player.ident(@intCast(u3, self.side(player).pokemon[0].position)); + return player.ident(@intCast(self.side(player).pokemon[0].position)); } pub fn update(self: *Self, c1: Choice, c2: Choice, log: anytype) !Result { @@ -205,11 +205,11 @@ const DVs = packed struct { 0xFF => .Unknown, else => if ((@as(u8, dvs.atk) << 4 | dvs.spe) < ratio) Gender.Female else Gender.Male, }; - const p = @intCast(u6, 1 + ((5 * @as(u8, (dvs.atk & 0b1000) | ((dvs.def & 0b1000)) >> 1 | + const p: u6 = @intCast(1 + ((5 * @as(u8, (dvs.atk & 0b1000) | ((dvs.def & 0b1000)) >> 1 | ((dvs.spe & 0b1000)) >> 2 | ((dvs.spc & 0b1000)) >> 3) + (dvs.spc & 0b0011)) >> 1)); var t = @as(u8, dvs.def & 0b0011) + (@as(u8, dvs.atk & 0b0011) << 2) + 1; if (t >= @intFromEnum(Type.@"???")) t = t + 1; - return DVs{ .gender = g, .pow = p, .type = @enumFromInt(Type, t) }; + return DVs{ .gender = g, .pow = p, .type = @enumFromInt(t) }; } comptime { @@ -327,10 +327,11 @@ pub fn Stats(comptime T: type) type { pub fn calc(comptime stat: []const u8, base: T, dv: u4, exp: u16, level: u8) T { assert(level > 0 and level <= 100); - const evs = @min(255, @intFromFloat(u16, @ceil(@sqrt(@floatFromInt(f32, exp))))); + const float: f32 = @floatFromInt(exp); + const evs = @min(255, @as(u16, @intFromFloat(@ceil(@sqrt(float))))); const core: u32 = (2 *% (@as(u32, base) +% dv)) +% (evs / 4); const factor: u32 = if (std.mem.eql(u8, stat, "hp")) level + 10 else 5; - return @intCast(T, core *% @as(u32, level) / 100 +% factor); + return @intCast(core *% @as(u32, level) / 100 +% factor); } }; } diff --git a/src/lib/gen2/data/items.zig b/src/lib/gen2/data/items.zig index 31458d98..f51ee16c 100644 --- a/src/lib/gen2/data/items.zig +++ b/src/lib/gen2/data/items.zig @@ -219,7 +219,7 @@ pub const Item = enum(u8) { pub inline fn boost(item: Item) ?Type { assert(item != .None); if (item == .PolkadotBow) return .Normal; - return if (@intFromEnum(item) <= 18) @enumFromInt(Type, @intFromEnum(item) - 1) else null; + return if (@intFromEnum(item) <= 18) @enumFromInt(@intFromEnum(item) - 1) else null; } /// Whether or not this item is a Berry. diff --git a/src/lib/gen2/helpers.zig b/src/lib/gen2/helpers.zig index 6fd42c29..7bf9014e 100644 --- a/src/lib/gen2/helpers.zig +++ b/src/lib/gen2/helpers.zig @@ -141,7 +141,7 @@ pub const Pokemon = struct { .id = m, .pp_ups = 3, // NB: PP can be at most 61 legally (though can overflow to 63) - .pp = @intCast(u8, @min(Move.pp(m) / 5 * 8, 61)), + .pp = @intCast(@min(Move.pp(m) / 5 * 8, 61)), }; } pokemon.item = p.item; @@ -158,7 +158,7 @@ pub const Pokemon = struct { } pub fn random(rand: *PSRNG, opt: Options) data.Pokemon { - const s = @enumFromInt(Species, rand.range(u8, 1, Species.size + 1)); + const s: Species = @enumFromInt(rand.range(u8, 1, Species.size + 1)); const species = Species.get(s); const lvl = if (rand.chance(u8, 1, 20)) rand.range(u8, 1, 99 + 1) else 100; // Pokémon Showdown does not support most items without in-battle held item effects @@ -184,14 +184,14 @@ pub const Pokemon = struct { for (0..n) |i| { var m: Move = .None; sample: while (true) { - m = @enumFromInt(Move, rand.range(u8, 1, 164 + 1)); + m = @enumFromInt(rand.range(u8, 1, 164 + 1)); for (0..i) |j| if (ms[j].id == m) continue :sample; break; } - const pp_ups = + const pp_ups: u8 = if (!opt.cleric and rand.chance(u8, 1, 10)) rand.range(u2, 0, 2 + 1) else 3; // NB: PP can be at most 61 legally (though can overflow to 63) - const max_pp = @intCast(u8, Move.pp(m) + @as(u8, pp_ups) * @min(Move.pp(m) / 5, 7)); + const max_pp: u8 = @intCast(Move.pp(m) + pp_ups * @min(Move.pp(m) / 5, 7)); ms[i] = .{ .id = m, .pp_ups = pp_ups, diff --git a/src/lib/gen2/test.zig b/src/lib/gen2/test.zig index a10e3698..e3c8017c 100644 --- a/src/lib/gen2/test.zig +++ b/src/lib/gen2/test.zig @@ -1389,9 +1389,9 @@ fn expectLog(expected: []const u8, actual: []const u8) !void { fn formatter(kind: protocol.Kind, byte: u8) []const u8 { return switch (kind) { - .Move => @tagName(@enumFromInt(Move, byte)), - .Species => @tagName(@enumFromInt(Species, byte)), - .Type => @tagName(@enumFromInt(Type, byte)), + .Move => @tagName(@as(Move, @enumFromInt(byte))), + .Species => @tagName(@as(Species, @enumFromInt(byte))), + .Type => @tagName(@as(Type, @enumFromInt(byte))), .Status => Status.name(byte), }; } diff --git a/src/tools/generate.ts b/src/tools/generate.ts index 12b106d6..5d7f9853 100644 --- a/src/tools/generate.ts +++ b/src/tools/generate.ts @@ -618,7 +618,7 @@ const GEN: { [gen in GenerationNum]?: GenerateFn } = { `/// The precedence order of type \`t2\` vs. type \`t1\`. pub fn precedence(t1: Type, t2: Type) u8 { for (PRECEDENCE, 0..) |matchup, i| { - if (matchup.type1 == t1 and matchup.type2 == t2) return @intCast(u8, i); + if (matchup.type1 == t1 and matchup.type2 == t2) return @intCast(i); } unreachable; }`;