Add BaseItemIndex struct (#1445)

* Add BaseItemIndex struct

* Please fix

* Update src/Inventory.zig

Co-authored-by: IntegratedQuantum <43880493+IntegratedQuantum@users.noreply.github.com>

* Sticks and stones may break my bones but pr will always need fixes

* Update src/assets.zig

* Replace break with return in Inventory.update

---------

Co-authored-by: IntegratedQuantum <43880493+IntegratedQuantum@users.noreply.github.com>
This commit is contained in:
Krzysztof Wiśniewski 2025-05-17 15:51:21 +02:00 committed by GitHub
parent f9a65a0681
commit 53d6cc70e9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
13 changed files with 120 additions and 83 deletions

View File

@ -14,6 +14,7 @@ const Vec3f = vec.Vec3f;
const Vec3i = vec.Vec3i;
const ZonElement = main.ZonElement;
const Neighbor = main.chunk.Neighbor;
const BaseItemIndex = main.items.BaseItemIndex;
const Gamemode = main.game.Gamemode;
@ -993,7 +994,7 @@ pub const Command = struct { // MARK: Command
fn canPutIntoWorkbench(source: InventoryAndSlot) bool {
if(source.ref().item) |item| {
if(item != .baseItem) return false;
return item.baseItem.material != null;
return item.baseItem.material() != null;
}
return true;
}
@ -1092,10 +1093,10 @@ pub const Command = struct { // MARK: Command
},
.recipe => |val| {
writer.writeInt(u16, val.resultAmount);
writer.writeWithDelimiter(val.resultItem.id, 0);
writer.writeWithDelimiter(val.resultItem.id(), 0);
for(0..val.sourceItems.len) |i| {
writer.writeInt(u16, val.sourceAmounts[i]);
writer.writeWithDelimiter(val.sourceItems[i].id, 0);
writer.writeWithDelimiter(val.sourceItems[i].id(), 0);
}
},
.blockInventory => |val| {
@ -1124,13 +1125,12 @@ pub const Command = struct { // MARK: Command
.hand => .{.hand = try reader.readInt(u32)},
.recipe => .{
.recipe = blk: {
var itemList = main.List(struct {amount: u16, item: *const main.items.BaseItem}).initCapacity(main.stackAllocator, len);
var itemList = main.List(struct {amount: u16, item: BaseItemIndex}).initCapacity(main.stackAllocator, len);
defer itemList.deinit();
while(reader.remaining.len >= 2) {
const resultAmount = try reader.readInt(u16);
const itemId = try reader.readUntilDelimiter(0);
const resultItem = main.items.getByID(itemId) orelse return error.Invalid;
itemList.append(.{.amount = resultAmount, .item = resultItem});
itemList.append(.{.amount = resultAmount, .item = BaseItemIndex.fromId(itemId) orelse return error.Invalid});
}
if(itemList.items.len != len) return error.Invalid;
// Find the recipe in our list:
@ -1864,30 +1864,29 @@ fn update(self: Inventory) void {
if(self.type == .workbench) {
self._items[self._items.len - 1].deinit();
self._items[self._items.len - 1].clear();
var availableItems: [25]?*const BaseItem = undefined;
var hasAllMandatory: bool = true;
var availableItems: [25]?BaseItemIndex = undefined;
const slotInfos = self.type.workbench.slotInfos;
for(0..25) |i| {
if(self._items[i].item != null and self._items[i].item.? == .baseItem) {
availableItems[i] = self._items[i].item.?.baseItem;
} else {
if(!self.type.workbench.slotInfos[i].optional and !self.type.workbench.slotInfos[i].disabled)
hasAllMandatory = false;
if(!slotInfos[i].optional and !slotInfos[i].disabled) {
return;
}
availableItems[i] = null;
}
}
if(hasAllMandatory) {
var hash = std.hash.Crc32.init();
for(availableItems) |item| {
if(item != null) {
hash.update(item.?.id);
} else {
hash.update("none");
}
var hash = std.hash.Crc32.init();
for(availableItems) |item| {
if(item != null) {
hash.update(item.?.id());
} else {
hash.update("none");
}
self._items[self._items.len - 1].item = Item{.tool = Tool.initFromCraftingGrid(availableItems, hash.final(), self.type.workbench)};
self._items[self._items.len - 1].amount = 1;
}
self._items[self._items.len - 1].item = Item{.tool = Tool.initFromCraftingGrid(availableItems, hash.final(), self.type.workbench)};
self._items[self._items.len - 1].amount = 1;
}
}

View File

@ -340,7 +340,9 @@ fn registerBlock(assetFolder: []const u8, id: []const u8, zon: ZonElement) !void
fn assignBlockItem(stringId: []const u8) !void {
const block = blocks_zig.getTypeById(stringId);
const item = items_zig.getByID(stringId) orelse unreachable;
// TODO: This must be gone in PixelGuys/Cubyz#1205
const index = (items_zig.BaseItemIndex.fromId(stringId) orelse unreachable).index;
const item = &items_zig.itemList[index];
item.block = block;
}

View File

@ -175,7 +175,7 @@ fn registerBlockDrop(typ: u16, zon: ZonElement) void {
name = _id[typ];
}
const item = items.getByID(name) orelse continue;
const item = items.BaseItemIndex.fromId(name) orelse continue;
resultItems.append(.{.item = .{.baseItem = item}, .amount = amount});
}

View File

@ -605,8 +605,9 @@ pub const Player = struct { // MARK: Player
const block = main.renderer.mesh_storage.getBlock(selectedPos[0], selectedPos[1], selectedPos[2]) orelse return;
const item: items.Item = for(0..items.itemListSize) |idx| {
if(items.itemList[idx].block == block.typ) {
break .{.baseItem = &items.itemList[idx]};
const baseItem: main.items.BaseItemIndex = .{.index = @intCast(idx)};
if(baseItem.block() == block.typ) {
break .{.baseItem = baseItem};
}
} else return;

View File

@ -28,11 +28,11 @@ var inventory: Inventory = undefined;
fn lessThan(_: void, lhs: Item, rhs: Item) bool {
if(lhs == .baseItem and rhs == .baseItem) {
const lhsFolders = std.mem.count(u8, lhs.baseItem.id, "/");
const rhsFolders = std.mem.count(u8, rhs.baseItem.id, "/");
const lhsFolders = std.mem.count(u8, lhs.baseItem.id(), "/");
const rhsFolders = std.mem.count(u8, rhs.baseItem.id(), "/");
if(lhsFolders < rhsFolders) return true;
if(lhsFolders > rhsFolders) return false;
return std.ascii.lessThanIgnoreCase(lhs.baseItem.id, rhs.baseItem.id);
return std.ascii.lessThanIgnoreCase(lhs.baseItem.id(), rhs.baseItem.id());
} else {
if(lhs == .baseItem) return true;
return false;

View File

@ -2,7 +2,7 @@ const std = @import("std");
const main = @import("main");
const items = main.items;
const BaseItem = items.BaseItem;
const BaseItemIndex = items.BaseItemIndex;
const Inventory = items.Inventory;
const ItemStack = items.ItemStack;
const Player = main.game.Player;
@ -31,7 +31,7 @@ pub var window = GuiWindow{
const padding: f32 = 8;
var availableItems: main.List(*BaseItem) = undefined;
var availableItems: main.List(BaseItemIndex) = undefined;
var itemAmount: main.List(u32) = undefined;
var inventories: main.List(Inventory) = undefined;

View File

@ -583,9 +583,9 @@ pub const ItemDropRenderer = struct { // MARK: ItemDropRenderer
self.* = ItemVoxelModel{
.item = template.item,
};
if(self.item == .baseItem and self.item.baseItem.block != null and self.item.baseItem.image.imageData.ptr == graphics.Image.defaultImage.imageData.ptr) {
if(self.item == .baseItem and self.item.baseItem.block() != null and self.item.baseItem.image().imageData.ptr == graphics.Image.defaultImage.imageData.ptr) {
// Find sizes and free index:
var block = blocks.Block{.typ = self.item.baseItem.block.?, .data = 0};
var block = blocks.Block{.typ = self.item.baseItem.block().?, .data = 0};
block.data = block.mode().naturalStandard;
const model = blocks.meshes.model(block).model();
var data = main.List(u32).init(main.stackAllocator);
@ -732,8 +732,8 @@ pub const ItemDropRenderer = struct { // MARK: ItemDropRenderer
var scale: f32 = 0.3;
var blockType: u16 = 0;
if(item == .baseItem and item.baseItem.block != null and item.baseItem.image.imageData.ptr == graphics.Image.defaultImage.imageData.ptr) {
blockType = item.baseItem.block.?;
if(item == .baseItem and item.baseItem.block() != null and item.baseItem.image().imageData.ptr == graphics.Image.defaultImage.imageData.ptr) {
blockType = item.baseItem.block().?;
vertices = model.len/2*6;
} else {
scale = 0.5;
@ -817,11 +817,11 @@ pub const ItemDropRenderer = struct { // MARK: ItemDropRenderer
const model = getModel(item);
var vertices: u31 = 36;
const isBlock: bool = item == .baseItem and item.baseItem.block != null and item.baseItem.image.imageData.ptr == graphics.Image.defaultImage.imageData.ptr;
const isBlock: bool = item == .baseItem and item.baseItem.block() != null and item.baseItem.image().imageData.ptr == graphics.Image.defaultImage.imageData.ptr;
var scale: f32 = 0;
var blockType: u16 = 0;
if(isBlock) {
blockType = item.baseItem.block.?;
blockType = item.baseItem.block().?;
vertices = model.len/2*6;
scale = 0.3;
pos = Vec3d{0.4, 0.55, -0.32};

View File

@ -156,6 +156,50 @@ const MaterialProperty = enum {
}
};
pub const BaseItemIndex = packed struct {
index: u16,
pub fn fromId(_id: []const u8) ?BaseItemIndex {
return reverseIndices.get(_id);
}
pub fn image(self: BaseItemIndex) graphics.Image {
return itemList[self.index].image;
}
pub fn texture(self: BaseItemIndex) ?graphics.Texture {
return itemList[self.index].texture;
}
pub fn id(self: BaseItemIndex) []const u8 {
return itemList[self.index].id;
}
pub fn name(self: BaseItemIndex) []const u8 {
return itemList[self.index].name;
}
pub fn tags(self: BaseItemIndex) []const Tag {
return itemList[self.index].tags;
}
pub fn stackSize(self: BaseItemIndex) u16 {
return itemList[self.index].stackSize;
}
pub fn material(self: BaseItemIndex) ?Material {
return itemList[self.index].material;
}
pub fn block(self: BaseItemIndex) ?u16 {
return itemList[self.index].block;
}
pub fn hasTag(self: BaseItemIndex, tag: Tag) bool {
return itemList[self.index].hasTag(tag);
}
pub fn hashCode(self: BaseItemIndex) u32 {
return itemList[self.index].hashCode();
}
pub fn getTexture(self: BaseItemIndex) graphics.Texture {
return itemList[self.index].getTexture();
}
pub fn getTooltip(self: BaseItemIndex) []const u8 {
return itemList[self.index].getTooltip();
}
};
pub const BaseItem = struct { // MARK: BaseItem
image: graphics.Image,
texture: ?graphics.Texture, // TODO: Properly deinit
@ -245,7 +289,7 @@ pub const BaseItem = struct { // MARK: BaseItem
///Generates the texture of a Tool using the material information.
const TextureGenerator = struct { // MARK: TextureGenerator
fn generateHeightMap(itemGrid: *[16][16]?*const BaseItem, seed: *u64) [17][17]f32 {
fn generateHeightMap(itemGrid: *[16][16]?BaseItemIndex, seed: *u64) [17][17]f32 {
var heightMap: [17][17]f32 = undefined;
var x: u8 = 0;
while(x < 17) : (x += 1) {
@ -263,7 +307,7 @@ const TextureGenerator = struct { // MARK: TextureGenerator
while(dy <= 0) : (dy += 1) {
if(y + dy < 0 or y + dy >= 16) continue;
const otherItem = itemGrid[@intCast(x + dx)][@intCast(y + dy)];
heightMap[x][y] = if(otherItem) |item| (if(item.material) |material| 1 + (4*random.nextFloat(seed) - 2)*material.textureRoughness else 0) else 0;
heightMap[x][y] = if(otherItem) |item| (if(item.material()) |material| 1 + (4*random.nextFloat(seed) - 2)*material.textureRoughness else 0) else 0;
if(otherItem != oneItem) {
hasDifferentItems = true;
}
@ -318,7 +362,7 @@ const TextureGenerator = struct { // MARK: TextureGenerator
var y: u8 = 0;
while(y < 16) : (y += 1) {
if(tool.materialGrid[x][y]) |item| {
if(item.material) |material| {
if(item.material()) |material| {
// Calculate the lighting based on the nearest free space:
const lightTL = heightMap[x][y] - heightMap[x + 1][y + 1];
const lightTR = heightMap[x + 1][y] - heightMap[x][y + 1];
@ -349,7 +393,7 @@ const ToolPhysics = struct { // MARK: ToolPhysics
var sum: f32 = 0;
var weight: f32 = 0;
for(0..25) |i| {
const material = (tool.craftingGrid[i] orelse continue).material orelse continue;
const material = (tool.craftingGrid[i] orelse continue).material() orelse continue;
sum += property.weigths[i]*material.getProperty(property.source orelse break);
weight += property.weigths[i];
}
@ -361,7 +405,7 @@ const ToolPhysics = struct { // MARK: ToolPhysics
if(tool.damage < 1) tool.damage = 1/(2 - tool.damage);
if(tool.swingTime < 1) tool.swingTime = 1/(2 - tool.swingTime);
for(0..25) |i| {
const material = (tool.craftingGrid[i] orelse continue).material orelse continue;
const material = (tool.craftingGrid[i] orelse continue).material() orelse continue;
outer: for(material.modifiers) |newMod| {
if(!newMod.restriction.satisfied(tool, @intCast(i%5), @intCast(i/5))) continue;
for(tempModifiers.items) |*oldMod| {
@ -424,8 +468,8 @@ const ToolProperty = enum {
};
pub const Tool = struct { // MARK: Tool
craftingGrid: [25]?*const BaseItem,
materialGrid: [16][16]?*const BaseItem,
craftingGrid: [25]?BaseItemIndex,
materialGrid: [16][16]?BaseItemIndex,
modifiers: []Modifier,
tooltip: main.List(u8),
image: graphics.Image,
@ -497,7 +541,7 @@ pub const Tool = struct { // MARK: Tool
return result;
}
pub fn initFromCraftingGrid(craftingGrid: [25]?*const BaseItem, seed: u32, typ: *const ToolType) *Tool {
pub fn initFromCraftingGrid(craftingGrid: [25]?BaseItemIndex, seed: u32, typ: *const ToolType) *Tool {
const self = init();
self.seed = seed;
self.craftingGrid = craftingGrid;
@ -518,11 +562,11 @@ pub const Tool = struct { // MARK: Tool
return self;
}
fn extractItemsFromZon(zonArray: ZonElement) [25]?*const BaseItem {
var items: [25]?*const BaseItem = undefined;
fn extractItemsFromZon(zonArray: ZonElement) [25]?BaseItemIndex {
var items: [25]?BaseItemIndex = undefined;
for(&items, 0..) |*item, i| {
item.* = reverseIndices.get(zonArray.getAtIndex([]const u8, i, "null"));
if(item.* != null and item.*.?.material == null) item.* = null;
item.* = .fromId(zonArray.getAtIndex([]const u8, i, "null"));
if(item.* != null and item.*.?.material() == null) item.* = null;
}
return items;
}
@ -530,9 +574,9 @@ pub const Tool = struct { // MARK: Tool
pub fn save(self: *const Tool, allocator: NeverFailingAllocator) ZonElement {
const zonObject = ZonElement.initObject(allocator);
const zonArray = ZonElement.initArray(allocator);
for(self.craftingGrid) |nullItem| {
if(nullItem) |item| {
zonArray.array.append(.{.string = item.id});
for(self.craftingGrid) |nullableItem| {
if(nullableItem) |item| {
zonArray.array.append(.{.string = item.id()});
} else {
zonArray.array.append(.null);
}
@ -548,13 +592,13 @@ pub const Tool = struct { // MARK: Tool
var hash: u32 = 0;
for(self.craftingGrid) |nullItem| {
if(nullItem) |item| {
hash = 33*%hash +% item.material.?.hashCode();
hash = 33*%hash +% item.material().?.hashCode();
}
}
return hash;
}
pub fn getItemAt(self: *const Tool, x: i32, y: i32) ?*const BaseItem {
pub fn getItemAt(self: *const Tool, x: i32, y: i32) ?BaseItemIndex {
if(x < 0 or x >= 5) return null;
if(y < 0 or y >= 5) return null;
return self.craftingGrid[@intCast(x + y*5)];
@ -619,11 +663,11 @@ pub const Tool = struct { // MARK: Tool
};
pub const Item = union(enum) { // MARK: Item
baseItem: *BaseItem,
baseItem: BaseItemIndex,
tool: *Tool,
pub fn init(zon: ZonElement) !Item {
if(reverseIndices.get(zon.get([]const u8, "item", "null"))) |baseItem| {
if(BaseItemIndex.fromId(zon.get([]const u8, "item", "null"))) |baseItem| {
return Item{.baseItem = baseItem};
} else {
const toolZon = zon.getChild("tool");
@ -653,7 +697,7 @@ pub const Item = union(enum) { // MARK: Item
pub fn stackSize(self: Item) u16 {
switch(self) {
.baseItem => |_baseItem| {
return _baseItem.stackSize;
return _baseItem.stackSize();
},
.tool => {
return 1;
@ -664,7 +708,7 @@ pub const Item = union(enum) { // MARK: Item
pub fn insertIntoZon(self: Item, allocator: NeverFailingAllocator, zonObject: ZonElement) void {
switch(self) {
.baseItem => |_baseItem| {
zonObject.put("item", _baseItem.id);
zonObject.put("item", _baseItem.id());
},
.tool => |_tool| {
zonObject.put("tool", _tool.save(allocator));
@ -697,7 +741,7 @@ pub const Item = union(enum) { // MARK: Item
pub fn getImage(self: Item) graphics.Image {
switch(self) {
.baseItem => |_baseItem| {
return _baseItem.image;
return _baseItem.image();
},
.tool => |_tool| {
return _tool.image;
@ -763,16 +807,16 @@ pub const ItemStack = struct { // MARK: ItemStack
};
pub const Recipe = struct { // MARK: Recipe
sourceItems: []*BaseItem,
sourceItems: []BaseItemIndex,
sourceAmounts: []u16,
resultItem: *BaseItem,
resultItem: BaseItemIndex,
resultAmount: u16,
cachedInventory: ?Inventory = null,
};
var arena: main.heap.NeverFailingArenaAllocator = undefined;
var toolTypes: std.StringHashMap(ToolType) = undefined;
var reverseIndices: std.StringHashMap(*BaseItem) = undefined;
var reverseIndices: std.StringHashMap(BaseItemIndex) = undefined;
var modifiers: std.StringHashMap(*const Modifier.VTable) = undefined;
var modifierRestrictions: std.StringHashMap(*const ModifierRestriction.VTable) = undefined;
pub var itemList: [65536]BaseItem = undefined;
@ -788,7 +832,7 @@ pub fn toolTypeIterator() std.StringHashMap(ToolType).ValueIterator {
return toolTypes.valueIterator();
}
pub fn iterator() std.StringHashMap(*BaseItem).ValueIterator {
pub fn iterator() std.StringHashMap(BaseItemIndex).ValueIterator {
return reverseIndices.valueIterator();
}
@ -833,7 +877,7 @@ pub fn register(_: []const u8, texturePath: []const u8, replacementTexturePath:
defer itemListSize += 1;
newItem.init(arena.allocator(), texturePath, replacementTexturePath, id, zon);
reverseIndices.put(newItem.id, newItem) catch unreachable;
reverseIndices.put(newItem.id, .{.index = itemListSize}) catch unreachable;
std.log.debug("Registered item: {d: >5} '{s}'", .{itemListSize, id});
return newItem;
@ -930,7 +974,7 @@ fn parseRecipeItem(zon: ZonElement) !ItemStack {
id = id[index + 1 ..];
id = std.mem.trim(u8, id, &std.ascii.whitespace);
}
result.item = .{.baseItem = getByID(id) orelse return error.ItemNotFound};
result.item = .{.baseItem = BaseItemIndex.fromId(id) orelse return error.ItemNotFound};
return result;
}
@ -938,7 +982,7 @@ 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),
.sourceItems = arena.allocator().alloc(BaseItemIndex, inputs.len),
.sourceAmounts = arena.allocator().alloc(u16, inputs.len),
.resultItem = output.item.?.baseItem,
.resultAmount = output.amount,
@ -990,15 +1034,6 @@ pub fn deinit() void {
Inventory.Sync.ClientSide.deinit();
}
pub fn getByID(id: []const u8) ?*BaseItem {
if(reverseIndices.get(id)) |result| {
return result;
} else {
std.log.err("Couldn't find item {s}.", .{id});
return null;
}
}
pub fn getToolTypeByID(id: []const u8) ?*const ToolType {
if(toolTypes.getPtr(id)) |result| {
return result;

View File

@ -958,7 +958,7 @@ pub const MeshSelection = struct { // MARK: MeshSelection
if(inventory.getItem(slot)) |item| {
switch(item) {
.baseItem => |baseItem| {
if(baseItem.block) |itemBlock| {
if(baseItem.block()) |itemBlock| {
const rotationMode = blocks.Block.mode(.{.typ = itemBlock, .data = 0});
var neighborDir = Vec3i{0, 0, 0};
// Check if stuff can be added to the block itself:
@ -1000,7 +1000,7 @@ pub const MeshSelection = struct { // MARK: MeshSelection
}
}
}
if(std.mem.eql(u8, baseItem.id, "cubyz:selection_wand")) {
if(std.mem.eql(u8, baseItem.id(), "cubyz:selection_wand")) {
game.Player.selectionPosition2 = selectedPos;
main.network.Protocols.genericUpdate.sendWorldEditPos(main.game.world.?.conn, .selectedPos2, selectedPos);
return;
@ -1017,7 +1017,7 @@ pub const MeshSelection = struct { // MARK: MeshSelection
pub fn breakBlock(inventory: main.items.Inventory, slot: u32, deltaTime: f64) void {
if(selectedBlockPos) |selectedPos| {
const stack = inventory.getStack(slot);
const isSelectionWand = stack.item != null and stack.item.? == .baseItem and std.mem.eql(u8, stack.item.?.baseItem.id, "cubyz:selection_wand");
const isSelectionWand = stack.item != null and stack.item.? == .baseItem and std.mem.eql(u8, stack.item.?.baseItem.id(), "cubyz:selection_wand");
if(isSelectionWand) {
game.Player.selectionPosition1 = selectedPos;
main.network.Protocols.genericUpdate.sendWorldEditPos(main.game.world.?.conn, .selectedPos1, selectedPos);
@ -1041,7 +1041,7 @@ pub const MeshSelection = struct { // MARK: MeshSelection
if(isTool) {
damage = stack.item.?.tool.getBlockDamage(block);
}
const isChisel = stack.item != null and stack.item.? == .baseItem and std.mem.eql(u8, stack.item.?.baseItem.id, "cubyz:chisel");
const isChisel = stack.item != null and stack.item.? == .baseItem and std.mem.eql(u8, stack.item.?.baseItem.id(), "cubyz:chisel");
if(isChisel and block.mode() == main.rotation.getByID("stairs")) { // TODO: Remove once the chisel is a tool.
damage = block.blockHealth();
}

View File

@ -113,7 +113,7 @@ pub const RotationMode = struct { // MARK: RotationMode
} else {
if(item.item) |_item| {
if(_item == .baseItem) {
if(_item.baseItem.block != null and _item.baseItem.block.? == newBlock.typ) {
if(_item.baseItem.block() != null and _item.baseItem.block().? == newBlock.typ) {
return .{.yes_costsItems = 1};
}
}

View File

@ -276,7 +276,7 @@ pub fn rayIntersection(block: Block, item: ?main.items.Item, relativePlayerPos:
if(item) |_item| {
switch(_item) {
.baseItem => |baseItem| {
if(std.mem.eql(u8, baseItem.id, "cubyz:chisel")) { // Select only one eighth of a block
if(std.mem.eql(u8, baseItem.id(), "cubyz:chisel")) { // Select only one eighth of a block
return closestRay(.intersection, block, relativePlayerPos, playerDir);
}
},
@ -290,7 +290,7 @@ pub fn onBlockBreaking(item: ?main.items.Item, relativePlayerPos: Vec3f, playerD
if(item) |_item| {
switch(_item) {
.baseItem => |baseItem| {
if(std.mem.eql(u8, baseItem.id, "cubyz:chisel")) { // Break only one eigth of a block
if(std.mem.eql(u8, baseItem.id(), "cubyz:chisel")) { // Break only one eigth of a block
currentData.data |= closestRay(.bit, currentData.*, relativePlayerPos, playerDir);
if(currentData.data == 255) currentData.* = .{.typ = 0, .data = 0};
return;
@ -305,7 +305,7 @@ pub fn onBlockBreaking(item: ?main.items.Item, relativePlayerPos: Vec3f, playerD
pub fn canBeChangedInto(oldBlock: Block, newBlock: Block, item: main.items.ItemStack, shouldDropSourceBlockOnSuccess: *bool) RotationMode.CanBeChangedInto {
if(oldBlock.typ != newBlock.typ) return RotationMode.DefaultFunctions.canBeChangedInto(oldBlock, newBlock, item, shouldDropSourceBlockOnSuccess);
if(oldBlock.data == newBlock.data) return .no;
if(item.item != null and item.item.? == .baseItem and std.mem.eql(u8, item.item.?.baseItem.id, "cubyz:chisel")) {
if(item.item != null and item.item.? == .baseItem and std.mem.eql(u8, item.item.?.baseItem.id(), "cubyz:chisel")) {
return .yes; // TODO: Durability change, after making the chisel a proper tool.
}
return .no;

View File

@ -78,7 +78,7 @@ pub fn onBlockBreaking(_: ?main.items.Item, _: Vec3f, _: Vec3f, currentData: *Bl
}
fn isItemBlock(block: Block, item: main.items.ItemStack) bool {
return item.item != null and item.item.? == .baseItem and item.item.?.baseItem.block == block.typ;
return item.item != null and item.item.? == .baseItem and item.item.?.baseItem.block() == block.typ;
}
pub fn canBeChangedInto(oldBlock: Block, newBlock: Block, item: main.items.ItemStack, shouldDropSourceBlockOnSuccess: *bool) RotationMode.CanBeChangedInto {

View File

@ -203,7 +203,7 @@ pub fn canBeChangedInto(oldBlock: Block, newBlock: Block, item: main.items.ItemS
if(torchAmountChange <= 0) {
return .{.yes_dropsItems = @intCast(-torchAmountChange)};
} else {
if(item.item == null or item.item.? != .baseItem or !std.meta.eql(item.item.?.baseItem.block, newBlock.typ)) return .no;
if(item.item == null or item.item.? != .baseItem or !std.meta.eql(item.item.?.baseItem.block(), newBlock.typ)) return .no;
return .{.yes_costsItems = @intCast(torchAmountChange)};
}
},