Database now handles entities
parent
a35d481b15
commit
240587344d
41
src/game.zig
41
src/game.zig
|
@ -207,6 +207,7 @@ fn loadLevel(lvl: usize) !void {
|
|||
map.clear();
|
||||
circuit.clearMap();
|
||||
level = try db.levelLoad(alloc, lvl);
|
||||
const levelc = world.Coordinate.fromWorld(level.world_x, level.world_y);
|
||||
|
||||
try extract.extractLevel(.{
|
||||
.alloc = frame_alloc,
|
||||
|
@ -225,9 +226,11 @@ fn loadLevel(lvl: usize) !void {
|
|||
{
|
||||
_ = try wires.resize(0);
|
||||
var a: usize = 0;
|
||||
while (level.getWire(a)) |wire| : (a += 1) {
|
||||
const p1 = util.vec2ToVec2f(Vec2{ wire[0].x, wire[0].y } * tile_size + Vec2{ 4, 4 });
|
||||
const p2 = util.vec2ToVec2f(Vec2{ wire[1].x, wire[1].y } * tile_size + Vec2{ 4, 4 });
|
||||
while (db.getWire(level, a)) |wire| : (a += 1) {
|
||||
const coord0 = wire[0].coord.subC(levelc);
|
||||
const coord1 = wire[1].coord.subC(levelc);
|
||||
const p1 = util.vec2ToVec2f(coord0.toVec2() * tile_size + Vec2{ 4, 4 });
|
||||
const p2 = util.vec2ToVec2f(coord1.toVec2() * tile_size + Vec2{ 4, 4 });
|
||||
|
||||
var w = try wires.addOne();
|
||||
_ = try w.nodes.resize(0);
|
||||
|
@ -249,15 +252,16 @@ fn loadLevel(lvl: usize) !void {
|
|||
|
||||
{
|
||||
var i: usize = 0;
|
||||
while (level.getDoor(i)) |door| : (i += 1) {
|
||||
try circuit.addDoor(Vec2{ door.x, door.y });
|
||||
while (db.getDoor(level, i)) |door| : (i += 1) {
|
||||
const coord = door.coord.subC(levelc);
|
||||
try circuit.addDoor(coord.toVec2());
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
var i: usize = 0;
|
||||
while (level.getJoin(i)) |join| : (i += 1) {
|
||||
const globalc = Coord.fromWorld(level.world_x, level.world_y).addC(join);
|
||||
const globalc = levelc.addC(join);
|
||||
var e = false;
|
||||
if (db.isEnergized(globalc)) {
|
||||
e = true;
|
||||
|
@ -270,9 +274,10 @@ fn loadLevel(lvl: usize) !void {
|
|||
try coins.resize(0);
|
||||
// if (!try Disk.load()) {
|
||||
var i: usize = 0;
|
||||
while (level.getCoin(i)) |coin| : (i += 1) {
|
||||
while (db.getCoin(level, i)) |coin| : (i += 1) {
|
||||
const coord = coin.coord.subC(levelc);
|
||||
try coins.append(.{
|
||||
.pos = Pos.init(util.vec2ToVec2f(Vec2{ coin.x, coin.y } * tile_size)),
|
||||
.pos = Pos.init(util.vec2ToVec2f(coord.toVec2() * tile_size)),
|
||||
.sprite = .{ .offset = .{ 0, 0 }, .size = .{ 8, 8 }, .index = 4, .flags = .{ .bpp = .b2 } },
|
||||
.anim = Anim{ .anim = &anim_store.coin },
|
||||
.area = .{ .pos = .{ 0, 0 }, .size = .{ 8, 8 } },
|
||||
|
@ -342,18 +347,20 @@ pub fn start() !void {
|
|||
|
||||
db = try world.Database.init(db_alloc);
|
||||
|
||||
try loadLevel(0);
|
||||
const spawn = db.getSpawn();
|
||||
|
||||
const spawnArr = level.getSpawn() orelse return error.NoPlayerSpawn;
|
||||
const spawn = Vec2{ spawnArr[0], spawnArr[1] };
|
||||
const spawn_worldc = spawn.coord.toWorld();
|
||||
const first_level = db.findLevel(spawn_worldc[0], spawn_worldc[1]) orelse return error.SpawnOutOfBounds;
|
||||
|
||||
camera = @divTrunc(spawn, @splat(2, @as(i32, 20))) * @splat(2, @as(i32, 20));
|
||||
try loadLevel(first_level);
|
||||
|
||||
camera = @divTrunc(spawn.coord.toVec2(), @splat(2, @as(i32, 20))) * @splat(2, @as(i32, 20));
|
||||
|
||||
const tile_size = Vec2{ 8, 8 };
|
||||
const offset = Vec2{ 4, 8 };
|
||||
|
||||
player = .{
|
||||
.pos = Pos.init(util.vec2ToVec2f(spawn * tile_size + offset)),
|
||||
.pos = Pos.init(util.vec2ToVec2f(spawn.coord.toVec2() * tile_size + offset)),
|
||||
.control = .{ .controller = .player, .state = .stand },
|
||||
.sprite = .{ .offset = .{ -4, -8 }, .size = .{ 8, 8 }, .index = 8, .flags = .{ .bpp = .b2 } },
|
||||
.physics = .{ .friction = Vec2f{ 0.15, 0.1 }, .gravity = Vec2f{ 0, 0.25 } },
|
||||
|
@ -713,15 +720,19 @@ fn updateCircuit() !void {
|
|||
|
||||
// Add doors to map
|
||||
var i: usize = 0;
|
||||
while (level.getDoor(i)) |door| : (i += 1) {
|
||||
while (db.getDoor(level, i)) |door| : (i += 1) {
|
||||
const tile: u8 = if (door.kind == .Door) world.Tiles.Door else world.Tiles.Trapdoor;
|
||||
try map.set_cell(.{ door.x, door.y }, tile);
|
||||
const globalc = world.Coordinate.fromWorld(level.world_x, level.world_y);
|
||||
const coord = door.coord.subC(globalc);
|
||||
w4.tracef("[getDoor] (%d, %d)", coord.val[0], coord.val[1]);
|
||||
try map.set_cell(coord.toVec2(), tile);
|
||||
}
|
||||
|
||||
// Remove doors that have been unlocked
|
||||
const enabledDoors = try circuit.enabledDoors(frame_alloc);
|
||||
defer frame_alloc.free(enabledDoors.items);
|
||||
for (enabledDoors.items) |door| {
|
||||
w4.tracef("[enabledDoors] (%d, %d)", door[0], door[1]);
|
||||
try map.set_cell(door, world.Tiles.Empty);
|
||||
}
|
||||
|
||||
|
|
|
@ -50,7 +50,7 @@ export fn update() void {
|
|||
error.EndOfStream => showErr(@errorName(e)),
|
||||
error.OutOfMemory => showErr(@errorName(e)),
|
||||
error.NullTiles => showErr(@errorName(e)),
|
||||
error.NoPlayerSpawn => showErr(@errorName(e)),
|
||||
error.SpawnOutOfBounds => showErr(@errorName(e)),
|
||||
error.InvalidLevel => showErr(@errorName(e)),
|
||||
},
|
||||
}
|
||||
|
|
194
src/world.zig
194
src/world.zig
|
@ -178,20 +178,37 @@ pub const Coordinate = struct {
|
|||
return .{ .val = .{ coord.val[0] + val[0], coord.val[1] + val[1] } };
|
||||
}
|
||||
|
||||
pub fn sub(coord: Coordinate, val: [2]i16) Coordinate {
|
||||
return .{ .val = .{ coord.val[0] - val[0], coord.val[1] - val[1] } };
|
||||
}
|
||||
|
||||
pub fn addC(coord: Coordinate, other: Coordinate) Coordinate {
|
||||
return .{ .val = .{ coord.val[0] + other.val[0], coord.val[1] + other.val[1] } };
|
||||
}
|
||||
|
||||
pub fn subC(coord: Coordinate, other: Coordinate) Coordinate {
|
||||
return .{ .val = .{ coord.val[0] - other.val[0], coord.val[1] - other.val[1] } };
|
||||
}
|
||||
|
||||
pub fn eq(coord: Coordinate, other: Coordinate) bool {
|
||||
return coord.val[0] == other.val[0] and coord.val[1] == other.val[1];
|
||||
}
|
||||
|
||||
pub fn within(coord: Coord, nw: Coord, se: Coord) bool {
|
||||
return coord.val[0] >= nw.val[0] and coord.val[1] >= nw.val[1] and
|
||||
coord.val[0] < se.val[0] and coord.val[1] < se.val[1];
|
||||
}
|
||||
|
||||
pub fn toWorld(coord: Coordinate) [2]i8 {
|
||||
const world_x = @intCast(i8, @divFloor(coord.val[0], LEVELSIZE));
|
||||
const world_y = @intCast(i8, @divFloor(coord.val[1], LEVELSIZE));
|
||||
return .{ world_x, world_y };
|
||||
}
|
||||
|
||||
pub fn toVec2(coord: Coordinate) @Vector(2, i32) {
|
||||
return .{ coord.val[0], coord.val[1] };
|
||||
}
|
||||
|
||||
pub fn fromWorld(x: i8, y: i8) Coordinate {
|
||||
return .{ .val = .{
|
||||
@intCast(i16, x) * 20,
|
||||
|
@ -222,50 +239,37 @@ pub const Level = struct {
|
|||
world_y: i8,
|
||||
width: u16,
|
||||
size: u16,
|
||||
entity_count: u16,
|
||||
tiles: ?[]TileData,
|
||||
entities: ?[]Entity = null,
|
||||
|
||||
pub fn init(x: u8, y: u8, width: u16, buf: []TileData, entities: []Entity) Level {
|
||||
pub fn init(x: u8, y: u8, width: u16, buf: []TileData) Level {
|
||||
return Level{
|
||||
.world_x = x,
|
||||
.world_y = y,
|
||||
.width = width,
|
||||
.size = buf.len,
|
||||
.entity_count = entities.len,
|
||||
.tiles = buf,
|
||||
.entities = entities,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn calculateSize(level: Level) !usize {
|
||||
const tiles = level.tiles orelse return error.NullTiles;
|
||||
const entities = level.entities orelse return error.NullEntities;
|
||||
return @sizeOf(i8) + // world_x
|
||||
@sizeOf(i8) + // world_y
|
||||
@sizeOf(u16) + // width
|
||||
@sizeOf(u16) + // size
|
||||
@sizeOf(u16) + // entity_count
|
||||
tiles.len + //
|
||||
entities.len * 5;
|
||||
tiles.len;
|
||||
}
|
||||
|
||||
pub fn write(level: Level, writer: anytype) !void {
|
||||
var tiles = level.tiles orelse return error.NullTiles;
|
||||
var entities = level.entities orelse return error.NullEntities;
|
||||
try writer.writeInt(i8, level.world_x, .Little);
|
||||
try writer.writeInt(i8, level.world_y, .Little);
|
||||
try writer.writeInt(u16, level.width, .Little);
|
||||
try writer.writeInt(u16, level.size, .Little);
|
||||
try writer.writeInt(u16, level.entity_count, .Little);
|
||||
|
||||
for (tiles) |tile| {
|
||||
try writer.writeByte(tile.toByte());
|
||||
}
|
||||
|
||||
for (entities) |entity| {
|
||||
try entity.write(writer);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn read(reader: anytype) !Level {
|
||||
|
@ -274,9 +278,7 @@ pub const Level = struct {
|
|||
.world_y = try reader.readInt(i8, .Little),
|
||||
.width = try reader.readInt(u16, .Little),
|
||||
.size = try reader.readInt(u16, .Little),
|
||||
.entity_count = try reader.readInt(u16, .Little),
|
||||
.tiles = null,
|
||||
.entities = null,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -289,25 +291,6 @@ pub const Level = struct {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn readEntities(level: *Level, reader: anytype, buf: []Entity) !void {
|
||||
std.debug.assert(buf.len >= level.entity_count);
|
||||
level.entities = buf;
|
||||
var i: usize = 0;
|
||||
while (i < level.entity_count) : (i += 1) {
|
||||
buf[i] = try Entity.read(reader);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn getSpawn(level: *Level) ?[2]i16 {
|
||||
std.debug.assert(level.entities != null);
|
||||
for (level.entities.?) |entity| {
|
||||
if (entity.kind == .Player) {
|
||||
return [2]i16{ entity.x, entity.y };
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
pub fn getTile(level: Level, globalc: Coord) ?TileData {
|
||||
const tiles = level.tiles orelse return null;
|
||||
const worldc = globalc.toLevelTopLeft();
|
||||
|
@ -338,47 +321,6 @@ pub const Level = struct {
|
|||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
pub fn getWire(level: *Level, num: usize) ?[2]Entity {
|
||||
std.debug.assert(level.entities != null);
|
||||
var node_begin: ?Entity = null;
|
||||
var wire_count: usize = 0;
|
||||
for (level.entities.?) |entity| {
|
||||
if (entity.kind == .WireNode or entity.kind == .WireAnchor) {
|
||||
node_begin = entity;
|
||||
} else if (entity.kind == .WireEndNode or entity.kind == .WireEndAnchor) {
|
||||
if (node_begin) |begin| {
|
||||
if (wire_count == num) return [2]Entity{ begin, entity };
|
||||
}
|
||||
wire_count += 1;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
pub fn getDoor(level: *Level, num: usize) ?Entity {
|
||||
std.debug.assert(level.entities != null);
|
||||
var count: usize = 0;
|
||||
for (level.entities.?) |entity| {
|
||||
if (entity.kind == .Door or entity.kind == .Trapdoor) {
|
||||
if (count == num) return entity;
|
||||
count += 1;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
pub fn getCoin(level: *Level, num: usize) ?Entity {
|
||||
std.debug.assert(level.entities != null);
|
||||
var count: usize = 0;
|
||||
for (level.entities.?) |entity| {
|
||||
if (entity.kind == .Coin) {
|
||||
if (count == num) return entity;
|
||||
count += 1;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
// AutoTile algorithm datatypes
|
||||
|
@ -493,8 +435,7 @@ pub const EntityKind = enum(u8) {
|
|||
|
||||
pub const Entity = struct {
|
||||
kind: EntityKind,
|
||||
x: i16,
|
||||
y: i16,
|
||||
coord: Coordinate,
|
||||
|
||||
pub fn calculateSize() usize {
|
||||
return @sizeOf(u8) + // kind
|
||||
|
@ -504,15 +445,13 @@ pub const Entity = struct {
|
|||
|
||||
pub fn write(entity: Entity, writer: anytype) !void {
|
||||
try writer.writeInt(u8, @enumToInt(entity.kind), .Little);
|
||||
try writer.writeInt(i16, entity.x, .Little);
|
||||
try writer.writeInt(i16, entity.y, .Little);
|
||||
try entity.coord.write(writer);
|
||||
}
|
||||
|
||||
pub fn read(reader: anytype) !Entity {
|
||||
return Entity{
|
||||
.kind = @intToEnum(EntityKind, try reader.readInt(u8, .Little)),
|
||||
.x = try reader.readInt(i16, .Little),
|
||||
.y = try reader.readInt(i16, .Little),
|
||||
.coord = try Coordinate.read(reader),
|
||||
};
|
||||
}
|
||||
};
|
||||
|
@ -546,11 +485,14 @@ pub const LevelHeader = struct {
|
|||
pub fn write(
|
||||
writer: anytype,
|
||||
level_headers: []LevelHeader,
|
||||
entities: []Entity,
|
||||
circuit_nodes: []CircuitNode,
|
||||
levels: []Level,
|
||||
) !void {
|
||||
// Write number of levels
|
||||
try writer.writeInt(u16, @intCast(u16, level_headers.len), .Little);
|
||||
// Write number of entities
|
||||
try writer.writeInt(u16, @intCast(u16, entities.len), .Little);
|
||||
// Write number of circuit nodes
|
||||
try writer.writeInt(u16, @intCast(u16, circuit_nodes.len), .Little);
|
||||
|
||||
|
@ -559,6 +501,11 @@ pub fn write(
|
|||
try lvl_header.write(writer);
|
||||
}
|
||||
|
||||
// Write entity data
|
||||
for (entities) |entity| {
|
||||
try entity.write(writer);
|
||||
}
|
||||
|
||||
// Write node data
|
||||
for (circuit_nodes) |node| {
|
||||
try node.write(writer);
|
||||
|
@ -574,6 +521,7 @@ const Cursor = std.io.FixedBufferStream([]const u8);
|
|||
pub const Database = struct {
|
||||
cursor: Cursor,
|
||||
level_info: []LevelHeader,
|
||||
entities: []Entity,
|
||||
circuit_info: []CircuitNode,
|
||||
level_data_begin: usize,
|
||||
|
||||
|
@ -589,6 +537,8 @@ pub const Database = struct {
|
|||
|
||||
// read number of levels
|
||||
const level_count = try reader.readInt(u16, .Little);
|
||||
// read number of entities
|
||||
const entity_count = try reader.readInt(u16, .Little);
|
||||
// read number of nodes
|
||||
const node_count = try reader.readInt(u16, .Little);
|
||||
|
||||
|
@ -599,23 +549,34 @@ pub const Database = struct {
|
|||
level_headers[i] = try LevelHeader.read(reader);
|
||||
}
|
||||
|
||||
// read entities
|
||||
var entities = try alloc.alloc(Entity, entity_count);
|
||||
|
||||
for (entities) |_, i| {
|
||||
entities[i] = try Entity.read(reader);
|
||||
}
|
||||
|
||||
// read circuits
|
||||
var circuit_nodes = try alloc.alloc(CircuitNode, node_count);
|
||||
|
||||
// read headers
|
||||
for (circuit_nodes) |_, i| {
|
||||
circuit_nodes[i] = try CircuitNode.read(reader);
|
||||
}
|
||||
|
||||
// Save where the rest of the data ended, and the level data begins
|
||||
var level_data_begin = @intCast(usize, try cursor.getPos());
|
||||
|
||||
return Database{
|
||||
.cursor = cursor,
|
||||
.level_info = level_headers,
|
||||
.entities = entities,
|
||||
.circuit_info = circuit_nodes,
|
||||
.level_data_begin = level_data_begin,
|
||||
};
|
||||
}
|
||||
|
||||
// Level functions
|
||||
|
||||
pub fn levelInfo(db: *Database, level: usize) !Level {
|
||||
if (level > db.level_info.len) return error.InvalidLevel;
|
||||
try db.cursor.seekTo(db.level_data_begin + db.level_info[level].offset);
|
||||
|
@ -632,9 +593,6 @@ pub const Database = struct {
|
|||
var level_buf = try alloc.alloc(TileData, level_info.size);
|
||||
try level_info.readTiles(reader, level_buf);
|
||||
|
||||
var entity_buf = try alloc.alloc(Entity, level_info.entity_count);
|
||||
try level_info.readEntities(reader, entity_buf);
|
||||
|
||||
return level_info;
|
||||
}
|
||||
|
||||
|
@ -647,6 +605,8 @@ pub const Database = struct {
|
|||
return null;
|
||||
}
|
||||
|
||||
// Circuit functions
|
||||
|
||||
fn getNodeID(db: *Database, coord: Coord) ?NodeID {
|
||||
for (db.circuit_info) |node, i| {
|
||||
if (!coord.eq(node.coord)) continue;
|
||||
|
@ -752,6 +712,66 @@ pub const Database = struct {
|
|||
if (i == 0) break;
|
||||
}
|
||||
}
|
||||
|
||||
// Entity functions
|
||||
|
||||
pub fn getWire(database: *Database, level: Level, num: usize) ?[2]Entity {
|
||||
const nw = Coord.fromWorld(level.world_x, level.world_y);
|
||||
const se = nw.add(.{ 20, 20 });
|
||||
var node_begin: ?Entity = null;
|
||||
var wire_count: usize = 0;
|
||||
for (database.entities) |entity| {
|
||||
if (!entity.coord.within(nw, se)) continue;
|
||||
if (entity.kind == .WireNode or entity.kind == .WireAnchor) {
|
||||
node_begin = entity;
|
||||
} else if (entity.kind == .WireEndNode or entity.kind == .WireEndAnchor) {
|
||||
if (node_begin) |begin| {
|
||||
if (wire_count == num) return [2]Entity{ begin, entity };
|
||||
}
|
||||
wire_count += 1;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
pub fn getDoor(database: *Database, level: Level, num: usize) ?Entity {
|
||||
const nw = Coord.fromWorld(level.world_x, level.world_y);
|
||||
const se = nw.add(.{ 20, 20 });
|
||||
var count: usize = 0;
|
||||
for (database.entities) |entity| {
|
||||
if (!entity.coord.within(nw, se)) continue;
|
||||
if (entity.kind == .Door or entity.kind == .Trapdoor) {
|
||||
if (count == num) return entity;
|
||||
count += 1;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
pub fn getCoin(database: *Database, level: Level, num: usize) ?Entity {
|
||||
const nw = Coord.fromWorld(level.world_x, level.world_y);
|
||||
const se = nw.add(.{ 20, 20 });
|
||||
var count: usize = 0;
|
||||
for (database.entities) |entity| {
|
||||
if (!entity.coord.within(nw, se)) continue;
|
||||
if (entity.kind == .Coin) {
|
||||
if (count == num) return entity;
|
||||
count += 1;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// Returns the players spawn location.
|
||||
/// Assumes a spawn exists and that there is only one of them
|
||||
pub fn getSpawn(database: *Database) Entity {
|
||||
for (database.entities) |entity| {
|
||||
if (entity.kind == .Player) {
|
||||
return entity;
|
||||
}
|
||||
}
|
||||
@panic("No player spawn found! Invalid state");
|
||||
}
|
||||
};
|
||||
|
||||
// All levels in the game. If two rooms are next to each other, they
|
||||
|
|
|
@ -55,10 +55,11 @@ fn make(step: *std.build.Step) !void {
|
|||
var levels = std.ArrayList(world.Level).init(allocator);
|
||||
defer levels.deinit();
|
||||
|
||||
for (ldtk.levels) |level| {
|
||||
var entity_array = std.ArrayList(world.Entity).init(allocator);
|
||||
defer entity_array.deinit();
|
||||
|
||||
for (ldtk.levels) |level| {
|
||||
std.log.warn("Level: {}", .{levels.items.len});
|
||||
const parsed_level = try parseLevel(.{
|
||||
.allocator = allocator,
|
||||
.ldtk = ldtk,
|
||||
|
@ -70,7 +71,6 @@ fn make(step: *std.build.Step) !void {
|
|||
}
|
||||
defer for (levels.items) |level| {
|
||||
allocator.free(level.tiles.?);
|
||||
allocator.free(level.entities.?);
|
||||
};
|
||||
|
||||
var circuit = try buildCircuit(allocator, levels.items);
|
||||
|
@ -109,7 +109,7 @@ fn make(step: *std.build.Step) !void {
|
|||
defer data.deinit();
|
||||
const writer = data.writer();
|
||||
|
||||
try world.write(writer, level_headers.items, circuit.items, levels.items);
|
||||
try world.write(writer, level_headers.items, entity_array.items, circuit.items, levels.items);
|
||||
|
||||
// Open output file and write data into it
|
||||
cwd.makePath(this.builder.getInstallPath(.lib, "")) catch |e| switch (e) {
|
||||
|
@ -163,20 +163,28 @@ fn parseLevel(opt: struct {
|
|||
// Parsing code for wire entities. They're a little more complex
|
||||
// than the rest
|
||||
if (kind_opt) |kind| {
|
||||
const levelc = world.Coordinate.fromWorld(world_x, world_y);
|
||||
if (kind != .WireNode) {
|
||||
const entc = world.Coordinate.init(.{
|
||||
@intCast(i16, entity.__grid[0]),
|
||||
@intCast(i16, entity.__grid[1]),
|
||||
});
|
||||
const world_entity = world.Entity{
|
||||
.kind = kind,
|
||||
.x = @intCast(i16, entity.__grid[0]),
|
||||
.y = @intCast(i16, entity.__grid[1]),
|
||||
.coord = levelc.addC(entc)
|
||||
};
|
||||
try entity_array.append(world_entity);
|
||||
} else {
|
||||
const p1_x: i16 = @intCast(i16, entity.__grid[0]);
|
||||
const p1_y: i16 = @intCast(i16, entity.__grid[1]);
|
||||
var anchor1 = false;
|
||||
var anchor2 = false;
|
||||
var p2_x: i16 = p1_x;
|
||||
var p2_y: i16 = p1_y;
|
||||
const p1_c = world.Coordinate.init(.{
|
||||
@intCast(i16, entity.__grid[0]),
|
||||
@intCast(i16, entity.__grid[1]),
|
||||
});
|
||||
var p2_c = world.Coordinate.init(.{
|
||||
@intCast(i16, entity.__grid[0]),
|
||||
@intCast(i16, entity.__grid[1]),
|
||||
});
|
||||
for (entity.fieldInstances) |field| {
|
||||
if (std.mem.eql(u8, field.__identifier, "Anchor")) {
|
||||
const anchors = field.__value.Array.items;
|
||||
|
@ -187,26 +195,28 @@ fn parseLevel(opt: struct {
|
|||
const endpoint = field.__value.Array.items[end];
|
||||
const x = endpoint.Object.get("cx").?;
|
||||
const y = endpoint.Object.get("cy").?;
|
||||
p2_x = @intCast(i16, x.Integer);
|
||||
p2_y = @intCast(i16, y.Integer);
|
||||
p2_c.val = .{
|
||||
@intCast(i16, x.Integer),
|
||||
@intCast(i16, y.Integer),
|
||||
};
|
||||
}
|
||||
}
|
||||
const wire_begin = world.Entity{
|
||||
.kind = if (anchor1) .WireAnchor else .WireNode,
|
||||
.x = p1_x,
|
||||
.y = p1_y,
|
||||
.coord = p1_c.addC(levelc),
|
||||
};
|
||||
try entity_array.append(wire_begin);
|
||||
|
||||
const wire_end = world.Entity{
|
||||
.kind = if (anchor2) .WireEndAnchor else .WireEndNode,
|
||||
.x = p2_x,
|
||||
.y = p2_y,
|
||||
.coord = p2_c.addC(levelc),
|
||||
};
|
||||
try entity_array.append(wire_end);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std.log.warn("Entities: {}", .{entity_array.items.len});
|
||||
} else if (std.mem.eql(u8, layer.__identifier, "Circuit")) {
|
||||
// Circuit
|
||||
std.debug.assert(layer.__type == .IntGrid);
|
||||
|
@ -235,14 +245,13 @@ fn parseLevel(opt: struct {
|
|||
const width = @intCast(u16, circuit.__cWid);
|
||||
const size = @intCast(u16, width * circuit.__cHei);
|
||||
|
||||
// Entities go into global scope now
|
||||
var parsed_level = world.Level{
|
||||
.world_x = world_x,
|
||||
.world_y = world_y,
|
||||
.width = @intCast(u16, width),
|
||||
.size = @intCast(u16, size),
|
||||
.entity_count = @intCast(u16, entity_array.items.len),
|
||||
.tiles = try allocator.alloc(world.TileData, size),
|
||||
.entities = try allocator.dupe(world.Entity, entity_array.items),
|
||||
};
|
||||
|
||||
const tiles = parsed_level.tiles.?;
|
||||
|
|
Loading…
Reference in New Issue