mirror of
https://github.com/PixelGuys/Cubyz.git
synced 2025-08-03 19:28:49 -04:00
Store the player position on the server to prioritize terrain generation.
This commit is contained in:
parent
cfc7b903e6
commit
4d092126cc
14
src/game.zig
14
src/game.zig
@ -45,8 +45,7 @@ pub const camera = struct {
|
|||||||
};
|
};
|
||||||
|
|
||||||
pub const Player = struct {
|
pub const Player = struct {
|
||||||
pub var pos: Vec3d = Vec3d{0, 0, 0};
|
pub var super: main.server.Entity = .{};
|
||||||
pub var vel: Vec3d = Vec3d{0, 0, 0};
|
|
||||||
pub var id: u32 = 0;
|
pub var id: u32 = 0;
|
||||||
pub var isFlying: std.atomic.Atomic(bool) = std.atomic.Atomic(bool).init(true);
|
pub var isFlying: std.atomic.Atomic(bool) = std.atomic.Atomic(bool).init(true);
|
||||||
pub var mutex: std.Thread.Mutex = std.Thread.Mutex{};
|
pub var mutex: std.Thread.Mutex = std.Thread.Mutex{};
|
||||||
@ -56,26 +55,26 @@ pub const Player = struct {
|
|||||||
pub var health: f32 = 4.5;
|
pub var health: f32 = 4.5;
|
||||||
|
|
||||||
fn loadFrom(json: JsonElement) !void {
|
fn loadFrom(json: JsonElement) !void {
|
||||||
// TODO: super.loadFrom(json);
|
super.loadFrom(json);
|
||||||
try inventory__SEND_CHANGES_TO_SERVER.loadFromJson(json.getChild("inventory"));
|
try inventory__SEND_CHANGES_TO_SERVER.loadFromJson(json.getChild("inventory"));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn setPosBlocking(newPos: Vec3d) void {
|
pub fn setPosBlocking(newPos: Vec3d) void {
|
||||||
mutex.lock();
|
mutex.lock();
|
||||||
defer mutex.unlock();
|
defer mutex.unlock();
|
||||||
pos = newPos;
|
super.pos = newPos;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn getPosBlocking() Vec3d {
|
pub fn getPosBlocking() Vec3d {
|
||||||
mutex.lock();
|
mutex.lock();
|
||||||
defer mutex.unlock();
|
defer mutex.unlock();
|
||||||
return pos;
|
return super.pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn getVelBlocking() Vec3d {
|
pub fn getVelBlocking() Vec3d {
|
||||||
mutex.lock();
|
mutex.lock();
|
||||||
defer mutex.unlock();
|
defer mutex.unlock();
|
||||||
return vel;
|
return super.vel;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -152,7 +151,6 @@ pub const World = struct {
|
|||||||
// ModLoader.postWorldGen(registries);
|
// ModLoader.postWorldGen(registries);
|
||||||
try assets.loadWorldAssets("serverAssets", self.blockPalette);
|
try assets.loadWorldAssets("serverAssets", self.blockPalette);
|
||||||
try Player.loadFrom(json.getChild("player"));
|
try Player.loadFrom(json.getChild("player"));
|
||||||
Player.pos = .{-2000, 100, 4000}; // TODO
|
|
||||||
Player.id = json.get(u32, "player_id", std.math.maxInt(u32));
|
Player.id = json.get(u32, "player_id", std.math.maxInt(u32));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -347,7 +345,7 @@ pub fn update(deltaTime: f64) !void {
|
|||||||
{
|
{
|
||||||
Player.mutex.lock();
|
Player.mutex.lock();
|
||||||
defer Player.mutex.unlock();
|
defer Player.mutex.unlock();
|
||||||
Player.pos += movement*@splat(3, deltaTime);
|
Player.super.pos += movement*@splat(3, deltaTime);
|
||||||
}
|
}
|
||||||
try world.?.update();
|
try world.?.update();
|
||||||
}
|
}
|
@ -164,7 +164,11 @@ pub const JsonElement = union(JsonType) {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
else => {
|
else => {
|
||||||
@compileError("Unknown value type.");
|
if(@TypeOf(value) == JsonElement) {
|
||||||
|
return value;
|
||||||
|
} else {
|
||||||
|
@compileError("Unknown value type.");
|
||||||
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -538,7 +538,7 @@ pub fn main() !void {
|
|||||||
try renderer.init();
|
try renderer.init();
|
||||||
defer renderer.deinit();
|
defer renderer.deinit();
|
||||||
|
|
||||||
network.init();
|
try network.init();
|
||||||
|
|
||||||
try renderer.RenderStructure.init();
|
try renderer.RenderStructure.init();
|
||||||
defer renderer.RenderStructure.deinit();
|
defer renderer.RenderStructure.deinit();
|
||||||
|
@ -80,7 +80,7 @@ const Socket = struct {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn init() void {
|
pub fn init() !void {
|
||||||
try Socket.startup();
|
try Socket.startup();
|
||||||
inline for(@typeInfo(Protocols).Struct.decls) |decl| {
|
inline for(@typeInfo(Protocols).Struct.decls) |decl| {
|
||||||
if(@TypeOf(@field(Protocols, decl.name)) == type) {
|
if(@TypeOf(@field(Protocols, decl.name)) == type) {
|
||||||
@ -610,15 +610,16 @@ pub const Protocols = struct {
|
|||||||
try conn.user.?.initPlayer(name);
|
try conn.user.?.initPlayer(name);
|
||||||
const jsonObject = try JsonElement.initObject(main.threadAllocator);
|
const jsonObject = try JsonElement.initObject(main.threadAllocator);
|
||||||
defer jsonObject.free(main.threadAllocator);
|
defer jsonObject.free(main.threadAllocator);
|
||||||
|
try jsonObject.put("player", try conn.user.?.player.save(main.threadAllocator));
|
||||||
// TODO:
|
// TODO:
|
||||||
// jsonObject.put("player", ((User)conn).player.save());
|
|
||||||
// jsonObject.put("player_id", ((User)conn).player.id);
|
// jsonObject.put("player_id", ((User)conn).player.id);
|
||||||
// jsonObject.put("blockPalette", Server.world.blockPalette.save());
|
// jsonObject.put("blockPalette", Server.world.blockPalette.save());
|
||||||
// JsonObject spawn = new JsonObject();
|
const spawn = try JsonElement.initObject(main.threadAllocator);
|
||||||
// spawn.put("x", Server.world.spawn.x);
|
try spawn.put("x", main.server.world.?.spawn[0]);
|
||||||
// spawn.put("y", Server.world.spawn.y);
|
try spawn.put("y", main.server.world.?.spawn[1]);
|
||||||
// spawn.put("z", Server.world.spawn.z);
|
try spawn.put("z", main.server.world.?.spawn[2]);
|
||||||
// jsonObject.put("spawn", spawn);
|
try jsonObject.put("spawn", spawn);
|
||||||
|
|
||||||
const outData = try jsonObject.toStringEfficient(main.threadAllocator, &[1]u8{stepServerData});
|
const outData = try jsonObject.toStringEfficient(main.threadAllocator, &[1]u8{stepServerData});
|
||||||
defer main.threadAllocator.free(outData);
|
defer main.threadAllocator.free(outData);
|
||||||
try conn.sendImportant(id, outData);
|
try conn.sendImportant(id, outData);
|
||||||
@ -751,9 +752,7 @@ pub const Protocols = struct {
|
|||||||
pub const playerPosition = struct {
|
pub const playerPosition = struct {
|
||||||
const id: u8 = 4;
|
const id: u8 = 4;
|
||||||
fn receive(conn: *Connection, data: []const u8) !void {
|
fn receive(conn: *Connection, data: []const u8) !void {
|
||||||
_ = conn;
|
conn.user.?.receiveData(data);
|
||||||
_ = data;
|
|
||||||
// TODO: ((User)conn).receiveData(data, offset);
|
|
||||||
}
|
}
|
||||||
var lastPositionSent: u16 = 0;
|
var lastPositionSent: u16 = 0;
|
||||||
pub fn send(conn: *Connection, playerPos: Vec3d, playerVel: Vec3d, time: u16) !void {
|
pub fn send(conn: *Connection, playerPos: Vec3d, playerVel: Vec3d, time: u16) !void {
|
||||||
@ -1053,7 +1052,7 @@ pub const Protocols = struct {
|
|||||||
try sendInventory_full(conn, game.Player.inventory__SEND_CHANGES_TO_SERVER);
|
try sendInventory_full(conn, game.Player.inventory__SEND_CHANGES_TO_SERVER);
|
||||||
if(remaining != 0) {
|
if(remaining != 0) {
|
||||||
// Couldn't collect everything → drop it again.
|
// Couldn't collect everything → drop it again.
|
||||||
try itemStackDrop(conn, ItemStack{.item=item, .amount=remaining}, game.Player.pos, Vec3f{0, 0, 0}, 0);
|
try itemStackDrop(conn, ItemStack{.item=item, .amount=remaining}, game.Player.super.pos, Vec3f{0, 0, 0}, 0);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
type_timeAndBiome => {
|
type_timeAndBiome => {
|
||||||
@ -1167,13 +1166,15 @@ pub const Protocols = struct {
|
|||||||
try addHeaderAndSendImportant(conn, type_itemStackCollect, string);
|
try addHeaderAndSendImportant(conn, type_itemStackCollect, string);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO:
|
pub fn sendTimeAndBiome(conn: *Connection, world: *const main.server.ServerWorld) !void {
|
||||||
// public void sendTimeAndBiome(User user, ServerWorld world) {
|
var json = try JsonElement.initObject(main.threadAllocator);
|
||||||
// JsonObject data = new JsonObject();
|
defer json.free(main.threadAllocator);
|
||||||
// data.put("time", world.gameTime);
|
try json.put("time", world.gameTime);
|
||||||
// data.put("biome", world.getBiome((int)user.player.getPosition().x, (int)user.player.getPosition().y, (int)user.player.getPosition().z).getRegistryID().toString());
|
// TODO: json.put("biome", world.getBiome((int)user.player.getPosition().x, (int)user.player.getPosition().y, (int)user.player.getPosition().z).getRegistryID().toString());
|
||||||
// addHeaderAndSendUnimportant(user, TIME_AND_BIOME, data.toString().getBytes(StandardCharsets.UTF_8));
|
const string = try json.toString(main.threadAllocator);
|
||||||
// }
|
defer main.threadAllocator.free(string);
|
||||||
|
try addHeaderAndSendUnimportant(conn, type_timeAndBiome, string);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
pub const chat = struct {
|
pub const chat = struct {
|
||||||
const id: u8 = 10;
|
const id: u8 = 10;
|
||||||
|
511
src/server/Entity.zig
Normal file
511
src/server/Entity.zig
Normal file
@ -0,0 +1,511 @@
|
|||||||
|
const std = @import("std");
|
||||||
|
const Allocator = std.mem.Allocator;
|
||||||
|
|
||||||
|
const main = @import("root");
|
||||||
|
const JsonElement = main.JsonElement;
|
||||||
|
const vec = main.vec;
|
||||||
|
const Vec3f = vec.Vec3f;
|
||||||
|
const Vec3d = vec.Vec3d;
|
||||||
|
|
||||||
|
pos: Vec3d = .{0, 0, 0},
|
||||||
|
vel: Vec3d = .{0, 0, 0},
|
||||||
|
rot: Vec3f = .{0, 0, 0},
|
||||||
|
|
||||||
|
fn loadVec3f(json: JsonElement) Vec3f {
|
||||||
|
return .{
|
||||||
|
json.get(f32, "x", 0),
|
||||||
|
json.get(f32, "y", 0),
|
||||||
|
json.get(f32, "z", 0),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
fn loadVec3d(json: JsonElement) Vec3d {
|
||||||
|
return .{
|
||||||
|
json.get(f64, "x", 0),
|
||||||
|
json.get(f64, "y", 0),
|
||||||
|
json.get(f64, "z", 0),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
fn saveVec3(allocator: Allocator, vector: anytype) !JsonElement {
|
||||||
|
const json = try JsonElement.initObject(allocator);
|
||||||
|
try json.put("x", vector[0]);
|
||||||
|
try json.put("y", vector[1]);
|
||||||
|
try json.put("z", vector[2]);
|
||||||
|
return json;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn loadFrom(self: *@This(), json: JsonElement) void {
|
||||||
|
self.pos = loadVec3d(json.getChild("position"));
|
||||||
|
self.vel = loadVec3d(json.getChild("velocity"));
|
||||||
|
self.rot = loadVec3f(json.getChild("rotation"));
|
||||||
|
// TODO:
|
||||||
|
// health = json.getFloat("health", maxHealth);
|
||||||
|
// hunger = json.getFloat("hunger", maxHunger);
|
||||||
|
// name = json.getString("name", "");
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn save(self: *@This(), allocator: Allocator) !JsonElement {
|
||||||
|
const json = try JsonElement.initObject(allocator);
|
||||||
|
// TODO: json.put("id", type.getRegistryID().toString());
|
||||||
|
try json.put("position", try saveVec3(allocator, self.pos));
|
||||||
|
try json.put("velocity", try saveVec3(allocator, self.vel));
|
||||||
|
try json.put("rotation", try saveVec3(allocator, self.rot));
|
||||||
|
// TODO:
|
||||||
|
// json.put("health", health);
|
||||||
|
// json.put("hunger", hunger);
|
||||||
|
// if(!name.isEmpty()) {
|
||||||
|
// json.put("name", name);
|
||||||
|
// }
|
||||||
|
return json;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Entity {
|
||||||
|
|
||||||
|
// protected World world;
|
||||||
|
// public double targetVX, targetVZ; // The velocity the AI wants the entity to have.
|
||||||
|
|
||||||
|
// protected double scale = 1f;
|
||||||
|
// public final double stepHeight;
|
||||||
|
|
||||||
|
// private final EntityType type;
|
||||||
|
|
||||||
|
// private final EntityAI entityAI;
|
||||||
|
|
||||||
|
// public float health, hunger;
|
||||||
|
// public final float maxHealth, maxHunger;
|
||||||
|
|
||||||
|
// public int id;
|
||||||
|
|
||||||
|
// public String name = "";
|
||||||
|
|
||||||
|
// private static int currentID = 0;
|
||||||
|
|
||||||
|
// /**
|
||||||
|
// * Used as hitbox.
|
||||||
|
// */
|
||||||
|
// public double width = CubyzMath.roundToAvoidPrecisionProblems(0.35), height = CubyzMath.roundToAvoidPrecisionProblems(1.8); // TODO: Make this a proper interface or switch to fixed-point arithmetic.
|
||||||
|
// /**
|
||||||
|
// * @param type
|
||||||
|
// * @param ai
|
||||||
|
// * @param world
|
||||||
|
// * @param maxHealth
|
||||||
|
// * @param maxHunger
|
||||||
|
// * @param stepHeight height the entity can move upwards without jumping.
|
||||||
|
// */
|
||||||
|
// public Entity(EntityType type, EntityAI ai, World world, float maxHealth, float maxHunger, float stepHeight) {
|
||||||
|
// this.type = type;
|
||||||
|
// this.world = world;
|
||||||
|
// this.maxHealth = health = maxHealth;
|
||||||
|
// this.maxHunger = hunger = maxHunger;
|
||||||
|
// this.stepHeight = stepHeight;
|
||||||
|
// entityAI = ai;
|
||||||
|
|
||||||
|
// id = currentID++;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// public double getScale() {
|
||||||
|
// return scale;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// /**
|
||||||
|
// * Checks collision against all blocks within the hitbox and updates positions.
|
||||||
|
// * @return The height of the step taken. Needed for hunger calculations.
|
||||||
|
// */
|
||||||
|
// protected double collisionDetection(float deltaTime) {
|
||||||
|
// // Simulate movement in all directions and prevent movement in a direction that would get the player into a block:
|
||||||
|
// int minX = (int)Math.floor(position.x - width);
|
||||||
|
// int maxX = (int)Math.ceil(position.x + width) - 1;
|
||||||
|
// int minY = (int)Math.floor(position.y);
|
||||||
|
// int maxY = (int)Math.ceil(position.y + height) - 1;
|
||||||
|
// int minZ = (int)Math.floor(position.z - width);
|
||||||
|
// int maxZ = (int)Math.ceil(position.z + width) - 1;
|
||||||
|
// double deltaX = vx*deltaTime;
|
||||||
|
// double deltaY = vy*deltaTime;
|
||||||
|
// double deltaZ = vz*deltaTime;
|
||||||
|
// Vector4d change = new Vector4d(deltaX, 0, 0, 0);
|
||||||
|
// double step = 0.0f;
|
||||||
|
// if (deltaX < 0) {
|
||||||
|
// int minX2 = (int)Math.floor(position.x - width + deltaX);
|
||||||
|
// // First check for partial blocks:
|
||||||
|
// for(int y = minY; y <= maxY; y++) {
|
||||||
|
// for(int z = minZ; z <= maxZ; z++) {
|
||||||
|
// checkBlock(minX, y, z, change);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// if (minX2 != minX && deltaX == change.x) {
|
||||||
|
// outer:
|
||||||
|
// for(int y = minY; y <= maxY; y++) {
|
||||||
|
// for(int z = minZ; z <= maxZ; z++) {
|
||||||
|
// if (checkBlock(minX2, y, z, change)) {
|
||||||
|
// change.x = 0;
|
||||||
|
// position.x = minX2 + 1 + width;
|
||||||
|
// break outer;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// } else if (deltaX > 0) {
|
||||||
|
// int maxX2 = (int)Math.floor(position.x + width + deltaX);
|
||||||
|
// // First check for partial blocks:
|
||||||
|
// for(int y = minY; y <= maxY; y++) {
|
||||||
|
// for(int z = minZ; z <= maxZ; z++) {
|
||||||
|
// checkBlock(maxX, y, z, change);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// if (maxX2 != maxX && deltaX == change.x) {
|
||||||
|
// outer:
|
||||||
|
// for(int y = minY; y <= maxY; y++) {
|
||||||
|
// for(int z = minZ; z <= maxZ; z++) {
|
||||||
|
// if (checkBlock(maxX2, y, z, change)) {
|
||||||
|
// change.x = 0;
|
||||||
|
// position.x = maxX2 - width;
|
||||||
|
// break outer;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// position.x += change.x;
|
||||||
|
// if (deltaX != change.x) {
|
||||||
|
// vx = 0;
|
||||||
|
// change.w = 0; // Don't step if the player walks into a wall.
|
||||||
|
// }
|
||||||
|
// step = Math.max(step, change.w);
|
||||||
|
// change.x = 0;
|
||||||
|
// change.y = deltaY;
|
||||||
|
// minX = (int)Math.floor(position.x - width);
|
||||||
|
// maxX = (int)Math.ceil(position.x + width) - 1;
|
||||||
|
// if (deltaY < 0) {
|
||||||
|
// int minY2 = (int)Math.floor(position.y + deltaY);
|
||||||
|
// // First check for partial blocks:
|
||||||
|
// for(int x = minX; x <= maxX; x++) {
|
||||||
|
// for(int z = minZ; z <= maxZ; z++) {
|
||||||
|
// checkBlock(x, minY, z, change);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// if (minY2 != minY && deltaY == change.y) {
|
||||||
|
// outer:
|
||||||
|
// for(int x = minX; x <= maxX; x++) {
|
||||||
|
// for(int z = minZ; z <= maxZ; z++) {
|
||||||
|
// if (checkBlock(x, minY2, z, change)) {
|
||||||
|
// change.y = 0;
|
||||||
|
// position.y = minY2 + 1;
|
||||||
|
// break outer;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// } else if (deltaY > 0) {
|
||||||
|
// int maxY2 = (int)Math.floor(position.y + height + deltaY);
|
||||||
|
// // First check for partial blocks:
|
||||||
|
// for(int x = minX; x <= maxX; x++) {
|
||||||
|
// for(int z = minZ; z <= maxZ; z++) {
|
||||||
|
// checkBlock(x, maxY, z, change);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// if (maxY2 != maxY && deltaY == change.y) {
|
||||||
|
// outer:
|
||||||
|
// for(int x = minX; x <= maxX; x++) {
|
||||||
|
// for(int z = minZ; z <= maxZ; z++) {
|
||||||
|
// if (checkBlock(x, maxY2, z, change)) {
|
||||||
|
// change.y = 0;
|
||||||
|
// position.y = maxY2 - height;
|
||||||
|
// break outer;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// position.y += change.y;
|
||||||
|
// if (deltaY != change.y) {
|
||||||
|
// stopVY();
|
||||||
|
// }
|
||||||
|
// change.w = 0; // Don't step in y-direction.
|
||||||
|
// step = Math.max(step, change.w);
|
||||||
|
// change.y = 0;
|
||||||
|
// change.z = deltaZ;
|
||||||
|
// minY = (int)Math.floor(position.y);
|
||||||
|
// maxY = (int)Math.ceil(position.y + height) - 1;
|
||||||
|
// if (deltaZ < 0) {
|
||||||
|
// int minZ2 = (int)Math.floor(position.z - width + deltaZ);
|
||||||
|
// // First check for partial blocks:
|
||||||
|
// for(int x = minX; x <= maxX; x++) {
|
||||||
|
// for(int y = minY; y <= maxY; y++) {
|
||||||
|
// checkBlock(x, y, minZ, change);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// if (minZ2 != minZ && change.z == deltaZ) {
|
||||||
|
// outer:
|
||||||
|
// for(int x = minX; x <= maxX; x++) {
|
||||||
|
// for(int y = minY; y <= maxY; y++) {
|
||||||
|
// if (checkBlock(x, y, minZ2, change)) {
|
||||||
|
// change.z = 0;
|
||||||
|
// position.z = minZ2 + 1 + width;
|
||||||
|
// break outer;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// } else if (deltaZ > 0) {
|
||||||
|
// int maxZ2 = (int)Math.floor(position.z + width + deltaZ);
|
||||||
|
// // First check for partial blocks:
|
||||||
|
// for(int x = minX; x <= maxX; x++) {
|
||||||
|
// for(int y = minY; y <= maxY; y++) {
|
||||||
|
// checkBlock(x, y, maxZ, change);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// if (maxZ2 != maxZ && deltaZ == change.z) {
|
||||||
|
// outer:
|
||||||
|
// for(int x = minX; x <= maxX; x++) {
|
||||||
|
// for(int y = minY; y <= maxY; y++) {
|
||||||
|
// if (checkBlock(x, y, maxZ2, change)) {
|
||||||
|
// change.z = 0;
|
||||||
|
// position.z = maxZ2 - width;
|
||||||
|
// break outer;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// position.z += change.z;
|
||||||
|
// if (deltaZ != change.z) {
|
||||||
|
// vz = 0;
|
||||||
|
// change.w = 0; // Don't step if the player walks into a wall.
|
||||||
|
// }
|
||||||
|
// step = Math.max(step, change.w);
|
||||||
|
// // And finally consider the stepping component:
|
||||||
|
// position.y += step;
|
||||||
|
// if (step != 0) vy = 0;
|
||||||
|
// return step;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// /**
|
||||||
|
// * All damage taken should get channeled through this function to remove redundant checks if the entity is dead.
|
||||||
|
// * @param amount
|
||||||
|
// */
|
||||||
|
// public void takeDamage(float amount) {
|
||||||
|
// health -= amount;
|
||||||
|
// if (health <= 0) {
|
||||||
|
// type.die(this);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// public void stopVY() {
|
||||||
|
// takeDamage(calculateFallDamage());
|
||||||
|
// vy = 0;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// public int calculateFallDamage() {
|
||||||
|
// if (vy < 0)
|
||||||
|
// return (int)(8*vy*vy/900);
|
||||||
|
// return 0;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// public boolean checkBlock(int x, int y, int z, Vector4d displacement) {
|
||||||
|
// int b = getBlock(x, y, z);
|
||||||
|
// if (b != 0 && Blocks.solid(b)) {
|
||||||
|
// if (Blocks.mode(b).changesHitbox()) {
|
||||||
|
// return Blocks.mode(b).checkEntityAndDoCollision(this, displacement, x, y, z, b);
|
||||||
|
// }
|
||||||
|
// // Check for stepping:
|
||||||
|
// if (y + 1 - position.y > 0 && y + 1 - position.y <= stepHeight) {
|
||||||
|
// displacement.w = Math.max(displacement.w, y + 1 - position.y);
|
||||||
|
// return false;
|
||||||
|
// }
|
||||||
|
// return true;
|
||||||
|
// }
|
||||||
|
// return false;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// protected int getBlock(int x, int y, int z) {
|
||||||
|
// return world.getBlock(x, y, z);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// public boolean checkBlock(int x, int y, int z) {
|
||||||
|
// int b = getBlock(x, y, z);
|
||||||
|
// if (b != 0 && Blocks.solid(b)) {
|
||||||
|
// if (Blocks.mode(b).changesHitbox()) {
|
||||||
|
// return Blocks.mode(b).checkEntity(position, width, height, x, y, z, b);
|
||||||
|
// }
|
||||||
|
// return true;
|
||||||
|
// }
|
||||||
|
// return false;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// public boolean isOnGround() {
|
||||||
|
// // Determine if the entity is on the ground by virtually displacing it by 0.2 below its current position:
|
||||||
|
// Vector4d displacement = new Vector4d(0, -0.2f, 0, 0);
|
||||||
|
// checkBlock((int)Math.floor(position.x), (int)Math.floor(position.y), (int)Math.floor(position.z), displacement);
|
||||||
|
// if (checkBlock((int)Math.floor(position.x), (int)Math.floor(position.y + displacement.y), (int)Math.floor(position.z), displacement)) {
|
||||||
|
// return true;
|
||||||
|
// }
|
||||||
|
// return displacement.y != -0.2f || displacement.w != 0;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// public void hit(Tool weapon, Vector3f direction) {
|
||||||
|
// if (weapon == null) {
|
||||||
|
// takeDamage(1);
|
||||||
|
// vx += direction.x*0.2;
|
||||||
|
// vy += direction.y*0.2;
|
||||||
|
// vz += direction.z*0.2;
|
||||||
|
// } else {
|
||||||
|
// takeDamage(weapon.getDamage());
|
||||||
|
// // TODO: Weapon specific knockback.
|
||||||
|
// vx += direction.x*0.2;
|
||||||
|
// vy += direction.y*0.2;
|
||||||
|
// vz += direction.z*0.2;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// public void update(float deltaTime) {
|
||||||
|
// double step = collisionDetection(deltaTime);
|
||||||
|
// if (entityAI != null)
|
||||||
|
// entityAI.update(this);
|
||||||
|
// updateVelocity(deltaTime);
|
||||||
|
|
||||||
|
// // clamp health between 0 and maxHealth
|
||||||
|
// if (health < 0)
|
||||||
|
// health = 0;
|
||||||
|
// if (health > maxHealth)
|
||||||
|
// health = maxHealth;
|
||||||
|
|
||||||
|
// if (maxHunger > 0) {
|
||||||
|
// hungerMechanics((float)step, deltaTime);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// double oldVY = 0;
|
||||||
|
// /**
|
||||||
|
// * Simulates the hunger system. TODO: Make dependent on mass
|
||||||
|
// * @param step How high the entity stepped in this update cycle.
|
||||||
|
// */
|
||||||
|
// protected void hungerMechanics(float step, float deltaTime) {
|
||||||
|
// // Passive energy consumption:
|
||||||
|
// hunger -= 0.00013333*deltaTime; // Will deplete hunger after 22 minutes of standing still.
|
||||||
|
// // Energy consumption due to movement:
|
||||||
|
// hunger -= (vx*vx + vz*vz)/900/16*deltaTime;
|
||||||
|
|
||||||
|
// // Jumping:
|
||||||
|
// if (oldVY < vy) { // Only care about positive changes.
|
||||||
|
// // Determine the difference in "signed" kinetic energy.
|
||||||
|
// double deltaE = vy*vy*Math.signum(vy) - oldVY*oldVY*Math.signum(oldVY);
|
||||||
|
// hunger -= (float)deltaE/900;
|
||||||
|
// }
|
||||||
|
// oldVY = vy;
|
||||||
|
|
||||||
|
// // Stepping: Consider potential energy of the step taken V = m·g·h
|
||||||
|
// hunger -= World.GRAVITY*step/900;
|
||||||
|
// hunger = Math.max(0, hunger);
|
||||||
|
|
||||||
|
// // Examples:
|
||||||
|
// // At 3 blocks/second(player base speed) the cost of movement is about twice as high as the passive consumption.
|
||||||
|
// // So when walking on a flat ground in one direction without sprinting the hunger bar will be empty after 22/3≈7 minutes.
|
||||||
|
// // When sprinting however the speed is twice as high, so the energy consumption is 4 times higher, meaning the hunger will be empty after only 2 minutes.
|
||||||
|
// // Jumping takes 0.05 hunger on jump and on land.
|
||||||
|
|
||||||
|
// // Heal if hunger is more than half full:
|
||||||
|
// if (hunger > maxHunger/2 && health < maxHealth) {
|
||||||
|
// // Maximum healing effect is 1% maxHealth per second:
|
||||||
|
// float healing = Math.min(maxHealth*deltaTime*0.01f, maxHealth-health);
|
||||||
|
// health += healing;
|
||||||
|
// hunger -= healing;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// protected void updateVelocity(float deltaTime) {
|
||||||
|
// // TODO: Use the entities mass, force and ground structure to calculate a realistic velocity change.
|
||||||
|
// vx += (targetVX-vx)/5*deltaTime;
|
||||||
|
// vz += (targetVZ-vz)/5*deltaTime;
|
||||||
|
// vy -= World.GRAVITY*deltaTime;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // NDT related
|
||||||
|
|
||||||
|
// public EntityType getType() {
|
||||||
|
// return type;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// public World getWorld() {
|
||||||
|
// return world;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// public Vector3d getPosition() {
|
||||||
|
// return position;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// public void setPosition(Vector3i position) {
|
||||||
|
// this.position.x = position.x;
|
||||||
|
// this.position.y = position.y;
|
||||||
|
// this.position.z = position.z;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// public void setPosition(Vector3d position) {
|
||||||
|
// this.position = position;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// public Vector3f getRotation() {
|
||||||
|
// return rotation;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// public void setRotation(Vector3f rotation) {
|
||||||
|
// this.rotation = rotation;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// public Inventory getInventory() {
|
||||||
|
// return null;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// public static boolean aabCollision(double x1, double y1, double z1, double w1, double h1, double d1, double x2, double y2, double z2, double w2, double h2, double d2) {
|
||||||
|
// return x1 + w1 >= x2
|
||||||
|
// && x1 <= x2 + w2
|
||||||
|
// && y1 + h1 >= y2
|
||||||
|
// && y1 <= y2 + h2
|
||||||
|
// && z1 + d1 >= z2
|
||||||
|
// && z1 <= z2 + d2;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// /**
|
||||||
|
// * @param vel
|
||||||
|
// * @param x0
|
||||||
|
// * @param y0
|
||||||
|
// * @param z0
|
||||||
|
// * @param w width in x direction
|
||||||
|
// * @param h height in y direction
|
||||||
|
// * @param d depth in z direction
|
||||||
|
// * @param block
|
||||||
|
// * @return
|
||||||
|
// */
|
||||||
|
// public void aabCollision(Vector4d vel, double x0, double y0, double z0, double w, double h, double d, int block) {
|
||||||
|
// // check if the displacement is inside the box:
|
||||||
|
// if (aabCollision(position.x - width + vel.x, position.y + vel.y, position.z - width + vel.z, width*2, height, width*2, x0, y0, z0, w, h, d)) {
|
||||||
|
// // Check if the entity can step on it:
|
||||||
|
// if (y0 + h - position.y > 0 && y0 + h - position.y <= stepHeight) {
|
||||||
|
// vel.w = Math.max(vel.w, y0 + h - position.y);
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
// // Only collide if the previous position was outside:
|
||||||
|
// if (!aabCollision(position.x - width, position.y, position.z - width, width*2, height, width*2, x0, y0, z0, w, h, d)) {
|
||||||
|
// // Check in which direction the current displacement goes and changes accordingly:
|
||||||
|
// if (vel.x < 0) {
|
||||||
|
// vel.x = x0 + w - (position.x - width) + 0.01f;
|
||||||
|
// } else if (vel.x > 0) {
|
||||||
|
// vel.x = x0 - (position.x + width) - 0.01f;
|
||||||
|
// }
|
||||||
|
// else if (vel.y < 0) {
|
||||||
|
// vel.y = y0 + h - (position.y) + 0.01f;
|
||||||
|
// }
|
||||||
|
// else if (vel.y > 0) {
|
||||||
|
// vel.y = y0 - (position.y + height) - 0.01f;
|
||||||
|
// }
|
||||||
|
// else if (vel.z < 0) {
|
||||||
|
// vel.z = z0 + d - (position.z - width) + 0.01f;
|
||||||
|
// } else if (vel.z > 0) {
|
||||||
|
// vel.z = z0 - (position.z + width) - 0.01f;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// }
|
||||||
|
|
||||||
|
// }
|
@ -10,11 +10,12 @@ const Vec3d = vec.Vec3d;
|
|||||||
|
|
||||||
pub const ServerWorld = @import("world.zig").ServerWorld;
|
pub const ServerWorld = @import("world.zig").ServerWorld;
|
||||||
pub const terrain = @import("terrain/terrain.zig");
|
pub const terrain = @import("terrain/terrain.zig");
|
||||||
|
pub const Entity = @import("Entity.zig");
|
||||||
|
|
||||||
|
|
||||||
pub const User = struct {
|
pub const User = struct {
|
||||||
conn: *Connection,
|
conn: *Connection,
|
||||||
//TODO: public Player player;
|
player: Entity = .{},
|
||||||
timeDifference: utils.TimeDifference = .{},
|
timeDifference: utils.TimeDifference = .{},
|
||||||
interpolation: utils.GenericInterpolation(3) = undefined,
|
interpolation: utils.GenericInterpolation(3) = undefined,
|
||||||
lastTime: i16 = undefined,
|
lastTime: i16 = undefined,
|
||||||
@ -22,8 +23,6 @@ pub const User = struct {
|
|||||||
renderDistance: u16 = undefined,
|
renderDistance: u16 = undefined,
|
||||||
lodFactor: f32 = undefined,
|
lodFactor: f32 = undefined,
|
||||||
receivedFirstEntityData: bool = false,
|
receivedFirstEntityData: bool = false,
|
||||||
pos: [3]f64 = undefined, // TODO: Use position from te entity.
|
|
||||||
vel: [3]f64 = undefined,
|
|
||||||
// TODO: ipPort: []const u8,
|
// TODO: ipPort: []const u8,
|
||||||
// TODO: public Thread waitingThread;
|
// TODO: public Thread waitingThread;
|
||||||
|
|
||||||
@ -33,8 +32,7 @@ pub const User = struct {
|
|||||||
.conn = try Connection.init(manager, ipPort),
|
.conn = try Connection.init(manager, ipPort),
|
||||||
};
|
};
|
||||||
self.conn.user = self;
|
self.conn.user = self;
|
||||||
self.interpolation.init(&self.pos, &self.vel);
|
self.interpolation.init(@ptrCast(*[3]f64, &self.player.pos), @ptrCast(*[3]f64, &self.player.vel));
|
||||||
// TODO: self.interpolation.init(&player.pos, &player.vel);
|
|
||||||
network.Protocols.handShake.serverSide(self.conn);
|
network.Protocols.handShake.serverSide(self.conn);
|
||||||
// TODO:
|
// TODO:
|
||||||
// synchronized(this) {
|
// synchronized(this) {
|
||||||
@ -58,28 +56,13 @@ pub const User = struct {
|
|||||||
|
|
||||||
pub fn initPlayer(self: *User, name: []const u8) !void {
|
pub fn initPlayer(self: *User, name: []const u8) !void {
|
||||||
self.name = try main.globalAllocator.dupe(u8, name);
|
self.name = try main.globalAllocator.dupe(u8, name);
|
||||||
// TODO:
|
try world.?.findPlayer(self);
|
||||||
// assert(player == null);
|
|
||||||
// player = Server.world.findPlayer(this);
|
|
||||||
// interpolation.outPosition[0] = player.getPosition().x;
|
|
||||||
// interpolation.outPosition[1] = player.getPosition().y;
|
|
||||||
// interpolation.outPosition[2] = player.getPosition().z;
|
|
||||||
// interpolation.outVelocity[0] = player.vx;
|
|
||||||
// interpolation.outVelocity[1] = player.vy;
|
|
||||||
// interpolation.outVelocity[2] = player.vz;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update(self: *User) void {
|
pub fn update(self: *User) void {
|
||||||
var time = @truncate(i16, std.time.milliTimestamp()) -% main.settings.entityLookback;
|
var time = @truncate(i16, std.time.milliTimestamp()) -% main.settings.entityLookback;
|
||||||
time -= self.timeDifference.difference.load(.Monotonic);
|
time -= self.timeDifference.difference.load(.Monotonic);
|
||||||
self.interpolation.update(time, self.lastTime);
|
self.interpolation.update(time, self.lastTime);
|
||||||
// TODO:
|
|
||||||
// player.getPosition().x = interpolation.outPosition[0];
|
|
||||||
// player.getPosition().y = interpolation.outPosition[1];
|
|
||||||
// player.getPosition().z = interpolation.outPosition[2];
|
|
||||||
// player.vx = interpolation.outVelocity[0];
|
|
||||||
// player.vy = interpolation.outVelocity[1];
|
|
||||||
// player.vz = interpolation.outVelocity[2];
|
|
||||||
self.lastTime = time;
|
self.lastTime = time;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -99,8 +82,7 @@ pub const User = struct {
|
|||||||
@bitCast(f32, std.mem.readIntBig(u32, data[52..56])),
|
@bitCast(f32, std.mem.readIntBig(u32, data[52..56])),
|
||||||
@bitCast(f32, std.mem.readIntBig(u32, data[56..60])),
|
@bitCast(f32, std.mem.readIntBig(u32, data[56..60])),
|
||||||
};
|
};
|
||||||
_ = rotation;
|
self.player.rot = rotation;
|
||||||
// TODO: player.getRotation().set(rotation);
|
|
||||||
const time = std.mem.readIntBig(i16, data[60..62]);
|
const time = std.mem.readIntBig(i16, data[60..62]);
|
||||||
self.timeDifference.addDataPoint(time);
|
self.timeDifference.addDataPoint(time);
|
||||||
self.interpolation.updatePosition(&position, &velocity, time);
|
self.interpolation.updatePosition(&position, &velocity, time);
|
||||||
@ -156,7 +138,7 @@ fn deinit() void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn update() !void {
|
fn update() !void {
|
||||||
world.?.update();
|
try world.?.update();
|
||||||
mutex.lock();
|
mutex.lock();
|
||||||
for(users.items) |user| {
|
for(users.items) |user| {
|
||||||
user.update();
|
user.update();
|
||||||
|
@ -20,6 +20,7 @@ const terrain = server.terrain;
|
|||||||
|
|
||||||
const server = @import("server.zig");
|
const server = @import("server.zig");
|
||||||
const User = server.User;
|
const User = server.User;
|
||||||
|
const Entity = server.Entity;
|
||||||
|
|
||||||
const ChunkManager = struct {
|
const ChunkManager = struct {
|
||||||
world: *ServerWorld,
|
world: *ServerWorld,
|
||||||
@ -52,9 +53,11 @@ const ChunkManager = struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn getPriority(self: *ChunkLoadTask) f32 {
|
pub fn getPriority(self: *ChunkLoadTask) f32 {
|
||||||
_ = self;
|
if(self.source) |user| {
|
||||||
return 0;
|
return self.pos.getPriority(user.player.pos);
|
||||||
// TODO: return self.pos.getPriority(self.source.player.getPosBlocking()); // TODO: This is called in loop, find a way to do this without calling the mutex every time.
|
} else {
|
||||||
|
return std.math.floatMax(f32);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn isStillNeeded(self: *ChunkLoadTask) bool {
|
pub fn isStillNeeded(self: *ChunkLoadTask) bool {
|
||||||
@ -74,19 +77,20 @@ const ChunkManager = struct {
|
|||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
if(std.time.milliTimestamp() - self.creationTime > 10000) { // Only remove stuff after 10 seconds to account for trouble when for example teleporting.
|
if(std.time.milliTimestamp() - self.creationTime > 10000) { // Only remove stuff after 10 seconds to account for trouble when for example teleporting.
|
||||||
// TODO:
|
server.mutex.lock();
|
||||||
// for(User user : Server.users) {
|
defer server.mutex.unlock();
|
||||||
// double minDistSquare = ch.getMinDistanceSquared(user.player.getPosition().x, user.player.getPosition().y, user.player.getPosition().z);
|
for(server.users.items) |user| {
|
||||||
// // ↓ Margin for error. (diagonal of 1 chunk)
|
const minDistSquare = self.pos.getMinDistanceSquared(user.player.pos);
|
||||||
// double targetRenderDistance = (user.renderDistance*Chunk.chunkSize + Chunk.chunkSize*Math.sqrt(3));//*Math.pow(user.LODFactor, Math.log(ch.voxelSize)/Math.log(2));
|
// ↓ Margin for error. (diagonal of 1 chunk)
|
||||||
// if(ch.voxelSize != 1) {
|
var targetRenderDistance = (@intToFloat(f32, user.renderDistance*chunk.chunkSize) + @intToFloat(f32, chunk.chunkSize)*@sqrt(3.0));
|
||||||
// targetRenderDistance *= ch.voxelSize*user.LODFactor;
|
if(self.pos.voxelSize != 1) {
|
||||||
// }
|
targetRenderDistance *= @intToFloat(f32, self.pos.voxelSize)*user.lodFactor;
|
||||||
// if(minDistSquare <= targetRenderDistance*targetRenderDistance) {
|
}
|
||||||
// return true;
|
if(minDistSquare <= targetRenderDistance*targetRenderDistance) {
|
||||||
// }
|
return true;
|
||||||
// }
|
}
|
||||||
// return false;
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -361,26 +365,27 @@ pub const ServerWorld = struct {
|
|||||||
std.log.info("Trying ({}, {})", .{self.spawn[0], self.spawn[2]});
|
std.log.info("Trying ({}, {})", .{self.spawn[0], self.spawn[2]});
|
||||||
if(try self.isValidSpawnLocation(self.spawn[0], self.spawn[2])) break;
|
if(try self.isValidSpawnLocation(self.spawn[0], self.spawn[2])) break;
|
||||||
}
|
}
|
||||||
// TODO: spawn[1] = chunkManager.getOrGenerateMapFragment(spawn.x, spawn.z, 1).getHeight(spawn.x, spawn.z);
|
self.spawn[1] = 0;// TODO: spawn[1] = chunkManager.getOrGenerateMapFragment(spawn.x, spawn.z, 1).getHeight(spawn.x, spawn.z);
|
||||||
}
|
}
|
||||||
self.generated = true;
|
self.generated = true;
|
||||||
try self.wio.saveWorldData();
|
try self.wio.saveWorldData();
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO:
|
|
||||||
// public Player findPlayer(User user) {
|
pub fn findPlayer(self: *ServerWorld, user: *User) !void {
|
||||||
// JsonObject playerData = JsonParser.parseObjectFromFile("saves/" + name + "/players/" + Utils.escapeFolderName(user.name) + ".json");
|
var buf: [1024]u8 = undefined;
|
||||||
// Player player = new Player(this, user.name);
|
const playerData = files.readToJson(main.threadAllocator, try std.fmt.bufPrint(&buf, "saves/{s}/player/{s}.json", .{self.name, user.name})) catch .JsonNull; // TODO: Utils.escapeFolderName(user.name)
|
||||||
// if(playerData.map.isEmpty()) {
|
defer playerData.free(main.threadAllocator);
|
||||||
// // Generate a new player:
|
const player = &user.player;
|
||||||
// player.setPosition(spawn);
|
if(playerData == .JsonNull) {
|
||||||
// } else {
|
// Generate a new player:
|
||||||
// player.loadFrom(playerData);
|
player.pos = vec.intToFloat(f64, self.spawn);
|
||||||
// }
|
} else {
|
||||||
// addEntity(player);
|
player.loadFrom(playerData);
|
||||||
// return player;
|
}
|
||||||
// }
|
// TODO: addEntity(player);
|
||||||
//
|
}
|
||||||
|
|
||||||
// private void savePlayers() {
|
// private void savePlayers() {
|
||||||
// for(User user : Server.users) {
|
// for(User user : Server.users) {
|
||||||
// try {
|
// try {
|
||||||
@ -466,12 +471,12 @@ pub const ServerWorld = struct {
|
|||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
|
||||||
pub fn update(self: *ServerWorld) void {
|
pub fn update(self: *ServerWorld) !void {
|
||||||
const newTime = std.time.milliTimestamp();
|
const newTime = std.time.milliTimestamp();
|
||||||
var deltaTime = @intToFloat(f32, newTime - self.lastUpdateTime)/1000.0;
|
var deltaTime = @intToFloat(f32, newTime - self.lastUpdateTime)/1000.0;
|
||||||
self.lastUpdateTime = newTime;
|
self.lastUpdateTime = newTime;
|
||||||
if(deltaTime > 0.3) {
|
if(deltaTime > 0.3) {
|
||||||
std.log.warn("Update time is getting too high. It's alread at {} s!", .{deltaTime});
|
std.log.warn("Update time is getting too high. It's already at {} s!", .{deltaTime});
|
||||||
deltaTime = 0.3;
|
deltaTime = 0.3;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -481,10 +486,9 @@ pub const ServerWorld = struct {
|
|||||||
}
|
}
|
||||||
if(self.lastUnimportantDataSent + 2000 < newTime) {// Send unimportant data every ~2s.
|
if(self.lastUnimportantDataSent + 2000 < newTime) {// Send unimportant data every ~2s.
|
||||||
self.lastUnimportantDataSent = newTime;
|
self.lastUnimportantDataSent = newTime;
|
||||||
// TODO:
|
for(server.users.items) |user| {
|
||||||
// for(User user : Server.users) {
|
try main.network.Protocols.genericUpdate.sendTimeAndBiome(user.conn, self);
|
||||||
// Protocols.GENERIC_UPDATE.sendTimeAndBiome(user, this);
|
}
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
// TODO:
|
// TODO:
|
||||||
// // Entities
|
// // Entities
|
||||||
|
Loading…
x
Reference in New Issue
Block a user