mirror of
https://github.com/PixelGuys/Cubyz.git
synced 2025-08-03 19:28:49 -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 posBeforeBlock: Vec3i = undefined;
|
||||||
|
var neighborOfSelection: chunk.Neighbor = undefined;
|
||||||
pub var selectedBlockPos: ?Vec3i = null;
|
pub var selectedBlockPos: ?Vec3i = null;
|
||||||
var lastSelectedBlockPos: Vec3i = undefined;
|
var lastSelectedBlockPos: Vec3i = undefined;
|
||||||
var currentBlockProgress: f32 = 0;
|
var currentBlockProgress: f32 = 0;
|
||||||
@ -752,20 +753,24 @@ pub const MeshSelection = struct { // MARK: MeshSelection
|
|||||||
voxelPos[0] +%= step[0];
|
voxelPos[0] +%= step[0];
|
||||||
total_tMax = tMax[0];
|
total_tMax = tMax[0];
|
||||||
tMax[0] += tDelta[0];
|
tMax[0] += tDelta[0];
|
||||||
|
neighborOfSelection = if(step[0] == 1) .dirPosX else .dirNegX;
|
||||||
} else {
|
} else {
|
||||||
voxelPos[2] +%= step[2];
|
voxelPos[2] +%= step[2];
|
||||||
total_tMax = tMax[2];
|
total_tMax = tMax[2];
|
||||||
tMax[2] += tDelta[2];
|
tMax[2] += tDelta[2];
|
||||||
|
neighborOfSelection = if(step[2] == 1) .dirUp else .dirDown;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if(tMax[1] < tMax[2]) {
|
if(tMax[1] < tMax[2]) {
|
||||||
voxelPos[1] +%= step[1];
|
voxelPos[1] +%= step[1];
|
||||||
total_tMax = tMax[1];
|
total_tMax = tMax[1];
|
||||||
tMax[1] += tDelta[1];
|
tMax[1] += tDelta[1];
|
||||||
|
neighborOfSelection = if(step[1] == 1) .dirPosY else .dirNegY;
|
||||||
} else {
|
} else {
|
||||||
voxelPos[2] +%= step[2];
|
voxelPos[2] +%= step[2];
|
||||||
total_tMax = tMax[2];
|
total_tMax = tMax[2];
|
||||||
tMax[2] += tDelta[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:
|
// Check if stuff can be added to the block itself:
|
||||||
if(itemBlock == block.typ) {
|
if(itemBlock == block.typ) {
|
||||||
const relPos: Vec3f = @floatCast(lastPos - @as(Vec3d, @floatFromInt(selectedPos)));
|
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;
|
if(!canPlaceBlock(selectedPos, block)) return;
|
||||||
updateBlockAndSendUpdate(inventory, slot, selectedPos[0], selectedPos[1], selectedPos[2], oldBlock, block);
|
updateBlockAndSendUpdate(inventory, slot, selectedPos[0], selectedPos[1], selectedPos[2], oldBlock, block);
|
||||||
return;
|
return;
|
||||||
@ -806,7 +811,7 @@ pub const MeshSelection = struct { // MARK: MeshSelection
|
|||||||
oldBlock = mesh_storage.getBlock(neighborPos[0], neighborPos[1], neighborPos[2]) orelse return;
|
oldBlock = mesh_storage.getBlock(neighborPos[0], neighborPos[1], neighborPos[2]) orelse return;
|
||||||
block = oldBlock;
|
block = oldBlock;
|
||||||
if(block.typ == itemBlock) {
|
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;
|
if(!canPlaceBlock(neighborPos, block)) return;
|
||||||
updateBlockAndSendUpdate(inventory, slot, neighborPos[0], neighborPos[1], neighborPos[2], oldBlock, block);
|
updateBlockAndSendUpdate(inventory, slot, neighborPos[0], neighborPos[1], neighborPos[2], oldBlock, block);
|
||||||
return;
|
return;
|
||||||
@ -815,7 +820,7 @@ pub const MeshSelection = struct { // MARK: MeshSelection
|
|||||||
if(block.solid()) return;
|
if(block.solid()) return;
|
||||||
block.typ = itemBlock;
|
block.typ = itemBlock;
|
||||||
block.data = 0;
|
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;
|
if(!canPlaceBlock(neighborPos, block)) return;
|
||||||
updateBlockAndSendUpdate(inventory, slot, neighborPos[0], neighborPos[1], neighborPos[2], oldBlock, block);
|
updateBlockAndSendUpdate(inventory, slot, neighborPos[0], neighborPos[1], neighborPos[2], oldBlock, block);
|
||||||
return;
|
return;
|
||||||
|
@ -26,7 +26,7 @@ pub const RotationMode = struct { // MARK: RotationMode
|
|||||||
fn model(block: Block) u16 {
|
fn model(block: Block) u16 {
|
||||||
return blocks.meshes.modelIndexStart(block);
|
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;
|
return blockPlacing;
|
||||||
}
|
}
|
||||||
fn createBlockModel(modelId: []const u8) u16 {
|
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.
|
/// 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.
|
/// 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.
|
/// Updates data of a placed block if the RotationMode dependsOnNeighbors.
|
||||||
updateData: *const fn(block: *Block, neighbor: Neighbor, neighborBlock: Block) bool = &DefaultFunctions.updateData,
|
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);
|
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(blockPlacing) {
|
||||||
if(relativeDir[0] == 1) currentData.data = Neighbor.dirNegX.toInt();
|
currentData.data = neighbor.?.reverse().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();
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@ -212,7 +207,7 @@ pub const RotationModes = struct {
|
|||||||
return blocks.meshes.modelIndexStart(block) + @min(block.data, 3);
|
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(blockPlacing) {
|
||||||
if(@abs(playerDir[0]) > @abs(playerDir[1])) {
|
if(@abs(playerDir[0]) > @abs(playerDir[1])) {
|
||||||
if(playerDir[0] < 0) currentData.data = Neighbor.dirNegX.toInt() - 2
|
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);
|
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) {
|
if(blockPlacing) {
|
||||||
currentData.data = 0;
|
currentData.data = 0;
|
||||||
return true;
|
return true;
|
||||||
@ -694,7 +689,11 @@ pub const RotationModes = struct {
|
|||||||
return blocks.meshes.modelIndexStart(block) + (@as(u5, @truncate(block.data)) -| 1);
|
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)));
|
var data: TorchData = @bitCast(@as(u5, @truncate(currentData.data)));
|
||||||
if(relativeDir[0] == 1) data.posX = true;
|
if(relativeDir[0] == 1) data.posX = true;
|
||||||
if(relativeDir[0] == -1) data.negX = 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 {
|
pub fn updateData(block: *Block, neighbor: Neighbor, neighborBlock: Block) bool {
|
||||||
const blockModel = blocks.meshes.modelIndexStart(block.*);
|
|
||||||
const neighborModel = blocks.meshes.model(neighborBlock);
|
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)));
|
var currentData: TorchData = @bitCast(@as(u5, @truncate(block.data)));
|
||||||
switch(neighbor) {
|
switch(neighbor) {
|
||||||
.dirNegX => {
|
.dirNegX => {
|
||||||
currentData.negX = currentData.negX and targetVal;
|
currentData.negX = currentData.negX and neighborSupport;
|
||||||
},
|
},
|
||||||
.dirPosX => {
|
.dirPosX => {
|
||||||
currentData.posX = currentData.posX and targetVal;
|
currentData.posX = currentData.posX and neighborSupport;
|
||||||
},
|
},
|
||||||
.dirNegY => {
|
.dirNegY => {
|
||||||
currentData.negY = currentData.negY and targetVal;
|
currentData.negY = currentData.negY and neighborSupport;
|
||||||
},
|
},
|
||||||
.dirPosY => {
|
.dirPosY => {
|
||||||
currentData.posY = currentData.posY and targetVal;
|
currentData.posY = currentData.posY and neighborSupport;
|
||||||
},
|
},
|
||||||
.dirDown => {
|
.dirDown => {
|
||||||
currentData.center = currentData.center and targetVal;
|
currentData.center = currentData.center and neighborSupport;
|
||||||
},
|
},
|
||||||
else => {},
|
else => {},
|
||||||
}
|
}
|
||||||
@ -863,7 +861,7 @@ pub const RotationModes = struct {
|
|||||||
return blocks.meshes.modelIndexStart(block) + (@as(u6, @truncate(block.data)) -| 1);
|
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: {
|
if(neighbor.mode() == currentData.mode()) parallelPlacing: {
|
||||||
const bit = closestRay(.bit, neighbor, null, relativePlayerPos - @as(Vec3f, @floatFromInt(relativeDir)), playerDir);
|
const bit = closestRay(.bit, neighbor, null, relativePlayerPos - @as(Vec3f, @floatFromInt(relativeDir)), playerDir);
|
||||||
const bitData: CarpetData = @bitCast(@as(u6, @truncate(bit)));
|
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 {
|
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 result: ?RayIntersectionResult = null;
|
||||||
var resultBit: u16 = 0;
|
var resultBit: u16 = 0;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user