Remove the other sources of off-by-one

master
Louis Pearson 2022-08-05 18:34:08 -06:00
parent d81c1f5ab1
commit 4c51c52d05
6 changed files with 39 additions and 40 deletions

View File

@ -123,12 +123,12 @@ fn get_plugs(tile: u8) Plugs {
pub fn get_cell(this: @This(), cell: Cell) ?u8 { pub fn get_cell(this: @This(), cell: Cell) ?u8 {
const i = this.indexOf(cell) orelse return null; const i = this.indexOf(cell) orelse return null;
return if (this.map[i] != 0) this.map[i] - 1 else null; return if (this.map[i] != 0) this.map[i] else null;
} }
pub fn set_cell(this: *@This(), cell: Cell, tile: u8) void { pub fn set_cell(this: *@This(), cell: Cell, tile: u8) void {
const i = this.indexOf(cell) orelse return; const i = this.indexOf(cell) orelse return;
this.map[i] = tile + 1; this.map[i] = tile;
this.levels[i] = 0; this.levels[i] = 0;
} }

View File

@ -188,8 +188,8 @@ pub fn extractLevel(opt: Options) !void {
.Switch_On => opt.switch_on.find(autotile), .Switch_On => opt.switch_on.find(autotile),
.Switch_Off => opt.switch_off.find(autotile), .Switch_Off => opt.switch_off.find(autotile),
.Plug => opt.plug.find(autotile), .Plug => opt.plug.find(autotile),
.And => 21, .And => world.Tiles.LogicAnd,
.Xor => 23, .Xor => world.Tiles.LogicXor,
else => 0, else => 0,
}; };
circuit.map[i] = tile; circuit.map[i] = tile;

View File

@ -228,19 +228,11 @@ pub fn start() !void {
.level = level, .level = level,
.map = &map, .map = &map,
.circuit = &circuit, .circuit = &circuit,
.tileset = world.AutoTileset.initOffsetFull(113), .tileset = world.Tiles.Walls,
.conduit = world.AutoTileset.initOffsetFull(97), .conduit = world.Tiles.Conduit,
.plug = world.AutoTileset.initOffsetCardinal(17), .plug = world.Tiles.Plugs,
.switch_off = world.AutoTileset.initSwitches(&.{ .switch_off = world.Tiles.SwitchesOff,
29, // South-North .switch_on = world.Tiles.SwitchesOn,
25, // South-West-North
27, // South-East-North
}, 2),
.switch_on = world.AutoTileset.initSwitches(&.{
30, // South-North
26, // South-West-North
28, // South-East-West
}, 2),
}); });
var entity_buf = try alloc.alloc(world.Entity, level.entity_count); var entity_buf = try alloc.alloc(world.Entity, level.entity_count);
@ -627,7 +619,7 @@ fn updateCircuit() !void {
var i: usize = 0; var i: usize = 0;
while (level.getDoor(i)) |door| : (i += 1) { while (level.getDoor(i)) |door| : (i += 1) {
const tile: u8 = if (door.kind == .Door) world.Tiles.Door else world.Tiles.Trapdoor; const tile: u8 = if (door.kind == .Door) world.Tiles.Door else world.Tiles.Trapdoor;
try map.set_cell(.{door.x, door.y}, tile); try map.set_cell(.{ door.x, door.y }, tile);
} }
// Remove doors that have been unlocked // Remove doors that have been unlocked

View File

@ -82,9 +82,8 @@ pub fn draw(this: @This(), offset: Vec2) void {
while (x < width) : (x += 1) { while (x < width) : (x += 1) {
const cell = Vec2{ @intCast(i32, x), @intCast(i32, y) } + offset; const cell = Vec2{ @intCast(i32, x), @intCast(i32, y) } + offset;
const pos = Vec2{ @intCast(i32, x), @intCast(i32, y) } * tile_size; const pos = Vec2{ @intCast(i32, x), @intCast(i32, y) } * tile_size;
const tilePlus = this.get_cell(cell) orelse continue; const tile = this.get_cell(cell) orelse continue;
if (tilePlus == 0) continue; if (tile == world.Tiles.Empty) continue;
const tile = tilePlus - 1;
const t = Vec2{ const t = Vec2{
@intCast(i32, (tile % tilemap_width) * tile_width), @intCast(i32, (tile % tilemap_width) * tile_width),
@intCast(i32, (tile / tilemap_width) * tile_width), @intCast(i32, (tile / tilemap_width) * tile_width),
@ -134,14 +133,14 @@ pub fn collide(this: @This(), body: BodyInfo) CollisionInfo {
const bottom = @floatToInt(i32, bot_right[1]); const bottom = @floatToInt(i32, bot_right[1]);
const foot = body.rect.pos[1] + body.rect.size[1]; const foot = body.rect.pos[1] + body.rect.size[1];
if (isOneWay(tile)) { if (world.Tiles.is_oneway(tile)) {
if (!body.is_passing and a == bottom and body.last[1] <= body.next[1] and foot < tiley + 2) { if (!body.is_passing and a == bottom and body.last[1] <= body.next[1] and foot < tiley + 2) {
collisions.append(util.AABB{ collisions.append(util.AABB{
.pos = Vec2f{ tilex, tiley }, .pos = Vec2f{ tilex, tiley },
.size = tile_sizef, .size = tile_sizef,
}); });
} }
} else if (isSolid(tile)) { } else if (world.Tiles.is_solid(tile)) {
collisions.append(util.AABB{ collisions.append(util.AABB{
.pos = Vec2f{ tilex, tiley }, .pos = Vec2f{ tilex, tiley },
.size = tile_sizef, .size = tile_sizef,
@ -171,14 +170,6 @@ pub const CollisionInfo = struct {
} }
}; };
pub fn isSolid(tile: u8) bool {
return if (tile == 0) false else world.Tiles.is_solid(tile - 1);
}
pub fn isOneWay(tile: u8) bool {
return if (tile == 0) false else world.Tiles.is_oneway(tile - 1);
}
// Debug functions // Debug functions
pub fn trace(this: @This()) void { pub fn trace(this: @This()) void {
@ -190,8 +181,7 @@ pub fn trace(this: @This()) void {
} }
pub fn traceDraw(this: @This()) void { pub fn traceDraw(this: @This()) void {
for (this.tiles) |tilePlus, i| { for (this.tiles) |tile, i| {
const tile = tilePlus - 1;
const t = Vec2{ const t = Vec2{
@intCast(i32, (tile % tilemap_width) * tile_width), @intCast(i32, (tile % tilemap_width) * tile_width),
@intCast(i32, (tile / tilemap_width) * tile_width), @intCast(i32, (tile / tilemap_width) * tile_width),

View File

@ -22,15 +22,18 @@ pub const Tiles = struct {
// Switches // Switches
pub const SwitchTeeWestOff = 24; pub const SwitchTeeWestOff = 24;
pub const SwitchTeeWestOn = 25; pub const SwitchTeeWestOn = 25;
pub const SwitchTeeEastOff = 26; pub const SwitchTeeEastOff = 26;
pub const SwitchTeeEastOn = 27; pub const SwitchTeeEastOn = 27;
pub const SwitchVerticalOff = 28; pub const SwitchVerticalOff = 28;
pub const SwitchVerticalOn = 29; pub const SwitchVerticalOn = 29;
pub const SwitchHorizontalOff = 30; pub const SwitchHorizontalOff = 30;
pub const SwitchHorizontalOn = 31; pub const SwitchHorizontalOn = 31;
pub fn is_switch(tile: u8) bool { pub fn is_switch(tile: u8) bool {
return tile >= 24 and tile <= 31; return tile >= SwitchTeeWestOff and tile <= SwitchHorizontalOn;
} }
// Plugs, sorted by autotile order // Plugs, sorted by autotile order
@ -51,8 +54,8 @@ pub const Tiles = struct {
return tile >= 21 and tile <= 24; return tile >= 21 and tile <= 24;
} }
pub const ConduitCross = 97; pub const ConduitCross = 96;
pub const ConduitSingle = 113; pub const ConduitSingle = 112;
pub fn is_conduit(tile: u8) bool { pub fn is_conduit(tile: u8) bool {
return tile >= ConduitCross and tile <= ConduitSingle; return tile >= ConduitCross and tile <= ConduitSingle;
@ -62,15 +65,15 @@ pub const Tiles = struct {
return is_plug(tile) or is_conduit(tile) or is_switch(tile) or is_logic(tile); return is_plug(tile) or is_conduit(tile) or is_switch(tile) or is_logic(tile);
} }
pub const WallSingle = 113; pub const WallSingle = 112;
pub const WallSurrounded = 127; pub const WallSurrounded = 127;
pub fn is_wall(tile: u8) bool { pub fn is_wall(tile: u8) bool {
return tile >= WallSingle and tile <= WallSurrounded; return tile >= WallSingle and tile <= WallSurrounded;
} }
pub const Door = 3; pub const Door = 2;
pub const Trapdoor = 4; pub const Trapdoor = 3;
pub fn is_door(tile: u8) bool { pub fn is_door(tile: u8) bool {
return tile == 3 or tile == 4; return tile == 3 or tile == 4;
@ -89,6 +92,20 @@ pub const Tiles = struct {
} }
pub const Empty = 0; pub const Empty = 0;
pub const Walls = AutoTileset.initOffsetFull(WallSingle);
pub const Conduit = AutoTileset.initOffsetFull(ConduitCross);
pub const Plugs = AutoTileset.initOffsetCardinal(PlugNorth);
pub const SwitchesOff = AutoTileset.initSwitches(&.{
SwitchVerticalOff, // South-North
SwitchTeeWestOff, // South-West-North
SwitchTeeEastOff, // South-East-North
}, 2);
pub const SwitchesOn = AutoTileset.initSwitches(&.{
SwitchVerticalOn, // South-North
SwitchTeeWestOn, // South-West-North
SwitchTeeEastOn, // South-East-North
}, 2);
}; };
pub const TileData = union(enum) { pub const TileData = union(enum) {

View File

@ -180,7 +180,7 @@ fn make(step: *std.build.Step) !void {
const i = @intCast(usize, x + y * width); const i = @intCast(usize, x + y * width);
const sx = @divExact(autotile.src[0], collision.__gridSize); const sx = @divExact(autotile.src[0], collision.__gridSize);
const sy = @divExact(autotile.src[1], collision.__gridSize); const sy = @divExact(autotile.src[1], collision.__gridSize);
const t = sx + sy * 16 + 1; const t = sx + sy * 16;
tiles[i] = world.TileData{ .tile = @intCast(u7, t) }; tiles[i] = world.TileData{ .tile = @intCast(u7, t) };
} }