Remove all the commented java code.

Most of it is already implemented elsewhere or no longer applicable and would need to be rewritten from scratch.
closes #129
This commit is contained in:
IntegratedQuantum 2024-04-20 10:58:59 +02:00
parent c9f9dbf634
commit e2459d1fbd
12 changed files with 23 additions and 1143 deletions

View File

@ -331,16 +331,3 @@ pub fn deinit() void {
biomes_zig.deinit();
blocks_zig.deinit();
}
//TODO:
// private void registerBlock(int block, Resource id, JsonObject json, Registry<DataOrientedRegistry> registries, NoIDRegistry<Ore> oreRegistry) {
// // block entities:
// if (json.has("blockEntity")) {
// try {
// Blocks.setBlockEntity(block, Class.forName(json.getString("blockEntity", "")).asSubclass(BlockEntity.class));
// } catch (ClassNotFoundException e) {
// Logger.error(e);
// }
// }
// }
//}

View File

@ -281,21 +281,6 @@ pub const Block = packed struct {
pub inline fn mode(self: Block) *RotationMode {
return _mode[self.typ];
}
// TODO:
// /**
// * Fires the blocks on click event(usually nothing or GUI opening).
// * @param world
// * @param pos
// * @return if the block did something on click.
// */
// public static boolean onClick(int block, World world, Vector3i pos) {
// if (gui[block & TYPE_MASK] != null) {
// GameLauncher.logic.openGUI("cubyz:workbench", new Inventory(26)); // TODO: Care about the inventory.
// return true;
// }
// return false;
// }
};
@ -554,38 +539,6 @@ pub const meshes = struct {
meshes.size += 1;
}
// TODO: (this one requires thinking about the allocated memory!)
// public static void reloadTextures() {
// for(int i = 0; i < blockTextures.size(); i++) {
// try {
// blockTextures.set(i, ImageIO.read(new File(textureIDs.get(i).replace(":animation", ""))));
// } catch(IOException e) {
// Logger.warning("Could not read image from path "+textureIDs.get(i));
// Logger.warning(e);
// blockTextures.set(i, blockTextures.get(0));
// }
// }
// generateTextureArray();
// }
// TODO:
// public static void loadMeshes() {
// // Goes through all meshes that were newly added:
// for(; loadedMeshes < size; loadedMeshes++) {
// if (meshes[loadedMeshes] == null) {
// meshes[loadedMeshes] = Meshes.cachedDefaultModels.get(models[loadedMeshes]);
// if (meshes[loadedMeshes] == null) {
// if(models[loadedMeshes].isEmpty())
// continue;
// Resource rs = new Resource(models[loadedMeshes]);
// meshes[loadedMeshes] = new Mesh(ModelLoader.loadModel(rs, "assets/" + rs.getMod() + "/models/3d/" + rs.getID()));
// Meshes.cachedDefaultModels.put(models[loadedMeshes], meshes[loadedMeshes]);
// }
// }
// }
// }
pub fn preProcessAnimationData(time: u32) void {
animationShader.bind();
graphics.c.glUniform1ui(animationUniforms.time, time);

View File

@ -298,28 +298,6 @@ pub const Chunk = struct {
return self.data.getValue(index);
}
pub fn getNeighbors(self: *const Chunk, x: i32, y: i32, z: i32, neighborsArray: *[6]Block) void {
x &= chunkMask;
y &= chunkMask;
z &= chunkMask;
for(Neighbors.relX, 0..) |_, i| {
const xi = x + Neighbors.relX[i];
const yi = y + Neighbors.relY[i];
const zi = z + Neighbors.relZ[i];
if (xi == (xi & chunkMask) and yi == (yi & chunkMask) and zi == (zi & chunkMask)) { // Simple double-bound test for coordinates.
neighborsArray[i] = self.getBlock(xi, yi, zi);
} else {
// TODO: What about other chunks?
// NormalChunk ch = world.getChunk(xi + wx, yi + wy, zi + wz);
// if (ch != null) {
// neighborsArray[i] = ch.getBlock(xi & chunkMask, yi & chunkMask, zi & chunkMask);
// } else {
// neighborsArray[i] = 1; // Some solid replacement, in case the chunk isn't loaded. TODO: Properly choose a solid block.
// }
}
}
}
pub fn updateFromLowerResolution(self: *Chunk, other: *const Chunk) void {
const xOffset = if(other.wx != self.wx) chunkSize/2 else 0; // Offsets of the lower resolution chunk in this chunk.
const yOffset = if(other.wy != self.wy) chunkSize/2 else 0;
@ -388,7 +366,7 @@ pub const Chunk = struct {
self.mutex.lock();
defer self.mutex.unlock();
if(self.wasChanged) {
// TODO: ChunkIO.storeChunkToFile(world, this);
// TODO: Actually store the chunk
self.wasChanged = false;
// Update the next lod chunk:
if(self.pos.voxelSize != 1 << settings.highestLOD) {

View File

@ -23,8 +23,6 @@ pub const ClientEntity = struct {
width: f64,
height: f64,
// TODO:
// public final EntityType type;
pos: Vec3d = undefined,
rot: Vec3f = undefined,
@ -35,8 +33,6 @@ pub const ClientEntity = struct {
pub fn init(self: *ClientEntity, json: JsonElement, allocator: NeverFailingAllocator) void {
self.* = ClientEntity{
.id = json.get(u32, "id", std.math.maxInt(u32)),
// TODO:
// CubyzRegistries.ENTITY_REGISTRY.getByID(json.getString("type", null)),
.width = json.get(f64, "width", 1),
.height = json.get(f64, "height", 1),
.name = allocator.dupe(u8, json.get([]const u8, "name", "")),

View File

@ -105,8 +105,6 @@ pub const World = struct {
blockPalette: *assets.BlockPalette = undefined,
itemDrops: ClientItemDropManager = undefined,
playerBiome: Atomic(*const main.server.terrain.biomes.Biome) = undefined,
// public final ArrayList<String> chatHistory = new ArrayList<>();
pub fn init(self: *World, ip: []const u8, manager: *ConnectionManager) !void {
self.* = .{
@ -117,8 +115,6 @@ pub const World = struct {
};
self.itemDrops.init(main.globalAllocator, self);
Player.inventory__SEND_CHANGES_TO_SERVER = Inventory.init(main.globalAllocator, 32);
// TODO:
// player = new ClientPlayer(this, 0);
network.Protocols.handShake.clientSide(self.conn, settings.playerName);
main.Window.setMouseGrabbed(true);
@ -153,16 +149,6 @@ pub const World = struct {
self.spawn[1] = jsonSpawn.get(f32, "y", 0);
self.spawn[2] = jsonSpawn.get(f32, "z", 0);
// TODO:
// if(Server.world != null) {
// // Share the registries of the local server:
// registries = Server.world.getCurrentRegistries();
// } else {
// registries = new CurrentWorldRegistries(this, "serverAssets/", blockPalette);
// }
//
// // Call mods for this new world. Mods sometimes need to do extra stuff for the specific world.
// ModLoader.postWorldGen(registries);
try assets.loadWorldAssets("serverAssets", self.blockPalette);
Player.loadFrom(json.getChild("player"));
Player.id = json.get(u32, "player_id", std.math.maxInt(u32));

View File

@ -196,38 +196,6 @@ pub const ItemDropManager = struct {
}
}
//TODO:
// public void checkEntity(Entity ent) {
// for(int ii = 0; ii < size; ii++) {
// int i = indices[ii] & 0xffff;
// int i3 = 3*i;
// if (pickupCooldown[i] >= 0) continue; // Item cannot be picked up yet.
// if (Math.abs(ent.position.x - posxyz[i3]) < ent.width + PICKUP_RANGE && Math.abs(ent.position.y + ent.height/2 - posxyz[i3 + 1]) < ent.height + PICKUP_RANGE && Math.abs(ent.position.z - posxyz[i3 + 2]) < ent.width + PICKUP_RANGE) {
// if(ent.getInventory().canCollect(itemStacks[i].getItem())) {
// if(ent instanceof Player) {
// // Needs to go through the network.
// for(User user : Server.users) {
// if(user.player == ent) {
// Protocols.GENERIC_UPDATE.itemStackCollect(user, itemStacks[i]);
// remove(i);
// ii--;
// break;
// }
// }
// } else {
// int newAmount = ent.getInventory().addItem(itemStacks[i].getItem(), itemStacks[i].getAmount());
// if(newAmount != 0) {
// itemStacks[i].setAmount(newAmount);
// } else {
// remove(i);
// ii--;
// }
// }
// }
// }
// }
// }
pub fn addFromBlockPosition(self: *ItemDropManager, blockPos: Vec3i, vel: Vec3d, itemStack: ItemStack, despawnTime: i32) void {
self.add(
vec.floatFromInt(f64, blockPos) + Vec3d { // TODO: Consider block bounding boxes.
@ -325,16 +293,6 @@ pub const ItemDropManager = struct {
// lastUpdates.add(new JsonInt(i));
// }
}
// TODO: Check if/how this is needed:
// public Vector3d getPosition(int index) {
// index *= 3;
// return new Vector3d(posxyz[index], posxyz[index+1], posxyz[index+2]);
// }
//
// public Vector3f getRotation(int index) {
// index *= 3;
// return new Vector3f(rotxyz[index], rotxyz[index+1], rotxyz[index+2]);
// }
fn updateEnt(self: *ItemDropManager, chunk: *Chunk, pos: *Vec3d, vel: *Vec3d, deltaTime: f64) void {
main.utils.assertLocked(&self.mutex);
@ -432,21 +390,12 @@ pub const ItemDropManager = struct {
}
fn checkBlock(self: *ItemDropManager, chunk: *Chunk, pos: *Vec3d, blockPos: Vec3i) bool {
// TODO:
// TODO: Check if the item drop collides with the block in the given location.
_ = self;
_ = chunk;
_ = pos;
_ = blockPos;
return false;
// // Transform to chunk-relative coordinates:
// int block = chunk.getBlockPossiblyOutside(x - chunk.wx, y - chunk.wy, z - chunk.wz);
// if (block == 0) return false;
// // Check if the item entity is inside the block:
// boolean isInside = true;
// if (Blocks.mode(block).changesHitbox()) {
// isInside = Blocks.mode(block).checkEntity(new Vector3d(posxyz[index3], posxyz[index3+1]-RADIUS, posxyz[index3+2]), RADIUS, DIAMETER, x, y, z, block);
// }
// return isInside && Blocks.solid(block);
}
};
@ -740,13 +689,7 @@ pub const ItemDropRenderer = struct {
if(itemDrops.list.items(.itemStack)[i].item) |item| {
var pos = itemDrops.list.items(.pos)[i];
const rot = itemDrops.list.items(.rot)[i];
// TODO: lighting:
// int x = (int)(manager.posxyz[index3] + 1.0f);
// int y = (int)(manager.posxyz[index3+1] + 1.0f);
// int z = (int)(manager.posxyz[index3+2] + 1.0f);
//
// int light = Cubyz.world.getLight(x, y, z, ambientLight, ClientSettings.easyLighting);
const light: u32 = 0xffffffff;
const light: u32 = 0xffffffff; // TODO: Get this light value from the mesh_storage.
c.glUniform3fv(itemUniforms.ambientLight, 1, @ptrCast(&@max(
ambientLight*@as(Vec3f, @splat(@as(f32, @floatFromInt(light >> 24))/255)),
Vec3f{light >> 16 & 255, light >> 8 & 255, light & 255}/@as(Vec3f, @splat(255))

View File

@ -141,43 +141,6 @@ pub const BaseItem = struct {
fn getTooltip(self: BaseItem) []const u8 {
return self.name;
}
// TODO: Check if/how this is needed:
// protected Item(int stackSize) {
// id = Resource.EMPTY;
// this.stackSize = stackSize;
// material = null;
// }
//
// public void update() {}
//
// /**
// * Returns true if this item should be consumed on use. May be accessed by non-player entities.
// * @param user
// * @return whether this item is consumed upon use.
// */
// public boolean onUse(Entity user) {
// return false;
// }
// From Consumable.java:
// @Override
// public boolean onUse(Entity user) {
// if((user.hunger >= user.maxHunger - Math.min(user.maxHunger*0.1, 0.5) && foodValue > 0) || (user.hunger == 0 && foodValue < 0)) return false;
// user.hunger = Math.min(user.maxHunger, user.hunger+foodValue);
// return true;
// }
// public static Item load(JsonObject json, CurrentWorldRegistries registries) {
// Item item = registries.itemRegistry.getByID(json.getString("item", "null"));
// if(item == null) {
// // Check if it is a tool:
// JsonObject tool = json.getObject("tool");
// if(tool != null) {
// item = new Tool(tool, registries);
// } else {
// // item not existant in this version of the game. Can't do much so ignore it.
// }
// }
// return item;
// }
};
///Generates the texture of a Tool using the material information.

View File

@ -625,14 +625,10 @@ pub const Protocols = struct {
conn.flush();
}
// TODO:
conn.user.?.initPlayer(name);
const jsonObject = JsonElement.initObject(main.stackAllocator);
defer jsonObject.free(main.stackAllocator);
jsonObject.put("player", conn.user.?.player.save(main.stackAllocator));
// TODO:
// jsonObject.put("player_id", ((User)conn).player.id);
// jsonObject.put("blockPalette", Server.world.blockPalette.save());
const spawn = JsonElement.initObject(main.stackAllocator);
spawn.put("x", main.server.world.?.spawn[0]);
spawn.put("y", main.server.world.?.spawn[1]);
@ -644,10 +640,6 @@ pub const Protocols = struct {
conn.sendImportant(id, outData);
conn.handShakeState.store(stepServerData, .monotonic);
conn.handShakeState.store(stepComplete, .monotonic);
// TODO:
// synchronized(conn) { // Notify the waiting server thread.
// conn.notifyAll();
// }
},
stepAssets => {
std.log.info("Received assets.", .{});
@ -905,91 +897,7 @@ pub const Protocols = struct {
pub fn send(conn: *Connection, msg: []const u8) void {
conn.sendImportant(id, msg);
}
// TODO:
// public void sendToClients(Entity[] currentEntities, Entity[] lastSentEntities, ItemEntityManager itemEntities) {
// synchronized(itemEntities) {
// byte[] data = new byte[currentEntities.length*(4 + 3*8 + 3*8 + 3*4)];
// int offset = 0;
// JsonArray entityChanges = new JsonArray();
// outer:
// for(Entity ent : currentEntities) {
// Bits.putInt(data, offset, ent.id);
// offset += 4;
// Bits.putDouble(data, offset, ent.getPosition().x);
// offset += 8;
// Bits.putDouble(data, offset, ent.getPosition().y);
// offset += 8;
// Bits.putDouble(data, offset, ent.getPosition().z);
// offset += 8;
// Bits.putFloat(data, offset, ent.getRotation().x);
// offset += 4;
// Bits.putFloat(data, offset, ent.getRotation().y);
// offset += 4;
// Bits.putFloat(data, offset, ent.getRotation().z);
// offset += 4;
// Bits.putDouble(data, offset, ent.vx);
// offset += 8;
// Bits.putDouble(data, offset, ent.vy);
// offset += 8;
// Bits.putDouble(data, offset, ent.vz);
// offset += 8;
// for(int i = 0; i < lastSentEntities.length; i++) {
// if(lastSentEntities[i] == ent) {
// lastSentEntities[i] = null;
// continue outer;
// }
// }
// JsonObject entityData = new JsonObject();
// entityData.put("id", ent.id);
// entityData.put("type", ent.getType().getRegistryID().toString());
// entityData.put("width", ent.width);
// entityData.put("height", ent.height);
// entityData.put("name", ent.name);
// entityChanges.add(entityData);
// }
// assert offset == data.length;
// for(Entity ent : lastSentEntities) {
// if(ent != null) {
// entityChanges.add(new JsonInt(ent.id));
// }
// }
// if(!itemEntities.lastUpdates.array.isEmpty()) {
// entityChanges.add(new JsonOthers(true, false));
// for(JsonElement elem : itemEntities.lastUpdates.array) {
// entityChanges.add(elem);
// }
// itemEntities.lastUpdates.array.clear();
// }
//
// if(!entityChanges.array.isEmpty()) {
// for(User user : Server.users) {
// if(user.receivedFirstEntityData) {
// user.sendImportant(this, entityChanges.toString().getBytes(StandardCharsets.UTF_8));
// }
// }
// }
// for(User user : Server.users) {
// if(!user.isConnected()) continue;
// if(!user.receivedFirstEntityData) {
// JsonArray fullEntityData = new JsonArray();
// for(Entity ent : currentEntities) {
// JsonObject entityData = new JsonObject();
// entityData.put("id", ent.id);
// entityData.put("type", ent.getType().getRegistryID().toString());
// entityData.put("width", ent.width);
// entityData.put("height", ent.height);
// entityData.put("name", ent.name);
// fullEntityData.add(entityData);
// }
// fullEntityData.add(new JsonOthers(true, false));
// fullEntityData.add(itemEntities.store());
// user.sendImportant(this, fullEntityData.toString().getBytes(StandardCharsets.UTF_8));
// user.receivedFirstEntityData = true;
// }
// Protocols.ENTITY_POSITION.send(user, data, itemEntities.getPositionAndVelocityData());
// }
// }
// }
// TODO: Send entity data.
};
pub const genericUpdate = struct {
pub const id: u8 = 9;
@ -1018,52 +926,23 @@ pub const Protocols = struct {
});
},
type_cure => {
// TODO:
// Cubyz.player.health = Cubyz.player.maxHealth;
// Cubyz.player.hunger = Cubyz.player.maxHunger;
// TODO: health and hunger
},
type_inventoryAdd => {
const slot = std.mem.readInt(u32, data[1..5], .big);
const amount = std.mem.readInt(u32, data[5..9], .big);
_ = slot;
_ = amount;
// TODO:
// ((User)conn).player.getInventory().getStack(slot).add(amount);
// TODO
},
type_inventoryFull => {
// TODO:
// JsonObject json = JsonParser.parseObjectFromString(new String(data, offset + 1, length - 1, StandardCharsets.UTF_8));
// ((User)conn).player.getInventory().loadFrom(json, Server.world.getCurrentRegistries());
// TODO: Parse inventory from json
},
type_inventoryClear => {
// TODO:
// if(conn instanceof User) {
// Inventory inv = ((User)conn).player.getInventory();
// for (int i = 0; i < inv.getCapacity(); i++) {
// inv.getStack(i).clear();
// }
// } else {
// Inventory inv = Cubyz.player.getInventory_AND_DONT_FORGET_TO_SEND_CHANGES_TO_THE_SERVER();
// for (int i = 0; i < inv.getCapacity(); i++) {
// inv.getStack(i).clear();
// }
// clearInventory(conn); // Needs to send changes back to server, to ensure correct order.
// }
// TODO: Clear inventory
},
type_itemStackDrop => {
// 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;
// }
// Server.world.drop(
// new ItemStack(item, json.getInt("amount", 1)),
// new Vector3d(json.getDouble("x", 0), json.getDouble("y", 0), json.getDouble("z", 0)),
// new Vector3f(json.getFloat("dirX", 0), json.getFloat("dirY", 0), json.getFloat("dirZ", 0)),
// json.getFloat("vel", 0),
// Server.UPDATES_PER_SEC*5
// );
// TODO: Drop stack
},
type_itemStackCollect => {
const json = JsonElement.parseFromString(main.stackAllocator, data[1..]);
@ -1660,22 +1539,7 @@ pub const Connection = struct {
if(protocol == Protocols.important) {
const id = std.mem.readInt(u32, data[1..5], .big);
if(self.handShakeState.load(.monotonic) == Protocols.handShake.stepComplete and id == 0) { // Got a new "first" packet from client. So the client tries to reconnect, but we still think it's connected.
// TODO:
// if(this instanceof User) {
// Server.disconnect((User)this);
// disconnected = true;
// manager.removeConnection(this);
// new Thread(() -> {
// try {
// Server.connect(new User(manager, remoteAddress.getHostAddress() + ":" + remotePort));
// } catch(Throwable e) {
// Logger.error(e);
// }
// }).start();
// return;
// } else {
// Logger.error("Server 'reconnected'? This makes no sense and the game can't handle that.");
// }
// TODO: re-initialize connection.
}
if(id - @as(i33, self.lastIncompletePacket) >= 65536) {
std.log.warn("Many incomplete packages. Cannot process any more packages for now.", .{});

View File

@ -124,31 +124,9 @@ pub fn updateViewport(width: u31, height: u31, fov: f32) void {
pub fn render(playerPosition: Vec3d) void {
const startTime = std.time.milliTimestamp();
// TODO:
// if (Cubyz.player != null) {
// if (Cubyz.playerInc.x != 0 || Cubyz.playerInc.y != 0) { // while walking
// if (bobbingUp) {
// playerBobbing += 0.005f;
// if (playerBobbing >= 0.05f) {
// bobbingUp = false;
// }
// } else {
// playerBobbing -= 0.005f;
// if (playerBobbing <= -0.05f) {
// bobbingUp = true;
// }
// }
// }
// if (Cubyz.playerInc.y != 0) {
// Cubyz.player.vy = Cubyz.playerInc.y;
// }
// if (Cubyz.playerInc.x != 0) {
// Cubyz.player.vx = Cubyz.playerInc.x;
// }
// playerPosition.z += Player.cameraHeight + playerBobbing;
// }
// TODO: player bobbing
if(game.world) |world| {
// // TODO: Handle colors and sun position in the world.
// TODO: Handle colors and sun position in the world.
var ambient: Vec3f = undefined;
ambient[0] = @max(0.1, world.ambientLight);
ambient[1] = @max(0.1, world.ambientLight);
@ -159,11 +137,6 @@ pub fn render(playerPosition: Vec3d) void {
renderWorld(world, ambient, skyColor, playerPosition);
mesh_storage.updateMeshes(startTime + maximumMeshTime);
} else {
// TODO:
// clearColor.y = clearColor.z = 0.7f;
// clearColor.x = 0.1f;@import("main.zig")
//
// Window.setClearColor(clearColor);
MenuBackGround.render();
}
}
@ -220,22 +193,10 @@ pub fn renderWorld(world: *World, ambientLight: Vec3f, skyColor: Vec3f, playerPo
blocks.meshes.reflectivityAndAbsorptionTextureArray.bind();
reflectionCubeMap.bindTo(4);
// SimpleList<NormalChunkMesh> visibleChunks = new SimpleList<NormalChunkMesh>(new NormalChunkMesh[64]);
// SimpleList<ReducedChunkMesh> visibleReduced = new SimpleList<ReducedChunkMesh>(new ReducedChunkMesh[64]);
chunk_meshing.quadsDrawn = 0;
chunk_meshing.transparentQuadsDrawn = 0;
const meshes = mesh_storage.updateAndGetRenderChunks(world.conn, playerPos, settings.renderDistance);
// for (ChunkMesh mesh : Cubyz.chunkTree.getRenderChunks(frustumInt, x0, y0, z0)) {
// if (mesh instanceof NormalChunkMesh) {
// visibleChunks.add((NormalChunkMesh)mesh);
//
// mesh.render(playerPosition);
// } else if (mesh instanceof ReducedChunkMesh) {
// visibleReduced.add((ReducedChunkMesh)mesh);
// }
// }
gpu_performance_measuring.startQuery(.chunk_rendering);
const direction = crosshairDirection(game.camera.viewMatrix, lastFov, lastWidth, lastHeight);
MeshSelection.select(playerPos, direction, game.Player.inventory__SEND_CHANGES_TO_SERVER.items[game.Player.selectedSlot]);
@ -249,11 +210,6 @@ pub fn renderWorld(world: *World, ambientLight: Vec3f, skyColor: Vec3f, playerPo
}
gpu_performance_measuring.stopQuery();
// for(int i = 0; i < visibleReduced.size; i++) {
// ReducedChunkMesh mesh = visibleReduced.array[i];
// mesh.render(playerPosition);
// }
gpu_performance_measuring.startQuery(.entity_rendering);
entity.ClientEntityManager.render(game.projectionMatrix, ambientLight, .{1, 0.5, 0.25}, playerPos);
@ -284,18 +240,9 @@ pub fn renderWorld(world: *World, ambientLight: Vec3f, skyColor: Vec3f, playerPo
c.glBlendFunc(c.GL_SRC_ALPHA, c.GL_ONE_MINUS_SRC_ALPHA);
chunk_meshing.endRender();
gpu_performance_measuring.stopQuery();
// NormalChunkMesh.bindTransparentShader(ambientLight, directionalLight.getDirection(), time);
worldFrameBuffer.bindTexture(c.GL_TEXTURE3);
// if(selected != null && Blocks.transparent(selected.getBlock())) {
// BlockBreakingRenderer.render(selected, playerPosition);
// glActiveTexture(GL_TEXTURE0);
// Meshes.blockTextureArray.bind();
// glActiveTexture(GL_TEXTURE1);
// Meshes.emissionTextureArray.bind();
// }
const playerBlock = mesh_storage.getBlockFromAnyLodFromRenderThread(@intFromFloat(@floor(playerPos[0])), @intFromFloat(@floor(playerPos[1])), @intFromFloat(@floor(playerPos[2])));
if(settings.bloom) {
@ -335,13 +282,6 @@ pub fn renderWorld(world: *World, ambientLight: Vec3f, skyColor: Vec3f, playerPo
gpu_performance_measuring.stopQuery();
}
// private float playerBobbing;
// private boolean bobbingUp;
//
// private Vector3f ambient = new Vector3f();
// private Vector4f clearColor = new Vector4f(0.1f, 0.7f, 0.7f, 1f);
// private DirectionalLight light = new DirectionalLight(new Vector3f(1.0f, 1.0f, 1.0f), new Vector3f(0.0f, 1.0f, 0.0f).mul(0.1f));
const Bloom = struct {
var buffer1: graphics.FrameBuffer = undefined;
var buffer2: graphics.FrameBuffer = undefined;
@ -827,17 +767,8 @@ pub const MeshSelection = struct {
return;
}
} else {
// Check if the block can actually be placed at that point. There might be entities or other blocks in the way.
// TODO: Check if the block can actually be placed at that point. There might be entities or other blocks in the way.
if(block.solid()) return;
// TODO:
// for(ClientEntity ent : ClientEntityManager.getEntities()) {
// Vector3d pos = ent.position;
// // Check if the block is inside:
// if (neighbor.x < pos.x + ent.width && neighbor.x + 1 > pos.x - ent.width
// && neighbor.y < pos.y + ent.width && neighbor.y + 1 > pos.y - ent.width
// && neighbor.z < pos.z + ent.height && neighbor.z + 1 > pos.z)
// return;
// }
block.typ = itemBlock;
block.data = 0;
if(rotationMode.generateData(main.game.world.?, neighborPos, relPos, lastDir, neighborDir, &block, true)) {

View File

@ -10,6 +10,8 @@ const NeverFailingAllocator = main.utils.NeverFailingAllocator;
pos: Vec3d = .{0, 0, 0},
vel: Vec3d = .{0, 0, 0},
rot: Vec3f = .{0, 0, 0},
// TODO: Health and hunger
// TODO: Name
fn loadVec3f(json: JsonElement) Vec3f {
return .{
@ -39,473 +41,12 @@ 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: NeverFailingAllocator) JsonElement {
const json = JsonElement.initObject(allocator);
// TODO: json.put("id", type.getRegistryID().toString());
json.put("position", saveVec3(allocator, self.pos));
json.put("velocity", saveVec3(allocator, self.vel));
json.put("rotation", saveVec3(allocator, self.rot));
// TODO:
// json.put("health", health);
// json.put("hunger", hunger);
// if(!name.isEmpty()) {
// json.put("name", name);
// }
return json;
}
// Entity {
// TODO: WARNING: This old code still uses y-up
// 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/37 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;
// }
// }
// }
// }
// }

View File

@ -24,7 +24,6 @@ pub const User = struct {
receivedFirstEntityData: bool = false,
isLocal: bool = false,
// TODO: ipPort: []const u8,
// TODO: public Thread waitingThread;
pub fn init(manager: *ConnectionManager, ipPort: []const u8) !*User {
const self = main.globalAllocator.create(User);
@ -35,12 +34,6 @@ pub const User = struct {
self.conn.user = self;
self.interpolation.init(@ptrCast(&self.player.pos), @ptrCast(&self.player.vel));
network.Protocols.handShake.serverSide(self.conn);
// TODO:
// synchronized(this) {
// waitingThread = Thread.currentThread();
// this.wait();
// waitingThread = null;
// }
return self;
}
@ -49,11 +42,6 @@ pub const User = struct {
main.globalAllocator.free(self.name);
main.globalAllocator.destroy(self);
}
// @Override
// public void disconnect() {
// super.disconnect();
// Server.disconnect(this);
// }
pub fn initPlayer(self: *User, name: []const u8) void {
self.name = main.globalAllocator.dupe(u8, name);
@ -91,11 +79,6 @@ pub const User = struct {
self.timeDifference.addDataPoint(time);
self.interpolation.updatePosition(&position, &velocity, time);
}
// TODO (Command stuff):
// @Override
// public void feedback(String feedback) {
// Protocols.CHAT.send(this, "#ffff00"+feedback);
// }
};
pub const updatesPerSec: u32 = 20;
@ -158,10 +141,7 @@ fn update() void {
user.update();
}
mutex.unlock();
// TODO:
// Entity[] entities = world.getEntities();
// Protocols.ENTITY.sendToClients(entities, lastSentEntities, world.itemEntityManager);
// lastSentEntities = entities;
// TODO: Send entities to client
}
pub fn start(name: []const u8) void {
@ -204,8 +184,6 @@ pub fn disconnect(user: *User) void {
break;
}
}
// TODO: world.removeEntity(user.player);
// TODO? users = usersList.toArray();
}
pub fn connect(user: *User) void {
@ -216,11 +194,8 @@ pub fn connect(user: *User) void {
sendMessage(message);
users.append(user);
// TODO: users = usersList.toArray();
}
// private Entity[] lastSentEntities = new Entity[0];
pub fn sendMessage(msg: []const u8) void {
main.utils.assertLocked(&mutex);
std.log.info("Chat: {s}", .{msg}); // TODO use color \033[0;32m

View File

@ -60,20 +60,8 @@ const ChunkManager = struct {
}
pub fn isStillNeeded(self: *ChunkLoadTask, milliTime: i64) bool {
// TODO:
if(self.source) |source| {
if(self.source) |source| { // TODO: Remove the task if the player disconnected
_ = source;
// TODO: This requires not garbage-collecting the source User.
// boolean isConnected = false;
// for(User user : Server.users) {
// if(source == user) {
// isConnected = true;
// break;
// }
// }
// if(!isConnected) {
// return false;
// }
}
if(milliTime - self.creationTime > 10000) { // Only remove stuff after 10 seconds to account for trouble when for example teleporting.
server.mutex.lock();
@ -167,22 +155,7 @@ const ChunkManager = struct {
}
pub fn deinit(self: ChunkManager) void {
// TODO:
// for(Cache<MapFragment> cache : mapCache) {
// cache.clear();
// }
// for(int i = 0; i < 5; i++) { // Saving one chunk may create and update a new lower resolution chunk.
//
// for(ReducedChunk[] array : reducedChunkCache.cache) {
// array = Arrays.copyOf(array, array.length); // Make a copy to prevent issues if the cache gets resorted during cleanup.
// for(ReducedChunk chunk : array) {
// if (chunk != null)
// chunk.clean();
// }
// }
// }
// ThreadPool.clear();
// ChunkIO.clean();
// TODO: Save chunks
chunkCache.clear();
server.terrain.deinit();
main.assets.unloadAssets();
@ -215,7 +188,7 @@ const ChunkManager = struct {
fn chunkInitFunctionForCache(pos: ChunkPosition) *Chunk {
const ch = Chunk.init(pos);
ch.generated = true;
// TODO: if(!ChunkIO.loadChunkFromFile(world, this)) {
// TODO: Try loading chunk from file
const caveMap = terrain.CaveMap.CaveMapView.init(ch);
defer caveMap.deinit();
const biomeMap = terrain.CaveBiomeMap.CaveBiomeMapView.init(ch);
@ -238,12 +211,6 @@ const ChunkManager = struct {
pub fn getChunkFromCache(pos: ChunkPosition) ?*Chunk {
return chunkCache.find(pos);
}
// public void forceSave() {
// for(int i = 0; i < 5; i++) { // Saving one chunk may create and update a new lower resolution chunk.
// reducedChunkCache.foreach(Chunk::save);
// }
// }
};
const WorldIO = struct {
@ -282,15 +249,6 @@ const WorldIO = struct {
const worldData: JsonElement = try self.dir.readToJson(main.stackAllocator, "world.dat");
defer worldData.free(main.stackAllocator);
const entityJson = worldData.getChild("entities");
_ = entityJson;
// Entity[] entities = new Entity[entityJson.array.size()];
// for(int i = 0; i < entities.length; i++) {
// // TODO: Only load entities that are in loaded chunks.
// entities[i] = EntityIO.loadEntity((JsonObject)entityJson.array.get(i), world);
// }
// world.setEntities(entities);
self.world.doGameTimeCycle = worldData.get(bool, "doGameTimeCycle", true);
self.world.gameTime = worldData.get(i64, "gameTime", 0);
const spawnData = worldData.getChild("spawn");
@ -306,22 +264,12 @@ const WorldIO = struct {
worldData.put("seed", self.world.seed);
worldData.put("doGameTimeCycle", self.world.doGameTimeCycle);
worldData.put("gameTime", self.world.gameTime);
// TODO:
// worldData.put("entityCount", world.getEntities().length);
const spawnData = JsonElement.initObject(main.stackAllocator);
spawnData.put("x", self.world.spawn[0]);
spawnData.put("y", self.world.spawn[1]);
spawnData.put("z", self.world.spawn[2]);
worldData.put("spawn", spawnData);
// TODO:
// JsonArray entityData = new JsonArray();
// worldData.put("entities", entityData);
// // TODO: Store entities per chunk.
// for (Entity ent : world.getEntities()) {
// if (ent != null && ent.getType().getClass() != PlayerEntity.class) {
// entityData.add(ent.save());
// }
// }
// TODO: Save entities
try self.dir.writeJson("world.dat", worldData);
}
};
@ -333,8 +281,6 @@ pub const ServerWorld = struct {
itemDropManager: ItemDropManager = undefined,
blockPalette: *main.assets.BlockPalette = undefined,
chunkManager: ChunkManager = undefined,
// TODO: protected HashMap<HashMapKey3D, MetaChunk> metaChunks = new HashMap<HashMapKey3D, MetaChunk>();
// TODO: protected NormalChunk[] chunks = new NormalChunk[0];
generated: bool = false,
@ -350,8 +296,6 @@ pub const ServerWorld = struct {
spawn: Vec3i = undefined,
wio: WorldIO = undefined,
// TODO:
// protected ArrayList<Entity> entities = new ArrayList<>();
pub fn init(name: []const u8, nullGeneratorSettings: ?JsonElement) !*ServerWorld {
const self = main.globalAllocator.create(ServerWorld);
@ -397,9 +341,6 @@ pub const ServerWorld = struct {
// Store the block palette now that everything is loaded.
try files.writeJson(try std.fmt.bufPrint(&buf, "saves/{s}/palette.json", .{name}), self.blockPalette.save(arenaAllocator));
// TODO: // Call mods for this new world. Mods sometimes need to do extra stuff for the specific world.
// ModLoader.postWorldGen(registries);
//
self.chunkManager = try ChunkManager.init(self, generatorSettings);
errdefer self.chunkManager.deinit();
try self.generate();
@ -450,49 +391,14 @@ pub const ServerWorld = struct {
// TODO: addEntity(player);
}
// private void savePlayers() {
// for(User user : Server.users) {
// try {
// File file = new File("saves/" + name + "/players/" + Utils.escapeFolderName(user.name) + ".json");
// file.getParentFile().mkdirs();
// PrintWriter writer = new PrintWriter(new FileOutputStream("saves/" + name + "/players/" + Utils.escapeFolderName(user.name) + ".json"), false, StandardCharsets.UTF_8);
// user.player.save().writeObjectToStream(writer);
// writer.close();
// } catch(FileNotFoundException e) {
// Logger.error(e);
// }
// }
// }
pub fn forceSave(self: *ServerWorld) !void {
// TODO:
// for(MetaChunk chunk : metaChunks.values().toArray(new MetaChunk[0])) {
// if (chunk != null) chunk.save();
// }
// TODO: Save chunks and player data
try self.wio.saveWorldData();
// TODO:
// savePlayers();
// chunkManager.forceSave();
// ChunkIO.save();
const itemDropJson = self.itemDropManager.store(main.stackAllocator);
defer itemDropJson.free(main.stackAllocator);
var buf: [32768]u8 = undefined;
try files.writeJson(try std.fmt.bufPrint(&buf, "saves/{s}/items.json", .{self.name}), itemDropJson);
}
// TODO:
// public void addEntity(Entity ent) {
// entities.add(ent);
// }
//
// public void removeEntity(Entity ent) {
// entities.remove(ent);
// }
//
// public void setEntities(Entity[] arr) {
// entities = new ArrayList<>(arr.length);
// for (Entity e : arr) {
// entities.add(e);
// }
// }
fn isValidSpawnLocation(_: *ServerWorld, wx: i32, wy: i32) bool {
const map = terrain.SurfaceMap.getOrGenerateFragment(wx, wy, 1);
@ -509,30 +415,6 @@ pub const ServerWorld = struct {
self.dropWithCooldown(stack, pos, dir, velocity, 0);
}
// TODO:
// @Override
// public void updateBlock(int x, int y, int z, int newBlock) {
// NormalChunk ch = getChunk(x, y, z);
// if (ch != null) {
// int old = ch.getBlock(x & Chunk.chunkMask, y & Chunk.chunkMask, z & Chunk.chunkMask);
// if(old == newBlock) return;
// ch.updateBlock(x & Chunk.chunkMask, y & Chunk.chunkMask, z & Chunk.chunkMask, newBlock);
// // Send the block update to all players:
// for(User user : Server.users) {
// Protocols.BLOCK_UPDATE.send(user, x, y, z, newBlock);
// }
// if((old & Blocks.TYPE_MASK) == (newBlock & Blocks.TYPE_MASK)) return;
// for(BlockDrop drop : Blocks.blockDrops(old)) {
// int amount = (int)(drop.amount);
// float randomPart = drop.amount - amount;
// if (Math.random() < randomPart) amount++;
// if (amount > 0) {
// itemEntityManager.add(x, y, z, 0, 0, 0, new ItemStack(drop.item, amount), 30*900);
// }
// }
// }
// }
pub fn update(self: *ServerWorld) void {
const newTime = std.time.milliTimestamp();
var deltaTime = @as(f32, @floatFromInt(newTime - self.lastUpdateTime))/1000.0;
@ -552,39 +434,12 @@ pub const ServerWorld = struct {
main.network.Protocols.genericUpdate.sendTimeAndBiome(user.conn, self);
}
}
// TODO:
// // Entities
// for (int i = 0; i < entities.size(); i++) {
// Entity en = entities.get(i);
// en.update(deltaTime);
// // Check item entities:
// if (en.getInventory() != null) {
// itemEntityManager.checkEntity(en);
// }
// }
// TODO: Entities
// Item Entities
self.itemDropManager.update(deltaTime);
// TODO:
// // Block Entities
// for(MetaChunk chunk : metaChunks.values()) {
// chunk.updateBlockEntities();
// }
//
// // Liquids
// if (gameTime % 3 == 0) {
// //Profiler.startProfiling();
// for(MetaChunk chunk : metaChunks.values()) {
// chunk.liquidUpdate();
// }
// //Profiler.printProfileTime("liquid-update");
// }
//
// seek();
}
// TODO:
// @Override
pub fn queueChunks(self: *ServerWorld, positions: []ChunkPosition, source: ?*User) void {
for(positions) |pos| {
self.queueChunk(pos, source);
@ -599,106 +454,14 @@ pub const ServerWorld = struct {
self.chunkManager.queueLightMap(pos, source);
}
pub fn seek() void {
// TODO: Remove this MetaChunk stuff. It wasn't really useful and made everything needlessly complicated.
// // Care about the metaChunks:
// HashMap<HashMapKey3D, MetaChunk> oldMetaChunks = new HashMap<>(metaChunks);
// HashMap<HashMapKey3D, MetaChunk> newMetaChunks = new HashMap<>();
// for(User user : Server.users) {
// ArrayList<NormalChunk> chunkList = new ArrayList<>();
// int metaRenderDistance = (int)Math.ceil(Settings.entityDistance/(float)(MetaChunk.metaChunkSize*Chunk.chunkSize));
// int x0 = (int)user.player.getPosition().x >> (MetaChunk.metaChunkShift + Chunk.chunkShift);
// int y0 = (int)user.player.getPosition().y >> (MetaChunk.metaChunkShift + Chunk.chunkShift);
// int z0 = (int)user.player.getPosition().z >> (MetaChunk.metaChunkShift + Chunk.chunkShift);
// for(int metaX = x0 - metaRenderDistance; metaX <= x0 + metaRenderDistance + 1; metaX++) {
// for(int metaY = y0 - metaRenderDistance; metaY <= y0 + metaRenderDistance + 1; metaY++) {
// for(int metaZ = z0 - metaRenderDistance; metaZ <= z0 + metaRenderDistance + 1; metaZ++) {
// HashMapKey3D key = new HashMapKey3D(metaX, metaY, metaZ);
// if(newMetaChunks.containsKey(key)) continue; // It was already updated from another players perspective.
// // Check if it already exists:
// MetaChunk metaChunk = oldMetaChunks.get(key);
// oldMetaChunks.remove(key);
// if (metaChunk == null) {
// metaChunk = new MetaChunk(metaX *(MetaChunk.metaChunkSize*Chunk.chunkSize), metaY*(MetaChunk.metaChunkSize*Chunk.chunkSize), metaZ *(MetaChunk.metaChunkSize*Chunk.chunkSize), this);
// }
// newMetaChunks.put(key, metaChunk);
// metaChunk.update(Settings.entityDistance, chunkList);
// }
// }
// }
// oldMetaChunks.forEach((key, chunk) -> {
// chunk.clean();
// });
// chunks = chunkList.toArray(new NormalChunk[0]);
// metaChunks = newMetaChunks;
// }
}
//
// public MetaChunk getMetaChunk(int wx, int wy, int wz) {
// // Test if the metachunk exists:
// int metaX = wx >> (MetaChunk.metaChunkShift + Chunk.chunkShift);
// int metaY = wy >> (MetaChunk.metaChunkShift + Chunk.chunkShift);
// int metaZ = wz >> (MetaChunk.metaChunkShift + Chunk.chunkShift);
// HashMapKey3D key = new HashMapKey3D(metaX, metaY, metaZ);
// return metaChunks.get(key);
// }
pub fn getChunk(self: *ServerWorld, x: i32, y: i32, z: i32) ?*Chunk {
_ = self;
_ = x;
_ = y;
_ = z;
// TODO:
// MetaChunk meta = getMetaChunk(wx, wy, wz);
// if (meta != null) {
// return meta.getChunk(wx, wy, wz);
// }
// TODO
return null;
}
// TODO:
// public BlockEntity getBlockEntity(int x, int y, int z) {
// /*BlockInstance bi = getBlockInstance(x, y, z);
// Chunk ck = _getNoGenerateChunk(bi.getX() >> NormalChunk.chunkShift, bi.getY() >> NormalChunk.chunkShift);
// return ck.blockEntities().get(bi);*/
// return null; // TODO: Work on BlockEntities!
// }
// public NormalChunk[] getChunks() {
// return chunks;
// }
//
// public Entity[] getEntities() {
// return entities.toArray(new Entity[0]);
// }
//
// public int getHeight(int wx, int wy) {
// return (int)chunkManager.getOrGenerateMapFragment(wx, wy, 1).getHeight(wx, wy);
// }
// @Override
// public void cleanup() {
// // Be sure to dereference and finalize the maximum of things
// try {
// for(MetaChunk chunk : metaChunks.values()) {
// if (chunk != null) chunk.clean();
// }
// chunkManager.forceSave();
// ChunkIO.save();
//
// chunkManager.cleanup();
//
// ChunkIO.clean();
//
// wio.saveWorldData();
// savePlayers();
// JsonParser.storeToFile(itemEntityManager.store(), "saves/" + name + "/items.json");
// metaChunks = null;
// } catch (Exception e) {
// Logger.error(e);
// }
// }
// @Override
// public CurrentWorldRegistries getCurrentRegistries() {
// return registries;
// }
pub fn getBiome(_: *const ServerWorld, wx: i32, wy: i32, wz: i32) *const terrain.biomes.Biome {
const map = terrain.CaveBiomeMap.InterpolatableCaveBiomeMapView.init(.{.wx = wx, .wy = wy, .wz = wz, .voxelSize = 1}, 1);