From 99a3d66bf16ea89cd1d0a7cc1db8ce72ba45a96b Mon Sep 17 00:00:00 2001 From: IntegratedQuantum Date: Fri, 8 Nov 2024 21:27:04 +0100 Subject: [PATCH] Convert recipe files to zon. fixes #767 --- assets/cubyz/recipes/brick_recipes | 42 -------- assets/cubyz/recipes/brick_recipes.zig.zon | 58 ++++++++++ assets/cubyz/recipes/special_recipes | 15 --- assets/cubyz/recipes/special_recipes.zig.zon | 18 ++++ assets/cubyz/recipes/wood_recipes | 63 ----------- assets/cubyz/recipes/wood_recipes.zig.zon | 85 +++++++++++++++ src/assets.zig | 20 ++-- src/items.zig | 107 +++++++------------ 8 files changed, 207 insertions(+), 201 deletions(-) delete mode 100644 assets/cubyz/recipes/brick_recipes create mode 100644 assets/cubyz/recipes/brick_recipes.zig.zon delete mode 100644 assets/cubyz/recipes/special_recipes create mode 100644 assets/cubyz/recipes/special_recipes.zig.zon delete mode 100644 assets/cubyz/recipes/wood_recipes create mode 100644 assets/cubyz/recipes/wood_recipes.zig.zon diff --git a/assets/cubyz/recipes/brick_recipes b/assets/cubyz/recipes/brick_recipes deleted file mode 100644 index 5e18471a..00000000 --- a/assets/cubyz/recipes/brick_recipes +++ /dev/null @@ -1,42 +0,0 @@ -cubyz:marble -result cubyz:marble_tile - -cubyz:marble -result cubyz:marble_bricks - -cubyz:glacite -result cubyz:glacite_tile - -cubyz:glacite -result cubyz:glacite_bricks - -cubyz:stone -result cubyz:stone_tile - -cubyz:stone -result cubyz:stone_bricks - -cubyz:sandstone -result cubyz:sandstone_tile - -cubyz:sandstone -result cubyz:sandstone_bricks - -cubyz:limestone -result cubyz:limestone_tiles - -cubyz:limestone -result cubyz:limestone_bricks - -cubyz:basalt -result cubyz:basalt_tile - -cubyz:basalt -result cubyz:basalt_bricks - -cubyz:ferrock -result cubyz:ferrock_bricks - -cubyz:void_stone -result cubyz:void_stone_bricks - diff --git a/assets/cubyz/recipes/brick_recipes.zig.zon b/assets/cubyz/recipes/brick_recipes.zig.zon new file mode 100644 index 00000000..a807c3c8 --- /dev/null +++ b/assets/cubyz/recipes/brick_recipes.zig.zon @@ -0,0 +1,58 @@ +.{ + .{ + .inputs = .{"cubyz:marble"}, + .output = "cubyz:marble_tile", + }, + .{ + .inputs = .{"cubyz:marble"}, + .output = "cubyz:marble_bricks", + }, + .{ + .inputs = .{"cubyz:glacite"}, + .output = "cubyz:glacite_tile", + }, + .{ + .inputs = .{"cubyz:glacite"}, + .output = "cubyz:glacite_bricks", + }, + .{ + .inputs = .{"cubyz:stone"}, + .output = "cubyz:stone_tile", + }, + .{ + .inputs = .{"cubyz:stone"}, + .output = "cubyz:stone_bricks", + }, + .{ + .inputs = .{"cubyz:sandstone"}, + .output = "cubyz:sandstone_tile", + }, + .{ + .inputs = .{"cubyz:sandstone"}, + .output = "cubyz:sandstone_bricks", + }, + .{ + .inputs = .{"cubyz:limestone"}, + .output = "cubyz:limestone_tiles", + }, + .{ + .inputs = .{"cubyz:limestone"}, + .output = "cubyz:limestone_bricks", + }, + .{ + .inputs = .{"cubyz:basalt"}, + .output = "cubyz:basalt_tile", + }, + .{ + .inputs = .{"cubyz:basalt"}, + .output = "cubyz:basalt_bricks", + }, + .{ + .inputs = .{"cubyz:ferrock"}, + .output = "cubyz:ferrock_bricks", + }, + .{ + .inputs = .{"cubyz:void_stone"}, + .output = "cubyz:void_stone_bricks", + }, +}, diff --git a/assets/cubyz/recipes/special_recipes b/assets/cubyz/recipes/special_recipes deleted file mode 100644 index 68a8db9c..00000000 --- a/assets/cubyz/recipes/special_recipes +++ /dev/null @@ -1,15 +0,0 @@ -cubyz:birch_planks -cubyz:iron_ingot -result cubyz:chisel - -cubyz:oak_planks -cubyz:iron_ingot -result cubyz:chisel - -cubyz:mahogany_planks -cubyz:iron_ingot -result cubyz:chisel - -cubyz:pine_planks -cubyz:iron_ingot -result cubyz:chisel \ No newline at end of file diff --git a/assets/cubyz/recipes/special_recipes.zig.zon b/assets/cubyz/recipes/special_recipes.zig.zon new file mode 100644 index 00000000..dcffbf90 --- /dev/null +++ b/assets/cubyz/recipes/special_recipes.zig.zon @@ -0,0 +1,18 @@ +.{ + .{ + .inputs = .{"cubyz:birch_planks", "cubyz:iron_ingot"}, + .output = "cubyz:chisel", + }, + .{ + .inputs = .{"cubyz:oak_planks", "cubyz:iron_ingot"}, + .output = "cubyz:chisel", + }, + .{ + .inputs = .{"cubyz:mahogany_planks", "cubyz:iron_ingot"}, + .output = "cubyz:chisel", + }, + .{ + .inputs = .{"cubyz:pine_planks", "cubyz:iron_ingot"}, + .output = "cubyz:chisel", + }, +} diff --git a/assets/cubyz/recipes/wood_recipes b/assets/cubyz/recipes/wood_recipes deleted file mode 100644 index be50dd69..00000000 --- a/assets/cubyz/recipes/wood_recipes +++ /dev/null @@ -1,63 +0,0 @@ -4*cubyz:birch_planks -result cubyz:workbench - -4*cubyz:oak_planks -result cubyz:workbench - -4*cubyz:mahogany_planks -result cubyz:workbench - -4*cubyz:pine_planks -result cubyz:workbench - -cubyz:birch_log -result 4*cubyz:birch_planks - -cubyz:birch_top -result 3*cubyz:birch_planks - -cubyz:oak_log -result 4*cubyz:oak_planks - -cubyz:oak_top -result 3*cubyz:oak_planks - -cubyz:mahogany_log -result 4*cubyz:mahogany_planks - -cubyz:mahogany_top -result 3*cubyz:mahogany_planks - -cubyz:pine_log -result 4*cubyz:pine_planks - -cubyz:pine_top -result 3*cubyz:pine_planks - -cubyz:birch_planks -result 2*cubyz:birch_fence - -cubyz:oak_planks -result 2*cubyz:oak_fence - -cubyz:mahogany_planks -result 2*cubyz:mahogany_fence - -cubyz:pine_planks -result 2*cubyz:pine_fence - -cubyz:coal -cubyz:birch_planks -result 8*cubyz:torch - -cubyz:coal -cubyz:oak_planks -result 8*cubyz:torch - -cubyz:coal -cubyz:mahogany_planks -result 8*cubyz:torch - -cubyz:coal -cubyz:pine_planks -result 8*cubyz:torch \ No newline at end of file diff --git a/assets/cubyz/recipes/wood_recipes.zig.zon b/assets/cubyz/recipes/wood_recipes.zig.zon new file mode 100644 index 00000000..f777d789 --- /dev/null +++ b/assets/cubyz/recipes/wood_recipes.zig.zon @@ -0,0 +1,85 @@ +.{ + .{ + .inputs = .{"4 cubyz:birch_planks"}, + .output = "cubyz:workbench", + }, + .{ + .inputs = .{"4 cubyz:oak_planks"}, + .output = "cubyz:workbench", + }, + .{ + .inputs = .{"4 cubyz:mahogany_planks"}, + .output = "cubyz:workbench", + }, + .{ + .inputs = .{"4 cubyz:pine_planks"}, + .output = "cubyz:workbench", + }, + + .{ + .inputs = .{"cubyz:birch_log"}, + .output = "4 cubyz:birch_planks", + }, + .{ + .inputs = .{"cubyz:birch_top"}, + .output = "3 cubyz:birch_planks", + }, + .{ + .inputs = .{"cubyz:oak_log"}, + .output = "4 cubyz:oak_planks", + }, + .{ + .inputs = .{"cubyz:oak_top"}, + .output = "3 cubyz:oak_planks", + }, + .{ + .inputs = .{"cubyz:mahogany_log"}, + .output = "4 cubyz:mahogany_planks", + }, + .{ + .inputs = .{"cubyz:mahogany_top"}, + .output = "3 cubyz:mahogany_planks", + }, + .{ + .inputs = .{"cubyz:pine_log"}, + .output = "4 cubyz:pine_planks", + }, + .{ + .inputs = .{"cubyz:pine_top"}, + .output = "3 cubyz:pine_planks", + }, + + .{ + .inputs = .{"cubyz:birch_planks"}, + .output = "2 cubyz:birch_fence", + }, + .{ + .inputs = .{"cubyz:oak_planks"}, + .output = "2 cubyz:oak_fence", + }, + .{ + .inputs = .{"cubyz:mahogany_planks"}, + .output = "2 cubyz:mahogany_fence", + }, + .{ + .inputs = .{"cubyz:pine_planks"}, + .output = "2 cubyz:pine_fence", + }, + + .{ + .inputs = .{"cubyz:birch_planks", "cubyz:coal"}, + .output = "8 cubyz:torch", + }, + .{ + .inputs = .{"cubyz:oak_planks", "cubyz:coal"}, + .output = "8 cubyz:torch", + }, + .{ + .inputs = .{"cubyz:mahogany_planks", "cubyz:coal"}, + .output = "8 cubyz:torch", + }, + .{ + .inputs = .{"cubyz:pine_planks", "cubyz:coal"}, + .output = "8 cubyz:torch", + }, +} diff --git a/src/assets.zig b/src/assets.zig index 3138a5d2..746f533b 100644 --- a/src/assets.zig +++ b/src/assets.zig @@ -12,7 +12,7 @@ var arenaAllocator: NeverFailingAllocator = undefined; var commonBlocks: std.StringHashMap(ZonElement) = undefined; var commonBiomes: std.StringHashMap(ZonElement) = undefined; var commonItems: std.StringHashMap(ZonElement) = undefined; -var commonRecipes: main.List([]const u8) = undefined; +var commonRecipes: std.StringHashMap(ZonElement) = undefined; var commonModels: std.StringHashMap([]const u8) = undefined; /// Reads .zig.zon files recursively from all subfolders. @@ -127,7 +127,7 @@ pub fn readAllObjFilesInAddonsHashmap(externalAllocator: NeverFailingAllocator, } } -pub fn readAssets(externalAllocator: NeverFailingAllocator, assetPath: []const u8, blocks: *std.StringHashMap(ZonElement), items: *std.StringHashMap(ZonElement), biomes: *std.StringHashMap(ZonElement), recipes: *main.List([]const u8), models: *std.StringHashMap([]const u8)) void { +pub fn readAssets(externalAllocator: NeverFailingAllocator, assetPath: []const u8, blocks: *std.StringHashMap(ZonElement), items: *std.StringHashMap(ZonElement), biomes: *std.StringHashMap(ZonElement), recipes: *std.StringHashMap(ZonElement), models: *std.StringHashMap([]const u8)) void { var addons = main.List(std.fs.Dir).init(main.stackAllocator); defer addons.deinit(); var addonNames = main.List([]const u8).init(main.stackAllocator); @@ -161,7 +161,7 @@ pub fn readAssets(externalAllocator: NeverFailingAllocator, assetPath: []const u readAllZonFilesInAddons(externalAllocator, addons, addonNames, "blocks", blocks); readAllZonFilesInAddons(externalAllocator, addons, addonNames, "items", items); readAllZonFilesInAddons(externalAllocator, addons, addonNames, "biomes", biomes); - readAllFilesInAddons(externalAllocator, addons, "recipes", recipes); + readAllZonFilesInAddons(externalAllocator, addons, addonNames, "recipes", recipes); readAllObjFilesInAddonsHashmap(externalAllocator, addons, addonNames, "models", models); } @@ -173,7 +173,7 @@ pub fn init() void { commonBlocks = .init(arenaAllocator.allocator); commonItems = .init(arenaAllocator.allocator); commonBiomes = .init(arenaAllocator.allocator); - commonRecipes = .init(arenaAllocator); + commonRecipes = .init(arenaAllocator.allocator); commonModels = .init(arenaAllocator.allocator); readAssets(arenaAllocator, "assets/", &commonBlocks, &commonItems, &commonBiomes, &commonRecipes, &commonModels); @@ -203,8 +203,8 @@ fn registerBlock(assetFolder: []const u8, id: []const u8, zon: ZonElement) !void } } -fn registerRecipesFromFile(file: []const u8) void { - items_zig.registerRecipes(file); +fn registerRecipesFromZon(zon: ZonElement) void { + items_zig.registerRecipes(zon); } pub const Palette = struct { // MARK: Palette @@ -270,8 +270,7 @@ pub fn loadWorldAssets(assetFolder: []const u8, blockPalette: *Palette, biomePal defer items.clearAndFree(); var biomes = commonBiomes.cloneWithAllocator(main.stackAllocator.allocator) catch unreachable; defer biomes.clearAndFree(); - var recipes = main.List([]const u8).init(main.stackAllocator); - recipes.appendSlice(commonRecipes.items); + var recipes = commonRecipes.cloneWithAllocator(main.stackAllocator.allocator) catch unreachable; defer recipes.clearAndFree(); var models = commonModels.cloneWithAllocator(main.stackAllocator.allocator) catch unreachable; defer models.clearAndFree(); @@ -312,8 +311,9 @@ pub fn loadWorldAssets(assetFolder: []const u8, blockPalette: *Palette, biomePal // block drops: blocks_zig.finishBlocks(blocks); - for(recipes.items) |recipe| { - registerRecipesFromFile(recipe); + iterator = recipes.iterator(); + while(iterator.next()) |entry| { + registerRecipesFromZon(entry.value_ptr.*); } // Biomes: diff --git a/src/items.zig b/src/items.zig index aad8495f..c7027fa0 100644 --- a/src/items.zig +++ b/src/items.zig @@ -1192,78 +1192,43 @@ pub fn register(_: []const u8, texturePath: []const u8, replacementTexturePath: return newItem; } -pub fn registerRecipes(file: []const u8) void { - var shortcuts = std.StringHashMap(*BaseItem).init(main.stackAllocator.allocator); - defer shortcuts.deinit(); - defer { - var keyIterator = shortcuts.keyIterator(); - while(keyIterator.next()) |key| { - main.stackAllocator.free(key.*); - } +fn parseRecipeItem(zon: ZonElement) !ItemStack { + var id = zon.as([]const u8, ""); + id = std.mem.trim(u8, id, &std.ascii.whitespace); + var result: ItemStack = .{.amount = 1}; + if(std.mem.indexOfScalar(u8, id, ' ')) |index| blk: { + result.amount = std.fmt.parseInt(u16, id[0..index], 0) catch break :blk; + id = id[index + 1..]; + id = std.mem.trim(u8, id, &std.ascii.whitespace); } - var items = main.List(*BaseItem).init(main.stackAllocator); - defer items.deinit(); - var itemAmounts = main.List(u16).init(main.stackAllocator); - defer itemAmounts.deinit(); - var string = main.List(u8).init(main.stackAllocator); - defer string.deinit(); - var lines = std.mem.splitScalar(u8, file, '\n'); - while(lines.next()) |line| { - // shortcuts: - if(std.mem.containsAtLeast(u8, line, 1, "=")) { - var parts = std.mem.splitScalar(u8, line, '='); - for(parts.first()) |char| { - if(std.ascii.isWhitespace(char)) continue; - string.append(char); - } - const shortcut = string.toOwnedSlice(); - const id = std.mem.trim(u8, parts.rest(), &std.ascii.whitespace); - const item = shortcuts.get(id) orelse getByID(id) orelse &BaseItem.unobtainable; - shortcuts.put(shortcut, item) catch unreachable; - } else if(std.mem.startsWith(u8, line, "result") and items.items.len != 0) { - defer items.clearAndFree(); - defer itemAmounts.clearAndFree(); - var id = line["result".len..]; - var amount: u16 = 1; - if(std.mem.containsAtLeast(u8, id, 1, "*")) { - var parts = std.mem.splitScalar(u8, id, '*'); - const amountString = std.mem.trim(u8, parts.first(), &std.ascii.whitespace); - amount = std.fmt.parseInt(u16, amountString, 0) catch 1; - id = parts.rest(); - } - id = std.mem.trim(u8, id, &std.ascii.whitespace); - const item = shortcuts.get(id) orelse getByID(id) orelse continue; - const recipe = Recipe { - .sourceItems = arena.allocator().dupe(*BaseItem, items.items), - .sourceAmounts = arena.allocator().dupe(u16, itemAmounts.items), - .resultItem = ItemStack{.item = Item{.baseItem = item}, .amount = amount}, - }; - recipeList.append(recipe); - } else { - var ingredients = std.mem.splitScalar(u8, line, ','); - outer: while(ingredients.next()) |ingredient| { - var id = ingredient; - if(id.len == 0) continue; - var amount: u16 = 1; - if(std.mem.containsAtLeast(u8, id, 1, "*")) { - var parts = std.mem.splitScalar(u8, id, '*'); - const amountString = std.mem.trim(u8, parts.first(), &std.ascii.whitespace); - amount = std.fmt.parseInt(u16, amountString, 0) catch 1; - id = parts.rest(); - } - id = std.mem.trim(u8, id, &std.ascii.whitespace); - const item = shortcuts.get(id) orelse getByID(id) orelse continue; - // Resolve duplicates: - for(items.items, 0..) |presentItem, i| { - if(presentItem == item) { - itemAmounts.items[i] += amount; - continue :outer; - } - } - items.append(item); - itemAmounts.append(amount); - } - } + result.item = .{.baseItem = getByID(id) orelse return error.ItemNotFound}; + return result; +} + +fn parseRecipe(zon: ZonElement) !Recipe { + const inputs = zon.getChild("inputs").toSlice(); + const output = try parseRecipeItem(zon.getChild("output")); + const recipe = Recipe { + .sourceItems = arena.allocator().alloc(*BaseItem, inputs.len), + .sourceAmounts = arena.allocator().alloc(u16, inputs.len), + .resultItem = output, + }; + errdefer { + arena.allocator().free(recipe.sourceAmounts); + arena.allocator().free(recipe.sourceItems); + } + for(inputs, 0..) |inputZon, i| { + const input = try parseRecipeItem(inputZon); + recipe.sourceItems[i] = input.item.?.baseItem; + recipe.sourceAmounts[i] = input.amount; + } + return recipe; +} + +pub fn registerRecipes(zon: ZonElement) void { + for(zon.toSlice()) |recipeZon| { + const recipe = parseRecipe(recipeZon) catch continue; + recipeList.append(recipe); } }