Skip to content
Open
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
3 changes: 3 additions & 0 deletions assets/cubyz/particles/flame.zig.zon
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,7 @@
.density = .{0.00065, 0.00085},
.rotationVelocity = .{20, 35},
.dragCoefficient = .{0.2, 0.3},
.onTouch = .{
.type = .destroy,
},
}
4 changes: 4 additions & 0 deletions src/callbacks/block/server/replace_block_type.zig
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ blockType: u16,
pub fn init(zon: main.ZonElement, creator: main.callbacks.Creator) ?*@This() {
const replacedBlock = switch (creator) {
.block => |b| b,
else => {
std.log.err("cannot use {} for replace_block_type", .{creator});
return null;
},
};
const result = main.worldArena.create(@This());
const blockId = zon.get([]const u8, "block") orelse {
Expand Down
5 changes: 5 additions & 0 deletions src/callbacks/callbacks.zig
Original file line number Diff line number Diff line change
@@ -1,25 +1,30 @@
const std = @import("std");

const main = @import("main");
const Particle = main.particles.Particle;
const Block = main.blocks.Block;
const vec = main.vec;
const Vec3f = vec.Vec3f;
const Vec3i = vec.Vec3i;

pub const ClientBlockCallback = Callback(struct { block: Block, chunk: *main.chunk.Chunk, blockPos: Vec3i }, @import("block/client/_list.zig"));
pub const ServerBlockCallback = Callback(struct { block: Block, chunk: *main.chunk.ServerChunk, blockPos: main.chunk.BlockPos }, @import("block/server/_list.zig"));

pub const BlockTouchCallback = Callback(struct { entity: *main.server.Entity, source: Block, blockPos: Vec3i, deltaTime: f64 }, @import("block/touch/_list.zig"));
pub const ParticleCollideCallback = Callback(struct { source: *Particle, pos: Vec3f }, @import("particles/client/_list.zig"));

pub const Result = enum { handled, ignored };

pub fn init() void {
ClientBlockCallback.globalInit();
ServerBlockCallback.globalInit();
BlockTouchCallback.globalInit();
ParticleCollideCallback.globalInit();
}

pub const Creator = union(enum) {
block: main.blocks.Block,
particle: main.particles.Particle,
};

fn Callback(_Params: type, list: type) type {
Expand Down
1 change: 1 addition & 0 deletions src/callbacks/particles/client/_list.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pub const destroy = @import("destroy.zig");
16 changes: 16 additions & 0 deletions src/callbacks/particles/client/destroy.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
const std = @import("std");

const main = @import("main");
const Block = main.blocks.Block;
const vec = main.vec;
const Vec3i = vec.Vec3i;
const ZonElement = main.ZonElement;

pub fn init(_: ZonElement, _: main.callbacks.Creator) ?*@This() {
return @as(*@This(), undefined);
}

pub fn run(_: *@This(), params: main.callbacks.ParticleCollideCallback.Params) main.callbacks.Result {
params.source.currentFrame = 0;
return .handled;
}
20 changes: 20 additions & 0 deletions src/particles.zig
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,20 @@ pub const particle_manager = struct { // MARK: particle_manager
.rotVel = rotVel,
.dragCoefficient = RandomRange(f32).fromZon(zon.getChild("dragCoefficient")) orelse .init(0.5, 0.6),
.loopTime = RandomRange(f32).fromZon(zon.getChild("loopTime")),
.onTouch = blk: {
break :blk main.callbacks.ParticleCollideCallback.init(
zon.getChildOrNull("onTouch") orelse break :blk .noop,
.{
.particle = .{
.typ = @intCast(types.items.len),
.pos = .{0, 0, 0},
},
},
) orelse {
std.log.err("Failed to load onTouch event for particle {s}", .{id});
break :blk .noop;
};
},
};

particleTypeHashmap.put(main.worldArena.allocator, id, @intCast(types.items.len)) catch unreachable;
Expand Down Expand Up @@ -253,8 +267,10 @@ pub const particle_system = struct { // MARK: particle_system

const posDelta = particleLocal.velAndRotationVel*vecDeltaTime;

var hasColided = false;
v3Pos[0] += posDelta[0];
if (physics.collision.collides(.client, .x, -posDelta[0], v3Pos, hitBox)) |box| {
hasColided = true;
if (posDelta[0] < 0) {
v3Pos[0] = box.max[0] - hitBox.min[0] + physics.epsilon;
} else {
Expand All @@ -263,6 +279,7 @@ pub const particle_system = struct { // MARK: particle_system
}
v3Pos[1] += posDelta[1];
if (physics.collision.collides(.client, .y, -posDelta[1], v3Pos, hitBox)) |box| {
hasColided = true;
if (posDelta[1] < 0) {
v3Pos[1] = box.max[1] - hitBox.min[1] + physics.epsilon;
} else {
Expand All @@ -271,13 +288,15 @@ pub const particle_system = struct { // MARK: particle_system
}
v3Pos[2] += posDelta[2];
if (physics.collision.collides(.client, .z, -posDelta[2], v3Pos, hitBox)) |box| {
hasColided = true;
if (posDelta[2] < 0) {
v3Pos[2] = box.max[2] - hitBox.min[2] + physics.epsilon;
} else {
v3Pos[2] = box.min[2] - hitBox.max[2] - physics.epsilon;
}
}
pos = @as(Vec3f, @floatCast(v3Pos - playerPos));
_ = if (hasColided) particle_manager.typesLocal.items[particle.typ].onTouch.run(.{.source = particle, .pos = pos});
} else {
const posDelta = particleLocal.velAndRotationVel*vecDeltaTime;

Expand Down Expand Up @@ -556,6 +575,7 @@ pub const ParticleTypeLocal = struct {
rotVel: RandomRange(f32),
dragCoefficient: RandomRange(f32),
loopTime: ?RandomRange(f32),
onTouch: main.callbacks.ParticleCollideCallback,
};

pub const Particle = extern struct {
Expand Down
Loading