mirror of
https://github.com/PixelGuys/Cubyz.git
synced 2025-08-03 11:17:05 -04:00
Merge a8daaf1d14651b36bbff9cd5129d53d7e16b75ac into 2dc2a6e79018221d5aab44e09be242d9dab3ddf2
This commit is contained in:
commit
ff332cac4c
101
src/blocks.zig
101
src/blocks.zig
@ -136,7 +136,6 @@ pub fn register(_: []const u8, id: []const u8, zon: ZonElement) u16 {
|
||||
_terminalVelocity[size] = zon.get(f32, "terminalVelocity", 90);
|
||||
_mobility[size] = zon.get(f32, "mobility", 1.0);
|
||||
_allowOres[size] = zon.get(bool, "allowOres", false);
|
||||
_tickEvent[size] = TickEvent.loadFromZon(zon.getChild("tickEvent"));
|
||||
|
||||
_touchFunction[size] = if(zon.get(?[]const u8, "touchFunction", null)) |touchFunctionName| blk: {
|
||||
const _function = touchFunctions.getFunctionPointer(touchFunctionName);
|
||||
@ -220,6 +219,10 @@ fn registerOpaqueVariant(typ: u16, zon: ZonElement) void {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn registerTickEvent(typ: u16, zon: ZonElement) void {
|
||||
_tickEvent[typ] = TickEvent.loadFromZon(zon.getChild("tickEvent"));
|
||||
}
|
||||
|
||||
pub fn finishBlocks(zonElements: Assets.ZonHashMap) void {
|
||||
var i: u16 = 0;
|
||||
while(i < size) : (i += 1) {
|
||||
@ -229,6 +232,7 @@ pub fn finishBlocks(zonElements: Assets.ZonHashMap) void {
|
||||
while(i < size) : (i += 1) {
|
||||
registerLodReplacement(i, zonElements.get(_id[i]) orelse continue);
|
||||
registerOpaqueVariant(i, zonElements.get(_id[i]) orelse continue);
|
||||
registerTickEvent(i, zonElements.get(_id[i]) orelse continue);
|
||||
}
|
||||
blueprint.registerVoidBlock(parseBlock("cubyz:void"));
|
||||
}
|
||||
@ -433,39 +437,102 @@ pub const Block = packed struct { // MARK: Block
|
||||
};
|
||||
|
||||
// MARK: Tick
|
||||
pub var tickFunctions: utils.NamedCallbacks(TickFunctions, TickFunction) = undefined;
|
||||
pub const TickFunction = fn(block: Block, _chunk: *chunk.ServerChunk, x: i32, y: i32, z: i32) void;
|
||||
pub const TickFunctions = struct {
|
||||
pub fn replaceWithCobble(block: Block, _chunk: *chunk.ServerChunk, x: i32, y: i32, z: i32) void {
|
||||
std.log.debug("Replace with cobblestone at ({d},{d},{d})", .{x, y, z});
|
||||
const cobblestone = parseBlock("cubyz:cobblestone");
|
||||
pub const TickEventVTableMap = struct {
|
||||
vTableMap: std.StringHashMap(*const TickEvent.VTable) = undefined,
|
||||
|
||||
const wx = _chunk.super.pos.wx + x;
|
||||
const wy = _chunk.super.pos.wy + y;
|
||||
const wz = _chunk.super.pos.wz + z;
|
||||
pub fn init() TickEventVTableMap {
|
||||
var self = TickEventVTableMap{
|
||||
.vTableMap = .init(main.globalAllocator.allocator),
|
||||
};
|
||||
|
||||
_ = main.server.world.?.cmpxchgBlock(wx, wy, wz, block, cobblestone);
|
||||
const typeInfo = @typeInfo(TickEvents);
|
||||
if(typeInfo != .@"struct") @compileError("Type " ++ @typeName(TickEvents) ++ " is not a struct");
|
||||
|
||||
inline for(typeInfo.@"struct".decls) |decl| {
|
||||
const field = @field(TickEvents, decl.name);
|
||||
if(@typeInfo(@TypeOf(field)) == .type) {
|
||||
self.registerEventStruct(field);
|
||||
}
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
pub fn deinit(self: *TickEventVTableMap) void {
|
||||
self.vTableMap.deinit();
|
||||
}
|
||||
|
||||
fn registerEventStruct(self: *TickEventVTableMap, comptime EventType: type) void {
|
||||
inline for(@typeInfo(EventType).@"struct".decls) |eventDecl| {
|
||||
const field = @field(EventType, eventDecl.name);
|
||||
if(@TypeOf(field) == *const TickEvent.VTable) {
|
||||
const id = @field(EventType, "id");
|
||||
self.vTableMap.putNoClobber(id, field) catch unreachable;
|
||||
std.log.debug("Registered TickEvent '{s}'", .{id});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn getVTable(self: *TickEventVTableMap, id: []const u8) ?*const TickEvent.VTable {
|
||||
return self.vTableMap.get(id);
|
||||
}
|
||||
};
|
||||
|
||||
pub const TickFunction = fn(self: *anyopaque, block: Block, world: *main.server.ServerWorld, wx: i32, wy: i32, wz: i32) void;
|
||||
pub var tickEvents: TickEventVTableMap = undefined;
|
||||
pub const TickEvents = struct {
|
||||
pub const ReplaceWithEvent = struct {
|
||||
pub const id = "replaceWith";
|
||||
replacementBlock: Block,
|
||||
|
||||
pub const VTable: *const TickEvent.VTable = &.{
|
||||
.id = id,
|
||||
.tickFunction = utils.castFunctionSelfToAnyopaque(replaceWith),
|
||||
.loadFromZon = utils.castFunctionReturnToAnyopaque(loadFromZon),
|
||||
};
|
||||
|
||||
pub fn replaceWith(self: *const ReplaceWithEvent, block: Block, world: *main.server.ServerWorld, wx: i32, wy: i32, wz: i32) void {
|
||||
_ = world.cmpxchgBlock(wx, wy, wz, block, self.replacementBlock);
|
||||
}
|
||||
|
||||
pub fn loadFromZon(zon: ZonElement) *ReplaceWithEvent {
|
||||
const self = allocator.create(ReplaceWithEvent);
|
||||
const newBlock = if(zon.get(?[]const u8, "block", null)) |blockName| parseBlock(blockName) else blk: {
|
||||
std.log.err("No 'block' parameter was provided for '{s}'. Using fallback block: {s}", .{id, Block.air.id()});
|
||||
break :blk Block.air;
|
||||
};
|
||||
self.* = .{.replacementBlock = newBlock};
|
||||
return self;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
pub const TickEvent = struct {
|
||||
function: *const TickFunction,
|
||||
args: *anyopaque,
|
||||
vTable: *const VTable,
|
||||
chance: f32,
|
||||
|
||||
pub const VTable = struct {
|
||||
id: []const u8,
|
||||
tickFunction: *const TickFunction,
|
||||
loadFromZon: *const fn(zon: ZonElement) *anyopaque,
|
||||
};
|
||||
|
||||
pub fn loadFromZon(zon: ZonElement) ?TickEvent {
|
||||
const functionName = zon.get(?[]const u8, "name", null) orelse return null;
|
||||
|
||||
const function = tickFunctions.getFunctionPointer(functionName) orelse {
|
||||
std.log.err("Could not find TickFunction {s}.", .{functionName});
|
||||
const eventVTable = tickEvents.getVTable(functionName) orelse {
|
||||
std.log.err("Could not find TickEvent {s}.", .{functionName});
|
||||
return null;
|
||||
};
|
||||
|
||||
return TickEvent{.function = function, .chance = zon.get(f32, "chance", 1)};
|
||||
const args = eventVTable.loadFromZon(zon);
|
||||
return TickEvent{.args = args, .vTable = eventVTable, .chance = zon.get(f32, "chance", 1)};
|
||||
}
|
||||
|
||||
pub fn tryRandomTick(self: *const TickEvent, block: Block, _chunk: *chunk.ServerChunk, x: i32, y: i32, z: i32) void {
|
||||
pub fn tryRandomTick(self: *const TickEvent, block: Block, world: *main.server.ServerWorld, wx: i32, wy: i32, wz: i32) void {
|
||||
if(self.chance >= 1.0 or main.random.nextFloat(&main.seed) < self.chance) {
|
||||
self.function(block, _chunk, x, y, z);
|
||||
self.vTable.tickFunction(self.args, block, world, wx, wy, wz);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -615,8 +615,8 @@ pub fn main() void { // MARK: main()
|
||||
block_entity.init();
|
||||
defer block_entity.deinit();
|
||||
|
||||
blocks.tickFunctions = .init();
|
||||
defer blocks.tickFunctions.deinit();
|
||||
blocks.tickEvents = .init();
|
||||
defer blocks.tickEvents.deinit();
|
||||
|
||||
blocks.touchFunctions = .init();
|
||||
defer blocks.touchFunctions.deinit();
|
||||
|
@ -1060,7 +1060,10 @@ pub const ServerWorld = struct { // MARK: ServerWorld
|
||||
const block = _chunk.getBlock(x, y, z);
|
||||
_chunk.mutex.unlock();
|
||||
if(block.tickEvent()) |event| {
|
||||
event.tryRandomTick(block, _chunk, x, y, z);
|
||||
const wx = _chunk.super.pos.wx + x;
|
||||
const wy = _chunk.super.pos.wy + y;
|
||||
const wz = _chunk.super.pos.wz + z;
|
||||
event.tryRandomTick(block, self, wx, wy, wz);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user