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",
.stackSize = 1,
.onLeftUse = .chisel,
}

View File

@ -72,8 +72,6 @@ pub const BaseItem = struct { // MARK: BaseItem
block: ?u16,
foodValue: f32, // TODO: Effects.
leftClickUse: ?*const fn(world: *main.game.World, pos: Vec3i, relativePlayerPos: Vec3f, playerDir: Vec3f, currentData: *Block) bool,
var unobtainable = BaseItem {
.image = graphics.Image.defaultImage,
.texture = null,
@ -83,7 +81,6 @@ pub const BaseItem = struct { // MARK: BaseItem
.material = null,
.block = null,
.foodValue = 0,
.leftClickUse = null,
};
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.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 {

View File

@ -808,23 +808,14 @@ pub const MeshSelection = struct { // MARK: MeshSelection
pub fn breakBlock(inventoryStack: *main.items.ItemStack) void {
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.
if(inventoryStack.item) |item| {
switch(item) {
.baseItem => |baseItem| {
if(baseItem.leftClickUse) |leftClick| {
const relPos: Vec3f = @floatCast(lastPos - @as(Vec3d, @floatFromInt(selectedPos)));
if(leftClick(main.game.world.?, selectedPos, relPos, lastDir, &block)) {
updateBlockAndSendUpdate(selectedPos[0], selectedPos[1], selectedPos[2], block);
block.mode().onBlockBreaking(inventoryStack.item, relPos, lastDir, &newBlock);
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;
}
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.
@ -74,6 +77,8 @@ pub const RotationMode = struct { // MARK: RotationMode
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,
onBlockBreaking: *const fn(item: ?main.items.Item, relativePlayerPos: Vec3f, playerDir: Vec3f, currentData: *Block) void = &DefaultFunctions.onBlockBreaking,
};
var rotationModes: std.StringHashMap(RotationMode) = undefined;
@ -538,13 +543,22 @@ pub const RotationModes = struct {
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| {
currentData.data = currentData.data | subBlockMask(intersection.minPos[0], intersection.minPos[1], intersection.minPos[2]);
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