Skip to content

Commit

Permalink
Fix discrepancy between client-side and server-side torch placement.
Browse files Browse the repository at this point in the history
fixes #993
  • Loading branch information
IntegratedQuantum committed Feb 2, 2025
1 parent 9be4ff1 commit f8a8d19
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 55 deletions.
11 changes: 8 additions & 3 deletions src/renderer.zig
Original file line number Diff line number Diff line change
Expand Up @@ -704,6 +704,7 @@ pub const MeshSelection = struct { // MARK: MeshSelection
}

var posBeforeBlock: Vec3i = undefined;
var neighborOfSelection: chunk.Neighbor = undefined;
pub var selectedBlockPos: ?Vec3i = null;
var lastSelectedBlockPos: Vec3i = undefined;
var currentBlockProgress: f32 = 0;
Expand Down Expand Up @@ -752,20 +753,24 @@ pub const MeshSelection = struct { // MARK: MeshSelection
voxelPos[0] +%= step[0];
total_tMax = tMax[0];
tMax[0] += tDelta[0];
neighborOfSelection = if(step[0] == 1) .dirPosX else .dirNegX;
} else {
voxelPos[2] +%= step[2];
total_tMax = tMax[2];
tMax[2] += tDelta[2];
neighborOfSelection = if(step[2] == 1) .dirUp else .dirDown;
}
} else {
if(tMax[1] < tMax[2]) {
voxelPos[1] +%= step[1];
total_tMax = tMax[1];
tMax[1] += tDelta[1];
neighborOfSelection = if(step[1] == 1) .dirPosY else .dirNegY;
} else {
voxelPos[2] +%= step[2];
total_tMax = tMax[2];
tMax[2] += tDelta[2];
neighborOfSelection = if(step[2] == 1) .dirUp else .dirDown;
}
}
}
Expand All @@ -792,7 +797,7 @@ pub const MeshSelection = struct { // MARK: MeshSelection
// Check if stuff can be added to the block itself:
if(itemBlock == block.typ) {
const relPos: Vec3f = @floatCast(lastPos - @as(Vec3d, @floatFromInt(selectedPos)));
if(rotationMode.generateData(main.game.world.?, selectedPos, relPos, lastDir, neighborDir, &block, .{.typ = 0, .data = 0}, false)) {
if(rotationMode.generateData(main.game.world.?, selectedPos, relPos, lastDir, neighborDir, null, &block, .{.typ = 0, .data = 0}, false)) {
if(!canPlaceBlock(selectedPos, block)) return;
updateBlockAndSendUpdate(inventory, slot, selectedPos[0], selectedPos[1], selectedPos[2], oldBlock, block);
return;
Expand All @@ -806,7 +811,7 @@ pub const MeshSelection = struct { // MARK: MeshSelection
oldBlock = mesh_storage.getBlock(neighborPos[0], neighborPos[1], neighborPos[2]) orelse return;
block = oldBlock;
if(block.typ == itemBlock) {
if(rotationMode.generateData(main.game.world.?, neighborPos, relPos, lastDir, neighborDir, &block, neighborBlock, false)) {
if(rotationMode.generateData(main.game.world.?, neighborPos, relPos, lastDir, neighborDir, neighborOfSelection, &block, neighborBlock, false)) {
if(!canPlaceBlock(neighborPos, block)) return;
updateBlockAndSendUpdate(inventory, slot, neighborPos[0], neighborPos[1], neighborPos[2], oldBlock, block);
return;
Expand All @@ -815,7 +820,7 @@ pub const MeshSelection = struct { // MARK: MeshSelection
if(block.solid()) return;
block.typ = itemBlock;
block.data = 0;
if(rotationMode.generateData(main.game.world.?, neighborPos, relPos, lastDir, neighborDir, &block, neighborBlock, true)) {
if(rotationMode.generateData(main.game.world.?, neighborPos, relPos, lastDir, neighborDir, neighborOfSelection, &block, neighborBlock, true)) {
if(!canPlaceBlock(neighborPos, block)) return;
updateBlockAndSendUpdate(inventory, slot, neighborPos[0], neighborPos[1], neighborPos[2], oldBlock, block);
return;
Expand Down
70 changes: 18 additions & 52 deletions src/rotation.zig
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ pub const RotationMode = struct { // MARK: RotationMode
fn model(block: Block) u16 {
return blocks.meshes.modelIndexStart(block);
}
fn generateData(_: *main.game.World, _: Vec3i, _: Vec3f, _: Vec3f, _: Vec3i, _: *Block, _: Block, blockPlacing: bool) bool {
fn generateData(_: *main.game.World, _: Vec3i, _: Vec3f, _: Vec3f, _: Vec3i, _: ?Neighbor, _: *Block, _: Block, blockPlacing: bool) bool {
return blockPlacing;
}
fn createBlockModel(modelId: []const u8) u16 {
Expand Down Expand Up @@ -110,7 +110,7 @@ pub const RotationMode = struct { // MARK: RotationMode

/// Updates the block data of a block in the world or places a block in the world.
/// return true if the placing was successful, false otherwise.
generateData: *const fn(world: *main.game.World, pos: Vec3i, relativePlayerPos: Vec3f, playerDir: Vec3f, relativeDir: Vec3i, currentData: *Block, neighborBlock: Block, blockPlacing: bool) bool = DefaultFunctions.generateData,
generateData: *const fn(world: *main.game.World, pos: Vec3i, relativePlayerPos: Vec3f, playerDir: Vec3f, relativeDir: Vec3i, neighbor: ?Neighbor, currentData: *Block, neighborBlock: Block, blockPlacing: bool) bool = DefaultFunctions.generateData,

/// Updates data of a placed block if the RotationMode dependsOnNeighbors.
updateData: *const fn(block: *Block, neighbor: Neighbor, neighborBlock: Block) bool = &DefaultFunctions.updateData,
Expand Down Expand Up @@ -169,14 +169,9 @@ pub const RotationModes = struct {
return blocks.meshes.modelIndexStart(block) + @min(block.data, 5);
}

pub fn generateData(_: *main.game.World, _: Vec3i, _: Vec3f, _: Vec3f, relativeDir: Vec3i, currentData: *Block, _: Block, blockPlacing: bool) bool {
pub fn generateData(_: *main.game.World, _: Vec3i, _: Vec3f, _: Vec3f, _: Vec3i, neighbor: ?Neighbor, currentData: *Block, _: Block, blockPlacing: bool) bool {
if(blockPlacing) {
if(relativeDir[0] == 1) currentData.data = Neighbor.dirNegX.toInt();
if(relativeDir[0] == -1) currentData.data = Neighbor.dirPosX.toInt();
if(relativeDir[1] == 1) currentData.data = Neighbor.dirNegY.toInt();
if(relativeDir[1] == -1) currentData.data = Neighbor.dirPosY.toInt();
if(relativeDir[2] == 1) currentData.data = Neighbor.dirDown.toInt();
if(relativeDir[2] == -1) currentData.data = Neighbor.dirUp.toInt();
currentData.data = neighbor.?.reverse().toInt();
return true;
}
return false;
Expand Down Expand Up @@ -212,7 +207,7 @@ pub const RotationModes = struct {
return blocks.meshes.modelIndexStart(block) + @min(block.data, 3);
}

pub fn generateData(_: *main.game.World, _: Vec3i, _: Vec3f, playerDir: Vec3f, _: Vec3i, currentData: *Block, _: Block, blockPlacing: bool) bool {
pub fn generateData(_: *main.game.World, _: Vec3i, _: Vec3f, playerDir: Vec3f, _: Vec3i, _: ?Neighbor, currentData: *Block, _: Block, blockPlacing: bool) bool {
if(blockPlacing) {
if(@abs(playerDir[0]) > @abs(playerDir[1])) {
if(playerDir[0] < 0) currentData.data = Neighbor.dirNegX.toInt() - 2
Expand Down Expand Up @@ -523,7 +518,7 @@ pub const RotationModes = struct {
return blocks.meshes.modelIndexStart(block) + (block.data & 255);
}

pub fn generateData(_: *main.game.World, _: Vec3i, _: Vec3f, _: Vec3f, _: Vec3i, currentData: *Block, _: Block, blockPlacing: bool) bool {
pub fn generateData(_: *main.game.World, _: Vec3i, _: Vec3f, _: Vec3f, _: Vec3i, _: ?Neighbor, currentData: *Block, _: Block, blockPlacing: bool) bool {
if(blockPlacing) {
currentData.data = 0;
return true;
Expand Down Expand Up @@ -694,7 +689,11 @@ pub const RotationModes = struct {
return blocks.meshes.modelIndexStart(block) + (@as(u5, @truncate(block.data)) -| 1);
}

pub fn generateData(_: *main.game.World, _: Vec3i, _: Vec3f, _: Vec3f, relativeDir: Vec3i, currentData: *Block, _: Block, _: bool) bool {
pub fn generateData(_: *main.game.World, _: Vec3i, _: Vec3f, _: Vec3f, relativeDir: Vec3i, neighbor: ?Neighbor, currentData: *Block, neighborBlock: Block, _: bool) bool {
if(neighbor == null) return false;
const neighborModel = blocks.meshes.model(neighborBlock);
const neighborSupport = neighborBlock.solid() and main.models.models.items[neighborModel].neighborFacingQuads[neighbor.?.reverse().toInt()].len != 0;
if(!neighborSupport) return false;
var data: TorchData = @bitCast(@as(u5, @truncate(currentData.data)));
if(relativeDir[0] == 1) data.posX = true;
if(relativeDir[0] == -1) data.negX = true;
Expand All @@ -710,25 +709,24 @@ pub const RotationModes = struct {
}

pub fn updateData(block: *Block, neighbor: Neighbor, neighborBlock: Block) bool {
const blockModel = blocks.meshes.modelIndexStart(block.*);
const neighborModel = blocks.meshes.model(neighborBlock);
const targetVal = neighborBlock.solid() and (blockModel == neighborModel or main.models.models.items[neighborModel].neighborFacingQuads[neighbor.reverse().toInt()].len != 0);
const neighborSupport = neighborBlock.solid() and main.models.models.items[neighborModel].neighborFacingQuads[neighbor.reverse().toInt()].len != 0;
var currentData: TorchData = @bitCast(@as(u5, @truncate(block.data)));
switch(neighbor) {
.dirNegX => {
currentData.negX = currentData.negX and targetVal;
currentData.negX = currentData.negX and neighborSupport;
},
.dirPosX => {
currentData.posX = currentData.posX and targetVal;
currentData.posX = currentData.posX and neighborSupport;
},
.dirNegY => {
currentData.negY = currentData.negY and targetVal;
currentData.negY = currentData.negY and neighborSupport;
},
.dirPosY => {
currentData.posY = currentData.posY and targetVal;
currentData.posY = currentData.posY and neighborSupport;
},
.dirDown => {
currentData.center = currentData.center and targetVal;
currentData.center = currentData.center and neighborSupport;
},
else => {},
}
Expand Down Expand Up @@ -863,7 +861,7 @@ pub const RotationModes = struct {
return blocks.meshes.modelIndexStart(block) + (@as(u6, @truncate(block.data)) -| 1);
}

pub fn generateData(_: *main.game.World, _: Vec3i, relativePlayerPos: Vec3f, playerDir: Vec3f, relativeDir: Vec3i, currentData: *Block, neighbor: Block, _: bool) bool {
pub fn generateData(_: *main.game.World, _: Vec3i, relativePlayerPos: Vec3f, playerDir: Vec3f, relativeDir: Vec3i, _: ?Neighbor, currentData: *Block, neighbor: Block, _: bool) bool {
if(neighbor.mode() == currentData.mode()) parallelPlacing: {
const bit = closestRay(.bit, neighbor, null, relativePlayerPos - @as(Vec3f, @floatFromInt(relativeDir)), playerDir);
const bitData: CarpetData = @bitCast(@as(u6, @truncate(bit)));
Expand All @@ -889,38 +887,6 @@ pub const RotationModes = struct {
}
}

pub fn updateData(block: *Block, neighbor: Neighbor, neighborBlock: Block) bool {
const blockModel = blocks.meshes.modelIndexStart(block.*);
const neighborModel = blocks.meshes.model(neighborBlock);
const targetVal = neighborBlock.solid() and (blockModel == neighborModel or main.models.models.items[neighborModel].neighborFacingQuads[neighbor.reverse().toInt()].len != 0);
var currentData: CarpetData = @bitCast(@as(u6, @truncate(block.data)));
switch(neighbor) {
.dirNegX => {
currentData.negX = currentData.negX and targetVal;
},
.dirPosX => {
currentData.posX = currentData.posX and targetVal;
},
.dirNegY => {
currentData.negY = currentData.negY and targetVal;
},
.dirPosY => {
currentData.posY = currentData.posY and targetVal;
},
.dirDown => {
currentData.negZ = currentData.negZ and targetVal;
},
.dirUp => {
currentData.posZ = currentData.posZ and targetVal;
},
}
const result: u16 = @as(u6, @bitCast(currentData));
if(result == block.data) return false;
if(result == 0) block.* = .{.typ = 0, .data = 0}
else block.data = result;
return true;
}

fn closestRay(comptime typ: enum{bit, intersection}, block: Block, _: ?main.items.Item, relativePlayerPos: Vec3f, playerDir: Vec3f) if(typ == .intersection) ?RayIntersectionResult else u16 {
var result: ?RayIntersectionResult = null;
var resultBit: u16 = 0;
Expand Down

0 comments on commit f8a8d19

Please sign in to comment.