diff --git a/src/assets.zig b/src/assets.zig index 6c2c1678..5e06f306 100644 --- a/src/assets.zig +++ b/src/assets.zig @@ -83,13 +83,17 @@ pub fn init() !void { } fn registerItem(assetFolder: []const u8, id: []const u8, info: JsonElement) !void { - try items_zig.register(assetFolder, id, info); + _ = try items_zig.register(assetFolder, id, info); } fn registerBlock(assetFolder: []const u8, id: []const u8, info: JsonElement) !void { - try blocks_zig.register(assetFolder, id, info); // TODO: Modded block registries + const block = try blocks_zig.register(assetFolder, id, info); // TODO: Modded block registries try blocks_zig.meshes.register(assetFolder, id, info); + if(info.get(bool, "hasItem", true)) { + const item = try items_zig.register(assetFolder, id, info.getChild("item")); + item.block = block; + } // TODO: // // Ores: // JsonObject oreProperties = json.getObject("ore"); @@ -105,35 +109,6 @@ fn registerBlock(assetFolder: []const u8, id: []const u8, info: JsonElement) !vo // oreRegistry.register(ore); // oreContainers.add(oreIDs); // } -// TODO: -// // Block drops: -// String[] blockDrops = json.getArrayNoNull("drops").getStrings(); -// ItemBlock self = null; -// if(json.getBool("hasItem", true)) { -// self = new ItemBlock(block, json.getObjectOrNew("item")); -// items.add(self); // Add each block as an item, so it gets displayed in the creative inventory. -// } -// for (String blockDrop : blockDrops) { -// blockDrop = blockDrop.trim(); -// String[] data = blockDrop.split("\\s+"); -// float amount = 1; -// String name = data[0]; -// if (data.length == 2) { -// amount = Float.parseFloat(data[0]); -// name = data[1]; -// } -// if (name.equals("auto")) { -// if(self == null) { -// Logger.error("Block "+id+" tried to drop itself(\"auto\"), but hasItem is false."); -// } else { -// Blocks.addBlockDrop(block, new BlockDrop(self, amount)); -// } -// } else if (!name.equals("none")) { -// missingDropsBlock.add(block); -// missingDropsAmount.add(amount); -// missingDropsItem.add(name); -// } -// } } pub const BlockPalette = struct { @@ -203,22 +178,23 @@ pub fn loadWorldAssets(assetFolder: []const u8, palette: *BlockPalette) !void { // blocks: var block: u32 = 0; for(palette.palette.items) |id| { - var nullKeyValue = blocks.fetchRemove(id); + var nullValue = blocks.get(id); var jsonObject: JsonElement = undefined; - if(nullKeyValue) |keyValue| { - jsonObject = keyValue.value; + if(nullValue) |value| { + jsonObject = value; } else { std.log.err("Missing block: {s}. Replacing it with default block.", .{id}); var map: *std.StringHashMap(JsonElement) = try main.threadAllocator.create(std.StringHashMap(JsonElement)); map.* = std.StringHashMap(JsonElement).init(main.threadAllocator); jsonObject = JsonElement{.JsonObject=map}; } - defer if(nullKeyValue == null) jsonObject.free(main.threadAllocator); + defer if(nullValue == null) jsonObject.free(main.threadAllocator); try registerBlock(assetFolder, id, jsonObject); block += 1; } var iterator = blocks.iterator(); while(iterator.next()) |entry| { + if(blocks_zig.hasRegistered(entry.key_ptr.*)) continue; try registerBlock(assetFolder, entry.key_ptr.*, entry.value_ptr.*); try palette.add(entry.key_ptr.*); block += 1; @@ -230,6 +206,9 @@ pub fn loadWorldAssets(assetFolder: []const u8, palette: *BlockPalette) !void { try registerItem(assetFolder, entry.key_ptr.*, entry.value_ptr.*); } + // block drops: + try blocks_zig.registerBlockDrops(blocks); + // public void registerBlocks(Registry registries, NoIDRegistry oreRegistry, BlockPalette palette) { // HashMap perWorldBlocks = new HashMap<>(commonBlocks); // readAllJsonObjects("blocks", (json, id) -> { @@ -251,11 +230,6 @@ pub fn deinit() void { //TODO: // public static final ArrayList addons = new ArrayList<>(); // private static final ArrayList items = new ArrayList<>(); -// -// // Used to fetch block drops that aren't loaded during block loading. -// private static final IntSimpleList missingDropsBlock = new IntSimpleList(); -// private static final ArrayList missingDropsItem = new ArrayList<>(); -// private static final ArrayList missingDropsAmount = new ArrayList<>(); // // private static final ArrayList ores = new ArrayList<>(); // private static final ArrayList oreContainers = new ArrayList<>(); diff --git a/src/blocks.zig b/src/blocks.zig index 6e67101e..abedff01 100644 --- a/src/blocks.zig +++ b/src/blocks.zig @@ -6,6 +6,7 @@ const SSBO = @import("graphics.zig").SSBO; const Image = @import("graphics.zig").Image; const Color = @import("graphics.zig").Color; const TextureArray = @import("graphics.zig").TextureArray; +const items = @import("items.zig"); const models = @import("models.zig"); pub const BlockClass = enum(u8) { @@ -23,7 +24,11 @@ var allocator = arena.allocator(); pub const MaxBLockCount: usize = 65536; // 16 bit limit -pub const BlockDrop = u0; // TODO! +pub const BlockDrop = struct { + item: items.Item, + amount: f32, +}; + pub const RotationMode = u0; // TODO! var _lightingTransparent: [MaxBLockCount]bool = undefined; @@ -51,7 +56,7 @@ var reverseIndices = std.StringHashMap(u16).init(arena.allocator()); var size: u32 = 0; -pub fn register(_: []const u8, id: []const u8, json: JsonElement) !void { +pub fn register(_: []const u8, id: []const u8, json: JsonElement) !u16 { if(reverseIndices.contains(id)) { std.log.warn("Registered block with id {s} twice!", .{id}); } @@ -81,6 +86,44 @@ pub fn register(_: []const u8, id: []const u8, json: JsonElement) !void { _viewThrough[size] = json.get(bool, "viewThrough", false) or _transparent[size]; size += 1; + return @intCast(u16, size - 1); +} + +fn registerBlockDrop(typ: u16, json: JsonElement) !void { + const drops = json.toSlice(); + + var result = try allocator.alloc(BlockDrop, drops.len); + result.len = 0; + + for(drops) |blockDrop| { + var string = blockDrop.as([]const u8, "auto"); + string = std.mem.trim(u8, string, " "); + var iterator = std.mem.split(u8, string, " "); + + var name = iterator.next() orelse continue; + var amount: f32 = 1; + while(iterator.next()) |next| { + if(next.len == 0) continue; // skip multiple spaces. + amount = std.fmt.parseFloat(f32, name) catch 1; + name = next; + break; + } + + if(std.mem.eql(u8, name, "auto")) { + name = _id[typ]; + } + + var item = items.getByID(name) orelse continue; + result.len += 1; + result[result.len - 1] = BlockDrop{.item = items.Item{.baseItem = item}, .amount = amount}; + } +} + +pub fn registerBlockDrops(jsonElements: std.StringHashMap(JsonElement)) !void { + var i: u16 = 0; + while(i < size) : (i += 1) { + try registerBlockDrop(i, jsonElements.get(_id[i]) orelse continue); + } } pub fn reset() void { @@ -100,6 +143,10 @@ pub fn getByID(id: []const u8) u16 { } } +pub fn hasRegistered(id: []const u8) bool { + return reverseIndices.contains(id); +} + pub const Block = packed struct { typ: u16, data: u16, diff --git a/src/items.zig b/src/items.zig index bed93fac..732f9965 100644 --- a/src/items.zig +++ b/src/items.zig @@ -1204,7 +1204,7 @@ pub fn globalInit() void { itemListSize = 0; } -pub fn register(_: []const u8, id: []const u8, jsonObject: JsonElement) !void { +pub fn register(_: []const u8, id: []const u8, jsonObject: JsonElement) !*BaseItem { std.log.info("{s}", .{id}); if(reverseIndices.contains(id)) { std.log.warn("Registered block with id {s} twice!", .{id}); @@ -1213,6 +1213,7 @@ pub fn register(_: []const u8, id: []const u8, jsonObject: JsonElement) !void { try newItem.init(arena.allocator(), id, jsonObject); try reverseIndices.put(newItem.id, newItem); itemListSize += 1; + return newItem; } pub fn reset() void { @@ -1226,4 +1227,13 @@ pub fn reset() void { pub fn deinit() void { reverseIndices.clearAndFree(); arena.deinit(); +} + +pub fn getByID(id: []const u8) ?*BaseItem { + if(reverseIndices.get(id)) |result| { + return result; + } else { + std.log.warn("Couldn't find item {s}.", .{id}); + return null; + } } \ No newline at end of file diff --git a/src/json.zig b/src/json.zig index 5c4828c0..a907e884 100644 --- a/src/json.zig +++ b/src/json.zig @@ -167,6 +167,15 @@ pub const JsonElement = union(JsonType) { try self.JsonObject.put(try self.JsonObject.allocator.dupe(u8, key), result); } + pub fn toSlice(self: *const JsonElement) []JsonElement { + switch(self.*) { + JsonType.JsonArray => |arr| { + return arr.items; + }, + else => return &[0]JsonElement{}, + } + } + pub fn free(self: *const JsonElement, allocator: Allocator) void { switch(self.*) { JsonType.JsonInt, JsonType.JsonFloat, JsonType.JsonBool, JsonType.JsonNull, JsonType.JsonString => return,