mirror of
https://github.com/PixelGuys/Cubyz.git
synced 2025-08-03 11:17:05 -04:00
Add the player inventory(no gui yet), fix compile errors from last commit and fix a data race.
This commit is contained in:
parent
0f0b0b6ac4
commit
df36109ee5
@ -450,7 +450,7 @@ pub const meshing = struct {
|
||||
pub const ChunkMesh = struct {
|
||||
pos: ChunkPosition,
|
||||
size: ChunkCoordinate,
|
||||
chunk: ?*Chunk,
|
||||
chunk: std.atomic.Atomic(?*Chunk),
|
||||
faces: std.ArrayList(u32),
|
||||
faceData: SSBO,
|
||||
coreCount: u31 = 0,
|
||||
@ -465,7 +465,7 @@ pub const meshing = struct {
|
||||
.pos = pos,
|
||||
.size = chunkSize*pos.voxelSize,
|
||||
.faces = std.ArrayList(u32).init(allocator),
|
||||
.chunk = null,
|
||||
.chunk = std.atomic.Atomic(?*Chunk).init(null),
|
||||
.faceData = SSBO.init(),
|
||||
};
|
||||
}
|
||||
@ -473,7 +473,7 @@ pub const meshing = struct {
|
||||
pub fn deinit(self: *ChunkMesh) void {
|
||||
self.faceData.deinit();
|
||||
self.faces.deinit();
|
||||
if(self.chunk) |ch| {
|
||||
if(self.chunk.load(.Monotonic)) |ch| {
|
||||
renderer.RenderStructure.allocator.destroy(ch);
|
||||
}
|
||||
}
|
||||
@ -544,10 +544,10 @@ pub const meshing = struct {
|
||||
}
|
||||
}
|
||||
|
||||
if(self.chunk) |oldChunk| {
|
||||
if(self.chunk.load(.Monotonic)) |oldChunk| {
|
||||
renderer.RenderStructure.allocator.destroy(oldChunk);
|
||||
}
|
||||
self.chunk = chunk;
|
||||
self.chunk.store(chunk, .Monotonic);
|
||||
self.coreCount = @intCast(u31, self.faces.items.len);
|
||||
self.neighborStart = [_]u31{self.coreCount} ** 7;
|
||||
}
|
||||
@ -625,7 +625,7 @@ pub const meshing = struct {
|
||||
self.mutex.lock();
|
||||
defer self.mutex.unlock();
|
||||
if(!self.generated) return;
|
||||
const oldBlock = self.chunk.?.blocks[getIndex(x, y, z)];
|
||||
const oldBlock = self.chunk.load(.Monotonic).?.blocks[getIndex(x, y, z)];
|
||||
for(Neighbors.iterable) |neighbor| {
|
||||
var neighborMesh = self;
|
||||
var nx = x + Neighbors.relX[neighbor];
|
||||
@ -640,7 +640,7 @@ pub const meshing = struct {
|
||||
nx &= chunkMask;
|
||||
ny &= chunkMask;
|
||||
nz &= chunkMask;
|
||||
const neighborBlock = neighborMesh.chunk.?.blocks[getIndex(nx, ny, nz)];
|
||||
const neighborBlock = neighborMesh.chunk.load(.Monotonic).?.blocks[getIndex(nx, ny, nz)];
|
||||
{
|
||||
{ // The face of the changed block
|
||||
const newVisibility = canBeSeenThroughOtherBlock(newBlock, neighborBlock, neighbor);
|
||||
@ -701,7 +701,7 @@ pub const meshing = struct {
|
||||
}
|
||||
if(neighborMesh != self) neighborMesh.uploadData();
|
||||
}
|
||||
self.chunk.?.blocks[getIndex(x, y, z)] = newBlock;
|
||||
self.chunk.load(.Monotonic).?.blocks[getIndex(x, y, z)] = newBlock;
|
||||
self.uploadData();
|
||||
}
|
||||
|
||||
@ -712,7 +712,7 @@ pub const meshing = struct {
|
||||
|
||||
pub fn uploadDataAndFinishNeighbors(self: *ChunkMesh) !void {
|
||||
std.debug.assert(!self.mutex.tryLock()); // The mutex should be locked when calling this function.
|
||||
if(self.chunk == null) return; // In the mean-time the mesh was discarded and recreated and all the data was lost.
|
||||
const chunk = self.chunk.load(.Monotonic) orelse return; // In the mean-time the mesh was discarded and recreated and all the data was lost.
|
||||
self.faces.shrinkRetainingCapacity(self.coreCount);
|
||||
for(Neighbors.iterable) |neighbor| {
|
||||
self.neighborStart[neighbor] = @intCast(u31, self.faces.items.len);
|
||||
@ -748,8 +748,8 @@ pub const meshing = struct {
|
||||
var otherX = @intCast(u8, x+%Neighbors.relX[neighbor] & chunkMask);
|
||||
var otherY = @intCast(u8, y+%Neighbors.relY[neighbor] & chunkMask);
|
||||
var otherZ = @intCast(u8, z+%Neighbors.relZ[neighbor] & chunkMask);
|
||||
var block = (&self.chunk.?.blocks)[getIndex(x, y, z)]; // ← a temporary fix to a compiler performance bug. TODO: check if this was fixed.
|
||||
var otherBlock = (&neighborMesh.chunk.?.blocks)[getIndex(otherX, otherY, otherZ)]; // ← a temporary fix to a compiler performance bug. TODO: check if this was fixed.
|
||||
var block = (&chunk.blocks)[getIndex(x, y, z)]; // ← a temporary fix to a compiler performance bug. TODO: check if this was fixed.
|
||||
var otherBlock = (&neighborMesh.chunk.load(.Monotonic).?.blocks)[getIndex(otherX, otherY, otherZ)]; // ← a temporary fix to a compiler performance bug. TODO: check if this was fixed.
|
||||
if(canBeSeenThroughOtherBlock(block, otherBlock, neighbor)) {
|
||||
const normal: u32 = neighbor;
|
||||
const position: u32 = @as(u32, otherX) | @as(u32, otherY)<<5 | @as(u32, otherZ)<<10 | normal<<24;
|
||||
@ -810,8 +810,8 @@ pub const meshing = struct {
|
||||
var otherX = @intCast(u8, (x+%Neighbors.relX[neighbor]+%offsetX >> 1) & chunkMask);
|
||||
var otherY = @intCast(u8, (y+%Neighbors.relY[neighbor]+%offsetY >> 1) & chunkMask);
|
||||
var otherZ = @intCast(u8, (z+%Neighbors.relZ[neighbor]+%offsetZ >> 1) & chunkMask);
|
||||
var block = (&self.chunk.?.blocks)[getIndex(x, y, z)]; // ← a temporary fix to a compiler performance bug. TODO: check if this was fixed.
|
||||
var otherBlock = (&neighborMesh.chunk.?.blocks)[getIndex(otherX, otherY, otherZ)]; // ← a temporary fix to a compiler performance bug. TODO: check if this was fixed.
|
||||
var block = (&chunk.blocks)[getIndex(x, y, z)]; // ← a temporary fix to a compiler performance bug. TODO: check if this was fixed.
|
||||
var otherBlock = (&neighborMesh.chunk.load(.Monotonic).?.blocks)[getIndex(otherX, otherY, otherZ)]; // ← a temporary fix to a compiler performance bug. TODO: check if this was fixed.
|
||||
if(canBeSeenThroughOtherBlock(otherBlock, block, neighbor ^ 1)) {
|
||||
const normal: u32 = neighbor ^ 1;
|
||||
const position: u32 = @as(u32, x) | @as(u32, y)<<5 | @as(u32, z)<<10 | normal<<24;
|
||||
|
@ -2,6 +2,8 @@ const std = @import("std");
|
||||
|
||||
const assets = @import("assets.zig");
|
||||
const chunk = @import("chunk.zig");
|
||||
const items = @import("items.zig");
|
||||
const Inventory = items.Inventory;
|
||||
const json = @import("json.zig");
|
||||
const JsonElement = json.JsonElement;
|
||||
const main = @import("main.zig");
|
||||
@ -46,7 +48,8 @@ pub const Player = struct {
|
||||
var vel: Vec3d = Vec3d{0, 0, 0};
|
||||
pub var id: u32 = 0;
|
||||
pub var isFlying: std.atomic.Atomic(bool) = std.atomic.Atomic(bool).init(true);
|
||||
var mutex: std.Thread.Mutex = std.Thread.Mutex{};
|
||||
pub var mutex: std.Thread.Mutex = std.Thread.Mutex{};
|
||||
pub var inventory__SEND_CHANGES_TO_SERVER: Inventory = undefined;
|
||||
|
||||
pub fn setPosBlocking(newPos: Vec3d) void {
|
||||
mutex.lock();
|
||||
@ -92,6 +95,7 @@ pub const World = struct {
|
||||
.name = "client",
|
||||
.milliTime = std.time.milliTimestamp(),
|
||||
};
|
||||
Player.inventory__SEND_CHANGES_TO_SERVER = try Inventory.init(renderer.RenderStructure.allocator, 32);
|
||||
// TODO:
|
||||
// super.itemEntityManager = new InterpolatedItemEntityManager(this);
|
||||
// player = new ClientPlayer(this, 0);
|
||||
@ -100,6 +104,7 @@ pub const World = struct {
|
||||
|
||||
pub fn deinit(self: *World) void {
|
||||
self.conn.deinit();
|
||||
Player.inventory__SEND_CHANGES_TO_SERVER.deinit(renderer.RenderStructure.allocator);
|
||||
}
|
||||
|
||||
pub fn finishHandshake(self: *World, jsonObject: JsonElement) !void {
|
||||
|
@ -660,6 +660,12 @@ pub const Image = struct {
|
||||
stb_image.stbi_image_free(data);
|
||||
return result;
|
||||
}
|
||||
pub fn setRGB(self: Image, x: usize, y: usize, rgb: Color) void {
|
||||
std.debug.assert(x < self.width);
|
||||
std.debug.assert(y < self.height);
|
||||
const index = x + y*self.width;
|
||||
self.imageData[index] = rgb;
|
||||
}
|
||||
};
|
||||
|
||||
pub const Fog = struct {
|
||||
|
591
src/items.zig
591
src/items.zig
File diff suppressed because it is too large
Load Diff
13
src/json.zig
13
src/json.zig
@ -136,7 +136,7 @@ pub const JsonElement = union(JsonType) {
|
||||
.Null => return JsonElement{.JsonNull={}},
|
||||
.Bool => return JsonElement{.JsonBool=value},
|
||||
.Int, .ComptimeInt => return JsonElement{.JsonInt=@intCast(i64, value)},
|
||||
.Float, .ComptimeFloat => return JsonElement{.JsonInt=@floatCast(f64, value)},
|
||||
.Float, .ComptimeFloat => return JsonElement{.JsonFloat=@floatCast(f64, value)},
|
||||
.Union => {
|
||||
if(@TypeOf(value) == JsonElement) {
|
||||
return value;
|
||||
@ -144,6 +144,14 @@ pub const JsonElement = union(JsonType) {
|
||||
@compileError("Unknown value type.");
|
||||
}
|
||||
},
|
||||
.Pointer => |ptr| {
|
||||
if(ptr.child == u8 and ptr.size == .Slice) {
|
||||
std.log.info("String: {s}", .{value});
|
||||
return JsonElement{.JsonString=value};
|
||||
} else {
|
||||
@compileError("Unknown value type.");
|
||||
}
|
||||
},
|
||||
else => {
|
||||
@compileError("Unknown value type.");
|
||||
},
|
||||
@ -152,7 +160,7 @@ pub const JsonElement = union(JsonType) {
|
||||
|
||||
pub fn put(self: *const JsonElement, key: []const u8, value: anytype) !void {
|
||||
const result = createElementFromRandomType(value);
|
||||
try self.JsonObject.put(key, result);
|
||||
try self.JsonObject.put(try self.JsonObject.allocator.dupe(u8, key), result);
|
||||
}
|
||||
|
||||
pub fn free(self: *const JsonElement, allocator: Allocator) void {
|
||||
@ -185,7 +193,6 @@ pub const JsonElement = union(JsonType) {
|
||||
return self.* == JsonType.JsonNull;
|
||||
}
|
||||
|
||||
// TODO: toString()
|
||||
fn escape(string: []const u8, allocator: Allocator) ![]const u8 {
|
||||
var out = std.ArrayList(u8).init(allocator);
|
||||
for(string) |char| {
|
||||
|
@ -22,6 +22,7 @@ pub const c = @cImport ({
|
||||
});
|
||||
|
||||
pub threadlocal var threadAllocator: std.mem.Allocator = undefined;
|
||||
pub var globalAllocator: std.mem.Allocator = undefined;
|
||||
pub var threadPool: utils.ThreadPool = undefined;
|
||||
|
||||
var logFile: std.fs.File = undefined;
|
||||
@ -218,6 +219,11 @@ pub fn main() !void {
|
||||
defer if(gpa.deinit()) {
|
||||
@panic("Memory leak");
|
||||
};
|
||||
var global_gpa = std.heap.GeneralPurposeAllocator(.{.thread_safe=true}){};
|
||||
globalAllocator = global_gpa.allocator();
|
||||
defer if(global_gpa.deinit()) {
|
||||
@panic("Memory leak");
|
||||
};
|
||||
|
||||
// init logging.
|
||||
try std.fs.cwd().makePath("logs");
|
||||
|
@ -5,15 +5,19 @@ const assets = @import("assets.zig");
|
||||
const Block = @import("blocks.zig").Block;
|
||||
const chunk = @import("chunk.zig");
|
||||
const entity = @import("entity.zig");
|
||||
const items = @import("items.zig");
|
||||
const Inventory = items.Inventory;
|
||||
const ItemStack = items.ItemStack;
|
||||
const json = @import("json.zig");
|
||||
const main = @import("main.zig");
|
||||
const game = @import("game.zig");
|
||||
const settings = @import("settings.zig");
|
||||
const json = @import("json.zig");
|
||||
const JsonElement = json.JsonElement;
|
||||
const renderer = @import("renderer.zig");
|
||||
const utils = @import("utils.zig");
|
||||
const vec = @import("vec.zig");
|
||||
const Vec3d = vec.Vec3d;
|
||||
const Vec3f = vec.Vec3f;
|
||||
|
||||
//TODO: Might want to use SSL or something similar to encode the message
|
||||
|
||||
@ -977,7 +981,7 @@ pub const Protocols: struct {
|
||||
const type_itemStackDrop: u8 = 6;
|
||||
const type_itemStackCollect: u8 = 7;
|
||||
const type_timeAndBiome: u8 = 8;
|
||||
fn receive(_: *Connection, data: []const u8) !void {
|
||||
fn receive(conn: *Connection, data: []const u8) !void {
|
||||
switch(data[0]) {
|
||||
type_renderDistance => {
|
||||
const renderDistance = std.mem.readIntBig(i32, data[1..5]);
|
||||
@ -1047,18 +1051,18 @@ pub const Protocols: struct {
|
||||
// );
|
||||
},
|
||||
type_itemStackCollect => {
|
||||
// TODO:
|
||||
// JsonObject json = JsonParser.parseObjectFromString(new String(data, offset + 1, length - 1, StandardCharsets.UTF_8));
|
||||
// Item item = Item.load(json, Cubyz.world.registries);
|
||||
// if (item == null) {
|
||||
// break;
|
||||
// }
|
||||
// int remaining = Cubyz.player.getInventory_AND_DONT_FORGET_TO_SEND_CHANGES_TO_THE_SERVER().addItem(item, json.getInt("amount", 1));
|
||||
// sendInventory_full(Cubyz.world.serverConnection, Cubyz.player.getInventory_AND_DONT_FORGET_TO_SEND_CHANGES_TO_THE_SERVER());
|
||||
// if(remaining != 0) {
|
||||
// // Couldn't collect everything → drop it again.
|
||||
// itemStackDrop(Cubyz.world.serverConnection, new ItemStack(item, remaining), Cubyz.player.getPosition(), Camera.getDirection(), 0);
|
||||
// }
|
||||
const jsonObject = json.parseFromString(main.threadAllocator, data[1..]);
|
||||
defer jsonObject.free(main.threadAllocator);
|
||||
const item = try items.Item.init(jsonObject);
|
||||
game.Player.mutex.lock();
|
||||
defer game.Player.mutex.unlock();
|
||||
const remaining = game.Player.inventory__SEND_CHANGES_TO_SERVER.addItem(item, jsonObject.get(u16, "amount", 0));
|
||||
|
||||
try sendInventory_full(conn, game.Player.inventory__SEND_CHANGES_TO_SERVER);
|
||||
if(remaining != 0) {
|
||||
// Couldn't collect everything → drop it again.
|
||||
try itemStackDrop(conn, ItemStack{.item=item, .amount=remaining}, game.Player.getPosBlocking(), Vec3f{0, 0, 0}, 0);
|
||||
}
|
||||
},
|
||||
type_timeAndBiome => {
|
||||
if(game.world) |world| {
|
||||
@ -1134,10 +1138,14 @@ pub const Protocols: struct {
|
||||
try conn.sendImportant(id, &data);
|
||||
}
|
||||
|
||||
// TODO:
|
||||
// public void sendInventory_full(ServerConnection conn, Inventory inv) {
|
||||
// addHeaderAndSendImportant(conn, INVENTORY_FULL, inv.save().toString().getBytes(StandardCharsets.UTF_8));
|
||||
// }
|
||||
|
||||
pub fn sendInventory_full(conn: *Connection, inv: Inventory) !void {
|
||||
const jsonObject = try inv.save(main.threadAllocator);
|
||||
defer jsonObject.free(main.threadAllocator);
|
||||
const string = try jsonObject.toString(main.threadAllocator);
|
||||
defer main.threadAllocator.free(string);
|
||||
try addHeaderAndSendImportant(conn, type_inventoryFull, string);
|
||||
}
|
||||
|
||||
pub fn clearInventory(conn: *Connection) !void {
|
||||
var data: [1]u8 = undefined;
|
||||
@ -1145,23 +1153,28 @@ pub const Protocols: struct {
|
||||
try conn.sendImportant(id, &data);
|
||||
}
|
||||
|
||||
// TODO:
|
||||
// public void itemStackDrop(ServerConnection conn, ItemStack stack, Vector3d pos, Vector3f dir, float vel) {
|
||||
// JsonObject json = stack.store();
|
||||
// json.put("x", pos.x);
|
||||
// json.put("y", pos.y);
|
||||
// json.put("z", pos.z);
|
||||
// json.put("dirX", dir.x);
|
||||
// json.put("dirY", dir.y);
|
||||
// json.put("dirZ", dir.z);
|
||||
// json.put("vel", vel);
|
||||
// addHeaderAndSendImportant(conn, ITEM_STACK_DROP, json.toString().getBytes(StandardCharsets.UTF_8));
|
||||
// }
|
||||
pub fn itemStackDrop(conn: *Connection, stack: ItemStack, pos: Vec3d, dir: Vec3f, vel: f32) !void {
|
||||
var jsonObject = try stack.store(main.threadAllocator);
|
||||
defer jsonObject.free(main.threadAllocator);
|
||||
try jsonObject.put("x", pos[0]);
|
||||
try jsonObject.put("y", pos[1]);
|
||||
try jsonObject.put("z", pos[2]);
|
||||
try jsonObject.put("dirX", dir[0]);
|
||||
try jsonObject.put("dirY", dir[1]);
|
||||
try jsonObject.put("dirZ", dir[2]);
|
||||
try jsonObject.put("vel", vel);
|
||||
const string = try jsonObject.toString(main.threadAllocator);
|
||||
defer main.threadAllocator.free(string);
|
||||
try addHeaderAndSendImportant(conn, type_itemStackDrop, string);
|
||||
}
|
||||
|
||||
// TODO:
|
||||
// public void itemStackCollect(User user, ItemStack stack) {
|
||||
// addHeaderAndSendImportant(user, ITEM_STACK_COLLECT, stack.store().toString().getBytes(StandardCharsets.UTF_8));
|
||||
// }
|
||||
pub fn itemStackCollect(conn: *Connection, stack: ItemStack) !void {
|
||||
var jsonObject = try stack.store(main.threadAllocator);
|
||||
defer jsonObject.free(main.threadAllocator);
|
||||
const string = try jsonObject.toString(main.threadAllocator);
|
||||
defer main.threadAllocator.free(string);
|
||||
try addHeaderAndSendImportant(conn, type_itemStackCollect, string);
|
||||
}
|
||||
|
||||
// TODO:
|
||||
// public void sendTimeAndBiome(User user, ServerWorld world) {
|
||||
|
@ -10,16 +10,16 @@ pub fn scrambleSeed(seed: *u64) void {
|
||||
seed.* = (seed.* ^ multiplier) & mask;
|
||||
}
|
||||
|
||||
fn nextWithBitSize(T: type, seed: *u64, bitSize: u6) T {
|
||||
fn nextWithBitSize(comptime T: type, seed: *u64, bitSize: u6) T {
|
||||
seed.* = ((seed.*)*multiplier + addend) & mask;
|
||||
return @intCast(T, (seed >> (48 - bitSize)) & std.math.maxInt(T));
|
||||
return @intCast(T, (seed.* >> (48 - bitSize)) & std.math.maxInt(T));
|
||||
}
|
||||
|
||||
fn next(T: type, seed: *u64) T {
|
||||
nextWithBitSize(T, seed, @bitSizeOf(T));
|
||||
fn next(comptime T: type, seed: *u64) T {
|
||||
return nextWithBitSize(T, seed, @bitSizeOf(T));
|
||||
}
|
||||
|
||||
pub fn nextInt(T: type, seed: *u64) T {
|
||||
pub fn nextInt(comptime T: type, seed: *u64) T {
|
||||
if(@bitSizeOf(T) > 48) {
|
||||
@compileError("Did not yet implement support for bigger numbers.");
|
||||
} else {
|
||||
@ -27,8 +27,8 @@ pub fn nextInt(T: type, seed: *u64) T {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn nextIntBounded(T: type, seed: *u64, bound: T) T {
|
||||
var bitSize = std.math.log2_int_ceil(bound);
|
||||
pub fn nextIntBounded(comptime T: type, seed: *u64, bound: T) T {
|
||||
var bitSize = std.math.log2_int_ceil(T, bound);
|
||||
var result = nextWithBitSize(T, seed, bitSize);
|
||||
while(result >= bound) {
|
||||
result = nextWithBitSize(T, seed, bitSize);
|
||||
|
@ -877,7 +877,7 @@ pub const RenderStructure = struct {
|
||||
|
||||
pub fn getBlock(x: chunk.ChunkCoordinate, y: chunk.ChunkCoordinate, z: chunk.ChunkCoordinate) ?blocks.Block {
|
||||
const node = RenderStructure._getNode(.{.wx = x, .wy = y, .wz = z, .voxelSize=1}) orelse return null;
|
||||
const block = (node.mesh.chunk orelse return null).getBlock(x & chunk.chunkMask, y & chunk.chunkMask, z & chunk.chunkMask);
|
||||
const block = (node.mesh.chunk.load(.Monotonic) orelse return null).getBlock(x & chunk.chunkMask, y & chunk.chunkMask, z & chunk.chunkMask);
|
||||
return block;
|
||||
}
|
||||
|
||||
|
@ -22,8 +22,8 @@ pub fn length(self: anytype) @typeInfo(@TypeOf(self)).Vector.child {
|
||||
return @sqrt(@reduce(.Add, self*self));
|
||||
}
|
||||
|
||||
pub fn normalize(self: anytype) @typeInfo(@TypeOf(self)).Vector.child {
|
||||
return self/length(self);
|
||||
pub fn normalize(self: anytype) @TypeOf(self) {
|
||||
return self/@splat(@typeInfo(@TypeOf(self)).Vector.len, length(self));
|
||||
}
|
||||
|
||||
pub fn cross(self: anytype, other: @TypeOf(self)) @TypeOf(self) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user