Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions assets/cubyz/blocks/transmutation_workbench.zig.zon
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
.{
.tags = .{.diggable},
.blockHealth = 6.5,
.drops = .{
.{.items = .{.auto}},
},
.model = "cubyz:cube",
.rotation = "cubyz:stairs",
.texture = "cubyz:aerosoil",
.onInteract = .{
.type = .open_crafting_window,
.craftingTags = .{.alchemy},
},
}
6 changes: 6 additions & 0 deletions assets/cubyz/recipes/cloth_recipes.zig.zon
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,10 @@
.output = "cubyz:cloth/block/{color}",
.reversible = true,
},
.{
.inputs = .{"4 cubyz:copper_ingot"},
.output = "cubyz:silver_ingot",
.reversible = true,
.craftingTags = .{.alchemy},
},
}
1 change: 1 addition & 0 deletions src/callbacks/block/client/_list.zig
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
pub const edit_sign = @import("edit_sign.zig");
pub const open_chest = @import("open_chest.zig");
pub const open_window = @import("open_window.zig");
pub const open_crafting_window = @import("open_crafting_window.zig");
2 changes: 1 addition & 1 deletion src/callbacks/block/client/edit_sign.zig
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ pub fn init(_: ZonElement, _: main.callbacks.Creator) ?*anyopaque {

pub fn run(_: *anyopaque, params: main.callbacks.ClientBlockCallback.Params) main.callbacks.Result {
if (params.block.blockEntity() == null or !std.mem.eql(u8, params.block.blockEntity().?.id, "cubyz:sign")) {
std.log.err("Can only edit sign if block entity of the block is a sign.", .{});
std.log.err("Error: Can only edit sign if block entity of the block is a sign.", .{});
return .ignored;
}
main.block_entity.BlockEntityTypes.@"cubyz:sign".StorageClient.mutex.lock();
Expand Down
2 changes: 1 addition & 1 deletion src/callbacks/block/client/open_chest.zig
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ pub fn init(_: ZonElement, _: main.callbacks.Creator) ?*anyopaque {

pub fn run(_: *anyopaque, params: main.callbacks.ClientBlockCallback.Params) main.callbacks.Result {
if (params.block.blockEntity() == null or !std.mem.eql(u8, params.block.blockEntity().?.id, "cubyz:chest")) {
std.log.err("Can only open chest if block entity of the block is a chest.", .{});
std.log.err("Error: Can only open chest if block entity of the block is a chest.", .{});
return .ignored;
}
main.network.protocols.blockEntityUpdate.sendClientDataUpdateToServer(main.game.world.?.conn, params.blockPos);
Expand Down
26 changes: 26 additions & 0 deletions src/callbacks/block/client/open_crafting_window.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
const std = @import("std");

const main = @import("main");
const Block = main.blocks.Block;
const vec = main.vec;
const Vec3i = vec.Vec3i;
const ZonElement = main.ZonElement;

craftingTags: []main.Tag,

pub fn init(zon: ZonElement, _: main.callbacks.Creator) ?*@This() {
const result = main.worldArena.create(@This());
const craftingTags = main.Tag.loadTagsFromZon(main.worldArena, zon.getChild("craftingTags"));
if (craftingTags.len == 0) std.log.err("Error: Missing craftingTags \"name\" for open_crafting_window event.", .{});
result.* = .{
.craftingTags = craftingTags,
};
return result;
}

pub fn run(self: *@This(), _: main.callbacks.ClientBlockCallback.Params) main.callbacks.Result {
main.gui.windowlist.inventory_crafting.openFromCallback(self.craftingTags);
main.Window.setMouseGrabbed(false);
defer main.worldArena.free(self.craftingTags);
return .handled;
}
2 changes: 1 addition & 1 deletion src/callbacks/block/client/open_window.zig
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ pub fn init(zon: ZonElement, _: main.callbacks.Creator) ?*@This() {
const result = main.worldArena.create(@This());
result.* = .{
.windowName = main.worldArena.dupe(u8, zon.get([]const u8, "name") orelse {
std.log.err("Missing field \"name\" for open_window event.", .{});
std.log.err("Error: Missing field \"name\" for open_window event.", .{});
return null;
}),
};
Expand Down
19 changes: 19 additions & 0 deletions src/gui/windows/inventory_crafting.zig
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,24 @@ var itemAmount: main.ListManaged(u32) = undefined;
var inventories: main.ListManaged(ClientInventory) = undefined;

pub var arrowTexture: Texture = undefined;
pub var craftableFromTags: []main.Tag = undefined;

pub fn init() void {
arrowTexture = Texture.initFromFile("assets/cubyz/ui/inventory/crafting_arrow.png");
craftableFromTags = main.stackAllocator.alloc(main.Tag, 1);
craftableFromTags[0] = main.Tag.handCraftable;
}

pub fn deinit() void {
arrowTexture.deinit();
main.stackAllocator.free(craftableFromTags);
}

pub fn openFromCallback(craftingTags: []main.Tag) void {
gui.closeWindowFromRef(&window);
gui.openWindowFromRef(&window);
craftableFromTags = craftingTags;
main.Window.setMouseGrabbed(false);
}

fn addItemStackToAvailable(itemStack: ItemStack) void {
Expand Down Expand Up @@ -93,6 +104,14 @@ fn findAvailableRecipes(list: *VerticalList) bool {
}
continue :outer; // Ingredient not found.
}
middle: for (recipe.craftingTags) |tag| {
for (craftableFromTags) |craftingStationTag| {
if (tag == craftingStationTag) {
continue :middle;
}
}
continue :outer; // Recipe not craftable by this.
}
// All ingredients found: Add it to the list.
const inv = ClientInventory.init(main.globalAllocator, recipe.sourceItems.len + 1, .{.crafting = recipe}, .other, .{});

Expand Down
20 changes: 19 additions & 1 deletion src/items.zig
Original file line number Diff line number Diff line change
Expand Up @@ -1160,16 +1160,21 @@ pub const Recipe = struct { // MARK: Recipe
sourceAmounts: []u16,
resultItem: BaseItemIndex,
resultAmount: u16,
craftingTags: []Tag,

fn getValidRecipe(self: Recipe) error{Invalid}!*Recipe {
outer: for (main.items.getRecipes()) |*recipe| {
if (recipe.resultItem != self.resultItem) continue;
if (recipe.resultAmount != self.resultAmount) continue;
if (recipe.sourceItems.len != self.sourceItems.len) continue;
if (recipe.craftingTags.len != self.craftingTags.len) continue;
for (recipe.sourceItems, recipe.sourceAmounts, self.sourceItems, self.sourceAmounts) |recipeItem, recipeAmount, selfItem, selfAmount| {
if (recipeItem != selfItem) continue :outer;
if (recipeAmount != selfAmount) continue :outer;
}
for (recipe.craftingTags, self.craftingTags) |recipeCraftingTag, selfCraftingTag| {
if (recipeCraftingTag != selfCraftingTag) continue :outer;
}
return recipe;
}
return error.Invalid;
Expand All @@ -1178,11 +1183,16 @@ pub const Recipe = struct { // MARK: Recipe
pub fn toBytes(self: *const Recipe, writer: *BinaryWriter) void {
writer.writeEnum(BaseItemIndex, self.resultItem);
writer.writeVarInt(u16, self.resultAmount);
writer.writeVarInt(u16, self.resultAmount);
writer.writeVarInt(usize, self.sourceItems.len);
for (self.sourceItems, self.sourceAmounts) |item, amount| {
writer.writeEnum(BaseItemIndex, item);
writer.writeVarInt(u16, amount);
}
writer.writeVarInt(usize, self.craftingTags.len);
for (self.craftingTags) |tag| {
writer.writeEnum(Tag, tag);
}
}

pub fn fromBytes(reader: *BinaryReader) !*Recipe {
Expand All @@ -1200,7 +1210,15 @@ pub const Recipe = struct { // MARK: Recipe
sourceAmounts.append(main.stackAllocator, try reader.readVarInt(u16));
}

return getValidRecipe(.{.sourceItems = sourceItems.items, .sourceAmounts = sourceAmounts.items, .resultItem = resultItem, .resultAmount = resultAmount});
const tagCount = try reader.readVarInt(usize);
var craftingTagTypes: main.List(Tag) = .initCapacity(main.stackAllocator, @min(256, tagCount));
defer craftingTagTypes.deinit(main.stackAllocator);

while (reader.remaining.len > 0 and craftingTagTypes.items.len < tagCount) {
craftingTagTypes.append(main.stackAllocator, try reader.readEnum(Tag));
}

return getValidRecipe(.{.sourceItems = sourceItems.items, .sourceAmounts = sourceAmounts.items, .resultItem = resultItem, .resultAmount = resultAmount, .craftingTags = craftingTagTypes.items});
}
};

Expand Down
15 changes: 12 additions & 3 deletions src/items/recipes.zig
Original file line number Diff line number Diff line change
Expand Up @@ -190,19 +190,23 @@ fn generateItemCombos(allocator: NeverFailingAllocator, recipe: []const ZonEleme
return newInputCombos;
}

pub fn addRecipe(itemCombo: []const ItemWithAmount, list: *main.ListManaged(Recipe)) void {
pub fn addRecipe(itemCombo: []const ItemWithAmount, list: *main.ListManaged(Recipe), craftingTags: []Tag) void {
const inputs = itemCombo[0 .. itemCombo.len - 1];
const output = itemCombo[itemCombo.len - 1];
const recipe = Recipe{
.sourceItems = main.worldArena.alloc(BaseItemIndex, inputs.len),
.sourceAmounts = main.worldArena.alloc(u16, inputs.len),
.resultItem = output.item,
.resultAmount = output.amount,
.craftingTags = main.worldArena.alloc(Tag, craftingTags.len),
};
for (inputs, 0..) |input, i| {
recipe.sourceItems[i] = input.item;
recipe.sourceAmounts[i] = input.amount;
}
for (craftingTags, 0..) |tag, i| {
recipe.craftingTags[i] = tag;
}
list.append(recipe);
}

Expand All @@ -218,11 +222,16 @@ pub fn parseRecipe(zon: ZonElement, list: *main.ListManaged(Recipe)) !void {
return error.InvalidReversibleRecipe;
}

var defaultCraftingTags = arena.alloc(main.Tag, 1);
defaultCraftingTags[0] = main.Tag.handCraftable;
const foundCraftingTags = Tag.loadTagsFromZon(arena, zon.getChild("craftingTags"));
const craftingTags = if (foundCraftingTags.len != 0) foundCraftingTags else defaultCraftingTags;

const itemCombos = try generateItemCombos(arena, recipeItems);
for (itemCombos) |itemCombo| {
addRecipe(itemCombo, list);
addRecipe(itemCombo, list, craftingTags);
if (reversible) {
addRecipe(&.{itemCombo[1], itemCombo[0]}, list);
addRecipe(&.{itemCombo[1], itemCombo[0]}, list, craftingTags);
}
}
}
Expand Down
1 change: 1 addition & 0 deletions src/tag.zig
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ pub const Tag = enum(u32) {
fluidPlaceable = 3,
chiselable = 4,
playerModel = 5,
handCraftable = 6,
_,

pub fn initTags() void {
Expand Down
Loading