Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions assets/cubyz/blocks/cloth/_defaults.zig.zon
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,6 @@
.collide = false,
.model = "cubyz:carpet",
.rotation = "cubyz:carpet",
.placementMode = .gridNeighbor,
.degradable = true,
}
1 change: 1 addition & 0 deletions assets/cubyz/blocks/daisies.zig.zon
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
.absorbedLight = 0x121012,
.model = "cubyz:plane",
.rotation = "cubyz:carpet",
.placementMode = .gridNeighbor,
.onUpdate = .{
.type = .check_support_blocks,
},
Expand Down
1 change: 1 addition & 0 deletions assets/cubyz/blocks/dandelions.zig.zon
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
.absorbedLight = 0x121012,
.model = "cubyz:plane",
.rotation = "cubyz:carpet",
.placementMode = .gridNeighbor,
.onUpdate = .{
.type = .check_support_blocks,
},
Expand Down
1 change: 1 addition & 0 deletions assets/cubyz/blocks/ivy.zig.zon
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
.absorbedLight = 0x121012,
.model = "cubyz:plane",
.rotation = "cubyz:carpet",
.placementMode = .gridNeighbor,
.texture = "cubyz:ivy",
.item = .{
.texture = "ivy.png",
Expand Down
1 change: 1 addition & 0 deletions assets/cubyz/blocks/osier.zig.zon
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
.absorbedLight = 0x121012,
.model = "cubyz:plane",
.rotation = "cubyz:carpet",
.placementMode = .gridNeighbor,
.onUpdate = .{
.type = .check_support_blocks,
},
Expand Down
11 changes: 11 additions & 0 deletions src/blocks.zig
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,11 @@ pub const Ore = struct {
seed: u64,
};

const PlacementMode = enum {
boundingBox,
gridNeighbor,
};

const SelectionCapabilities = union(enum) {
always: void,
custom: packed struct(u1) {
Expand Down Expand Up @@ -117,6 +122,7 @@ var _degradable: [maxBlockCount]bool = undefined;
var _viewThrough: [maxBlockCount]bool = undefined;
var _alwaysViewThrough: [maxBlockCount]bool = undefined;
var _hasBackFace: [maxBlockCount]bool = undefined;
var _placementMode: [maxBlockCount]PlacementMode = undefined;
var _tags: [maxBlockCount][]Tag = undefined;
var _light: [maxBlockCount]u32 = undefined;
/// How much light this block absorbs if it is transparent
Expand Down Expand Up @@ -185,6 +191,7 @@ pub fn register(_: []const u8, id: []const u8, zon: ZonElement) u16 {
_alwaysViewThrough[size] = zon.get(bool, "alwaysViewThrough") orelse false;
_viewThrough[size] = (zon.get(bool, "viewThrough") orelse false) or _transparent[size] or _alwaysViewThrough[size];
_hasBackFace[size] = zon.get(bool, "hasBackFace") orelse false;
_placementMode[size] = zon.get(PlacementMode, "placementMode") orelse .boundingBox;
_friction[size] = zon.get(f32, "friction") orelse 20;
_bounciness[size] = zon.get(f32, "bounciness") orelse 0.0;
_density[size] = zon.get(f32, "density") orelse main.physics.airDensity;
Expand Down Expand Up @@ -478,6 +485,10 @@ pub const Block = packed struct(u32) { // MARK: Block
return _hasBackFace[self.typ];
}

pub inline fn placementMode(self: Block) PlacementMode {
return _placementMode[self.typ];
}

pub inline fn tags(self: Block) []const Tag {
return _tags[self.typ];
}
Expand Down
30 changes: 26 additions & 4 deletions src/renderer.zig
Original file line number Diff line number Diff line change
Expand Up @@ -993,6 +993,25 @@ pub const MeshSelection = struct { // MARK: MeshSelection
// TODO: Test entities
}

fn boundingBoxFaceNormal(relativePos: Vec3f, dir: Vec3f, min: Vec3f, max: Vec3f) ?Vec3i {
var tEnter: f32 = -std.math.inf(f32);
var result: ?Vec3i = null;
inline for (0..3) |axis| {
if (dir[axis] != 0) {
const t1 = (min[axis] - relativePos[axis])/dir[axis];
const t2 = (max[axis] - relativePos[axis])/dir[axis];
const t = @min(t1, t2);
if (t > tEnter) {
tEnter = t;
var normal: Vec3i = .{0, 0, 0};
normal[axis] = if (dir[axis] > 0) -1 else 1;
result = normal;
}
}
}
return if (tEnter >= 0) result else null;
}

fn canPlaceBlock(pos: Vec3i, block: main.blocks.Block) bool {
if (main.physics.collision.collideWithBlock(block, pos[0], pos[1], pos[2], main.game.Player.getPosBlocking() + main.game.Player.outerBoundingBox.center(), main.game.Player.outerBoundingBox.extent(), .{0, 0, 0}) != null) {
return false;
Expand Down Expand Up @@ -1025,14 +1044,17 @@ pub const MeshSelection = struct { // MARK: MeshSelection
}
}
// Check the block in front of it:
const neighborPos = posBeforeBlock;
neighborDir = selectedPos - posBeforeBlock;
const selectedRelPos: Vec3f = @floatCast(lastPos - @as(Vec3d, @floatFromInt(selectedPos)));
const boxFaceNormal: ?Vec3i = if (oldBlock.placementMode() == .boundingBox) boundingBoxFaceNormal(selectedRelPos, lastDir, selectionMin, selectionMax) else null;
const neighborPos = if (boxFaceNormal) |normal| selectedPos + normal else posBeforeBlock;
neighborDir = if (boxFaceNormal) |normal| -normal else selectedPos - posBeforeBlock;
const neighborOfSelectionValue = if (boxFaceNormal != null) chunk.Neighbor.fromRelPos(neighborDir).? else neighborOfSelection;
const relPos: Vec3f = @floatCast(lastPos - @as(Vec3d, @floatFromInt(neighborPos)));
const neighborBlock = block;
oldBlock = mesh_storage.getBlockFromRenderThread(neighborPos[0], neighborPos[1], neighborPos[2]) orelse return;
block = oldBlock;
if (block.typ == itemBlock) {
if (rotationMode.generateData(main.game.world.?, neighborPos, relPos, lastDir, neighborDir, neighborOfSelection, &block, neighborBlock, false)) {
if (rotationMode.generateData(main.game.world.?, neighborPos, relPos, lastDir, neighborDir, neighborOfSelectionValue, &block, neighborBlock, false)) {
if (!canPlaceBlock(neighborPos, block)) return;
updateBlockAndSendUpdate(inventory, slot, neighborPos, oldBlock, block);
return;
Expand All @@ -1041,7 +1063,7 @@ pub const MeshSelection = struct { // MARK: MeshSelection
if (!block.replaceable()) return;
block.typ = itemBlock;
block.data = 0;
if (rotationMode.generateData(main.game.world.?, neighborPos, relPos, lastDir, neighborDir, neighborOfSelection, &block, neighborBlock, true)) {
if (rotationMode.generateData(main.game.world.?, neighborPos, relPos, lastDir, neighborDir, neighborOfSelectionValue, &block, neighborBlock, true)) {
if (!canPlaceBlock(neighborPos, block)) return;
updateBlockAndSendUpdate(inventory, slot, neighborPos, oldBlock, block);
return;
Expand Down
2 changes: 1 addition & 1 deletion src/rotation.zig
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ pub const RotationMode = struct { // MARK: RotationMode
}
if (minimum != null) {
// Invert the normal if the player is behind the face (eg. cross model)
if (vec.dot(normal.?, relativePlayerPos) < 0.0) {
if (vec.dot(normal.?, playerDir) > 0.0) {
normal = -normal.?;
}
return .{
Expand Down
Loading