mirror of
https://github.com/PixelGuys/Cubyz.git
synced 2025-08-03 11:17:05 -04:00
Simplified Block Touch Detection (#1143)
* Add block touch detection * Fix touch detection syntax errors * Remove Whitespace * Fix off by one in negatives * Remove Block Touch Detection * Simpler touch detection as suggested by Quantum * Remove touchRetraction because for some reason it is no longer needed * Touch Functions are now function pointers * Remove unwanted debug prints * Add parameter names to TouchFunction declaration * Add error check --------- Co-authored-by: gfh <@> Co-authored-by: SuperIceG <102669377+SEGenjoysBlivits@users.noreply.github.com>
This commit is contained in:
parent
471210f585
commit
2b3547d103
@ -13,6 +13,7 @@ const items = @import("items.zig");
|
||||
const models = @import("models.zig");
|
||||
const rotation = @import("rotation.zig");
|
||||
const RotationMode = rotation.RotationMode;
|
||||
const Entity = main.server.Entity;
|
||||
|
||||
pub const BlockTag = enum(u32) {
|
||||
air = 0,
|
||||
@ -109,6 +110,8 @@ var _friction: [maxBlockCount]f32 = undefined;
|
||||
|
||||
var _allowOres: [maxBlockCount]bool = undefined;
|
||||
|
||||
var _touchFunction: [maxBlockCount]?*const TouchFunction = undefined;
|
||||
|
||||
var reverseIndices = std.StringHashMap(u16).init(allocator.allocator);
|
||||
|
||||
var size: u32 = 0;
|
||||
@ -149,6 +152,7 @@ pub fn register(_: []const u8, id: []const u8, zon: ZonElement) u16 {
|
||||
_hasBackFace[size] = zon.get(bool, "hasBackFace", false);
|
||||
_friction[size] = zon.get(f32, "friction", 20);
|
||||
_allowOres[size] = zon.get(bool, "allowOres", false);
|
||||
_touchFunction[size] = TouchFunctions.getFunctionPointer(zon.get([]const u8, "touchFunction", ""));
|
||||
|
||||
const oreProperties = zon.getChild("ore");
|
||||
if(oreProperties != .null) blk: {
|
||||
@ -374,11 +378,44 @@ pub const Block = packed struct { // MARK: Block
|
||||
return _allowOres[self.typ];
|
||||
}
|
||||
|
||||
pub inline fn touchFunction(self: Block) ?*const TouchFunction {
|
||||
return _touchFunction[self.typ];
|
||||
}
|
||||
|
||||
pub fn canBeChangedInto(self: Block, newBlock: Block, item: main.items.ItemStack, shouldDropSourceBlockOnSuccess: *bool) main.rotation.RotationMode.CanBeChangedInto {
|
||||
return newBlock.mode().canBeChangedInto(self, newBlock, item, shouldDropSourceBlockOnSuccess);
|
||||
}
|
||||
};
|
||||
|
||||
pub const TouchFunction = fn(block: Block, entity: Entity, posX: i32, posY: i32, posZ: i32, isEntityInside: bool) void;
|
||||
|
||||
pub const TouchFunctions = struct {
|
||||
var hashMap: std.StringHashMap(*const TouchFunction) = undefined;
|
||||
|
||||
pub fn init() void {
|
||||
hashMap = .init(main.globalAllocator.allocator);
|
||||
inline for(@typeInfo(TouchFunctions).@"struct".decls) |declaration| {
|
||||
if(@TypeOf(@field(TouchFunctions, declaration.name)) == TouchFunction) {
|
||||
hashMap.putNoClobber(declaration.name, &@field(TouchFunctions, declaration.name)) catch unreachable;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn deinit() void {
|
||||
hashMap.deinit();
|
||||
}
|
||||
|
||||
pub fn getFunctionPointer(id: []const u8) ?*const TouchFunction {
|
||||
const pointer = hashMap.getPtr(id);
|
||||
if(pointer == null) {
|
||||
if(id.len != 0)
|
||||
std.log.err("Could not find touch function {s}.", .{id});
|
||||
return null;
|
||||
}
|
||||
return pointer.?.*;
|
||||
}
|
||||
};
|
||||
|
||||
pub const meshes = struct { // MARK: meshes
|
||||
const AnimationData = extern struct {
|
||||
startFrame: u32,
|
||||
|
57
src/game.zig
57
src/game.zig
@ -25,6 +25,7 @@ const models = main.models;
|
||||
const Fog = graphics.Fog;
|
||||
const renderer = @import("renderer.zig");
|
||||
const settings = @import("settings.zig");
|
||||
const Block = main.blocks.Block;
|
||||
|
||||
pub const camera = struct { // MARK: camera
|
||||
pub var rotation: Vec3f = Vec3f{0, 0, 0};
|
||||
@ -362,6 +363,61 @@ pub const collision = struct {
|
||||
return resultingMovement;
|
||||
}
|
||||
|
||||
fn isBlockIntersecting(block: Block, posX: i32, posY: i32, posZ: i32, center: Vec3d, extent: Vec3d) bool {
|
||||
const model = &models.models.items[block.mode().model(block)];
|
||||
const position = Vec3d{@floatFromInt(posX), @floatFromInt(posY), @floatFromInt(posZ)};
|
||||
for(model.neighborFacingQuads) |quads| {
|
||||
for(quads) |quadIndex| {
|
||||
const quad = &models.quads.items[quadIndex];
|
||||
if(triangleAABB(.{quad.corners[0] + quad.normal + position, quad.corners[2] + quad.normal + position, quad.corners[1] + quad.normal + position}, center, extent) or
|
||||
triangleAABB(.{quad.corners[1] + quad.normal + position, quad.corners[2] + quad.normal + position, quad.corners[3] + quad.normal + position}, center, extent)) return true;
|
||||
}
|
||||
}
|
||||
for(model.internalQuads) |quadIndex| {
|
||||
const quad = &models.quads.items[quadIndex];
|
||||
if(triangleAABB(.{quad.corners[0] + position, quad.corners[2] + position, quad.corners[1] + position}, center, extent) or
|
||||
triangleAABB(.{quad.corners[1] + position, quad.corners[2] + position, quad.corners[3] + position}, center, extent)) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
pub fn touchBlocks(entity: main.server.Entity, hitBox: Box, side: main.utils.Side) void {
|
||||
const boundingBox: Box = .{.min = entity.pos + hitBox.min, .max = entity.pos + hitBox.max};
|
||||
|
||||
const minX: i32 = @intFromFloat(@floor(boundingBox.min[0] - 0.01));
|
||||
const maxX: i32 = @intFromFloat(@floor(boundingBox.max[0] + 0.01));
|
||||
const minY: i32 = @intFromFloat(@floor(boundingBox.min[1] - 0.01));
|
||||
const maxY: i32 = @intFromFloat(@floor(boundingBox.max[1] + 0.01));
|
||||
const minZ: i32 = @intFromFloat(@floor(boundingBox.min[2] - 0.01));
|
||||
const maxZ: i32 = @intFromFloat(@floor(boundingBox.max[2] + 0.01));
|
||||
|
||||
const center: Vec3d = boundingBox.center();
|
||||
const extent: Vec3d = boundingBox.extent();
|
||||
|
||||
const extentX: Vec3d = extent + Vec3d{0.01, -0.01, -0.01};
|
||||
const extentY: Vec3d = extent + Vec3d{-0.01, 0.01, -0.01};
|
||||
const extentZ: Vec3d = extent + Vec3d{-0.01, -0.01, 0.01};
|
||||
|
||||
var posX: i32 = minX;
|
||||
while(posX <= maxX) : (posX += 1) {
|
||||
var posY: i32 = minY;
|
||||
while(posY <= maxY) : (posY += 1) {
|
||||
var posZ: i32 = minZ;
|
||||
while(posZ <= maxZ) : (posZ += 1) {
|
||||
const block: ?Block =
|
||||
if(side == .client) main.renderer.mesh_storage.getBlock(posX, posY, posZ) else main.server.world.?.getBlock(posX, posY, posZ);
|
||||
if(block == null or block.?.touchFunction() == null)
|
||||
continue;
|
||||
const touchX: bool = isBlockIntersecting(block.?, posX, posY, posZ, center, extentX);
|
||||
const touchY: bool = isBlockIntersecting(block.?, posX, posY, posZ, center, extentY);
|
||||
const touchZ: bool = isBlockIntersecting(block.?, posX, posY, posZ, center, extentZ);
|
||||
if(touchX or touchY or touchZ)
|
||||
block.?.touchFunction().?(block.?, entity, posX, posY, posZ, touchX and touchY and touchZ);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub const Box = struct {
|
||||
min: Vec3d,
|
||||
max: Vec3d,
|
||||
@ -1126,6 +1182,7 @@ pub fn update(deltaTime: f64) void { // MARK: update()
|
||||
} else if(Player.eyeCoyote > 0) {
|
||||
Player.eyePos[2] -= move[2];
|
||||
}
|
||||
collision.touchBlocks(Player.super, hitBox, .client);
|
||||
} else {
|
||||
Player.super.pos += move;
|
||||
}
|
||||
|
@ -580,6 +580,9 @@ pub fn main() void { // MARK: main()
|
||||
rotation.init();
|
||||
defer rotation.deinit();
|
||||
|
||||
blocks.TouchFunctions.init();
|
||||
defer blocks.TouchFunctions.deinit();
|
||||
|
||||
models.init();
|
||||
defer models.deinit();
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user