Unhardcode how chiselling is handled, given the opportunity for other rotation modes to do similar things.

Preparing for #798
This commit is contained in:
IntegratedQuantum 2024-11-25 17:42:44 +01:00
parent 1fffecb870
commit 0d50346fad
4 changed files with 26 additions and 33 deletions

View File

@ -1,5 +1,4 @@
.{ .{
.texture = "special/chisel.png", .texture = "special/chisel.png",
.stackSize = 1, .stackSize = 1,
.onLeftUse = .chisel,
} }

View File

@ -72,8 +72,6 @@ pub const BaseItem = struct { // MARK: BaseItem
block: ?u16, block: ?u16,
foodValue: f32, // TODO: Effects. foodValue: f32, // TODO: Effects.
leftClickUse: ?*const fn(world: *main.game.World, pos: Vec3i, relativePlayerPos: Vec3f, playerDir: Vec3f, currentData: *Block) bool,
var unobtainable = BaseItem { var unobtainable = BaseItem {
.image = graphics.Image.defaultImage, .image = graphics.Image.defaultImage,
.texture = null, .texture = null,
@ -83,7 +81,6 @@ pub const BaseItem = struct { // MARK: BaseItem
.material = null, .material = null,
.block = null, .block = null,
.foodValue = 0, .foodValue = 0,
.leftClickUse = null,
}; };
fn init(self: *BaseItem, allocator: NeverFailingAllocator, texturePath: []const u8, replacementTexturePath: []const u8, id: []const u8, zon: ZonElement) void { fn init(self: *BaseItem, allocator: NeverFailingAllocator, texturePath: []const u8, replacementTexturePath: []const u8, id: []const u8, zon: ZonElement) void {
@ -110,14 +107,6 @@ pub const BaseItem = struct { // MARK: BaseItem
}; };
self.texture = null; self.texture = null;
self.foodValue = zon.get(f32, "food", 0); self.foodValue = zon.get(f32, "food", 0);
self.leftClickUse = if(std.mem.eql(u8, zon.get([]const u8, "onLeftUse", ""), "chisel")) &chiselFunction else null; // TODO: Proper registry.
}
fn chiselFunction(world: *main.game.World, pos: Vec3i, relativePlayerPos: Vec3f, playerDir: Vec3f, currentData: *Block) bool {
if(currentData.mode() == main.rotation.getByID("stairs")) {
return main.rotation.RotationModes.Stairs.chisel(world, pos, relativePlayerPos, playerDir, currentData);
}
return false;
} }
fn hashCode(self: BaseItem) u32 { fn hashCode(self: BaseItem) u32 {

View File

@ -808,23 +808,14 @@ pub const MeshSelection = struct { // MARK: MeshSelection
pub fn breakBlock(inventoryStack: *main.items.ItemStack) void { pub fn breakBlock(inventoryStack: *main.items.ItemStack) void {
if(selectedBlockPos) |selectedPos| { if(selectedBlockPos) |selectedPos| {
var block = mesh_storage.getBlock(selectedPos[0], selectedPos[1], selectedPos[2]) orelse return; const block = mesh_storage.getBlock(selectedPos[0], selectedPos[1], selectedPos[2]) orelse return;
var newBlock = block;
// TODO: Breaking animation and tools. // TODO: Breaking animation and tools.
if(inventoryStack.item) |item| {
switch(item) {
.baseItem => |baseItem| {
if(baseItem.leftClickUse) |leftClick| {
const relPos: Vec3f = @floatCast(lastPos - @as(Vec3d, @floatFromInt(selectedPos))); const relPos: Vec3f = @floatCast(lastPos - @as(Vec3d, @floatFromInt(selectedPos)));
if(leftClick(main.game.world.?, selectedPos, relPos, lastDir, &block)) { block.mode().onBlockBreaking(inventoryStack.item, relPos, lastDir, &newBlock);
updateBlockAndSendUpdate(selectedPos[0], selectedPos[1], selectedPos[2], block); if(!std.meta.eql(newBlock, block)) {
updateBlockAndSendUpdate(selectedPos[0], selectedPos[1], selectedPos[2], newBlock);
} }
return;
}
},
else => {},
}
}
updateBlockAndSendUpdate(selectedPos[0], selectedPos[1], selectedPos[2], .{.typ = 0, .data = 0});
} }
} }

View File

@ -57,6 +57,9 @@ pub const RotationMode = struct { // MARK: RotationMode
} }
return null; return null;
} }
fn onBlockBreaking(_: ?main.items.Item, _: Vec3f, _: Vec3f, currentData: *Block) void {
currentData.* = .{.typ = 0, .data = 0};
}
}; };
/// if the block should be destroyed or changed when a certain neighbor is removed. /// if the block should be destroyed or changed when a certain neighbor is removed.
@ -74,6 +77,8 @@ pub const RotationMode = struct { // MARK: RotationMode
updateData: *const fn(block: *Block, neighbor: Neighbor, neighborBlock: Block) bool = &DefaultFunctions.updateData, updateData: *const fn(block: *Block, neighbor: Neighbor, neighborBlock: Block) bool = &DefaultFunctions.updateData,
rayIntersection: *const fn(block: Block, item: ?main.items.Item, relativePlayerPos: Vec3f, playerDir: Vec3f) ?RayIntersectionResult = &DefaultFunctions.rayIntersection, rayIntersection: *const fn(block: Block, item: ?main.items.Item, relativePlayerPos: Vec3f, playerDir: Vec3f) ?RayIntersectionResult = &DefaultFunctions.rayIntersection,
onBlockBreaking: *const fn(item: ?main.items.Item, relativePlayerPos: Vec3f, playerDir: Vec3f, currentData: *Block) void = &DefaultFunctions.onBlockBreaking,
}; };
var rotationModes: std.StringHashMap(RotationMode) = undefined; var rotationModes: std.StringHashMap(RotationMode) = undefined;
@ -538,13 +543,22 @@ pub const RotationModes = struct {
return RotationMode.DefaultFunctions.rayIntersection(block, item, relativePlayerPos, playerDir); return RotationMode.DefaultFunctions.rayIntersection(block, item, relativePlayerPos, playerDir);
} }
pub fn chisel(_: *main.game.World, _: Vec3i, relativePlayerPos: Vec3f, playerDir: Vec3f, currentData: *Block) bool { pub fn onBlockBreaking(item: ?main.items.Item, relativePlayerPos: Vec3f, playerDir: Vec3f, currentData: *Block) void {
if(item) |_item| {
switch(_item) {
.baseItem => |baseItem| {
if(std.mem.eql(u8, baseItem.id, "cubyz:chisel")) { // Break only one eigth of a block
if(intersectionPos(currentData.*, relativePlayerPos, playerDir)) |intersection| { if(intersectionPos(currentData.*, relativePlayerPos, playerDir)) |intersection| {
currentData.data = currentData.data | subBlockMask(intersection.minPos[0], intersection.minPos[1], intersection.minPos[2]); currentData.data = currentData.data | subBlockMask(intersection.minPos[0], intersection.minPos[1], intersection.minPos[2]);
if(currentData.data == 255) currentData.* = .{.typ = 0, .data = 0}; if(currentData.data == 255) currentData.* = .{.typ = 0, .data = 0};
return true; return;
} }
return false; }
},
else => {},
}
}
return RotationMode.DefaultFunctions.onBlockBreaking(item, relativePlayerPos, playerDir, currentData);
} }
}; };
pub const Torch = struct { // MARK: Torch pub const Torch = struct { // MARK: Torch