mirror of
https://github.com/PixelGuys/Cubyz.git
synced 2025-08-03 11:17:05 -04:00
Fix discrepancy between client-side and server-side torch placement.
fixes #993
This commit is contained in:
parent
9be4ff1047
commit
f8a8d19759
@ -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;
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
@ -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;
|
||||
@ -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;
|
||||
|
@ -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 {
|
||||
@ -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,
|
||||
@ -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;
|
||||
@ -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
|
||||
@ -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;
|
||||
@ -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;
|
||||
@ -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 => {},
|
||||
}
|
||||
@ -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)));
|
||||
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user